TI's CC3100 websocket camera demo with Arducam mini ov5642 and freertos. Should work with other M3's. Work in progress test demo.
cc3100_driver.cpp
00001 /* 00002 * driver.c - CC31xx/CC32xx Host Driver Implementation 00003 * 00004 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 00005 * 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. 00018 * 00019 * Neither the name of Texas Instruments Incorporated nor the names of 00020 * its contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00026 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00027 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00028 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00029 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00031 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00032 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 */ 00036 00037 /*****************************************************************************/ 00038 /* Include files */ 00039 /*****************************************************************************/ 00040 #include "cc3100_simplelink.h" 00041 #include "cc3100_protocol.h" 00042 #include "cc3100_driver.h" 00043 00044 #include "fPtr_func.h" 00045 #include "cli_uart.h" 00046 00047 #if (defined (SL_PLATFORM_MULTI_THREADED)) || (defined (SL_PLATFORM_EXTERNAL_SPAWN)) 00048 #include "osi.h" 00049 #endif 00050 00051 /*****************************************************************************/ 00052 /* Macro declarations */ 00053 /*****************************************************************************/ 00054 00055 namespace mbed_cc3100 { 00056 00057 #ifndef SL_MEMORY_MGMT_DYNAMIC 00058 typedef struct { 00059 uint32_t Align; 00060 _SlDriverCb_t DriverCB; 00061 uint8_t AsyncRespBuf[SL_ASYNC_MAX_MSG_LEN]; 00062 } _SlStatMem_t; 00063 00064 _SlStatMem_t g_StatMem; 00065 #endif 00066 00067 00068 _SlDriverCb_t* g_pCB = NULL; 00069 00070 uint8_t gFirstCmdMode = 0; 00071 00072 const _SlSyncPattern_t g_H2NSyncPattern = H2N_SYNC_PATTERN; 00073 const _SlSyncPattern_t g_H2NCnysPattern = H2N_CNYS_PATTERN; 00074 volatile uint8_t RxIrqCnt; 00075 00076 #ifndef SL_TINY_EXT 00077 const _SlActionLookup_t _SlActionLookupTable[] = { 00078 {ACCEPT_ID, SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE, (_SlSpawnEntryFunc_t) &_sl_HandleAsync_Accept}, 00079 {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_Connect}, 00080 {SELECT_ID, SL_OPCODE_SOCKET_SELECTASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_Select}, 00081 {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_DnsGetHostByName}, 00082 {GETHOSYBYSERVICE_ID, SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_DnsGetHostByService}, 00083 {PING_ID, SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE, (_SlSpawnEntryFunc_t) &_sl_HandleAsync_PingResponse}, 00084 {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_Stop} 00085 00086 }; 00087 #else 00088 const _SlActionLookup_t _SlActionLookupTable[] = 00089 { 00090 {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Connect}, 00091 {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByName}, 00092 {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Stop} 00093 }; 00094 #endif 00095 00096 typedef struct 00097 { 00098 uint16_t opcode; 00099 uint8_t event; 00100 } OpcodeKeyVal_t; 00101 00102 /* The table translates opcode to user's event type */ 00103 const OpcodeKeyVal_t OpcodeTranslateTable[] = 00104 { 00105 {SL_OPCODE_WLAN_SMART_CONFIG_START_ASYNC_RESPONSE, SL_WLAN_SMART_CONFIG_COMPLETE_EVENT}, 00106 {SL_OPCODE_WLAN_SMART_CONFIG_STOP_ASYNC_RESPONSE,SL_WLAN_SMART_CONFIG_STOP_EVENT}, 00107 {SL_OPCODE_WLAN_STA_CONNECTED, SL_WLAN_STA_CONNECTED_EVENT}, 00108 {SL_OPCODE_WLAN_STA_DISCONNECTED,SL_WLAN_STA_DISCONNECTED_EVENT}, 00109 {SL_OPCODE_WLAN_P2P_DEV_FOUND,SL_WLAN_P2P_DEV_FOUND_EVENT}, 00110 {SL_OPCODE_WLAN_P2P_NEG_REQ_RECEIVED, SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT}, 00111 {SL_OPCODE_WLAN_CONNECTION_FAILED, SL_WLAN_CONNECTION_FAILED_EVENT}, 00112 {SL_OPCODE_WLAN_WLANASYNCCONNECTEDRESPONSE, SL_WLAN_CONNECT_EVENT}, 00113 {SL_OPCODE_WLAN_WLANASYNCDISCONNECTEDRESPONSE, SL_WLAN_DISCONNECT_EVENT}, 00114 {SL_OPCODE_NETAPP_IPACQUIRED, SL_NETAPP_IPV4_IPACQUIRED_EVENT}, 00115 {SL_OPCODE_NETAPP_IPACQUIRED_V6, SL_NETAPP_IPV6_IPACQUIRED_EVENT}, 00116 {SL_OPCODE_NETAPP_IP_LEASED, SL_NETAPP_IP_LEASED_EVENT}, 00117 {SL_OPCODE_NETAPP_IP_RELEASED, SL_NETAPP_IP_RELEASED_EVENT}, 00118 {SL_OPCODE_SOCKET_TXFAILEDASYNCRESPONSE, SL_SOCKET_TX_FAILED_EVENT}, 00119 {SL_OPCODE_SOCKET_SOCKETASYNCEVENT, SL_SOCKET_ASYNC_EVENT} 00120 }; 00121 00122 /* 00123 00124 #define SL_OPCODE_SILO_DEVICE ( 0x0 << SL_OPCODE_SILO_OFFSET ) 00125 #define SL_OPCODE_SILO_WLAN ( 0x1 << SL_OPCODE_SILO_OFFSET ) 00126 #define SL_OPCODE_SILO_SOCKET ( 0x2 << SL_OPCODE_SILO_OFFSET ) 00127 #define SL_OPCODE_SILO_NETAPP ( 0x3 << SL_OPCODE_SILO_OFFSET ) 00128 #define SL_OPCODE_SILO_NVMEM ( 0x4 << SL_OPCODE_SILO_OFFSET ) 00129 #define SL_OPCODE_SILO_NETCFG ( 0x5 << SL_OPCODE_SILO_OFFSET ) 00130 00131 00132 */ 00133 00134 /* The Lookup table below holds the event handlers to be called according to the incoming 00135 RX message SILO type */ 00136 const _SlSpawnEntryFunc_t RxMsgClassLUT[] = { 00137 (_SlSpawnEntryFunc_t)_SlDrvDeviceEventHandler, /* SL_OPCODE_SILO_DEVICE */ 00138 #if defined(sl_WlanEvtHdlr) || defined(EXT_LIB_REGISTERED_WLAN_EVENTS) 00139 (_SlSpawnEntryFunc_t)_SlDrvHandleWlanEvents, /* SL_OPCODE_SILO_WLAN */ 00140 #else 00141 NULL, 00142 #endif 00143 #if defined (sl_SockEvtHdlr) || defined(EXT_LIB_REGISTERED_SOCK_EVENTS) 00144 (_SlSpawnEntryFunc_t)_SlDrvHandleSockEvents, /* SL_OPCODE_SILO_SOCKET */ 00145 #else 00146 NULL, 00147 #endif 00148 00149 #if defined(sl_NetAppEvtHdlr) || defined(EXT_LIB_REGISTERED_NETAPP_EVENTS) 00150 (_SlSpawnEntryFunc_t)_SlDrvHandleNetAppEvents, /* SL_OPCODE_SILO_NETAPP */ 00151 #else 00152 NULL, 00153 #endif 00154 NULL, /* SL_OPCODE_SILO_NVMEM */ 00155 NULL, /* SL_OPCODE_SILO_NETCFG */ 00156 NULL, 00157 NULL 00158 }; 00159 00160 #ifndef SL_PLATFORM_MULTI_THREADED 00161 cc3100_driver::cc3100_driver(cc3100_spi &spi, cc3100_nonos &nonos, cc3100_netapp &netapp, cc3100_flowcont &flowcont) 00162 : _spi(spi), _nonos(nonos), _netapp(netapp), _flowcont(flowcont) 00163 { 00164 } 00165 #else 00166 00167 cc3100_driver::cc3100_driver(cc3100_spi &spi, cc3100_netapp &netapp, cc3100_flowcont &flowcont) 00168 : _spi(spi), _netapp(netapp), _flowcont(flowcont) 00169 { 00170 } 00171 #endif 00172 00173 cc3100_driver::~cc3100_driver() 00174 { 00175 00176 } 00177 00178 /*****************************************************************************/ 00179 /* Variables */ 00180 /*****************************************************************************/ 00181 00182 /********************************************************************************/ 00183 00184 uint8_t cc3100_driver::_SlDrvProtectAsyncRespSetting(uint8_t *pAsyncRsp, uint8_t ActionID, uint8_t SocketID) 00185 { 00186 uint8_t ObjIdx; 00187 00188 00189 /* Use Obj to issue the command, if not available try later */ 00190 ObjIdx = _SlDrvWaitForPoolObj(ActionID, SocketID); 00191 00192 if (MAX_CONCURRENT_ACTIONS != ObjIdx) 00193 { 00194 _SlDrvProtectionObjLockWaitForever(); 00195 g_pCB->ObjPool[ObjIdx].pRespArgs = pAsyncRsp; 00196 _SlDrvProtectionObjUnLock(); 00197 } 00198 00199 return ObjIdx; 00200 } 00201 00202 00203 /*****************************************************************************/ 00204 /* Internal functions */ 00205 /*****************************************************************************/ 00206 bool cc3100_driver::_SL_PENDING_RX_MSG(pDriver* pDriverCB){ 00207 00208 if(RxIrqCnt != (pDriverCB)->RxDoneCnt){ 00209 return TRUE; 00210 }else{ 00211 return FALSE; 00212 } 00213 } 00214 00215 /***************************************************************************** 00216 _SlDrvDriverCBInit - init Driver Control Block 00217 *****************************************************************************/ 00218 void cc3100_driver::_SlDrvDriverCBInit(void) 00219 { 00220 00221 uint8_t Idx = 0; 00222 00223 #ifdef SL_MEMORY_MGMT_DYNAMIC 00224 00225 g_pCB = sl_Malloc(sizeof(_SlDriverCb_t)); 00226 #else 00227 g_pCB = &(g_StatMem.DriverCB); 00228 #endif 00229 00230 MALLOC_OK_CHECK(g_pCB); 00231 _SlDrvMemZero(g_pCB, sizeof(_SlDriverCb_t)); 00232 RxIrqCnt = 0; 00233 #ifndef SL_PLATFORM_MULTI_THREADED 00234 OSI_RET_OK_CHECK( _nonos.sl_SyncObjCreate(&g_pCB->CmdSyncObj, "CmdSyncObj") ); 00235 _nonos.sl_SyncObjClear(&g_pCB->CmdSyncObj); 00236 OSI_RET_OK_CHECK( _nonos.sl_LockObjCreate(&g_pCB->GlobalLockObj, "GlobalLockObj") ); 00237 OSI_RET_OK_CHECK( _nonos.sl_LockObjCreate(&g_pCB->ProtectionLockObj, "ProtectionLockObj") ); 00238 #else 00239 OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->CmdSyncObj, "CmdSyncObj") ); 00240 sl_SyncObjClear(&g_pCB->CmdSyncObj); 00241 OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->GlobalLockObj, "GlobalLockObj") ); 00242 OSI_RET_OK_CHECK( sl_LockObjCreate(&g_pCB->ProtectionLockObj, "ProtectionLockObj") ); 00243 #endif 00244 /* Init Drv object */ 00245 _SlDrvMemZero(&g_pCB->ObjPool[0], MAX_CONCURRENT_ACTIONS*sizeof(_SlPoolObj_t)); 00246 00247 /* place all Obj in the free list*/ 00248 g_pCB->FreePoolIdx = 0; 00249 00250 for (Idx = 0 ; Idx < MAX_CONCURRENT_ACTIONS ; Idx++) 00251 { 00252 g_pCB->ObjPool[Idx].NextIndex = Idx + 1; 00253 g_pCB->ObjPool[Idx].AdditionalData = SL_MAX_SOCKETS; 00254 #ifndef SL_PLATFORM_MULTI_THREADED 00255 OSI_RET_OK_CHECK( _nonos.sl_SyncObjCreate(&g_pCB->ObjPool[Idx].SyncObj, "SyncObj")); 00256 _nonos.sl_SyncObjClear(&g_pCB->ObjPool[Idx].SyncObj); 00257 #else 00258 OSI_RET_OK_CHECK( sl_SyncObjCreate(&g_pCB->ObjPool[Idx].SyncObj, "SyncObj")); 00259 sl_SyncObjClear(&g_pCB->ObjPool[Idx].SyncObj); 00260 #endif 00261 } 00262 00263 g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS; 00264 g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS; 00265 00266 /* Flow control init */ 00267 g_pCB->FlowContCB.TxPoolCnt = FLOW_CONT_MIN; 00268 #ifndef SL_PLATFORM_MULTI_THREADED 00269 OSI_RET_OK_CHECK(_nonos.sl_LockObjCreate(&g_pCB->FlowContCB.TxLockObj, "TxLockObj")); 00270 OSI_RET_OK_CHECK(_nonos.sl_SyncObjCreate(&g_pCB->FlowContCB.TxSyncObj, "TxSyncObj")); 00271 #else 00272 OSI_RET_OK_CHECK(sl_LockObjCreate(&g_pCB->FlowContCB.TxLockObj, "TxLockObj")); 00273 OSI_RET_OK_CHECK(sl_SyncObjCreate(&g_pCB->FlowContCB.TxSyncObj, "TxSyncObj")); 00274 #endif 00275 gFirstCmdMode = 0; 00276 } 00277 00278 /***************************************************************************** 00279 _SlDrvDriverCBDeinit - De init Driver Control Block 00280 *****************************************************************************/ 00281 void cc3100_driver::_SlDrvDriverCBDeinit() 00282 { 00283 uint8_t Idx = 0; 00284 00285 /* Flow control de-init */ 00286 g_pCB->FlowContCB.TxPoolCnt = 0; 00287 #ifndef SL_PLATFORM_MULTI_THREADED 00288 OSI_RET_OK_CHECK(_nonos.sl_LockObjDelete(&g_pCB->FlowContCB.TxLockObj)); 00289 OSI_RET_OK_CHECK(_nonos.sl_SyncObjDelete(&g_pCB->FlowContCB.TxSyncObj)); 00290 00291 OSI_RET_OK_CHECK( _nonos.sl_SyncObjDelete(&g_pCB->CmdSyncObj) ); 00292 OSI_RET_OK_CHECK( _nonos.sl_LockObjDelete(&g_pCB->GlobalLockObj) ); 00293 OSI_RET_OK_CHECK( _nonos.sl_LockObjDelete(&g_pCB->ProtectionLockObj) ); 00294 #else 00295 OSI_RET_OK_CHECK(sl_LockObjDelete(&g_pCB->FlowContCB.TxLockObj)); 00296 OSI_RET_OK_CHECK(sl_SyncObjDelete(&g_pCB->FlowContCB.TxSyncObj)); 00297 00298 OSI_RET_OK_CHECK( sl_SyncObjDelete(&g_pCB->CmdSyncObj) ); 00299 OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->GlobalLockObj) ); 00300 OSI_RET_OK_CHECK( sl_LockObjDelete(&g_pCB->ProtectionLockObj) ); 00301 #endif 00302 00303 #ifndef SL_TINY_EXT 00304 for (Idx = 0; Idx < MAX_CONCURRENT_ACTIONS; Idx++) 00305 #endif 00306 00307 g_pCB->FreePoolIdx = 0; 00308 g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS; 00309 g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS; 00310 00311 #ifdef SL_MEMORY_MGMT_DYNAMIC 00312 sl_Free(g_pCB); 00313 #else 00314 g_pCB = NULL; 00315 #endif 00316 00317 g_pCB = NULL; 00318 } 00319 00320 /***************************************************************************** 00321 _SlDrvRxIrqHandler - Interrupt handler 00322 *****************************************************************************/ 00323 00324 void cc3100_driver::_SlDrvRxIrqHandler(void *pValue) 00325 { 00326 00327 int32_t rv = 0; 00328 _spi.MaskIntHdlr(); 00329 00330 RxIrqCnt++; 00331 00332 if (TRUE == g_pCB->IsCmdRespWaited) { 00333 #ifndef SL_PLATFORM_MULTI_THREADED 00334 OSI_RET_OK_CHECK( _nonos.sl_SyncObjSignalFromIRQ(&g_pCB->CmdSyncObj) ); 00335 #else 00336 OSI_RET_OK_CHECK( sl_SyncObjSignalFromIRQ(&g_pCB->CmdSyncObj) ); 00337 #endif 00338 } else { 00339 #if (defined (SL_PLATFORM_MULTI_THREADED)) || (defined (SL_PLATFORM_EXTERNAL_SPAWN)) 00340 rv = sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, 0); 00341 00342 if(rv <0){ 00343 Uart_Write((uint8_t*)"\n\r OSI_OPERATION_FAILED \n\r"); 00344 } 00345 #else 00346 _nonos._SlNonOsSpawn((_SlSpawnEntryFunc_t)&_SlDrvMsgReadSpawnCtx, NULL, 0); 00347 #endif 00348 00349 } 00350 } 00351 00352 /***************************************************************************** 00353 _SlDrvCmdOp 00354 *****************************************************************************/ 00355 _SlReturnVal_t cc3100_driver::_SlDrvCmdOp(_SlCmdCtrl_t *pCmdCtrl,void* pTxRxDescBuff, _SlCmdExt_t *pCmdExt) 00356 { 00357 _SlReturnVal_t RetVal; 00358 00359 _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj); 00360 00361 g_pCB->IsCmdRespWaited = TRUE; 00362 SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdOp: call _SlDrvMsgWrite"); 00363 00364 /* send the message */ 00365 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t*)pTxRxDescBuff); 00366 00367 if(SL_OS_RET_CODE_OK == RetVal) { 00368 00369 #ifndef SL_IF_TYPE_UART 00370 /* Waiting for SPI to stabilize after first command */ 00371 if( 0 == gFirstCmdMode ) { 00372 gFirstCmdMode = 1; 00373 wait_ms(2); 00374 } 00375 #endif 00376 00377 /* wait for respond */ 00378 RetVal = _SlDrvMsgReadCmdCtx(); /* will free global lock */ 00379 SL_TRACE0(DBG_MSG, MSG_314, "_SlDrvCmdOp: exited _SlDrvMsgReadCmdCtx"); 00380 00381 } else 00382 { 00383 _SlDrvObjUnLock(&g_pCB->GlobalLockObj); 00384 } 00385 return RetVal; 00386 } 00387 00388 /***************************************************************************** 00389 _SlDrvDataReadOp 00390 *****************************************************************************/ 00391 _SlReturnVal_t cc3100_driver::_SlDrvDataReadOp(_SlSd_t Sd, _SlCmdCtrl_t *pCmdCtrl, void* pTxRxDescBuff, _SlCmdExt_t *pCmdExt) 00392 { 00393 _SlReturnVal_t RetVal; 00394 uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS; 00395 _SlArgsData_t pArgsData; 00396 00397 /* Validate input arguments */ 00398 VERIFY_PROTOCOL(NULL != pCmdExt->pRxPayload); 00399 00400 /* If zero bytes is requested, return error. */ 00401 /* This allows us not to fill remote socket's IP address in return arguments */ 00402 VERIFY_PROTOCOL(0 != pCmdExt->RxPayloadLen); 00403 00404 /* Validate socket */ 00405 if((Sd & BSD_SOCKET_ID_MASK) >= SL_MAX_SOCKETS) { 00406 return SL_EBADF; 00407 } 00408 00409 /*Use Obj to issue the command, if not available try later*/ 00410 ObjIdx = (uint8_t)_SlDrvWaitForPoolObj(RECV_ID, Sd & BSD_SOCKET_ID_MASK); 00411 00412 if (MAX_CONCURRENT_ACTIONS == ObjIdx) { 00413 return SL_POOL_IS_EMPTY; 00414 } 00415 00416 _SlDrvProtectionObjLockWaitForever(); 00417 00418 pArgsData.pData = pCmdExt->pRxPayload; 00419 pArgsData.pArgs = (uint8_t *)pTxRxDescBuff; 00420 g_pCB->ObjPool[ObjIdx].pRespArgs = (uint8_t *)&pArgsData; 00421 _SlDrvProtectionObjUnLock(); 00422 00423 /* Do Flow Control check/update for DataWrite operation */ 00424 _SlDrvObjLockWaitForever(&g_pCB->FlowContCB.TxLockObj); 00425 00426 /* Clear SyncObj for the case it was signalled before TxPoolCnt */ 00427 /* dropped below '1' (last Data buffer was taken) */ 00428 /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */ 00429 #ifndef SL_PLATFORM_MULTI_THREADED 00430 _nonos.sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj); 00431 #else 00432 sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj); 00433 #endif 00434 if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN) { 00435 00436 /* If TxPoolCnt was increased by other thread at this moment, 00437 TxSyncObj won't wait here */ 00438 _SlDrvSyncObjWaitForever(&g_pCB->FlowContCB.TxSyncObj); 00439 00440 } 00441 00442 _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj); 00443 00444 VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN); 00445 g_pCB->FlowContCB.TxPoolCnt--; 00446 00447 _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj); 00448 00449 /* send the message */ 00450 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t *)pTxRxDescBuff); 00451 00452 _SlDrvObjUnLock(&g_pCB->GlobalLockObj); 00453 00454 if(SL_OS_RET_CODE_OK == RetVal) { 00455 /* Wait for response message. Will be signaled by _SlDrvMsgRead. */ 00456 _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj); 00457 } 00458 00459 _SlDrvReleasePoolObj(ObjIdx); 00460 return RetVal; 00461 } 00462 00463 /* ******************************************************************************/ 00464 /* _SlDrvDataWriteOp */ 00465 /* ******************************************************************************/ 00466 _SlReturnVal_t cc3100_driver::_SlDrvDataWriteOp(_SlSd_t Sd, _SlCmdCtrl_t *pCmdCtrl, void* pTxRxDescBuff, _SlCmdExt_t *pCmdExt) 00467 { 00468 _SlReturnVal_t RetVal = SL_EAGAIN; /* initiated as SL_EAGAIN for the non blocking mode */ 00469 while( 1 ) { 00470 /* Do Flow Control check/update for DataWrite operation */ 00471 _SlDrvObjLockWaitForever(&g_pCB->FlowContCB.TxLockObj); 00472 00473 /* Clear SyncObj for the case it was signalled before TxPoolCnt */ 00474 /* dropped below '1' (last Data buffer was taken) */ 00475 /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */ 00476 #ifndef SL_PLATFORM_MULTI_THREADED 00477 _nonos.sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj); 00478 #else 00479 sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj); 00480 #endif 00481 /* we have indication that the last send has failed - socket is no longer valid for operations */ 00482 if(g_pCB->SocketTXFailure & (1<<(Sd & BSD_SOCKET_ID_MASK))) { 00483 _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj); 00484 return SL_SOC_ERROR; 00485 } 00486 00487 if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN + 1) { 00488 /* we have indication that this socket is set as blocking and we try to */ 00489 /* unblock it - return an error */ 00490 if( g_pCB->SocketNonBlocking & (1<< (Sd & BSD_SOCKET_ID_MASK))) 00491 { 00492 _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj); 00493 return RetVal; 00494 } 00495 /* If TxPoolCnt was increased by other thread at this moment, */ 00496 /* TxSyncObj won't wait here */ 00497 _SlDrvSyncObjWaitForever(&g_pCB->FlowContCB.TxSyncObj); 00498 } 00499 00500 if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ) { 00501 break; 00502 } 00503 else 00504 { 00505 _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj); 00506 } 00507 } 00508 00509 _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj); 00510 00511 00512 VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ); 00513 g_pCB->FlowContCB.TxPoolCnt--; 00514 00515 _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj); 00516 00517 /* send the message */ 00518 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t*)pTxRxDescBuff); 00519 00520 _SlDrvObjUnLock(&g_pCB->GlobalLockObj); 00521 00522 return RetVal; 00523 } 00524 00525 /* ******************************************************************************/ 00526 /* _SlDrvMsgWrite */ 00527 /* ******************************************************************************/ 00528 _SlReturnVal_t cc3100_driver::_SlDrvMsgWrite(_SlCmdCtrl_t *pCmdCtrl, _SlCmdExt_t *pCmdExt, uint8_t *pTxRxDescBuff) 00529 { 00530 uint8_t sendRxPayload = FALSE; 00531 VERIFY_PROTOCOL(NULL != pCmdCtrl); 00532 00533 g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl; 00534 g_pCB->FunctionParams.pTxRxDescBuff = pTxRxDescBuff; 00535 g_pCB->FunctionParams.pCmdExt = pCmdExt; 00536 00537 g_pCB->TempProtocolHeader.Opcode = pCmdCtrl->Opcode; 00538 g_pCB->TempProtocolHeader.Len = _SL_PROTOCOL_CALC_LEN(pCmdCtrl, pCmdExt); 00539 00540 if (pCmdExt && pCmdExt->RxPayloadLen < 0 && pCmdExt->TxPayloadLen) 00541 { 00542 pCmdExt->RxPayloadLen = pCmdExt->RxPayloadLen * (-1); /* change sign */ 00543 sendRxPayload = TRUE; 00544 g_pCB->TempProtocolHeader.Len = g_pCB->TempProtocolHeader.Len + pCmdExt->RxPayloadLen; 00545 } 00546 00547 #ifdef SL_START_WRITE_STAT 00548 sl_IfStartWriteSequence(g_pCB->FD); 00549 #endif 00550 00551 #ifdef SL_IF_TYPE_UART 00552 /* Write long sync pattern */ 00553 _spi.spi_Write(g_pCB->FD, (uint8_t *)&g_H2NSyncPattern.Long, 2*SYNC_PATTERN_LEN); 00554 #else 00555 /* Write short sync pattern */ 00556 _spi.spi_Write(g_pCB->FD, (uint8_t *)&g_H2NSyncPattern.Short, SYNC_PATTERN_LEN); 00557 #endif 00558 /* Header */ 00559 _spi.spi_Write(g_pCB->FD, (uint8_t *)&g_pCB->TempProtocolHeader, _SL_CMD_HDR_SIZE); 00560 00561 /* Descriptors */ 00562 if (pTxRxDescBuff && pCmdCtrl->TxDescLen > 0) 00563 { 00564 _spi.spi_Write(g_pCB->FD, pTxRxDescBuff, 00565 _SL_PROTOCOL_ALIGN_SIZE(pCmdCtrl->TxDescLen)); 00566 } 00567 00568 /* A special mode where Rx payload and Rx length are used as Tx as well */ 00569 /* This mode requires no Rx payload on the response and currently used by fs_Close and sl_Send on */ 00570 /* transceiver mode */ 00571 if (sendRxPayload == TRUE ) 00572 { 00573 _spi.spi_Write(g_pCB->FD, pCmdExt->pRxPayload, _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->RxPayloadLen)); 00574 } 00575 00576 /* Payload */ 00577 if (pCmdExt && pCmdExt->TxPayloadLen > 0) 00578 { 00579 /* If the message has payload, it is mandatory that the message's arguments are protocol aligned. */ 00580 /* Otherwise the aligning of arguments will create a gap between arguments and payload. */ 00581 VERIFY_PROTOCOL(_SL_IS_PROTOCOL_ALIGNED_SIZE(pCmdCtrl->TxDescLen)); 00582 00583 _spi.spi_Write(g_pCB->FD, pCmdExt->pTxPayload, _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->TxPayloadLen)); 00584 } 00585 00586 _SL_DBG_CNT_INC(MsgCnt.Write); 00587 00588 #ifdef SL_START_WRITE_STAT 00589 sl_IfEndWriteSequence(g_pCB->FD); 00590 #endif 00591 00592 return SL_OS_RET_CODE_OK; 00593 } 00594 00595 /* ******************************************************************************/ 00596 /* _SlDrvMsgRead */ 00597 /* ******************************************************************************/ 00598 _SlReturnVal_t cc3100_driver::_SlDrvMsgRead(void) 00599 { 00600 /* alignment for small memory models */ 00601 union { 00602 uint8_t TempBuf[_SL_RESP_HDR_SIZE]; 00603 uint32_t DummyBuf[2]; 00604 } uBuf; 00605 uint8_t TailBuffer[4]; 00606 uint16_t LengthToCopy; 00607 uint16_t AlignedLengthRecv; 00608 uint8_t AlignSize; 00609 uint8_t *pAsyncBuf = NULL; 00610 uint16_t OpCode; 00611 uint16_t RespPayloadLen; 00612 uint8_t sd = SL_MAX_SOCKETS; 00613 _SlRxMsgClass_e RxMsgClass; 00614 00615 00616 /* save params in global CB */ 00617 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; 00618 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL; 00619 00620 00621 VERIFY_RET_OK(_SlDrvRxHdrRead((uint8_t*)(uBuf.TempBuf), &AlignSize)); 00622 00623 OpCode = OPCODE(uBuf.TempBuf); 00624 RespPayloadLen = RSP_PAYLOAD_LEN(uBuf.TempBuf); 00625 00626 00627 /* 'Init Compelete' message bears no valid FlowControl info */ 00628 if(SL_OPCODE_DEVICE_INITCOMPLETE != OpCode) { 00629 g_pCB->FlowContCB.TxPoolCnt = ((_SlResponseHeader_t *)uBuf.TempBuf)->TxPoolCnt; 00630 g_pCB->SocketNonBlocking = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketNonBlocking; 00631 g_pCB->SocketTXFailure = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketTXFailure; 00632 00633 if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN) { 00634 _SlDrvSyncObjSignal(&g_pCB->FlowContCB.TxSyncObj); 00635 } 00636 } 00637 00638 /* Find the RX messaage class and set its async event handler */ 00639 _SlDrvClassifyRxMsg(OpCode); 00640 00641 RxMsgClass = g_pCB->FunctionParams.AsyncExt.RxMsgClass; 00642 00643 00644 switch(RxMsgClass) 00645 { 00646 case ASYNC_EVT_CLASS: 00647 00648 VERIFY_PROTOCOL(NULL == pAsyncBuf); 00649 00650 #ifdef SL_MEMORY_MGMT_DYNAMIC 00651 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = sl_Malloc(SL_ASYNC_MAX_MSG_LEN); 00652 #else 00653 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = g_StatMem.AsyncRespBuf; 00654 #endif 00655 /* set the local pointer to the allocated one */ 00656 pAsyncBuf = g_pCB->FunctionParams.AsyncExt.pAsyncBuf; 00657 00658 /* clear the async buffer */ 00659 _SlDrvMemZero(pAsyncBuf, SL_ASYNC_MAX_MSG_LEN); 00660 00661 MALLOC_OK_CHECK(pAsyncBuf); 00662 00663 memcpy(pAsyncBuf, uBuf.TempBuf, _SL_RESP_HDR_SIZE); 00664 if (_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) <= SL_ASYNC_MAX_PAYLOAD_LEN) 00665 { 00666 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen); 00667 } 00668 else 00669 { 00670 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(SL_ASYNC_MAX_PAYLOAD_LEN); 00671 } 00672 if (RespPayloadLen > 0) 00673 { 00674 _spi.spi_Read(g_pCB->FD, pAsyncBuf + _SL_RESP_HDR_SIZE, AlignedLengthRecv); 00675 } 00676 /* In case ASYNC RX buffer length is smaller then the received data length, dump the rest */ 00677 if ((_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) > SL_ASYNC_MAX_PAYLOAD_LEN)) 00678 { 00679 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) - SL_ASYNC_MAX_PAYLOAD_LEN; 00680 while (AlignedLengthRecv > 0) 00681 { 00682 _spi.spi_Read(g_pCB->FD,TailBuffer,4); 00683 AlignedLengthRecv = AlignedLengthRecv - 4; 00684 } 00685 } 00686 00687 _SlDrvProtectionObjLockWaitForever(); 00688 00689 if ( 00690 #ifndef SL_TINY_EXT 00691 (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE == OpCode) || (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE_V6 == OpCode) || 00692 #endif 00693 (SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE == OpCode) 00694 ) 00695 { 00696 /* go over the active list if exist to find obj waiting for this Async event */ 00697 sd = ((((_SocketResponse_t *)(pAsyncBuf + _SL_RESP_HDR_SIZE))->sd) & BSD_SOCKET_ID_MASK); 00698 } 00699 _SlFindAndSetActiveObj(OpCode, sd); 00700 _SlDrvProtectionObjUnLock(); 00701 00702 break; 00703 case RECV_RESP_CLASS: 00704 { 00705 uint8_t ExpArgSize; /* Expected size of Recv/Recvfrom arguments */ 00706 00707 switch(OpCode) 00708 { 00709 case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE: 00710 ExpArgSize = RECVFROM_IPV4_ARGS_SIZE; 00711 break; 00712 #ifndef SL_TINY_EXT 00713 case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6: 00714 ExpArgSize = RECVFROM_IPV6_ARGS_SIZE; 00715 break; 00716 #endif 00717 default: 00718 /* SL_OPCODE_SOCKET_RECVASYNCRESPONSE: */ 00719 ExpArgSize = RECV_ARGS_SIZE; 00720 } 00721 00722 /* Read first 4 bytes of Recv/Recvfrom response to get SocketId and actual */ 00723 /* response data length */ 00724 _spi.spi_Read(g_pCB->FD, &uBuf.TempBuf[4], RECV_ARGS_SIZE); 00725 00726 /* Validate Socket ID and Received Length value. */ 00727 VERIFY_PROTOCOL((SD(&uBuf.TempBuf[4])& BSD_SOCKET_ID_MASK) < SL_MAX_SOCKETS); 00728 00729 _SlDrvProtectionObjLockWaitForever(); 00730 00731 /* go over the active list if exist to find obj waiting for this Async event */ 00732 VERIFY_RET_OK(_SlFindAndSetActiveObj(OpCode,SD(&uBuf.TempBuf[4]) & BSD_SOCKET_ID_MASK)); 00733 00734 /* Verify data is waited on this socket. The pArgs should have been set by _SlDrvDataReadOp(). */ 00735 VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData))->pArgs); 00736 00737 memcpy( ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs, &uBuf.TempBuf[4], RECV_ARGS_SIZE); 00738 00739 if(ExpArgSize > RECV_ARGS_SIZE) 00740 { 00741 _spi.spi_Read(g_pCB->FD, 00742 ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs + RECV_ARGS_SIZE, 00743 ExpArgSize - RECV_ARGS_SIZE); 00744 } 00745 00746 /* Here g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData contains requested(expected) Recv/Recvfrom DataSize. */ 00747 /* Overwrite requested DataSize with actual one. */ 00748 /* If error is received, this information will be read from arguments. */ 00749 if(ACT_DATA_SIZE(&uBuf.TempBuf[4]) > 0) 00750 { 00751 VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData); 00752 00753 /* Read 4 bytes aligned from interface */ 00754 /* therefore check the requested length and read only */ 00755 /* 4 bytes aligned data. The rest unaligned (if any) will be read */ 00756 /* and copied to a TailBuffer */ 00757 LengthToCopy = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (3); 00758 AlignedLengthRecv = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (~3); 00759 if( AlignedLengthRecv >= 4) 00760 { 00761 _spi.spi_Read(g_pCB->FD,((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData,AlignedLengthRecv ); 00762 } 00763 /* copy the unaligned part, if any */ 00764 if( LengthToCopy > 0) 00765 { 00766 _spi.spi_Read(g_pCB->FD,TailBuffer,4); 00767 /* copy TailBuffer unaligned part (1/2/3 bytes) */ 00768 memcpy(((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData + AlignedLengthRecv,TailBuffer,LengthToCopy); 00769 } 00770 } 00771 _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj); 00772 _SlDrvProtectionObjUnLock(); 00773 } 00774 break; 00775 00776 case CMD_RESP_CLASS: 00777 00778 /* Some commands pass a maximum arguments size. */ 00779 /* In this case Driver will send extra dummy patterns to NWP if */ 00780 /* the response message is smaller than maximum. */ 00781 /* When RxDescLen is not exact, using RxPayloadLen is forbidden! */ 00782 /* If such case cannot be avoided - parse message here to detect */ 00783 /* arguments/payload border. */ 00784 _spi.spi_Read(g_pCB->FD, g_pCB->FunctionParams.pTxRxDescBuff, _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdCtrl->RxDescLen)); 00785 00786 if((NULL != g_pCB->FunctionParams.pCmdExt) && (0 != g_pCB->FunctionParams.pCmdExt->RxPayloadLen)) { 00787 /* Actual size of command's response payload: <msg_payload_len> - <rsp_args_len> */ 00788 int16_t ActDataSize = RSP_PAYLOAD_LEN(uBuf.TempBuf) - g_pCB->FunctionParams.pCmdCtrl->RxDescLen; 00789 00790 g_pCB->FunctionParams.pCmdExt->ActualRxPayloadLen = ActDataSize; 00791 00792 /* Check that the space prepared by user for the response data is sufficient. */ 00793 if(ActDataSize <= 0) { 00794 g_pCB->FunctionParams.pCmdExt->RxPayloadLen = 0; 00795 } else { 00796 /* In case the user supplied Rx buffer length which is smaller then the received data length, copy according to user length */ 00797 if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) { 00798 LengthToCopy = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (3); 00799 AlignedLengthRecv = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3); 00800 } else { 00801 LengthToCopy = ActDataSize & (3); 00802 AlignedLengthRecv = ActDataSize & (~3); 00803 } 00804 /* Read 4 bytes aligned from interface */ 00805 /* therefore check the requested length and read only */ 00806 /* 4 bytes aligned data. The rest unaligned (if any) will be read */ 00807 /* and copied to a TailBuffer */ 00808 00809 if( AlignedLengthRecv >= 4) { 00810 _spi.spi_Read(g_pCB->FD, 00811 g_pCB->FunctionParams.pCmdExt->pRxPayload, 00812 AlignedLengthRecv ); 00813 00814 } 00815 /* copy the unaligned part, if any */ 00816 if( LengthToCopy > 0) { 00817 _spi.spi_Read(g_pCB->FD,TailBuffer,4); 00818 /* copy TailBuffer unaligned part (1/2/3 bytes) */ 00819 memcpy(g_pCB->FunctionParams.pCmdExt->pRxPayload + AlignedLengthRecv, 00820 TailBuffer, 00821 LengthToCopy); 00822 ActDataSize = ActDataSize-4; 00823 } 00824 /* In case the user supplied Rx buffer length which is smaller then the received data length, dump the rest */ 00825 if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) { 00826 /* calculate the rest of the data size to dump */ 00827 AlignedLengthRecv = ActDataSize - (g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3)); 00828 while( AlignedLengthRecv > 0) { 00829 _spi.spi_Read(g_pCB->FD,TailBuffer, 4 ); 00830 AlignedLengthRecv = AlignedLengthRecv - 4; 00831 } 00832 } 00833 } 00834 } 00835 break; 00836 00837 default: 00838 /* DUMMY_MSG_CLASS: Flow control message has no payload. */ 00839 break; 00840 } 00841 00842 if(AlignSize > 0) { 00843 _spi.spi_Read(g_pCB->FD, uBuf.TempBuf, AlignSize); 00844 } 00845 00846 _SL_DBG_CNT_INC(MsgCnt.Read); 00847 00848 /* Unmask Interrupt call */ 00849 _spi.UnMaskIntHdlr(); 00850 00851 return SL_OS_RET_CODE_OK; 00852 } 00853 00854 /* ******************************************************************************/ 00855 /* _SlAsyncEventGenericHandler */ 00856 /* ******************************************************************************/ 00857 void cc3100_driver::_SlAsyncEventGenericHandler(void) 00858 { 00859 uint32_t SlAsyncEvent = 0; 00860 uint8_t OpcodeFound = FALSE; 00861 uint8_t i; 00862 00863 uint32_t* pEventLocation = NULL; /* This pointer will override the async buffer with the translated event type */ 00864 _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)g_pCB->FunctionParams.AsyncExt.pAsyncBuf; 00865 00866 00867 /* if no async event registered nothing to do..*/ 00868 if (g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler == NULL) 00869 return; 00870 00871 /* Iterate through all the opcode in the table */ 00872 for (i=0; i< (sizeof(OpcodeTranslateTable) / sizeof(OpcodeKeyVal_t)); i++) 00873 { 00874 if (OpcodeTranslateTable[i].opcode == pHdr->GenHeader.Opcode) 00875 { 00876 SlAsyncEvent = OpcodeTranslateTable[i].event; 00877 OpcodeFound = TRUE; 00878 break; 00879 } 00880 } 00881 00882 /* No Async event found in the table */ 00883 if (OpcodeFound == FALSE) 00884 { 00885 /* This case handles all the async events handlers of the DEVICE & SOCK Silos which are handled internally. 00886 For these cases we send the async even buffer as is */ 00887 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00888 } 00889 else 00890 { 00891 /* calculate the event type location to be filled in the async buffer */ 00892 pEventLocation = (uint32_t*)(g_pCB->FunctionParams.AsyncExt.pAsyncBuf + sizeof (_SlResponseHeader_t) - sizeof(SlAsyncEvent) ); 00893 00894 /* Override the async buffer (before the data starts ) with our event type */ 00895 *pEventLocation = SlAsyncEvent; 00896 00897 /* call the event handler registered by the user with our async buffer which now holds 00898 the User's event type and its related data */ 00899 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(pEventLocation); 00900 } 00901 00902 } 00903 00904 00905 /* ******************************************************************************/ 00906 /* _SlDrvMsgReadCmdCtx */ 00907 /* ******************************************************************************/ 00908 _SlReturnVal_t cc3100_driver::_SlDrvMsgReadCmdCtx(void) 00909 { 00910 00911 /* after command response is received and isCmdRespWaited */ 00912 /* flag is set FALSE, it is necessary to read out all */ 00913 /* Async messages in Commands context, because ssiDma_IsrHandleSignalFromSlave */ 00914 /* could have dispatched some Async messages to g_NwpIf.CmdSyncObj */ 00915 /* after command response but before this response has been processed */ 00916 /* by spi_singleRead and isCmdRespWaited was set FALSE. */ 00917 00918 while (TRUE == g_pCB->IsCmdRespWaited) { 00919 00920 if(_SL_PENDING_RX_MSG(g_pCB)) { 00921 00922 VERIFY_RET_OK(_SlDrvMsgRead()); 00923 g_pCB->RxDoneCnt++; 00924 00925 if (CMD_RESP_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) { 00926 g_pCB->IsCmdRespWaited = FALSE; 00927 00928 /* In case CmdResp has been read without waiting on CmdSyncObj - that */ 00929 /* Sync object. That to prevent old signal to be processed. */ 00930 #ifndef SL_PLATFORM_MULTI_THREADED 00931 _nonos.sl_SyncObjClear(&g_pCB->CmdSyncObj); 00932 #else 00933 sl_SyncObjClear(&g_pCB->CmdSyncObj); 00934 #endif 00935 } else if (ASYNC_EVT_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) { 00936 /* If Async event has been read in CmdResp context, check whether */ 00937 /* there is a handler for this event. If there is, spawn specific */ 00938 /* handler. Otherwise free the event's buffer. */ 00939 /* This way there will be no "dry shots" from CmdResp context to */ 00940 /* temporary context, i.e less waste of CPU and faster buffer */ 00941 /* release. */ 00942 _SlAsyncEventGenericHandler(); 00943 00944 #ifdef SL_MEMORY_MGMT_DYNAMIC 00945 sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf); 00946 #else 00947 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL; 00948 #endif 00949 } 00950 } else { 00951 /* CmdSyncObj will be signaled by IRQ */ 00952 _SlDrvSyncObjWaitForever(&g_pCB->CmdSyncObj); 00953 } 00954 } 00955 00956 /* If there are more pending Rx Msgs after CmdResp is received, */ 00957 /* that means that these are Async, Dummy or Read Data Msgs. */ 00958 /* Spawn _SlDrvMsgReadSpawnCtx to trigger reading these messages from */ 00959 /* Temporary context. */ 00960 /* sl_Spawn is activated, using a different context */ 00961 _SlDrvObjUnLock(&g_pCB->GlobalLockObj); 00962 00963 if(_SL_PENDING_RX_MSG(g_pCB)) { 00964 #ifndef SL_PLATFORM_MULTI_THREADED 00965 _nonos._SlNonOsSpawn((_SlSpawnEntryFunc_t)&_SlDrvMsgReadSpawnCtx, NULL, 0); 00966 #else 00967 sl_Spawn((_SlSpawnEntryFunc_t)&_SlDrvMsgReadSpawnCtx, NULL, 0); 00968 #endif 00969 } 00970 00971 return SL_OS_RET_CODE_OK; 00972 } 00973 00974 /* ******************************************************************************/ 00975 /* _SlDrvClassifyRxMsg */ 00976 /* ******************************************************************************/ 00977 void cc3100_driver::_SlDrvClassifyRxMsg(_SlOpcode_t Opcode) 00978 { 00979 _SlSpawnEntryFunc_t AsyncEvtHandler = NULL; 00980 _SlRxMsgClass_e RxMsgClass = CMD_RESP_CLASS; 00981 uint8_t Silo; 00982 00983 00984 if (0 == (SL_OPCODE_SYNC & Opcode)) 00985 { /* Async event has received */ 00986 00987 if (SL_OPCODE_DEVICE_DEVICEASYNCDUMMY == Opcode) 00988 { 00989 RxMsgClass = DUMMY_MSG_CLASS; 00990 } 00991 else if ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) 00992 #ifndef SL_TINY_EXT 00993 || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) 00994 #endif 00995 ) 00996 { 00997 RxMsgClass = RECV_RESP_CLASS; 00998 } 00999 else 01000 { 01001 /* This is Async Event class message */ 01002 RxMsgClass = ASYNC_EVT_CLASS; 01003 01004 /* Despite the fact that 4 bits are allocated in the SILO field, we actually have only 6 SILOs 01005 So we can use the 8 options of SILO in look up table */ 01006 Silo = ((Opcode >> SL_OPCODE_SILO_OFFSET) & 0x7); 01007 01008 VERIFY_PROTOCOL(Silo < (sizeof(RxMsgClassLUT)/sizeof(_SlSpawnEntryFunc_t))); 01009 01010 /* Set the async event hander according to the LUT */ 01011 AsyncEvtHandler = RxMsgClassLUT[Silo]; 01012 01013 if ((SL_OPCODE_NETAPP_HTTPGETTOKENVALUE == Opcode) || (SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE == Opcode)) 01014 { 01015 AsyncEvtHandler = _SlDrvNetAppEventHandler; 01016 } 01017 #ifndef SL_TINY_EXT 01018 else if (SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE == Opcode) 01019 { 01020 AsyncEvtHandler = (_SlSpawnEntryFunc_t)_sl_HandleAsync_PingResponse; 01021 } 01022 #endif 01023 } 01024 } 01025 01026 g_pCB->FunctionParams.AsyncExt.RxMsgClass = RxMsgClass; 01027 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = AsyncEvtHandler; 01028 01029 } 01030 01031 /* ******************************************************************************/ 01032 /* _SlDrvRxHdrRead */ 01033 /* ******************************************************************************/ 01034 _SlReturnVal_t cc3100_driver::_SlDrvRxHdrRead(uint8_t *pBuf, uint8_t *pAlignSize) 01035 { 01036 uint32_t SyncCnt = 0; 01037 uint8_t ShiftIdx; 01038 01039 #ifndef SL_IF_TYPE_UART 01040 /* 1. Write CNYS pattern to NWP when working in SPI mode only */ 01041 _spi.spi_Write(g_pCB->FD, (uint8_t *)&g_H2NCnysPattern.Short, SYNC_PATTERN_LEN); 01042 #endif 01043 01044 /* 2. Read 4 bytes (protocol aligned) */ 01045 _spi.spi_Read(g_pCB->FD, &pBuf[0], 4); 01046 _SL_DBG_SYNC_LOG(SyncCnt,pBuf); 01047 01048 /* Wait for SYNC_PATTERN_LEN from the device */ 01049 while ( ! N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) { 01050 /* 3. Debug limit of scan */ 01051 VERIFY_PROTOCOL(SyncCnt < SL_SYNC_SCAN_THRESHOLD); 01052 01053 /* 4. Read next 4 bytes to Low 4 bytes of buffer */ 01054 if(0 == (SyncCnt % (uint32_t)SYNC_PATTERN_LEN)) { 01055 _spi.spi_Read(g_pCB->FD, &pBuf[4], 4); 01056 _SL_DBG_SYNC_LOG(SyncCnt,pBuf); 01057 } 01058 01059 /* 5. Shift Buffer Up for checking if the sync is shifted */ 01060 for(ShiftIdx = 0; ShiftIdx< 7; ShiftIdx++) 01061 { 01062 pBuf[ShiftIdx] = pBuf[ShiftIdx+1]; 01063 } 01064 pBuf[7] = 0; 01065 01066 SyncCnt++; 01067 } 01068 01069 /* 5. Sync pattern found. If needed, complete number of read bytes to multiple of 4 (protocol align) */ 01070 SyncCnt %= SYNC_PATTERN_LEN; 01071 01072 if(SyncCnt > 0) { 01073 *(uint32_t *)&pBuf[0] = *(uint32_t *)&pBuf[4]; 01074 _spi.spi_Read(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN - SyncCnt], (uint16_t)SyncCnt); 01075 } else { 01076 _spi.spi_Read(g_pCB->FD, &pBuf[0], 4); 01077 } 01078 01079 /* 6. Scan for Double pattern. */ 01080 while ( N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) { 01081 _SL_DBG_CNT_INC(Work.DoubleSyncPattern); 01082 _spi.spi_Read(g_pCB->FD, &pBuf[0], SYNC_PATTERN_LEN); 01083 } 01084 g_pCB->TxSeqNum++; 01085 01086 /* 7. Here we've read Generic Header (4 bytes). Read the Resp Specific header (4 more bytes). */ 01087 _spi.spi_Read(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN], _SL_RESP_SPEC_HDR_SIZE); 01088 01089 /* 8. Here we've read the entire Resp Header. */ 01090 /* Return number bytes needed to be sent after read for NWP Rx 4-byte alignment (protocol alignment) */ 01091 *pAlignSize = (uint8_t)((SyncCnt > 0) ? (SYNC_PATTERN_LEN - SyncCnt) : 0); 01092 01093 return SL_RET_CODE_OK; 01094 } 01095 01096 /* ***************************************************************************** */ 01097 /* _SlDrvBasicCmd */ 01098 /* ***************************************************************************** */ 01099 typedef union { 01100 _BasicResponse_t Rsp; 01101 } _SlBasicCmdMsg_u; 01102 01103 #ifndef SL_TINY_EXT 01104 int16_t cc3100_driver::_SlDrvBasicCmd(_SlOpcode_t Opcode) 01105 { 01106 _SlBasicCmdMsg_u Msg = {0}; 01107 _SlCmdCtrl_t CmdCtrl; 01108 01109 CmdCtrl.Opcode = Opcode; 01110 CmdCtrl.TxDescLen = 0; 01111 CmdCtrl.RxDescLen = sizeof(_BasicResponse_t); 01112 01113 01114 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL)); 01115 01116 return (int16_t)Msg.Rsp.status; 01117 } 01118 01119 /***************************************************************************** 01120 _SlDrvCmdSend 01121 Send SL command without waiting for command response 01122 This function is unprotected and the caller should make 01123 sure global lock is active 01124 *****************************************************************************/ 01125 _SlReturnVal_t cc3100_driver::_SlDrvCmdSend(_SlCmdCtrl_t *pCmdCtrl, void *pTxRxDescBuff, _SlCmdExt_t *pCmdExt) 01126 { 01127 _SlReturnVal_t RetVal; 01128 uint8_t IsCmdRespWaitedOriginalVal; 01129 01130 _SlFunctionParams_t originalFuncParms; 01131 01132 /* save the current RespWait flag before clearing it */ 01133 IsCmdRespWaitedOriginalVal = g_pCB->IsCmdRespWaited; 01134 01135 /* save the current command parameters */ 01136 memcpy(&originalFuncParms, &g_pCB->FunctionParams, sizeof(_SlFunctionParams_t)); 01137 01138 g_pCB->IsCmdRespWaited = FALSE; 01139 01140 SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdSend: call _SlDrvMsgWrite"); 01141 01142 /* send the message */ 01143 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t*)pTxRxDescBuff); 01144 01145 /* restore the original RespWait flag */ 01146 g_pCB->IsCmdRespWaited = IsCmdRespWaitedOriginalVal; 01147 01148 /* restore the original command parameters */ 01149 memcpy(&g_pCB->FunctionParams, &originalFuncParms, sizeof(_SlFunctionParams_t)); 01150 01151 return RetVal; 01152 01153 01154 } 01155 #endif 01156 01157 /* ***************************************************************************** */ 01158 /* _SlDrvWaitForPoolObj */ 01159 /* ***************************************************************************** */ 01160 uint8_t cc3100_driver::_SlDrvWaitForPoolObj(uint8_t ActionID, uint8_t SocketID) 01161 { 01162 uint8_t CurrObjIndex = MAX_CONCURRENT_ACTIONS; 01163 01164 /* Get free object */ 01165 _SlDrvProtectionObjLockWaitForever(); 01166 if (MAX_CONCURRENT_ACTIONS > g_pCB->FreePoolIdx) { 01167 /* save the current obj index */ 01168 CurrObjIndex = g_pCB->FreePoolIdx; 01169 /* set the new free index */ 01170 #ifndef SL_TINY_EXT 01171 if (MAX_CONCURRENT_ACTIONS > g_pCB->ObjPool[CurrObjIndex].NextIndex) { 01172 g_pCB->FreePoolIdx = g_pCB->ObjPool[CurrObjIndex].NextIndex; 01173 } 01174 else 01175 #endif 01176 { 01177 /* No further free actions available */ 01178 g_pCB->FreePoolIdx = MAX_CONCURRENT_ACTIONS; 01179 } 01180 } else { 01181 _SlDrvProtectionObjUnLock(); 01182 return CurrObjIndex; 01183 } 01184 g_pCB->ObjPool[CurrObjIndex].ActionID = (uint8_t)ActionID; 01185 if (SL_MAX_SOCKETS > SocketID) { 01186 g_pCB->ObjPool[CurrObjIndex].AdditionalData = SocketID; 01187 } 01188 #ifndef SL_TINY_EXT 01189 /*In case this action is socket related, SocketID bit will be on 01190 In case SocketID is set to SL_MAX_SOCKETS, the socket is not relevant to the action. In that case ActionID bit will be on */ 01191 while ( ( (SL_MAX_SOCKETS > SocketID) && (g_pCB->ActiveActionsBitmap & (1<<SocketID)) ) || 01192 ( (g_pCB->ActiveActionsBitmap & (1<<ActionID)) && (SL_MAX_SOCKETS == SocketID) ) ) 01193 { 01194 /* action in progress - move to pending list */ 01195 g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->PendingPoolIdx; 01196 g_pCB->PendingPoolIdx = CurrObjIndex; 01197 _SlDrvProtectionObjUnLock(); 01198 01199 /* wait for action to be free */ 01200 _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[CurrObjIndex].SyncObj); 01201 01202 /* set params and move to active (remove from pending list at _SlDrvReleasePoolObj) */ 01203 _SlDrvProtectionObjLockWaitForever(); 01204 } 01205 #endif 01206 /* mark as active. Set socket as active if action is on socket, otherwise mark action as active */ 01207 if (SL_MAX_SOCKETS > SocketID) { 01208 g_pCB->ActiveActionsBitmap |= (1<<SocketID); 01209 } else { 01210 g_pCB->ActiveActionsBitmap |= (1<<ActionID); 01211 } 01212 /* move to active list */ 01213 g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->ActivePoolIdx; 01214 g_pCB->ActivePoolIdx = CurrObjIndex; 01215 /* unlock */ 01216 _SlDrvProtectionObjUnLock(); 01217 return CurrObjIndex; 01218 } 01219 01220 /* ******************************************************************************/ 01221 /* _SlDrvReleasePoolObj */ 01222 /* ******************************************************************************/ 01223 void cc3100_driver::_SlDrvReleasePoolObj(uint8_t ObjIdx) 01224 { 01225 #ifndef SL_TINY_EXT 01226 uint8_t PendingIndex; 01227 #endif 01228 01229 _SlDrvProtectionObjLockWaitForever(); 01230 01231 /* In Tiny mode, there is only one object pool so no pending actions are available */ 01232 #ifndef SL_TINY_EXT 01233 /* go over the pending list and release other pending action if needed */ 01234 PendingIndex = g_pCB->PendingPoolIdx; 01235 01236 while(MAX_CONCURRENT_ACTIONS > PendingIndex) 01237 { 01238 /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */ 01239 if ( (g_pCB->ObjPool[PendingIndex].ActionID == g_pCB->ObjPool[ObjIdx].ActionID) && 01240 ( (SL_MAX_SOCKETS == (g_pCB->ObjPool[PendingIndex].AdditionalData & BSD_SOCKET_ID_MASK)) || 01241 ((SL_MAX_SOCKETS > (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)) && ( (g_pCB->ObjPool[PendingIndex].AdditionalData & BSD_SOCKET_ID_MASK) == (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK) ))) ) 01242 { 01243 /* remove from pending list */ 01244 _SlRemoveFromList(&g_pCB->PendingPoolIdx, PendingIndex); 01245 _SlDrvSyncObjSignal(&g_pCB->ObjPool[PendingIndex].SyncObj); 01246 break; 01247 } 01248 PendingIndex = g_pCB->ObjPool[PendingIndex].NextIndex; 01249 } 01250 #endif 01251 01252 if (SL_MAX_SOCKETS > (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)) 01253 { 01254 /* unset socketID */ 01255 g_pCB->ActiveActionsBitmap &= ~(1<<(g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK)); 01256 } 01257 else 01258 { 01259 /* unset actionID */ 01260 g_pCB->ActiveActionsBitmap &= ~(1<<g_pCB->ObjPool[ObjIdx].ActionID); 01261 } 01262 01263 /* delete old data */ 01264 g_pCB->ObjPool[ObjIdx].pRespArgs = NULL; 01265 g_pCB->ObjPool[ObjIdx].ActionID = 0; 01266 g_pCB->ObjPool[ObjIdx].AdditionalData = SL_MAX_SOCKETS; 01267 01268 /* remove from active list */ 01269 _SlRemoveFromList(&g_pCB->ActivePoolIdx, ObjIdx); 01270 /* move to free list */ 01271 g_pCB->ObjPool[ObjIdx].NextIndex = g_pCB->FreePoolIdx; 01272 g_pCB->FreePoolIdx = ObjIdx; 01273 01274 _SlDrvProtectionObjUnLock(); 01275 } 01276 01277 /* ******************************************************************************/ 01278 /* _SlRemoveFromList */ 01279 /* ******************************************************************************/ 01280 void cc3100_driver::_SlRemoveFromList(uint8_t *ListIndex, uint8_t ItemIndex) 01281 { 01282 #ifndef SL_TINY_EXT 01283 uint8_t Idx; 01284 #endif 01285 01286 if (MAX_CONCURRENT_ACTIONS == g_pCB->ObjPool[*ListIndex].NextIndex) 01287 { 01288 *ListIndex = MAX_CONCURRENT_ACTIONS; 01289 } 01290 /* As MAX_CONCURRENT_ACTIONS is equal to 1 in Tiny mode */ 01291 #ifndef SL_TINY_EXT 01292 /* need to remove the first item in the list and therefore update the global which holds this index */ 01293 else if (*ListIndex == ItemIndex) 01294 { 01295 *ListIndex = g_pCB->ObjPool[ItemIndex].NextIndex; 01296 } 01297 else 01298 { 01299 Idx = *ListIndex; 01300 01301 while(MAX_CONCURRENT_ACTIONS > Idx) 01302 { 01303 /* remove from list */ 01304 if (g_pCB->ObjPool[Idx].NextIndex == ItemIndex) 01305 { 01306 g_pCB->ObjPool[Idx].NextIndex = g_pCB->ObjPool[ItemIndex].NextIndex; 01307 break; 01308 } 01309 01310 Idx = g_pCB->ObjPool[Idx].NextIndex; 01311 } 01312 } 01313 #endif 01314 } 01315 01316 /* ******************************************************************************/ 01317 /* _SlFindAndSetActiveObj */ 01318 /* ******************************************************************************/ 01319 _SlReturnVal_t cc3100_driver::_SlFindAndSetActiveObj(_SlOpcode_t Opcode, uint8_t Sd) 01320 { 01321 uint8_t ActiveIndex; 01322 01323 ActiveIndex = g_pCB->ActivePoolIdx; 01324 /* go over the active list if exist to find obj waiting for this Async event */ 01325 #ifndef SL_TINY_EXT 01326 while (MAX_CONCURRENT_ACTIONS > ActiveIndex){ 01327 #else 01328 /* Only one Active action is availabe in tiny mode, so we can replace the loop with if condition */ 01329 if (MAX_CONCURRENT_ACTIONS > ActiveIndex) 01330 #endif 01331 /* unset the Ipv4\IPv6 bit in the opcode if family bit was set */ 01332 if (g_pCB->ObjPool[ActiveIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) { 01333 Opcode &= ~SL_OPCODE_IPV6; 01334 } 01335 01336 if ((g_pCB->ObjPool[ActiveIndex].ActionID == RECV_ID) && (Sd == g_pCB->ObjPool[ActiveIndex].AdditionalData) && 01337 ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode) 01338 #ifndef SL_TINY_EXT 01339 || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode) 01340 #endif 01341 ) 01342 01343 ) 01344 { 01345 g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex; 01346 return SL_RET_CODE_OK; 01347 } 01348 /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */ 01349 if ( (_SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].ActionAsyncOpcode == Opcode) && 01350 ( ((Sd == (g_pCB->ObjPool[ActiveIndex].AdditionalData & BSD_SOCKET_ID_MASK) ) && (SL_MAX_SOCKETS > Sd)) || (SL_MAX_SOCKETS == (g_pCB->ObjPool[ActiveIndex].AdditionalData & BSD_SOCKET_ID_MASK)) ) ) { 01351 /* set handler */ 01352 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].AsyncEventHandler; 01353 g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex; 01354 return SL_RET_CODE_OK; 01355 } 01356 ActiveIndex = g_pCB->ObjPool[ActiveIndex].NextIndex; 01357 } 01358 01359 return SL_RET_CODE_SELF_ERROR; 01360 01361 } 01362 01363 /* Wrappers for the object functions */ 01364 01365 void cc3100_driver::_SlDrvSyncObjWaitForever(_SlSyncObj_t *pSyncObj) 01366 { 01367 #ifndef SL_PLATFORM_MULTI_THREADED 01368 OSI_RET_OK_CHECK(_nonos.sl_SyncObjWait(pSyncObj, SL_OS_WAIT_FOREVER)); 01369 #else 01370 OSI_RET_OK_CHECK(sl_SyncObjWait(pSyncObj, SL_OS_WAIT_FOREVER)); 01371 #endif 01372 } 01373 01374 void cc3100_driver::_SlDrvSyncObjSignal(_SlSyncObj_t *pSyncObj) 01375 { 01376 #ifndef SL_PLATFORM_MULTI_THREADED 01377 OSI_RET_OK_CHECK(_nonos.sl_SyncObjSignal(pSyncObj)); 01378 #else 01379 OSI_RET_OK_CHECK(sl_SyncObjSignal(pSyncObj)); 01380 #endif 01381 } 01382 01383 void cc3100_driver::_SlDrvObjLockWaitForever(_SlLockObj_t *pLockObj) 01384 { 01385 #ifndef SL_PLATFORM_MULTI_THREADED 01386 OSI_RET_OK_CHECK(_nonos.sl_LockObjLock(pLockObj, SL_OS_WAIT_FOREVER)); 01387 #else 01388 OSI_RET_OK_CHECK(sl_LockObjLock(pLockObj, SL_OS_WAIT_FOREVER)); 01389 #endif 01390 } 01391 01392 void cc3100_driver::_SlDrvProtectionObjLockWaitForever() 01393 { 01394 #ifndef SL_PLATFORM_MULTI_THREADED 01395 OSI_RET_OK_CHECK(_nonos.sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); 01396 #else 01397 OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); 01398 #endif 01399 } 01400 01401 void cc3100_driver::_SlDrvObjUnLock(_SlLockObj_t *pLockObj) 01402 { 01403 #ifndef SL_PLATFORM_MULTI_THREADED 01404 OSI_RET_OK_CHECK(_nonos.sl_LockObjUnlock(pLockObj)); 01405 #else 01406 OSI_RET_OK_CHECK(sl_LockObjUnlock(pLockObj)); 01407 #endif 01408 } 01409 01410 void cc3100_driver::_SlDrvProtectionObjUnLock() 01411 { 01412 #ifndef SL_PLATFORM_MULTI_THREADED 01413 OSI_RET_OK_CHECK(_nonos.sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); 01414 #else 01415 OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); 01416 #endif 01417 } 01418 01419 01420 void cc3100_driver::_SlDrvMemZero(void* Addr, uint16_t size) 01421 { 01422 memset(Addr, 0, size); 01423 } 01424 01425 01426 void cc3100_driver::_SlDrvResetCmdExt(_SlCmdExt_t* pCmdExt) 01427 { 01428 _SlDrvMemZero(pCmdExt, sizeof (_SlCmdExt_t)); 01429 } 01430 01431 }//namespace mbed_cc3100 01432 01433
Generated on Wed Jul 13 2022 15:58:45 by 1.7.2