for EthernetInterface library compatibility.\\ ** Unoffical fix. may be a problem. **
Dependents: SNIC-httpclient-example SNIC-ntpclient-example
Fork of SNICInterface by
SNIC_Core.cpp
00001 /* Copyright (C) 2014 Murata Manufacturing Co.,Ltd., MIT License 00002 * muRata, SWITCH SCIENCE Wi-FI module TypeYD SNIC-UART. 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00005 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00006 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00007 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in all copies or 00011 * substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00014 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00015 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00016 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00017 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00018 */ 00019 #include "mbed.h" 00020 #include "SNIC_Core.h" 00021 #include "SNIC_UartMsgUtil.h" 00022 #include <string> 00023 00024 /** Wait signal ID of UART recv */ 00025 #define UART_DISPATCH_SIGNAL 0x00000002 00026 00027 #define UART_RECVBUF_SIZE 2048 00028 #define UART_THREAD_STACK_SIZE 512 00029 #define UART_FIXED_HEADER_SIZE 3 00030 #define UART_FIXED_SIZE_IN_FRAME 6 00031 #define UART_RECV_QUEUE_TIMEOUT 500 00032 00033 typedef struct 00034 { 00035 tagMEMPOOL_BLOCK_T *mem_p; 00036 unsigned int size; 00037 }tagUART_RECVBUF_T; 00038 00039 /* 00040 Define the global buffer using the area for Ethernet. 00041 */ 00042 unsigned char gUART_TEMP_BUF[UART_RECVBUF_SIZE] __attribute__((section("AHBSRAM1"))); 00043 unsigned char gUART_COMMAND_BUF[UART_REQUEST_PAYLOAD_MAX] __attribute__((section("AHBSRAM1"))); 00044 /** MemoryPool for payload of UART response */ 00045 //MemoryPool<tagMEMPOOL_BLOCK_T, MEMPOOL_PAYLOAD_NUM> mMemPoolPayload __attribute__((section("AHBSRAM1"))); 00046 MemoryPool<tagMEMPOOL_BLOCK_T, MEMPOOL_PAYLOAD_NUM> mMemPoolPayload __attribute__((section("AHBSRAM0"))); 00047 /** MemoryPool for UART receive */ 00048 MemoryPool<tagMEMPOOL_BLOCK_T, MEMPOOL_UART_RECV_NUM> mMemPoolUartRecv __attribute__((section("AHBSRAM0"))); 00049 Queue<tagMEMPOOL_BLOCK_T, MEMPOOL_UART_RECV_NUM> mUartRecvQueue; 00050 00051 tagMEMPOOL_BLOCK_T *gUART_RCVBUF_p; 00052 int gUART_RECV_COUNT = 0; 00053 00054 C_SNIC_Core *C_SNIC_Core::mInstance_p = NULL; 00055 00056 C_SNIC_Core *C_SNIC_Core::getInstance() 00057 { 00058 if( mInstance_p == NULL ) 00059 { 00060 mInstance_p = new C_SNIC_Core(); 00061 } 00062 return mInstance_p; 00063 } 00064 00065 C_SNIC_Core::C_SNIC_Core() 00066 { 00067 int i; 00068 00069 mUartCommand_p = new C_SNIC_UartCommandManager(); 00070 for( i = 0; i < MAX_SOCKET_ID+1; i++ ) 00071 { 00072 mConnectInfo[i].recvbuf_p = NULL; 00073 mConnectInfo[i].is_connected = false; 00074 mConnectInfo[i].is_receive_complete = true; 00075 00076 mUdpRecvInfo[i].recvbuf_p = NULL; 00077 mUdpRecvInfo[i].is_received = false; 00078 } 00079 00080 mUartRecvThread_p = NULL; 00081 mUartRecvDispatchThread_p = NULL; 00082 } 00083 00084 C_SNIC_Core::~C_SNIC_Core() 00085 { 00086 } 00087 00088 int C_SNIC_Core::resetModule( PinName reset ) 00089 { 00090 DigitalOut reset_pin( reset ); 00091 00092 reset_pin = 0; 00093 wait(0.3); 00094 reset_pin = 1; 00095 wait(0.3); 00096 00097 return 0; 00098 } 00099 00100 int C_SNIC_Core::initUart(PinName tx, PinName rx, int baud) 00101 { 00102 mUartRequestSeq = 0; 00103 00104 mUart_p = new RawSerial( tx, rx ); 00105 mUart_p->baud( baud ); 00106 mUart_p->format(8, SerialBase::None, 1); 00107 00108 // Initialize uart 00109 gUART_RCVBUF_p = NULL; 00110 00111 mUart_p->attach( C_SNIC_Core::uartRecvCallback ); 00112 // Create UART recv dispatch thread 00113 mUartRecvDispatchThread_p = new Thread( C_SNIC_Core::uartRecvDispatchThread, NULL, osPriorityNormal, UART_THREAD_STACK_SIZE); 00114 if( mUartRecvDispatchThread_p == NULL ) 00115 { 00116 DEBUG_PRINT("[C_SNIC_Core::initUart] thread create failed\r\n"); 00117 return -1; 00118 } 00119 00120 return 0; 00121 } 00122 unsigned int C_SNIC_Core::preparationSendCommand( unsigned char cmd_id, unsigned char cmd_sid 00123 , unsigned char *req_buf_p, unsigned int req_buf_len 00124 , unsigned char *response_buf_p, unsigned char *command_p ) 00125 { 00126 unsigned int command_len = 0; 00127 00128 // Make all command request 00129 command_len = C_SNIC_UartMsgUtil::makeRequest( cmd_id, req_buf_p, req_buf_len, command_p ); 00130 00131 // Set data for response 00132 mUartCommand_p->setCommandID( cmd_id ); 00133 mUartCommand_p->setCommandSID( cmd_sid | 0x80 ); 00134 mUartCommand_p->setResponseBuf( response_buf_p ); 00135 00136 return command_len; 00137 } 00138 00139 int C_SNIC_Core::sendUart( unsigned int len, unsigned char *data ) 00140 { 00141 int ret = 0; 00142 mUartMutex.lock(); 00143 for( int i = 0; i < len; i++ ) 00144 { 00145 // Write to UART 00146 ret = mUart_p->putc( data[i] ); 00147 if( ret == -1 ) 00148 { 00149 break; 00150 } 00151 } 00152 mUartMutex.unlock(); 00153 00154 return ret; 00155 } 00156 00157 tagMEMPOOL_BLOCK_T *C_SNIC_Core::allocCmdBuf() 00158 { 00159 // Get buffer from MemoryPool 00160 return mMemPoolPayload.alloc(); 00161 } 00162 00163 void C_SNIC_Core::freeCmdBuf( tagMEMPOOL_BLOCK_T *buf_p ) 00164 { 00165 mMemPoolPayload.free( buf_p ); 00166 } 00167 00168 tagMEMPOOL_BLOCK_T *C_SNIC_Core::allocUartRcvBuf() 00169 { 00170 // Get buffer from MemoryPool 00171 return mMemPoolUartRecv.alloc(); 00172 } 00173 00174 void C_SNIC_Core::freeUartRecvBuf( tagMEMPOOL_BLOCK_T *buf_p ) 00175 { 00176 mMemPoolUartRecv.free( buf_p ); 00177 } 00178 00179 C_SNIC_Core::tagCONNECT_INFO_T *C_SNIC_Core::getConnectInfo( int socket_id ) 00180 { 00181 if( (socket_id < 0) || (socket_id > MAX_SOCKET_ID) ) 00182 { 00183 return NULL; 00184 } 00185 return &mConnectInfo[socket_id]; 00186 } 00187 00188 C_SNIC_Core::tagUDP_RECVINFO_T *C_SNIC_Core::getUdpRecvInfo( int socket_id ) 00189 { 00190 if( (socket_id < 0) || (socket_id > MAX_SOCKET_ID) ) 00191 { 00192 return NULL; 00193 } 00194 return &mUdpRecvInfo[socket_id]; 00195 } 00196 00197 C_SNIC_UartCommandManager *C_SNIC_Core::getUartCommand() 00198 { 00199 return mUartCommand_p; 00200 } 00201 00202 unsigned char *C_SNIC_Core::getCommandBuf() 00203 { 00204 return gUART_COMMAND_BUF; 00205 } 00206 00207 void C_SNIC_Core::lockAPI( void ) 00208 { 00209 mAPIMutex.lock(); 00210 } 00211 00212 void C_SNIC_Core::unlockAPI( void ) 00213 { 00214 mAPIMutex.unlock(); 00215 } 00216 00217 void C_SNIC_Core::uartRecvCallback( void ) 00218 { 00219 C_SNIC_Core *instance_p = C_SNIC_Core::getInstance(); 00220 if( instance_p != NULL ) 00221 { 00222 int recvdata = 0; 00223 00224 // Check received data from UART. 00225 while( instance_p->mUart_p->readable() ) 00226 { 00227 // Receive data from UART. 00228 recvdata = instance_p->mUart_p->getc(); 00229 00230 // Check UART receiving buffer 00231 if( gUART_RCVBUF_p != NULL ) 00232 { 00233 gUART_RCVBUF_p->buf[ gUART_RCVBUF_p->size ] = (unsigned char)recvdata; 00234 gUART_RCVBUF_p->size++; 00235 00236 if( gUART_RCVBUF_p->size == UART_FIXED_HEADER_SIZE ) 00237 { 00238 // get demand size 00239 unsigned short payload_len = ( ( (gUART_RCVBUF_p->buf[1] & ~0x80) & 0xff) | ( ( (gUART_RCVBUF_p->buf[2] & ~0xC0) << 7) & 0xff80) ); 00240 gUART_RCVBUF_p->demand_size = payload_len + UART_FIXED_SIZE_IN_FRAME; 00241 if( gUART_RCVBUF_p->demand_size > MEMPOOL_BLOCK_SIZE ) 00242 { 00243 gUART_RCVBUF_p->demand_size = MEMPOOL_BLOCK_SIZE; 00244 } 00245 } 00246 00247 if( gUART_RCVBUF_p->demand_size > 0 ) 00248 { 00249 // Check size of received data. 00250 if( gUART_RCVBUF_p->size >= gUART_RCVBUF_p->demand_size ) 00251 { 00252 // Add queue 00253 mUartRecvQueue.put( gUART_RCVBUF_p ); 00254 00255 gUART_RCVBUF_p = NULL; 00256 00257 if( gUART_RECV_COUNT >= MEMPOOL_UART_RECV_NUM ) 00258 { 00259 instance_p->mUart_p->attach( NULL ); 00260 } 00261 // set signal for dispatch thread 00262 instance_p->mUartRecvDispatchThread_p->signal_set( UART_DISPATCH_SIGNAL ); 00263 break; 00264 } 00265 } 00266 } 00267 else 00268 { 00269 // Check received data is SOM. 00270 if( recvdata == UART_CMD_SOM ) 00271 { 00272 gUART_RCVBUF_p = instance_p->allocUartRcvBuf(); 00273 gUART_RECV_COUNT++; 00274 gUART_RCVBUF_p->size = 0; 00275 gUART_RCVBUF_p->demand_size = 0; 00276 00277 // get buffer for Uart receive 00278 gUART_RCVBUF_p->buf[ 0 ] = (unsigned char)recvdata; 00279 00280 gUART_RCVBUF_p->size++; 00281 } 00282 } 00283 } 00284 } 00285 } 00286 00287 void C_SNIC_Core::uartRecvDispatchThread (void const *args_p) 00288 { 00289 C_SNIC_Core *instance_p = C_SNIC_Core::getInstance(); 00290 C_SNIC_UartCommandManager *uartCmdMgr_p = instance_p->getUartCommand(); 00291 00292 tagMEMPOOL_BLOCK_T *uartRecvBuf_p; 00293 osEvent evt; 00294 00295 for(;;) 00296 { 00297 // wait 00298 Thread::signal_wait( UART_DISPATCH_SIGNAL ); 00299 00300 // Get scanresults from queue 00301 evt = mUartRecvQueue.get(UART_RECV_QUEUE_TIMEOUT); 00302 if (evt.status == osEventMessage) 00303 { 00304 do 00305 { 00306 uartRecvBuf_p = (tagMEMPOOL_BLOCK_T *)evt.value.p; 00307 00308 #if 0 /* for Debug */ 00309 { 00310 int i; 00311 for(i=0;i<uartRecvBuf_p->size;i++) 00312 { 00313 DEBUG_PRINT("%02x", uartRecvBuf_p->buf[i]); 00314 } 00315 DEBUG_PRINT("\r\n"); 00316 } 00317 #endif 00318 unsigned char command_id; 00319 // Get payload from received data from UART. 00320 int payload_len = C_SNIC_UartMsgUtil::getResponsePayload( uartRecvBuf_p->size, uartRecvBuf_p->buf 00321 , &command_id, gUART_TEMP_BUF ); 00322 // Check receive a TCP packet 00323 if( (command_id == UART_CMD_ID_SNIC) && (gUART_TEMP_BUF[0] == UART_CMD_SID_SNIC_CONNECTION_RECV_IND) ) 00324 { 00325 // Packet buffering 00326 uartCmdMgr_p->bufferredPacket( gUART_TEMP_BUF, payload_len ); 00327 } 00328 // Check connected from TCP client 00329 else if( (command_id == UART_CMD_ID_SNIC) && (gUART_TEMP_BUF[0] == UART_CMD_SID_SNIC_TCP_CLIENT_SOCKET_IND) ) 00330 { 00331 // Connected from TCP client 00332 uartCmdMgr_p->connectedTCPClient( gUART_TEMP_BUF, payload_len ); 00333 } 00334 // Check receive UDP packet 00335 else if( (command_id == UART_CMD_ID_SNIC) && (gUART_TEMP_BUF[0] == UART_CMD_SID_SNIC_UDP_RECV_IND) ) 00336 { 00337 // UDP packet buffering 00338 uartCmdMgr_p->bufferredUDPPacket( gUART_TEMP_BUF, payload_len ); 00339 } 00340 // Check scan results indication 00341 else if( (command_id == UART_CMD_ID_WIFI) && (gUART_TEMP_BUF[0] == UART_CMD_SID_WIFI_SCAN_RESULT_IND) ) 00342 { 00343 // Scan result indicate 00344 uartCmdMgr_p->scanResultIndicate( gUART_TEMP_BUF, payload_len ); 00345 } 00346 // Checks in the command which is waiting. 00347 else if( uartCmdMgr_p->isWaitingCommand(command_id, gUART_TEMP_BUF) ) 00348 { 00349 // Get buffer for payload data 00350 unsigned char *payload_buf_p = uartCmdMgr_p->getResponseBuf(); 00351 if( payload_buf_p != NULL ) 00352 { 00353 memcpy( payload_buf_p, gUART_TEMP_BUF, payload_len ); 00354 uartCmdMgr_p->setResponseBuf( NULL ); 00355 } 00356 // Set status 00357 uartCmdMgr_p->setCommandStatus( gUART_TEMP_BUF[2] ); 00358 // Set signal for command response wait. 00359 uartCmdMgr_p->signal(); 00360 } 00361 else 00362 { 00363 //DEBUG_PRINT(" The received data is not expected.\r\n"); 00364 } 00365 00366 // 00367 instance_p->freeUartRecvBuf( uartRecvBuf_p ); 00368 gUART_RECV_COUNT--; 00369 if( gUART_RECV_COUNT == (MEMPOOL_UART_RECV_NUM-1) ) 00370 { 00371 instance_p->mUart_p->attach( C_SNIC_Core::uartRecvCallback ); //debug 00372 } 00373 00374 evt = mUartRecvQueue.get(500); 00375 } while( evt.status == osEventMessage ); 00376 } 00377 } 00378 }
Generated on Tue Jul 12 2022 18:43:49 by 1.7.2