Serial Interrupt Library with mbed RTOS for multi-threading
Dependencies: buffered-serial1 mbed-rtos mbed
Fork of Serial_interrupts by
Revision 1:2f1e54d137c7, committed 2012-12-10
- Comitter:
- tylerjw
- Date:
- Mon Dec 10 00:32:22 2012 +0000
- Parent:
- 0:023c5cda6102
- Child:
- 2:3d959c9fc9d7
- Commit message:
- library based buffered serial
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/buffered_serial.cpp Mon Dec 10 00:32:22 2012 +0000 @@ -0,0 +1,123 @@ +#include "buffered_serial.h" + +BufferedSerial::BufferedSerial(PinName tx, PinName rx) : Serial(tx,rx) +{ + tx_in=0; + tx_out=0; + rx_in=0; + rx_out=0; + + switch( _serial.index ) { + case 0: + device_irqn = UART0_IRQn; + break; + case 1: + device_irqn = UART1_IRQn; + break; + case 2: + device_irqn = UART2_IRQn; + break; + case 3: + device_irqn = UART3_IRQn; + break; + } + //device_irqn = UART1_IRQn; + // attach the interrupts + Serial::attach(this, &BufferedSerial::Rx_interrupt, Serial::RxIrq); + Serial::attach(this, &BufferedSerial::Tx_interrupt, Serial::TxIrq); +} + +// Copy tx line buffer to large tx buffer for tx interrupt routine +void BufferedSerial::send_line(char *c) +{ + int i; + char temp_char; + bool empty; + i = 0; + strncpy(tx_line,c,LINE_SIZE); +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(device_irqn); + empty = (tx_in == tx_out); + while ((i==0) || (tx_line[i-1] != '\n')) { +// Wait if buffer full + if (((tx_in + 1) & BUFFER_SIZE) == tx_out) { +// End Critical Section - need to let interrupt routine empty buffer by sending + NVIC_EnableIRQ(device_irqn); + while (((tx_in + 1) & BUFFER_SIZE) == tx_out) { + } +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(device_irqn); + } + tx_buffer[tx_in] = tx_line[i]; + i++; + tx_in = (tx_in + 1) & BUFFER_SIZE; + } + if (Serial::writeable() && (empty)) { + temp_char = tx_buffer[tx_out]; + tx_out = (tx_out + 1) & BUFFER_SIZE; +// Send first character to start tx interrupts, if stopped + Serial::putc(temp_char); + } +// End Critical Section + NVIC_EnableIRQ(device_irqn); + return; +} + +// Read a line from the large rx buffer from rx interrupt routine +void BufferedSerial::read_line(char *c) +{ + int i; + i = 0; +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(device_irqn); +// Loop reading rx buffer characters until end of line character + while ((i==0) || (rx_line[i-1] != '\r')) { +// Wait if buffer empty + if (rx_in == rx_out) { +// End Critical Section - need to allow rx interrupt to get new characters for buffer + NVIC_EnableIRQ(device_irqn); + while (rx_in == rx_out) { + } +// Start Critical Section - don't interrupt while changing global buffer variables + NVIC_DisableIRQ(device_irqn); + } + rx_line[i] = rx_buffer[rx_out]; + i++; + rx_out = (rx_out + 1) & BUFFER_SIZE; + } + rx_line[i-1] = 0; +// End Critical Section + NVIC_EnableIRQ(device_irqn); + strncpy(c,rx_line,LINE_SIZE); + return; +} + +// Interupt Routine to read in data from serial port +void BufferedSerial::Rx_interrupt() +{ + //led1=1; +// Loop just in case more than one character is in UART's receive FIFO buffer +// Stop if buffer full + while ((Serial::readable()) || (((rx_in + 1) & BUFFER_SIZE) == rx_out)) { + rx_buffer[rx_in] = Serial::getc(); +// Uncomment to Echo to USB serial to watch data flow +// monitor_Serial::putc(rx_buffer[rx_in]); + rx_in = (rx_in + 1) & BUFFER_SIZE; + } + //led1=0; + return; +} + +// Interupt Routine to write out data to serial port +void BufferedSerial::Tx_interrupt() +{ + //led2=1; +// Loop to fill more than one character in UART's transmit FIFO buffer +// Stop if buffer empty + while ((Serial::writeable()) && (tx_in != tx_out)) { + Serial::putc(tx_buffer[tx_out]); + tx_out = (tx_out + 1) & BUFFER_SIZE; + } + //led2=0; + return; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/buffered_serial.h Mon Dec 10 00:32:22 2012 +0000 @@ -0,0 +1,39 @@ +#ifndef BUFFERED_SERIAL_H +#define BUFFERED_SERIAL_H + +#define BUFFER_SIZE 255 +#define LINE_SIZE 80 + +#include "mbed.h" + +class BufferedSerial : public Serial +{ +public: + BufferedSerial::BufferedSerial(PinName tx, PinName rx); + + void send_line(char*); + void read_line(char*); + + +private: + void Tx_interrupt(); + void Rx_interrupt(); + +// for disabling the irq + IRQn device_irqn; +// Circular buffers for serial TX and RX data - used by interrupt routines +// might need to increase buffer size for high baud rates + char tx_buffer[BUFFER_SIZE]; + char rx_buffer[BUFFER_SIZE]; +// Circular buffer pointers +// volatile makes read-modify-write atomic + volatile int tx_in; + volatile int tx_out; + volatile int rx_in; + volatile int rx_out; +// Line buffers for sprintf and sscanf + char tx_line[LINE_SIZE]; + char rx_line[LINE_SIZE]; +}; + +#endif \ No newline at end of file
--- a/main.cpp Tue Nov 16 15:00:30 2010 +0000 +++ b/main.cpp Mon Dec 10 00:32:22 2012 +0000 @@ -1,5 +1,5 @@ - #include "mbed.h" +#include "buffered_serial.h" // Serial TX & RX interrupt loopback test using formatted IO - sprintf and sscanf // Connect TX to RX (p9 to p10) // or can also use USB and type back in the number printed out in a terminal window @@ -9,7 +9,8 @@ // LED3 changing indicate main loop running -Serial device(p9, p10); // tx, rx +BufferedSerial device(p13,p14); // tx, rx +//IRQn device_irqn = UART1_IRQn; // Can also use USB and type back in the number printed out in a terminal window // Serial monitor_device(USBTX, USBRX); DigitalOut led1(LED1); @@ -17,7 +18,7 @@ DigitalOut led3(LED3); DigitalOut led4(LED4); - +/* void Tx_interrupt(); void Rx_interrupt(); void send_line(); @@ -35,21 +36,23 @@ volatile int tx_out=0; volatile int rx_in=0; volatile int rx_out=0; +*/ // Line buffers for sprintf and sscanf char tx_line[80]; char rx_line[80]; // main test program -int main() { +int main() +{ int i=0; int rx_i=0; device.baud(9600); - +/* // Setup a serial interrupt function to receive data device.attach(&Rx_interrupt, Serial::RxIrq); // Setup a serial interrupt function to transmit data device.attach(&Tx_interrupt, Serial::TxIrq); - +*/ // Formatted IO test using send and receive serial interrupts // with sprintf and sscanf while (1) { @@ -59,30 +62,30 @@ // Print ASCII number to tx line buffer in hex sprintf(tx_line,"%x\r\n",i); // Copy tx line buffer to large tx buffer for tx interrupt routine - send_line(); + device.send_line(tx_line); // Print ASCII number to tx line buffer in decimal sprintf(tx_line,"%d\r\n",i); // Copy tx line buffer to large tx buffer for tx interrupt routine - send_line(); + device.send_line(tx_line); // Print ASCII number to tx line buffer in octal sprintf(tx_line,"%o\r\n",i); // Copy tx line buffer to large tx buffer for tx interrupt routine - send_line(); + device.send_line(tx_line); led3=0; // Read a line from the large rx buffer from rx interrupt routine - read_line(); + device.read_line(rx_line); // Read ASCII number from rx line buffer sscanf(rx_line,"%x",&rx_i); // Check that numbers are the same if (i != rx_i) led4=1; // Read a line from the large rx buffer from rx interrupt routine - read_line(); + device.read_line(rx_line); // Read ASCII number from rx line buffer sscanf(rx_line,"%d",&rx_i); // Check that numbers are the same if (i != rx_i) led4=1; // Read a line from the large rx buffer from rx interrupt routine - read_line(); + device.read_line(rx_line); // Read ASCII number from rx line buffer sscanf(rx_line,"%o",&rx_i); // Check that numbers are the same @@ -91,91 +94,3 @@ } } -// Copy tx line buffer to large tx buffer for tx interrupt routine -void send_line() { - int i; - char temp_char; - bool empty; - i = 0; -// Start Critical Section - don't interrupt while changing global buffer variables - NVIC_DisableIRQ(UART1_IRQn); - empty = (tx_in == tx_out); - while ((i==0) || (tx_line[i-1] != '\n')) { -// Wait if buffer full - if (((tx_in + 1) % buffer_size) == tx_out) { -// End Critical Section - need to let interrupt routine empty buffer by sending - NVIC_EnableIRQ(UART1_IRQn); - while (((tx_in + 1) % buffer_size) == tx_out) { - } -// Start Critical Section - don't interrupt while changing global buffer variables - NVIC_DisableIRQ(UART1_IRQn); - } - tx_buffer[tx_in] = tx_line[i]; - i++; - tx_in = (tx_in + 1) % buffer_size; - } - if (device.writeable() && (empty)) { - temp_char = tx_buffer[tx_out]; - tx_out = (tx_out + 1) % buffer_size; -// Send first character to start tx interrupts, if stopped - device.putc(temp_char); - } -// End Critical Section - NVIC_EnableIRQ(UART1_IRQn); - return; -} - -// Read a line from the large rx buffer from rx interrupt routine -void read_line() { - int i; - i = 0; -// Start Critical Section - don't interrupt while changing global buffer variables - NVIC_DisableIRQ(UART1_IRQn); -// Loop reading rx buffer characters until end of line character - while ((i==0) || (rx_line[i-1] != '\r')) { -// Wait if buffer empty - if (rx_in == rx_out) { -// End Critical Section - need to allow rx interrupt to get new characters for buffer - NVIC_EnableIRQ(UART1_IRQn); - while (rx_in == rx_out) { - } -// Start Critical Section - don't interrupt while changing global buffer variables - NVIC_DisableIRQ(UART1_IRQn); - } - rx_line[i] = rx_buffer[rx_out]; - i++; - rx_out = (rx_out + 1) % buffer_size; - } - rx_line[i-1] = 0; -// End Critical Section - NVIC_EnableIRQ(UART1_IRQn); - return; -} - -// Interupt Routine to read in data from serial port -void Rx_interrupt() { - led1=1; -// Loop just in case more than one character is in UART's receive FIFO buffer -// Stop if buffer full - while ((device.readable()) || (((rx_in + 1) % buffer_size) == rx_out)) { - rx_buffer[rx_in] = device.getc(); -// Uncomment to Echo to USB serial to watch data flow -// monitor_device.putc(rx_buffer[rx_in]); - rx_in = (rx_in + 1) % buffer_size; - } - led1=0; - return; -} - -// Interupt Routine to write out data to serial port -void Tx_interrupt() { - led2=1; -// Loop to fill more than one character in UART's transmit FIFO buffer -// Stop if buffer empty - while ((device.writeable()) && (tx_in != tx_out)) { - device.putc(tx_buffer[tx_out]); - tx_out = (tx_out + 1) % buffer_size; - } - led2=0; - return; -} \ No newline at end of file
--- a/mbed.bld Tue Nov 16 15:00:30 2010 +0000 +++ b/mbed.bld Mon Dec 10 00:32:22 2012 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e +http://mbed.org/users/mbed_official/code/mbed/builds/63cdd78b2dc1 \ No newline at end of file