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

Dependencies:   FIFO

Dependents:   Brute_TS_Controller_2018_11

Committer:
babylonica
Date:
Mon Aug 28 12:25:37 2017 +0000
Revision:
14:54cbbb00bd19
This is stable version. Require the mbed Library Rev.147 or later.

Who changed what in which revision?

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