//========================================================================
// Skyline Robotics PowerStep stepper motor driver control software
//
// BeagleBone patform back-end
//
// AUTHOR:  Gabor Nagy
// DATE:    2015-Sep-27 20:31:17
//
// Copyright (C) 1996-2026 By Gabor Nagy. All rights reserved.
//========================================================================
#ifndef SR_BeagleBone_h
#define SR_BeagleBone_h


#define Sr_SetToOut(m)\
do\
{\
	if(m##bit >= 0)\
	{\
		char  lStr[128];\
		int   lResult;\
		sprintf(lStr, "echo %d > /sys/class/gpio/unexport", m##bit);\
		lResult = system(lStr);if(lResult != 0)\
		{\
printf("%s() %s:%d  '%s' failed\n", __FUNCTION__, __FILE__, __LINE__, lStr);fflush(stdout);\
		}\
		sprintf(lStr, "echo %d > /sys/class/gpio/export", m##bit);\
		lResult = system(lStr);if(lResult != 0)\
		{\
printf("%s() %s:%d  '%s' failed\n", __FUNCTION__, __FILE__, __LINE__, lStr);fflush(stdout);\
		}\
		else\
		{\
			sprintf(lStr, "echo out > /sys/class/gpio/gpio%d/direction", m##bit);\
			lResult = system(lStr);if(lResult != 0)\
			{\
printf("%s() %s:%d  '%s' failed\n", __FUNCTION__, __FILE__, __LINE__, lStr);fflush(stdout);\
			}\
		}\
	}\
} while(0)



#define Sr_SetToIn(m)\
do\
{\
	if(m##bit >= 0)\
	{\
		char  lStr[128];\
		int   lResult;\
printf("%s() %s:%d  %d\n", __FUNCTION__, __FILE__, __LINE__, m##bit);fflush(stdout);\
		sprintf(lStr, "echo %d > /sys/class/gpio/unexport", m##bit);\
		lResult = system(lStr);if(lResult != 0)\
		{\
printf("%s() %s:%d  '%s' failed\n", __FUNCTION__, __FILE__, __LINE__, lStr);fflush(stdout);\
		}\
		sprintf(lStr, "echo %d > /sys/class/gpio/export", m##bit);\
		lResult = system(lStr);if(lResult != 0)\
		{\
printf("%s() %s:%d  '%s' failed\n", __FUNCTION__, __FILE__, __LINE__, lStr);fflush(stdout);\
		}\
		else\
		{\
			sprintf(lStr, "echo in > /sys/class/gpio/gpio%d/direction", m##bit);\
			lResult = system(lStr);if(lResult != 0)\
			{\
printf("%s() %s:%d  '%s' failed\n", __FUNCTION__, __FILE__, __LINE__, lStr);fflush(stdout);\
			}\
		}\
	}\
} while(0)



#define Sr_SetToOutO(m)\
do\
{\
	if(m >= 0)\
	{\
		char  lStr[128];\
		int   lResult;\
		sprintf(lStr, "echo %d > /sys/class/gpio/unexport", m);\
		lResult = system(lStr);if(lResult != 0)\
		{\
printf("%s() %s:%d  '%s' failed\n", __FUNCTION__, __FILE__, __LINE__, lStr);fflush(stdout);\
		}\
		sprintf(lStr, "echo %d > /sys/class/gpio/export", m);\
		lResult = system(lStr);if(lResult != 0)\
		{\
printf("%s() %s:%d  '%s' failed\n", __FUNCTION__, __FILE__, __LINE__, lStr);fflush(stdout);\
		}\
		else\
		{\
			sprintf(lStr, "echo out > /sys/class/gpio/gpio%d/direction", m);\
			lResult = system(lStr);if(lResult != 0)\
			{\
printf("%s() %s:%d  '%s' failed\n", __FUNCTION__, __FILE__, __LINE__, lStr);fflush(stdout);\
			}\
		}\
	}\
} while(0)

#define _DriverBit0(mDriver, m) do { if((mDriver)->m##bit >= 0) LGPIO->Registers[(mDriver)->m##bit >> 5][0x190/4] = 1 << ((mDriver)->m##bit & 0x0000001F); } while(0)
#define _DriverBit1(mDriver, m) do { if((mDriver)->m##bit >= 0) LGPIO->Registers[(mDriver)->m##bit >> 5][0x194/4] = 1 << ((mDriver)->m##bit & 0x0000001F); } while(0)

#define E_GPIOBit0(mGPIO, mBank, mPin) do { mGPIO->Registers[mBank][0x190/4] = 1 << (mPin); } while(0)
#define E_GPIOBit1(mGPIO, mBank, mPin) do { mGPIO->Registers[mBank][0x194/4] = 1 << (mPin); } while(0)

// GPIO
//
#define SrBB_PWM_START  0x44C00000

#define SrGPIO0_START   0x44E07000
#define SrGPIO1_START   0x4804C000
#define SrGPIO2_START   0x481AC000
#define SrGPIO3_START   0x481AE000
#define SrGPIO_DATAOUT  0x13C



// PWM
//
#define CM_PER_BASE (0x44e00000 - SrBB_PWM_START)
#define CM_PER_EPWMSS0_CLKCTRL_OFFSET (CM_PER_BASE + 0xd4)
#define CM_PER_EPWMSS1_CLKCTRL_OFFSET (CM_PER_BASE + 0xcc)
#define CM_PER_EPWMSS2_CLKCTRL_OFFSET (CM_PER_BASE + 0xd8)

#define PWM_CLOCK_ENABLE   0x2
#define PWM_CLOCK_DISABLE  0x0
 
#define PWM_LIST_MAX  3


#include <sys/mman.h>

typedef struct
{
	int              FileDescriptor;
	volatile ulong*  Registers[4];
} SrGPIO;

typedef struct
{
	int              FileDescriptor;
	volatile ulong*  Registers;
} SrPWM;



typedef struct s_BBPWM
{
  char   muxmode;   // Mux mode, 0-7, see am335x technical manual
  char*  name;      // Name of pwm pin, i.e.: "EHRPWM2B"
  char*  path;      // Path to the pwm, i.e.: "ehrpwm.2:1"
} SrBBPWM;


typedef struct s_PIN
{
  char*          name;         // Readable name of pin, i.e.: "GPIO1_21", see beaglebone user guide
  unsigned int   gpio_bank;    // Which of the four gpio banks is this pin in, i.e.: GPIO1, r 0x4804C000
  uint8_t        gpio;         // Pin number on the am335x processor
  uint8_t        bank_id;      // Pin number within each bank, should be 0-31
  char*          mux;          // File name for setting mux
  uint8_t        eeprom;       // Position in eeprom
  unsigned char  pwm_present;  // Whether or not this pin can be used for PWM
  SrBBPWM        PWM;          // PWM struct if pwm_present is true
} SrBBPIN;

#define TRUE 1
#define FALSE 0

#define GPIO0 (0x44E07000)
#define GPIO1 (0x4804C000)
#define GPIO2 (0x481AC000)
#define GPIO3 (0x481AE000)




// P8_5, P8_6 etc. are reserved by the system (at least on the version of Angstrom I have).
// cat /sys/kernel/debug/gpio will show which ones are taken by the system.

#define BLANK  { NULL, 0, 0, 0, NULL, 0, FALSE }

#define USR0  { "GPIO1_21", GPIO1, 0, 21, "", 0, FALSE }
#define USR1  { "GPIO1_22", GPIO1, 0, 22, "", 0, FALSE }
#define USR2  { "GPIO1_23", GPIO1, 0, 23, "", 0, FALSE }
#define USR3  { "GPIO1_24", GPIO1, 0, 24, "", 0, FALSE }
#define P8_3  { "GPIO1_6", GPIO1, 38, 6, "gpmc_ad6", 26, FALSE }
#define P8_4  { "GPIO1_7", GPIO1, 39, 7, "gpmc_ad7", 27, FALSE }
#define P8_5  { "GPIO1_2", GPIO1, 34, 2, "gpmc_ad2", 22, FALSE }
#define P8_6  { "GPIO1_3", GPIO1, 35, 3, "gpmc_ad3", 23, FALSE }
#define P8_7  { "TIMER4", GPIO2, 66, 2, "gpmc_advn_ale", 41, FALSE }
#define P8_8  { "TIMER7", GPIO2, 67, 3, "gpmc_oen_ren", 44, FALSE }
#define P8_9  { "TIMER5", GPIO2, 69, 5, "gpmc_ben0_cle", 42, FALSE }
#define P8_10 { "TIMER6", GPIO2, 68, 4, "gpmc_wen", 43, FALSE }
#define P8_11 { "GPIO1_13", GPIO1, 45, 13, "gpmc_ad13", 29, FALSE }
#define P8_12 { "GPIO1_12", GPIO1, 44, 12, "gpmc_ad12", 28, FALSE }
#define P8_13 { "EHRPWM2B", GPIO0, 23, 23, "gpmc_ad9", 15, TRUE, .PWM={4, "EHRPWM2B", "ehrpwm.2:1"}}
#define P8_14 { "GPIO0_26", GPIO0, 26, 26, "gpmc_ad10", 16, FALSE }
#define P8_15 { "GPIO1_15", GPIO1, 47, 15, "gpmc_ad15", 31, FALSE }
#define P8_16 { "GPIO1_14", GPIO1, 46, 14, "gpmc_ad14", 30, FALSE }
#define P8_17 { "GPIO0_27", GPIO0, 27, 27, "gpmc_ad11", 17, FALSE }
#define P8_18 { "GPIO2_1", GPIO2, 65, 1, "gpmc_clk", 40, FALSE }
#define P8_19 { "EHRPWM2A", GPIO0, 22, 22, "gpmc_ad8", 14, TRUE, .PWM={4, "EHRPWM2A", "ehrpwm.2:0"}}
#define P8_20 { "GPIO1_31", GPIO1, 63, 31, "gpmc_csn2", 39, FALSE }
#define P8_21 { "GPIO1_30", GPIO1, 62, 30, "gpmc_csn1", 38, FALSE }
#define P8_22 { "GPIO1_5", GPIO1, 37, 5, "gpmc_ad5", 25, FALSE }
#define P8_23 { "GPIO1_4", GPIO1, 36, 4, "gpmc_ad4", 24, FALSE }
#define P8_24 { "GPIO1_1", GPIO1, 33, 1, "gpmc_ad1", 21, FALSE }
#define P8_25 { .name= "GPIO1_0", .gpio_bank= GPIO1, .gpio=32, .bank_id= 0, .mux="gpmc_ad0", .eeprom= 20 }
#define P8_26 { "GPIO1_29", GPIO1, 61, 29, "gpmc_csn0", 37, FALSE }
#define P8_27 { "GPIO2_22", GPIO2, 86, 22, "lcd_vsync", 57, FALSE }
#define P8_28 { "GPIO2_24", GPIO2, 88, 24, "lcd_pclk", 59, FALSE }
#define P8_29 { "GPIO2_23", GPIO2, 87, 23, "lcd_hsync", 58, FALSE }
#define P8_30 { "GPIO2_25", GPIO2, 89, 25, "lcd_ac_bias_en", 60, FALSE }
#define P8_31 { "UART5_CTSN", GPIO0, 10, 10, "lcd_data14", 7, FALSE }
#define P8_32 { "UART5_RTSN", GPIO0, 11, 11, "lcd_data15", 8, FALSE }
#define P8_33 { "UART4_RTSN", GPIO0, 9, 9, "lcd_data13", 6, FALSE }
#define P8_34 { "UART3_RTSN", GPIO2, 81, 17, "lcd_data11", 56, TRUE, .PWM={2, "EHRPWM1B", "ehrpwm.1:1"}}
#define P8_35 { "UART4_CTSN", GPIO0, 8, 8, "lcd_data12", 5, FALSE }
#define P8_36 { "UART3_CTSN", GPIO2, 80, 16, "lcd_data10", 55, TRUE, .PWM={2, "EHRPWM1A", "ehrpwm.1:0"}}
#define P8_37 { "UART5_TXD", GPIO2, 78, 14, "lcd_data8", 53, FALSE }
#define P8_38 { "UART5_RXD", GPIO2, 79, 15, "lcd_data9", 54, FALSE }
#define P8_39 { "GPIO2_12", GPIO2, 76, 12, "lcd_data6", 51, FALSE }
#define P8_40 { "GPIO2_13", GPIO2, 77, 13, "lcd_data7", 52, FALSE }
#define P8_41 { "GPIO2_10", GPIO2, 74, 10, "lcd_data4", 49, FALSE }
#define P8_42 { "GPIO2_11", GPIO2, 75, 11, "lcd_data5", 50, FALSE }
#define P8_43 { "GPIO2_8", GPIO2, 72, 8, "lcd_data2", 47, FALSE }
#define P8_44 { "GPIO2_9", GPIO2, 73, 9, "lcd_data3", 48, FALSE }
#define P8_45 { "GPIO2_6", GPIO2, 70, 6, "lcd_data0", 45, TRUE, .PWM={3, "EHRPWM2A", "ehrpwm.2:0"}}
#define P8_46 { "GPIO2_7", GPIO2, 71, 7, "lcd_data1", 46, TRUE, .PWM={3, "EHRPWM2B", "ehrpwm.2:1"}}

#define P9_11 { "UART4_RXD", GPIO0, 30, 30, "gpmc_wait0", 18, FALSE }
#define P9_12 { "GPIO1_28", GPIO1, 60, 28, "gpmc_ben1", 36, FALSE }
#define P9_13 { "UART4_TXD", GPIO0, 31, 31, "gpmc_wpn", 19, FALSE }
#define P9_14 { "EHRPWM1A", GPIO1, 50, 18, "gpmc_a2", 34, TRUE, .PWM={6, "EHRPWM1A", "ehrpwm.1:0"}}
#define P9_15 { "GPIO1_16", GPIO1, 48, 16, "mii1_rxd3", 32, FALSE }
#define P9_16 { "EHRPWM1B", GPIO1, 51, 19, "gpmc_a3", 35, TRUE, .PWM={6, "EHRPWM1B", "ehrpwm.1:1"}}
#define P9_17 { "I2C1_SCL", GPIO0, 5, 5, "spi0_cs0", 3, FALSE }
#define P9_18 { "I2C1_SDA", GPIO0, 4, 4, "spi0_d1", 2, FALSE }
#define P9_19 { "I2C2_SCL", GPIO0, 13, 13, "uart1_rtsn", 9, FALSE }
#define P9_20 { "I2C2_SDA", GPIO0, 12, 12, "uart1_ctsn", 10, FALSE }
#define P9_21 { "UART2_TXD", GPIO0, 3, 3, "spi0_d0", 1, TRUE, .PWM={3, "EHRPWM0B", "ehrpwm.0:1"}}
#define P9_22 { "UART2_RXD", GPIO0, 2, 2, "spi0_sclk", 0, TRUE, .PWM={3, "EHRPWM0A", "ehrpwm.0:0"}}
#define P9_23 { "GPIO1_17", GPIO1, 49, 17, "gpmc_a1", 33, FALSE }
#define P9_24 { "UART1_TXD", GPIO0, 15, 15, "uart1_txd", 12, FALSE }
#define P9_25 { "GPIO3_21", GPIO3, 117, 21, "mcasp0_ahclkx", 66, FALSE }
#define P9_26 { "UART1_RXD", GPIO0, 14, 14, "uart1_rxd", 11, FALSE }
#define P9_27 { "GPIO3_19", GPIO3, 115, 19, "mcasp0_fsr", 64, FALSE }
#define P9_28 { "SPI1_CS0", GPIO3, 113, 17, "mcasp0_ahclkr", 63, TRUE, .PWM={4, "ECAPPWM2", "ecap.2"}}
#define P9_29 { "SPI1_D0", GPIO3, 111, 15, "mcasp0_fsx", 61, TRUE, .PWM={1, "EHRPWM0B", "ehrpwm.0:1"}}
#define P9_30 { "SPI1_D1", GPIO3, 112, 16, "mcasp0_axr0", 62, FALSE }
#define P9_31 { "SPI1_SCLK", GPIO3, 110, 14, "mcasp0_aclkx", 65, TRUE, .PWM={1, "EHRPWM0A", "ehrpwm.0:0"}}
#define P9_33 { "AIN4", 0, 4, 4, "", 71, FALSE }
#define P9_35 { "AIN6", 0, 6, 6, "", 73, FALSE }
#define P9_36 { "AIN5", 0, 5, 5, "", 72, FALSE }
#define P9_37 { "AIN2", 0, 2, 2, "", 69, FALSE }
#define P9_38 { "AIN3", 0, 3, 3, "", 70, FALSE }
#define P9_39 { "AIN0", 0, 0, 0, "", 67, FALSE }
#define P9_40 { "AIN1", 0, 1, 1, "", 68, FALSE }
#define P9_41 { "CLKOUT2", GPIO0, 20, 20, "xdma_event_intr1", 13, FALSE }
#define P9_42 { "GPIO0_7", GPIO0, 7, 7, "ecap0_in_pwm0_out", 4, TRUE, .PWM={0, "ECAPPWM0", "ecap.0"}}












//
// POutput  If TRUE, make pin an output, otherwise make it an input
//
static inline void Sr_GPIOSetDirection(SrGPIO* PGPIO, const int PBank, const int PPin, const EBool POutput)
{
printf("%s() %s:%d  %d_%02d %s%c%s\n", __FUNCTION__, __FILE__, __LINE__, PBank, PPin, ECodeGreen, POutput ? '>' : '<', ECodeNormal);fflush(stdout);
	if(POutput)
	{
		PGPIO->Registers[PBank][SrGPIO_DATAOUT/4] |= 1 << PPin;
	}
	else
	{
		const uint32_t  PBit = ~(1 << PPin);
		PGPIO->Registers[PBank][SrGPIO_DATAOUT/4] &= PBit;
	}
}


static inline void Sr_GPIO(SrGPIO* PGPIO)
{
}





static inline int _BeagleBoneGPIOInit(SrGPIO* PGPIO, const int PVerbosity)
{
	memset(PGPIO, 0, sizeof(SrGPIO));

	const int  LGPIO_fd = open("/dev/mem", O_RDWR | O_SYNC);if(LGPIO_fd < 0)
	{
		printf("%s() %s:%d  %sCould not open GPIO memory fd%s\n", __FUNCTION__, __FILE__, __LINE__, ECodeRed, ECodeNormal);fflush(stdout);
		return(E_COULD_NOT_OPEN_FILE);
	}


// GPIO configuration
//

// Set MUX
// On the BeagleBone Black, we need to use device-tree overlays for this,
// so this only applies to the old BeagleBone (white)
//


#if __BEAGLEBONE__ == BeagleBoneWHITE
	const SrBBPIN  LGPIOPins[] =
	{
		P8_25, P8_24, P8_5,  P8_6, P8_23, P8_22, P8_3, P8_4,   // GPIO1_0 to 1_7
		P8_12, P8_11, P8_16, P8_15                             // GPIO1_13 to 1_15
// FINISHME - see (A)
	};

	EIndex  LC = 0;const int  LGPIO_Count = sizeof(LGPIOPins) / sizeof(SrBBPIN);const SrBBPIN*  LPin = LGPIOPins;for(;LC < LGPIO_Count;LC++, LPin++)
	{
		if(LPin->mux)
		{
			char  LCmdStr[256];sprintf(LCmdStr, "echo 7 > /sys/kernel/debug/omap_mux/%s", LPin->mux);
//printf("%s() %s:%d  '%s'\n", __FUNCTION__, __FILE__, __LINE__, LCmdStr);fflush(stdout);
			if(system(LCmdStr) != 0)
			{
				if(PVerbosity) { printf("%s() %s:%d %s%s failed%s\n", __FUNCTION__, __FILE__, __LINE__, ECodeRed, LCmdStr, ECodeNormal);fflush(stdout); }
			}
		}
	}
#endif


/*
// (A) These pins' MUX is not initialized yet
#define P8_7  { "TIMER4", GPIO2, 66, 2, "gpmc_advn_ale", 41, FALSE }
#define P8_8  { "TIMER7", GPIO2, 67, 3, "gpmc_oen_ren", 44, FALSE }
#define P8_9  { "TIMER5", GPIO2, 69, 5, "gpmc_ben0_cle", 42, FALSE }
#define P8_10 { "TIMER6", GPIO2, 68, 4, "gpmc_wen", 43, FALSE }
#define P8_13 { "EHRPWM2B", GPIO0, 23, 23, "gpmc_ad9", 15, TRUE, .PWM={4, "EHRPWM2B", "ehrpwm.2:1"}}
#define P8_14 { "GPIO0_26", GPIO0, 26, 26, "gpmc_ad10", 16, FALSE }
#define P8_17 { "GPIO0_27", GPIO0, 27, 27, "gpmc_ad11", 17, FALSE }
#define P8_18 { "GPIO2_1", GPIO2, 65, 1, "gpmc_clk", 40, FALSE }
#define P8_19 { "EHRPWM2A", GPIO0, 22, 22, "gpmc_ad8", 14, TRUE, .PWM={4, "EHRPWM2A", "ehrpwm.2:0"}}
#define P8_20 { "GPIO1_31", GPIO1, 63, 31, "gpmc_csn2", 39, FALSE }
#define P8_21 { "GPIO1_30", GPIO1, 62, 30, "gpmc_csn1", 38, FALSE }
#define P8_26 { "GPIO1_29", GPIO1, 61, 29, "gpmc_csn0", 37, FALSE }
#define P8_27 { "GPIO2_22", GPIO2, 86, 22, "lcd_vsync", 57, FALSE }
#define P8_28 { "GPIO2_24", GPIO2, 88, 24, "lcd_pclk", 59, FALSE }
#define P8_29 { "GPIO2_23", GPIO2, 87, 23, "lcd_hsync", 58, FALSE }
#define P8_30 { "GPIO2_25", GPIO2, 89, 25, "lcd_ac_bias_en", 60, FALSE }
#define P8_31 { "UART5_CTSN", GPIO0, 10, 10, "lcd_data14", 7, FALSE }
#define P8_32 { "UART5_RTSN", GPIO0, 11, 11, "lcd_data15", 8, FALSE }
#define P8_33 { "UART4_RTSN", GPIO0, 9, 9, "lcd_data13", 6, FALSE }
#define P8_34 { "UART3_RTSN", GPIO2, 81, 17, "lcd_data11", 56, TRUE, .PWM={2, "EHRPWM1B", "ehrpwm.1:1"}}
#define P8_35 { "UART4_CTSN", GPIO0, 8, 8, "lcd_data12", 5, FALSE }
#define P8_36 { "UART3_CTSN", GPIO2, 80, 16, "lcd_data10", 55, TRUE, .PWM={2, "EHRPWM1A", "ehrpwm.1:0"}}
#define P8_37 { "UART5_TXD", GPIO2, 78, 14, "lcd_data8", 53, FALSE }
#define P8_38 { "UART5_RXD", GPIO2, 79, 15, "lcd_data9", 54, FALSE }
#define P8_39 { "GPIO2_12", GPIO2, 76, 12, "lcd_data6", 51, FALSE }
#define P8_40 { "GPIO2_13", GPIO2, 77, 13, "lcd_data7", 52, FALSE }
#define P8_41 { "GPIO2_10", GPIO2, 74, 10, "lcd_data4", 49, FALSE }
#define P8_42 { "GPIO2_11", GPIO2, 75, 11, "lcd_data5", 50, FALSE }
#define P8_43 { "GPIO2_8", GPIO2, 72, 8, "lcd_data2", 47, FALSE }
#define P8_44 { "GPIO2_9", GPIO2, 73, 9, "lcd_data3", 48, FALSE }
#define P8_45 { "GPIO2_6", GPIO2, 70, 6, "lcd_data0", 45, TRUE, .PWM={3, "EHRPWM2A", "ehrpwm.2:0"}}
#define P8_46 { "GPIO2_7", GPIO2, 71, 7, "lcd_data1", 46, TRUE, .PWM={3, "EHRPWM2B", "ehrpwm.2:1"}}

#define P9_11 { "UART4_RXD", GPIO0, 30, 30, "gpmc_wait0", 18, FALSE }
#define P9_12 { "GPIO1_28", GPIO1, 60, 28, "gpmc_ben1", 36, FALSE }
#define P9_13 { "UART4_TXD", GPIO0, 31, 31, "gpmc_wpn", 19, FALSE }
#define P9_14 { "EHRPWM1A", GPIO1, 50, 18, "gpmc_a2", 34, TRUE, .PWM={6, "EHRPWM1A", "ehrpwm.1:0"}}
#define P9_15 { "GPIO1_16", GPIO1, 48, 16, "mii1_rxd3", 32, FALSE }
#define P9_16 { "EHRPWM1B", GPIO1, 51, 19, "gpmc_a3", 35, TRUE, .PWM={6, "EHRPWM1B", "ehrpwm.1:1"}}
#define P9_17 { "I2C1_SCL", GPIO0, 5, 5, "spi0_cs0", 3, FALSE }
#define P9_18 { "I2C1_SDA", GPIO0, 4, 4, "spi0_d1", 2, FALSE }
#define P9_19 { "I2C2_SCL", GPIO0, 13, 13, "uart1_rtsn", 9, FALSE }
#define P9_20 { "I2C2_SDA", GPIO0, 12, 12, "uart1_ctsn", 10, FALSE }
#define P9_21 { "UART2_TXD", GPIO0, 3, 3, "spi0_d0", 1, TRUE, .PWM={3, "EHRPWM0B", "ehrpwm.0:1"}}
#define P9_22 { "UART2_RXD", GPIO0, 2, 2, "spi0_sclk", 0, TRUE, .PWM={3, "EHRPWM0A", "ehrpwm.0:0"}}
#define P9_23 { "GPIO1_17", GPIO1, 49, 17, "gpmc_a1", 33, FALSE }
#define P9_24 { "UART1_TXD", GPIO0, 15, 15, "uart1_txd", 12, FALSE }
#define P9_25 { "GPIO3_21", GPIO3, 117, 21, "mcasp0_ahclkx", 66, FALSE }
#define P9_26 { "UART1_RXD", GPIO0, 14, 14, "uart1_rxd", 11, FALSE }
#define P9_27 { "GPIO3_19", GPIO3, 115, 19, "mcasp0_fsr", 64, FALSE }
#define P9_28 { "SPI1_CS0", GPIO3, 113, 17, "mcasp0_ahclkr", 63, TRUE, .PWM={4, "ECAPPWM2", "ecap.2"}}
#define P9_29 { "SPI1_D0", GPIO3, 111, 15, "mcasp0_fsx", 61, TRUE, .PWM={1, "EHRPWM0B", "ehrpwm.0:1"}}
#define P9_30 { "SPI1_D1", GPIO3, 112, 16, "mcasp0_axr0", 62, FALSE }
#define P9_31 { "SPI1_SCLK", GPIO3, 110, 14, "mcasp0_aclkx", 65, TRUE, .PWM={1, "EHRPWM0A", "ehrpwm.0:0"}}
#define P9_33 { "AIN4", 0, 4, 4, "", 71, FALSE }
#define P9_35 { "AIN6", 0, 6, 6, "", 73, FALSE }
#define P9_36 { "AIN5", 0, 5, 5, "", 72, FALSE }
#define P9_37 { "AIN2", 0, 2, 2, "", 69, FALSE }
#define P9_38 { "AIN3", 0, 3, 3, "", 70, FALSE }
#define P9_39 { "AIN0", 0, 0, 0, "", 67, FALSE }
#define P9_40 { "AIN1", 0, 1, 1, "", 68, FALSE }
#define P9_41 { "CLKOUT2", GPIO0, 20, 20, "xdma_event_intr1", 13, FALSE }
#define P9_42 { "GPIO0_7", GPIO0, 7, 7, "ecap0_in_pwm0_out", 4, TRUE, .PWM={0, "ECAPPWM0", "ecap.0"}}
*/


printf("%s() %s:%d  %sMapping GPIO%s\n", __FUNCTION__, __FILE__, __LINE__, ECodeGreen, ECodeNormal);fflush(stdout);

	PGPIO->Registers[0] = (ulong*)mmap(NULL, 0xFFF, PROT_READ | PROT_WRITE, MAP_SHARED, LGPIO_fd, SrGPIO0_START);if(PGPIO->Registers[0] == MAP_FAILED)
	{
		printf("GPIO0 Mapping failed\n");
		close(LGPIO_fd);
		return(E_NO_DATA);
	}

	PGPIO->Registers[1] = (ulong*)mmap(NULL, 0xFFF, PROT_READ | PROT_WRITE, MAP_SHARED, LGPIO_fd, SrGPIO1_START);if(PGPIO->Registers[1] == MAP_FAILED)
	{
		printf("GPIO1 Mapping failed\n");
		close(LGPIO_fd);
		return(E_NO_DATA);
	}

	PGPIO->Registers[2] = (ulong*)mmap(NULL, 0xFFF, PROT_READ | PROT_WRITE, MAP_SHARED, LGPIO_fd, SrGPIO2_START);if(PGPIO->Registers[2] == MAP_FAILED)
	{
		printf("GPIO2 Mapping failed\n");
		close(LGPIO_fd);
		return(E_NO_DATA);
	}

	PGPIO->Registers[3] = (ulong*)mmap(NULL, 0xFFF, PROT_READ | PROT_WRITE, MAP_SHARED, LGPIO_fd, SrGPIO3_START);if(PGPIO->Registers[3] == MAP_FAILED)
	{
		printf("GPIO3 Mapping failed\n");
		close(LGPIO_fd);
		return(E_NO_DATA);
	}

	PGPIO->FileDescriptor = LGPIO_fd;

	return(E_SUCCESS);
}


static inline int _BeagleBonePWMInit(SrPWM* PPWM)
{
	memset(PPWM, 0, sizeof(SrPWM));

	const int  LPWM_fd = open("/dev/mem", O_RDWR | O_SYNC);if(LPWM_fd < 0)
	{
		printf("%s() %s:%d  %sCould not open PWM memory fd%s\n", __FUNCTION__, __FILE__, __LINE__, ECodeRed, ECodeNormal);fflush(stdout);
		return(E_COULD_NOT_OPEN_FILE);
	}


// PWM configuration
//
printf("%s() %s:%d  %sMapping PWM%s\n", __FUNCTION__, __FILE__, __LINE__, ECodeGreen, ECodeNormal);fflush(stdout);

	PPWM->Registers = (ulong*)mmap(NULL, 0x48ffffff-SrBB_PWM_START, PROT_READ | PROT_WRITE, MAP_SHARED, LPWM_fd, SrBB_PWM_START);if(PPWM->Registers == MAP_FAILED)
	{
		printf("PWM0 Mapping failed\n");
		close(LPWM_fd);
		return(E_NO_DATA);
	}

	PPWM->FileDescriptor = LPWM_fd;

	return(E_SUCCESS);
}


extern void  Sr_GPIOTest(SrGPIO* PGPIO);

#endif // SR_BeagleBone_h
