libbcm2835.c (1613B)
1 #include <stdio.h> 2 #include <fcntl.h> 3 #include <unistd.h> 4 #include <sys/mman.h> 5 6 #include "libbcm2835.h" 7 8 static volatile u32_t *reg = MAP_FAILED; 9 10 u32_t __bcm_bank(u32_t pin) { 11 return (pin >> 5); 12 } 13 14 int bcm_init(void) { 15 int fd = open("/dev/gpiomem", O_RDWR | O_SYNC); 16 if (fd < 0) { 17 fprintf(stderr, "Failed to open() /dev/gpiomem!\n"); 18 return -1; 19 } 20 reg = (u32_t *) mmap(NULL, 0xB4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 21 close(fd); 22 if (reg == MAP_FAILED) { 23 fprintf(stderr, "Bad, mmap() failed!\n"); 24 return -1; 25 } 26 return 0; 27 } 28 29 void bcm_fsel(u32_t pin, bcm_fsel_e fsel) { 30 int idx = BCM_FSEL0 + (pin / 10); 31 int shift = 3 * (pin % 10); 32 reg[idx] = (reg[idx] & ~(7 << shift)) | (fsel << shift); 33 } 34 35 void bcm_set(u32_t pin) { 36 int idx = BCM_SET0 + __bcm_bank(pin); 37 reg[idx] = (1 << (pin & 0x1F)); 38 } 39 40 void bcm_clr(u32_t pin) { 41 int idx = BCM_CLR0 + __bcm_bank(pin); 42 reg[idx] = (1 << (pin & 0x1F)); 43 } 44 45 int bcm_lev(u32_t pin) { 46 int idx = BCM_LEV0 + __bcm_bank(pin); 47 return (reg[idx] & (1 << (pin & 0x1F))) != 0; 48 } 49 50 void bcm_pud(u32_t pin, bcm_pud_e pud) { 51 reg[BCM_PUD] = pud; 52 usleep(20); 53 reg[BCM_PUDCLK0 + __bcm_bank(pin)] = (1 << (pin & 0x1F)); 54 usleep(20); 55 reg[BCM_PUD] = PUD_OFF; 56 reg[BCM_PUDCLK0 + __bcm_bank(pin)] = 0x00; 57 } 58 59 void bcm_write(u32_t pin, int level) { 60 level == HIGH 61 ? bcm_set(pin) 62 : bcm_clr(pin); 63 } 64 65 int bcm_read(u32_t pin) { 66 return bcm_lev(pin); 67 } 68 69 void bcm_pulse(u32_t pin, int level, u32_t sleep) { 70 level == HIGH 71 ? bcm_set(pin) 72 : bcm_clr(pin); 73 usleep(sleep); 74 level != HIGH 75 ? bcm_set(pin) 76 : bcm_clr(pin); 77 }