Hi guys, I’ve wrote some functions to control Raspberry Pi IO’s via C code.
The control approach is the same like in Arduino IDE:
void pinMode (unsigned int pinNumber, unsigned int pinFunction)
void digitalWrite (unsigned int pinNumber, unsigned int pinState)
unsigned int digitalRead (unsigned int pinNumber)
Complete C code File:
/* RASPBERRY PI IO access www.engsta.com */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <stdbool.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/errno.h> #include <sys/time.h> #include <err.h> #include <sys/ioctl.h> #include <time.h> /* Pinout: http://www.raspberry-projects.com/pi/pi-hardware/raspberry-pi-model-b-plus/model-b-plus-io-pins # ///////////// # +3V3 OUT -o| 1 2|o- +5V # I2C1 SDA/GPIO2 -o| 3 4|o- +5V # I2C1 SCL/GPIO3 -o| 5 6|o- GND # GP CLK0/GPIO14 -o| 7 08|o- GPIO14/UART0TX # GND -o| 9 10|o- GPIO15/UART0RX # GPIO17 -o| 11 12|o- GPIO18/PWM0 # ARM TMS/GPIO27 -o| 13 14|o- GND # GPIO22 -o| 15 16|o- GPIO23 # +3V3 OUT -o| 17 18|o- GPIO24 # SPI MOSI/GPIO10 -o| 19 20|o- GND # SPI MISO/GPIO9 -o| 21 22|o- GPIO25 # SPI SCLK/GPIO11 -o| 23 22|o- GPIO8/SPI CS0 # GND -o| 25 22|o- GPIO7/SPI CS1 # ID_SD(ID EEprom)-o| 27 22|o- ID_SC(ID EEprom) # GPCLK1/GPIO5 -o| 29 22|o- GND # GPCLK2/GPIO6 -o| 31 32|o- GPIO12 # PWM1/GPIO13 -o| 33 34|o- GND # PWM1/GPIO19 -o| 35 36|o- GPIO16 # GPIO26 -o| 37 38|o- GPIO20 # GND -o| 39 40|o- GPIO21/GPCLK1 # ///////////// */ //#################################################################### // GPIO #define MEM_BASE_GPIO_ADDR 0x20200000UL // GPIO GPIO Register Mem offset #define GPFSEL0_ADDR_OFFSET 0x00 // GPIO Funktion setup #define GPFSEL1_ADDR_OFFSET 0x04 // GPIO Funktion setup #define GPFSEL2_ADDR_OFFSET 0x08 // GPIO Funktion setup #define GPFSEL3_ADDR_OFFSET 0x0C // GPIO Funktion setup #define GPFSEL4_ADDR_OFFSET 0x10 // GPIO Funktion setup #define GPFSEL5_ADDR_OFFSET 0x14 // GPIO Funktion setup #define GPSET0_ADDR_OFFSET 0x1C // Pin Output Set #define GPSET1_ADDR_OFFSET 0x20 // Pin Output Set #define GPCLR0_ADDR_OFFSET 0x28 // Pin Output Clear #define GPCLR1_ADDR_OFFSET 0x2C // Pin Output Clear #define GPLEV0_ADDR_OFFSET 0x34 // Pin Level State register #define GPLEV1_ADDR_OFFSET 0x38 // Pin Level State register #define GPPUD_ADDR_OFFSET 0x94 // Pin Pull-up/down Enable #define GPPUDCLK0_ADDR_OFFSET 0x98 // Pin Pull-up/down ClkIn #define GPPUDCLK1_ADDR_OFFSET 0x9C // Pin Pull-up/down ClkIn // GPIO Option defines for higher level functions #define INPUT 0 #define OUTPUT 1 #define INPUT_PULLUP 2 #define INPUT_PULLDOWN 3 #define HIGH 1 #define LOW 0 volatile unsigned int* gpio; bool GPIOMEMMapDoneFlag = false; int fd = -1; void *gpiomemmap; void GPIOMEMMap (void) { if ((fd = open("/dev/mem", O_RDWR|O_SYNC) ) == -1) { printf("can't open /dev/mem \n"); err(1, "/dev/mem open failed"); } else { gpiomemmap = mmap(NULL,4096,(PROT_READ | PROT_WRITE), MAP_SHARED, fd, MEM_BASE_GPIO_ADDR); close(fd); if (gpiomemmap == MAP_FAILED) { err(2, "/dev/mem memory map failed"); } else { gpio = (volatile unsigned *)gpiomemmap; GPIOMEMMapDoneFlag = true; } } } void pinMode (unsigned int pinNumber, unsigned int pinFunction) { if(!GPIOMEMMapDoneFlag) GPIOMEMMap(); int i; switch (pinFunction) { case INPUT: // disable pull-up/down control bits for responding GPIO *(gpio+GPPUD_ADDR_OFFSET/4) &= 0xFFFFFFFC; // wrtite 0b00 to GPPUD Register // wait at least 150 cycles for ( i= 0; i < 100; i++); // shall be changed to timer based version // clear clock *((gpio+GPPUDCLK0_ADDR_OFFSET/4)+ (pinNumber/32)) &= ~(1 << (pinNumber % 32)); // wait at least 150 cycles for ( i= 0; i < 100; i++); // shall be changed to timer based version // clear responding register bitset to 0b000 for Input *((gpio+GPFSEL0_ADDR_OFFSET/4)+ (pinNumber/10)) &= ~((1 << (3*(pinNumber % 10))) | (1 << (3*(pinNumber % 10)+1)) | (1 << (3*(pinNumber % 10)+2))); break; case OUTPUT: // disable pull-up/down control bits for responding GPIO *(gpio+GPPUD_ADDR_OFFSET/4) &= 0xFFFFFFFC; // wrtite 0b00 to GPPUD Register // wait at least 150 cycles for ( i= 0; i < 100; i++); // shall be changed to timer based version // clear clock *((gpio+GPPUDCLK0_ADDR_OFFSET/4)+ (pinNumber/32)) &= ~(1 << (pinNumber % 32)); // wait at least 150 cycles for ( i= 0; i < 100; i++); // shall be changed to timer based version // clear current bit setup, set register bitset to 0b000 *((gpio+GPFSEL0_ADDR_OFFSET/4)+ (pinNumber/10)) &= ~((1 << (3*(pinNumber % 10))) | (1 << (3*(pinNumber % 10)+1)) | (1 << (3*(pinNumber % 10)+2))); // set responding register bitset to 0b001 for output *((gpio+GPFSEL0_ADDR_OFFSET/4)+ (pinNumber/10)) = (1 << (3*(pinNumber % 10))); break; case INPUT_PULLUP: // clear the responding GPFSEL register bitset to 0b000 for Input *((gpio+GPFSEL0_ADDR_OFFSET/4)+ (pinNumber/10)) &= ~((1 << (3*(pinNumber % 10))) | (1 << (3*(pinNumber % 10)+1)) | (1 << (3*(pinNumber % 10)+2))); // enable pull-up for responding GPIO *(gpio+GPPUD_ADDR_OFFSET/4) |= 0x00000002; // wrtite 0b10 to GPPUD Register // wait at least 150 cycles for ( i= 0; i < 100; i++); // clock in the control signal of responding GPIO *((gpio+GPPUDCLK0_ADDR_OFFSET/4)+ (pinNumber/32)) = (1 << pinNumber); // wait at least 150 cycles for ( i= 0; i < 100; i++); // shall be changed to timer based version // clear GPPUD register *((gpio+GPPUD_ADDR_OFFSET/4)+ (pinNumber/10)) &= 0xFFFFFFFC; // wrtite 0b00 to GPPUD Register // clear clock *((gpio+GPPUDCLK0_ADDR_OFFSET/4)+ (pinNumber/32)) &= ~(1 << (pinNumber % 32)); break; case INPUT_PULLDOWN: // clear the responding GPFSEL register bitset to 0b000 for Input *((gpio+GPFSEL0_ADDR_OFFSET/4)+ (pinNumber/10)) &= ~((1 << (3*(pinNumber % 10))) | (1 << (3*(pinNumber % 10)+1)) | (1 << (3*(pinNumber % 10)+2))); // enable pull-up for responding GPIO *(gpio+GPPUD_ADDR_OFFSET/4) |= 0x00000001; // wrtite 0b10 to GPPUD Register // wait at least 150 cycles for ( i= 0; i < 100; i++); // clock in the control signal of responding GPIO *((gpio+GPPUDCLK0_ADDR_OFFSET/4)+ (pinNumber/32)) = (1 << pinNumber); // wait at least 150 cycles for ( i= 0; i < 100; i++); // shall be changed to timer based version // clear GPPUD register *((gpio+GPPUD_ADDR_OFFSET/4)+ (pinNumber/10)) &= 0xFFFFFFFC; // wrtite 0b00 to GPPUD Register // clear clock *((gpio+GPPUDCLK0_ADDR_OFFSET/4)+ (pinNumber/32)) &= ~(1 << (pinNumber % 32)); break; default: break; } } void digitalWrite (unsigned int pinNumber, unsigned int pinState) { if (pinState) { *((gpio+GPSET0_ADDR_OFFSET/4)+ (unsigned int)(pinNumber/32)) = (1 << (pinNumber % 32)); } else { *((gpio+GPCLR0_ADDR_OFFSET/4)+ (unsigned int)(pinNumber/32)) = (1 << (pinNumber % 32)); } } unsigned int digitalRead (unsigned int pinNumber){ if(*((gpio+GPLEV0_ADDR_OFFSET/4)+ (unsigned int)(pinNumber/32)) & (1 << pinNumber % 32)) { return 1; } else { return 0; } } void delayMicrosecondsHard (unsigned int howLong) { struct timeval tNow, tLong, tEnd ; gettimeofday (&tNow, NULL) ; tLong.tv_sec = howLong / 1000000 ; tLong.tv_usec = howLong % 1000000 ; timeradd (&tNow, &tLong, &tEnd) ; while (timercmp (&tNow, &tEnd, <)) gettimeofday (&tNow, NULL); } void delay (unsigned int ms) { delayMicrosecondsHard(ms * 1000); }
Click to rate this post!
[Total: 2 Average: 5]