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, 4 months ago.
RawSerial Rx interrupt only triggering once. LPC1768
I have setup RawSerial within an RTOS and attached an ISR to the Rx interrupt. The first character triggers the ISR but then it is never called again, my only thought is that the interrupt is not being cleared? RawSerial is working fine without using the RTOS.
main
void network(void const *args) { NetworkInterface net(p13, p14, 9600); while(true) { } } int main() { Thread networkThread(network); while(1){}; }
NetworkInterface.cpp
NetworkInterface::NetworkInterface(PinName tx, PinName rx, int baudRate) : RawSerial(tx, rx) , mIO(LED3) { baud(baudRate); attach(this, &NetworkInterface::onNetworkData); } void NetworkInterface::onNetworkData() { mIO = !mIO; //LED only changes on first character. char c = getc(); mBuffer += c; }
Any help would be greatly appreciated.
1 Answer
9 years, 4 months ago.
The receive interrupt is only cleared when the buffer is empty. Any interrupts that deal with data input should check for multiple bytes/packets. e.g.
void NetworkInterface::onNetworkData() { mIO = !mIO; //LED only changes on interrupts not every byte. Move inside the while for every byte. while (readable()) mBuffer += getc(); }
Thanks for the help. Unfortunately that didn't fix it. I also tried adding a check so the LED only flicks on a specific letter, in case there was always an even amount of data causing the LED to stay on.
What's weird is simply by adding the RTOS package is enough to stop it working even in a standard 'super-loop' configuration. Removing the RTOS I have to perform a 'Compile-All' for it to work correctly again. Any ideas?
Edit: Forwarding the output to PC serial also shows only the first character is sent/received.
posted by 18 Aug 2015mBuffer is defined in my NetworkInterface class. Here are all three files of the project:
main.cpp
#include "mbed.h" #include "rtos.h" #include "NetworkInterface.h" void network(void const *args) { NetworkInterface net(p13, p14, 9600); while(1){} } int main() { Thread networkThread(network); while(1){}; }
NetworkInterface.h
#include "mbed.h" #include <string> class NetworkInterface : public RawSerial { public: NetworkInterface(PinName, PinName, int); private: void onNetworkData(); DigitalOut mIO; std::string mBuffer; };
NetworkInterface.cpp
#include "NetworkInterface.h" NetworkInterface::NetworkInterface(PinName tx, PinName rx, int baudRate) : RawSerial(tx, rx) , mIO(LED3) { baud(baudRate); attach(this, &NetworkInterface::onNetworkData); } void NetworkInterface::onNetworkData() { mIO = !mIO; while(readable()) { char c = getc(); mBuffer += c; } }
Thanks again.
posted by 18 Aug 2015A quick google (google searches this site far better than the search box on the site) shows this is a fairly common problem.
Try:
void NetworkInterface::onNetworkData() { mIO = !mIO; while(readable()) { int temp = (int)LPC_UART1->RBR; char c = getc(); mBuffer += c; } }
Not very portable since it's dependent on the specific serial port being used but there is no point in creating a more generic implementation if it doesn't fix the issue.
posted by 18 Aug 2015That seemed very promising but annoyingly didn't work. I tried performing it both inside and out the while loop and on UART0, UART1, UART2 to no avail. Perhaps I need to alter another element? Could you link the source? Thanks again.
posted by 18 Aug 2015One more thing to try:
uint32_t IRR1 = LPC_UART1->IIR;
Outside the loop and then the RBR line inside
Pins 13 and 14 should be UART1.
I'm basing this on https://developer.mbed.org/users/tylerjw/notebook/buffered-serial-with-rtos/ however https://www.google.co.uk/search?q=site%3Adeveloper.mbed.org%20RTOS%20serial%20interrupt&rct=j gives a lot of other posts about similar problems.
posted by 18 Aug 2015