Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:566fc5f530fe, committed 2012-05-02
- Comitter:
- janwesterkamp
- Date:
- Wed May 02 06:01:00 2012 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r 566fc5f530fe main.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed May 02 06:01:00 2012 +0000
@@ -0,0 +1,103 @@
+#include "mbed.h"
+#include "parser.h"
+#include "string"
+#include "list"
+
+Serial pc(USBTX, USBRX); // initialize RS232 via USB
+
+DigitalOut prg_activity_led(LED1); // some LED to show activity
+DigitalOut rx_activity_led(LED2);
+DigitalOut tx_activity_led(LED3);
+DigitalOut message_led(LED4);
+
+// we need some storage for the messages we want to send and receive
+string singleSendMessageBuffer;
+string singleReceiveMessageBuffer;
+// and a buffer for those messages, until they are processed
+list<string> sendMessagesBuffer;
+list<string> receiveMessagesBuffer;
+
+
+// Interupt Routine to read in data from serial port
+void Rx_interrupt() {
+ rx_activity_led=!rx_activity_led;
+ // Loop just in case more than one character is in UART's receive FIFO buffer
+ while (pc.readable()) {
+ char c = pc.getc();
+ unwrap_protocol(&c, &singleReceiveMessageBuffer, &receiveMessagesBuffer);
+ // pc.putc(c); // echo
+ }
+ return;
+}
+
+
+// Interupt Routine to write out data to serial port
+void Tx_interrupt() {
+ char c;
+ int finished = WRAP_SEND;
+ int messageAvailable = !sendMessagesBuffer.empty();
+
+ tx_activity_led=!tx_activity_led;
+
+ // Loop to fill more than one character in UART's transmit FIFO buffer
+ while ( pc.writeable() && messageAvailable && (finished == WRAP_SEND)) {
+ finished = wrap_protocol( &c, &singleSendMessageBuffer, &sendMessagesBuffer );
+ if (finished != WRAP_ABORT)
+ pc.putc(c);
+ }
+
+ //tx_activity_led=0;
+ return;
+}
+
+
+int main() {
+
+ string sendString;
+
+ pc.baud(115200); // other high speed: 921600
+
+ // Setup a serial interrupt function to receive data
+ pc.attach(&Rx_interrupt, Serial::RxIrq);
+ // Setup a serial interrupt function to transmit data
+ pc.attach(&Tx_interrupt, Serial::TxIrq);
+ // enable interrupt
+ NVIC_EnableIRQ(UART1_IRQn);
+
+ set_time(0); // needed to initialize rtc
+
+ while (1) {
+ prg_activity_led = !prg_activity_led; // toggle LED
+ time_t seconds = time(NULL); // get current time
+
+ //printf("Time as a string = %s\r\n", ctime(&seconds));
+
+ if (!receiveMessagesBuffer.empty()) {
+ //pc.printf("\r\nMessage: %s\r\n", receiveMessagesBuffer.front().c_str());
+
+ sendString = "Message '";
+ sendString += receiveMessagesBuffer.front().c_str();
+ sendString += "' received at ";
+ sendString += ctime(&seconds);
+ sendString += "\r";
+
+ sendMessagesBuffer.push_back(sendString);
+ receiveMessagesBuffer.pop_front();
+
+ } else {
+ //sendString = "Hallo Welt!\r\n";
+ sendString = ctime(&seconds);
+ sendString += "\r";
+ sendMessagesBuffer.push_back(sendString);
+ }
+
+
+ // trigger sending interrupt
+ char c;
+ int finished = wrap_protocol( &c, &singleSendMessageBuffer, &sendMessagesBuffer );
+ if (finished != WRAP_ABORT)
+ pc.putc(c);
+
+ wait(1); // wait and don't flood the RS232
+ }
+}
diff -r 000000000000 -r 566fc5f530fe mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed May 02 06:01:00 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/737756e0b479
diff -r 000000000000 -r 566fc5f530fe parser.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/parser.c Wed May 02 06:01:00 2012 +0000
@@ -0,0 +1,113 @@
+/*
+ *
+ */
+
+#include "mbed.h"
+#include "parser.h"
+
+int wrap_protocol(char *c, string *message, list<string> *messages, char header, char footer, char dle ) {
+
+ static int state = 0;
+ static int dle_state = 0;
+ static int index;
+ static int size;
+
+
+ switch (state) {
+ case 0: // start sending a header if there is a valid message available
+ if (!messages->empty()) {
+ *message = messages->front();
+ messages->pop_front(); // now that we have the message, delete it from the list
+ index = 0; // initialize sending the actual message
+ size = message->size();
+ state = 1;
+ *c = header;
+ return WRAP_SEND;
+ }
+ return WRAP_ABORT;
+
+ case 1:
+ if ((size == 0) || (index==size)) {
+ *c = footer;
+ state = 0;
+ return WRAP_FINISHED;
+ }
+
+ *c = (*message)[index];
+
+ if ( dle_state == 1 ) {
+ dle_state = 0;
+ index++;
+ return WRAP_SEND;
+ }
+
+ if ( (*c == header) || (*c == footer) || (*c == dle) ) {
+ dle_state = 1;
+ *c = dle;
+ return WRAP_SEND;
+ }
+
+ index++;
+ return WRAP_SEND;
+ }
+
+ // if we reach this point, something went wrong!
+ return WRAP_ABORT;
+}
+
+void unwrap_protocol(char *c, string *buffer, list<string> *messages, unsigned int max_message_size,
+ unsigned int max_messages, char header, char footer, char dle ) {
+
+ // these are needed for the internal state of the function
+ // they are also the reaseon, why this function can only be used in exactly one location
+ // i.e. the interrupt routine for receiving characters from the RS232
+ static int state = 0;
+ static int dle_state = 0;
+
+ switch (state) {
+ case 0:
+ if (*c == header) {
+ message_led=!message_led;
+ state = 1;
+ }
+ return;
+
+ case 1:
+ if (*c== header && dle_state==0) {
+ // new header that is not escaped will set e new message start
+ buffer->clear();
+ return;
+ }
+ if (*c == footer && dle_state==0 ) {
+ // a frame end is only a frame end, if the footer is not escaped
+ messages->push_back( *buffer );
+ buffer->clear();
+ state = 0;
+ message_led=!message_led;
+ return;
+ }
+
+ // check length of buffer; clear, if too large; restart search for header!
+ if (buffer->length() > max_message_size) {
+ // prevent buffer overflows if someone is flooding us with characters
+ buffer->clear();
+ state=0;
+ return;
+ }
+
+ if (*c == dle && dle_state==0) {
+ // the next character is "escaped" and is part of the message
+ dle_state = 1;
+ return;
+ }
+
+ // probably the easiest and quickest way of resetting the dle_state
+ dle_state = 0;
+
+ // in all other cases, we found a new character and append it to the buffer
+ *buffer += *c;
+ }
+}
+
+
+
diff -r 000000000000 -r 566fc5f530fe parser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/parser.h Wed May 02 06:01:00 2012 +0000 @@ -0,0 +1,32 @@ +/* + * + */ + +#ifndef _PARSER_H_ +#define _PARSER_H_ + +#include "string" +#include "list" + +#define WRAP_SEND 1 +#define WRAP_ABORT 2 +#define WRAP_FINISHED 3 + +#define HEADER_CHAR 'A' +#define FOOTER_CHAR 'B' +#define DLE_CHAR '+' + +void unwrap_protocol(char *, string *buffer, list<string> *messages, + unsigned int max_message_size = 255, unsigned int max_message = 5, + char header=HEADER_CHAR, char footer=FOOTER_CHAR, char dle=DLE_CHAR); + + +int wrap_protocol(char *c, string *buffer, list<string> *messages, + char header=HEADER_CHAR, char footer=FOOTER_CHAR, char dle=DLE_CHAR); + + +// these have to be declared somewhere else for consistency +extern DigitalOut message_led; + + +#endif