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:
Thu Mar 30 13:50:53 2017 +0000
Revision:
6:08e3b1bba0ac
Parent:
5:a50cdaa90d6a
Child:
8:7390f9bb28d3
Update puts(). LF to CR/LF.

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