Asynchronous (Non-blocking) Serial Communication library with variable length software ring buffer (FIFO). You can use primary method of the RawSerial Library. Operability confirmed on mbed 2.0. (Rev.146)

Dependencies:   FIFO

Dependents:   InvertedPendulum2017 SerialConnect mbed_2018 mbed_2019_rx3 ... more

Committer:
babylonica
Date:
Tue Jul 24 02:38:17 2018 +0000
Revision:
15:278f7f125495
Parent:
14:54cbbb00bd19
Minor fixes;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
babylonica 5:a50cdaa90d6a 1 // -*- coding: utf-8 -*-
babylonica 5:a50cdaa90d6a 2 /**
babylonica 5:a50cdaa90d6a 3 @file AsyncSerial.cpp
babylonica 5:a50cdaa90d6a 4 @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.
babylonica 5:a50cdaa90d6a 5
babylonica 5:a50cdaa90d6a 6 @author T.Kawamura
babylonica 13:e372a354d969 7 @version 1.3
babylonica 5:a50cdaa90d6a 8 @date 2017-03-29 T.Kawamura Written for C++/mbed.
babylonica 5:a50cdaa90d6a 9 @date 2017-03-30 T.Kawamura Bug Fixed: Cannot use format(), baud().
babylonica 8:7390f9bb28d3 10 @date 2017-06-17 T.Kawamura Update: FIFO Buffer Fixed.
babylonica 5:a50cdaa90d6a 11
babylonica 13:e372a354d969 12
babylonica 5:a50cdaa90d6a 13 @see
babylonica 5:a50cdaa90d6a 14 Copyright (C) 2017 T.Kawamura.
babylonica 5:a50cdaa90d6a 15 Released under the MIT license.
babylonica 5:a50cdaa90d6a 16 http://opensource.org/licenses/mit-license.php
babylonica 5:a50cdaa90d6a 17
babylonica 5:a50cdaa90d6a 18 */
babylonica 5:a50cdaa90d6a 19
babylonica 5:a50cdaa90d6a 20 #include "AsyncSerial.hpp"
babylonica 5:a50cdaa90d6a 21
babylonica 10:1baa8e833ac6 22 AsyncSerial::AsyncSerial(PinName txpin, PinName rxpin, uint32_t baudrate, uint32_t buffer_size){
babylonica 10:1baa8e833ac6 23 // RawSerial port init
babylonica 10:1baa8e833ac6 24 serial = new RawSerial(txpin, rxpin, baudrate);
babylonica 10:1baa8e833ac6 25
babylonica 10:1baa8e833ac6 26 // FIFO init
babylonica 10:1baa8e833ac6 27 fifo_tx = new FIFO<uint8_t>(buffer_size);
babylonica 10:1baa8e833ac6 28 fifo_rx = new FIFO<uint8_t>(buffer_size);
babylonica 14:54cbbb00bd19 29
babylonica 14:54cbbb00bd19 30 fifo_tx->clear();
babylonica 14:54cbbb00bd19 31 fifo_rx->clear();
babylonica 14:54cbbb00bd19 32
babylonica 14:54cbbb00bd19 33 Is_Serial_Sending = false;
babylonica 14:54cbbb00bd19 34
babylonica 5:a50cdaa90d6a 35 //Initialize ISR
babylonica 13:e372a354d969 36 serial->attach(callback(this, &AsyncSerial::ISR_TX), SerialBase::TxIrq);
babylonica 13:e372a354d969 37 serial->attach(callback(this, &AsyncSerial::ISR_RX), SerialBase::RxIrq);
babylonica 12:bfe3984fb2e5 38
babylonica 5:a50cdaa90d6a 39 return;
babylonica 5:a50cdaa90d6a 40 }
babylonica 5:a50cdaa90d6a 41
babylonica 5:a50cdaa90d6a 42 AsyncSerial::~AsyncSerial(){
babylonica 10:1baa8e833ac6 43 serial->attach(NULL, serial->TxIrq);
babylonica 10:1baa8e833ac6 44 serial->attach(NULL, serial->RxIrq);
babylonica 15:278f7f125495 45
babylonica 10:1baa8e833ac6 46 delete serial;
babylonica 5:a50cdaa90d6a 47 return;
babylonica 5:a50cdaa90d6a 48 }
babylonica 5:a50cdaa90d6a 49
babylonica 5:a50cdaa90d6a 50 void AsyncSerial::ISR_TX(void){
babylonica 5:a50cdaa90d6a 51 int data;
babylonica 13:e372a354d969 52
babylonica 10:1baa8e833ac6 53 if( fifo_tx->available() > 0 ){
babylonica 10:1baa8e833ac6 54 data = (int)fifo_tx->get();
babylonica 10:1baa8e833ac6 55 serial->putc(data);
babylonica 5:a50cdaa90d6a 56 }else{
babylonica 5:a50cdaa90d6a 57 Is_Serial_Sending = false;
babylonica 10:1baa8e833ac6 58 }
babylonica 5:a50cdaa90d6a 59 }
babylonica 5:a50cdaa90d6a 60
babylonica 5:a50cdaa90d6a 61 void AsyncSerial::ISR_RX(void){
babylonica 5:a50cdaa90d6a 62 uint8_t data;
babylonica 5:a50cdaa90d6a 63
babylonica 10:1baa8e833ac6 64 data = (uint8_t)serial->getc();
babylonica 10:1baa8e833ac6 65 fifo_rx->put(data);
babylonica 5:a50cdaa90d6a 66 }
babylonica 5:a50cdaa90d6a 67
babylonica 5:a50cdaa90d6a 68 int AsyncSerial::readable(void){
babylonica 10:1baa8e833ac6 69 return (int)fifo_rx->available();
babylonica 5:a50cdaa90d6a 70 }
babylonica 5:a50cdaa90d6a 71
babylonica 5:a50cdaa90d6a 72 int AsyncSerial::writeable(void){
babylonica 5:a50cdaa90d6a 73 return 1;
babylonica 5:a50cdaa90d6a 74 }
babylonica 5:a50cdaa90d6a 75
babylonica 5:a50cdaa90d6a 76 int AsyncSerial::getc(void){
babylonica 10:1baa8e833ac6 77 return (int)fifo_rx->get();
babylonica 5:a50cdaa90d6a 78 }
babylonica 5:a50cdaa90d6a 79
babylonica 5:a50cdaa90d6a 80 int AsyncSerial::peekc(void){
babylonica 10:1baa8e833ac6 81 return (int)fifo_rx->peek();
babylonica 5:a50cdaa90d6a 82 }
babylonica 5:a50cdaa90d6a 83
babylonica 8:7390f9bb28d3 84 void AsyncSerial::putc(int c){
babylonica 5:a50cdaa90d6a 85 if( Is_Serial_Sending ){
babylonica 10:1baa8e833ac6 86 fifo_tx->put((uint8_t)c);
babylonica 5:a50cdaa90d6a 87 }else{
babylonica 5:a50cdaa90d6a 88 Is_Serial_Sending = true;
babylonica 10:1baa8e833ac6 89 serial->putc(c);
babylonica 5:a50cdaa90d6a 90 }
babylonica 8:7390f9bb28d3 91 return;
babylonica 5:a50cdaa90d6a 92 }
babylonica 5:a50cdaa90d6a 93
babylonica 8:7390f9bb28d3 94 void AsyncSerial::puts(const char *str){
babylonica 5:a50cdaa90d6a 95 uint8_t temp;
babylonica 0:907ac3c2fadc 96
babylonica 5:a50cdaa90d6a 97 for(uint32_t i = 0; i < strlen(str); i++){
babylonica 5:a50cdaa90d6a 98 temp = (uint8_t)str[i];
babylonica 10:1baa8e833ac6 99 fifo_tx->put(temp);
babylonica 5:a50cdaa90d6a 100 }
babylonica 5:a50cdaa90d6a 101
babylonica 5:a50cdaa90d6a 102 if( !Is_Serial_Sending ){
babylonica 5:a50cdaa90d6a 103 Is_Serial_Sending = true;
babylonica 10:1baa8e833ac6 104 serial->putc((int)fifo_tx->get());
babylonica 5:a50cdaa90d6a 105 }
babylonica 6:08e3b1bba0ac 106
babylonica 6:08e3b1bba0ac 107 AsyncSerial::putc('\r');
babylonica 5:a50cdaa90d6a 108 AsyncSerial::putc('\n');
babylonica 8:7390f9bb28d3 109 return;
babylonica 5:a50cdaa90d6a 110 }
babylonica 5:a50cdaa90d6a 111
babylonica 5:a50cdaa90d6a 112 int AsyncSerial::printf(const char *format, ...){
babylonica 5:a50cdaa90d6a 113 int32_t wrote_length = 0;
babylonica 5:a50cdaa90d6a 114 char string_buffer[PRINTF_STRING_BUFFER_SIZE];
babylonica 5:a50cdaa90d6a 115
babylonica 5:a50cdaa90d6a 116 memset(string_buffer, 0, PRINTF_STRING_BUFFER_SIZE);
babylonica 5:a50cdaa90d6a 117
babylonica 5:a50cdaa90d6a 118 va_list arg;
babylonica 5:a50cdaa90d6a 119 va_start(arg, format);
babylonica 5:a50cdaa90d6a 120 wrote_length = vsprintf(string_buffer, format, arg);
babylonica 5:a50cdaa90d6a 121
babylonica 5:a50cdaa90d6a 122 if( wrote_length > PRINTF_STRING_BUFFER_SIZE ) {
babylonica 5:a50cdaa90d6a 123 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);
babylonica 5:a50cdaa90d6a 124 va_end(arg);
babylonica 5:a50cdaa90d6a 125 return 0;
babylonica 5:a50cdaa90d6a 126 }
babylonica 5:a50cdaa90d6a 127
babylonica 5:a50cdaa90d6a 128 if( wrote_length < 0 ){
babylonica 5:a50cdaa90d6a 129 va_end(arg);
babylonica 5:a50cdaa90d6a 130 error("Function vsprintf() was failed.");
babylonica 5:a50cdaa90d6a 131 return 0;
babylonica 5:a50cdaa90d6a 132 }
babylonica 5:a50cdaa90d6a 133
babylonica 5:a50cdaa90d6a 134 va_end(arg);
babylonica 8:7390f9bb28d3 135 AsyncSerial::write((uint8_t*)string_buffer, wrote_length);
babylonica 5:a50cdaa90d6a 136
babylonica 8:7390f9bb28d3 137 return wrote_length;
babylonica 5:a50cdaa90d6a 138 }
babylonica 5:a50cdaa90d6a 139
babylonica 5:a50cdaa90d6a 140 int AsyncSerial::write(const uint8_t *buffer, int length){
babylonica 5:a50cdaa90d6a 141 uint8_t temp;
babylonica 5:a50cdaa90d6a 142
babylonica 5:a50cdaa90d6a 143 if ( length < 1 ){
babylonica 5:a50cdaa90d6a 144 return 0;
babylonica 5:a50cdaa90d6a 145 }
babylonica 5:a50cdaa90d6a 146
babylonica 5:a50cdaa90d6a 147 for(uint32_t i = 0; i < length; i++){
babylonica 5:a50cdaa90d6a 148 temp = (uint8_t)buffer[i];
babylonica 10:1baa8e833ac6 149 fifo_tx->put(temp);
babylonica 5:a50cdaa90d6a 150 }
babylonica 5:a50cdaa90d6a 151
babylonica 5:a50cdaa90d6a 152 if( !Is_Serial_Sending ){
babylonica 5:a50cdaa90d6a 153 Is_Serial_Sending = true;
babylonica 10:1baa8e833ac6 154 serial->putc((int)fifo_tx->get());
babylonica 5:a50cdaa90d6a 155 }
babylonica 5:a50cdaa90d6a 156
babylonica 8:7390f9bb28d3 157 return 1;
babylonica 5:a50cdaa90d6a 158 }
babylonica 5:a50cdaa90d6a 159
babylonica 10:1baa8e833ac6 160 void AsyncSerial::abort_read(void){
babylonica 10:1baa8e833ac6 161 fifo_rx->clear();
babylonica 10:1baa8e833ac6 162 return;
babylonica 10:1baa8e833ac6 163 }
babylonica 10:1baa8e833ac6 164
babylonica 10:1baa8e833ac6 165 void AsyncSerial::abort_write(void){
babylonica 10:1baa8e833ac6 166 fifo_tx->clear();
babylonica 5:a50cdaa90d6a 167 return;
babylonica 5:a50cdaa90d6a 168 }
babylonica 5:a50cdaa90d6a 169
babylonica 5:a50cdaa90d6a 170 void AsyncSerial::wait(void){
babylonica 10:1baa8e833ac6 171 while( fifo_tx->available() > 0 ){}
babylonica 5:a50cdaa90d6a 172 return;
babylonica 5:a50cdaa90d6a 173 }
babylonica 5:a50cdaa90d6a 174
babylonica 10:1baa8e833ac6 175 void AsyncSerial::format(int bits, RawSerial::Parity parity, int stop_bits){
babylonica 10:1baa8e833ac6 176 serial->attach(NULL, serial->TxIrq);
babylonica 10:1baa8e833ac6 177 serial->attach(NULL, serial->RxIrq);
babylonica 5:a50cdaa90d6a 178
babylonica 10:1baa8e833ac6 179 serial->format(bits, parity, stop_bits);
babylonica 5:a50cdaa90d6a 180
babylonica 12:bfe3984fb2e5 181 serial->attach(callback(this, &AsyncSerial::ISR_TX), serial->TxIrq);
babylonica 12:bfe3984fb2e5 182 serial->attach(callback(this, &AsyncSerial::ISR_RX), serial->RxIrq);
babylonica 5:a50cdaa90d6a 183 }
babylonica 5:a50cdaa90d6a 184
babylonica 5:a50cdaa90d6a 185 void AsyncSerial::baud(int baudrate){
babylonica 10:1baa8e833ac6 186 serial->attach(NULL, serial->TxIrq);
babylonica 10:1baa8e833ac6 187 serial->attach(NULL, serial->RxIrq);
babylonica 5:a50cdaa90d6a 188
babylonica 10:1baa8e833ac6 189 serial->baud(baudrate);
babylonica 5:a50cdaa90d6a 190
babylonica 12:bfe3984fb2e5 191 serial->attach(callback(this, &AsyncSerial::ISR_TX), serial->TxIrq);
babylonica 12:bfe3984fb2e5 192 serial->attach(callback(this, &AsyncSerial::ISR_RX), serial->RxIrq);
babylonica 5:a50cdaa90d6a 193 }
babylonica 5:a50cdaa90d6a 194