noka @willow-micro / AsyncSerial

Dependencies:   FIFO

Dependents:   InvertedPendulum2017 SerialConnect mbed_2018 mbed_2019_rx3 ... more

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 #include "AsyncSerial.hpp"
00021 
00022 AsyncSerial::AsyncSerial(PinName txpin, PinName rxpin, uint32_t baudrate, uint32_t buffer_size){
00023     // RawSerial port init
00024     serial = new RawSerial(txpin, rxpin, baudrate);
00025     
00026     // FIFO init
00027     fifo_tx = new FIFO<uint8_t>(buffer_size);
00028     fifo_rx = new FIFO<uint8_t>(buffer_size);
00029         
00030     fifo_tx->clear();
00031     fifo_rx->clear();
00032     
00033     Is_Serial_Sending = false;
00034     
00035     //Initialize ISR
00036     serial->attach(callback(this, &AsyncSerial::ISR_TX), SerialBase::TxIrq);
00037     serial->attach(callback(this, &AsyncSerial::ISR_RX), SerialBase::RxIrq);
00038     
00039     return;
00040 }
00041 
00042 AsyncSerial::~AsyncSerial(){
00043     serial->attach(NULL, serial->TxIrq);
00044     serial->attach(NULL, serial->RxIrq);
00045     
00046     delete serial;
00047     return;
00048 }
00049 
00050 void AsyncSerial::ISR_TX(void){
00051     int data;
00052     
00053     if( fifo_tx->available() > 0 ){
00054         data = (int)fifo_tx->get();
00055         serial->putc(data);
00056     }else{
00057         Is_Serial_Sending = false;
00058     }
00059 }
00060 
00061 void AsyncSerial::ISR_RX(void){
00062     uint8_t data;
00063 
00064     data = (uint8_t)serial->getc();
00065     fifo_rx->put(data);
00066 }
00067 
00068 int AsyncSerial::readable(void){
00069     return (int)fifo_rx->available();
00070 }
00071 
00072 int AsyncSerial::writeable(void){
00073     return 1;
00074 }
00075 
00076 int AsyncSerial::getc(void){
00077     return (int)fifo_rx->get();
00078 }
00079 
00080 int AsyncSerial::peekc(void){
00081     return (int)fifo_rx->peek();
00082 }
00083 
00084 void AsyncSerial::putc(int c){
00085     if( Is_Serial_Sending ){
00086         fifo_tx->put((uint8_t)c);
00087     }else{
00088         Is_Serial_Sending = true;
00089         serial->putc(c);
00090     }
00091     return;
00092 }
00093 
00094 void AsyncSerial::puts(const char *str){
00095     uint8_t temp;
00096 
00097     for(uint32_t i = 0; i < strlen(str); i++){
00098         temp = (uint8_t)str[i];
00099         fifo_tx->put(temp);
00100     }
00101 
00102     if( !Is_Serial_Sending ){
00103         Is_Serial_Sending = true;
00104         serial->putc((int)fifo_tx->get());
00105     }
00106     
00107     AsyncSerial::putc('\r');
00108     AsyncSerial::putc('\n');
00109     return;
00110 }
00111 
00112 int AsyncSerial::printf(const char *format, ...){
00113     int32_t wrote_length = 0;
00114     char string_buffer[PRINTF_STRING_BUFFER_SIZE];
00115 
00116     memset(string_buffer, 0, PRINTF_STRING_BUFFER_SIZE);
00117     
00118     va_list arg;
00119     va_start(arg, format);
00120     wrote_length = vsprintf(string_buffer, format, arg);
00121     
00122     if( wrote_length > PRINTF_STRING_BUFFER_SIZE ) {
00123         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);
00124         va_end(arg);
00125         return 0;
00126     }
00127 
00128     if( wrote_length < 0 ){
00129         va_end(arg);
00130         error("Function vsprintf() was failed.");
00131         return 0;
00132     }
00133 
00134     va_end(arg);
00135     AsyncSerial::write((uint8_t*)string_buffer, wrote_length);
00136     
00137     return wrote_length;
00138 }
00139 
00140 int AsyncSerial::write(const uint8_t *buffer, int length){
00141     uint8_t temp;
00142     
00143     if ( length < 1 ){
00144         return 0;
00145     }
00146 
00147     for(uint32_t i = 0; i < length; i++){
00148         temp = (uint8_t)buffer[i];
00149         fifo_tx->put(temp);
00150     }
00151 
00152     if( !Is_Serial_Sending ){
00153         Is_Serial_Sending = true;
00154         serial->putc((int)fifo_tx->get());
00155     }
00156 
00157     return 1;
00158 }
00159 
00160 void AsyncSerial::abort_read(void){
00161     fifo_rx->clear();
00162     return;
00163 }
00164 
00165 void AsyncSerial::abort_write(void){
00166     fifo_tx->clear();
00167     return;
00168 }
00169 
00170 void AsyncSerial::wait(void){
00171     while( fifo_tx->available() > 0 ){}
00172     return;
00173 }
00174 
00175 void AsyncSerial::format(int bits, RawSerial::Parity parity, int stop_bits){
00176     serial->attach(NULL, serial->TxIrq);
00177     serial->attach(NULL, serial->RxIrq);
00178 
00179     serial->format(bits, parity, stop_bits);
00180 
00181     serial->attach(callback(this, &AsyncSerial::ISR_TX), serial->TxIrq);
00182     serial->attach(callback(this, &AsyncSerial::ISR_RX), serial->RxIrq);
00183 }
00184 
00185 void AsyncSerial::baud(int baudrate){
00186     serial->attach(NULL, serial->TxIrq);
00187     serial->attach(NULL, serial->RxIrq);
00188 
00189     serial->baud(baudrate);
00190 
00191     serial->attach(callback(this, &AsyncSerial::ISR_TX), serial->TxIrq);
00192     serial->attach(callback(this, &AsyncSerial::ISR_RX), serial->RxIrq);    
00193 }
00194