Prof Greg Egan / Mbed 2 deprecated UAVXArm-GKE

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SerialBuffered.cpp Source File

SerialBuffered.cpp

00001 /*
00002     Copyright (c) 2010 Andy Kirkham
00003  
00004     Permission is hereby granted, free of charge, to any person obtaining a copy
00005     of this software and associated documentation files (the "Software"), to deal
00006     in the Software without restriction, including without limitation the rights
00007     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008     copies of the Software, and to permit persons to whom the Software is
00009     furnished to do so, subject to the following conditions:
00010  
00011     The above copyright notice and this permission notice shall be included in
00012     all copies or substantial portions of the Software.
00013  
00014     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020     THE SOFTWARE.
00021 */
00022 
00023 
00024 #include "mbed.h"
00025 
00026 #ifndef SERIALBUFFERED_C
00027 #define SERIALBUFFERED_C
00028 #endif
00029 
00030 #include "SerialBuffered.h"
00031 #include "sb_globals.h"
00032 
00033 enum { None, One, Two };
00034 enum { WordLength5, WordLength6, WordLength7, WordLength8 };
00035 enum { NoParity, OddParity, EvenParity, Forced1, Forced0 };
00036 enum { StopBit1, StopBit2 };
00037         
00038 SerialBuffered::SerialBuffered(PinName tx, PinName rx) : Serial(tx, rx) {
00039 
00040     // Depending upon the pins used, set-up the Uart.
00041     if (tx == p9 || rx == p10) {
00042         uart_number = 3;
00043         uart_base = LPC_UART3_BASE; 
00044         set_uart3(tx, rx);
00045     }
00046     else if (tx == p13 || tx == p26 || rx == p14 || rx == p25) {        
00047         uart_number = 1;
00048         uart_base = LPC_UART1_BASE; 
00049         set_uart1(tx, rx);
00050     }
00051     else if (tx == p28 || rx == p27) {
00052         uart_number = 2;
00053         uart_base = LPC_UART2_BASE; 
00054         set_uart2(tx, rx);
00055     }
00056     else if (tx == USBTX || rx == USBRX) {
00057         uart_number = 0;
00058         uart_base = LPC_UART0_BASE; 
00059         set_uart0(tx, rx);
00060     }
00061     else {
00062         uart_number = -1;
00063         return;
00064     }
00065 }
00066 
00067 SerialBuffered::~SerialBuffered() {
00068     if (_tx_buffer_used_malloc[uart_number] && _tx_buffer[uart_number]) free(_tx_buffer[uart_number]);
00069     if (_rx_buffer_used_malloc[uart_number] && _rx_buffer[uart_number]) free(_rx_buffer[uart_number]);
00070 }
00071         
00072 /** SerialBuffered_ISR
00073  *
00074  * The main Uart interrupt handler.
00075  */
00076 extern "C" void SerialBuffered_ISR(unsigned long uart_base, int uart_number) {
00077     char c __attribute__((unused));
00078     volatile uint32_t iir, lsr;
00079     
00080     iir = GET_REGISTER(SERIALBUFFERED_IIR); 
00081 
00082     if (iir & 1) {        
00083         return;    /* Eh, wtf? */
00084     }
00085     
00086     iir = (iir >> 1) & 0x3;   
00087     
00088     if (iir == 2) {
00089         while(GET_REGISTER(SERIALBUFFERED_LSR) & 0x1) {
00090             if (_rx_buffer_in[uart_number] == _rx_buffer_out[uart_number] && _rx_buffer_full[uart_number]) {            
00091                 c = GET_REGISTER(SERIALBUFFERED_RBR); /* Oh dear, we need a bigger buffer!, send to dev/null */
00092                 _rx_buffer_overflow[uart_number] = true;
00093             }
00094             else {
00095                 if (_rx_buffer[uart_number]) { /* Ensure buffer pointer is not null before use. */
00096                     c = GET_REGISTER(SERIALBUFFERED_RBR);
00097                     _rx_buffer[uart_number][_rx_buffer_in[uart_number]++] = c;
00098                     if (_rx_buffer_in[uart_number] >= _rx_buffer_size[uart_number]) _rx_buffer_in[uart_number] = 0;
00099                     if (_rx_buffer_in[uart_number] == _rx_buffer_out[uart_number]) _rx_buffer_full[uart_number] = true;
00100                 }
00101             }
00102         }
00103     }
00104     
00105     if (iir == 1) {        
00106         if (_tx_buffer[uart_number]) { /* Ensure buffer pointer is not null before use. */
00107             if (_tx_buffer_in[uart_number] != _tx_buffer_out[uart_number] || _tx_buffer_full[uart_number]) {
00108                 SET_REGISTER(SERIALBUFFERED_THR, (uint32_t)(_tx_buffer[uart_number][_tx_buffer_out[uart_number]++]));
00109                 if (_tx_buffer_out[uart_number] >= _tx_buffer_size[uart_number]) _tx_buffer_out[uart_number] = 0;
00110                 _tx_buffer_full[uart_number] = false;            
00111             }
00112             else {
00113                 SET_REGISTER(SERIALBUFFERED_IER, 1);
00114             }                
00115         }
00116     }
00117     
00118     if (iir == 3) {  
00119         /* We need to provide an error handling system. For now, just dismiss the IRQ. */       
00120         lsr = GET_REGISTER(SERIALBUFFERED_LSR);
00121     } 
00122 }
00123