nizam
Posts: 15
Joined: Wed Jul 30, 2014 1:52 am

C using MMAP I/O for raspberry pi

Fri Oct 17, 2014 3:18 am

I try to follow the gerboard manual but still without using the gertboard, only by using raspberry pi. Could somebody tell me what is wrong with it? I already compile it but there is nothing.This is the code I took from Gert van Loo and Dom blinking LED code and use it for ultrasonic sensor.Anyway thanks for helping :)

Code: Select all

#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <time.h>

#define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024)

int mem_fd;
void *gpio_map;

// I/O access
volatile unsigned *gpio;


// GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or SET_GPIO_ALT(x,y)
#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
#define OUT_GPIO(g) *(gpio+((g)/10)) |= (1<<(((g)%10)*3))
#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))

#define GPIO_SET *(gpio+7) // sets bits which are 1 ignores bits which are 0
#define GPIO_CLR *(gpio+10) // clears bits which are 1 ignores bits which are 0

#define GET_GPIO *(gpio+13)

#define GPIO_PULL *(gpio+37) // Pull up/pull down
#define GPIO_PULLCLK0 *(gpio+38) // Pull up/pull down clock

void setup_io();

int main(int argc, char **argv)
{
int distance;
time_t start= 0;
time_t end= 0;
time_t elapsed = 0;
// Set up gpi pointer for direct register access
setup_io();
INP_GPIO(23); // must use INP_GPIO before we can use OUT_GPIO
OUT_GPIO(23);
INP_GPIO(7); //input for echo pin

GPIO_CLR = (1 << 23);
sleep(0.1) // allow module to settle
GPIO_SET = (1<<23);
sleep(0.00001); // send pulse 10us 
GPIO_CLR = (1<<23);

while ((GET_GPIO = ( 0<<7)))
{} // i already change the get_gpio
start = time(NULL);
while ((GET_GPIO = ( 1<<7))) 
{} // input HIGH
end = time(NULL);
elapsed = end- start;
distance = (elapsed*34000)/2 ; //in cm
printf("distance: %d cm¥n", distance);


return 0;

} // main


//
// Set up a memory regions to access GPIO
//
void setup_io()
{
/* open /dev/mem */
if ((mem_fd = open("/dev/mem", O_RDWR|O_SYNC) ) < 0) {
printf("can't open /dev/mem \n");
exit(-1);
}

/* mmap GPIO */
gpio_map = mmap(
NULL, //Any adddress in our space will do
BLOCK_SIZE, //Map length
PROT_READ|PROT_WRITE,// Enable reading & writting to mapped memory
MAP_SHARED, //Shared with other processes
mem_fd, //File to map
GPIO_BASE //Offset to GPIO peripheral
);

close(mem_fd); //No need to keep mem_fd open after mmap

if (gpio_map == MAP_FAILED) {
printf("mmap error %d\n", (int)gpio_map);//errno also set!
exit(-1);
}

// Always use volatile pointer!
gpio = (volatile unsigned *)gpio_map;


} // setup_io

Heater
Posts: 13926
Joined: Tue Jul 17, 2012 3:02 pm

Re: C using MMAP I/O for raspberry pi

Fri Oct 17, 2014 5:48 am

What do you mean "there is nothing"?

Do yo get the error message "can't open /dev/mem"?

Are you running your code as root user?

I played with mmap code from here: http://elinux.org/RPi_Low-level_peripherals which looks like it should be the same. Worked fine.
Memory in C++ is a leaky abstraction .

nizam
Posts: 15
Joined: Wed Jul 30, 2014 1:52 am

Re: C using MMAP I/O for raspberry pi

Fri Oct 17, 2014 6:02 am

Thanks for replying my post. I didn't get any error. But when compiling there seems like it stuck. It should be state the distance detected from the ultrasonic sensor but it doesn't come out :(

User avatar
joan
Posts: 14476
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: C using MMAP I/O for raspberry pi

Fri Oct 17, 2014 7:49 am

You are probably not sending a trigger pulse.

man 3 sleep # there are several sleep commands, you want manual 3

will show that sleep is in units of a second, so sleep(0.1) and sleep(0.0001) etc. will result in sleep(0) which is no delay at all.

Perhaps you meant to use usleep which is in units of microseconds,

man usleep

clock on my laptop returns units of 1/100ths of a second. You probably won't get the resolution you need.

man 3 clock

Have a look at gettimeofday.

man gettimeofday

nizam
Posts: 15
Joined: Wed Jul 30, 2014 1:52 am

Re: C using MMAP I/O for raspberry pi

Fri Oct 17, 2014 8:37 am

Thanks Joan. I follow your advice and end up rewrite back my code. But still the same problem appear.

this my code.

Code: Select all

#include <sys/time.h>
int main(int argc, char **argv)
{
int distance;
struct timeval start,end;;
double elapsed ;
// Set up gpi pointer for direct register access
setup_io();
INP_GPIO(23); // must use INP_GPIO before we can use OUT_GPIO
OUT_GPIO(23);
INP_GPIO(7); //input for echo pin

GPIO_CLR = (1 << 23);
usleep(30000) // allow module to settle

printf("starting measurement")
GPIO_SET = (1<<23);
usleep(10); // send pulse 10us 
GPIO_CLR = (1<<23);


while ((GPIO_CLR = ( 0<<7)))
{} 
gettimeofday(&start,NULL);
while ((GPIO_SET = ( 1<<7))) 
{} // input HIGH
gettimeofday(&end,NULL);
elapsed = (end.tv_sec - start.tv_sec);
distance = (elapsed)/2 ; //in cm
printf("distance: %d cm¥n", distance);


return 0;

}

User avatar
joan
Posts: 14476
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: C using MMAP I/O for raspberry pi

Sun Oct 19, 2014 8:05 am

I'm not a great fan of those macros.

while ((GPIO_CLR = ( 0<<7)))

Should that be

while ((GPIO_CLR = ( 1<<7)))

User avatar
Redrobes
Posts: 80
Joined: Mon Dec 26, 2011 9:19 pm
Location: S.W. UK
Contact: Website

Re: C using MMAP I/O for raspberry pi

Sun Oct 19, 2014 10:07 am

I think you may need an == instead of = as well. Maybe. Its hard to read the code like that. Looks to me like you need to set the GPIO_CLR value in which case putting that in a while loop seems like it might loop forever.

Using macros like this is poor style. You should only do this if you need the absolute max performance and even then the format that you have used is not great. You would be better off writing small functions to write and read values and then return a code which you could put into the loop test. Something like.

while( !GPIO_Clr() ) { }

etc.

Return to “C/C++”