keyboard/qmk/lib/ugfx/boards/base/RaspberryPi/FreeRTOS/gpio.c

135 lines
2.8 KiB
C

/**
* 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;
}