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.
Dependencies: buffered-serial1 mbed-rtos mbed
Fork of Serial_interrupts by
buffered_serial.cpp@1:2f1e54d137c7, 2012-12-10 (annotated)
- Committer:
- tylerjw
- Date:
- Mon Dec 10 00:32:22 2012 +0000
- Revision:
- 1:2f1e54d137c7
- Child:
- 2:3d959c9fc9d7
library based buffered serial
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| tylerjw | 1:2f1e54d137c7 | 1 | #include "buffered_serial.h" |
| tylerjw | 1:2f1e54d137c7 | 2 | |
| tylerjw | 1:2f1e54d137c7 | 3 | BufferedSerial::BufferedSerial(PinName tx, PinName rx) : Serial(tx,rx) |
| tylerjw | 1:2f1e54d137c7 | 4 | { |
| tylerjw | 1:2f1e54d137c7 | 5 | tx_in=0; |
| tylerjw | 1:2f1e54d137c7 | 6 | tx_out=0; |
| tylerjw | 1:2f1e54d137c7 | 7 | rx_in=0; |
| tylerjw | 1:2f1e54d137c7 | 8 | rx_out=0; |
| tylerjw | 1:2f1e54d137c7 | 9 | |
| tylerjw | 1:2f1e54d137c7 | 10 | switch( _serial.index ) { |
| tylerjw | 1:2f1e54d137c7 | 11 | case 0: |
| tylerjw | 1:2f1e54d137c7 | 12 | device_irqn = UART0_IRQn; |
| tylerjw | 1:2f1e54d137c7 | 13 | break; |
| tylerjw | 1:2f1e54d137c7 | 14 | case 1: |
| tylerjw | 1:2f1e54d137c7 | 15 | device_irqn = UART1_IRQn; |
| tylerjw | 1:2f1e54d137c7 | 16 | break; |
| tylerjw | 1:2f1e54d137c7 | 17 | case 2: |
| tylerjw | 1:2f1e54d137c7 | 18 | device_irqn = UART2_IRQn; |
| tylerjw | 1:2f1e54d137c7 | 19 | break; |
| tylerjw | 1:2f1e54d137c7 | 20 | case 3: |
| tylerjw | 1:2f1e54d137c7 | 21 | device_irqn = UART3_IRQn; |
| tylerjw | 1:2f1e54d137c7 | 22 | break; |
| tylerjw | 1:2f1e54d137c7 | 23 | } |
| tylerjw | 1:2f1e54d137c7 | 24 | //device_irqn = UART1_IRQn; |
| tylerjw | 1:2f1e54d137c7 | 25 | // attach the interrupts |
| tylerjw | 1:2f1e54d137c7 | 26 | Serial::attach(this, &BufferedSerial::Rx_interrupt, Serial::RxIrq); |
| tylerjw | 1:2f1e54d137c7 | 27 | Serial::attach(this, &BufferedSerial::Tx_interrupt, Serial::TxIrq); |
| tylerjw | 1:2f1e54d137c7 | 28 | } |
| tylerjw | 1:2f1e54d137c7 | 29 | |
| tylerjw | 1:2f1e54d137c7 | 30 | // Copy tx line buffer to large tx buffer for tx interrupt routine |
| tylerjw | 1:2f1e54d137c7 | 31 | void BufferedSerial::send_line(char *c) |
| tylerjw | 1:2f1e54d137c7 | 32 | { |
| tylerjw | 1:2f1e54d137c7 | 33 | int i; |
| tylerjw | 1:2f1e54d137c7 | 34 | char temp_char; |
| tylerjw | 1:2f1e54d137c7 | 35 | bool empty; |
| tylerjw | 1:2f1e54d137c7 | 36 | i = 0; |
| tylerjw | 1:2f1e54d137c7 | 37 | strncpy(tx_line,c,LINE_SIZE); |
| tylerjw | 1:2f1e54d137c7 | 38 | // Start Critical Section - don't interrupt while changing global buffer variables |
| tylerjw | 1:2f1e54d137c7 | 39 | NVIC_DisableIRQ(device_irqn); |
| tylerjw | 1:2f1e54d137c7 | 40 | empty = (tx_in == tx_out); |
| tylerjw | 1:2f1e54d137c7 | 41 | while ((i==0) || (tx_line[i-1] != '\n')) { |
| tylerjw | 1:2f1e54d137c7 | 42 | // Wait if buffer full |
| tylerjw | 1:2f1e54d137c7 | 43 | if (((tx_in + 1) & BUFFER_SIZE) == tx_out) { |
| tylerjw | 1:2f1e54d137c7 | 44 | // End Critical Section - need to let interrupt routine empty buffer by sending |
| tylerjw | 1:2f1e54d137c7 | 45 | NVIC_EnableIRQ(device_irqn); |
| tylerjw | 1:2f1e54d137c7 | 46 | while (((tx_in + 1) & BUFFER_SIZE) == tx_out) { |
| tylerjw | 1:2f1e54d137c7 | 47 | } |
| tylerjw | 1:2f1e54d137c7 | 48 | // Start Critical Section - don't interrupt while changing global buffer variables |
| tylerjw | 1:2f1e54d137c7 | 49 | NVIC_DisableIRQ(device_irqn); |
| tylerjw | 1:2f1e54d137c7 | 50 | } |
| tylerjw | 1:2f1e54d137c7 | 51 | tx_buffer[tx_in] = tx_line[i]; |
| tylerjw | 1:2f1e54d137c7 | 52 | i++; |
| tylerjw | 1:2f1e54d137c7 | 53 | tx_in = (tx_in + 1) & BUFFER_SIZE; |
| tylerjw | 1:2f1e54d137c7 | 54 | } |
| tylerjw | 1:2f1e54d137c7 | 55 | if (Serial::writeable() && (empty)) { |
| tylerjw | 1:2f1e54d137c7 | 56 | temp_char = tx_buffer[tx_out]; |
| tylerjw | 1:2f1e54d137c7 | 57 | tx_out = (tx_out + 1) & BUFFER_SIZE; |
| tylerjw | 1:2f1e54d137c7 | 58 | // Send first character to start tx interrupts, if stopped |
| tylerjw | 1:2f1e54d137c7 | 59 | Serial::putc(temp_char); |
| tylerjw | 1:2f1e54d137c7 | 60 | } |
| tylerjw | 1:2f1e54d137c7 | 61 | // End Critical Section |
| tylerjw | 1:2f1e54d137c7 | 62 | NVIC_EnableIRQ(device_irqn); |
| tylerjw | 1:2f1e54d137c7 | 63 | return; |
| tylerjw | 1:2f1e54d137c7 | 64 | } |
| tylerjw | 1:2f1e54d137c7 | 65 | |
| tylerjw | 1:2f1e54d137c7 | 66 | // Read a line from the large rx buffer from rx interrupt routine |
| tylerjw | 1:2f1e54d137c7 | 67 | void BufferedSerial::read_line(char *c) |
| tylerjw | 1:2f1e54d137c7 | 68 | { |
| tylerjw | 1:2f1e54d137c7 | 69 | int i; |
| tylerjw | 1:2f1e54d137c7 | 70 | i = 0; |
| tylerjw | 1:2f1e54d137c7 | 71 | // Start Critical Section - don't interrupt while changing global buffer variables |
| tylerjw | 1:2f1e54d137c7 | 72 | NVIC_DisableIRQ(device_irqn); |
| tylerjw | 1:2f1e54d137c7 | 73 | // Loop reading rx buffer characters until end of line character |
| tylerjw | 1:2f1e54d137c7 | 74 | while ((i==0) || (rx_line[i-1] != '\r')) { |
| tylerjw | 1:2f1e54d137c7 | 75 | // Wait if buffer empty |
| tylerjw | 1:2f1e54d137c7 | 76 | if (rx_in == rx_out) { |
| tylerjw | 1:2f1e54d137c7 | 77 | // End Critical Section - need to allow rx interrupt to get new characters for buffer |
| tylerjw | 1:2f1e54d137c7 | 78 | NVIC_EnableIRQ(device_irqn); |
| tylerjw | 1:2f1e54d137c7 | 79 | while (rx_in == rx_out) { |
| tylerjw | 1:2f1e54d137c7 | 80 | } |
| tylerjw | 1:2f1e54d137c7 | 81 | // Start Critical Section - don't interrupt while changing global buffer variables |
| tylerjw | 1:2f1e54d137c7 | 82 | NVIC_DisableIRQ(device_irqn); |
| tylerjw | 1:2f1e54d137c7 | 83 | } |
| tylerjw | 1:2f1e54d137c7 | 84 | rx_line[i] = rx_buffer[rx_out]; |
| tylerjw | 1:2f1e54d137c7 | 85 | i++; |
| tylerjw | 1:2f1e54d137c7 | 86 | rx_out = (rx_out + 1) & BUFFER_SIZE; |
| tylerjw | 1:2f1e54d137c7 | 87 | } |
| tylerjw | 1:2f1e54d137c7 | 88 | rx_line[i-1] = 0; |
| tylerjw | 1:2f1e54d137c7 | 89 | // End Critical Section |
| tylerjw | 1:2f1e54d137c7 | 90 | NVIC_EnableIRQ(device_irqn); |
| tylerjw | 1:2f1e54d137c7 | 91 | strncpy(c,rx_line,LINE_SIZE); |
| tylerjw | 1:2f1e54d137c7 | 92 | return; |
| tylerjw | 1:2f1e54d137c7 | 93 | } |
| tylerjw | 1:2f1e54d137c7 | 94 | |
| tylerjw | 1:2f1e54d137c7 | 95 | // Interupt Routine to read in data from serial port |
| tylerjw | 1:2f1e54d137c7 | 96 | void BufferedSerial::Rx_interrupt() |
| tylerjw | 1:2f1e54d137c7 | 97 | { |
| tylerjw | 1:2f1e54d137c7 | 98 | //led1=1; |
| tylerjw | 1:2f1e54d137c7 | 99 | // Loop just in case more than one character is in UART's receive FIFO buffer |
| tylerjw | 1:2f1e54d137c7 | 100 | // Stop if buffer full |
| tylerjw | 1:2f1e54d137c7 | 101 | while ((Serial::readable()) || (((rx_in + 1) & BUFFER_SIZE) == rx_out)) { |
| tylerjw | 1:2f1e54d137c7 | 102 | rx_buffer[rx_in] = Serial::getc(); |
| tylerjw | 1:2f1e54d137c7 | 103 | // Uncomment to Echo to USB serial to watch data flow |
| tylerjw | 1:2f1e54d137c7 | 104 | // monitor_Serial::putc(rx_buffer[rx_in]); |
| tylerjw | 1:2f1e54d137c7 | 105 | rx_in = (rx_in + 1) & BUFFER_SIZE; |
| tylerjw | 1:2f1e54d137c7 | 106 | } |
| tylerjw | 1:2f1e54d137c7 | 107 | //led1=0; |
| tylerjw | 1:2f1e54d137c7 | 108 | return; |
| tylerjw | 1:2f1e54d137c7 | 109 | } |
| tylerjw | 1:2f1e54d137c7 | 110 | |
| tylerjw | 1:2f1e54d137c7 | 111 | // Interupt Routine to write out data to serial port |
| tylerjw | 1:2f1e54d137c7 | 112 | void BufferedSerial::Tx_interrupt() |
| tylerjw | 1:2f1e54d137c7 | 113 | { |
| tylerjw | 1:2f1e54d137c7 | 114 | //led2=1; |
| tylerjw | 1:2f1e54d137c7 | 115 | // Loop to fill more than one character in UART's transmit FIFO buffer |
| tylerjw | 1:2f1e54d137c7 | 116 | // Stop if buffer empty |
| tylerjw | 1:2f1e54d137c7 | 117 | while ((Serial::writeable()) && (tx_in != tx_out)) { |
| tylerjw | 1:2f1e54d137c7 | 118 | Serial::putc(tx_buffer[tx_out]); |
| tylerjw | 1:2f1e54d137c7 | 119 | tx_out = (tx_out + 1) & BUFFER_SIZE; |
| tylerjw | 1:2f1e54d137c7 | 120 | } |
| tylerjw | 1:2f1e54d137c7 | 121 | //led2=0; |
| tylerjw | 1:2f1e54d137c7 | 122 | return; |
| tylerjw | 1:2f1e54d137c7 | 123 | } |
