benoit poulain / AsyncSerialh

Dependencies:   FIFO

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AsyncSerial.cpp Source File

AsyncSerial.cpp

Go to the documentation of this file.
00001 // -*- coding: utf-8 -*-
00002 /**
00003  @file      AsyncSerial.cpp
00004  @brief     Asynchronous (Non-brocking) Serial Communication library with variable length software ring buffer (FIFO). You can use also RawSerial Library's method. You can set the baudrate of the serial communication when instantiating.
00005  
00006  @author    T.Kawamura
00007  @version   1.3
00008  @date      2017-03-29  T.Kawamura  Written for C++/mbed.
00009  @date      2017-03-30  T.Kawamura  Bug Fixed: Cannot use format(), baud().
00010  @date      2017-06-17  T.Kawamura  Update: FIFO Buffer Fixed.
00011  
00012  
00013  @see 
00014  Copyright (C) 2017 T.Kawamura.
00015  Released under the MIT license.
00016  http://opensource.org/licenses/mit-license.php
00017  
00018 */
00019 
00020 
00021 
00022 
00023 
00024 #include "AsyncSerial.hpp"
00025 
00026 AsyncSerial::AsyncSerial(PinName txpin, PinName rxpin, uint32_t baudrate, uint32_t buffer_size){
00027     // RawSerial port init
00028     serial = new RawSerial(txpin, rxpin, baudrate);
00029     
00030     // FIFO init
00031     fifo_tx = new FIFO<uint8_t>(buffer_size);
00032     fifo_rx = new FIFO<uint8_t>(buffer_size);
00033         
00034     fifo_tx->clear();
00035     fifo_rx->clear();
00036     
00037     Is_Serial_Sending = false;
00038     
00039     //Initialize ISR
00040     serial->attach(callback(this, &AsyncSerial::ISR_TX), SerialBase::TxIrq);
00041     serial->attach(callback(this, &AsyncSerial::ISR_RX), SerialBase::RxIrq);
00042     
00043     return;
00044 }
00045 
00046 AsyncSerial::~AsyncSerial(){
00047     serial->attach(NULL, serial->TxIrq);
00048     serial->attach(NULL, serial->RxIrq);
00049     
00050     delete serial;
00051     return;
00052 }
00053 
00054 void AsyncSerial::ISR_TX(void){
00055     int data;
00056     
00057     if( fifo_tx->available() > 0 ){
00058         data = (int)fifo_tx->get();
00059         serial->putc(data);
00060     }else{
00061         Is_Serial_Sending = false;
00062     }
00063 }
00064 
00065 void AsyncSerial::ISR_RX(void){
00066     uint8_t data;
00067 
00068     data = (uint8_t)serial->getc();
00069     fifo_rx->put(data);
00070 }
00071 
00072 int AsyncSerial::readable(void){
00073     return (int)fifo_rx->available();
00074 }
00075 
00076 int AsyncSerial::writeable(void){
00077     return 1;
00078 }
00079 
00080 int AsyncSerial::getc(void){
00081     return (int)fifo_rx->get();
00082 }
00083 
00084 int AsyncSerial::peekc(void){
00085     return (int)fifo_rx->peek();
00086 }
00087 
00088 void AsyncSerial::putc(int c){
00089     if( Is_Serial_Sending ){
00090         fifo_tx->put((uint8_t)c);
00091     }else{
00092         Is_Serial_Sending = true;
00093         serial->putc(c);
00094     }
00095     return;
00096 }
00097 
00098 void AsyncSerial::puts(const char *str){
00099     uint8_t temp;
00100 
00101     for(uint32_t i = 0; i < strlen(str); i++){
00102         temp = (uint8_t)str[i];
00103         fifo_tx->put(temp);
00104     }
00105 
00106     if( !Is_Serial_Sending ){
00107         Is_Serial_Sending = true;
00108         serial->putc((int)fifo_tx->get());
00109     }
00110     
00111     AsyncSerial::putc('\r');
00112     AsyncSerial::putc('\n');
00113     return;
00114 }
00115 
00116 int AsyncSerial::printf(const char *format, ...){
00117     int32_t wrote_length = 0;
00118     char string_buffer[PRINTF_STRING_BUFFER_SIZE];
00119 
00120     memset(string_buffer, 0, PRINTF_STRING_BUFFER_SIZE);
00121     
00122     va_list arg;
00123     va_start(arg, format);
00124     wrote_length = vsprintf(string_buffer, format, arg);
00125     
00126     if( wrote_length > PRINTF_STRING_BUFFER_SIZE ) {
00127         error("%s @ %d : String is too large, string buffer overwrite. (Max buffer size: %d Wrote length: %d)\n", __FILE__, __LINE__, PRINTF_STRING_BUFFER_SIZE, wrote_length);
00128         va_end(arg);
00129         return 0;
00130     }
00131 
00132     if( wrote_length < 0 ){
00133         va_end(arg);
00134         error("Function vsprintf() was failed.");
00135         return 0;
00136     }
00137 
00138     va_end(arg);
00139     AsyncSerial::write((uint8_t*)string_buffer, wrote_length);
00140     
00141     return wrote_length;
00142 }
00143 
00144 int AsyncSerial::write(const uint8_t *buffer, int length){
00145     uint8_t temp;
00146     
00147     if ( length < 1 ){
00148         return 0;
00149     }
00150 
00151     for(uint32_t i = 0; i < length; i++){
00152         temp = (uint8_t)buffer[i];
00153         fifo_tx->put(temp);
00154     }
00155 
00156     if( !Is_Serial_Sending ){
00157         Is_Serial_Sending = true;
00158         serial->putc((int)fifo_tx->get());
00159     }
00160 
00161     return 1;
00162 }
00163 
00164 void AsyncSerial::abort_read(void){
00165     fifo_rx->clear();
00166     return;
00167 }
00168 
00169 void AsyncSerial::abort_write(void){
00170     fifo_tx->clear();
00171     return;
00172 }
00173 
00174 void AsyncSerial::wait(void){
00175     while( fifo_tx->available() > 0 ){}
00176     return;
00177 }
00178 
00179 void AsyncSerial::format(int bits, RawSerial::Parity parity, int stop_bits){
00180     serial->attach(NULL, serial->TxIrq);
00181     serial->attach(NULL, serial->RxIrq);
00182 
00183     serial->format(bits, parity, stop_bits);
00184 
00185     serial->attach(callback(this, &AsyncSerial::ISR_TX), serial->TxIrq);
00186     serial->attach(callback(this, &AsyncSerial::ISR_RX), serial->RxIrq);
00187 }
00188 
00189 void AsyncSerial::baud(int baudrate){
00190     serial->attach(NULL, serial->TxIrq);
00191     serial->attach(NULL, serial->RxIrq);
00192 
00193     serial->baud(baudrate);
00194 
00195     serial->attach(callback(this, &AsyncSerial::ISR_TX), serial->TxIrq);
00196     serial->attach(callback(this, &AsyncSerial::ISR_RX), serial->RxIrq);    
00197 }
00198