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:
Tue Aug 22 15:08:21 2017 +0000
Revision:
12:bfe3984fb2e5
Parent:
10:1baa8e833ac6
Child:
13:e372a354d969
Fixed warnings.

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