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.
Fork of buffered-serial1 by
buffered_serial.cpp@5:8daa0697fa7f, 2013-06-10 (annotated)
- Committer:
- jrj
- Date:
- Mon Jun 10 14:13:11 2013 +0000
- Revision:
- 5:8daa0697fa7f
- Parent:
- 2:8ccf9bb8dc65
Adding buffered-serial1 from http://mbed.org/users/tylerjw/code/Serial_interrupts_buffered/docs/e489f1ee71d8/main_8cpp_source.html; ; normal serial interface with callbacks doesn't work when the project includes RTOS.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| tylerjw | 0:707b9f3904dd | 1 | #include "buffered_serial.h" |
| tylerjw | 0:707b9f3904dd | 2 | |
| tylerjw | 0:707b9f3904dd | 3 | BufferedSerial::BufferedSerial(PinName tx, PinName rx) : Serial(tx,rx), led1(LED1), led2(LED2), rx_sem(0), tx_sem(0) |
| tylerjw | 0:707b9f3904dd | 4 | { |
| tylerjw | 0:707b9f3904dd | 5 | tx_in=0; |
| tylerjw | 0:707b9f3904dd | 6 | tx_out=0; |
| tylerjw | 0:707b9f3904dd | 7 | rx_in=0; |
| tylerjw | 0:707b9f3904dd | 8 | rx_out=0; |
| tylerjw | 0:707b9f3904dd | 9 | |
| jrj | 5:8daa0697fa7f | 10 | device_irqn = UART0_IRQn; |
| tylerjw | 0:707b9f3904dd | 11 | |
| tylerjw | 0:707b9f3904dd | 12 | // attach the interrupts |
| tylerjw | 0:707b9f3904dd | 13 | Serial::attach(this, &BufferedSerial::Rx_interrupt, Serial::RxIrq); |
| tylerjw | 0:707b9f3904dd | 14 | Serial::attach(this, &BufferedSerial::Tx_interrupt, Serial::TxIrq); |
| tylerjw | 0:707b9f3904dd | 15 | } |
| tylerjw | 0:707b9f3904dd | 16 | |
| tylerjw | 0:707b9f3904dd | 17 | // Copy tx line buffer to large tx buffer for tx interrupt routine |
| tylerjw | 0:707b9f3904dd | 18 | void BufferedSerial::send_line(char *c) |
| tylerjw | 0:707b9f3904dd | 19 | { |
| tylerjw | 0:707b9f3904dd | 20 | int i; |
| tylerjw | 0:707b9f3904dd | 21 | char temp_char; |
| tylerjw | 0:707b9f3904dd | 22 | bool empty; |
| tylerjw | 0:707b9f3904dd | 23 | i = 0; |
| tylerjw | 0:707b9f3904dd | 24 | strncpy(tx_line,c,LINE_SIZE); |
| tylerjw | 0:707b9f3904dd | 25 | // Start Critical Section - don't interrupt while changing global buffer variables |
| tylerjw | 0:707b9f3904dd | 26 | NVIC_DisableIRQ(device_irqn); |
| tylerjw | 0:707b9f3904dd | 27 | empty = (tx_in == tx_out); |
| tylerjw | 0:707b9f3904dd | 28 | while ((i==0) || (tx_line[i-1] != '\n')) { |
| tylerjw | 0:707b9f3904dd | 29 | // Wait if buffer full |
| tylerjw | 0:707b9f3904dd | 30 | if (IS_TX_FULL) { |
| tylerjw | 0:707b9f3904dd | 31 | // End Critical Section - need to let interrupt routine empty buffer by sending |
| tylerjw | 0:707b9f3904dd | 32 | NVIC_EnableIRQ(device_irqn); |
| tylerjw | 0:707b9f3904dd | 33 | //while (IS_TX_FULL) ; // buffer is full |
| tylerjw | 0:707b9f3904dd | 34 | tx_sem.wait(); |
| tylerjw | 0:707b9f3904dd | 35 | // Start Critical Section - don't interrupt while changing global buffer variables |
| tylerjw | 0:707b9f3904dd | 36 | NVIC_DisableIRQ(device_irqn); |
| tylerjw | 0:707b9f3904dd | 37 | } |
| tylerjw | 0:707b9f3904dd | 38 | tx_buffer[tx_in] = tx_line[i]; |
| tylerjw | 0:707b9f3904dd | 39 | i++; |
| tylerjw | 0:707b9f3904dd | 40 | tx_in = NEXT(tx_in); |
| tylerjw | 0:707b9f3904dd | 41 | } |
| tylerjw | 0:707b9f3904dd | 42 | if (Serial::writeable() && (empty)) { |
| tylerjw | 0:707b9f3904dd | 43 | temp_char = tx_buffer[tx_out]; |
| tylerjw | 0:707b9f3904dd | 44 | tx_out = NEXT(tx_out); |
| tylerjw | 0:707b9f3904dd | 45 | // Send first character to start tx interrupts, if stopped |
| jrj | 5:8daa0697fa7f | 46 | LPC_UART0->THR = temp_char; |
| tylerjw | 0:707b9f3904dd | 47 | } |
| tylerjw | 0:707b9f3904dd | 48 | // End Critical Section |
| tylerjw | 0:707b9f3904dd | 49 | NVIC_EnableIRQ(device_irqn); |
| tylerjw | 0:707b9f3904dd | 50 | } |
| tylerjw | 0:707b9f3904dd | 51 | |
| tylerjw | 0:707b9f3904dd | 52 | // Read a line from the large rx buffer from rx interrupt routine |
| tylerjw | 0:707b9f3904dd | 53 | void BufferedSerial::read_line(char *c) |
| tylerjw | 0:707b9f3904dd | 54 | { |
| tylerjw | 0:707b9f3904dd | 55 | int i; |
| tylerjw | 0:707b9f3904dd | 56 | i = 0; |
| tylerjw | 0:707b9f3904dd | 57 | // Start Critical Section - don't interrupt while changing global buffer variables |
| tylerjw | 0:707b9f3904dd | 58 | NVIC_DisableIRQ(device_irqn); |
| tylerjw | 0:707b9f3904dd | 59 | // Loop reading rx buffer characters until end of line character |
| tylerjw | 1:eabb26ce183b | 60 | while ((i==0) || (rx_line[i-1] != '\n')) { |
| tylerjw | 0:707b9f3904dd | 61 | // Wait if buffer empty |
| tylerjw | 0:707b9f3904dd | 62 | if (IS_RX_EMPTY) { // buffer empty |
| tylerjw | 0:707b9f3904dd | 63 | // End Critical Section - need to allow rx interrupt to get new characters for buffer |
| tylerjw | 0:707b9f3904dd | 64 | NVIC_EnableIRQ(device_irqn); |
| tylerjw | 0:707b9f3904dd | 65 | //while (rx_in == rx_out) ; // buffer empty |
| tylerjw | 0:707b9f3904dd | 66 | rx_sem.wait(); |
| tylerjw | 0:707b9f3904dd | 67 | // Start Critical Section - don't interrupt while changing global buffer variables |
| tylerjw | 0:707b9f3904dd | 68 | NVIC_DisableIRQ(device_irqn); |
| tylerjw | 0:707b9f3904dd | 69 | } else { |
| tylerjw | 0:707b9f3904dd | 70 | rx_sem.wait(); |
| tylerjw | 0:707b9f3904dd | 71 | } |
| tylerjw | 0:707b9f3904dd | 72 | rx_line[i] = rx_buffer[rx_out]; |
| tylerjw | 0:707b9f3904dd | 73 | i++; |
| tylerjw | 0:707b9f3904dd | 74 | rx_out = NEXT(rx_out); |
| tylerjw | 1:eabb26ce183b | 75 | |
| tylerjw | 1:eabb26ce183b | 76 | // prevent overflow on rx_line |
| tylerjw | 2:8ccf9bb8dc65 | 77 | if(i == LINE_SIZE) |
| tylerjw | 1:eabb26ce183b | 78 | { |
| tylerjw | 1:eabb26ce183b | 79 | i--; |
| tylerjw | 1:eabb26ce183b | 80 | break; |
| tylerjw | 2:8ccf9bb8dc65 | 81 | } |
| tylerjw | 0:707b9f3904dd | 82 | } |
| tylerjw | 1:eabb26ce183b | 83 | rx_line[i++] = 0; |
| tylerjw | 0:707b9f3904dd | 84 | // End Critical Section |
| tylerjw | 0:707b9f3904dd | 85 | NVIC_EnableIRQ(device_irqn); |
| tylerjw | 1:eabb26ce183b | 86 | strncpy(c,rx_line,i); |
| tylerjw | 0:707b9f3904dd | 87 | } |
| tylerjw | 0:707b9f3904dd | 88 | |
| tylerjw | 0:707b9f3904dd | 89 | // Interupt Routine to read in data from serial port |
| tylerjw | 0:707b9f3904dd | 90 | void BufferedSerial::Rx_interrupt() |
| tylerjw | 0:707b9f3904dd | 91 | { |
| jrj | 5:8daa0697fa7f | 92 | uint32_t IRR0= LPC_UART0->IIR; |
| tylerjw | 0:707b9f3904dd | 93 | led1=1; |
| tylerjw | 0:707b9f3904dd | 94 | while (readable() && !(IS_RX_FULL)) { |
| jrj | 5:8daa0697fa7f | 95 | rx_buffer[rx_in] = LPC_UART0->RBR; |
| tylerjw | 0:707b9f3904dd | 96 | rx_in = NEXT(rx_in); |
| tylerjw | 0:707b9f3904dd | 97 | rx_sem.release(); |
| tylerjw | 0:707b9f3904dd | 98 | } |
| tylerjw | 0:707b9f3904dd | 99 | led1=0; |
| tylerjw | 0:707b9f3904dd | 100 | } |
| tylerjw | 0:707b9f3904dd | 101 | |
| tylerjw | 0:707b9f3904dd | 102 | // Interupt Routine to write out data to serial port |
| tylerjw | 0:707b9f3904dd | 103 | void BufferedSerial::Tx_interrupt() |
| tylerjw | 0:707b9f3904dd | 104 | { |
| jrj | 5:8daa0697fa7f | 105 | uint32_t IRR = LPC_UART0->IIR; |
| tylerjw | 0:707b9f3904dd | 106 | led2=1; |
| tylerjw | 0:707b9f3904dd | 107 | while ((writeable()) && (tx_in != tx_out)) { // while serial is writeable and there are still characters in the buffer |
| jrj | 5:8daa0697fa7f | 108 | LPC_UART0->THR = tx_buffer[tx_out]; // send the character |
| tylerjw | 0:707b9f3904dd | 109 | tx_out = NEXT(tx_out); |
| tylerjw | 0:707b9f3904dd | 110 | } |
| tylerjw | 0:707b9f3904dd | 111 | if(!IS_TX_FULL) // if not full |
| tylerjw | 0:707b9f3904dd | 112 | tx_sem.release(); |
| tylerjw | 0:707b9f3904dd | 113 | led2=0; |
| tylerjw | 0:707b9f3904dd | 114 | } |
