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