Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of simplelink_V2 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:08:23 by
1.7.2
