for EthernetInterface library compatibility.\\ ** Unoffical fix. may be a problem. **

Dependents:   SNIC-httpclient-example SNIC-ntpclient-example

Fork of SNICInterface by muRata

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 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 }