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 02:21:20 2017 +0000
Revision:
1:d3af33dfc87d
Parent:
0:907ac3c2fadc
Child:
4:c7555051a851
Minor changes

Who changed what in which revision?

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