From d0ac352ed689c278a3e863186d06d338cc869bd9 Mon Sep 17 00:00:00 2001
From: Rubberazer <47650457+Rubberazer@users.noreply.github.com>
Date: Sun, 23 Jun 2024 22:16:20 +0200
Subject: [PATCH] adding support for Orin AGX
---
README.md | 10 +-
docs/jetgpio.dox | 2 +-
get_chip_id.c | 22 +-
jetgpio.h | 72 +-
makefile | 7 +-
nano.c | 2 +-
orin.c | 4 +-
orinagx.c | 2735 ++++++++++++++++++++++++++++++++++++++++
scripts/pwm_enabler.sh | 1 +
9 files changed, 2828 insertions(+), 27 deletions(-)
create mode 100644 orinagx.c
diff --git a/README.md b/README.md
index 3cbe9d5..ab98684 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
C library to manage the GPIO header of the Nvidia JETSON boards
-[ORIN AGX WANTED TO EXPAND THE LIBRARY](https://github.com/Rubberazer/JETGPIO/discussions/21)
+[UPDATE: ORIN AGX SUPPORTED IN BETA](https://github.com/Rubberazer/JETGPIO/discussions/21)
FUNCTIONALITY:
@@ -13,11 +13,13 @@ C library to manage the GPIO header of the Nvidia JETSON boards
- JETSON ORIN NANO and ORIN NX
+ - JETSON ORIN AGX
+
- GPIO control of all the header pinout as input or output. Low latency, see also [The need for speed](#the-need-for-speed) below for some more information on this
- Catching rising or falling edges in any header pin working as input. Timestamp of the event in nanoseconds in epoch format is provided
-- PWM (hardware) control on header pins 32, 33 for all models and also 15 for Orin
+- PWM (hardware) control on header pins 32, 33 for all models and also 15 for Orin Nano/NX, for Orin AGX the pins are: 13, 15 & 18
- I2C serial communication over pins: 27 (SDA) & 28 (SCL) and 3 (SDA) & 5 (SCL)
@@ -112,7 +114,9 @@ https://jetsonhacks.com/nvidia-jetson-nano-j41-header-pinout/
https://jetsonhacks.com/nvidia-jetson-orin-nano-gpio-header-pinout/
-The library has been tested on a Jetson Nano: tegra210 (TX1) and on a Jetson Orin Nano: tegra234
+https://jetsonhacks.com/nvidia-jetson-agx-orin-gpio-header-pinout/
+
+The library has been tested on a Jetson Nano: tegra210 (TX1), on a Jetson Orin Nano: tegra234 and also on an Orin AGX.
diff --git a/docs/jetgpio.dox b/docs/jetgpio.dox
index 87c5a34..e87501c 100644
--- a/docs/jetgpio.dox
+++ b/docs/jetgpio.dox
@@ -48,7 +48,7 @@ PROJECT_NAME = Jetgpio
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.0
+PROJECT_NUMBER = 1.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/get_chip_id.c b/get_chip_id.c
index 4614b57..00d17e0 100644
--- a/get_chip_id.c
+++ b/get_chip_id.c
@@ -22,7 +22,10 @@ int chip_get_id(void) {
static void *baseMISC;
static volatile uint32_t *nano_get_id;
static volatile uint32_t *orin_get_id;
-
+ size_t page = sysconf(_SC_PAGESIZE);
+ size_t n_pages = sysconf(_SC_PHYS_PAGES);
+ size_t total_ram = page*n_pages/(1024*1024*1024);
+
fd_id = open("/dev/mem", O_RDWR | O_SYNC);
if (fd_id < 0) {
perror("/dev/mem");
@@ -49,9 +52,16 @@ int chip_get_id(void) {
// Trying for Orin first
if (((*orin_get_id >>8) & 0xFF) == 0x23) {
- model = ORIN;
- printf("T234/Orin detected\n");
+ if (total_ram > 24) {
+ model = ORINAGX;
+ printf("T234/Orin AGX detected\n");
+ }
+ else {
+ model = ORIN;
+ printf("T234/Orin Nano or NX detected\n");
+ }
}
+
// Trying for Nano Classic next
else if (((*nano_get_id >>8) & 0xFF) == 0x21) {
model = NANO;
@@ -83,6 +93,9 @@ int main (void) {
case ORIN:
strcpy(hardware, "orin");
break;
+ case ORINAGX:
+ strcpy(hardware, "orinagx");
+ break;
case NANO:
strcpy(hardware, "nano");
break;
@@ -92,9 +105,10 @@ int main (void) {
printf("\t\tJetson Nano\n");
printf("\t\tJetson Orin Nano\n");
printf("\t\tJetson Orin NX\n");
+ printf("\t\tJetson Orin AGX\n");
printf("\tAnd therefore supported, you can still force install with:\n");
printf("\t\tsudo make followed by sudo make install\n");
- printf("\te.g. sudo make orin\n");
+ printf("\te.g. sudo make orin to compile for Orin Nano or NX\n");
exit(EXIT_FAILURE);
}
FILE *fp = fopen("hardware", "w+");
diff --git a/jetgpio.h b/jetgpio.h
index 376a749..6093abc 100644
--- a/jetgpio.h
+++ b/jetgpio.h
@@ -21,7 +21,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
*/
-/* jetgpio version 1.0 */
+/* jetgpio version 1.1 */
/** @file jetgpio.h */
#ifndef jetgpio_h__
@@ -172,20 +172,22 @@ For more information, please refer to
/* GPIO base address Orin */
-#define base_CNF_AON 0x0c2f1000 // Base address Orin AON: 3,5,27,28
-#define base_CNF_NAON 0x02210000 // Base address Orin Non AON: 7,8,10,11,29,31,36,15,12,32,33,35,38,40,13,16,18,19,21,22,23,24,26,37
-#define Pinmux_AON 0x0c302000 // Pinmux + config GPIO Orin PADCTL_A14 pad: 3,5,27,28
-#define Pinmux_G7 0x02448000 // Pinmux + config GPIO Orin PADCTL_A24 pad: 7
-#define Pinmux_G3 0x02430000 // Pinmux + config GPIO Orin PADCTL_A0 pad: 8,10,11,29,31,36
-#define Pinmux_EDP 0x02440000 // Pinmux + config GPIO Orin PADCTL_A16 pad: 15
-#define Pinmux_G4 0x02434000 // Pinmux + config GPIO Orin PADCTL_A4 pad: 12,32,33,35,38,40
-#define Pinmux_G2 0x0243d000 // Pinmux + config GPIO Orin PADCTL_A13 pad: 13,16,18,19,21,22,23,24,26,37
+#define base_CNF_AON 0x0c2f1000 // Base address Nano AON: 3,5,27,28 AGX: 3,5,16,27,28,29,31,32,33,37
+#define base_CNF_NAON 0x02210000 // Base address Nano Non AON: 7,8,10,11,29,31,36,15,12,32,33,35,38,40,13,16,18,19,21,22,23,24,26,37 AGX: 7,8,10,11,36,15,12,35,38,40,13,18,19,21,22,23,24,26
+#define Pinmux_AON 0x0c302000 // Pinmux + config GPIO PADCTL_A14 pad Nano & AGX: 3,5,27,28
+#define Pinmux_AONHV 0x0c303000 // Pinmux + config GPIO PADCTL_A15 pad AGX: 29,31,33,37
+#define Pinmux_G7 0x02448000 // Pinmux + config GPIO PADCTL_A24 pad Nano: 7
+#define Pinmux_G3 0x02430000 // Pinmux + config GPIO PADCTL_A0 pad Nano: 8,10,11,29,31,36 AGX: 8,10,11,13,22,26
+#define Pinmux_EDP 0x02440000 // Pinmux + config GPIO PADCTL_A16 pad Nano & AGX: 15
+#define Pinmux_G4 0x02434000 // Pinmux + config GPIO PADCTL_A4 pad Nano: 12,32,33,35,38,40 AGX: 18
+#define Pinmux_G2 0x0243d000 // Pinmux + config GPIO PADCTL_A13 pad Nano: 13,16,18,19,21,22,23,24,26,37 AGX: 19,21,23,24,26
/* PWM Control Orin */
-#define base_PWM1 0x03280000 // PWM1 Controller base address pin 15
-#define base_PWM5 0x032c0000 // PWM5 Controller base address pin 33
-#define base_PWM7 0x032e0000 // PWM7 Controller base address pin 32
+#define base_PWM1 0x03280000 // PWM1 Controller base address Nano & AGX: pin 15
+#define base_PWM5 0x032c0000 // PWM5 Controller base address Nano: pin 33, AGX: pin 18
+#define base_PWM7 0x032e0000 // PWM7 Controller base address Nano: pin 32
+#define base_PWM8 0x032f0000 // PWM8 Controller base address AGX: pin 13
/* GPIO CNF registers Orin */
@@ -280,6 +282,45 @@ For more information, please refer to
#define CFGO_38 0x9c // Config 38 G4_CFG2TMC_SOC_GPIO43_0
#define CFGO_40 0x94 // Config 40 G4_CFG2TMC_SOC_GPIO42_0
+/* GPIO CNF registers Orin AGX */
+
+#define CNFOX_7 0x026c0 // Pin 7 G3_SOC_GPIO33_0
+#define CNFOX_13 0x02800 // Pin 13 G3_SOC_GPIO37_0
+#define CNFOX_16 0x0a20 // Pin 16 AO_HV_CAN1_EN_0
+#define CNFOX_18 0x04200 // Pin 18 G4_SOC_GPIO21_0
+#define CNFOX_22 0x02480 // Pin 22 G3_SOC_GPIO23_0
+#define CNFOX_29 0x0820 // Pin 29 AO_HV_CAN0_DIN_0
+#define CNFOX_31 0x0800 // Pin 31 AO_HV_CAN0_DOUT_0
+#define CNFOX_32 0x0a00 // Pin 32 AO_HV_CAN1_STB_0
+#define CNFOX_33 0x0840 // Pin 33 AO_HV_CAN1_DOUT_0
+#define CNFOX_37 0x0860 // Pin 37 AO_HV_CAN1_DIN_0
+
+/* GPIO Pinmux registers Orin AGX */
+
+#define PINMUXOX_7 0x70 // Pinmux 7 G3_SOC_GPIO33_0
+#define PINMUXOX_13 0x80 // Pinmux 13 G3_SOC_GPIO37_0
+#define PINMUXOX_16 0x48 // Pinmux 16 AO_HV_CAN1_EN_0
+#define PINMUXOX_18 0x40 // Pinmux 18 G4_SOC_GPIO21_0
+#define PINMUXOX_22 0x20 // Pinmux 22 G3_SOC_GPIO23_0
+#define PINMUXOX_29 0x18 // Pinmux 29 AO_HV_CAN0_DIN_0
+#define PINMUXOX_31 0x10 // Pinmux 31 AO_HV_CAN0_DOUT_0
+#define PINMUXOX_32 0x40 // Pinmux 32 AO_HV_CAN1_STB_0
+#define PINMUXOX_33 0X0 // Pinmux 33 AO_HV_CAN1_DOUT_0
+#define PINMUXOX_37 0x8 // Pinmux 37 AO_HV_CAN1_DIN_0
+
+/* GPIO Cfg registers Orin AGX */
+
+#define CFGOX_7 0x74 // Config 7 G3_CFG2TMC_SOC_GPIO33_0
+#define CFGOX_13 0x84 // Config 13 G3_CFG2TMC_SOC_GPIO37_0
+#define CFGOX_16 0x4c // Config 16 AO_HV_CFG2TMC_CAN1_EN_0
+#define CFGOX_18 0x44 // Config 18 G4_CFG2TMC_SOC_GPIO21_0
+#define CFGOX_22 0x24 // Config 22 G3_CFG2TMC_SOC_GPIO23_0
+#define CFGOX_29 0x1c // Config 29 AO_HV_CFG2TMC_CAN0_DIN_0
+#define CFGOX_31 0x14 // Config 31 AO_HV_CFG2TMC_CAN0_DOUT_0
+#define CFGOX_32 0x44 // Config 32 AO_HV_CFG2TMC_CAN1_STB_0
+#define CFGOX_33 0x4 // Config 33 AO_HV_CFG2TMC_CAN1_DOUT_0
+#define CFGOX_37 0xc // Config 37 AO_HV_CFG2TMC_CAN1_DIN_0
+
/* Typical values Pinmux & Cfg registers Orin */
#define CNFO_IN 0x00000001 // Typical for CNF register as input
@@ -295,6 +336,7 @@ For more information, please refer to
#define NANO 210
#define ORIN 234
+#define ORINAGX 235
/* Define typical input/output */
@@ -495,7 +537,7 @@ int gpioSetISRFunc(unsigned gpio, unsigned edge, unsigned debounce, unsigned lon
int gpioSetPWMfrequency(unsigned gpio, unsigned frequency);
/**<
* @brief Sets the frequency in hertz to be used for the GPIO.
- * @param gpio (15 Orin only), 32, 33
+ * @param gpio Nano: 32, 33 Orin Nano,NX: 15, 32, 33 Orin AGX: 13, 15, 18
* @param frequency 25Hz to 187 kHz on Nano and 50 Hz to 1593 kHz on Orin
* @return Returns 1 if OK, a negative number otherwise
*
@@ -506,7 +548,7 @@ int gpioPWM(unsigned gpio, unsigned dutycycle);
/**<
* @brief Starts PWM on the GPIO, dutycycle between 0 (off) and range (fully on).
* Arduino style: analogWrite
- * @param gpio (15 Orin only), 32, 33
+ * @param gpio Nano: 32, 33 Orin Nano,NX: 15, 32, 33 Orin AGX: 13, 15, 18
* @param dutycycle: 0-256 (0 to 100%)
* @return Returns 0 if OK, a negative number otherwise
*
@@ -589,7 +631,7 @@ int spiOpen(unsigned spiChan, unsigned speed, unsigned mode, unsigned cs_delay,
/**<
* @brief This function returns a handle for the SPI device on the channel.
* Data will be transferred at baud bits per second. The flags may be used to modify the default behaviour of a 4-wire operation, mode 0, active low chip select.
- * There are 2 SPI channels called SPI1 & SPI2 on Nano and SPI0 & SPI1 on Orin.
+ * There are 2 SPI channels called SPI1 & SPI2 on Nano and SPI0 & SPI1 on Orin Nano & NX. For Orin AGX there is only 1 PSI channel: SPI0.
* The pins used are given in the following table.
*
* |Port |MISO |MOSI |SCLK |CS0 |CS1 |
diff --git a/makefile b/makefile
index 65aee4a..2b0566f 100644
--- a/makefile
+++ b/makefile
@@ -27,7 +27,7 @@ step4:
install -m 0644 jetgpio.h /usr/include
ldconfig
ldconfig -p | grep libjetgpio.so
- @if [ $(MODEL) == orin ]; then\
+ @if (( $(MODEL) == orin || $(MODEL) == orinagx )); then\
cp ./scripts/pwm_enabler.sh /etc/systemd/system;\
cp ./scripts/pwm_enable.service /etc/systemd/system;\
chmod +x /etc/systemd/system/pwm_enabler.sh;\
@@ -59,6 +59,11 @@ orin:
$(CC) $(LDFLAGS) -o $(LIB) orin.o $(LIBS)
@echo orin > ./hardware
+orinagx:
+ $(CC) $(CFLAGS) orinagx.c
+ $(CC) $(LDFLAGS) -o $(LIB) orinagx.o $(LIBS)
+ @echo orinagx > ./hardware
+
clean:
rm -f *.o $(LIB) get_chip_id hardware
diff --git a/nano.c b/nano.c
index 33ff9bf..7f3852f 100644
--- a/nano.c
+++ b/nano.c
@@ -21,7 +21,7 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
*/
-/* jetgpio version 1.0 */
+/* jetgpio version 1.1 */
/* Nano classic extension */
#include
diff --git a/orin.c b/orin.c
index 7d0582d..7edcfe1 100644
--- a/orin.c
+++ b/orin.c
@@ -21,8 +21,8 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to
*/
-/* jetgpio version 1.0 */
-/* Orin extension */
+/* jetgpio version 1.1 */
+/* Orin Nano & NX extension */
#include
#include
diff --git a/orinagx.c b/orinagx.c
new file mode 100644
index 0000000..f365c85
--- /dev/null
+++ b/orinagx.c
@@ -0,0 +1,2735 @@
+/*
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+For more information, please refer to
+*/
+
+/* jetgpio version 1.1 */
+/* Orin AGX extension */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "jetgpio.h"
+
+#define BILLION 1000000000L
+
+static int fd_GPIO;
+
+static volatile GPIO_CNF_Init pin_CNF;
+static volatile GPIO_CNF_Init pin_DEB;
+static volatile GPIO_CNF_Init pin_IN;
+static volatile GPIO_CNF_Init pin_OUT;
+static volatile GPIO_CNF_Init pin_OUT_VLE;
+static volatile GPIO_CNF_Init pin_INT_CLR;
+static volatile GPIO_CNF_Init pin_MUX;
+static volatile GPIO_CNF_Init pin_CFG;
+
+PISRFunc ISRFunc_CFG[41];
+
+static volatile uint32_t *PWM1;
+static volatile uint32_t *PWM5;
+static volatile uint32_t *PWM8;
+static volatile uint32_t PWM1_Init;
+static volatile uint32_t PWM5_Init;
+static volatile uint32_t PWM8_Init;
+
+static i2cInfo_t i2cInfo[8];
+static int i2c_speed[8];
+
+static SPIInfo_t SpiInfo[1];
+
+static volatile GPIO_CNFO *pin3;
+static volatile GPIO_CNFO *pin5;
+static volatile GPIO_CNFO *pin7;
+static volatile GPIO_CNFO *pin8;
+static volatile GPIO_CNFO *pin10;
+static volatile GPIO_CNFO *pin11;
+static volatile GPIO_CNFO *pin12;
+static volatile GPIO_CNFO *pin13;
+static volatile GPIO_CNFO *pin15;
+static volatile GPIO_CNFO *pin16;
+static volatile GPIO_CNFO *pin18;
+static volatile GPIO_CNFO *pin19;
+static volatile GPIO_CNFO *pin21;
+static volatile GPIO_CNFO *pin22;
+static volatile GPIO_CNFO *pin23;
+static volatile GPIO_CNFO *pin24;
+static volatile GPIO_CNFO *pin26;
+static volatile GPIO_CNFO *pin27;
+static volatile GPIO_CNFO *pin28;
+static volatile GPIO_CNFO *pin29;
+static volatile GPIO_CNFO *pin31;
+static volatile GPIO_CNFO *pin32;
+static volatile GPIO_CNFO *pin33;
+static volatile GPIO_CNFO *pin35;
+static volatile GPIO_CNFO *pin36;
+static volatile GPIO_CNFO *pin37;
+static volatile GPIO_CNFO *pin38;
+static volatile GPIO_CNFO *pin40;
+
+static volatile uint32_t *pinmux3;
+static volatile uint32_t *pinmux5;
+static volatile uint32_t *pinmux7;
+static volatile uint32_t *pinmux8;
+static volatile uint32_t *pinmux10;
+static volatile uint32_t *pinmux11;
+static volatile uint32_t *pinmux12;
+static volatile uint32_t *pinmux13;
+static volatile uint32_t *pinmux15;
+static volatile uint32_t *pinmux16;
+static volatile uint32_t *pinmux18;
+static volatile uint32_t *pinmux19;
+static volatile uint32_t *pinmux21;
+static volatile uint32_t *pinmux22;
+static volatile uint32_t *pinmux23;
+static volatile uint32_t *pinmux24;
+static volatile uint32_t *pinmux26;
+static volatile uint32_t *pinmux27;
+static volatile uint32_t *pinmux28;
+static volatile uint32_t *pinmux29;
+static volatile uint32_t *pinmux31;
+static volatile uint32_t *pinmux32;
+static volatile uint32_t *pinmux33;
+static volatile uint32_t *pinmux35;
+static volatile uint32_t *pinmux36;
+static volatile uint32_t *pinmux37;
+static volatile uint32_t *pinmux38;
+static volatile uint32_t *pinmux40;
+
+static volatile uint32_t *pincfg3;
+static volatile uint32_t *pincfg5;
+static volatile uint32_t *pincfg7;
+static volatile uint32_t *pincfg8;
+static volatile uint32_t *pincfg10;
+static volatile uint32_t *pincfg11;
+static volatile uint32_t *pincfg12;
+static volatile uint32_t *pincfg13;
+static volatile uint32_t *pincfg15;
+static volatile uint32_t *pincfg16;
+static volatile uint32_t *pincfg18;
+static volatile uint32_t *pincfg19;
+static volatile uint32_t *pincfg21;
+static volatile uint32_t *pincfg22;
+static volatile uint32_t *pincfg23;
+static volatile uint32_t *pincfg24;
+static volatile uint32_t *pincfg26;
+static volatile uint32_t *pincfg27;
+static volatile uint32_t *pincfg28;
+static volatile uint32_t *pincfg29;
+static volatile uint32_t *pincfg31;
+static volatile uint32_t *pincfg32;
+static volatile uint32_t *pincfg33;
+static volatile uint32_t *pincfg35;
+static volatile uint32_t *pincfg36;
+static volatile uint32_t *pincfg37;
+static volatile uint32_t *pincfg38;
+static volatile uint32_t *pincfg40;
+
+static void *baseCNF_AON;
+static void *baseCNF_NAON;
+
+static void *basePINMUX_AON;
+static void *basePINMUX_AONHV;
+static void *basePINMUX_G7;
+static void *basePINMUX_G3;
+static void *basePINMUX_EDP;
+static void *basePINMUX_G4;
+static void *basePINMUX_G2;
+
+static void *basePWM1;
+static void *basePWM5;
+static void *basePWM8;
+static unsigned clk_rate_PWM1 = 408000000;
+static unsigned clk_rate_PWM5 = 408000000;
+static unsigned clk_rate_PWM8 = 408000000;
+
+static volatile unsigned global_int;
+static pthread_t callThd[28];
+static pthread_attr_t attr;
+static int pth_err;
+static void *status_thread;
+static int thread_n = 0;
+static unsigned long long pin_tracker = 0;
+
+int gpioInitialise(void)
+{
+ int status = 1;
+ // Getting the page size
+ int pagesize = sysconf(_SC_PAGESIZE);
+
+ // read physical memory (needs root)
+ fd_GPIO = open("/dev/mem", O_RDWR | O_SYNC);
+ if (fd_GPIO < 0) {
+ perror("/dev/mem");
+ fprintf(stderr, "Please run this program as root (for example with sudo)\n");
+ return -1;
+ }
+ // Mapping GPIO_CNF_AON
+ baseCNF_AON = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, base_CNF_AON);
+ if (baseCNF_AON == MAP_FAILED) {
+ return -2;
+ }
+
+ // Mapping GPIO_CNF_NAON
+ baseCNF_NAON = mmap(0, 5 * pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, base_CNF_NAON);
+ if (baseCNF_NAON == MAP_FAILED) {
+ return -3;
+ }
+
+ // Mapping PINMUX_AON
+ basePINMUX_AON = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, Pinmux_AON);
+ if (basePINMUX_AON == MAP_FAILED) {
+ return -4;
+ }
+
+ // Mapping PINMUX_AONHV
+ basePINMUX_AONHV = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, Pinmux_AONHV);
+ if (basePINMUX_AONHV == MAP_FAILED) {
+ return -5;
+ }
+
+ // Mapping PINMUX_G7
+ basePINMUX_G7 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, Pinmux_G7);
+ if (basePINMUX_G7 == MAP_FAILED) {
+ return -6;
+ }
+
+ // Mapping PINMUX_G3
+ basePINMUX_G3 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, Pinmux_G3);
+ if (basePINMUX_G3 == MAP_FAILED) {
+ return -7;
+ }
+
+ // Mapping PINMUX_EDP
+ basePINMUX_EDP = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, Pinmux_EDP);
+ if (basePINMUX_EDP == MAP_FAILED) {
+ return -8;
+ }
+
+ // Mapping PINMUX_G4
+ basePINMUX_G4 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, Pinmux_G4);
+ if (basePINMUX_G4 == MAP_FAILED) {
+ return -9;
+ }
+
+ // Mapping PINMUX_G2
+ basePINMUX_G2 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, Pinmux_G2);
+ if (basePINMUX_G2 == MAP_FAILED) {
+ return -10;
+ }
+
+ // Mapping PWM1
+ basePWM1 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, base_PWM1);
+ if (basePWM1 == MAP_FAILED) {
+ return -11;
+ }
+
+ // Mapping PWM5
+ basePWM5 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, base_PWM5);
+ if (basePWM5 == MAP_FAILED) {
+ return -12;
+ }
+
+ // Mapping PWM8
+ basePWM8 = mmap(0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd_GPIO, base_PWM8);
+ if (basePWM8 == MAP_FAILED) {
+ return -13;
+ }
+
+ // Pointer to CNFO_3
+ pin3 = (GPIO_CNFO volatile *)((char *)baseCNF_AON + CNFO_3);
+ pin_CNF.pin3 = pin3->CNF[0];
+ pin_DEB.pin3 = pin3->DEB[0];
+ pin_IN.pin3 = pin3->IN[0];
+ pin_OUT.pin3 = pin3->OUT[0];
+ pin_OUT_VLE.pin3 = pin3->OUT_VLE[0];
+
+ // Pointer to PINMUX3
+ pinmux3 = (uint32_t volatile *)((char *)basePINMUX_AON + PINMUXO_3);
+ pin_MUX.pin3 = *pinmux3;
+
+ // Pointer to PINCFG3
+ pincfg3 = (uint32_t volatile *)((char *)basePINMUX_AON + CFGO_3);
+ pin_CFG.pin3 = *pincfg3;
+
+ // Pointer to CNF5
+ pin5 = (GPIO_CNFO volatile *)((char *)baseCNF_AON + CNFO_5);
+ pin_CNF.pin5 = pin5->CNF[0];
+ pin_DEB.pin5 = pin5->DEB[0];
+ pin_IN.pin5 = pin5->IN[0];
+ pin_OUT.pin5 = pin5->OUT[0];
+ pin_OUT_VLE.pin5 = pin5->OUT_VLE[0];
+
+ // Pointer to PINMUX5
+ pinmux5 = (uint32_t volatile *)((char *)basePINMUX_AON + PINMUXO_5);
+ pin_MUX.pin5 = *pinmux5;
+
+ // Pointer to PINCFG5
+ pincfg5 = (uint32_t volatile *)((char *)basePINMUX_AON + CFGO_5);
+ pin_CFG.pin5 = *pincfg5;
+
+ // Pointer to CNF7
+ pin7 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFOX_7);
+ pin_CNF.pin7 = pin7->CNF[0];
+ pin_DEB.pin7 = pin7->DEB[0];
+ pin_IN.pin7 = pin7->IN[0];
+ pin_OUT.pin7 = pin7->OUT[0];
+ pin_OUT_VLE.pin7 = pin7->OUT_VLE[0];
+
+ // Pointer to PINMUX7
+ pinmux7 = (uint32_t volatile *)((char *)basePINMUX_G3 + PINMUXOX_7);
+ pin_MUX.pin7 = *pinmux7;
+
+ // Pointer to PINCFG7
+ pincfg7 = (uint32_t volatile *)((char *)basePINMUX_G3 + CFGOX_7);
+ pin_CFG.pin7 = *pincfg7;
+
+ // Pointer to CNF8
+ pin8 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_8);
+ pin_CNF.pin8 = pin8->CNF[0];
+ pin_DEB.pin8 = pin8->DEB[0];
+ pin_IN.pin8 = pin8->IN[0];
+ pin_OUT.pin8 = pin8->OUT[0];
+ pin_OUT_VLE.pin8 = pin8->OUT_VLE[0];
+
+ // Pointer to PINMUX8
+ pinmux8 = (uint32_t volatile *)((char *)basePINMUX_G3 + PINMUXO_8);
+ pin_MUX.pin8 = *pinmux8;
+
+ // Pointer to PINCFG8
+ pincfg8 = (uint32_t volatile *)((char *)basePINMUX_G3 + CFGO_8);
+ pin_CFG.pin8 = *pincfg8;
+
+ // Pointer to CNF10
+ pin10 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_10);
+ pin_CNF.pin10 = pin10->CNF[0];
+ pin_DEB.pin10 = pin10->DEB[0];
+ pin_IN.pin10 = pin10->IN[0];
+ pin_OUT.pin10 = pin10->OUT[0];
+ pin_OUT_VLE.pin10 = pin10->OUT_VLE[0];
+
+ // Pointer to PINMUX10
+ pinmux10 = (uint32_t volatile *)((char *)basePINMUX_G3 + PINMUXO_10);
+ pin_MUX.pin10 = *pinmux10;
+
+ // Pointer to PINCFG10
+ pincfg10 = (uint32_t volatile *)((char *)basePINMUX_G3 + CFGO_10);
+ pin_CFG.pin10 = *pincfg10;
+
+ // Pointer to CNF11
+ pin11 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_11);
+ pin_CNF.pin11 = pin11->CNF[0];
+ pin_DEB.pin11 = pin11->DEB[0];
+ pin_IN.pin11 = pin11->IN[0];
+ pin_OUT.pin11 = pin11->OUT[0];
+ pin_OUT_VLE.pin11 = pin11->OUT_VLE[0];
+
+ // Pointer to PINMUX11
+ pinmux11 = (uint32_t volatile *)((char *)basePINMUX_G3 + PINMUXO_11);
+ pin_MUX.pin11 = *pinmux11;
+
+ // Pointer to PINCFG11
+ pincfg11 = (uint32_t volatile *)((char *)basePINMUX_G3 + CFGO_11);
+ pin_CFG.pin11 = *pincfg11;
+
+ // Pointer to CNF12
+ pin12 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_12);
+ pin_CNF.pin12 = pin12->CNF[0];
+ pin_DEB.pin12 = pin12->DEB[0];
+ pin_IN.pin12 = pin12->IN[0];
+ pin_OUT.pin12 = pin12->OUT[0];
+ pin_OUT_VLE.pin12 = pin12->OUT_VLE[0];
+
+ // Pointer to PINMUX12
+ pinmux12 = (uint32_t volatile *)((char *)basePINMUX_G4 + PINMUXO_12);
+ pin_MUX.pin12 = *pinmux12;
+
+ // Pointer to PINCFG12
+ pincfg12 = (uint32_t volatile *)((char *)basePINMUX_G4 + CFGO_12);
+ pin_CFG.pin12 = *pincfg12;
+
+ // Pointer to CNF13
+ pin13 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFOX_13);
+ pin_CNF.pin13 = pin13->CNF[0];
+ pin_DEB.pin13 = pin13->DEB[0];
+ pin_IN.pin13 = pin13->IN[0];
+ pin_OUT.pin13 = pin13->OUT[0];
+ pin_OUT_VLE.pin13 = pin13->OUT_VLE[0];
+
+ // Pointer to PINMUX13
+ pinmux13 = (uint32_t volatile *)((char *)basePINMUX_G3 + PINMUXOX_13);
+ pin_MUX.pin13 = *pinmux13;
+
+ // Pointer to PINCFG13
+ pincfg13 = (uint32_t volatile *)((char *)basePINMUX_G3 + CFGOX_13);
+ pin_CFG.pin13 = *pincfg13;
+
+ // Pointer to CNF15
+ pin15 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_15);
+ pin_CNF.pin15 = pin15->CNF[0];
+ pin_DEB.pin15 = pin15->DEB[0];
+ pin_IN.pin15 = pin15->IN[0];
+ pin_OUT.pin15 = pin15->OUT[0];
+ pin_OUT_VLE.pin15 = pin15->OUT_VLE[0];
+
+ // Pointer to PINMUX15
+ pinmux15 = (uint32_t volatile *)((char *)basePINMUX_EDP + PINMUXO_15);
+ pin_MUX.pin15 = *pinmux15;
+
+ // Pointer to PINCFG15
+ pincfg15 = (uint32_t volatile *)((char *)basePINMUX_EDP + CFGO_15);
+ pin_CFG.pin15 = *pincfg15;
+
+ // Pointer to CNF16
+ pin16 = (GPIO_CNFO volatile *)((char *)baseCNF_AON + CNFOX_16);
+ pin_CNF.pin16 = pin16->CNF[0];
+ pin_DEB.pin16 = pin16->DEB[0];
+ pin_IN.pin16 = pin16->IN[0];
+ pin_OUT.pin16 = pin16->OUT[0];
+ pin_OUT_VLE.pin16 = pin16->OUT_VLE[0];
+
+ // Pointer to PINMUX16
+ pinmux16 = (uint32_t volatile *)((char *)basePINMUX_AONHV + PINMUXOX_16);
+ pin_MUX.pin16 = *pinmux16;
+
+ // Pointer to PINCFG16
+ pincfg16 = (uint32_t volatile *)((char *)basePINMUX_AONHV + CFGOX_16);
+ pin_CFG.pin16 = *pincfg16;
+
+ // Pointer to CNF18
+ pin18 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFOX_18);
+ pin_CNF.pin18 = pin18->CNF[0];
+ pin_DEB.pin18 = pin18->DEB[0];
+ pin_IN.pin18 = pin18->IN[0];
+ pin_OUT.pin18 = pin18->OUT[0];
+ pin_OUT_VLE.pin18 = pin18->OUT_VLE[0];
+
+ // Pointer to PINMUX18
+ pinmux18 = (uint32_t volatile *)((char *)basePINMUX_G4 + PINMUXOX_18);
+ pin_MUX.pin18 = *pinmux18;
+
+ // Pointer to PINCFG18
+ pincfg18 = (uint32_t volatile *)((char *)basePINMUX_G4 + CFGOX_18);
+ pin_CFG.pin18 = *pincfg18;
+
+ // Pointer to CNF19
+ pin19 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_19);
+ pin_CNF.pin19 = pin19->CNF[0];
+ pin_DEB.pin19 = pin19->DEB[0];
+ pin_IN.pin19 = pin19->IN[0];
+ pin_OUT.pin19 = pin19->OUT[0];
+ pin_OUT_VLE.pin19 = pin19->OUT_VLE[0];
+
+ // Pointer to PINMUX19
+ pinmux19 = (uint32_t volatile *)((char *)basePINMUX_G2 + PINMUXO_19);
+ pin_MUX.pin19 = *pinmux19;
+
+ // Pointer to PINCFG19
+ pincfg19 = (uint32_t volatile *)((char *)basePINMUX_G2 + CFGO_19);
+ pin_CFG.pin19 = *pincfg19;
+
+ // Pointer to CNF21
+ pin21 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_21);
+ pin_CNF.pin21 = pin21->CNF[0];
+ pin_DEB.pin21 = pin21->DEB[0];
+ pin_IN.pin21 = pin21->IN[0];
+ pin_OUT.pin21 = pin21->OUT[0];
+ pin_OUT_VLE.pin21 = pin21->OUT_VLE[0];
+
+ // Pointer to PINMUX21
+ pinmux21 = (uint32_t volatile *)((char *)basePINMUX_G2 + PINMUXO_21);
+ pin_MUX.pin21 = *pinmux21;
+
+ // Pointer to PINCFG21
+ pincfg21 = (uint32_t volatile *)((char *)basePINMUX_G2 + CFGO_21);
+ pin_CFG.pin21 = *pincfg21;
+
+ // Pointer to CNF22
+ pin22 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFOX_22);
+ pin_CNF.pin22 = pin22->CNF[0];
+ pin_DEB.pin22 = pin22->DEB[0];
+ pin_IN.pin22 = pin22->IN[0];
+ pin_OUT.pin22 = pin22->OUT[0];
+ pin_OUT_VLE.pin22 = pin22->OUT_VLE[0];
+
+ // Pointer to PINMUX22
+ pinmux22 = (uint32_t volatile *)((char *)basePINMUX_G3 + PINMUXOX_22);
+ pin_MUX.pin22 = *pinmux22;
+
+ // Pointer to PINCFG22
+ pincfg22 = (uint32_t volatile *)((char *)basePINMUX_G3 + CFGOX_22);
+ pin_CFG.pin22 = *pincfg22;
+
+ // Pointer to CNF23
+ pin23 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_23);
+ pin_CNF.pin23 = pin23->CNF[0];
+ pin_DEB.pin23 = pin23->DEB[0];
+ pin_IN.pin23 = pin23->IN[0];
+ pin_OUT.pin23 = pin23->OUT[0];
+ pin_OUT_VLE.pin23 = pin23->OUT_VLE[0];
+
+ // Pointer to PINMUX23
+ pinmux23 = (uint32_t volatile *)((char *)basePINMUX_G2 + PINMUXO_23);
+ pin_MUX.pin23 = *pinmux23;
+
+ // Pointer to PINCFG23
+ pincfg23 = (uint32_t volatile *)((char *)basePINMUX_G2 + CFGO_23);
+ pin_CFG.pin23 = *pincfg23;
+
+ // Pointer to CNF24
+ pin24 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_24);
+ pin_CNF.pin24 = pin24->CNF[0];
+ pin_DEB.pin24 = pin24->DEB[0];
+ pin_IN.pin24 = pin24->IN[0];
+ pin_OUT.pin24 = pin24->OUT[0];
+ pin_OUT_VLE.pin24 = pin24->OUT_VLE[0];
+
+ // Pointer to PINMUX24
+ pinmux24 = (uint32_t volatile *)((char *)basePINMUX_G2 + PINMUXO_24);
+ pin_MUX.pin24 = *pinmux24;
+
+ // Pointer to PINCFG24
+ pincfg24 = (uint32_t volatile *)((char *)basePINMUX_G2 + CFGO_24);
+ pin_CFG.pin24 = *pincfg24;
+
+ // Pointer to CNF26
+ pin26 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_26);
+ pin_CNF.pin26 = pin26->CNF[0];
+ pin_DEB.pin26 = pin26->DEB[0];
+ pin_IN.pin26 = pin26->IN[0];
+ pin_OUT.pin26 = pin26->OUT[0];
+ pin_OUT_VLE.pin26 = pin26->OUT_VLE[0];
+
+ // Pointer to PINMUX26
+ pinmux26 = (uint32_t volatile *)((char *)basePINMUX_G2 + PINMUXO_26);
+ pin_MUX.pin26 = *pinmux26;
+
+ // Pointer to PINCFG26
+ pincfg26 = (uint32_t volatile *)((char *)basePINMUX_G2 + CFGO_26);
+ pin_CFG.pin26 = *pincfg26;
+
+ // Pointer to CNF27
+ pin27 = (GPIO_CNFO volatile *)((char *)baseCNF_AON + CNFO_27);
+ pin_CNF.pin27 = pin27->CNF[0];
+ pin_DEB.pin27 = pin27->DEB[0];
+ pin_IN.pin27 = pin27->IN[0];
+ pin_OUT.pin27 = pin27->OUT[0];
+ pin_OUT_VLE.pin27 = pin27->OUT_VLE[0];
+
+ // Pointer to PINMUX27
+ pinmux27 = (uint32_t volatile *)((char *)basePINMUX_AON + PINMUXO_27);
+ pin_MUX.pin27 = *pinmux27;
+
+ // Pointer to PINCFG27
+ pincfg27 = (uint32_t volatile *)((char *)basePINMUX_AON + CFGO_27);
+ pin_CFG.pin27 = *pincfg27;
+
+ // Pointer to CNF28
+ pin28 = (GPIO_CNFO volatile *)((char *)baseCNF_AON + CNFO_28);
+ pin_CNF.pin28 = pin28->CNF[0];
+ pin_DEB.pin28 = pin28->DEB[0];
+ pin_IN.pin28 = pin28->IN[0];
+ pin_OUT.pin28 = pin28->OUT[0];
+ pin_OUT_VLE.pin28 = pin28->OUT_VLE[0];
+
+ // Pointer to PINMUX28
+ pinmux28 = (uint32_t volatile *)((char *)basePINMUX_AON + PINMUXO_28);
+ pin_MUX.pin28 = *pinmux28;
+
+ // Pointer to PINCFG28
+ pincfg28 = (uint32_t volatile *)((char *)basePINMUX_AON + CFGO_28);
+ pin_CFG.pin28 = *pincfg28;
+
+ // Pointer to CNF29
+ pin29 = (GPIO_CNFO volatile *)((char *)baseCNF_AON + CNFOX_29);
+ pin_CNF.pin29 = pin29->CNF[0];
+ pin_DEB.pin29 = pin29->DEB[0];
+ pin_IN.pin29 = pin29->IN[0];
+ pin_OUT.pin29 = pin29->OUT[0];
+ pin_OUT_VLE.pin29 = pin29->OUT_VLE[0];
+
+ // Pointer to PINMUX29
+ pinmux29 = (uint32_t volatile *)((char *)basePINMUX_AONHV + PINMUXOX_29);
+ pin_MUX.pin29 = *pinmux29;
+
+ // Pointer to PINCFG29
+ pincfg29 = (uint32_t volatile *)((char *)basePINMUX_AONHV + CFGOX_29);
+ pin_CFG.pin29 = *pincfg29;
+
+ // Pointer to CNF31
+ pin31 = (GPIO_CNFO volatile *)((char *)baseCNF_AON + CNFOX_31);
+ pin_CNF.pin31 = pin31->CNF[0];
+ pin_DEB.pin31 = pin31->DEB[0];
+ pin_IN.pin31 = pin31->IN[0];
+ pin_OUT.pin31 = pin31->OUT[0];
+ pin_OUT_VLE.pin31 = pin31->OUT_VLE[0];
+
+ // Pointer to PINMUX31
+ pinmux31 = (uint32_t volatile *)((char *)basePINMUX_AONHV + PINMUXOX_31);
+ pin_MUX.pin31 = *pinmux31;
+
+ // Pointer to PINCFG31
+ pincfg31 = (uint32_t volatile *)((char *)basePINMUX_AONHV + CFGOX_31);
+ pin_CFG.pin31 = *pincfg31;
+
+ // Pointer to CNF32
+ pin32 = (GPIO_CNFO volatile *)((char *)baseCNF_AON + CNFOX_32);
+ pin_CNF.pin32 = pin32->CNF[0];
+ pin_DEB.pin32 = pin32->DEB[0];
+ pin_IN.pin32 = pin32->IN[0];
+ pin_OUT.pin32 = pin32->OUT[0];
+ pin_OUT_VLE.pin32 = pin32->OUT_VLE[0];
+
+ // Pointer to PINMUX32
+ pinmux32 = (uint32_t volatile *)((char *)basePINMUX_AONHV + PINMUXOX_32);
+ pin_MUX.pin32 = *pinmux32;
+
+ // Pointer to PINCFG32
+ pincfg32 = (uint32_t volatile *)((char *)basePINMUX_AONHV + CFGOX_32);
+ pin_CFG.pin32 = *pincfg32;
+
+ // Pointer to CNF33
+ pin33 = (GPIO_CNFO volatile *)((char *)baseCNF_AON + CNFOX_33);
+ pin_CNF.pin33 = pin33->CNF[0];
+ pin_DEB.pin33 = pin33->DEB[0];
+ pin_IN.pin33 = pin33->IN[0];
+ pin_OUT.pin33 = pin33->OUT[0];
+ pin_OUT_VLE.pin33 = pin33->OUT_VLE[0];
+
+ // Pointer to PINMUX33
+ pinmux33 = (uint32_t volatile *)((char *)basePINMUX_AONHV + PINMUXOX_33);
+ pin_MUX.pin33 = *pinmux33;
+
+ // Pointer to PINCFG33
+ pincfg33 = (uint32_t volatile *)((char *)basePINMUX_AONHV + CFGOX_33);
+ pin_CFG.pin33 = *pincfg33;
+
+ // Pointer to CNF35
+ pin35 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_35);
+ pin_CNF.pin35 = pin35->CNF[0];
+ pin_DEB.pin35 = pin35->DEB[0];
+ pin_IN.pin35 = pin35->IN[0];
+ pin_OUT.pin35 = pin35->OUT[0];
+ pin_OUT_VLE.pin35 = pin35->OUT_VLE[0];
+
+ // Pointer to PINMUX35
+ pinmux35 = (uint32_t volatile *)((char *)basePINMUX_G4 + PINMUXO_35);
+ pin_MUX.pin35 = *pinmux35;
+
+ // Pointer to PINCFG35
+ pincfg35 = (uint32_t volatile *)((char *)basePINMUX_G4 + CFGO_35);
+ pin_CFG.pin35 = *pincfg35;
+
+ // Pointer to CNF36
+ pin36 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_36);
+ pin_CNF.pin36 = pin36->CNF[0];
+ pin_DEB.pin36 = pin36->DEB[0];
+ pin_IN.pin36 = pin36->IN[0];
+ pin_OUT.pin36 = pin36->OUT[0];
+ pin_OUT_VLE.pin36 = pin36->OUT_VLE[0];
+
+ // Pointer to PINMUX36
+ pinmux36 = (uint32_t volatile *)((char *)basePINMUX_G3 + PINMUXO_36);
+ pin_MUX.pin36 = *pinmux36;
+
+ // Pointer to PINCFG36
+ pincfg36 = (uint32_t volatile *)((char *)basePINMUX_G3 + CFGO_36);
+ pin_CFG.pin36 = *pincfg36;
+
+ // Pointer to CNF37
+ pin37 = (GPIO_CNFO volatile *)((char *)baseCNF_AON + CNFOX_37);
+ pin_CNF.pin37 = pin37->CNF[0];
+ pin_DEB.pin37 = pin37->DEB[0];
+ pin_IN.pin37 = pin37->IN[0];
+ pin_OUT.pin37 = pin37->OUT[0];
+ pin_OUT_VLE.pin37 = pin37->OUT_VLE[0];
+
+ // Pointer to PINMUX37
+ pinmux37 = (uint32_t volatile *)((char *)basePINMUX_AONHV + PINMUXOX_37);
+ pin_MUX.pin37 = *pinmux37;
+
+ // Pointer to PINCFG37
+ pincfg37 = (uint32_t volatile *)((char *)basePINMUX_AONHV + CFGOX_37);
+ pin_CFG.pin37 = *pincfg37;
+
+ // Pointer to CNF38
+ pin38 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_38);
+ pin_CNF.pin38 = pin38->CNF[0];
+ pin_DEB.pin38 = pin38->DEB[0];
+ pin_IN.pin38 = pin38->IN[0];
+ pin_OUT.pin38 = pin38->OUT[0];
+ pin_OUT_VLE.pin38 = pin38->OUT_VLE[0];
+
+ // Pointer to PINMUX38
+ pinmux38 = (uint32_t volatile *)((char *)basePINMUX_G4 + PINMUXO_38);
+ pin_MUX.pin38 = *pinmux38;
+
+ // Pointer to PINCFG38
+ pincfg38 = (uint32_t volatile *)((char *)basePINMUX_G4 + CFGO_38);
+ pin_CFG.pin38 = *pincfg38;
+
+ // Pointer to CNF40
+ pin40 = (GPIO_CNFO volatile *)((char *)baseCNF_NAON + CNFO_40);
+ pin_CNF.pin40 = pin40->CNF[0];
+ pin_DEB.pin40 = pin40->DEB[0];
+ pin_IN.pin40 = pin40->IN[0];
+ pin_OUT.pin40 = pin40->OUT[0];
+ pin_OUT_VLE.pin40 = pin40->OUT_VLE[0];
+
+ // Pointer to PINMUX40
+ pinmux40 = (uint32_t volatile *)((char *)basePINMUX_G4 + PINMUXO_40);
+ pin_MUX.pin40 = *pinmux40;
+
+ // Pointer to PINCFG40
+ pincfg40 = (uint32_t volatile *)((char *)basePINMUX_G4 + CFGO_40);
+ pin_CFG.pin40 = *pincfg40;
+
+ // Pointer to PWM1
+ PWM1 = (uint32_t volatile *)((char *)basePWM1);
+ PWM1_Init = *PWM1;
+
+ // Pointer to PWM5
+ PWM5 = (uint32_t volatile *)((char *)basePWM5);
+ PWM5_Init = *PWM5;
+
+ // Pointer to PWM8
+ PWM8 = (uint32_t volatile *)((char *)basePWM8);
+ PWM8_Init = *PWM8;
+
+ // Initialize i2c
+ i2cInfo[1].state = I2C_CLOSED;
+ i2cInfo[7].state = I2C_CLOSED;
+
+ // Initialize spi
+ SpiInfo[0].state = SPI_CLOSED;
+ SpiInfo[2].state = SPI_CLOSED;
+
+ // Global interrupt variable
+ global_int = 1;
+
+ // Allocating memory for the struct
+ for (int j = 0; j < 41; j++) {
+ ISRFunc_CFG[j] = calloc (1, sizeof(ISRFunc));
+ }
+ return status;
+}
+
+void gpioTerminate(void) {
+ // Stopping threads
+ global_int = 0;
+
+ // Cancelling threads to avoid blocking on read()
+ for(int i = 0;i < thread_n; i++) {
+ pthread_cancel(callThd[i]);
+ //printf("Thread number: %d cancelled\n",i);
+ }
+
+ //Joining threads
+ for(int j = 0;j < thread_n; j++) {
+ pthread_join(callThd[j], &status_thread);
+ //printf("Thread number: %d joined\n",j);
+ }
+
+ // Free allocated memory
+ for (int k = 0; k < 41; k++) {
+ free(ISRFunc_CFG[k]);
+ }
+
+ int pagesize = sysconf(_SC_PAGESIZE);
+ // Restoring registers to their previous state
+
+ if ((pin_tracker >> 28) & 1) {
+ *PWM1 = PWM1_Init;
+ char buf[100];
+
+ snprintf(buf, sizeof(buf), "echo %u > /sys/kernel/debug/bpmp/debug/clk/pwm1/rate", clk_rate_PWM1);
+ if (system(buf) == -1) {
+ printf( "Not possible to change clock rate on pwm1\n");
+ }
+ }
+
+ if ((pin_tracker >> 29) & 1) {
+ *PWM5 = PWM5_Init;
+ char buf[100];
+
+ snprintf(buf, sizeof(buf), "echo %u > /sys/kernel/debug/bpmp/debug/clk/pwm5/rate", clk_rate_PWM5);
+ if (system(buf) == -1) {
+ printf( "Not possible to change clock rate on pwm5\n");
+ }
+ }
+
+ if ((pin_tracker >> 30) & 1) {
+ *PWM8 = PWM8_Init;
+ char buf[100];
+
+ snprintf(buf, sizeof(buf), "echo %u > /sys/kernel/debug/bpmp/debug/clk/pwm8/rate", clk_rate_PWM8);
+ if (system(buf) == -1) {
+ printf( "Not possible to change clock rate on pwm8\n");
+ }
+ }
+
+ if (pin_tracker & 1) {
+ pin3->CNF[0] = pin_CNF.pin3;
+ pin3->DEB[0] = pin_DEB.pin3;
+ pin3->IN[0] = pin_IN.pin3;
+ pin3->OUT[0] = pin_OUT.pin3;
+ pin3->OUT_VLE[0] = pin_OUT_VLE.pin3;
+ *pinmux3 = pin_MUX.pin3;
+ *pincfg3 = pin_CFG.pin3;
+ }
+
+ if ((pin_tracker >> 1) & 1) {
+ pin5->CNF[0] = pin_CNF.pin5;
+ pin5->DEB[0] = pin_DEB.pin5;
+ pin5->IN[0] = pin_IN.pin5;
+ pin5->OUT[0] = pin_OUT.pin5;
+ pin5->OUT_VLE[0] = pin_OUT_VLE.pin5;
+ *pinmux5 = pin_MUX.pin5;
+ *pincfg5 = pin_CFG.pin5;
+ }
+
+ if ((pin_tracker >> 2) & 1) {
+ pin7->CNF[0] = pin_CNF.pin7;
+ pin7->DEB[0] = pin_DEB.pin7;
+ pin7->IN[0] = pin_IN.pin7;
+ pin7->OUT[0] = pin_OUT.pin7;
+ pin7->OUT_VLE[0] = pin_OUT_VLE.pin7;
+ *pinmux7 = pin_MUX.pin7;
+ *pincfg7 = pin_CFG.pin7;
+ }
+
+ if ((pin_tracker >> 3) & 1) {
+ pin8->CNF[0] = pin_CNF.pin8;
+ pin8->DEB[0] = pin_DEB.pin8;
+ pin8->IN[0] = pin_IN.pin8;
+ pin8->OUT[0] = pin_OUT.pin8;
+ pin8->OUT_VLE[0] = pin_OUT_VLE.pin8;
+ *pinmux8 = pin_MUX.pin8;
+ *pincfg8 = pin_CFG.pin8;
+ }
+
+ if ((pin_tracker >> 4) & 1) {
+ pin10->CNF[0] = pin_CNF.pin10;
+ pin10->DEB[0] = pin_DEB.pin10;
+ pin10->IN[0] = pin_IN.pin10;
+ pin10->OUT[0] = pin_OUT.pin10;
+ pin10->OUT_VLE[0] = pin_OUT_VLE.pin10;
+ *pinmux10 = pin_MUX.pin10;
+ *pincfg10 = pin_CFG.pin10;
+ }
+
+ if ((pin_tracker >> 5) & 1) {
+ pin11->CNF[0] = pin_CNF.pin11;
+ pin11->DEB[0] = pin_DEB.pin11;
+ pin11->IN[0] = pin_IN.pin11;
+ pin11->OUT[0] = pin_OUT.pin11;
+ pin11->OUT_VLE[0] = pin_OUT_VLE.pin11;
+ *pinmux11 = pin_MUX.pin11;
+ *pincfg11 = pin_CFG.pin11;
+ }
+
+ if ((pin_tracker >> 6) & 1) {
+ pin12->CNF[0] = pin_CNF.pin12;
+ pin12->DEB[0] = pin_DEB.pin12;
+ pin12->IN[0] = pin_IN.pin12;
+ pin12->OUT[0] = pin_OUT.pin12;
+ pin12->OUT_VLE[0] = pin_OUT_VLE.pin12;
+ *pinmux12 = pin_MUX.pin12;
+ *pincfg12 = pin_CFG.pin12;
+ }
+
+ if (((pin_tracker >> 7) & 1) || ((pin_tracker >> 30) & 1)) {
+ pin13->CNF[0] = pin_CNF.pin13;
+ pin13->DEB[0] = pin_DEB.pin13;
+ pin13->IN[0] = pin_IN.pin13;
+ pin13->OUT[0] = pin_OUT.pin13;
+ pin13->OUT_VLE[0] = pin_OUT_VLE.pin13;
+ *pinmux13 = pin_MUX.pin13;
+ *pincfg13 = pin_CFG.pin13;
+ }
+
+ if (((pin_tracker >> 8) & 1) || ((pin_tracker >> 28) & 1)) {
+ pin15->CNF[0] = pin_CNF.pin15;
+ pin15->DEB[0] = pin_DEB.pin15;
+ pin15->IN[0] = pin_IN.pin15;
+ pin15->OUT[0] = pin_OUT.pin15;
+ pin15->OUT_VLE[0] = pin_OUT_VLE.pin15;
+ *pinmux15 = pin_MUX.pin15;
+ *pincfg15 = pin_CFG.pin15;
+ }
+
+ if ((pin_tracker >> 9) & 1) {
+ pin16->CNF[0] = pin_CNF.pin16;
+ pin16->DEB[0] = pin_DEB.pin16;
+ pin16->IN[0] = pin_IN.pin16;
+ pin16->OUT[0] = pin_OUT.pin16;
+ pin16->OUT_VLE[0] = pin_OUT_VLE.pin16;
+ *pinmux16 = pin_MUX.pin16;
+ *pincfg16 = pin_CFG.pin16;
+ }
+
+ if (((pin_tracker >> 10) & 1) || ((pin_tracker >> 29) & 1)) {
+ pin18->CNF[0] = pin_CNF.pin18;
+ pin18->DEB[0] = pin_DEB.pin18;
+ pin18->IN[0] = pin_IN.pin18;
+ pin18->OUT[0] = pin_OUT.pin18;
+ pin18->OUT_VLE[0] = pin_OUT_VLE.pin18;
+ *pinmux18 = pin_MUX.pin18;
+ *pincfg18 = pin_CFG.pin18;
+ }
+
+ if (((pin_tracker >> 11) & 1) || ((pin_tracker >> 31) & 1)) {
+ pin19->CNF[0] = pin_CNF.pin19;
+ pin19->DEB[0] = pin_DEB.pin19;
+ pin19->IN[0] = pin_IN.pin19;
+ pin19->OUT[0] = pin_OUT.pin19;
+ pin19->OUT_VLE[0] = pin_OUT_VLE.pin19;
+ *pinmux19 = pin_MUX.pin19;
+ *pincfg19 = pin_CFG.pin19;
+ }
+
+ if (((pin_tracker >> 12) & 1) || ((pin_tracker >> 31) & 1)) {
+ pin21->CNF[0] = pin_CNF.pin21;
+ pin21->DEB[0] = pin_DEB.pin21;
+ pin21->IN[0] = pin_IN.pin21;
+ pin21->OUT[0] = pin_OUT.pin21;
+ pin21->OUT_VLE[0] = pin_OUT_VLE.pin21;
+ *pinmux21 = pin_MUX.pin21;
+ *pincfg21 = pin_CFG.pin21;
+ }
+
+ if ((pin_tracker >> 13) & 1) {
+ pin22->CNF[0] = pin_CNF.pin22;
+ pin22->DEB[0] = pin_DEB.pin22;
+ pin22->IN[0] = pin_IN.pin22;
+ pin22->OUT[0] = pin_OUT.pin22;
+ pin22->OUT_VLE[0] = pin_OUT_VLE.pin22;
+ *pinmux22 = pin_MUX.pin22;
+ *pincfg22 = pin_CFG.pin22;
+ }
+
+ if (((pin_tracker >> 14) & 1) || ((pin_tracker >> 31) & 1)) {
+ pin23->CNF[0] = pin_CNF.pin23;
+ pin23->DEB[0] = pin_DEB.pin23;
+ pin23->IN[0] = pin_IN.pin23;
+ pin23->OUT[0] = pin_OUT.pin23;
+ pin23->OUT_VLE[0] = pin_OUT_VLE.pin23;
+ *pinmux23 = pin_MUX.pin23;
+ *pincfg23 = pin_CFG.pin23;
+ }
+
+ if (((pin_tracker >> 15) & 1) || ((pin_tracker >> 31) & 1)) {
+ pin24->CNF[0] = pin_CNF.pin24;
+ pin24->DEB[0] = pin_DEB.pin24;
+ pin24->IN[0] = pin_IN.pin24;
+ pin24->OUT[0] = pin_OUT.pin24;
+ pin24->OUT_VLE[0] = pin_OUT_VLE.pin24;
+ *pinmux24 = pin_MUX.pin24;
+ *pincfg24 = pin_CFG.pin24;
+ }
+
+ if ((pin_tracker >> 16) & 1) {
+ pin26->CNF[0] = pin_CNF.pin26;
+ pin26->DEB[0] = pin_DEB.pin26;
+ pin26->IN[0] = pin_IN.pin26;
+ pin26->OUT[0] = pin_OUT.pin26;
+ pin26->OUT_VLE[0] = pin_OUT_VLE.pin26;
+ *pinmux26 = pin_MUX.pin26;
+ *pincfg26 = pin_CFG.pin26;
+ }
+
+ if ((pin_tracker >> 17) & 1) {
+ pin27->CNF[0] = pin_CNF.pin27;
+ pin27->DEB[0] = pin_DEB.pin27;
+ pin27->IN[0] = pin_IN.pin27;
+ pin27->OUT[0] = pin_OUT.pin27;
+ pin27->OUT_VLE[0] = pin_OUT_VLE.pin27;
+ *pinmux27 = pin_MUX.pin27;
+ *pincfg27 = pin_CFG.pin27;
+ }
+
+ if ((pin_tracker >> 18) & 1) {
+ pin28->CNF[0] = pin_CNF.pin28;
+ pin28->DEB[0] = pin_DEB.pin28;
+ pin28->IN[0] = pin_IN.pin28;
+ pin28->OUT[0] = pin_OUT.pin28;
+ pin28->OUT_VLE[0] = pin_OUT_VLE.pin28;
+ *pinmux28 = pin_MUX.pin28;
+ *pincfg28 = pin_CFG.pin28;
+ }
+
+ if ((pin_tracker >> 19) & 1) {
+ pin29->CNF[0] = pin_CNF.pin29;
+ pin29->DEB[0] = pin_DEB.pin29;
+ pin29->IN[0] = pin_IN.pin29;
+ pin29->OUT[0] = pin_OUT.pin29;
+ pin29->OUT_VLE[0] = pin_OUT_VLE.pin29;
+ *pinmux29 = pin_MUX.pin29;
+ *pincfg29 = pin_CFG.pin29;
+ }
+
+ if ((pin_tracker >> 20) & 1) {
+ pin31->CNF[0] = pin_CNF.pin31;
+ pin31->DEB[0] = pin_DEB.pin31;
+ pin31->IN[0] = pin_IN.pin31;
+ pin31->OUT[0] = pin_OUT.pin31;
+ pin31->OUT_VLE[0] = pin_OUT_VLE.pin31;
+ *pinmux31 = pin_MUX.pin31;
+ *pincfg31 = pin_CFG.pin31;
+ }
+
+ if ((pin_tracker >> 21) & 1) {
+ pin32->CNF[0] = pin_CNF.pin32;
+ pin32->DEB[0] = pin_DEB.pin32;
+ pin32->IN[0] = pin_IN.pin32;
+ pin32->OUT[0] = pin_OUT.pin32;
+ pin32->OUT_VLE[0] = pin_OUT_VLE.pin32;
+ *pinmux32 = pin_MUX.pin32;
+ *pincfg32 = pin_CFG.pin32;
+ }
+
+ if ((pin_tracker >> 22) & 1) {
+ pin33->CNF[0] = pin_CNF.pin33;
+ pin33->DEB[0] = pin_DEB.pin33;
+ pin33->IN[0] = pin_IN.pin33;
+ pin33->OUT[0] = pin_OUT.pin33;
+ pin33->OUT_VLE[0] = pin_OUT_VLE.pin3;
+ *pinmux33 = pin_MUX.pin33;
+ *pincfg33 = pin_CFG.pin33;
+ }
+
+ if ((pin_tracker >> 23) & 1) {
+ pin35->CNF[0] = pin_CNF.pin35;
+ pin35->DEB[0] = pin_DEB.pin35;
+ pin35->IN[0] = pin_IN.pin35;
+ pin35->OUT[0] = pin_OUT.pin35;
+ pin35->OUT_VLE[0] = pin_OUT_VLE.pin35;
+ *pinmux35 = pin_MUX.pin35;
+ *pincfg35 = pin_CFG.pin35;
+ }
+
+ if ((pin_tracker >> 24) & 1) {
+ pin36->CNF[0] = pin_CNF.pin36;
+ pin36->DEB[0] = pin_DEB.pin36;
+ pin36->IN[0] = pin_IN.pin36;
+ pin36->OUT[0] = pin_OUT.pin36;
+ pin36->OUT_VLE[0] = pin_OUT_VLE.pin36;
+ *pinmux36 = pin_MUX.pin36;
+ *pincfg36 = pin_CFG.pin36;
+ }
+
+ if ((pin_tracker >> 25) & 1) {
+ pin37->CNF[0] = pin_CNF.pin37;
+ pin37->DEB[0] = pin_DEB.pin37;
+ pin37->IN[0] = pin_IN.pin37;
+ pin37->OUT[0] = pin_OUT.pin37;
+ pin37->OUT_VLE[0] = pin_OUT_VLE.pin37;
+ *pinmux37 = pin_MUX.pin37;
+ *pincfg37 = pin_CFG.pin37;
+ }
+
+ if ((pin_tracker >> 26) & 1) {
+ pin38->CNF[0] = pin_CNF.pin38;
+ pin38->DEB[0] = pin_DEB.pin38;
+ pin38->IN[0] = pin_IN.pin38;
+ pin38->OUT[0] = pin_OUT.pin38;
+ pin38->OUT_VLE[0] = pin_OUT_VLE.pin38;
+ *pinmux38 = pin_MUX.pin38;
+ *pincfg38 = pin_CFG.pin38;
+ }
+
+ if ((pin_tracker >> 27) & 1) {
+ pin40->CNF[0] = pin_CNF.pin40;
+ pin40->DEB[0] = pin_DEB.pin40;
+ pin40->IN[0] = pin_IN.pin40;
+ pin40->OUT[0] = pin_OUT.pin40;
+ pin40->OUT_VLE[0] = pin_OUT_VLE.pin40;
+ *pinmux40 = pin_MUX.pin40;
+ *pincfg40 = pin_CFG.pin40;
+ }
+
+ // Ummapping CNF AON registers
+ munmap(baseCNF_AON, pagesize);
+
+ // Ummapping CNF Non AON registers
+ munmap(baseCNF_NAON, 4 * pagesize);
+
+ // Ummapping PINMUX G7 registers
+ munmap(basePINMUX_G7, pagesize);
+
+ // Ummapping PINMUX G3 registers
+ munmap(basePINMUX_G3, pagesize);
+
+ // Ummapping PINMUX EDP registers
+ munmap(basePINMUX_EDP, pagesize);
+
+ // Ummapping PINMUX G4 registers
+ munmap(basePINMUX_G4, pagesize);
+
+ // Ummapping PINMUX G2 registers
+ munmap(basePINMUX_G2, pagesize);
+
+ // Ummapping PWM1 registers
+ munmap(basePWM1, pagesize);
+
+ // Ummapping PWM5 registers
+ munmap(basePWM5, pagesize);
+
+ // Ummapping PWM8 registers
+ munmap(basePWM8, pagesize);
+
+ // close /dev/mem
+ close(fd_GPIO);
+}
+
+int gpioSetMode(unsigned gpio, unsigned mode) {
+ int status = 1;
+ if (mode == JET_INPUT) {
+ switch (gpio){
+
+ case 3:
+ *pinmux3 = PINMUXO_IN;
+ *pincfg3 = CFGO_IN;
+ pin3->CNF[0] = CNFO_IN;
+ pin3->OUT[0] |= 0x00000001;
+ pin_tracker |= 1;
+ break;
+ case 5:
+ *pinmux5 = PINMUXO_IN;
+ *pincfg5 = CFGO_IN;
+ pin5->CNF[0] = CNFO_IN;
+ pin5->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 1);
+ break;
+ case 7:
+ *pinmux7 = PINMUXO_IN;
+ *pincfg7 = CFGO_IN;
+ pin7->CNF[0] = CNFO_IN;
+ pin7->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 2);
+ break;
+ case 8:
+ *pinmux8 = PINMUXO_IN;
+ *pincfg8 = CFGO_IN;
+ pin8->CNF[0] = CNFO_IN;
+ pin8->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 3);
+ break;
+ case 10:
+ *pinmux10 = PINMUXO_IN;
+ *pincfg10 = CFGO_IN;
+ pin10->CNF[0] = CNFO_IN;
+ pin10->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 4);
+ break;
+ case 11:
+ *pinmux11 = PINMUXO_IN;
+ *pincfg11 = CFGO_IN;
+ pin11->CNF[0] = CNFO_IN;
+ pin11->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 5);
+ break;
+ case 12:
+ *pinmux12 = PINMUXO_IN;
+ *pincfg12 = CFGO_IN;
+ pin12->CNF[0] = CNFO_IN;
+ pin12->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 6);
+ break;
+ case 13:
+ *pinmux13 = PINMUXO_IN;
+ *pincfg13 = CFGO_IN;
+ pin13->CNF[0] = CNFO_IN;
+ pin13->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 7);
+ break;
+ case 15:
+ *pinmux15 = PINMUXO_IN;
+ *pincfg15 = CFGO_IN;
+ pin15->CNF[0] = CNFO_IN;
+ pin15->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 8);
+ break;
+ case 16:
+ *pinmux16 = PINMUXO_IN;
+ *pincfg16 = CFGO_IN;
+ pin16->CNF[0] = CNFO_IN;
+ pin16->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 9);
+ break;
+ case 18:
+ *pinmux18 = PINMUXO_IN;
+ *pincfg18 = CFGO_IN;
+ pin18->CNF[0] = CNFO_IN;
+ pin18->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 10);
+ break;
+ case 19:
+ *pinmux19 = PINMUXO_IN;
+ *pincfg19 = CFGO_IN;
+ pin19->CNF[0] = CNFO_IN;
+ pin19->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 11);
+ break;
+ case 21:
+ *pinmux21 = PINMUXO_IN;
+ *pincfg21 = CFGO_IN;
+ pin21->CNF[0] = CNFO_IN;
+ pin21->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 12);
+ break;
+ case 22:
+ *pinmux22 = PINMUXO_IN;
+ *pincfg22 = CFGO_IN;
+ pin22->CNF[0] = CNFO_IN;
+ pin22->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 13);
+ break;
+ case 23:
+ *pinmux23 = PINMUXO_IN;
+ *pincfg23 = CFGO_IN;
+ pin23->CNF[0] = CNFO_IN;
+ pin23->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 14);
+ break;
+ case 24:
+ *pinmux24 = PINMUXO_IN;
+ *pincfg24 = CFGO_IN;
+ pin24->CNF[0] = CNFO_IN;
+ pin24->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 15);
+ break;
+ case 26:
+ *pinmux26 = PINMUXO_IN;
+ *pincfg26 = CFGO_IN;
+ pin26->CNF[0] = CNFO_IN;
+ pin26->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 16);
+ break;
+ case 27:
+ *pinmux27 = PINMUXO_IN;
+ *pincfg27 = CFGO_IN;
+ pin27->CNF[0] = CNFO_IN;
+ pin27->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 17);
+ break;
+ case 28:
+ *pinmux28 = PINMUXO_IN;
+ *pincfg28 = CFGO_IN;
+ pin28->CNF[0] = CNFO_IN;
+ pin28->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 18);
+ break;
+ case 29:
+ *pinmux29 = PINMUXO_IN;
+ *pincfg29 = CFGO_IN;
+ pin29->CNF[0] = CNFO_IN;
+ pin29->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 19);
+ break;
+ case 31:
+ *pinmux31 = PINMUXO_IN;
+ *pincfg31 = CFGO_IN;
+ pin31->CNF[0] = CNFO_IN;
+ pin31->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 20);
+ break;
+ case 32:
+ *pinmux32 = PINMUXO_IN;
+ *pincfg32 = CFGO_IN;
+ pin32->CNF[0] = CNFO_IN;
+ pin32->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 21);
+ break;
+ case 33:
+ *pinmux33 = PINMUXO_IN;
+ *pincfg33 = CFGO_IN;
+ pin33->CNF[0] = CNFO_IN;
+ pin33->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 22);
+ break;
+ case 35:
+ *pinmux35 = PINMUXO_IN;
+ *pincfg35 = CFGO_IN;
+ pin35->CNF[0] = CNFO_IN;
+ pin35->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 23);
+ break;
+ case 36:
+ *pinmux36 = PINMUXO_IN;
+ *pincfg36 = CFGO_IN;
+ pin36->CNF[0] = CNFO_IN;
+ pin36->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 24);
+ break;
+ case 37:
+ *pinmux37 = PINMUXO_IN;
+ *pincfg37 = CFGO_IN;
+ pin37->CNF[0] = CNFO_IN;
+ pin37->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 25);
+ break;
+ case 38:
+ *pinmux38 = PINMUXO_IN;
+ *pincfg38 = CFGO_IN;
+ pin38->CNF[0] = CNFO_IN;
+ pin38->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 26);
+ break;
+ case 40:
+ *pinmux40 = PINMUXO_IN;
+ *pincfg40 = CFGO_IN;
+ pin40->CNF[0] = CNFO_IN;
+ pin40->OUT[0] |= 0x00000001;
+ pin_tracker |= (1 << 27);
+ break;
+ default:
+ status = -1;
+ printf("Only gpio numbers from 3 to 40 are accepted, this function will read the level on the Jetson header pins,\n");
+ printf("numbered as the header pin numbers e.g. AUD_MCLK is pin header number 7\n");
+ }
+ }
+ else if (mode == JET_OUTPUT) {
+ switch (gpio) {
+
+ case 3:
+ *pinmux3 = PINMUXO_OUT1;
+ *pincfg3 = CFGO_OUT;
+ pin3->CNF[0] = CNFO_OUT;
+ pin3->OUT[0] &= ~(0x00000001);
+ pin_tracker |= 1;
+ break;
+ case 5:
+ *pinmux5 = PINMUXO_OUT1;
+ *pincfg5 = CFGO_OUT;
+ pin5->CNF[0] = CNFO_OUT;
+ pin5->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 1);
+ break;
+ case 7:
+ *pinmux7 = PINMUXO_OUT;
+ *pincfg7 = CFGO_OUT;
+ pin7->CNF[0] = CNFO_OUT;
+ pin7->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 2);
+ break;
+ case 8:
+ *pinmux8 = PINMUXO_OUT;
+ *pincfg8 = CFGO_OUT;
+ pin8->CNF[0] = CNFO_OUT;
+ pin8->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 3);
+ break;
+ case 10:
+ *pinmux10 = PINMUXO_OUT;
+ *pincfg10 = CFGO_OUT;
+ pin10->CNF[0] = CNFO_OUT;
+ pin10->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 4);
+ break;
+ case 11:
+ *pinmux11 = PINMUXO_OUT;
+ *pincfg11 = CFGO_OUT;
+ pin11->CNF[0] = CNFO_OUT;
+ pin11->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 5);
+ break;
+ case 12:
+ *pinmux12 = PINMUXO_OUT;
+ *pincfg12 = CFGO_OUT;
+ pin12->CNF[0] = CNFO_OUT;
+ pin12->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 6);
+ break;
+ case 13:
+ *pinmux13 = PINMUXO_OUT;
+ *pincfg13 = CFGO_OUT;
+ pin13->CNF[0] = CNFO_OUT;
+ pin13->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 7);
+ break;
+ case 15:
+ *pinmux15 = PINMUXO_OUT;
+ *pincfg15 = CFGO_OUT;
+ pin15->CNF[0] = CNFO_OUT;
+ pin15->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 8);
+ break;
+ case 16:
+ *pinmux16 = PINMUXO_OUT;
+ *pincfg16 = CFGO_OUT;
+ pin16->CNF[0] = CNFO_OUT;
+ pin16->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 9);
+ break;
+ case 18:
+ *pinmux18 = PINMUXO_OUT;
+ *pincfg18 = CFGO_OUT;
+ pin18->CNF[0] = CNFO_OUT;
+ pin18->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 10);
+ break;
+ case 19:
+ *pinmux19 = PINMUXO_OUT;
+ *pincfg19 = CFGO_OUT;
+ pin19->CNF[0] = CNFO_OUT;
+ pin19->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 11);
+ break;
+ case 21:
+ *pinmux21 = PINMUXO_OUT;
+ *pincfg21 = CFGO_OUT;
+ pin21->CNF[0] = CNFO_OUT;
+ pin21->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 12);
+ break;
+ case 22:
+ *pinmux22 = PINMUXO_OUT;
+ *pincfg22 = CFGO_OUT;
+ pin22->CNF[0] = CNFO_OUT;
+ pin22->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 13);
+ break;
+ case 23:
+ *pinmux23 = PINMUXO_OUT;
+ *pincfg23 = CFGO_OUT;
+ pin23->CNF[0] = CNFO_OUT;
+ pin23->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 14);
+ break;
+ case 24:
+ *pinmux24 = PINMUXO_OUT;
+ *pincfg24 = CFGO_OUT;
+ pin24->CNF[0] = CNFO_OUT;
+ pin24->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 15);
+ break;
+ case 26:
+ *pinmux26 = PINMUXO_OUT;
+ *pincfg26 = CFGO_OUT;
+ pin26->CNF[0] = CNFO_OUT;
+ pin26->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 16);
+ break;
+ case 27:
+ *pinmux27 = PINMUXO_OUT1;
+ *pincfg27 = CFGO_OUT;
+ pin27->CNF[0] = CNFO_OUT;
+ pin27->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 17);
+ break;
+ case 28:
+ *pinmux28 = PINMUXO_OUT1;
+ *pincfg28 = CFGO_OUT;
+ pin28->CNF[0] = CNFO_OUT;
+ pin28->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 18);
+ break;
+ case 29:
+ *pinmux29 = PINMUXO_OUT;
+ *pincfg29 = CFGO_OUT;
+ pin29->CNF[0] = CNFO_OUT;
+ pin29->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 19);
+ break;
+ case 31:
+ *pinmux31 = PINMUXO_OUT;
+ *pincfg31 = CFGO_OUT;
+ pin31->CNF[0] = CNFO_OUT;
+ pin31->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 20);
+ break;
+ case 32:
+ *pinmux32 = PINMUXO_OUT;
+ *pincfg32 = CFGO_OUT;
+ pin32->CNF[0] = CNFO_OUT;
+ pin32->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 21);
+ break;
+ case 33:
+ *pinmux33 = PINMUXO_OUT;
+ *pincfg33 = CFGO_OUT;
+ pin33->CNF[0] = CNFO_OUT;
+ pin33->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 22);
+ break;
+ case 35:
+ *pinmux35 = PINMUXO_OUT;
+ *pincfg35 = CFGO_OUT;
+ pin35->CNF[0] = CNFO_OUT;
+ pin35->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 23);
+ break;
+ case 36:
+ *pinmux36 = PINMUXO_OUT;
+ *pincfg36 = CFGO_OUT;
+ pin36->CNF[0] = CNFO_OUT;
+ pin36->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 24);
+ break;
+ case 37:
+ *pinmux37 = PINMUXO_OUT;
+ *pincfg37 = CFGO_OUT;
+ pin37->CNF[0] = CNFO_OUT;
+ pin37->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 25);
+ break;
+ case 38:
+ *pinmux38 = PINMUXO_OUT;
+ *pincfg38 = CFGO_OUT;
+ pin38->CNF[0] = CNFO_OUT;
+ pin38->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 26);
+ break;
+ case 40:
+ *pinmux40 = PINMUXO_OUT;
+ *pincfg40 = CFGO_OUT;
+ pin40->CNF[0] = CNFO_OUT;
+ pin40->OUT[0] &= ~(0x00000001);
+ pin_tracker |= (1 << 27);
+ break;
+ default:
+ status = -2;
+ printf("Only gpio numbers from 3 to 40 are accepted, this function will only write the level on the Jetson header pins,\n");
+ printf("numbered as the header pin numbers e.g. AUD_MCLK is pin header number 7\n");
+ }
+ }
+ else { printf("Only modes allowed are JET_INPUT and JET_OUTPUT\n");
+ status = -3;
+ }
+ return status;
+}
+
+int gpioRead(unsigned gpio) {
+ int level = 0;
+ switch (gpio){
+
+ case 3:
+ level = pin3->IN[0] & 1;
+ break;
+ case 5:
+ level = pin5->IN[0] & 1;
+ break;
+ case 7:
+ level = pin7->IN[0] & 1;
+ break;
+ case 8:
+ level = pin8->IN[0] & 1;
+ break;
+ case 10:
+ level = pin10->IN[0] & 1;
+ break;
+ case 11:
+ level = pin11->IN[0] & 1;
+ break;
+ case 12:
+ level = pin12->IN[0] & 1;
+ break;
+ case 13:
+ level = pin13->IN[0] & 1;
+ break;
+ case 15:
+ level = pin15->IN[0] & 1;
+ break;
+ case 16:
+ level = pin16->IN[0] & 1;
+ break;
+ case 18:
+ level = pin18->IN[0] & 1;
+ break;
+ case 19:
+ level = pin19->IN[0] & 1;
+ break;
+ case 21:
+ level = pin21->IN[0] & 1;
+ break;
+ case 22:
+ level = pin22->IN[0] & 1;
+ break;
+ case 23:
+ level = pin23->IN[0] & 1;
+ break;
+ case 24:
+ level = pin24->IN[0] & 1;
+ break;
+ case 26:
+ level = pin26->IN[0] & 1;
+ break;
+ case 27:
+ level = pin27->IN[0] & 1;
+ break;
+ case 28:
+ level = pin28->IN[0] & 1;
+ break;
+ case 29:
+ level = pin29->IN[0] & 1;
+ break;
+ case 31:
+ level = pin31->IN[0] & 1;
+ break;
+ case 32:
+ level = pin32->IN[0] & 1;
+ break;
+ case 33:
+ level = pin33->IN[0] & 1;
+ break;
+ case 35:
+ level = pin35->IN[0] & 1;
+ break;
+ case 36:
+ level = pin36->IN[0] & 1;
+ break;
+ case 37:
+ level = pin37->IN[0] & 1;
+ break;
+ case 38:
+ level = pin38->IN[0] & 1;
+ break;
+ case 40:
+ level = pin40->IN[0] & 1;
+ break;
+ default:
+ level = -1;
+ printf("Only gpio numbers from 3 to 40 are accepted, this function will only read the level of the Jetson header pins,\n");
+ printf("numbered as the header pin numbers e.g. AUD_MCLK is pin header number 7\n");
+ }
+ return level;
+}
+
+int gpioWrite(unsigned gpio, unsigned level) {
+ int status = 1;
+ if (level == 0) {
+ switch (gpio){
+
+ case 3:
+ pin3->OUT_VLE[0] &= level;
+ break;
+ case 5:
+ pin5->OUT_VLE[0] &= level;
+ break;
+ case 7:
+ pin7->OUT_VLE[0] &= level;
+ break;
+ case 8:
+ pin8->OUT_VLE[0] &= level;
+ break;
+ case 10:
+ pin10->OUT_VLE[0] &= level;
+ break;
+ case 11:
+ pin11->OUT_VLE[0] &= level;
+ break;
+ case 12:
+ pin12->OUT_VLE[0] &= level;
+ break;
+ case 13:
+ pin13->OUT_VLE[0] &= level;
+ break;
+ case 15:
+ pin15->OUT_VLE[0] &= level;
+ break;
+ case 16:
+ pin16->OUT_VLE[0] &= level;
+ break;
+ case 18:
+ pin18->OUT_VLE[0] &= level;
+ break;
+ case 19:
+ pin19->OUT_VLE[0] &= level;
+ break;
+ case 21:
+ pin21->OUT_VLE[0] &= level;
+ break;
+ case 22:
+ pin22->OUT_VLE[0] &= level;
+ break;
+ case 23:
+ pin23->OUT_VLE[0] &= level;
+ break;
+ case 24:
+ pin24->OUT_VLE[0] &= level;
+ break;
+ case 26:
+ pin26->OUT_VLE[0] &= level;
+ break;
+ case 27:
+ pin27->OUT_VLE[0] &= level;
+ break;
+ case 28:
+ pin28->OUT_VLE[0] &= level;
+ break;
+ case 29:
+ pin29->OUT_VLE[0] &= level;
+ break;
+ case 31:
+ pin31->OUT_VLE[0] &= level;
+ break;
+ case 32:
+ pin32->OUT_VLE[0] &= level;
+ break;
+ case 33:
+ pin33->OUT_VLE[0] &= level;
+ break;
+ case 35:
+ pin35->OUT_VLE[0] &= level;
+ break;
+ case 36:
+ pin36->OUT_VLE[0] &= level;
+ break;
+ case 37:
+ pin37->OUT_VLE[0] &= level;
+ break;
+ case 38:
+ pin38->OUT_VLE[0] &= level;
+ break;
+ case 40:
+ pin40->OUT_VLE[0] &= level;
+ break;
+ default:
+ status = -1;
+ printf("Only gpio numbers from 3 to 40 are accepted, this function will only read the level of the Jetson header pins,\n");
+ printf("numbered as the header pin numbers e.g. AUD_MCLK is pin header number 7\n");
+ }
+ }
+ else if (level == 1) {
+ switch (gpio){
+
+ case 3:
+ pin3->OUT_VLE[0] |= level;
+ break;
+ case 5:
+ pin5->OUT_VLE[0] |= level;
+ break;
+ case 7:
+ pin7->OUT_VLE[0] |= level;
+ break;
+ case 8:
+ pin8->OUT_VLE[0] |= level;
+ break;
+ case 10:
+ pin10->OUT_VLE[0] |= level;
+ break;
+ case 11:
+ pin11->OUT_VLE[0] |= level;
+ break;
+ case 12:
+ pin12->OUT_VLE[0] |= level;
+ break;
+ case 13:
+ pin13->OUT_VLE[0] |= level;
+ break;
+ case 15:
+ pin15->OUT_VLE[0] |= level;
+ break;
+ case 16:
+ pin16->OUT_VLE[0] |= level;
+ break;
+ case 18:
+ pin18->OUT_VLE[0] |= level;
+ break;
+ case 19:
+ pin19->OUT_VLE[0] |= level;
+ break;
+ case 21:
+ pin21->OUT_VLE[0] |= level;
+ break;
+ case 22:
+ pin22->OUT_VLE[0] |= level;
+ break;
+ case 23:
+ pin23->OUT_VLE[0] |= level;
+ break;
+ case 24:
+ pin24->OUT_VLE[0] |= level;
+ break;
+ case 26:
+ pin26->OUT_VLE[0] |= level;
+ break;
+ case 27:
+ pin27->OUT_VLE[0] |= level;
+ break;
+ case 28:
+ pin28->OUT_VLE[0] |= level;
+ break;
+ case 29:
+ pin29->OUT_VLE[0] |= level;
+ break;
+ case 31:
+ pin31->OUT_VLE[0] |= level;
+ break;
+ case 32:
+ pin32->OUT_VLE[0] |= level;
+ break;
+ case 33:
+ pin33->OUT_VLE[0] |= level;
+ break;
+ case 35:
+ pin35->OUT_VLE[0] |= level;
+ break;
+ case 36:
+ pin36->OUT_VLE[0] |= level;
+ break;
+ case 37:
+ pin37->OUT_VLE[0] |= level;
+ break;
+ case 38:
+ pin38->OUT_VLE[0] |= level;
+ break;
+ case 40:
+ pin40->OUT_VLE[0] |= level;
+ break;
+ default:
+ status = -2;
+ printf("Only gpio numbers from 3 to 40 are accepted, this function will only read the level of the Jetson header pins,\n");
+ printf("numbered as the header pin numbers e.g. AUD_MCLK is pin header number 7\n");
+ }
+ }
+ else {printf("Only levels 0 or 1 are allowed\n");
+ status = -3;
+ }
+ return status;
+}
+
+void *callback(void *arg) {
+ ISRFunc *int_struct = (ISRFunc *) arg;
+ unsigned gpio = int_struct->gpio;
+ int edge = int_struct->edge;
+ unsigned gpio_offset = int_struct->gpio_offset;
+ uint64_t *timestamp = int_struct->timestamp;
+ *timestamp = 0;
+ uint64_t timestamp_new = 0;
+ unsigned debounce = int_struct->debounce;
+ char dev[20];
+ int fd;
+ int ret;
+ struct timespec start;
+
+ struct gpioevent_request req = {0};
+ struct gpioevent_data event = {0};
+
+ if (gpio == 3 || gpio == 5 || gpio == 27 || gpio == 28) {
+ strcpy(dev, "/dev/gpiochip1");
+ }
+ else {
+ strcpy(dev, "/dev/gpiochip0");
+ }
+
+ fd = open(dev, O_RDONLY);
+ if (fd < 0) {
+ printf("Bad handle (%d)\n", fd);
+ pthread_exit(NULL);
+ }
+
+ req.lineoffset = gpio_offset;
+ req.handleflags = GPIOHANDLE_REQUEST_INPUT;
+ req.eventflags = edge;
+ strncpy(req.consumer_label, "gpio_event", sizeof(req.consumer_label) - 1);
+
+ ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
+ if (ret == -1) {
+ ret = -errno;
+ printf("Failed to issue GET EVENT ""IOCTL (%d)\n",ret);
+ close(fd);
+ pthread_exit(NULL);
+ }
+ close(fd);
+
+ while (global_int) {
+ ret = read(req.fd, &event, sizeof(event));
+ if ((ret == -1) || (ret != sizeof(event))) {
+ ret = -errno;
+ printf("Failed to read event (%d)\n", ret);
+ break;
+ }
+ /* Had to do this as the timestamp returned by event.timestamp was rubbish, it was good to run a diff between
+ * 2 timestamps but it wasn't CLOCK_REALTIME, neither looked like MONOTONIC as the EPOCH was in the future. As this was working fine in
+ * previous versions of the kernel, I assume the framework/driver is broken @ v5.10, also tried with GPIO V2
+ * with the same outcome. NOTE that on this version the flag: GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME is NOT
+ * available, the whole thing smells like a transition (broken) version of either the framework or the driver.
+ */
+ clock_gettime(CLOCK_REALTIME, &start);
+ timestamp_new = BILLION * (start.tv_sec) + start.tv_nsec;
+
+ if ((timestamp_new - *timestamp) > (debounce * 100)) {
+ *timestamp = timestamp_new;
+ }
+ else{
+ event.id = 0x00;
+ }
+
+ switch (event.id) {
+ case GPIOEVENT_EVENT_RISING_EDGE:
+ int_struct->f();
+ break;
+ case GPIOEVENT_EVENT_FALLING_EDGE:
+ int_struct->f();
+ break;
+ default:
+ //Do nothing
+ break;
+ }
+ }
+ pthread_exit(NULL);
+}
+
+int gpioSetISRFunc(unsigned gpio, unsigned edge, unsigned debounce, unsigned long *timestamp, void (*f)()) {
+ int status = 1;
+ unsigned gpio_offset = 0;
+
+ if (debounce < 0 || debounce > 1000) {
+ printf( "Debounce setting should be a number between 0 and 1000 useconds\n");
+ status = -1;
+ }
+
+ if (edge == RISING_EDGE || edge == FALLING_EDGE || edge == EITHER_EDGE) {
+
+ switch (gpio) {
+
+ case 3:
+ pin3->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin3->INT_CLR[0] |= 1;
+ gpio_offset = 22;//base is 316
+ break;
+ case 5:
+ pin5->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin5->INT_CLR[0] |= 1;
+ gpio_offset = 21;
+ break;
+ case 7:
+ pin7->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin7->INT_CLR[0] |= 1;
+ gpio_offset = 106;//base is 348
+ break;
+ case 8:
+ pin8->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin8->INT_CLR[0] |= 1;
+ gpio_offset = 110;
+ break;
+ case 10:
+ pin10->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin10->INT_CLR[0] |= 1;
+ gpio_offset = 111;
+ break;
+ case 11:
+ pin11->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin11->INT_CLR[0] |= 1;
+ gpio_offset = 112;
+ break;
+ case 12:
+ pin12->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin12->INT_CLR[0] |= 1;
+ gpio_offset = 50;
+ break;
+ case 13:
+ pin13->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin13->INT_CLR[0] |= 1;
+ gpio_offset = 108;
+ break;
+ case 15:
+ pin15->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin15->INT_CLR[0] |= 1;
+ gpio_offset = 85;
+ break;
+ case 16:
+ pin16->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin16->INT_CLR[0] |= 1;
+ gpio_offset = 9;
+ break;
+ case 18:
+ pin18->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin18->INT_CLR[0] |= 1;
+ gpio_offset = 43;
+ break;
+ case 19:
+ pin19->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin19->INT_CLR[0] |= 1;
+ gpio_offset = 135;
+ break;
+ case 21:
+ pin21->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin21->INT_CLR[0] |= 1;
+ gpio_offset = 134;
+ break;
+ case 22:
+ pin22->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin22->INT_CLR[0] |= 1;
+ gpio_offset = 96;
+ break;
+ case 23:
+ pin23->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin23->INT_CLR[0] |= 1;
+ gpio_offset = 133;
+ break;
+ case 24:
+ pin24->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin24->INT_CLR[0] |= 1;
+ gpio_offset = 136;
+ break;
+ case 26:
+ pin26->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin26->INT_CLR[0] |= 1;
+ gpio_offset = 137;
+ break;
+ case 27:
+ pin27->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin27->INT_CLR[0] |= 1;
+ gpio_offset = 20;
+ break;
+ case 28:
+ pin28->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin28->INT_CLR[0] |= 1;
+ gpio_offset = 19;
+ break;
+ case 29:
+ pin29->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin29->INT_CLR[0] |= 1;
+ gpio_offset = 1;
+ break;
+ case 31:
+ pin31->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin31->INT_CLR[0] |= 1;
+ gpio_offset = 0;
+ break;
+ case 32:
+ pin32->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin32->INT_CLR[0] |= 1;
+ gpio_offset = 8;
+ break;
+ case 33:
+ pin33->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin33->INT_CLR[0] |= 1;
+ gpio_offset = 2;
+ break;
+ case 35:
+ pin35->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin35->INT_CLR[0] |= 1;
+ gpio_offset = 53;
+ break;
+ case 36:
+ pin36->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin36->INT_CLR[0] |= 1;
+ gpio_offset = 113;
+ break;
+ case 37:
+ pin37->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin37->INT_CLR[0] |= 1;
+ gpio_offset = 3;
+ break;
+ case 38:
+ pin38->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin38->INT_CLR[0] |= 1;
+ gpio_offset = 52;
+ break;
+ case 40:
+ pin40->CNF[0] = (edge == RISING_EDGE ? 0xd9 : (edge == FALLING_EDGE ? 0xc9 : 0xcd));
+ pin40->INT_CLR[0] |= 1;
+ gpio_offset = 51;
+ break;
+ default:
+ status = -2;
+ printf("Only gpio numbers from 3 to 40 are accepted\n");
+ }
+ }
+
+ else {printf("Edge should be: RISING_EDGE,FALLING_EDGE or EITHER_EDGE\n");
+ status = -3;
+ }
+ if (ISRFunc_CFG[gpio]->gpio != 0) {
+ printf("Input pin %d is already being monitored for interruptions\n", gpio);
+ status = -4;
+ }
+ else {
+ ISRFunc_CFG[gpio]->gpio = gpio;
+ ISRFunc_CFG[gpio]->f = f;
+ ISRFunc_CFG[gpio]->edge = edge;
+ ISRFunc_CFG[gpio]->gpio_offset = gpio_offset;
+ ISRFunc_CFG[gpio]->stat_reg = 0;
+ ISRFunc_CFG[gpio]->timestamp = timestamp;
+ ISRFunc_CFG[gpio]->debounce = debounce;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+ pth_err = pthread_create(&callThd[thread_n], &attr, callback, (void *)ISRFunc_CFG[gpio]);
+ if (pth_err !=0){
+ printf("Thread not created, exiting the function with error: %d\n", pth_err);
+ return(-5);
+ }
+ thread_n++;
+ }
+ return status;
+}
+
+int gpioSetPWMfrequency(unsigned gpio, unsigned frequency) {
+ int status = 1;
+ int PFM = 0;
+ unsigned clk_rate_PWM;
+ char buf[100];
+ FILE *fptr;
+
+ if ((frequency >= 50) && (frequency <=1593000)) {
+ if (frequency > 796875) {
+ clk_rate_PWM = 408000000;
+ PFM = round(1593750.0/(double)frequency)-1;
+ }
+
+ if ((frequency >= 98) && (frequency <= 796875)) {
+ clk_rate_PWM = 204000000;
+ PFM = round(796875.0/(double)frequency)-1;
+ }
+
+ if (frequency < 98) {
+ clk_rate_PWM = 102000000;
+ PFM = round(398437.5/(double)frequency)-1;
+ }
+ switch(gpio) {
+ case 13:
+ snprintf(buf, sizeof(buf), "/sys/kernel/debug/bpmp/debug/clk/pwm8/rate");
+ fptr = fopen(buf, "r");
+
+ if (fptr == NULL) {
+ printf("Not possible to read current clock rate on pwm8\n");
+ }
+
+ fscanf(fptr, "%u", &clk_rate_PWM8);
+
+ snprintf(buf, sizeof(buf), "echo %u > /sys/kernel/debug/bpmp/debug/clk/pwm8/rate", clk_rate_PWM);
+ if (system(buf) == -1) {
+ printf( "Not possible to change clock rate on pwm8\n");
+ }
+ fclose(fptr);
+ break;
+ case 15:
+ snprintf(buf, sizeof(buf), "/sys/kernel/debug/bpmp/debug/clk/pwm1/rate");
+ fptr = fopen(buf, "r");
+
+ if (fptr == NULL) {
+ printf("Not possible to read current clock rate on pwm1\n");
+ }
+
+ fscanf(fptr, "%u", &clk_rate_PWM1);
+
+ snprintf(buf, sizeof(buf), "echo %u > /sys/kernel/debug/bpmp/debug/clk/pwm1/rate", clk_rate_PWM);
+ if (system(buf) == -1) {
+ printf( "Not possible to change clock rate on pwm1\n");
+ }
+ fclose(fptr);
+ break;
+ case 18:
+ snprintf(buf, sizeof(buf), "/sys/kernel/debug/bpmp/debug/clk/pwm5/rate");
+ fptr = fopen(buf, "r");
+
+ if (fptr == NULL) {
+ printf("Not possible to read current clock rate on pwm5\n");
+ }
+
+ fscanf(fptr, "%u", &clk_rate_PWM5);
+
+ snprintf(buf, sizeof(buf), "echo %u > /sys/kernel/debug/bpmp/debug/clk/pwm5/rate", clk_rate_PWM);
+ if (system(buf) == -1) {
+ printf( "Not possible to change clock rate on pwm5\n");
+ }
+ fclose(fptr);
+ break;
+ default:
+ status = -1;
+ printf("Only gpio numbers 13, 15 and 18 are accepted\n");
+ }
+ switch (gpio) {
+ case 13:
+ *pinmux13 = 0x00000400;
+ *pincfg13 = CFGO_OUT;
+ pin13->CNF[0] = 0x00000001;
+ *PWM8 = 0x0;
+ *PWM8 = PFM;
+ pin_tracker |= (1 << 30);
+ break;
+ case 15:
+ *pinmux15 = 0x00000400;
+ *pincfg15 = CFGO_OUT;
+ pin15->CNF[0] = 0x00000001;
+ *PWM1 = 0x0;
+ *PWM1 = PFM;
+ pin_tracker |= (1 << 28);
+ break;
+ case 18:
+ *pinmux18 = 0x00000401;
+ *pincfg18 = CFGO_OUT;
+ pin18->CNF[0] = 0x00000001;
+ *PWM5 = 0x0;
+ *PWM5 = PFM;
+ pin_tracker |= (1 << 29);
+ break;
+ default:
+ status = -1;
+ printf("Only gpio numbers 13, 15 and 18 are accepted\n");
+ }
+ }
+ else {printf("Only frequencies from 50 to 1595000 Hz are allowed\n");
+ status =-2;}
+ return status;
+}
+
+int gpioPWM(unsigned gpio, unsigned dutycycle) {
+ int status = 1;
+
+ if ((dutycycle >= 0) && (dutycycle <=256)) {
+ switch (gpio) {
+ case 13:
+ *PWM8 &= ~(0xFFFF0000);
+ *PWM8 |= dutycycle<<16;
+ *PWM8 |= 0x80000000;
+ break;
+ case 15:
+ *PWM1 &= ~(0xFFFF0000);
+ *PWM1 |= dutycycle<<16;
+ *PWM1 |= 0x80000000;
+ break;
+ case 18:
+ *PWM5 &= ~(0xFFFF0000);
+ *PWM5 |= dutycycle<<16;
+ *PWM5 |= 0x80000000;
+ break;
+ default:
+ status = -1;
+ printf("Only gpio numbers 13, 15 and 18 are accepted,\n");
+ }
+ }
+ else {printf("Only a dutycycle from 0 to 256 is allowed\n");
+ status =-2;}
+ return status;
+}
+
+int i2c_smbus_access(int file, char read_write, __u8 command, int size, union i2c_smbus_data *data) {
+ struct i2c_smbus_ioctl_data args;
+ args.read_write = read_write;
+ args.command = command;
+ args.size = size;
+ args.data = data;
+ return ioctl(file,I2C_SMBUS,&args);
+}
+
+int i2cOpen(unsigned i2cBus, unsigned i2cFlags) {
+ char dev[20], buf[100];
+ int fd, slot, speed;
+ uint32_t funcs;
+ FILE *fptr;
+
+ if (!(i2cBus == 0 || i2cBus == 1)) {
+ printf("Bad i2c device (%d) only 0 or 1 are accepted\n", i2cBus);
+ return -1;
+ }
+
+ if (i2cBus == 0) {
+ i2cBus = 1;
+ }
+ else {
+ i2cBus = 7;
+ }
+
+ if (!(i2cFlags == 0 || i2cFlags == 1 || i2cFlags == 2)) {
+ printf("Only flags 0 to 2 are supported to set up bus speed\n");
+ return -2;
+ }
+
+ switch(i2cFlags) {
+ case 0:
+ speed = 100000;
+ break;
+ case 1:
+ speed = 400000;
+ break;
+ case 2:
+ speed = 1000000;
+ break;
+ default:
+ i2cFlags = 3;
+ }
+
+ slot = -5;
+
+ if (i2cInfo[i2cBus].state == I2C_CLOSED) {
+ slot = i2cBus;
+ i2cInfo[slot].state = I2C_RESERVED;
+ }
+ else { printf("i2c bus already open\n");
+ return -3;
+ }
+
+ snprintf(buf, sizeof(buf), "/sys/bus/i2c/devices/i2c-%d/bus_clk_rate", i2cBus);
+ fptr = fopen(buf, "r");
+
+ if (fptr == NULL) {
+ printf("Not possible to read current bus speed\n");
+ }
+
+ fscanf(fptr, "%d", &i2c_speed[i2cBus]);
+
+ snprintf(buf, sizeof(buf), "echo %d > /sys/bus/i2c/devices/i2c-%d/bus_clk_rate", speed, i2cBus);
+ if (system(buf) == -1) {
+ printf( "Not possible to change bus speed\n");
+ }
+
+ fclose(fptr);
+
+ strcpy(buf, "modprobe i2c_dev");
+
+ if (system(buf) == -1) { /* Ignore errors */
+ }
+
+ snprintf(dev, 19, "/dev/i2c-%d", i2cBus);
+ fd = open(dev, O_RDWR);
+ if (fd < 0) {
+ printf( "Bad handle (%d)\n", fd);
+ return -4;
+ }
+
+ if (ioctl(fd, I2C_FUNCS, &funcs) < 0) {
+ funcs = -1; /* assume all smbus commands allowed */
+ return -6;
+ }
+
+ i2cInfo[slot].fd = fd;
+ i2cInfo[slot].flags = i2cFlags;
+ i2cInfo[slot].funcs = funcs;
+ i2cInfo[slot].state = I2C_OPENED;
+
+ return slot;
+}
+
+int i2cClose(unsigned handle) {
+ char buf[100];
+
+ if (!(handle == 1 || handle == 7)) {
+ printf( "Bad handle (%d)", handle);
+ return -1;
+ }
+
+ if (i2cInfo[handle].state != I2C_OPENED) {
+ printf( "I2c bus is already closed (%d)", handle);
+ return -2;
+ }
+
+ if (i2cInfo[handle].fd >= 0) {close(i2cInfo[handle].fd);}
+
+ i2cInfo[handle].fd = -1;
+ i2cInfo[handle].state = I2C_CLOSED;
+
+ snprintf(buf, sizeof(buf), "echo %d > /sys/bus/i2c/devices/i2c-%d/bus_clk_rate", i2c_speed[handle], handle);
+ if (system(buf) == -1) {
+ printf( "Not possible to return bus speed to original value\n");
+ }
+
+ return 0;
+}
+
+int i2cWriteByteData(unsigned handle, unsigned i2cAddr, unsigned reg, unsigned bVal) {
+ union i2c_smbus_data data;
+ int status = 0;
+
+ if (!(handle == 1 || handle == 7)) {
+ printf( "Bad handle (%d)\n", handle);
+ status = -1;
+ }
+
+ if (i2cInfo[handle].state != I2C_OPENED) {
+ printf( "I2c%d is not open\n", handle);
+ status = -2;
+ }
+
+ if (i2cAddr > 0x7f) {
+ printf( "Bad I2C address (%d)\n", i2cAddr);
+ status = -3;
+ }
+
+ if (reg > 0xFF) {
+ printf( "Register address on device bigger than 0xFF\n");
+ status = -4;
+ }
+
+ if (bVal > 0xFF) {
+ printf( "Value to be written bigger than byte\n");
+ status = -5;
+ }
+
+ i2cInfo[handle].addr = i2cAddr;
+
+ if (ioctl(i2cInfo[handle].fd, I2C_SLAVE, i2cAddr) < 0) {
+ printf( "I2C slave address not found on bus\n");
+ status = -6;
+ }
+
+ if ((i2cInfo[handle].funcs & I2C_FUNC_SMBUS_WRITE_BYTE_DATA) == 0) {
+ printf( "Write byte data function not supported by device\n");
+ status = -7;
+ }
+
+ data.byte = bVal;
+
+ if (i2c_smbus_access(i2cInfo[handle].fd,I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA, &data)<0) {
+ printf( "Not possible to write register\n");
+ status = -8;}
+ return status;
+}
+
+int i2cReadByteData(unsigned handle, unsigned i2cAddr, unsigned reg) {
+ int status = 0;
+ union i2c_smbus_data data;
+
+ if (!(handle == 1 || handle == 7)) {
+ printf( "Bad handle (%d)\n", handle);
+ status = -1;
+ }
+
+ if (i2cInfo[handle].state != I2C_OPENED) {
+ printf( "I2c%d is not open\n", handle);
+ status = -2;
+ }
+
+ if (i2cAddr > 0x7f) {
+ printf( "Bad I2C address (%d)\n", i2cAddr);
+ status = -3;
+ }
+
+ if (reg > 0xFF) {
+ printf( "Register address on device bigger than 0xFF\n");
+ status = -4;
+ }
+
+ i2cInfo[handle].addr = i2cAddr;
+
+ if (ioctl(i2cInfo[handle].fd, I2C_SLAVE, i2cAddr) < 0) {
+ printf( "I2C slave address not found on bus\n");
+ status = -5;
+ }
+
+ if ((i2cInfo[handle].funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA) == 0) {
+ printf( "Write byte data function not supported by device\n");
+ status = -6;
+ }
+
+ if (i2c_smbus_access(i2cInfo[handle].fd,I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA,&data)<0) {
+ printf( "Not possible to read register\n");
+ status = -7;}
+ else {
+ status = 0x0FF & data.byte;
+ }
+ return status;
+}
+
+int i2cWriteWordData(unsigned handle, unsigned i2cAddr, unsigned reg, unsigned wVal) {
+
+ union i2c_smbus_data data;
+ int status = 0;
+
+ if (!(handle == 1 || handle == 7)) {
+ printf( "Bad handle (%d)\n", handle);
+ status = -1;
+ }
+
+ if (i2cInfo[handle].state != I2C_OPENED){
+ printf( "i2c%d is not open\n", handle);
+ status = -2;
+ }
+
+ if (i2cAddr > 0x7f){
+ printf( "Bad I2C address (%d)\n", i2cAddr);
+ status = -3;
+ }
+
+ if (reg > 0xFF){
+ printf( "Register address on device bigger than 0xFF\n");
+ status = -4;
+ }
+
+ if (wVal > 0xFFFF){
+ printf( "Value to be written bigger than word\n");
+ status = -5;
+ }
+
+ i2cInfo[handle].addr = i2cAddr;
+
+ if (ioctl(i2cInfo[handle].fd, I2C_SLAVE, i2cAddr) < 0) {
+ printf( "I2C slave address not found on bus\n");
+ status = -6;
+ }
+
+ if ((i2cInfo[handle].funcs & I2C_FUNC_SMBUS_WRITE_WORD_DATA) == 0){
+ printf( "Write word data function not supported by device\n");
+ status = -7;
+ }
+
+ data.word = wVal;
+
+ if (i2c_smbus_access(i2cInfo[handle].fd,I2C_SMBUS_WRITE, reg, I2C_SMBUS_WORD_DATA, &data)<0) {
+ printf( "Not possible to write register\n");
+ status = -8;}
+ return status;
+}
+
+int i2cReadWordData(unsigned handle, unsigned i2cAddr, unsigned reg) {
+
+ int status = 0;
+ union i2c_smbus_data data;
+
+ if (!(handle == 1 || handle == 7)) {
+ printf( "Bad handle (%d)\n", handle);
+ status = -1;
+ }
+
+ if (i2cInfo[handle].state != I2C_OPENED){
+ printf( "i2c%d is not open\n", handle);
+ status = -2;
+ }
+
+ if (i2cAddr > 0x7f){
+ printf( "Bad I2C address (%d)\n", i2cAddr);
+ status = -3;
+ }
+
+ if (reg > 0xFF){
+ printf( "Register address on device bigger than 0xFF\n");
+ status = -4;
+ }
+
+ i2cInfo[handle].addr = i2cAddr;
+
+ if (ioctl(i2cInfo[handle].fd, I2C_SLAVE, i2cAddr) < 0) {
+ printf( "I2C slave address not found on bus\n");
+ status = -5;
+ }
+
+ if ((i2cInfo[handle].funcs & I2C_FUNC_SMBUS_READ_WORD_DATA) == 0){
+ printf( "Read word data function not supported by device\n");
+ status = -6;
+ }
+
+ if (i2c_smbus_access(i2cInfo[handle].fd,I2C_SMBUS_READ, reg, I2C_SMBUS_WORD_DATA, &data)<0) {
+ printf( "Not possible to read register\n");
+ status = -7;}
+ else
+ {status = 0x0FFFF & data.word;}
+ return status;
+}
+
+int spiOpen(unsigned spiChan, unsigned speed, unsigned mode, unsigned cs_delay, unsigned bits_word, unsigned lsb_first, unsigned cs_change) {
+ char dev[20], buf[100];
+ int fd, slot;
+ int ret = 0;
+
+ if (!(spiChan == 0)) {
+ printf( "Bad spi device (%d) only 0 is accepted\n", spiChan);
+ return -1;
+ }
+
+ if (speed < 0 || speed > 50000000) {
+ printf( "Speed in bits/second (%d) shouldn't be bigger that 50 Mbit/s\n", speed);
+ return -2;
+ }
+
+ if (!(mode == 0 || mode == 1 || mode == 2 || mode == 3)) {
+ printf( "Mode (%d) should be a number between 0 and 3\n", mode);
+ return -3;
+ }
+
+ if (cs_delay < 0 || cs_delay > 1000) {
+ printf( "Cs_delay in us (%d) shouldn't be bigger that 1000 us\n", cs_delay);
+ return -5;
+ }
+
+ if (bits_word < 0 || bits_word > 32) {
+ printf( "Bits per word (%d) should be a number between 0 and 32\n", bits_word);
+ return -6;
+ }
+
+ if (!(lsb_first == 0 || lsb_first == 1)) {
+ printf( "Least significant bit first option (%d) should be 0 or 1\n", lsb_first);
+ return -7;
+ }
+
+ if (!(cs_change == 0 || cs_change == 1)) {
+ printf( "Cs_change option (%d) should be 0 or 1\n", cs_change);
+ return -10;
+ }
+
+ slot = -22;
+
+ if (SpiInfo[spiChan].state == SPI_CLOSED) {
+ slot = spiChan;
+ SpiInfo[slot].state = SPI_RESERVED;
+ }
+ else {
+ printf("Spi bus already open\n");
+ return -11;
+ }
+
+ pin19->CNF[0] |= 0x00000003;
+ *pinmux19 = 0x00000400;
+ *pincfg19 = CFGO_OUT;
+ pin21->CNF[0] |= 0x00000001;
+ *pinmux21 = 0x00000440;
+ *pincfg21 = CFGO_IN;
+ pin23->CNF[0] |= 0x00000003;
+ *pinmux23 = 0x00000400;
+ *pincfg23 = CFGO_OUT;
+ pin24->CNF[0] |= 0x00000003;
+ *pinmux24 = 0x00000400;
+ *pincfg24 = CFGO_OUT;
+ pin_tracker |= (1 << 31);
+
+ strcpy(buf, "modprobe spidev bufsiz=65535");
+
+ if (system(buf) == -1) {
+ printf( "Not possible to load the linux spidev module (driver) \n");
+ return -12;
+ }
+
+ snprintf(dev, 19, "/dev/spidev%d.0", spiChan);
+ fd = open(dev, O_RDWR);
+ if (fd < 0) {
+ printf( "Bad handle (%d)\n", fd);
+ return -13;
+ }
+
+ ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
+ if (ret < 0) {
+ printf("Can't set spi mode\n");
+ return -14;
+ }
+
+ ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
+ if (ret < 0) {
+ printf("Can't get spi mode\n");
+ return -15;
+ }
+
+ ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits_word);
+ if (ret < 0) {
+ printf("Can't set bits per word\n");
+ return -16;
+ }
+
+ ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits_word);
+ if (ret < 0) {
+ printf("Can't get bits per word\n");
+ return -17;
+ }
+
+ ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
+ if (ret < 0) {
+ printf("Can't set max speed hz");
+ return -18;
+ }
+
+ ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
+ if (ret < 0) {
+ printf("Can't get max speed\n");
+ return -19;
+ }
+
+ ret = ioctl(fd, SPI_IOC_WR_LSB_FIRST, &lsb_first);
+ if (ret < 0) {
+ printf("Can't set lsb first\n");
+ return -20;
+ }
+
+ ret = ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb_first);
+ if (ret < 0) {
+ printf("Can't get lsb first\n");
+ return -21;
+ }
+
+ SpiInfo[slot].fd = fd;
+ SpiInfo[slot].mode = mode;
+ SpiInfo[slot].speed = speed;
+ SpiInfo[slot].cs_delay = cs_delay;
+ SpiInfo[slot].cs_change = cs_change;
+ SpiInfo[slot].bits_word = bits_word;
+ SpiInfo[slot].state = SPI_OPENED;
+
+ return slot;
+}
+
+int spiClose(unsigned handle) {
+ if (handle > 1) {
+ printf( "Bad handle (%d)", handle);
+ return -1;
+ }
+
+ if (SpiInfo[handle].state != SPI_OPENED) {
+ printf( "Spi bus is already closed (%d)", handle);
+ return -2;
+ }
+
+ if (SpiInfo[handle].fd >= 0) {
+ close(SpiInfo[handle].fd);
+ }
+
+ //*apbdev_pmc_pwr_det_val = 0x00fcbc2d;
+
+ SpiInfo[handle].fd = -1;
+ SpiInfo[handle].state = SPI_CLOSED;
+
+ return 0;
+}
+
+int spiXfer(unsigned handle, char *txBuf, char *rxBuf, unsigned len) {
+ int ret;
+ struct spi_ioc_transfer tr;
+
+ if (handle > 2) {
+ printf( "Bad handle (%d)\n", handle);
+ return -1;
+ }
+
+ tr.tx_buf = (unsigned long)txBuf;
+ tr.rx_buf = (unsigned long)rxBuf;
+ tr.len = len;
+ tr.delay_usecs = SpiInfo[handle].cs_delay;
+ tr.speed_hz = SpiInfo[handle].speed;
+ tr.bits_per_word = SpiInfo[handle].bits_word;
+ tr.cs_change = SpiInfo[handle].cs_change;
+ tr.tx_nbits = 1;
+ tr.rx_nbits = 1;
+
+ ret = ioctl(SpiInfo[handle].fd, SPI_IOC_MESSAGE(1), &tr);
+ if (ret < 1) {
+ printf("Can't send spi message\n");
+ return -2;
+ }
+ return ret;
+}
diff --git a/scripts/pwm_enabler.sh b/scripts/pwm_enabler.sh
index 31f7acc..6398df5 100644
--- a/scripts/pwm_enabler.sh
+++ b/scripts/pwm_enabler.sh
@@ -4,3 +4,4 @@
bash -c 'echo "1" > /sys/kernel/debug/bpmp/debug/clk/pwm1/state'
bash -c 'echo "1" > /sys/kernel/debug/bpmp/debug/clk/pwm5/state'
bash -c 'echo "1" > /sys/kernel/debug/bpmp/debug/clk/pwm7/state'
+bash -c 'echo "1" > /sys/kernel/debug/bpmp/debug/clk/pwm8/state'