From: Peck H K. <pk...@me...> - 2008-07-15 20:56:30
|
Hi there, I am trying to detect the external pulses on the Gumstix Connex via a PIC and use the pulses to control the sampling rate of an ADC (which samples and stores the data on the Gumstix CF card). However, I'm having problems trying to receive the pulses accurately. I've tried using the following example programs to detect the pulses, however it didn't work for me. I've verified the PIC pulses on a scope and it's working fine. 1. Using the program (http://docwiki.gumstix.org/index.php/Sample_code/C/gpregs) , I tried to update the "gpio-status" of the GPIO line on the gumstix and when it is set, it will trigger the ADC. However, the number of detected pulses counts was more than what the PIC produced. I would suspect that the program reads in all the "logic ones" during the loop and increment the pulse counts. Modifying the code to detect only the "rising edge" (i.e. compare between gpio-status-pre and gpio-status-post) did not help either. Is there a smarter way to work around this? 2. Using the gpio-event program (http://docwiki.gumstix.org/index.php/GPIO_event) I couldn't get it to work at all, although I have no problem making the executable and installing the kernel module on the gumstix. When I typed "gpio-event 58:r:20", apparently no edge was detected as there was no output on the screen. I was wondering if I am doing something wrong. I will greatly appreciate if anyone can advise me on how I can modify any of the existing codes to detect the number of pulses accurately (i.e. every edge of signal pulse from the PIC)? My understanding is that the Gumstix will set the GPIO signal when the incoming voltage level is above 3.3V. Am I right? Thanks for any help in advance. Peck |
From: Dave H. <dhy...@gm...> - 2008-07-15 21:36:41
|
Hi Peck, > 2. Using the gpio-event program > (http://docwiki.gumstix.org/index.php/GPIO_event) I couldn't get it to work > at all, although I have no problem making the executable and installing the > kernel module on the gumstix. When I typed "gpio-event 58:r:20", apparently > no edge was detected as there was no output on the screen. I was wondering > if I am doing something wrong. gpio-event should work fine. Just running gpio-event 58:r:20 registers GPIO 58 to be monitored. You need to also run a program to read /dev/gpio-event to receive the events. You can use: gpio-event -m to monitor and report the events. Have you tried manually connecting the gpio input between ground and Vcc? That should definitely trigger gpio-event. Do you have ground connected between the gumstix and your PIC? That's a common problem (voltages are relative to ground - no ground, and the voltages don't mean anything). cat /proc/interrupts should show the number of interrupts that occur for each GPIO. Irq 81 should correspond to GPIO 58 GPIO 58 is LDD0. Is that what your signal from the PIC connects to? Does your build disable the LCD? -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ |
From: Peck H K. <pk...@me...> - 2008-07-16 09:30:10
|
Hi Dave, Thank you so much for your helpful explanation. Now that I understand that using the command "gpio-event 58:r:20" helps to register and monitor the GPIO pin. And that I will need to use the command "gpio-event -m" or "cat /dev/gpio-event" to printf the events. I am now able to read these events successfully - the Vcc and the common ground between the gumstix and PIC are working fine. Can I ask how can I incorporate these codes into the user program to monitor the trigger edges and thereafter execute the ADC sampling? Can you give me some hints on which part of the codes I should look at and do modification to use the gpio-event in my program? Something like: int gptrig, count; gpio-event 58:r:20 gptrig = "gpio-event -m" if (gptrig){ execute_ADC(); count++; } Is this workable? Also I will appreciate if you can advise me on how I can set the GPIO 58-LDD0 as high priority interrupt? The reason is that I am using multithreading and I need to make sure that having to detect the trigger pulses to read the ADC samples precedes over the other threads. Thanks. Peck -----Original Message----- From: gum...@li... [mailto:gum...@li...] On Behalf Of Dave Hylands Sent: 15 July 2008 22:37 To: General mailing list for gumstix users. Subject: Re: [Gumstix-users] How to detect GPIO signal edge to control ADC sampling Hi Peck, > 2. Using the gpio-event program > (http://docwiki.gumstix.org/index.php/GPIO_event) I couldn't get it to work > at all, although I have no problem making the executable and installing the > kernel module on the gumstix. When I typed "gpio-event 58:r:20", apparently > no edge was detected as there was no output on the screen. I was wondering > if I am doing something wrong. gpio-event should work fine. Just running gpio-event 58:r:20 registers GPIO 58 to be monitored. You need to also run a program to read /dev/gpio-event to receive the events. You can use: gpio-event -m to monitor and report the events. Have you tried manually connecting the gpio input between ground and Vcc? That should definitely trigger gpio-event. Do you have ground connected between the gumstix and your PIC? That's a common problem (voltages are relative to ground - no ground, and the voltages don't mean anything). cat /proc/interrupts should show the number of interrupts that occur for each GPIO. Irq 81 should correspond to GPIO 58 GPIO 58 is LDD0. Is that what your signal from the PIC connects to? Does your build disable the LCD? -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ gumstix-users mailing list gum...@li... https://lists.sourceforge.net/lists/listinfo/gumstix-users |
From: Dave H. <dhy...@gm...> - 2008-07-16 15:42:31
|
Hi peck, > Can I ask how can I incorporate these codes into the user program to monitor > the trigger edges and thereafter execute the ADC sampling? Can you give me > some hints on which part of the codes I should look at and do modification > to use the gpio-event in my program? In your C code, you should be able to do something like this (mostly copied and pasted from gpio-event.c) #include <stdio.h> #include <gpio-event-drv.h" FILE *evFs; GPIO_EventMonitor_t monitor; if (( evFs = fopen( "/dev/gpio-event", "r" )) == NULL ) { // error } // Ask gpio-event-drv to monitor a pin. Call multiple times to register multiple pins monitor.gpio = 58; monitor.onOff = 1; monitor.edgeType = GPIO_EventRisingEdge; monitor.debounceMilliSec = 20; if ( ioctl( fileno( evFs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor ) != 0 ) { // error } // Use the following to set the reporting to be in binary mode ioctl( fileno( evFs ), GPIO_EVENT_IOCTL_SET_READ_MODE, 1 ); // Use select or a separate thread (see gpio-event.c for select example) while ( 1 ) { GPIO_Event_t event; fread( &event, 1 , sizeof( event ), evFs ); printf( "%2d %c %ld.%06ld", event.gpio, (( event.edgeType == GPIO_EventRisingEdge ) ? 'R' : 'F' ), event.time.tv_sec, event.time.tv_usec ); } -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ |
From: Peck H K. <pk...@me...> - 2008-07-16 15:53:00
|
Hi Dave, I have tried to modify the codes in "gpio-event.c" to count the number of received pulses on the gumstix. However, it appears that the pulse count does not match the pulses sent out by the PIC (the count is far too less). I was wondering if I am missing something here. Can you kindly have a quick look at the modified codes and advise me on the possible mistakes that I could have made: #include <stdio.h> #include <stdlib.h> #include <getopt.h> #include <fcntl.h> #include <ctype.h> #include <unistd.h> #include <string.h> #include <time.h> #include "gpio-event-drv.h" int main( int argc, char **argv ) { GPIO_EventMonitor_t monitor; FILE *fs; if (( fs = fopen( "/dev/gpio-event", "r" )) < 0 ) { perror( "Unable to open /dev/gpio-event" ); exit( 1 ); } // Define GPIO 58 -rising edge and debounce = 20 monitor.gpio = 58; monitor.onOff = 1; monitor.edgeType = GPIO_EventRisingEdge; //monitor.edgeType = GPIO_EventFallingEdge; monitor.debounceMilliSec = 20; if ( ioctl( fileno( fs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor ) != 0 ) { perror( "ioctl GPIO_EVENT_IOCTL_MONITOR_GPIO failed" ); } // Determine the trigger rate int count=0; time_t prevTime; time_t endTime; prevTime = time( NULL ); while ( time( NULL ) == prevTime ) {;} endTime = prevTime + 10; while (time( NULL ) <= endTime) //while (1) { char argStr[ 60 ]; if ( fgets( argStr, sizeof( argStr ), fs ) != NULL ) { count++; } } printf( "Read: '%d'\n\n", count); fclose( fs ); exit( 0 ); return 0; } I really appreciate your great help. Thanks. Peck -----Original Message----- From: gum...@li... [mailto:gum...@li...] On Behalf Of Peck H Koh Sent: 16 July 2008 10:30 To: 'General mailing list for gumstix users.' Subject: Re: [Gumstix-users] How to detect GPIO signal edge to control ADC sampling Hi Dave, Thank you so much for your helpful explanation. Now that I understand that using the command "gpio-event 58:r:20" helps to register and monitor the GPIO pin. And that I will need to use the command "gpio-event -m" or "cat /dev/gpio-event" to printf the events. I am now able to read these events successfully - the Vcc and the common ground between the gumstix and PIC are working fine. Can I ask how can I incorporate these codes into the user program to monitor the trigger edges and thereafter execute the ADC sampling? Can you give me some hints on which part of the codes I should look at and do modification to use the gpio-event in my program? Something like: int gptrig, count; gpio-event 58:r:20 gptrig = "gpio-event -m" if (gptrig){ execute_ADC(); count++; } Is this workable? Also I will appreciate if you can advise me on how I can set the GPIO 58-LDD0 as high priority interrupt? The reason is that I am using multithreading and I need to make sure that having to detect the trigger pulses to read the ADC samples precedes over the other threads. Thanks. Peck -----Original Message----- From: gum...@li... [mailto:gum...@li...] On Behalf Of Dave Hylands Sent: 15 July 2008 22:37 To: General mailing list for gumstix users. Subject: Re: [Gumstix-users] How to detect GPIO signal edge to control ADC sampling Hi Peck, > 2. Using the gpio-event program > (http://docwiki.gumstix.org/index.php/GPIO_event) I couldn't get it to work > at all, although I have no problem making the executable and installing the > kernel module on the gumstix. When I typed "gpio-event 58:r:20", apparently > no edge was detected as there was no output on the screen. I was wondering > if I am doing something wrong. gpio-event should work fine. Just running gpio-event 58:r:20 registers GPIO 58 to be monitored. You need to also run a program to read /dev/gpio-event to receive the events. You can use: gpio-event -m to monitor and report the events. Have you tried manually connecting the gpio input between ground and Vcc? That should definitely trigger gpio-event. Do you have ground connected between the gumstix and your PIC? That's a common problem (voltages are relative to ground - no ground, and the voltages don't mean anything). cat /proc/interrupts should show the number of interrupts that occur for each GPIO. Irq 81 should correspond to GPIO 58 GPIO 58 is LDD0. Is that what your signal from the PIC connects to? Does your build disable the LCD? -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ gumstix-users mailing list gum...@li... https://lists.sourceforge.net/lists/listinfo/gumstix-users ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ gumstix-users mailing list gum...@li... https://lists.sourceforge.net/lists/listinfo/gumstix-users |
From: Dave H. <dhy...@gm...> - 2008-07-16 15:59:47
|
Hi Peck, > I have tried to modify the codes in "gpio-event.c" to count the number of > received pulses on the gumstix. However, it appears that the pulse count > does not match the pulses sent out by the PIC (the count is far too less). I > was wondering if I am missing something here. Can you kindly have a quick > look at the modified codes and advise me on the possible mistakes that I > could have made: What pulse rate is being sent? Using a 20 millisecond debounce will limit the input rate to about 30 pulses/sec. You really only need to use debounce with a mechanical switch. I'd recommend setting debounce to zero for use with a clean signal (like the one you'd get from a PIC). -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ |
From: Peck H K. <pk...@me...> - 2008-07-16 19:38:08
|
Hi Dave, Thanks for your helpful advice. I am hoping to detect the pulse rate from the PIC at 7KHz (hence every 0.14 millisec). I tried to estimate the elapsed time between the receiving pulses (using your codes) when I specified the debounce to zero and the elapsed time was about 2.5 millisec. Why do you think causes this delay? Is there a way that I can improve on these rates and detect these pulses (using gpio-event) at 7KHz? Pardon me for my poor programming skill but I'm confused by the command "ioctl( fileno( fs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor )". My guess is that this command monitors the GPIO event based on what is being specified in the "monitor" structure. Should I be using this command if I need to set an output variable whenever an edge trigger is being detected e.g. trig_pulse= ioctl( fileno( fs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor )? Thereafter I will use the trig_pulse to trigger the ADC. Once again thank you so much for your time and help. Peck -----Original Message----- From: gum...@li... [mailto:gum...@li...] On Behalf Of Dave Hylands Sent: 16 July 2008 17:00 To: General mailing list for gumstix users. Subject: Re: [Gumstix-users] How to detect GPIO signal edge to control ADC sampling Hi Peck, > I have tried to modify the codes in "gpio-event.c" to count the number of > received pulses on the gumstix. However, it appears that the pulse count > does not match the pulses sent out by the PIC (the count is far too less). I > was wondering if I am missing something here. Can you kindly have a quick > look at the modified codes and advise me on the possible mistakes that I > could have made: What pulse rate is being sent? Using a 20 millisecond debounce will limit the input rate to about 30 pulses/sec. You really only need to use debounce with a mechanical switch. I'd recommend setting debounce to zero for use with a clean signal (like the one you'd get from a PIC). -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ gumstix-users mailing list gum...@li... https://lists.sourceforge.net/lists/listinfo/gumstix-users |
From: Dave H. <dhy...@gm...> - 2008-07-16 20:03:36
|
Hi Peck, > Thanks for your helpful advice. > > I am hoping to detect the pulse rate from the PIC at 7KHz (hence every 0.14 > millisec). > > I tried to estimate the elapsed time between the receiving pulses (using > your codes) when I specified the debounce to zero and the elapsed time was > about 2.5 millisec. Why do you think causes this delay? Not sure. Are you saying that the delta in the time stamps is 2.5 msec? (each event reported from gpio-event has a timestamp associated with it). How many did you check? > Is there a way that I can improve on these rates and detect these pulses > (using gpio-event) at 7KHz? I'd have to try it and see. gpio-event should be able to deal with 7 kHz without any troubles, but I'd need to double check. Simple things like printk's in the code can mess stuff up. You may need to elevate the priority of your process. > Pardon me for my poor programming skill but I'm confused by the command > "ioctl( fileno( fs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor )". My guess > is that this command monitors the GPIO event based on what is being > specified in the "monitor" structure. Should I be using this command if I > need to set an output variable whenever an edge trigger is being detected > e.g. trig_pulse= ioctl( fileno( fs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, > &monitor )? Thereafter I will use the trig_pulse to trigger the ADC. This ioctl sets up a gpio to be monitored. It doesn't have any capability to set a gpio for output. You'd probably want to use the gpreg example to do that. Having control go from kernel mode into user-mode at 7 kHz will have jitter when other things happen on the system. In order to do this properly, you should have the ISR for the input GPIO toggle initiate the ADC sample. Trying to do stuff at 7 kHz in user space, I can pretty much guarantee that you'll miss samples here and there, especially if you're connected to a network or have anything else running that might disable interrupts for more than your 0.14 milliseconds. I'm surprised that you don't use the PIC to grab the ADC samples and send them to the gumstix over SPI or something. -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ |
From: Peck H K. <pk...@me...> - 2008-07-17 11:20:57
|
Hi Dave, Yes, you are right. I calculated the timestamp difference between each event reported in the printf. However, can I ask if the timestamp includes the time it takes to printf the event results (which could possibly explain the 2.5 millisec)? I am confused by what actually happens in the background in "GPIO_EVENT_IOCTL_MONITOR_GPIO" when the events are stored in evFs file in real time. Previously I calculated the time difference when the monitor was ON and my guess is that the evFs file will contain the delay in writing the results. Can we remove the writing results to the evFs file or to retrieve this file only after say 10 seconds and determine the number of events that had happened previously? Can you please help to have a quick look at the following codes which I'm hoping to use it to determine the rate of detecting the trigger? #include <stdio.h> #include <stdlib.h> #include <getopt.h> #include <fcntl.h> #include <ctype.h> #include <unistd.h> #include <string.h> #include <time.h> #include "gpio-event-drv.h" int main( int argc, char **argv ) { FILE *evFs; GPIO_EventMonitor_t monitor; if (( evFs = fopen( "/dev/gpio-event", "r" )) == NULL ) { perror( "Unable to open /dev/gpio-event" ); exit( 1 ); } // Determine the trigger rate int count=0; time_t prevTime; time_t endTime; prevTime = time( NULL ); endTime = prevTime + 10; // Define GPIO 58 -rising edge and debounce = 20 monitor.gpio = 58; monitor.onOff = 1; monitor.edgeType = GPIO_EventRisingEdge; monitor.debounceMilliSec = 0; // Determine the trigger rate while (time( NULL ) <= endTime) { if ( ioctl( fileno( evFs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor ) != 0 ) { perror( "ioctl GPIO_EVENT_IOCTL_MONITOR_GPIO failed" ); } } // Disable the GPIO monitoring monitor.onOff = 0; if ( ioctl( fileno( evFs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor ) != 0 ) { perror( "ioctl GPIO_EVENT_IOCTL_MONITOR_GPIO failed" ); } // Use the following to set the reporting to be in binary mode ioctl( fileno( evFs ), GPIO_EVENT_IOCTL_SET_READ_MODE, 1 ); // Use select or a separate thread (see gpio-event.c for select example) while ( 1 ) { GPIO_Event_t event; fread( &event, 1 , sizeof( event ), evFs ); count++; printf("%d\t %2d %c %ld.%06ld\n", count, event.gpio, (( event.edgeType == GPIO_EventRisingEdge ) ? 'R' : 'F' ), event.time.tv_sec, event.time.tv_usec ); } } I'm sorry for the confusion - I was trying to ask if the ioctl can have an output argument so that I can use it to activate the ADC. In other words, whenever there is a new event detected, the "ioctl( fileno( evFs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor)" will report this event which I can then use it to trigger the ADC. Is it possible? Can you give me hints to start with on how I can initiate an ISR for the GPIO signal? This will definitely be helpful because I like to prioritize this process and not allow other threads to affect the 7KHz trigger. As regards to the PIC, are you suggesting that I could use the ADC on the PIC and send it via SPI? Or that I should send a trigger signal from the PIC to the ADC to retrieve the sample? I have no idea if I can do that on the ADC which I'm using (i.e. waiting for the incoming trigger before sending out samples via the SPI). Do you think it is something feasible which I should be looking at? Thanks for your help. Peck -----Original Message----- From: gum...@li... [mailto:gum...@li...] On Behalf Of Dave Hylands Sent: 16 July 2008 21:04 To: General mailing list for gumstix users. Subject: Re: [Gumstix-users] How to detect GPIO signal edge to control ADC sampling Hi Peck, > Thanks for your helpful advice. > > I am hoping to detect the pulse rate from the PIC at 7KHz (hence every 0.14 > millisec). > > I tried to estimate the elapsed time between the receiving pulses (using > your codes) when I specified the debounce to zero and the elapsed time was > about 2.5 millisec. Why do you think causes this delay? Not sure. Are you saying that the delta in the time stamps is 2.5 msec? (each event reported from gpio-event has a timestamp associated with it). How many did you check? > Is there a way that I can improve on these rates and detect these pulses > (using gpio-event) at 7KHz? I'd have to try it and see. gpio-event should be able to deal with 7 kHz without any troubles, but I'd need to double check. Simple things like printk's in the code can mess stuff up. You may need to elevate the priority of your process. > Pardon me for my poor programming skill but I'm confused by the command > "ioctl( fileno( fs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor )". My guess > is that this command monitors the GPIO event based on what is being > specified in the "monitor" structure. Should I be using this command if I > need to set an output variable whenever an edge trigger is being detected > e.g. trig_pulse= ioctl( fileno( fs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, > &monitor )? Thereafter I will use the trig_pulse to trigger the ADC. This ioctl sets up a gpio to be monitored. It doesn't have any capability to set a gpio for output. You'd probably want to use the gpreg example to do that. Having control go from kernel mode into user-mode at 7 kHz will have jitter when other things happen on the system. In order to do this properly, you should have the ISR for the input GPIO toggle initiate the ADC sample. Trying to do stuff at 7 kHz in user space, I can pretty much guarantee that you'll miss samples here and there, especially if you're connected to a network or have anything else running that might disable interrupts for more than your 0.14 milliseconds. I'm surprised that you don't use the PIC to grab the ADC samples and send them to the gumstix over SPI or something. -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ gumstix-users mailing list gum...@li... https://lists.sourceforge.net/lists/listinfo/gumstix-users |
From: Dave H. <dhy...@gm...> - 2008-07-17 14:29:27
|
HI Peck, > Yes, you are right. I calculated the timestamp difference between each event > reported in the printf. However, can I ask if the timestamp includes the > time it takes to printf the event results (which could possibly explain the > 2.5 millisec)? gpio-event-drv maintains a queue of 20 entries. If the queue gets full, then events are dropped and a statistic is incremented. You can view this statistic by looking at /proc/sys/gpio-event/lost-events. The timestamp in the event record is the timestamp of when the event was put into the queue. Since your events are happening at 7 kHz, or approximately once every 0.14 milliseconds. Since the console output is 115200 baud, that's one character approximately every 0.086 milliseconds. So you can output about 1.6 characters for each sample. Outputting any more data than this will cause things to backup and events will get lost. Your printf is outputtting approx 25 characters, which will take approx 2 milliseconds, or 14 samples of your 7 kHz clock. You need to collect your data into a memory buffer and do all of the printing afterwards. > I am confused by what actually happens in the background in > "GPIO_EVENT_IOCTL_MONITOR_GPIO" when the events are stored in evFs file in > real time. Think of the MONITOR_GPIO ioctl as a configuration. It just says to start monitor a particular gpio and configures attributes of the gpio. The driver then generates events each time anything occurs on the gpio, and the events are put in queue. When the user-mode application issues a read on the evFs file, it removes items from the queue. You only need to call the MONITOR_GPIO ioctl ONCE per gpio. Calling it more than once just wastes CPU. So your loop of calling it for 10 seconds is basically just wasting 10 seconds of CPU time. > Previously I calculated the time difference when the monitor was > ON and my guess is that the evFs file will contain the delay in writing the > results. The first batch of 20 events will not contain the delay, but once the queue is filled, then since the user-mode application is removing them too slowly, the driver will drop approximately 14 events for every event that actually makes it into the queue. > Can we remove the writing results to the evFs file or to retrieve > this file only after say 10 seconds and determine the number of events that > had happened previously? Sure - just store the 70,000 events that will occur in the 10 second interval into an array. Each event takes up 12 bytes. So you're looking at 70,000 * 12 = 840K of memory, which should be fine. > Can you please help to have a quick look at the > following codes which I'm hoping to use it to determine the rate of > detecting the trigger? Note that the time function returns a 1-second granularity. You're waiting for 10 seconds. But because you don't know when in the second you made the first call, you'll actually wind up waiting somewhere between 10 and 11 seconds. So even if you weren't dropping any samples, your count would vary between 70,000 and 77,000. You should probably use the gettimeofday function instead, which returns microsecond or nansecond resolution. If you want to use time, you should at least have a loop that waits until the value of time changes so you're at least at the start of the second each time. > I'm sorry for the confusion - I was trying to ask if the ioctl can have an > output argument so that I can use it to activate the ADC. In other words, > whenever there is a new event detected, the "ioctl( fileno( evFs ), > GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor)" will report this event which I can > then use it to trigger the ADC. Is it possible? The MONITOR_GPIO ioctl doesn't report events, it configures the gpio and starts the monitoring process. reading the evFs is what retrieves the events. > Can you give me hints to start with on how I can initiate an ISR for the > GPIO signal? Look at the gpio-event-drv.c file. > This will definitely be helpful because I like to prioritize > this process and not allow other threads to affect the 7KHz trigger. As > regards to the PIC, are you suggesting that I could use the ADC on the PIC > and send it via SPI? Or that I should send a trigger signal from the PIC to > the ADC to retrieve the sample? I have no idea if I can do that on the ADC > which I'm using (i.e. waiting for the incoming trigger before sending out > samples via the SPI). Do you think it is something feasible which I should > be looking at? Because of the high sample rate that you're dealing with, doing as much as possible at the lowest level is generally required. I don't know what's possible because I don't know what your hardware is or how its hooked up, or even what you're trying to accomplish with your samples. -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ |
From: Peck H K. <pk...@me...> - 2008-07-18 14:27:24
|
Hi Dave, I've made those necessary changes as had been suggested by you. I've stored the events in a temp array and later save it into a file after the specific time. I think that I've managed to read all the events before they were dropped as I could not see any statistic in /proc/sys/gpio-event/lost-events. Am I right? >From my understanding, when you explained that "the timestamp in the event record is the timestamp of when the event was put into the queue", hence any delay in retrieving the events from the evFs file (as long as it's within the queue limit of 20 entries) should not result in a delay in the timestamp. Am I right? However, the results that I'm having looks rather awkward when I tried to measure the total count over 10 seconds. The total count was very close to 140,000 (double of that of my 7KHz PIC). And more interestingly when I tried to plot the the elapsed time (time difference between two events) I saw a very consistent "sawtooth" waveform - that is, every "odd" event has a 20 microsec elapsed time and every "even" event has a 126 micro elapsed time. I was wondering if the gpio-event driver is detecting the events twice? Or that have I done something wrong in my program in trying to read in the gpio events? Can you kindly advise me if I've done something wrong in my program: #include <stdio.h> #include <stdlib.h> #include <getopt.h> #include <fcntl.h> #include <ctype.h> #include <unistd.h> #include <string.h> #include <time.h> #include "gpio-event-drv.h" int main( int argc, char **argv ) { FILE *evFs; GPIO_EventMonitor_t monitor; FILE *p_file; char *filename= "/mnt/cf/gpiodata.log"; p_file=fopen(filename,"w"); fclose(p_file); if (( evFs = fopen( "/dev/gpio-event", "r" )) == NULL ) { perror( "Unable to open /dev/gpio-event" ); exit( 1 ); } // Determine the trigger rate int count=0; struct timeval tnow; long end_time; // Define GPIO 58 -rising edge and zero debounce monitor.gpio = 58; monitor.onOff = 1; monitor.edgeType = GPIO_EventRisingEdge; monitor.debounceMilliSec = 0; printf("gpio-event(): Running program...\n\n"); if ( ioctl( fileno( evFs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor ) != 0 ) { perror( "ioctl GPIO_EVENT_IOCTL_MONITOR_GPIO failed" ); } // Use the following to set the reporting to be in binary mode ioctl( fileno( evFs ), GPIO_EVENT_IOCTL_SET_READ_MODE, 1 ); GPIO_Event_t event; long gpio_info[200000][3]; gettimeofday(&tnow, NULL); end_time = tnow.tv_sec + 10; while (tnow.tv_sec <= end_time) { gettimeofday(&tnow, NULL); fread( &event, 1 , sizeof( event ), evFs ); gpio_info[count][0]=event.gpio; gpio_info[count][1]=event.time.tv_sec; gpio_info[count][2]=event.time.tv_usec; count++; } // Disable the GPIO monitoring monitor.onOff = 0; if ( ioctl( fileno( evFs ), GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor ) != 0 ) { perror( "ioctl GPIO_EVENT_IOCTL_MONITOR_GPIO failed" ); } printf("gpio-event(): Writing %d data to file...\n", count); p_file=fopen(filename,"a"); int i; for (i=0; i<count; i++) { fprintf(p_file, "%d\t %2d %ld.%06ld\n", i, gpio_info[i][0], gpio_info[i][1], gpio_info[i][2]); } printf("gpio-event(): Completed writing...\n"); fflush(p_file); fclose(p_file); return 0; } I've no idea if I should post the question here - I am very keen after hearing from your advice that I can use the PIC signal to grab the samples from the ADC, by controlling the Frame Conversion signal on the ADC (I'm using the LTC1867 ADC) using the PIC signal and subsequently send the samples to the gumstix via the SPI bus. I'm currently using the example SPI program (http://docwiki.gumstix.org/Sample_code/C/SPI) to read in the samples. Do you think if this is feasible? Because there is a FRAME signal for the SPI on the breakout board, I cannot see the option to disable this FRAME signal in the existing SPI program. Also can you advise me if there is an issue on the synchronization as I'll be using the SCK signal from the gumstix but now using the "Frame Conversion" signal from the PIC? I've tried to run the program with the PIC configuration, however the signal results were very noisy. Please share with me your thoughts. Thanks for your encouraging help. Peck -----Original Message----- From: gum...@li... [mailto:gum...@li...] On Behalf Of Dave Hylands Sent: 17 July 2008 15:30 To: General mailing list for gumstix users. Subject: Re: [Gumstix-users] How to detect GPIO signal edge to control ADC sampling HI Peck, > Yes, you are right. I calculated the timestamp difference between each event > reported in the printf. However, can I ask if the timestamp includes the > time it takes to printf the event results (which could possibly explain the > 2.5 millisec)? gpio-event-drv maintains a queue of 20 entries. If the queue gets full, then events are dropped and a statistic is incremented. You can view this statistic by looking at /proc/sys/gpio-event/lost-events. The timestamp in the event record is the timestamp of when the event was put into the queue. Since your events are happening at 7 kHz, or approximately once every 0.14 milliseconds. Since the console output is 115200 baud, that's one character approximately every 0.086 milliseconds. So you can output about 1.6 characters for each sample. Outputting any more data than this will cause things to backup and events will get lost. Your printf is outputtting approx 25 characters, which will take approx 2 milliseconds, or 14 samples of your 7 kHz clock. You need to collect your data into a memory buffer and do all of the printing afterwards. > I am confused by what actually happens in the background in > "GPIO_EVENT_IOCTL_MONITOR_GPIO" when the events are stored in evFs file in > real time. Think of the MONITOR_GPIO ioctl as a configuration. It just says to start monitor a particular gpio and configures attributes of the gpio. The driver then generates events each time anything occurs on the gpio, and the events are put in queue. When the user-mode application issues a read on the evFs file, it removes items from the queue. You only need to call the MONITOR_GPIO ioctl ONCE per gpio. Calling it more than once just wastes CPU. So your loop of calling it for 10 seconds is basically just wasting 10 seconds of CPU time. > Previously I calculated the time difference when the monitor was > ON and my guess is that the evFs file will contain the delay in writing the > results. The first batch of 20 events will not contain the delay, but once the queue is filled, then since the user-mode application is removing them too slowly, the driver will drop approximately 14 events for every event that actually makes it into the queue. > Can we remove the writing results to the evFs file or to retrieve > this file only after say 10 seconds and determine the number of events that > had happened previously? Sure - just store the 70,000 events that will occur in the 10 second interval into an array. Each event takes up 12 bytes. So you're looking at 70,000 * 12 = 840K of memory, which should be fine. > Can you please help to have a quick look at the > following codes which I'm hoping to use it to determine the rate of > detecting the trigger? Note that the time function returns a 1-second granularity. You're waiting for 10 seconds. But because you don't know when in the second you made the first call, you'll actually wind up waiting somewhere between 10 and 11 seconds. So even if you weren't dropping any samples, your count would vary between 70,000 and 77,000. You should probably use the gettimeofday function instead, which returns microsecond or nansecond resolution. If you want to use time, you should at least have a loop that waits until the value of time changes so you're at least at the start of the second each time. > I'm sorry for the confusion - I was trying to ask if the ioctl can have an > output argument so that I can use it to activate the ADC. In other words, > whenever there is a new event detected, the "ioctl( fileno( evFs ), > GPIO_EVENT_IOCTL_MONITOR_GPIO, &monitor)" will report this event which I can > then use it to trigger the ADC. Is it possible? The MONITOR_GPIO ioctl doesn't report events, it configures the gpio and starts the monitoring process. reading the evFs is what retrieves the events. > Can you give me hints to start with on how I can initiate an ISR for the > GPIO signal? Look at the gpio-event-drv.c file. > This will definitely be helpful because I like to prioritize > this process and not allow other threads to affect the 7KHz trigger. As > regards to the PIC, are you suggesting that I could use the ADC on the PIC > and send it via SPI? Or that I should send a trigger signal from the PIC to > the ADC to retrieve the sample? I have no idea if I can do that on the ADC > which I'm using (i.e. waiting for the incoming trigger before sending out > samples via the SPI). Do you think it is something feasible which I should > be looking at? Because of the high sample rate that you're dealing with, doing as much as possible at the lowest level is generally required. I don't know what's possible because I don't know what your hardware is or how its hooked up, or even what you're trying to accomplish with your samples. -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ gumstix-users mailing list gum...@li... https://lists.sourceforge.net/lists/listinfo/gumstix-users |
From: Dave H. <dhy...@gm...> - 2008-07-18 15:05:32
|
Hi Peck, > I've made those necessary changes as had been suggested by you. I've stored > the events in a temp array and later save it into a file after the specific > time. I think that I've managed to read all the events before they were > dropped as I could not see any statistic in > /proc/sys/gpio-event/lost-events. Am I right? Yep. > >From my understanding, when you explained that "the timestamp in the event > record is the timestamp of when the event > was put into the queue", hence any delay in retrieving the events from the > evFs file (as long as it's within the queue limit of 20 entries) should not > result in a delay in the timestamp. Am I right? RIght. > However, the results that I'm having looks rather awkward when I tried to > measure the total count over 10 seconds. The total count was very close to > 140,000 (double of that of my 7KHz PIC). And more interestingly when I tried > to plot the the elapsed time (time difference between two events) I saw a > very consistent "sawtooth" waveform - that is, every "odd" event has a 20 > microsec elapsed time and every "even" event has a 126 micro elapsed time. I > was wondering if the gpio-event driver is detecting the events twice? Or > that have I done something wrong in my program in trying to read in the gpio > events? You just tripped over a bug in gpio-event-drv. It's reporting both edges as the same type of edge. If you search (in gpio-event-drv.c) for IRQF_TRIGGER, you'll the following 2 lines of code: if (( monitor->edgeType | GPIO_EventRisingEdge ) != 0 ) { irqFlags |= IRQF_TRIGGER_RISING; } if (( monitor->edgeType | GPIO_EventFallingEdge ) != 0 ) { irqFlags |= IRQF_TRIGGER_FALLING; } The '|' in the if test shold be an &. So change the code to look like: if (( monitor->edgeType & GPIO_EventRisingEdge ) != 0 ) { irqFlags |= IRQF_TRIGGER_RISING; } if (( monitor->edgeType & GPIO_EventFallingEdge ) != 0 ) { irqFlags |= IRQF_TRIGGER_FALLING; } and then you should only get events on the reqested edge. -- Dave Hylands Vancouver, BC, Canada http://www.DaveHylands.com/ |