Port of TI's CC3100 Websock camera demo. Using FreeRTOS, mbedTLS, also parts of Arducam for cams ov5642 and 0v2640. Can also use MT9D111. Work in progress. Be warned some parts maybe a bit flacky. This is for Seeed Arch max only, for an M3, see the demo for CM3 using the 0v5642 aducam mini.
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