RPC over Serial with read line interrupt tested on LPC1768 and mac minicom terminal. Baudrate 115200

Dependencies:   mbed-rpc-stmfork mbed-src

Fork of rpc_over_serial by Suga koubou

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "mbed_rpc.h"
00003 #include "stmbed.h"
00004 
00005 //Serial pc(USBTX, USBRX);
00006 //Serial pc(p29, p30); // stm32f103b
00007 Serial pc(SERIAL_TX, SERIAL_RX); // stm32f103b  PA_2 PA_3
00008 DigitalOut ld1(PA_5);
00009 DigitalOut myled(LED1);
00010 
00011 void Tx_interrupt();
00012 void Rx_interrupt();
00013 void send_line();
00014 void read_line();
00015  
00016  
00017 // Circular buffers for serial TX and RX data - used by interrupt routines
00018 const int buffer_size = 255;
00019 // might need to increase buffer size for high baud rates
00020 char tx_buffer[buffer_size];
00021 char rx_buffer[buffer_size];
00022 // Circular buffer pointers
00023 // volatile makes read-modify-write atomic 
00024 volatile int tx_in=0;
00025 volatile int tx_out=0;
00026 volatile int rx_in=0;
00027 volatile int rx_out=0;
00028 // Line buffers for sprintf and sscanf
00029 char tx_line[80];
00030 char rx_line[80];
00031 
00032 
00033 void blink(){
00034     myled = 1; // LED is ON
00035     wait(0.5); // 200 ms
00036     myled = 0; // LED is OFF
00037     wait(1.0); // 1 sec
00038     }
00039     
00040 int main() {
00041     ld1=0;
00042     blink();
00043     blink();
00044     blink();
00045         
00046     char buf[256], outbuf[256];
00047     //pc.baud(115200);
00048     pc.baud(9600); // nucleo F103RB
00049     
00050     // receive commands, and send back the responses
00051     pc.printf(" ************** Serial RPC example starting ************************* \r\n");
00052     
00053     // setup the classes that can be created dynamically
00054     //    RPC::add_rpc_class<RpcAnalogIn>();
00055     //    RPC::add_rpc_class<RpcAnalogOut>();
00056     RPC::add_rpc_class<RpcDigitalIn>();
00057     RPC::add_rpc_class<RpcDigitalOut>();
00058     RPC::add_rpc_class<RpcDigitalInOut>();
00059     RPC::add_rpc_class<RpcPwmOut>();
00060     RPC::add_rpc_class<RpcTimer>();
00061     RPC::add_rpc_class<RpcSPI>();
00062     RPC::add_rpc_class<RpcSerial>();
00063     // receive commands, and send back the responses
00064     pc.printf(" ************** 1 \r\n");
00065 
00066     // Setup a serial interrupt function to receive data
00067     pc.attach(&Rx_interrupt, Serial::RxIrq);
00068     // Setup a serial interrupt function to transmit data
00069     //pc.attach(&Tx_interrupt, Serial::TxIrq);
00070     pc.printf(" ************** 2 \r\n");    
00071     
00072     while(1) {
00073         // Read a line from the large rx buffer from rx interrupt routine
00074         read_line();
00075             
00076         //pc.gets(buf, 4);        
00077         //pc.printf("#> '%s'\r\n", buf);
00078         
00079         /************************************
00080         This is an example of the RPC command required to create an LED object and turn it on:
00081         /DigitalOut/new LED1 myled
00082         /myled/write 1
00083         *************************************
00084         */
00085 
00086 
00087         RPC::call(buf, outbuf); 
00088         RPC::call(rx_line, outbuf); 
00089 
00090         pc.printf("%s\r\n", outbuf);
00091     }
00092 }
00093 
00094 
00095 
00096 // Copy tx line buffer to large tx buffer for tx interrupt routine
00097 void send_line() {
00098     int i;
00099     char temp_char;
00100     bool empty;
00101     i = 0;
00102 // Start Critical Section - don't interrupt while changing global buffer variables
00103     NVIC_DisableIRQ(USART2_IRQn);
00104     empty = (tx_in == tx_out);
00105     while ((i==0) || (tx_line[i-1] != '\n')) {
00106 // Wait if buffer full
00107         if (((tx_in + 1) % buffer_size) == tx_out) {
00108 // End Critical Section - need to let interrupt routine empty buffer by sending
00109             NVIC_EnableIRQ(USART2_IRQn);
00110             while (((tx_in + 1) % buffer_size) == tx_out) {
00111             }
00112 // Start Critical Section - don't interrupt while changing global buffer variables
00113             NVIC_DisableIRQ(USART2_IRQn);
00114         }
00115         tx_buffer[tx_in] = tx_line[i];
00116         i++;
00117         tx_in = (tx_in + 1) % buffer_size;
00118     }
00119     if (pc.writeable() && (empty)) {
00120         temp_char = tx_buffer[tx_out];
00121         tx_out = (tx_out + 1) % buffer_size;
00122 // Send first character to start tx interrupts, if stopped
00123         pc.putc(temp_char);
00124     }
00125 // End Critical Section
00126     NVIC_EnableIRQ(USART2_IRQn);
00127     return;
00128 }
00129  
00130  
00131 // Read a line from the large rx buffer from rx interrupt routine
00132 void read_line() {
00133     int i;
00134     i = 0;
00135 // Start Critical Section - don't interrupt while changing global buffer variables
00136     NVIC_DisableIRQ(USART2_IRQn); // stm32: USART2_IRQn lpc nxp: UART1_IRQn
00137 // Loop reading rx buffer characters until end of line character
00138     while ((i==0) || (rx_line[i-1] != '\r')) {
00139 // Wait if buffer empty
00140         if (rx_in == rx_out) {
00141 // End Critical Section - need to allow rx interrupt to get new characters for buffer
00142             NVIC_EnableIRQ(USART2_IRQn);
00143             while (rx_in == rx_out) {
00144             }
00145 // Start Critical Section - don't interrupt while changing global buffer variables
00146             NVIC_DisableIRQ(USART2_IRQn);
00147         }
00148         rx_line[i] = rx_buffer[rx_out];
00149         i++;
00150         rx_out = (rx_out + 1) % buffer_size;
00151     }
00152 // End Critical Section
00153     NVIC_EnableIRQ(USART2_IRQn);
00154     rx_line[i-1] = 0;
00155     return;
00156 }
00157  
00158  
00159 // Interupt Routine to read in data from serial port
00160 void Rx_interrupt() {
00161 //    led1=1;
00162 // Loop just in case more than one character is in UART's receive FIFO buffer
00163 // Stop if buffer full
00164     while ((pc.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
00165         rx_buffer[rx_in] = pc.getc();
00166 // Uncomment to Echo to USB serial to watch data flow
00167         pc.putc(rx_buffer[rx_in]);
00168         rx_in = (rx_in + 1) % buffer_size;
00169     }
00170 //    led1=0;
00171     return;
00172 }
00173  
00174  
00175 // Interupt Routine to write out data to serial port
00176 void Tx_interrupt() {
00177 //    led2=1;
00178 // Loop to fill more than one character in UART's transmit FIFO buffer
00179 // Stop if buffer empty
00180     while ((pc.writeable()) && (tx_in != tx_out)) {
00181         pc.putc(tx_buffer[tx_out]);
00182         tx_out = (tx_out + 1) % buffer_size;
00183     }
00184 //    led2=0;
00185     return;
00186 }