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 L432KC-SMT16030 by
SerialIRQ.cpp@0:af4af28f0975, 2017-01-10 (annotated)
- Committer:
- lmboogaard
- Date:
- Tue Jan 10 11:32:26 2017 +0000
- Revision:
- 0:af4af28f0975
test program for Mbed CLI; no SPI rate, no UART, no I2C
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| lmboogaard | 0:af4af28f0975 | 1 | #include "mbed.h" |
| lmboogaard | 0:af4af28f0975 | 2 | // Serial TX & RX interrupt loopback test using formatted IO - sprintf and sscanf |
| lmboogaard | 0:af4af28f0975 | 3 | // Connect TX to RX (p9 to p10) |
| lmboogaard | 0:af4af28f0975 | 4 | // or can also use USB and type back in the number printed out in a terminal window |
| lmboogaard | 0:af4af28f0975 | 5 | // Sends out ASCII numbers in a loop and reads them back |
| lmboogaard | 0:af4af28f0975 | 6 | // If not the same number LED4 goes on |
| lmboogaard | 0:af4af28f0975 | 7 | // LED1 and LED2 indicate RX and TX interrupt routine activity |
| lmboogaard | 0:af4af28f0975 | 8 | // LED3 changing indicate main loop running |
| lmboogaard | 0:af4af28f0975 | 9 | |
| lmboogaard | 0:af4af28f0975 | 10 | |
| lmboogaard | 0:af4af28f0975 | 11 | Serial device(PA_2, PA_3); // tx, rx |
| lmboogaard | 0:af4af28f0975 | 12 | // Can also use USB and type back in the number printed out in a terminal window |
| lmboogaard | 0:af4af28f0975 | 13 | // Serial monitor_device(USBTX, USBRX); |
| lmboogaard | 0:af4af28f0975 | 14 | DigitalOut led1(PB_3); |
| lmboogaard | 0:af4af28f0975 | 15 | DigitalOut led2(PB_4); |
| lmboogaard | 0:af4af28f0975 | 16 | DigitalOut led3(PB_5); |
| lmboogaard | 0:af4af28f0975 | 17 | DigitalOut led4(PB_6); |
| lmboogaard | 0:af4af28f0975 | 18 | |
| lmboogaard | 0:af4af28f0975 | 19 | #define UART1_IRQn 1 |
| lmboogaard | 0:af4af28f0975 | 20 | |
| lmboogaard | 0:af4af28f0975 | 21 | int Serial_main(void); |
| lmboogaard | 0:af4af28f0975 | 22 | void Tx_interrupt(); |
| lmboogaard | 0:af4af28f0975 | 23 | void Rx_interrupt(); |
| lmboogaard | 0:af4af28f0975 | 24 | void send_line(); |
| lmboogaard | 0:af4af28f0975 | 25 | void read_line(); |
| lmboogaard | 0:af4af28f0975 | 26 | void NVIC_DisableIRQ(int IRQ); |
| lmboogaard | 0:af4af28f0975 | 27 | void NVIC_EnableIRQ(int IRQ); |
| lmboogaard | 0:af4af28f0975 | 28 | |
| lmboogaard | 0:af4af28f0975 | 29 | // Circular buffers for serial TX and RX data - used by interrupt routines |
| lmboogaard | 0:af4af28f0975 | 30 | const int buffer_size = 255; |
| lmboogaard | 0:af4af28f0975 | 31 | // might need to increase buffer size for high baud rates |
| lmboogaard | 0:af4af28f0975 | 32 | char tx_buffer[buffer_size+1]; |
| lmboogaard | 0:af4af28f0975 | 33 | char rx_buffer[buffer_size+1]; |
| lmboogaard | 0:af4af28f0975 | 34 | // Circular buffer pointers |
| lmboogaard | 0:af4af28f0975 | 35 | // volatile makes read-modify-write atomic |
| lmboogaard | 0:af4af28f0975 | 36 | volatile int tx_in=0; |
| lmboogaard | 0:af4af28f0975 | 37 | volatile int tx_out=0; |
| lmboogaard | 0:af4af28f0975 | 38 | volatile int rx_in=0; |
| lmboogaard | 0:af4af28f0975 | 39 | volatile int rx_out=0; |
| lmboogaard | 0:af4af28f0975 | 40 | // Line buffers for sprintf and sscanf |
| lmboogaard | 0:af4af28f0975 | 41 | char tx_line[80]; |
| lmboogaard | 0:af4af28f0975 | 42 | char rx_line[80]; |
| lmboogaard | 0:af4af28f0975 | 43 | |
| lmboogaard | 0:af4af28f0975 | 44 | |
| lmboogaard | 0:af4af28f0975 | 45 | // main test program |
| lmboogaard | 0:af4af28f0975 | 46 | int Serial_main() { |
| lmboogaard | 0:af4af28f0975 | 47 | int i=0; |
| lmboogaard | 0:af4af28f0975 | 48 | int rx_i=0; |
| lmboogaard | 0:af4af28f0975 | 49 | device.baud(9600); |
| lmboogaard | 0:af4af28f0975 | 50 | |
| lmboogaard | 0:af4af28f0975 | 51 | // Setup a serial interrupt function to receive data |
| lmboogaard | 0:af4af28f0975 | 52 | device.attach(&Rx_interrupt, Serial::RxIrq); |
| lmboogaard | 0:af4af28f0975 | 53 | // Setup a serial interrupt function to transmit data |
| lmboogaard | 0:af4af28f0975 | 54 | device.attach(&Tx_interrupt, Serial::TxIrq); |
| lmboogaard | 0:af4af28f0975 | 55 | |
| lmboogaard | 0:af4af28f0975 | 56 | // Formatted IO test using send and receive serial interrupts |
| lmboogaard | 0:af4af28f0975 | 57 | // with sprintf and sscanf |
| lmboogaard | 0:af4af28f0975 | 58 | while (1) { |
| lmboogaard | 0:af4af28f0975 | 59 | // Loop to generate different test values - send value in hex, decimal, and octal and then read back |
| lmboogaard | 0:af4af28f0975 | 60 | for (i=0; i<0xFFFF; i++) { |
| lmboogaard | 0:af4af28f0975 | 61 | led3=1; |
| lmboogaard | 0:af4af28f0975 | 62 | // Print ASCII number to tx line buffer in hex |
| lmboogaard | 0:af4af28f0975 | 63 | sprintf(tx_line,"%x\r\n",i); |
| lmboogaard | 0:af4af28f0975 | 64 | // Copy tx line buffer to large tx buffer for tx interrupt routine |
| lmboogaard | 0:af4af28f0975 | 65 | send_line(); |
| lmboogaard | 0:af4af28f0975 | 66 | // Print ASCII number to tx line buffer in decimal |
| lmboogaard | 0:af4af28f0975 | 67 | sprintf(tx_line,"%d\r\n",i); |
| lmboogaard | 0:af4af28f0975 | 68 | // Copy tx line buffer to large tx buffer for tx interrupt routine |
| lmboogaard | 0:af4af28f0975 | 69 | send_line(); |
| lmboogaard | 0:af4af28f0975 | 70 | // Print ASCII number to tx line buffer in octal |
| lmboogaard | 0:af4af28f0975 | 71 | sprintf(tx_line,"%o\r\n",i); |
| lmboogaard | 0:af4af28f0975 | 72 | // Copy tx line buffer to large tx buffer for tx interrupt routine |
| lmboogaard | 0:af4af28f0975 | 73 | send_line(); |
| lmboogaard | 0:af4af28f0975 | 74 | led3=0; |
| lmboogaard | 0:af4af28f0975 | 75 | |
| lmboogaard | 0:af4af28f0975 | 76 | // Read a line from the large rx buffer from rx interrupt routine |
| lmboogaard | 0:af4af28f0975 | 77 | read_line(); |
| lmboogaard | 0:af4af28f0975 | 78 | // Read ASCII number from rx line buffer |
| lmboogaard | 0:af4af28f0975 | 79 | sscanf(rx_line,"%x",&rx_i); |
| lmboogaard | 0:af4af28f0975 | 80 | // Check that numbers are the same |
| lmboogaard | 0:af4af28f0975 | 81 | if (i != rx_i) led4=1; |
| lmboogaard | 0:af4af28f0975 | 82 | // Read a line from the large rx buffer from rx interrupt routine |
| lmboogaard | 0:af4af28f0975 | 83 | read_line(); |
| lmboogaard | 0:af4af28f0975 | 84 | // Read ASCII number from rx line buffer |
| lmboogaard | 0:af4af28f0975 | 85 | sscanf(rx_line,"%d",&rx_i); |
| lmboogaard | 0:af4af28f0975 | 86 | // Check that numbers are the same |
| lmboogaard | 0:af4af28f0975 | 87 | if (i != rx_i) led4=1; |
| lmboogaard | 0:af4af28f0975 | 88 | // Read a line from the large rx buffer from rx interrupt routine |
| lmboogaard | 0:af4af28f0975 | 89 | read_line(); |
| lmboogaard | 0:af4af28f0975 | 90 | // Read ASCII number from rx line buffer |
| lmboogaard | 0:af4af28f0975 | 91 | sscanf(rx_line,"%o",&rx_i); |
| lmboogaard | 0:af4af28f0975 | 92 | // Check that numbers are the same |
| lmboogaard | 0:af4af28f0975 | 93 | if (i != rx_i) led4=1; |
| lmboogaard | 0:af4af28f0975 | 94 | } |
| lmboogaard | 0:af4af28f0975 | 95 | } |
| lmboogaard | 0:af4af28f0975 | 96 | } |
| lmboogaard | 0:af4af28f0975 | 97 | |
| lmboogaard | 0:af4af28f0975 | 98 | |
| lmboogaard | 0:af4af28f0975 | 99 | // Copy tx line buffer to large tx buffer for tx interrupt routine |
| lmboogaard | 0:af4af28f0975 | 100 | void send_line() { |
| lmboogaard | 0:af4af28f0975 | 101 | int i; |
| lmboogaard | 0:af4af28f0975 | 102 | char temp_char; |
| lmboogaard | 0:af4af28f0975 | 103 | bool empty; |
| lmboogaard | 0:af4af28f0975 | 104 | i = 0; |
| lmboogaard | 0:af4af28f0975 | 105 | // Start Critical Section - don't interrupt while changing global buffer variables |
| lmboogaard | 0:af4af28f0975 | 106 | NVIC_DisableIRQ(UART1_IRQn); |
| lmboogaard | 0:af4af28f0975 | 107 | empty = (tx_in == tx_out); |
| lmboogaard | 0:af4af28f0975 | 108 | while ((i==0) || (tx_line[i-1] != '\n')) { |
| lmboogaard | 0:af4af28f0975 | 109 | // Wait if buffer full |
| lmboogaard | 0:af4af28f0975 | 110 | if (((tx_in + 1) % buffer_size) == tx_out) { |
| lmboogaard | 0:af4af28f0975 | 111 | // End Critical Section - need to let interrupt routine empty buffer by sending |
| lmboogaard | 0:af4af28f0975 | 112 | NVIC_EnableIRQ(UART1_IRQn); |
| lmboogaard | 0:af4af28f0975 | 113 | while (((tx_in + 1) % buffer_size) == tx_out) { |
| lmboogaard | 0:af4af28f0975 | 114 | } |
| lmboogaard | 0:af4af28f0975 | 115 | // Start Critical Section - don't interrupt while changing global buffer variables |
| lmboogaard | 0:af4af28f0975 | 116 | NVIC_DisableIRQ(UART1_IRQn); |
| lmboogaard | 0:af4af28f0975 | 117 | } |
| lmboogaard | 0:af4af28f0975 | 118 | tx_buffer[tx_in] = tx_line[i]; |
| lmboogaard | 0:af4af28f0975 | 119 | i++; |
| lmboogaard | 0:af4af28f0975 | 120 | tx_in = (tx_in + 1) % buffer_size; |
| lmboogaard | 0:af4af28f0975 | 121 | } |
| lmboogaard | 0:af4af28f0975 | 122 | if (device.writeable() && (empty)) { |
| lmboogaard | 0:af4af28f0975 | 123 | temp_char = tx_buffer[tx_out]; |
| lmboogaard | 0:af4af28f0975 | 124 | tx_out = (tx_out + 1) % buffer_size; |
| lmboogaard | 0:af4af28f0975 | 125 | // Send first character to start tx interrupts, if stopped |
| lmboogaard | 0:af4af28f0975 | 126 | device.putc(temp_char); |
| lmboogaard | 0:af4af28f0975 | 127 | } |
| lmboogaard | 0:af4af28f0975 | 128 | // End Critical Section |
| lmboogaard | 0:af4af28f0975 | 129 | NVIC_EnableIRQ(UART1_IRQn); |
| lmboogaard | 0:af4af28f0975 | 130 | return; |
| lmboogaard | 0:af4af28f0975 | 131 | } |
| lmboogaard | 0:af4af28f0975 | 132 | |
| lmboogaard | 0:af4af28f0975 | 133 | |
| lmboogaard | 0:af4af28f0975 | 134 | // Read a line from the large rx buffer from rx interrupt routine |
| lmboogaard | 0:af4af28f0975 | 135 | void read_line() { |
| lmboogaard | 0:af4af28f0975 | 136 | int i; |
| lmboogaard | 0:af4af28f0975 | 137 | i = 0; |
| lmboogaard | 0:af4af28f0975 | 138 | // Start Critical Section - don't interrupt while changing global buffer variables |
| lmboogaard | 0:af4af28f0975 | 139 | NVIC_DisableIRQ(UART1_IRQn); |
| lmboogaard | 0:af4af28f0975 | 140 | // Loop reading rx buffer characters until end of line character |
| lmboogaard | 0:af4af28f0975 | 141 | while ((i==0) || (rx_line[i-1] != '\r')) { |
| lmboogaard | 0:af4af28f0975 | 142 | // Wait if buffer empty |
| lmboogaard | 0:af4af28f0975 | 143 | if (rx_in == rx_out) { |
| lmboogaard | 0:af4af28f0975 | 144 | // End Critical Section - need to allow rx interrupt to get new characters for buffer |
| lmboogaard | 0:af4af28f0975 | 145 | NVIC_EnableIRQ(UART1_IRQn); |
| lmboogaard | 0:af4af28f0975 | 146 | while (rx_in == rx_out) { |
| lmboogaard | 0:af4af28f0975 | 147 | } |
| lmboogaard | 0:af4af28f0975 | 148 | // Start Critical Section - don't interrupt while changing global buffer variables |
| lmboogaard | 0:af4af28f0975 | 149 | NVIC_DisableIRQ(UART1_IRQn); |
| lmboogaard | 0:af4af28f0975 | 150 | } |
| lmboogaard | 0:af4af28f0975 | 151 | rx_line[i] = rx_buffer[rx_out]; |
| lmboogaard | 0:af4af28f0975 | 152 | i++; |
| lmboogaard | 0:af4af28f0975 | 153 | rx_out = (rx_out + 1) % buffer_size; |
| lmboogaard | 0:af4af28f0975 | 154 | } |
| lmboogaard | 0:af4af28f0975 | 155 | // End Critical Section |
| lmboogaard | 0:af4af28f0975 | 156 | NVIC_EnableIRQ(UART1_IRQn); |
| lmboogaard | 0:af4af28f0975 | 157 | rx_line[i-1] = 0; |
| lmboogaard | 0:af4af28f0975 | 158 | return; |
| lmboogaard | 0:af4af28f0975 | 159 | } |
| lmboogaard | 0:af4af28f0975 | 160 | |
| lmboogaard | 0:af4af28f0975 | 161 | |
| lmboogaard | 0:af4af28f0975 | 162 | // Interupt Routine to read in data from serial port |
| lmboogaard | 0:af4af28f0975 | 163 | void Rx_interrupt() { |
| lmboogaard | 0:af4af28f0975 | 164 | led1=1; |
| lmboogaard | 0:af4af28f0975 | 165 | // Loop just in case more than one character is in UART's receive FIFO buffer |
| lmboogaard | 0:af4af28f0975 | 166 | // Stop if buffer full |
| lmboogaard | 0:af4af28f0975 | 167 | while ((device.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) { |
| lmboogaard | 0:af4af28f0975 | 168 | rx_buffer[rx_in] = device.getc(); |
| lmboogaard | 0:af4af28f0975 | 169 | // Uncomment to Echo to USB serial to watch data flow |
| lmboogaard | 0:af4af28f0975 | 170 | // monitor_device.putc(rx_buffer[rx_in]); |
| lmboogaard | 0:af4af28f0975 | 171 | rx_in = (rx_in + 1) % buffer_size; |
| lmboogaard | 0:af4af28f0975 | 172 | } |
| lmboogaard | 0:af4af28f0975 | 173 | led1=0; |
| lmboogaard | 0:af4af28f0975 | 174 | return; |
| lmboogaard | 0:af4af28f0975 | 175 | } |
| lmboogaard | 0:af4af28f0975 | 176 | |
| lmboogaard | 0:af4af28f0975 | 177 | |
| lmboogaard | 0:af4af28f0975 | 178 | // Interupt Routine to write out data to serial port |
| lmboogaard | 0:af4af28f0975 | 179 | void Tx_interrupt() { |
| lmboogaard | 0:af4af28f0975 | 180 | led2=1; |
| lmboogaard | 0:af4af28f0975 | 181 | // Loop to fill more than one character in UART's transmit FIFO buffer |
| lmboogaard | 0:af4af28f0975 | 182 | // Stop if buffer empty |
| lmboogaard | 0:af4af28f0975 | 183 | while ((device.writeable()) && (tx_in != tx_out)) { |
| lmboogaard | 0:af4af28f0975 | 184 | device.putc(tx_buffer[tx_out]); |
| lmboogaard | 0:af4af28f0975 | 185 | tx_out = (tx_out + 1) % buffer_size; |
| lmboogaard | 0:af4af28f0975 | 186 | } |
| lmboogaard | 0:af4af28f0975 | 187 | led2=0; |
| lmboogaard | 0:af4af28f0975 | 188 | return; |
| lmboogaard | 0:af4af28f0975 | 189 | } |
| lmboogaard | 0:af4af28f0975 | 190 | |
| lmboogaard | 0:af4af28f0975 | 191 | void NVIC_EnableIRQ(int IRQ){ |
| lmboogaard | 0:af4af28f0975 | 192 | __enable_irq(); |
| lmboogaard | 0:af4af28f0975 | 193 | } |
| lmboogaard | 0:af4af28f0975 | 194 | |
| lmboogaard | 0:af4af28f0975 | 195 | void NVIC_DisableIRQ(int IRQ){ |
| lmboogaard | 0:af4af28f0975 | 196 | __disable_irq(); |
| lmboogaard | 0:af4af28f0975 | 197 | } |
