SNIC UART Interface library: Serial to Wi-Fi library for Murata TypeYD Wi-Fi module. For more information about TypeYD: http://www.murata.co.jp/products/microwave/module/lbwb1zzydz/index.html

Dependents:   SNIC-xively-jumpstart-demo SNIC-FluentLogger-example TCPEchoServer murataDemo ... more

Fork of YDwifiInterface by Takao Kishino

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SNIC_Core.cpp Source File

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 #if defined(TARGET_LPC1768)
00043 unsigned char  gUART_TEMP_BUF[UART_RECVBUF_SIZE]                __attribute__((section("AHBSRAM1")));
00044 unsigned char  gUART_COMMAND_BUF[UART_REQUEST_PAYLOAD_MAX]      __attribute__((section("AHBSRAM1")));
00045 /** MemoryPool for payload of UART response */
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 #else
00050 unsigned char  gUART_TEMP_BUF[UART_RECVBUF_SIZE];
00051 unsigned char  gUART_COMMAND_BUF[UART_REQUEST_PAYLOAD_MAX];
00052 /** MemoryPool for payload of UART response */
00053 MemoryPool<tagMEMPOOL_BLOCK_T, MEMPOOL_PAYLOAD_NUM>     mMemPoolPayload;
00054 /** MemoryPool for UART receive */
00055 MemoryPool<tagMEMPOOL_BLOCK_T, MEMPOOL_UART_RECV_NUM>   mMemPoolUartRecv;
00056 #endif
00057 Queue<tagMEMPOOL_BLOCK_T, MEMPOOL_UART_RECV_NUM>        mUartRecvQueue;
00058 
00059 tagMEMPOOL_BLOCK_T   *gUART_RCVBUF_p;
00060 int gUART_RECV_COUNT = 0;
00061 
00062 C_SNIC_Core *C_SNIC_Core::mInstance_p = NULL;
00063 
00064 C_SNIC_Core *C_SNIC_Core::getInstance()
00065 {
00066     if( mInstance_p == NULL )
00067     {
00068         mInstance_p    = new C_SNIC_Core();
00069     }
00070     return mInstance_p;
00071 }
00072 
00073 C_SNIC_Core::C_SNIC_Core()
00074 {
00075     int i;
00076     
00077     mUartCommand_p = new C_SNIC_UartCommandManager();
00078     for( i = 0; i < MAX_SOCKET_ID+1; i++ )
00079     {
00080         mConnectInfo[i].recvbuf_p    = NULL;
00081         mConnectInfo[i].is_connected = false;
00082         mConnectInfo[i].is_receive_complete = true;
00083         
00084         mUdpRecvInfo[i].recvbuf_p    = NULL;
00085         mUdpRecvInfo[i].is_received  = false;
00086     }
00087     
00088     mUartRecvThread_p         = NULL;
00089     mUartRecvDispatchThread_p = NULL;
00090 }
00091 
00092 C_SNIC_Core::~C_SNIC_Core()
00093 {
00094 }
00095 
00096 int C_SNIC_Core::resetModule( PinName reset )
00097 {
00098     DigitalOut reset_pin( reset );
00099 
00100     reset_pin = 0;
00101     wait(0.3);
00102     reset_pin = 1;
00103     wait(0.3);
00104     
00105     return 0;
00106 }
00107 
00108 int C_SNIC_Core::initUart(PinName tx, PinName rx, int baud)
00109 {
00110     mUartRequestSeq = 0;
00111 
00112     mUart_p = new RawSerial( tx, rx );
00113     mUart_p->baud( baud );
00114     mUart_p->format(8, SerialBase::None, 1);
00115      
00116     // Initialize uart
00117     gUART_RCVBUF_p = NULL;
00118 
00119     mUart_p->attach( C_SNIC_Core::uartRecvCallback );
00120     // Create UART recv dispatch thread
00121     mUartRecvDispatchThread_p = new Thread( C_SNIC_Core::uartRecvDispatchThread, NULL, osPriorityNormal, UART_THREAD_STACK_SIZE);
00122     if( mUartRecvDispatchThread_p == NULL )
00123     {
00124         DEBUG_PRINT("[C_SNIC_Core::initUart] thread create failed\r\n");
00125         return -1;
00126     }
00127 
00128     return 0;
00129 }
00130 unsigned int C_SNIC_Core::preparationSendCommand( unsigned char cmd_id, unsigned char cmd_sid
00131                                             , unsigned char *req_buf_p,    unsigned int req_buf_len
00132                                             , unsigned char *response_buf_p, unsigned char *command_p )
00133 {
00134     unsigned int command_len = 0;
00135     
00136     // Make all command request
00137     command_len = C_SNIC_UartMsgUtil::makeRequest( cmd_id, req_buf_p, req_buf_len, command_p );
00138 
00139     // Set data for response
00140     mUartCommand_p->setCommandID( cmd_id );
00141     mUartCommand_p->setCommandSID( cmd_sid | 0x80 );
00142     mUartCommand_p->setResponseBuf( response_buf_p );
00143     
00144     return command_len;
00145 }
00146 
00147 int C_SNIC_Core::sendUart( unsigned int len, unsigned char *data )
00148 {
00149     int ret = 0;
00150     mUartMutex.lock();
00151     for( int i = 0; i < len; i++ )
00152     {
00153         // Write to UART
00154         ret = mUart_p->putc( data[i] );
00155         if( ret == -1 )
00156         {
00157             break;
00158         }
00159     }
00160     mUartMutex.unlock();
00161 
00162     return ret;
00163 }
00164 
00165 tagMEMPOOL_BLOCK_T *C_SNIC_Core::allocCmdBuf()
00166 {
00167     // Get buffer from MemoryPool
00168     return mMemPoolPayload.alloc();
00169 }
00170 
00171 void C_SNIC_Core::freeCmdBuf( tagMEMPOOL_BLOCK_T *buf_p )
00172 {
00173     mMemPoolPayload.free( buf_p );
00174 }
00175 
00176 tagMEMPOOL_BLOCK_T *C_SNIC_Core::allocUartRcvBuf()
00177 {
00178     // Get buffer from MemoryPool
00179     return mMemPoolUartRecv.alloc();
00180 }
00181 
00182 void C_SNIC_Core::freeUartRecvBuf( tagMEMPOOL_BLOCK_T *buf_p )
00183 {
00184     mMemPoolUartRecv.free( buf_p );
00185 }
00186 
00187 C_SNIC_Core::tagCONNECT_INFO_T  *C_SNIC_Core::getConnectInfo( int socket_id )
00188 {
00189     if( (socket_id < 0) || (socket_id > MAX_SOCKET_ID) )
00190     {
00191         return NULL;
00192     }
00193     return &mConnectInfo[socket_id];
00194 }
00195 
00196 C_SNIC_Core::tagUDP_RECVINFO_T  *C_SNIC_Core::getUdpRecvInfo( int socket_id )
00197 {
00198     if( (socket_id < 0) || (socket_id > MAX_SOCKET_ID) )
00199     {
00200         return NULL;
00201     }
00202     return &mUdpRecvInfo[socket_id];
00203 }
00204 
00205 C_SNIC_UartCommandManager *C_SNIC_Core::getUartCommand()
00206 {
00207     return mUartCommand_p;
00208 }
00209 
00210 unsigned char *C_SNIC_Core::getCommandBuf()
00211 {
00212     return gUART_COMMAND_BUF;
00213 }
00214 
00215 void C_SNIC_Core::lockAPI( void )
00216 {
00217     mAPIMutex.lock();
00218 }
00219 
00220 void C_SNIC_Core::unlockAPI( void )
00221 {
00222     mAPIMutex.unlock();
00223 }
00224 
00225 void C_SNIC_Core::uartRecvCallback( void )
00226 {
00227     C_SNIC_Core *instance_p = C_SNIC_Core::getInstance();
00228     if( instance_p != NULL )
00229     {
00230         int  recvdata = 0;
00231 
00232         // Check received data from UART.
00233         while( instance_p->mUart_p->readable() )
00234         {
00235             // Receive data from UART.
00236             recvdata = instance_p->mUart_p->getc();
00237 
00238             // Check UART receiving buffer
00239             if( gUART_RCVBUF_p != NULL )
00240             {
00241                 gUART_RCVBUF_p->buf[ gUART_RCVBUF_p->size ] = (unsigned char)recvdata;
00242                 gUART_RCVBUF_p->size++;
00243                 
00244                 if( gUART_RCVBUF_p->size == UART_FIXED_HEADER_SIZE )
00245                 {
00246                     // get demand size
00247                     unsigned short  payload_len = ( ( (gUART_RCVBUF_p->buf[1] & ~0x80) & 0xff) | ( ( (gUART_RCVBUF_p->buf[2] & ~0xC0) << 7) & 0xff80) );
00248                     gUART_RCVBUF_p->demand_size = payload_len + UART_FIXED_SIZE_IN_FRAME;
00249                     if( gUART_RCVBUF_p->demand_size > MEMPOOL_BLOCK_SIZE )
00250                     {
00251                         gUART_RCVBUF_p->demand_size = MEMPOOL_BLOCK_SIZE;
00252                     }
00253                 }
00254 
00255                 if( gUART_RCVBUF_p->demand_size > 0 )
00256                 {
00257                     // Check size of received data.
00258                     if( gUART_RCVBUF_p->size >= gUART_RCVBUF_p->demand_size )
00259                     {
00260                         // Add queue 
00261                         mUartRecvQueue.put( gUART_RCVBUF_p );
00262                         
00263                         gUART_RCVBUF_p = NULL;
00264                     
00265                         if( gUART_RECV_COUNT >= MEMPOOL_UART_RECV_NUM )
00266                         {
00267                             instance_p->mUart_p->attach( NULL );
00268                         }
00269                         // set signal for dispatch thread
00270                         instance_p->mUartRecvDispatchThread_p->signal_set( UART_DISPATCH_SIGNAL );
00271                         break;
00272                     }
00273                 }
00274             }
00275             else
00276             {
00277                 // Check  received data is SOM.
00278                 if( recvdata == UART_CMD_SOM )
00279                 {
00280                     gUART_RCVBUF_p = instance_p->allocUartRcvBuf();
00281                     gUART_RECV_COUNT++;
00282                     gUART_RCVBUF_p->size = 0;
00283                     gUART_RCVBUF_p->demand_size = 0;
00284 
00285                     // get buffer for Uart receive
00286                     gUART_RCVBUF_p->buf[ 0 ] = (unsigned char)recvdata;
00287                     
00288                     gUART_RCVBUF_p->size++;
00289                 }
00290             }
00291         }
00292     }
00293 }
00294 
00295 void C_SNIC_Core::uartRecvDispatchThread (void const *args_p)
00296 {
00297     C_SNIC_Core               *instance_p   = C_SNIC_Core::getInstance();
00298     C_SNIC_UartCommandManager *uartCmdMgr_p = instance_p->getUartCommand();
00299     
00300     tagMEMPOOL_BLOCK_T  *uartRecvBuf_p;
00301     osEvent      evt;
00302     
00303     for(;;)
00304     {
00305         // wait
00306         Thread::signal_wait( UART_DISPATCH_SIGNAL );
00307 
00308         // Get scanresults from queue
00309         evt = mUartRecvQueue.get(UART_RECV_QUEUE_TIMEOUT);
00310         if (evt.status == osEventMessage)
00311         {
00312             do
00313             {
00314                 uartRecvBuf_p = (tagMEMPOOL_BLOCK_T *)evt.value.p;
00315 
00316 #if 0   /* for Debug */
00317                 {
00318                     int i;
00319                     for(i=0;i<uartRecvBuf_p->size;i++)
00320                     {
00321                         DEBUG_PRINT("%02x", uartRecvBuf_p->buf[i]);
00322                     }
00323                     DEBUG_PRINT("\r\n");
00324                 }
00325 #endif
00326                 unsigned char command_id;
00327                 // Get payload from received data from UART.
00328                 int payload_len = C_SNIC_UartMsgUtil::getResponsePayload( uartRecvBuf_p->size, uartRecvBuf_p->buf
00329                                                         , &command_id, gUART_TEMP_BUF );
00330                 // Check receive a TCP packet
00331                 if( (command_id == UART_CMD_ID_SNIC) && (gUART_TEMP_BUF[0] == UART_CMD_SID_SNIC_CONNECTION_RECV_IND) )
00332                 {
00333                     // Packet buffering
00334                     uartCmdMgr_p->bufferredPacket( gUART_TEMP_BUF, payload_len );
00335                 }
00336                 // Check connected from TCP client
00337                 else if( (command_id == UART_CMD_ID_SNIC) && (gUART_TEMP_BUF[0] == UART_CMD_SID_SNIC_TCP_CLIENT_SOCKET_IND) )
00338                 {
00339                     // Connected from TCP client
00340                     uartCmdMgr_p->connectedTCPClient( gUART_TEMP_BUF, payload_len );
00341                 }
00342                 // Check receive UDP packet
00343                 else if( (command_id == UART_CMD_ID_SNIC) && (gUART_TEMP_BUF[0] == UART_CMD_SID_SNIC_UDP_RECV_IND) )
00344                 {
00345                     // UDP packet buffering
00346                     uartCmdMgr_p->bufferredUDPPacket( gUART_TEMP_BUF, payload_len );
00347                 }
00348                 // Check scan results indication 
00349                 else if( (command_id == UART_CMD_ID_WIFI) && (gUART_TEMP_BUF[0] == UART_CMD_SID_WIFI_SCAN_RESULT_IND) )
00350                 {
00351                     // Scan result indicate
00352                     uartCmdMgr_p->scanResultIndicate( gUART_TEMP_BUF, payload_len );
00353                 }
00354                 // Checks in the command which is waiting.
00355                 else if( uartCmdMgr_p->isWaitingCommand(command_id, gUART_TEMP_BUF) )
00356                 {
00357                     // Get buffer for payload data
00358                     unsigned char *payload_buf_p = uartCmdMgr_p->getResponseBuf();
00359                     if( payload_buf_p != NULL )
00360                     {
00361                         memcpy( payload_buf_p, gUART_TEMP_BUF, payload_len );
00362                         uartCmdMgr_p->setResponseBuf( NULL );
00363                     }
00364                     // Set status
00365                     uartCmdMgr_p->setCommandStatus( gUART_TEMP_BUF[2] );
00366                     // Set signal for command response wait.
00367                     uartCmdMgr_p->signal();
00368                 }
00369                 else
00370                 {
00371                     //DEBUG_PRINT(" The received data is not expected.\r\n");
00372                 }
00373                 
00374                 // 
00375                 instance_p->freeUartRecvBuf( uartRecvBuf_p );
00376                 gUART_RECV_COUNT--;
00377                 if( gUART_RECV_COUNT == (MEMPOOL_UART_RECV_NUM-1) )
00378                 {
00379                     instance_p->mUart_p->attach( C_SNIC_Core::uartRecvCallback );   //debug
00380                 }
00381                 
00382                 evt = mUartRecvQueue.get(500);
00383             } while( evt.status == osEventMessage );
00384         }
00385     }
00386 }