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