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