Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
9 years, 11 months ago.
Problems with timeout timer on nRF51822 board.
Hello,
I have two ISRs that are attached to the falling edge of two pins on the Arch BLE board. These lines provide data that I want to record, and it comes at unpredictable times. I know that the data is finished after I don't receive anymore for 3ms.
So I need to somehow start a timer from within the ISR that resets each time new data is received so when it hits 3ms it can process the data, then detach the timer and go back to the ble.WaitForEvent().
What I'm doing now doesn't seem to be working, can anyone help me out? I've tried tons of different variations of the code below.
see note below the code this code works on the FRDM K64F.
Thanks very much!
#include "mbed.h" #include "BLEDevice.h" #define MAX_BITS 100 #define WIEGAND_WAIT_TIME 3000 // wait for 3000us max for next Wiegand signal (max time between pulses is 2ms) BLEDevice ble; Serial pc(USBTX, USBRX); Timeout wiegandTimer; InterruptIn DATA0(p0); InterruptIn DATA1(p1); volatile unsigned char databits[MAX_BITS]; // stores all of the data bits volatile unsigned char bitCount= 0; // number of bits currently captured volatile bool flagDone = false; // goes low when data is currently being captured void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) { ble.startAdvertising(); // restart advertising } void parseWiegand (void) { pc.printf("\r\nRead %d bits.\r\n", bitCount); bitCount = 0; for (uint8_t i=0; i<MAX_BITS; i++) { databits[i] = 0; } } void DATA0_ISR() { //wiegandTimer.detach(); //pc.printf("0 %db\r\n", bitCount); bitCount++; flagDone = false; } void DATA1_ISR() { //wiegandTimer.detach(); //pc.printf("1 %db\r\n", bitCount); databits[bitCount] = 1; bitCount++; flagDone = false; } int main() { pc.baud (115200); DATA0.fall(&DATA0_ISR); // assign ISRs DATA1.fall(&DATA1_ISR); ble.init(); ble.onDisconnection(disconnectionCallback); ble.startAdvertising(); while (true) { if (bitCount > 0 && (!flagDone)) { wiegandTimer.attach_us(&parseWiegand, WIEGAND_WAIT_TIME); flagDone = true; } else { ble.waitForEvent(); // let the library manage power and stuff. } } }
Additional Information:
OK, so I took out the BLE stuff and ported this to my FRDM-K64F and it works. I'm pretty sure there is a bug in the nrf51 interrupt library somewhere that's causing this.
I also tried to simply comment out the ble.waitForEvent(); and run again on the nRF incase that was the cause and it did NOT work. So... I'm lost. :( My C skillz are not good.
printf in a callback is not ideal since these are blocking calls. What if you comment out all these pc.printf? Does it work?
posted by Sam Grove 04 Dec 2014Nope. I tried that, but no luck. Thanks anyway for the suggestion!
posted by Mark Baseggio 04 Dec 2014I think you should not make function call from within ISR routines, apart from commenting the printf you also need to comment out wiegandTimer.detach(); within the ISR , instead insert the code of the function within the ISR to avoid function jump
posted by Kanchan Debnath 04 Dec 2014I did that too, and still no luck. As I said, I am nearly positive this is a bug in the nRF interrupt handling. Otherwise why would it work fine on the FRDM K64F and not on the nRF51?
I've been working on the K64F because it's working fine, obviously I removed *all* the BLE stuff, and just out of curiosity I compiled it for the nRF again, and it didn't work (of course I changed pins and everything specific to the board).
posted by Mark Baseggio 04 Dec 2014If you're convinced of that I'd suggest writing a simple test case with instructions on how to run that is detached from your application. It'll be easier to track down root cause that way.
posted by Sam Grove 04 Dec 2014Well here is the latest code from the FRDM board that works fine. I've also included a function to send Wiegand data called txWiegand. You'll see that I set up a quick and dirty test using one of the buttons on the FRDM and I've even included some random Wiegand data so you can test this.
Ideally you'd have one board to send the data using the txWiegand function and another board to receive it:
Import programWiegand_Test
This code works on FRDM but not on nRF boards.
Last commit 04 Dec 2014 by Mark Baseggio
Just as a sanity check, I recently ran this code on a completely different nrf51822 module and it didn't work.
It works FINE on FRDM series boards and I'm also about to test it on an Xpresso board. I wish I had the nrf knowledge and C skills to troubleshoot WHY the timers are broken but they certainly seem to be.
I hope someone with more knowledge about the nrf platform can take a look at this because I'd really like to use mbed for my project.
Thanks, I'll update you after I try the LPC Xpresso board with this code.
posted by Mark Baseggio 13 Dec 2014Alright, so it's confirmed. The Wiegand_Test code works on:
So I'm 99% certain that there is an issue with the nrf Timer code. Why would it work on both other boards but not on two completely different nRF boards?
posted by Mark Baseggio 13 Dec 2014Hi, perhaps we are suck on the same problem: https://developer.mbed.org/questions/3733/When-I-use-the-BLE-functionPWM-is-not-su/
posted by Rok Okorn 14 Dec 2014