raspberrypi gpio examples with c language – part 2- blink led

now we are going deep.

how to reach gpio pins on raspberrypi. as I sad before

one of them /sys/class/gpio file system. if you use it, it will be slow. you can find performance tests

one of them is writing a linux driver. it will be fast

and the last one is, user space driver. it will be also fast.

I will explain in this article. writing a user space driver.

I will write this code explanation with my codes.

also we need the arm bcm2835 peripherals document.

we will map raspberrypi memory. and change values in memory.

first of all we are getting peripherals start phsical address from document(page 6)

#define PERIPHERALS_BASE_PHYSICAL 0x20000000

then we are getting gpio register physical start address from document(page 90)

this document says that gpio peripherals start from 0x7e20 0000, but this address are not physical address. we can easily convert them. 0x7e20 0000 means PERIPHERALS_BASE_PHYSICAL+ 0x20 0000 pyhsical address.address

#define PERIPHERALS_REGISTER_PHYSICAL 0x200000

raspberry pi has 54 GPIOS pin in SOC.   now we will map memory to our program. you must be root to do this.

creating some variables

//lenght of registers end to top

#define REGISTERS_SIZE (0x7E2000B0-0x7E200000)

int mem_fd;
volatile int * gpio;

opening memory device

mem_fd = open(“/dev/mem”, O_RDWR | O_SYNC);

mapping to our space

gpio = (volatile int *) mmap(NULL, REGISTERS_SIZE,PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd,
(PERIPHERALS_BASE_PHYSICAL + PERIPHERALS_REGISTER_PHYSICAL));

as above picture, there is “GPIO Function Select 0″,”GPIO Function Select 1″ etc… there is 6 count. every them is 32 bits. this is important!

you can use this registers to manage functions of  pins.  you can set to OUTPUT,INPUT,TxD or etc.

you can manage pins with 3 bits

000 = GPIO Pin  is an input
001 = GPIO Pin  is an output
100 = GPIO Pin  takes alternate function 0
101 = GPIO Pin  takes alternate function 1
110 = GPIO Pin  takes alternate function 2
111 = GPIO Pin  takes alternate function 3
011 = GPIO Pin  takes alternate function 4
010 = GPIO Pin  takes alternate function 5

alternate function means, you can set some bits for using different functions. suppose I2C,RxD,PWM etc…

you can find which pin can have an alternate  function from page 102. a sample image below

alt

lets continue,every 32  function  select  bits can manage only 10 pins. ( 3×10=30).

if you want to manage pin 21, you can calculate its position like this

24/10=2  this means that your pin is in “GPIO Function Select 3″ bits.

#define PIN_MODE_POSITION(number) (number/10)

every 3 bits is assigned to a pin,

24%10=4 you are the 5th pin in “GPIO Function Select 3″ bits. and every pin has 3 bit than 12-13-14 is your pin

#define PIN_MODE_SHIFT(number)   ((number%10)*3)

if you set 000  then pin 24 is input

if you set 001 then pin 24 is output

if you set 100 then pin 24 is ALT_FUNC_0 from above picture.

for setting pin INPUT

*(gpio + PIN_MODE_POSITION(number)) &= ~(0x0000007<< PIN_MODE_SHIFT(number));

for setting pin OUTPUT

first setting all zero (000)

*(gpio + PIN_MODE_POSITION(number)) &= ~(0x0000007<< PIN_MODE_SHIFT(number));

then setting 001
*(gpio + PIN_MODE_POSITION(number)) |=  0x01<< PIN_MODE_SHIFT(number);

lets continue to set LOW and  set HIGH

First set HIGH

you must use below addresses

0x 7E20 001C      GPSET0 GPIO Pin Output Set 0
0x 7E20 0020       GPSET1 GPIO Pin Output Set 1

you have got 2 registers 32 bit

as I said, there is 54 pin on raspi SOC , then you need 64 bit

if pin number is 24 then where your address start

24/32=0

#define PIN_WRITE_POSITION(number)  ((number/32))

what is your address

gpio + 7 +PIN_WRITE_POSITION(24) is your address

what will you write that address  1<< number%32

#define PIN_WRITE_SHIFT(number)  (number%32)

to set HIGH

*(gpio + 7 + PIN_WRITE_POSITION(number) ) = 1 << PIN_WRITE_SHIFT(number);

 

Second set LOW

find output clear parts from document as above,

0x 7E20 0028 GPCLR0 GPIO Pin Output Clear 0
0x 7E20 002C GPCLR1 GPIO Pin Output Clear 1

you have got 64 bits again

to set low

*(gpio + 10 + PIN_WRITE_POSITION(number) ) = 1 << PIN_WRITE_SHIFT(number);

 

and this is the main.c file main

download and

gcc -o blink main.c

./blink

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir


*

Şu HTML etiketlerini ve özelliklerini kullanabilirsiniz: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>