aboutsummaryrefslogtreecommitdiffstats
path: root/boards/base/RaspberryPi/FreeRTOS/gpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'boards/base/RaspberryPi/FreeRTOS/gpio.c')
-rw-r--r--boards/base/RaspberryPi/FreeRTOS/gpio.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/boards/base/RaspberryPi/FreeRTOS/gpio.c b/boards/base/RaspberryPi/FreeRTOS/gpio.c
new file mode 100644
index 00000000..485de897
--- /dev/null
+++ b/boards/base/RaspberryPi/FreeRTOS/gpio.c
@@ -0,0 +1,134 @@
+/**
+ * Quick and very Dirty GPIO API.
+ *
+ **/
+
+#include "gpio.h"
+
+typedef struct {
+ unsigned long GPFSEL[6]; ///< Function selection registers.
+ unsigned long Reserved_1;
+ unsigned long GPSET[2];
+ unsigned long Reserved_2;
+ unsigned long GPCLR[2];
+ unsigned long Reserved_3;
+ unsigned long GPLEV[2];
+ unsigned long Reserved_4;
+ unsigned long GPEDS[2];
+ unsigned long Reserved_5;
+ unsigned long GPREN[2];
+ unsigned long Reserved_6;
+ unsigned long GPFEN[2];
+ unsigned long Reserved_7;
+ unsigned long GPHEN[2];
+ unsigned long Reserved_8;
+ unsigned long GPLEN[2];
+ unsigned long Reserved_9;
+ unsigned long GPAREN[2];
+ unsigned long Reserved_A;
+ unsigned long GPAFEN[2];
+ unsigned long Reserved_B;
+ unsigned long GPPUD[1];
+ unsigned long GPPUDCLK[2];
+ //Ignoring the reserved and test bytes
+} BCM2835_GPIO_REGS;
+
+volatile BCM2835_GPIO_REGS * const pRegs = (BCM2835_GPIO_REGS *) (0x20200000);
+
+
+void SetGpioFunction(unsigned int pinNum, unsigned int funcNum) {
+
+ int offset = pinNum / 10;
+
+ unsigned long val = pRegs->GPFSEL[offset]; // Read in the original register value.
+
+ int item = pinNum % 10;
+ val &= ~(0x7 << (item * 3));
+ val |= ((funcNum & 0x7) << (item * 3));
+ pRegs->GPFSEL[offset] = val;
+}
+
+void SetGpioDirection(unsigned int pinNum, enum GPIO_DIR dir) {
+ SetGpioFunction(pinNum,dir);
+}
+
+void SetGpio(unsigned int pinNum, unsigned int pinVal) {
+ unsigned long offset=pinNum/32;
+ unsigned long mask=(1<<(pinNum%32));
+
+ if(pinVal) {
+ pRegs->GPSET[offset]|=mask;
+ } else {
+ pRegs->GPCLR[offset]|=mask;
+ }
+}
+
+int ReadGpio(unsigned int pinNum) {
+ return ((pRegs->GPLEV[pinNum/32])>>(pinNum%32))&1;
+}
+
+void EnableGpioDetect(unsigned int pinNum, enum DETECT_TYPE type)
+{
+ unsigned long mask=(1<<pinNum);
+ unsigned long offset=pinNum/32;
+
+ switch(type) {
+ case DETECT_RISING:
+ pRegs->GPREN[offset]|=mask;
+ break;
+ case DETECT_FALLING:
+ pRegs->GPFEN[offset]|=mask;
+ break;
+ case DETECT_HIGH:
+ pRegs->GPHEN[offset]|=mask;
+ break;
+ case DETECT_LOW:
+ pRegs->GPLEN[offset]|=mask;
+ break;
+ case DETECT_RISING_ASYNC:
+ pRegs->GPAREN[offset]|=mask;
+ break;
+ case DETECT_FALLING_ASYNC:
+ pRegs->GPAFEN[offset]|=mask;
+ break;
+ case DETECT_NONE:
+ break;
+ }
+}
+
+void DisableGpioDetect(unsigned int pinNum, enum DETECT_TYPE type)
+{
+ unsigned long mask=~(1<<(pinNum%32));
+ unsigned long offset=pinNum/32;
+
+ switch(type) {
+ case DETECT_RISING:
+ pRegs->GPREN[offset]&=mask;
+ break;
+ case DETECT_FALLING:
+ pRegs->GPFEN[offset]&=mask;
+ break;
+ case DETECT_HIGH:
+ pRegs->GPHEN[offset]&=mask;
+ break;
+ case DETECT_LOW:
+ pRegs->GPLEN[offset]&=mask;
+ break;
+ case DETECT_RISING_ASYNC:
+ pRegs->GPAREN[offset]&=mask;
+ break;
+ case DETECT_FALLING_ASYNC:
+ pRegs->GPAFEN[offset]&=mask;
+ break;
+ case DETECT_NONE:
+ break;
+ }
+}
+
+void ClearGpioInterrupt(unsigned int pinNum)
+{
+ unsigned long mask=(1<<(pinNum%32));
+ unsigned long offset=pinNum/32;
+
+ pRegs->GPEDS[offset]=mask;
+}