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