Host library for controlling a WiConnect enabled Wi-Fi module.
Dependents: wiconnect-ota_example wiconnect-web_setup_example wiconnect-test-console wiconnect-tcp_server_example ... more
WiconnectSerial.cpp
00001 /** 00002 * ACKme WiConnect Host Library is licensed under the BSD licence: 00003 * 00004 * Copyright (c)2014 ACKme Networks. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without modification, 00008 * are permitted provided that the following conditions are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright notice, 00011 * this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright notice, 00013 * this list of conditions and the following disclaimer in the documentation 00014 * and/or other materials provided with the distribution. 00015 * 3. The name of the author may not be used to endorse or promote products 00016 * derived from this software without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED 00019 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00020 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00021 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00022 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00023 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00026 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00027 * OF SUCH DAMAGE. 00028 */ 00029 00030 #include "Wiconnect.h" 00031 #include "internal/common.h" 00032 00033 #ifndef WICONNECT_SERIAL_RX_BUFFER 00034 #error WICONNECT_SERIAL_RX_BUFFER NOT defined NOT currently supported 00035 #endif 00036 00037 00038 00039 00040 typedef struct 00041 { 00042 uint16_t size; 00043 volatile uint16_t count; 00044 uint8_t *start, *end; 00045 volatile uint8_t *head; 00046 volatile uint8_t *tail; 00047 } SerialRxBuffer; 00048 00049 00050 /*************************************************************************************************/ 00051 WiconnectSerial::WiconnectSerial(const SerialConfig &config, Wiconnect *wiconnect) : RawSerial(config.tx, config.rx) 00052 { 00053 ct_assert(sizeof(ringBuffer) >= sizeof(SerialRxBuffer)); 00054 00055 baud(config.baud); 00056 00057 SerialRxBuffer *rxBuffer = (SerialRxBuffer*)ringBuffer; 00058 memset(rxBuffer, 0, sizeof(SerialRxBuffer)); 00059 bufferAlloc = false; 00060 if(config.serialRxBufferSize > 0) 00061 { 00062 if(config.serialRxBuffer != NULL) 00063 { 00064 rxBuffer->start = (uint8_t*)config.serialRxBuffer; 00065 } 00066 #ifdef WICONNECT_ENABLE_MALLOC 00067 else 00068 { 00069 wiconnect_assert(wiconnect, "WiconnectSerial(), malloc not defined", wiconnect->_malloc != NULL); 00070 rxBuffer->start = (uint8_t*)wiconnect->_malloc(config.serialRxBufferSize); 00071 wiconnect_assert(wiconnect, "WiconnectSerial(), malloc failed", rxBuffer->start != NULL); 00072 bufferAlloc = true; 00073 } 00074 #endif 00075 rxBuffer->head = rxBuffer->tail = (volatile uint8_t*)rxBuffer->start; 00076 rxBuffer->end = (uint8_t*)rxBuffer->head + config.serialRxBufferSize; 00077 rxBuffer->size = config.serialRxBufferSize; 00078 attach(this, &WiconnectSerial::rxIrqHandler, SerialBase::RxIrq); 00079 } 00080 } 00081 00082 /*************************************************************************************************/ 00083 WiconnectSerial::~WiconnectSerial() 00084 { 00085 #ifdef WICONNECT_ENABLE_MALLOC 00086 if(bufferAlloc) 00087 { 00088 SerialRxBuffer *rxBuffer = (SerialRxBuffer*)ringBuffer; 00089 Wiconnect::getInstance()->_free(rxBuffer->start); 00090 } 00091 #endif 00092 } 00093 00094 00095 /*************************************************************************************************/ 00096 void WiconnectSerial::initialize(void) 00097 { 00098 } 00099 00100 /*************************************************************************************************/ 00101 void WiconnectSerial::flush(void) 00102 { 00103 while (readable()) 00104 { 00105 int c = getc(); 00106 } 00107 00108 SerialRxBuffer *rxBuffer = (SerialRxBuffer*)ringBuffer; 00109 rxBuffer->tail = rxBuffer->head = rxBuffer->start; 00110 rxBuffer->count = 0; 00111 } 00112 00113 /*************************************************************************************************/ 00114 int WiconnectSerial::write(const void *data, int bytesToWrite, TimerTimeout timeoutMs) 00115 { 00116 uint8_t *ptr = (uint8_t*)data; 00117 int remaining = bytesToWrite; 00118 00119 while(remaining > 0) 00120 { 00121 if(!writeable()) 00122 { 00123 timeoutTimer.reset(); 00124 while(!writeable()) 00125 { 00126 if(timeoutMs == 0) 00127 { 00128 if(timeoutTimer.timedOut(timeoutMs)) 00129 { 00130 goto exit; 00131 } 00132 } 00133 else 00134 { 00135 if(timeoutTimer.timedOut(timeoutMs)) 00136 { 00137 goto exit; 00138 } 00139 } 00140 } 00141 } 00142 00143 putc(*ptr); 00144 ++ptr; 00145 --remaining; 00146 } 00147 00148 exit: 00149 return bytesToWrite - remaining; 00150 } 00151 00152 /*************************************************************************************************/ 00153 int WiconnectSerial::read(void *data, int bytesToRead, TimerTimeout timeoutMs) 00154 { 00155 SerialRxBuffer *rxBuffer = (SerialRxBuffer*)ringBuffer; 00156 uint8_t *ptr = (uint8_t*)data; 00157 int remaining = bytesToRead; 00158 00159 while(remaining > 0) 00160 { 00161 if(rxBuffer->count == 0) 00162 { 00163 if(timeoutMs == 0) 00164 { 00165 break; 00166 } 00167 else 00168 { 00169 timeoutTimer.reset(); 00170 while(rxBuffer->count == 0) 00171 { 00172 if(timeoutTimer.timedOut(timeoutMs)) 00173 { 00174 goto exit; 00175 } 00176 } 00177 } 00178 } 00179 00180 *ptr++ = *rxBuffer->tail++; 00181 --remaining; 00182 --rxBuffer->count; 00183 if(rxBuffer->tail >= rxBuffer->end) 00184 rxBuffer->tail = rxBuffer->start; 00185 } 00186 00187 exit: 00188 return bytesToRead - remaining; 00189 } 00190 00191 /*************************************************************************************************/ 00192 void WiconnectSerial::rxIrqHandler(void) 00193 { 00194 SerialRxBuffer *rxBuffer = (SerialRxBuffer*)ringBuffer; 00195 00196 while (readable() && rxBuffer->count < rxBuffer->size) 00197 { 00198 *rxBuffer->head++ = (uint8_t)getc(); 00199 ++rxBuffer->count; 00200 if(rxBuffer->head >= rxBuffer->end) 00201 rxBuffer->head = rxBuffer->start; 00202 } 00203 }
Generated on Tue Jul 12 2022 17:35:59 by 1.7.2