u-blox / gnss

Dependents:   example-ublox-at-cellular-interface-ext example-low-power-sleep example-C030-out-of-box-demo example-C030-out-of-box-demo ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers serial_pipe.cpp Source File

serial_pipe.cpp

00001 /* Copyright (c) 2017 Michael Ammann
00002  *
00003  * Licensed under the Apache License, Version 2.0 (the "License");
00004  * you may not use this file except in compliance with the License.
00005  * You may obtain a copy of the License at
00006  *
00007  *     http://www.apache.org/licenses/LICENSE-2.0
00008  *
00009  * Unless required by applicable law or agreed to in writing, software
00010  * distributed under the License is distributed on an "AS IS" BASIS,
00011  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012  * See the License for the specific language governing permissions and
00013  * limitations under the License.
00014  */
00015 
00016 #include "serial_pipe.h"
00017 
00018 SerialPipe::SerialPipe(PinName tx, PinName rx, int baudrate, int rxSize, int txSize) :
00019             _SerialPipeBase(tx, rx, baudrate),
00020             _pipeRx( (rx!=NC) ? rxSize : 0), 
00021             _pipeTx( (tx!=NC) ? txSize : 0)
00022 {
00023     if (rx!=NC) {
00024         attach(callback(this, &SerialPipe::rxIrqBuf), RxIrq);
00025     }
00026 }
00027 
00028 SerialPipe::~SerialPipe(void)
00029 {
00030     attach(NULL, RxIrq);
00031     attach(NULL, TxIrq);
00032 }
00033 
00034 // tx channel
00035 int SerialPipe::writeable(void)    
00036 {
00037     return _pipeTx.free();
00038 }
00039 
00040 int SerialPipe::putc(int c)    
00041 {
00042     c = _pipeTx.putc(c);
00043     txStart();
00044     return c;
00045 }
00046 
00047 int SerialPipe::put(const void* buffer, int length, bool blocking)    
00048 { 
00049     int count = length;
00050     const char* ptr = (const char*)buffer;
00051     if (count) {
00052         do {
00053             int written = _pipeTx.put(ptr, count, false);
00054             if (written) {
00055                 ptr += written;
00056                 count -= written;
00057                 txStart();
00058             }
00059             else if (!blocking) {
00060                 /* nothing / just wait */;
00061                 break;
00062             }
00063         }
00064         while (count);
00065     }
00066     
00067     return (length - count);
00068 }
00069 
00070 void SerialPipe::txCopy(void)
00071 {
00072     while (_SerialPipeBase::writeable() && _pipeTx.readable()) {
00073         char c = _pipeTx.getc();
00074         _SerialPipeBase::_base_putc(c);
00075     }
00076 }
00077 
00078 void SerialPipe::txIrqBuf(void)
00079 {
00080     txCopy();
00081     // detach tx isr if we are done 
00082     if (!_pipeTx.readable()) {
00083         attach(NULL, TxIrq);
00084     }
00085 }
00086 
00087 void SerialPipe::txStart(void)
00088 {
00089     // disable the tx isr to avoid interruption
00090     attach(NULL, TxIrq);
00091     txCopy();
00092     // attach the tx isr to handle the remaining data
00093     if (_pipeTx.readable()) {
00094         attach(callback(this, &SerialPipe::txIrqBuf), TxIrq);
00095     }
00096 }
00097 
00098 // rx channel
00099 int SerialPipe::readable(void)                      
00100 { 
00101     return _pipeRx.readable(); 
00102 } 
00103 
00104 int SerialPipe::getc(void)                          
00105 { 
00106     if (!_pipeRx.readable()) {
00107         return EOF;
00108     }
00109 
00110     return _pipeRx.getc(); 
00111 } 
00112 
00113 int SerialPipe::get(void* buffer, int length, bool blocking) 
00114 { 
00115     return _pipeRx.get ((char*)buffer,length,blocking); 
00116 }
00117 
00118 void SerialPipe::rxIrqBuf(void)
00119 {
00120     while (_SerialPipeBase::readable())
00121     {
00122         char c = _SerialPipeBase::_base_getc();
00123         if (_pipeRx.writeable()) {
00124             _pipeRx.putc(c);
00125         } else {
00126             /* overflow */
00127         }
00128     }
00129 }