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 12:58:56 2017 +0000
Revision:
4:c7555051a851
Parent:
1:d3af33dfc87d
Child:
5:a50cdaa90d6a
Bug Fixed: Cannot use format(), baud().

Who changed what in which revision?

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