Jon Freeman / AsyncSerial

Dependencies:   FIFO

Dependents:   Brute_TS_Controller_2018_11

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