Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
AsyncSerial.cpp
- Committer:
- babylonica
- Date:
- 2017-03-30
- Revision:
- 4:c7555051a851
- Parent:
- 1:d3af33dfc87d
- Child:
- 5:a50cdaa90d6a
File content as of revision 4:c7555051a851:
// -*- coding: utf-8 -*-
/**
@file AsyncSerial.cpp
@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.
@author T.Kawamura
@version 1.0
@date 2017-03-29 T.Kawamura Written for C++/mbed.
@date 2017-03-30 T.Kawamura Bug Fixed: Cannot use format(), baud().
@see
Copyright (C) 2017 T.Kawamura.
Released under the MIT license.
http://opensource.org/licenses/mit-license.php
*/
#include "AsyncSerial.hpp"
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){
//Initialize ISR
RawSerial::attach(this, &AsyncSerial::ISR_TX, RawSerial::TxIrq);
RawSerial::attach(this, &AsyncSerial::ISR_RX, RawSerial::RxIrq);
fifo_tx.clear();
fifo_rx.clear();
Is_Serial_Sending = false;
return;
}
AsyncSerial::~AsyncSerial(){
RawSerial::attach(NULL, RawSerial::TxIrq);
RawSerial::attach(NULL, RawSerial::RxIrq);
return;
}
void AsyncSerial::ISR_TX(void){
int data;
if( fifo_tx.available() > 0 ){
data = (int)fifo_tx.get();
RawSerial::putc(data);
}else{
Is_Serial_Sending = false;
}
}
void AsyncSerial::ISR_RX(void){
uint8_t data;
data = (uint8_t)RawSerial::getc();
fifo_rx.put(data);
}
int AsyncSerial::readable(void){
return (int)fifo_rx.available();
}
int AsyncSerial::writeable(void){
return 1;
}
int AsyncSerial::getc(void){
return (int)fifo_rx.get();
}
int AsyncSerial::peekc(void){
return (int)fifo_rx.peek();
}
int AsyncSerial::putc(int c){
int status;
if( Is_Serial_Sending ){
status = fifo_tx.put((uint8_t)c);
if( status != 0 ){
return 1;
}else{
return 0;
}
}else{
Is_Serial_Sending = true;
RawSerial::putc(c);
}
return 1;
}
int AsyncSerial::puts(const char *str){
uint8_t temp;
int status = 0;
for(uint32_t i = 0; i < strlen(str); i++){
temp = (uint8_t)str[i];
status = fifo_tx.put(temp);
}
if( !Is_Serial_Sending ){
Is_Serial_Sending = true;
RawSerial::putc((int)fifo_tx.get());
}
if( status == 0 ){
return 0;
}
AsyncSerial::putc('\n');
return 1;
}
int AsyncSerial::printf(const char *format, ...){
int32_t wrote_length = 0;
char string_buffer[PRINTF_STRING_BUFFER_SIZE];
memset(string_buffer, 0, PRINTF_STRING_BUFFER_SIZE);
va_list arg;
va_start(arg, format);
wrote_length = vsprintf(string_buffer, format, arg);
if( wrote_length > PRINTF_STRING_BUFFER_SIZE ) {
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);
va_end(arg);
return 0;
}
if( wrote_length < 0 ){
va_end(arg);
error("Function vsprintf() was failed.");
return 0;
}
va_end(arg);
wrote_length = AsyncSerial::write((uint8_t*)string_buffer, wrote_length);
return (uint16_t)wrote_length;
}
int AsyncSerial::write(const uint8_t *buffer, int length){
uint8_t temp;
int status;
if ( length < 1 ){
return 0;
}
for(uint32_t i = 0; i < length; i++){
temp = (uint8_t)buffer[i];
status = fifo_tx.put(temp);
}
if( !Is_Serial_Sending ){
Is_Serial_Sending = true;
RawSerial::putc((int)fifo_tx.get());
}
if( status == 0 ){
return 0;
}
return 1;
}
void AsyncSerial::flush(void){
fifo_rx.clear();
return;
}
void AsyncSerial::wait(void){
while( fifo_rx.available() > 0 ){}
return;
}
void AsyncSerial::format(int bits, Parity parity, int stop_bits){
RawSerial::attach(NULL, RawSerial::TxIrq);
RawSerial::attach(NULL, RawSerial::RxIrq);
RawSerial::format(bits, parity, stop_bits);
RawSerial::attach(this, &AsyncSerial::ISR_TX, RawSerial::TxIrq);
RawSerial::attach(this, &AsyncSerial::ISR_RX, RawSerial::RxIrq);
}
void AsyncSerial::baud(int baudrate){
RawSerial::attach(NULL, RawSerial::TxIrq);
RawSerial::attach(NULL, RawSerial::RxIrq);
RawSerial::baud(baudrate);
RawSerial::attach(this, &AsyncSerial::ISR_TX, RawSerial::TxIrq);
RawSerial::attach(this, &AsyncSerial::ISR_RX, RawSerial::RxIrq);
}