Updated to use external spawn.

Fork of simplelink_V2 by David Fletcher

Committer:
dflet
Date:
Sat Jun 06 13:48:29 2015 +0000
Revision:
1:9b68e650b3f6
Parent:
0:1a07906111ec
Oppps

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dflet 0:1a07906111ec 1 /*
dflet 0:1a07906111ec 2 * driver.c - CC31xx/CC32xx Host Driver Implementation
dflet 0:1a07906111ec 3 *
dflet 0:1a07906111ec 4 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
dflet 0:1a07906111ec 5 *
dflet 0:1a07906111ec 6 *
dflet 0:1a07906111ec 7 * Redistribution and use in source and binary forms, with or without
dflet 0:1a07906111ec 8 * modification, are permitted provided that the following conditions
dflet 0:1a07906111ec 9 * are met:
dflet 0:1a07906111ec 10 *
dflet 0:1a07906111ec 11 * Redistributions of source code must retain the above copyright
dflet 0:1a07906111ec 12 * notice, this list of conditions and the following disclaimer.
dflet 0:1a07906111ec 13 *
dflet 0:1a07906111ec 14 * Redistributions in binary form must reproduce the above copyright
dflet 0:1a07906111ec 15 * notice, this list of conditions and the following disclaimer in the
dflet 0:1a07906111ec 16 * documentation and/or other materials provided with the
dflet 0:1a07906111ec 17 * distribution.
dflet 0:1a07906111ec 18 *
dflet 0:1a07906111ec 19 * Neither the name of Texas Instruments Incorporated nor the names of
dflet 0:1a07906111ec 20 * its contributors may be used to endorse or promote products derived
dflet 0:1a07906111ec 21 * from this software without specific prior written permission.
dflet 0:1a07906111ec 22 *
dflet 0:1a07906111ec 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
dflet 0:1a07906111ec 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
dflet 0:1a07906111ec 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
dflet 0:1a07906111ec 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
dflet 0:1a07906111ec 27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
dflet 0:1a07906111ec 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
dflet 0:1a07906111ec 29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
dflet 0:1a07906111ec 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
dflet 0:1a07906111ec 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
dflet 0:1a07906111ec 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
dflet 0:1a07906111ec 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dflet 0:1a07906111ec 34 *
dflet 0:1a07906111ec 35 */
dflet 0:1a07906111ec 36
dflet 0:1a07906111ec 37 /*****************************************************************************/
dflet 0:1a07906111ec 38 /* Include files */
dflet 0:1a07906111ec 39 /*****************************************************************************/
dflet 0:1a07906111ec 40 #include "cc3100_simplelink.h"
dflet 0:1a07906111ec 41 #include "cc3100_protocol.h"
dflet 0:1a07906111ec 42 #include "cc3100_driver.h"
dflet 0:1a07906111ec 43
dflet 0:1a07906111ec 44 #include "fPtr_func.h"
dflet 0:1a07906111ec 45 #include "cli_uart.h"
dflet 0:1a07906111ec 46 #include "osi.h"
dflet 0:1a07906111ec 47
dflet 0:1a07906111ec 48 /*****************************************************************************/
dflet 0:1a07906111ec 49 /* Macro declarations */
dflet 0:1a07906111ec 50 /*****************************************************************************/
dflet 0:1a07906111ec 51
dflet 0:1a07906111ec 52 namespace mbed_cc3100 {
dflet 0:1a07906111ec 53
dflet 0:1a07906111ec 54 #ifndef SL_MEMORY_MGMT_DYNAMIC
dflet 0:1a07906111ec 55 typedef struct {
dflet 0:1a07906111ec 56 uint32_t Align;
dflet 0:1a07906111ec 57 _SlDriverCb_t DriverCB;
dflet 0:1a07906111ec 58 uint8_t AsyncRespBuf[SL_ASYNC_MAX_MSG_LEN];
dflet 0:1a07906111ec 59 } _SlStatMem_t;
dflet 0:1a07906111ec 60
dflet 0:1a07906111ec 61 _SlStatMem_t g_StatMem;
dflet 0:1a07906111ec 62 #endif
dflet 0:1a07906111ec 63
dflet 0:1a07906111ec 64
dflet 0:1a07906111ec 65 _SlDriverCb_t* g_pCB = NULL;
dflet 0:1a07906111ec 66
dflet 0:1a07906111ec 67 uint8_t gFirstCmdMode = 0;
dflet 0:1a07906111ec 68
dflet 0:1a07906111ec 69 const _SlSyncPattern_t g_H2NSyncPattern = H2N_SYNC_PATTERN;
dflet 0:1a07906111ec 70 const _SlSyncPattern_t g_H2NCnysPattern = H2N_CNYS_PATTERN;
dflet 0:1a07906111ec 71 volatile uint8_t RxIrqCnt;
dflet 0:1a07906111ec 72
dflet 0:1a07906111ec 73 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 74 const _SlActionLookup_t _SlActionLookupTable[] = {
dflet 0:1a07906111ec 75 {ACCEPT_ID, SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE, (_SlSpawnEntryFunc_t) &_sl_HandleAsync_Accept},
dflet 0:1a07906111ec 76 {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_Connect},
dflet 0:1a07906111ec 77 {SELECT_ID, SL_OPCODE_SOCKET_SELECTASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_Select},
dflet 0:1a07906111ec 78 {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_DnsGetHostByName},
dflet 0:1a07906111ec 79 {GETHOSYBYSERVICE_ID, SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_DnsGetHostByService},
dflet 0:1a07906111ec 80 {PING_ID, SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE, (_SlSpawnEntryFunc_t) &_sl_HandleAsync_PingResponse},
dflet 0:1a07906111ec 81 {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t) &_sl_HandleAsync_Stop}
dflet 0:1a07906111ec 82
dflet 0:1a07906111ec 83 };
dflet 0:1a07906111ec 84 #else
dflet 0:1a07906111ec 85 const _SlActionLookup_t _SlActionLookupTable[] =
dflet 0:1a07906111ec 86 {
dflet 0:1a07906111ec 87 {CONNECT_ID, SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Connect},
dflet 0:1a07906111ec 88 {GETHOSYBYNAME_ID, SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_DnsGetHostByName},
dflet 0:1a07906111ec 89 {START_STOP_ID, SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE,(_SlSpawnEntryFunc_t)_sl_HandleAsync_Stop}
dflet 0:1a07906111ec 90 };
dflet 0:1a07906111ec 91 #endif
dflet 0:1a07906111ec 92
dflet 0:1a07906111ec 93 typedef struct
dflet 0:1a07906111ec 94 {
dflet 0:1a07906111ec 95 uint16_t opcode;
dflet 0:1a07906111ec 96 uint8_t event;
dflet 0:1a07906111ec 97 } OpcodeKeyVal_t;
dflet 0:1a07906111ec 98
dflet 0:1a07906111ec 99 /* The table translates opcode to user's event type */
dflet 0:1a07906111ec 100 const OpcodeKeyVal_t OpcodeTranslateTable[] =
dflet 0:1a07906111ec 101 {
dflet 0:1a07906111ec 102 {SL_OPCODE_WLAN_SMART_CONFIG_START_ASYNC_RESPONSE, SL_WLAN_SMART_CONFIG_COMPLETE_EVENT},
dflet 0:1a07906111ec 103 {SL_OPCODE_WLAN_SMART_CONFIG_STOP_ASYNC_RESPONSE,SL_WLAN_SMART_CONFIG_STOP_EVENT},
dflet 0:1a07906111ec 104 {SL_OPCODE_WLAN_STA_CONNECTED, SL_WLAN_STA_CONNECTED_EVENT},
dflet 0:1a07906111ec 105 {SL_OPCODE_WLAN_STA_DISCONNECTED,SL_WLAN_STA_DISCONNECTED_EVENT},
dflet 0:1a07906111ec 106 {SL_OPCODE_WLAN_P2P_DEV_FOUND,SL_WLAN_P2P_DEV_FOUND_EVENT},
dflet 0:1a07906111ec 107 {SL_OPCODE_WLAN_P2P_NEG_REQ_RECEIVED, SL_WLAN_P2P_NEG_REQ_RECEIVED_EVENT},
dflet 0:1a07906111ec 108 {SL_OPCODE_WLAN_CONNECTION_FAILED, SL_WLAN_CONNECTION_FAILED_EVENT},
dflet 0:1a07906111ec 109 {SL_OPCODE_WLAN_WLANASYNCCONNECTEDRESPONSE, SL_WLAN_CONNECT_EVENT},
dflet 0:1a07906111ec 110 {SL_OPCODE_WLAN_WLANASYNCDISCONNECTEDRESPONSE, SL_WLAN_DISCONNECT_EVENT},
dflet 0:1a07906111ec 111 {SL_OPCODE_NETAPP_IPACQUIRED, SL_NETAPP_IPV4_IPACQUIRED_EVENT},
dflet 0:1a07906111ec 112 {SL_OPCODE_NETAPP_IPACQUIRED_V6, SL_NETAPP_IPV6_IPACQUIRED_EVENT},
dflet 0:1a07906111ec 113 {SL_OPCODE_NETAPP_IP_LEASED, SL_NETAPP_IP_LEASED_EVENT},
dflet 0:1a07906111ec 114 {SL_OPCODE_NETAPP_IP_RELEASED, SL_NETAPP_IP_RELEASED_EVENT},
dflet 0:1a07906111ec 115 {SL_OPCODE_SOCKET_TXFAILEDASYNCRESPONSE, SL_SOCKET_TX_FAILED_EVENT},
dflet 0:1a07906111ec 116 {SL_OPCODE_SOCKET_SOCKETASYNCEVENT, SL_SOCKET_ASYNC_EVENT}
dflet 0:1a07906111ec 117 };
dflet 0:1a07906111ec 118
dflet 0:1a07906111ec 119 /*
dflet 0:1a07906111ec 120
dflet 0:1a07906111ec 121 #define SL_OPCODE_SILO_DEVICE ( 0x0 << SL_OPCODE_SILO_OFFSET )
dflet 0:1a07906111ec 122 #define SL_OPCODE_SILO_WLAN ( 0x1 << SL_OPCODE_SILO_OFFSET )
dflet 0:1a07906111ec 123 #define SL_OPCODE_SILO_SOCKET ( 0x2 << SL_OPCODE_SILO_OFFSET )
dflet 0:1a07906111ec 124 #define SL_OPCODE_SILO_NETAPP ( 0x3 << SL_OPCODE_SILO_OFFSET )
dflet 0:1a07906111ec 125 #define SL_OPCODE_SILO_NVMEM ( 0x4 << SL_OPCODE_SILO_OFFSET )
dflet 0:1a07906111ec 126 #define SL_OPCODE_SILO_NETCFG ( 0x5 << SL_OPCODE_SILO_OFFSET )
dflet 0:1a07906111ec 127
dflet 0:1a07906111ec 128
dflet 0:1a07906111ec 129 */
dflet 0:1a07906111ec 130
dflet 0:1a07906111ec 131 /* The Lookup table below holds the event handlers to be called according to the incoming
dflet 0:1a07906111ec 132 RX message SILO type */
dflet 0:1a07906111ec 133 const _SlSpawnEntryFunc_t RxMsgClassLUT[] = {
dflet 0:1a07906111ec 134 (_SlSpawnEntryFunc_t)_SlDrvDeviceEventHandler, /* SL_OPCODE_SILO_DEVICE */
dflet 0:1a07906111ec 135 #if defined(sl_WlanEvtHdlr) || defined(EXT_LIB_REGISTERED_WLAN_EVENTS)
dflet 0:1a07906111ec 136 (_SlSpawnEntryFunc_t)_SlDrvHandleWlanEvents, /* SL_OPCODE_SILO_WLAN */
dflet 0:1a07906111ec 137 #else
dflet 0:1a07906111ec 138 NULL,
dflet 0:1a07906111ec 139 #endif
dflet 0:1a07906111ec 140 #if defined (sl_SockEvtHdlr) || defined(EXT_LIB_REGISTERED_SOCK_EVENTS)
dflet 0:1a07906111ec 141 (_SlSpawnEntryFunc_t)_SlDrvHandleSockEvents, /* SL_OPCODE_SILO_SOCKET */
dflet 0:1a07906111ec 142 #else
dflet 0:1a07906111ec 143 NULL,
dflet 0:1a07906111ec 144 #endif
dflet 0:1a07906111ec 145
dflet 0:1a07906111ec 146 #if defined(sl_NetAppEvtHdlr) || defined(EXT_LIB_REGISTERED_NETAPP_EVENTS)
dflet 0:1a07906111ec 147 (_SlSpawnEntryFunc_t)_SlDrvHandleNetAppEvents, /* SL_OPCODE_SILO_NETAPP */
dflet 0:1a07906111ec 148 #else
dflet 0:1a07906111ec 149 NULL,
dflet 0:1a07906111ec 150 #endif
dflet 0:1a07906111ec 151 NULL, /* SL_OPCODE_SILO_NVMEM */
dflet 0:1a07906111ec 152 NULL, /* SL_OPCODE_SILO_NETCFG */
dflet 0:1a07906111ec 153 NULL,
dflet 0:1a07906111ec 154 NULL
dflet 0:1a07906111ec 155 };
dflet 0:1a07906111ec 156
dflet 0:1a07906111ec 157 cc3100_driver::cc3100_driver(cc3100_spi &spi, cc3100_nonos &nonos, cc3100_netapp &netapp, cc3100_flowcont &flowcont)
dflet 0:1a07906111ec 158 : _spi(spi), _nonos(nonos),_netapp(netapp), _flowcont(flowcont)
dflet 0:1a07906111ec 159 {
dflet 0:1a07906111ec 160
dflet 0:1a07906111ec 161 }
dflet 0:1a07906111ec 162
dflet 0:1a07906111ec 163 cc3100_driver::~cc3100_driver()
dflet 0:1a07906111ec 164 {
dflet 0:1a07906111ec 165
dflet 0:1a07906111ec 166 }
dflet 0:1a07906111ec 167
dflet 0:1a07906111ec 168 /*****************************************************************************/
dflet 0:1a07906111ec 169 /* Variables */
dflet 0:1a07906111ec 170 /*****************************************************************************/
dflet 0:1a07906111ec 171
dflet 0:1a07906111ec 172 /********************************************************************************/
dflet 0:1a07906111ec 173
dflet 0:1a07906111ec 174 uint8_t cc3100_driver::_SlDrvProtectAsyncRespSetting(uint8_t *pAsyncRsp, uint8_t ActionID, uint8_t SocketID)
dflet 0:1a07906111ec 175 {
dflet 0:1a07906111ec 176 uint8_t ObjIdx;
dflet 0:1a07906111ec 177
dflet 0:1a07906111ec 178
dflet 0:1a07906111ec 179 /* Use Obj to issue the command, if not available try later */
dflet 0:1a07906111ec 180 ObjIdx = _SlDrvWaitForPoolObj(ActionID, SocketID);
dflet 0:1a07906111ec 181
dflet 0:1a07906111ec 182 if (MAX_CONCURRENT_ACTIONS != ObjIdx)
dflet 0:1a07906111ec 183 {
dflet 0:1a07906111ec 184 _SlDrvProtectionObjLockWaitForever();
dflet 0:1a07906111ec 185 g_pCB->ObjPool[ObjIdx].pRespArgs = pAsyncRsp;
dflet 0:1a07906111ec 186 _SlDrvProtectionObjUnLock();
dflet 0:1a07906111ec 187 }
dflet 0:1a07906111ec 188
dflet 0:1a07906111ec 189 return ObjIdx;
dflet 0:1a07906111ec 190 }
dflet 0:1a07906111ec 191
dflet 0:1a07906111ec 192
dflet 0:1a07906111ec 193 /*****************************************************************************/
dflet 0:1a07906111ec 194 /* Internal functions */
dflet 0:1a07906111ec 195 /*****************************************************************************/
dflet 0:1a07906111ec 196 bool cc3100_driver::_SL_PENDING_RX_MSG(pDriver* pDriverCB){
dflet 0:1a07906111ec 197
dflet 0:1a07906111ec 198 if(RxIrqCnt != (pDriverCB)->RxDoneCnt){
dflet 0:1a07906111ec 199 return TRUE;
dflet 0:1a07906111ec 200 }else{
dflet 0:1a07906111ec 201 return FALSE;
dflet 0:1a07906111ec 202 }
dflet 0:1a07906111ec 203 }
dflet 0:1a07906111ec 204
dflet 0:1a07906111ec 205 /*****************************************************************************
dflet 0:1a07906111ec 206 _SlDrvDriverCBInit - init Driver Control Block
dflet 0:1a07906111ec 207 *****************************************************************************/
dflet 0:1a07906111ec 208 void cc3100_driver::_SlDrvDriverCBInit(void)
dflet 0:1a07906111ec 209 {
dflet 0:1a07906111ec 210
dflet 0:1a07906111ec 211 uint8_t Idx = 0;
dflet 0:1a07906111ec 212
dflet 0:1a07906111ec 213 #ifdef SL_MEMORY_MGMT_DYNAMIC
dflet 0:1a07906111ec 214
dflet 0:1a07906111ec 215 g_pCB = sl_Malloc(sizeof(_SlDriverCb_t));
dflet 0:1a07906111ec 216 #else
dflet 0:1a07906111ec 217 g_pCB = &(g_StatMem.DriverCB);
dflet 0:1a07906111ec 218 #endif
dflet 0:1a07906111ec 219
dflet 0:1a07906111ec 220 MALLOC_OK_CHECK(g_pCB);
dflet 0:1a07906111ec 221 _SlDrvMemZero(g_pCB, sizeof(_SlDriverCb_t));
dflet 0:1a07906111ec 222 RxIrqCnt = 0;
dflet 0:1a07906111ec 223
dflet 0:1a07906111ec 224 OSI_RET_OK_CHECK( _nonos.sl_SyncObjCreate(&g_pCB->CmdSyncObj, "CmdSyncObj") );
dflet 0:1a07906111ec 225 _nonos.sl_SyncObjClear(&g_pCB->CmdSyncObj);
dflet 0:1a07906111ec 226
dflet 0:1a07906111ec 227 OSI_RET_OK_CHECK( _nonos.sl_LockObjCreate(&g_pCB->GlobalLockObj, "GlobalLockObj") );
dflet 0:1a07906111ec 228
dflet 0:1a07906111ec 229 OSI_RET_OK_CHECK( _nonos.sl_LockObjCreate(&g_pCB->ProtectionLockObj, "ProtectionLockObj") );
dflet 0:1a07906111ec 230
dflet 0:1a07906111ec 231 /* Init Drv object */
dflet 0:1a07906111ec 232 _SlDrvMemZero(&g_pCB->ObjPool[0], MAX_CONCURRENT_ACTIONS*sizeof(_SlPoolObj_t));
dflet 0:1a07906111ec 233
dflet 0:1a07906111ec 234 /* place all Obj in the free list*/
dflet 0:1a07906111ec 235 g_pCB->FreePoolIdx = 0;
dflet 0:1a07906111ec 236
dflet 0:1a07906111ec 237 for (Idx = 0 ; Idx < MAX_CONCURRENT_ACTIONS ; Idx++)
dflet 0:1a07906111ec 238 {
dflet 0:1a07906111ec 239 g_pCB->ObjPool[Idx].NextIndex = Idx + 1;
dflet 0:1a07906111ec 240 g_pCB->ObjPool[Idx].AdditionalData = SL_MAX_SOCKETS;
dflet 0:1a07906111ec 241
dflet 0:1a07906111ec 242 OSI_RET_OK_CHECK( _nonos.sl_SyncObjCreate(&g_pCB->ObjPool[Idx].SyncObj, "SyncObj"));
dflet 0:1a07906111ec 243 _nonos.sl_SyncObjClear(&g_pCB->ObjPool[Idx].SyncObj);
dflet 0:1a07906111ec 244 }
dflet 0:1a07906111ec 245
dflet 0:1a07906111ec 246 g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS;
dflet 0:1a07906111ec 247 g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS;
dflet 0:1a07906111ec 248
dflet 0:1a07906111ec 249 /* Flow control init */
dflet 0:1a07906111ec 250 g_pCB->FlowContCB.TxPoolCnt = FLOW_CONT_MIN;
dflet 0:1a07906111ec 251 OSI_RET_OK_CHECK(_nonos.sl_LockObjCreate(&g_pCB->FlowContCB.TxLockObj, "TxLockObj"));
dflet 0:1a07906111ec 252 OSI_RET_OK_CHECK(_nonos.sl_SyncObjCreate(&g_pCB->FlowContCB.TxSyncObj, "TxSyncObj"));
dflet 0:1a07906111ec 253
dflet 0:1a07906111ec 254 gFirstCmdMode = 0;
dflet 0:1a07906111ec 255 }
dflet 0:1a07906111ec 256
dflet 0:1a07906111ec 257 /*****************************************************************************
dflet 0:1a07906111ec 258 _SlDrvDriverCBDeinit - De init Driver Control Block
dflet 0:1a07906111ec 259 *****************************************************************************/
dflet 0:1a07906111ec 260 void cc3100_driver::_SlDrvDriverCBDeinit()
dflet 0:1a07906111ec 261 {
dflet 0:1a07906111ec 262 uint8_t Idx = 0;
dflet 0:1a07906111ec 263
dflet 0:1a07906111ec 264 /* Flow control de-init */
dflet 0:1a07906111ec 265 g_pCB->FlowContCB.TxPoolCnt = 0;
dflet 0:1a07906111ec 266 OSI_RET_OK_CHECK(_nonos.sl_LockObjDelete(&g_pCB->FlowContCB.TxLockObj,0));
dflet 0:1a07906111ec 267 OSI_RET_OK_CHECK(_nonos.sl_SyncObjDelete(&g_pCB->FlowContCB.TxSyncObj,0));
dflet 0:1a07906111ec 268
dflet 0:1a07906111ec 269
dflet 0:1a07906111ec 270 OSI_RET_OK_CHECK( _nonos.sl_SyncObjDelete(&g_pCB->CmdSyncObj, 0) );
dflet 0:1a07906111ec 271 OSI_RET_OK_CHECK( _nonos.sl_LockObjDelete(&g_pCB->GlobalLockObj, 0) );
dflet 0:1a07906111ec 272 OSI_RET_OK_CHECK( _nonos.sl_LockObjDelete(&g_pCB->ProtectionLockObj, 0) );
dflet 0:1a07906111ec 273
dflet 0:1a07906111ec 274 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 275 for (Idx = 0; Idx < MAX_CONCURRENT_ACTIONS; Idx++)
dflet 0:1a07906111ec 276 #endif
dflet 0:1a07906111ec 277
dflet 0:1a07906111ec 278 g_pCB->FreePoolIdx = 0;
dflet 0:1a07906111ec 279 g_pCB->PendingPoolIdx = MAX_CONCURRENT_ACTIONS;
dflet 0:1a07906111ec 280 g_pCB->ActivePoolIdx = MAX_CONCURRENT_ACTIONS;
dflet 0:1a07906111ec 281
dflet 0:1a07906111ec 282 #ifdef SL_MEMORY_MGMT_DYNAMIC
dflet 0:1a07906111ec 283 sl_Free(g_pCB);
dflet 0:1a07906111ec 284 #else
dflet 0:1a07906111ec 285 g_pCB = NULL;
dflet 0:1a07906111ec 286 #endif
dflet 0:1a07906111ec 287
dflet 0:1a07906111ec 288 g_pCB = NULL;
dflet 0:1a07906111ec 289 }
dflet 0:1a07906111ec 290
dflet 0:1a07906111ec 291 /*****************************************************************************
dflet 0:1a07906111ec 292 _SlDrvRxIrqHandler - Interrupt handler
dflet 0:1a07906111ec 293 *****************************************************************************/
dflet 0:1a07906111ec 294
dflet 0:1a07906111ec 295 void cc3100_driver::_SlDrvRxIrqHandler(void *pValue)
dflet 0:1a07906111ec 296 {
dflet 0:1a07906111ec 297
dflet 0:1a07906111ec 298 int32_t rv = 0;
dflet 0:1a07906111ec 299 _spi.MaskIntHdlr();
dflet 0:1a07906111ec 300
dflet 0:1a07906111ec 301 RxIrqCnt++;
dflet 0:1a07906111ec 302
dflet 0:1a07906111ec 303 if (TRUE == g_pCB->IsCmdRespWaited) {
dflet 0:1a07906111ec 304 OSI_RET_OK_CHECK( _nonos.sl_SyncObjSignalFromIRQ(&g_pCB->CmdSyncObj, NON_OS_SYNC_OBJ_SIGNAL_VALUE) );
dflet 0:1a07906111ec 305 } else {
dflet 0:1a07906111ec 306 #ifdef SL_PLATFORM_EXTERNAL_SPAWN
dflet 0:1a07906111ec 307 rv = sl_Spawn((_SlSpawnEntryFunc_t)_SlDrvMsgReadSpawnCtx, NULL, 0);
dflet 0:1a07906111ec 308
dflet 0:1a07906111ec 309 if(rv <0){
dflet 0:1a07906111ec 310 Uart_Write((uint8_t*)"\n\r OSI_OPERATION_FAILED \n\r");
dflet 0:1a07906111ec 311 }
dflet 0:1a07906111ec 312 #else
dflet 0:1a07906111ec 313 _nonos._SlNonOsSpawn((_SlSpawnEntryFunc_t)&_SlDrvMsgReadSpawnCtx, NULL, 0);
dflet 0:1a07906111ec 314 #endif
dflet 0:1a07906111ec 315 }
dflet 0:1a07906111ec 316
dflet 0:1a07906111ec 317 }
dflet 0:1a07906111ec 318
dflet 0:1a07906111ec 319 /*****************************************************************************
dflet 0:1a07906111ec 320 _SlDrvCmdOp
dflet 0:1a07906111ec 321 *****************************************************************************/
dflet 0:1a07906111ec 322 _SlReturnVal_t cc3100_driver::_SlDrvCmdOp(_SlCmdCtrl_t *pCmdCtrl,void* pTxRxDescBuff, _SlCmdExt_t *pCmdExt)
dflet 0:1a07906111ec 323 {
dflet 0:1a07906111ec 324
dflet 0:1a07906111ec 325 _SlReturnVal_t RetVal;
dflet 0:1a07906111ec 326
dflet 0:1a07906111ec 327 _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj);
dflet 0:1a07906111ec 328
dflet 0:1a07906111ec 329 g_pCB->IsCmdRespWaited = TRUE;
dflet 0:1a07906111ec 330 SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdOp: call _SlDrvMsgWrite");
dflet 0:1a07906111ec 331
dflet 0:1a07906111ec 332 /* send the message */
dflet 0:1a07906111ec 333 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t*)pTxRxDescBuff);
dflet 0:1a07906111ec 334
dflet 0:1a07906111ec 335 if(SL_OS_RET_CODE_OK == RetVal) {
dflet 0:1a07906111ec 336
dflet 0:1a07906111ec 337 #ifndef SL_IF_TYPE_UART
dflet 0:1a07906111ec 338 /* Waiting for SPI to stabilize after first command */
dflet 0:1a07906111ec 339 if( 0 == gFirstCmdMode ) {
dflet 0:1a07906111ec 340 gFirstCmdMode = 1;
dflet 0:1a07906111ec 341 wait_ms(2);
dflet 0:1a07906111ec 342 }
dflet 0:1a07906111ec 343 #endif
dflet 0:1a07906111ec 344
dflet 0:1a07906111ec 345 /* wait for respond */
dflet 0:1a07906111ec 346 RetVal = _SlDrvMsgReadCmdCtx(); /* will free global lock */
dflet 0:1a07906111ec 347 SL_TRACE0(DBG_MSG, MSG_314, "_SlDrvCmdOp: exited _SlDrvMsgReadCmdCtx");
dflet 0:1a07906111ec 348
dflet 0:1a07906111ec 349 } else
dflet 0:1a07906111ec 350 {
dflet 0:1a07906111ec 351 _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
dflet 0:1a07906111ec 352 }
dflet 0:1a07906111ec 353 return RetVal;
dflet 0:1a07906111ec 354 }
dflet 0:1a07906111ec 355
dflet 0:1a07906111ec 356 /*****************************************************************************
dflet 0:1a07906111ec 357 _SlDrvDataReadOp
dflet 0:1a07906111ec 358 *****************************************************************************/
dflet 0:1a07906111ec 359 _SlReturnVal_t cc3100_driver::_SlDrvDataReadOp(_SlSd_t Sd, _SlCmdCtrl_t *pCmdCtrl, void* pTxRxDescBuff, _SlCmdExt_t *pCmdExt)
dflet 0:1a07906111ec 360 {
dflet 0:1a07906111ec 361 _SlReturnVal_t RetVal;
dflet 0:1a07906111ec 362 uint8_t ObjIdx = MAX_CONCURRENT_ACTIONS;
dflet 0:1a07906111ec 363 _SlArgsData_t pArgsData;
dflet 0:1a07906111ec 364
dflet 0:1a07906111ec 365 /* Validate input arguments */
dflet 0:1a07906111ec 366 VERIFY_PROTOCOL(NULL != pCmdExt->pRxPayload);
dflet 0:1a07906111ec 367
dflet 0:1a07906111ec 368 /* If zero bytes is requested, return error. */
dflet 0:1a07906111ec 369 /* This allows us not to fill remote socket's IP address in return arguments */
dflet 0:1a07906111ec 370 VERIFY_PROTOCOL(0 != pCmdExt->RxPayloadLen);
dflet 0:1a07906111ec 371
dflet 0:1a07906111ec 372 /* Validate socket */
dflet 0:1a07906111ec 373 if((Sd & BSD_SOCKET_ID_MASK) >= SL_MAX_SOCKETS) {
dflet 0:1a07906111ec 374 return SL_EBADF;
dflet 0:1a07906111ec 375 }
dflet 0:1a07906111ec 376
dflet 0:1a07906111ec 377 /*Use Obj to issue the command, if not available try later*/
dflet 0:1a07906111ec 378 ObjIdx = (uint8_t)_SlDrvWaitForPoolObj(RECV_ID, Sd & BSD_SOCKET_ID_MASK);
dflet 0:1a07906111ec 379
dflet 0:1a07906111ec 380 if (MAX_CONCURRENT_ACTIONS == ObjIdx) {
dflet 0:1a07906111ec 381 return SL_POOL_IS_EMPTY;
dflet 0:1a07906111ec 382 }
dflet 0:1a07906111ec 383
dflet 0:1a07906111ec 384 _SlDrvProtectionObjLockWaitForever();
dflet 0:1a07906111ec 385
dflet 0:1a07906111ec 386 pArgsData.pData = pCmdExt->pRxPayload;
dflet 0:1a07906111ec 387 pArgsData.pArgs = (uint8_t *)pTxRxDescBuff;
dflet 0:1a07906111ec 388 g_pCB->ObjPool[ObjIdx].pRespArgs = (uint8_t *)&pArgsData;
dflet 0:1a07906111ec 389 _SlDrvProtectionObjUnLock();
dflet 0:1a07906111ec 390
dflet 0:1a07906111ec 391 /* Do Flow Control check/update for DataWrite operation */
dflet 0:1a07906111ec 392 _SlDrvObjLockWaitForever(&g_pCB->FlowContCB.TxLockObj);
dflet 0:1a07906111ec 393
dflet 0:1a07906111ec 394 /* Clear SyncObj for the case it was signalled before TxPoolCnt */
dflet 0:1a07906111ec 395 /* dropped below '1' (last Data buffer was taken) */
dflet 0:1a07906111ec 396 /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */
dflet 0:1a07906111ec 397 _nonos.sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj);
dflet 0:1a07906111ec 398
dflet 0:1a07906111ec 399 if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN) {
dflet 0:1a07906111ec 400
dflet 0:1a07906111ec 401 /* If TxPoolCnt was increased by other thread at this moment,
dflet 0:1a07906111ec 402 TxSyncObj won't wait here */
dflet 0:1a07906111ec 403 _SlDrvSyncObjWaitForever(&g_pCB->FlowContCB.TxSyncObj);
dflet 0:1a07906111ec 404
dflet 0:1a07906111ec 405 }
dflet 0:1a07906111ec 406
dflet 0:1a07906111ec 407 _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj);
dflet 0:1a07906111ec 408
dflet 0:1a07906111ec 409 VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN);
dflet 0:1a07906111ec 410 g_pCB->FlowContCB.TxPoolCnt--;
dflet 0:1a07906111ec 411
dflet 0:1a07906111ec 412 _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj);
dflet 0:1a07906111ec 413
dflet 0:1a07906111ec 414 /* send the message */
dflet 0:1a07906111ec 415 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t *)pTxRxDescBuff);
dflet 0:1a07906111ec 416
dflet 0:1a07906111ec 417 _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
dflet 0:1a07906111ec 418
dflet 0:1a07906111ec 419 if(SL_OS_RET_CODE_OK == RetVal) {
dflet 0:1a07906111ec 420 /* Wait for response message. Will be signaled by _SlDrvMsgRead. */
dflet 0:1a07906111ec 421 _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[ObjIdx].SyncObj);
dflet 0:1a07906111ec 422 }
dflet 0:1a07906111ec 423
dflet 0:1a07906111ec 424 _SlDrvReleasePoolObj(ObjIdx);
dflet 0:1a07906111ec 425 return RetVal;
dflet 0:1a07906111ec 426 }
dflet 0:1a07906111ec 427
dflet 0:1a07906111ec 428 /* ******************************************************************************/
dflet 0:1a07906111ec 429 /* _SlDrvDataWriteOp */
dflet 0:1a07906111ec 430 /* ******************************************************************************/
dflet 0:1a07906111ec 431 _SlReturnVal_t cc3100_driver::_SlDrvDataWriteOp(_SlSd_t Sd, _SlCmdCtrl_t *pCmdCtrl, void* pTxRxDescBuff, _SlCmdExt_t *pCmdExt)
dflet 0:1a07906111ec 432 {
dflet 0:1a07906111ec 433 _SlReturnVal_t RetVal = SL_EAGAIN; /* initiated as SL_EAGAIN for the non blocking mode */
dflet 0:1a07906111ec 434 while( 1 ) {
dflet 0:1a07906111ec 435 /* Do Flow Control check/update for DataWrite operation */
dflet 0:1a07906111ec 436 _SlDrvObjLockWaitForever(&g_pCB->FlowContCB.TxLockObj);
dflet 0:1a07906111ec 437
dflet 0:1a07906111ec 438 /* Clear SyncObj for the case it was signalled before TxPoolCnt */
dflet 0:1a07906111ec 439 /* dropped below '1' (last Data buffer was taken) */
dflet 0:1a07906111ec 440 /* OSI_RET_OK_CHECK( sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj) ); */
dflet 0:1a07906111ec 441 _nonos.sl_SyncObjClear(&g_pCB->FlowContCB.TxSyncObj);
dflet 0:1a07906111ec 442 /* we have indication that the last send has failed - socket is no longer valid for operations */
dflet 0:1a07906111ec 443 if(g_pCB->SocketTXFailure & (1<<(Sd & BSD_SOCKET_ID_MASK))) {
dflet 0:1a07906111ec 444 _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj);
dflet 0:1a07906111ec 445 return SL_SOC_ERROR;
dflet 0:1a07906111ec 446 }
dflet 0:1a07906111ec 447
dflet 0:1a07906111ec 448 if(g_pCB->FlowContCB.TxPoolCnt <= FLOW_CONT_MIN + 1) {
dflet 0:1a07906111ec 449 /* we have indication that this socket is set as blocking and we try to */
dflet 0:1a07906111ec 450 /* unblock it - return an error */
dflet 0:1a07906111ec 451 if( g_pCB->SocketNonBlocking & (1<< (Sd & BSD_SOCKET_ID_MASK)))
dflet 0:1a07906111ec 452 {
dflet 0:1a07906111ec 453 _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj);
dflet 0:1a07906111ec 454 return RetVal;
dflet 0:1a07906111ec 455 }
dflet 0:1a07906111ec 456 /* If TxPoolCnt was increased by other thread at this moment, */
dflet 0:1a07906111ec 457 /* TxSyncObj won't wait here */
dflet 0:1a07906111ec 458 _SlDrvSyncObjWaitForever(&g_pCB->FlowContCB.TxSyncObj);
dflet 0:1a07906111ec 459 }
dflet 0:1a07906111ec 460
dflet 0:1a07906111ec 461 if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 ) {
dflet 0:1a07906111ec 462 break;
dflet 0:1a07906111ec 463 }
dflet 0:1a07906111ec 464 else
dflet 0:1a07906111ec 465 {
dflet 0:1a07906111ec 466 _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj);
dflet 0:1a07906111ec 467 }
dflet 0:1a07906111ec 468 }
dflet 0:1a07906111ec 469
dflet 0:1a07906111ec 470 _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj);
dflet 0:1a07906111ec 471
dflet 0:1a07906111ec 472
dflet 0:1a07906111ec 473 VERIFY_PROTOCOL(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN + 1 );
dflet 0:1a07906111ec 474 g_pCB->FlowContCB.TxPoolCnt--;
dflet 0:1a07906111ec 475
dflet 0:1a07906111ec 476 _SlDrvObjUnLock(&g_pCB->FlowContCB.TxLockObj);
dflet 0:1a07906111ec 477
dflet 0:1a07906111ec 478 /* send the message */
dflet 0:1a07906111ec 479 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t*)pTxRxDescBuff);
dflet 0:1a07906111ec 480
dflet 0:1a07906111ec 481 _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
dflet 0:1a07906111ec 482
dflet 0:1a07906111ec 483 return RetVal;
dflet 0:1a07906111ec 484 }
dflet 0:1a07906111ec 485
dflet 0:1a07906111ec 486 /* ******************************************************************************/
dflet 0:1a07906111ec 487 /* _SlDrvMsgWrite */
dflet 0:1a07906111ec 488 /* ******************************************************************************/
dflet 0:1a07906111ec 489 _SlReturnVal_t cc3100_driver::_SlDrvMsgWrite(_SlCmdCtrl_t *pCmdCtrl, _SlCmdExt_t *pCmdExt, uint8_t *pTxRxDescBuff)
dflet 0:1a07906111ec 490 {
dflet 0:1a07906111ec 491
dflet 0:1a07906111ec 492 uint8_t sendRxPayload = FALSE;
dflet 0:1a07906111ec 493 VERIFY_PROTOCOL(NULL != pCmdCtrl);
dflet 0:1a07906111ec 494
dflet 0:1a07906111ec 495 g_pCB->FunctionParams.pCmdCtrl = pCmdCtrl;
dflet 0:1a07906111ec 496 g_pCB->FunctionParams.pTxRxDescBuff = pTxRxDescBuff;
dflet 0:1a07906111ec 497 g_pCB->FunctionParams.pCmdExt = pCmdExt;
dflet 0:1a07906111ec 498
dflet 0:1a07906111ec 499 g_pCB->TempProtocolHeader.Opcode = pCmdCtrl->Opcode;
dflet 0:1a07906111ec 500 g_pCB->TempProtocolHeader.Len = _SL_PROTOCOL_CALC_LEN(pCmdCtrl, pCmdExt);
dflet 0:1a07906111ec 501
dflet 0:1a07906111ec 502 if (pCmdExt && pCmdExt->RxPayloadLen < 0 && pCmdExt->TxPayloadLen)
dflet 0:1a07906111ec 503 {
dflet 0:1a07906111ec 504 pCmdExt->RxPayloadLen = pCmdExt->RxPayloadLen * (-1); /* change sign */
dflet 0:1a07906111ec 505 sendRxPayload = TRUE;
dflet 0:1a07906111ec 506 g_pCB->TempProtocolHeader.Len = g_pCB->TempProtocolHeader.Len + pCmdExt->RxPayloadLen;
dflet 0:1a07906111ec 507 }
dflet 0:1a07906111ec 508
dflet 0:1a07906111ec 509 #ifdef SL_START_WRITE_STAT
dflet 0:1a07906111ec 510 sl_IfStartWriteSequence(g_pCB->FD);
dflet 0:1a07906111ec 511 #endif
dflet 0:1a07906111ec 512
dflet 0:1a07906111ec 513 #ifdef SL_IF_TYPE_UART
dflet 0:1a07906111ec 514 /* Write long sync pattern */
dflet 0:1a07906111ec 515 _spi.spi_Write(g_pCB->FD, (uint8_t *)&g_H2NSyncPattern.Long, 2*SYNC_PATTERN_LEN);
dflet 0:1a07906111ec 516 #else
dflet 0:1a07906111ec 517 /* Write short sync pattern */
dflet 0:1a07906111ec 518 _spi.spi_Write(g_pCB->FD, (uint8_t *)&g_H2NSyncPattern.Short, SYNC_PATTERN_LEN);
dflet 0:1a07906111ec 519 #endif
dflet 0:1a07906111ec 520 /* Header */
dflet 0:1a07906111ec 521 _spi.spi_Write(g_pCB->FD, (uint8_t *)&g_pCB->TempProtocolHeader, _SL_CMD_HDR_SIZE);
dflet 0:1a07906111ec 522
dflet 0:1a07906111ec 523 /* Descriptors */
dflet 0:1a07906111ec 524 if (pTxRxDescBuff && pCmdCtrl->TxDescLen > 0)
dflet 0:1a07906111ec 525 {
dflet 0:1a07906111ec 526 _spi.spi_Write(g_pCB->FD, pTxRxDescBuff,
dflet 0:1a07906111ec 527 _SL_PROTOCOL_ALIGN_SIZE(pCmdCtrl->TxDescLen));
dflet 0:1a07906111ec 528 }
dflet 0:1a07906111ec 529
dflet 0:1a07906111ec 530 /* A special mode where Rx payload and Rx length are used as Tx as well */
dflet 0:1a07906111ec 531 /* This mode requires no Rx payload on the response and currently used by fs_Close and sl_Send on */
dflet 0:1a07906111ec 532 /* transceiver mode */
dflet 0:1a07906111ec 533 if (sendRxPayload == TRUE )
dflet 0:1a07906111ec 534 {
dflet 0:1a07906111ec 535 _spi.spi_Write(g_pCB->FD, pCmdExt->pRxPayload, _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->RxPayloadLen));
dflet 0:1a07906111ec 536 }
dflet 0:1a07906111ec 537
dflet 0:1a07906111ec 538 /* Payload */
dflet 0:1a07906111ec 539 if (pCmdExt && pCmdExt->TxPayloadLen > 0)
dflet 0:1a07906111ec 540 {
dflet 0:1a07906111ec 541 /* If the message has payload, it is mandatory that the message's arguments are protocol aligned. */
dflet 0:1a07906111ec 542 /* Otherwise the aligning of arguments will create a gap between arguments and payload. */
dflet 0:1a07906111ec 543 VERIFY_PROTOCOL(_SL_IS_PROTOCOL_ALIGNED_SIZE(pCmdCtrl->TxDescLen));
dflet 0:1a07906111ec 544
dflet 0:1a07906111ec 545 _spi.spi_Write(g_pCB->FD, pCmdExt->pTxPayload, _SL_PROTOCOL_ALIGN_SIZE(pCmdExt->TxPayloadLen));
dflet 0:1a07906111ec 546 }
dflet 0:1a07906111ec 547
dflet 0:1a07906111ec 548 _SL_DBG_CNT_INC(MsgCnt.Write);
dflet 0:1a07906111ec 549
dflet 0:1a07906111ec 550 #ifdef SL_START_WRITE_STAT
dflet 0:1a07906111ec 551 sl_IfEndWriteSequence(g_pCB->FD);
dflet 0:1a07906111ec 552 #endif
dflet 0:1a07906111ec 553
dflet 0:1a07906111ec 554 return SL_OS_RET_CODE_OK;
dflet 0:1a07906111ec 555 }
dflet 0:1a07906111ec 556
dflet 0:1a07906111ec 557 /* ******************************************************************************/
dflet 0:1a07906111ec 558 /* _SlDrvMsgRead */
dflet 0:1a07906111ec 559 /* ******************************************************************************/
dflet 0:1a07906111ec 560 _SlReturnVal_t cc3100_driver::_SlDrvMsgRead(void)
dflet 0:1a07906111ec 561 {
dflet 0:1a07906111ec 562 /* alignment for small memory models */
dflet 0:1a07906111ec 563 union {
dflet 0:1a07906111ec 564 uint8_t TempBuf[_SL_RESP_HDR_SIZE];
dflet 0:1a07906111ec 565 uint32_t DummyBuf[2];
dflet 0:1a07906111ec 566 } uBuf;
dflet 0:1a07906111ec 567 uint8_t TailBuffer[4];
dflet 0:1a07906111ec 568 uint16_t LengthToCopy;
dflet 0:1a07906111ec 569 uint16_t AlignedLengthRecv;
dflet 0:1a07906111ec 570 uint8_t AlignSize;
dflet 0:1a07906111ec 571 uint8_t *pAsyncBuf = NULL;
dflet 0:1a07906111ec 572 uint16_t OpCode;
dflet 0:1a07906111ec 573 uint16_t RespPayloadLen;
dflet 0:1a07906111ec 574 uint8_t sd = SL_MAX_SOCKETS;
dflet 0:1a07906111ec 575 _SlRxMsgClass_e RxMsgClass;
dflet 0:1a07906111ec 576
dflet 0:1a07906111ec 577
dflet 0:1a07906111ec 578 /* save params in global CB */
dflet 0:1a07906111ec 579 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;
dflet 0:1a07906111ec 580 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL;
dflet 0:1a07906111ec 581
dflet 0:1a07906111ec 582
dflet 0:1a07906111ec 583 VERIFY_RET_OK(_SlDrvRxHdrRead((uint8_t*)(uBuf.TempBuf), &AlignSize));
dflet 0:1a07906111ec 584
dflet 0:1a07906111ec 585 OpCode = OPCODE(uBuf.TempBuf);
dflet 0:1a07906111ec 586 RespPayloadLen = RSP_PAYLOAD_LEN(uBuf.TempBuf);
dflet 0:1a07906111ec 587
dflet 0:1a07906111ec 588
dflet 0:1a07906111ec 589 /* 'Init Compelete' message bears no valid FlowControl info */
dflet 0:1a07906111ec 590 if(SL_OPCODE_DEVICE_INITCOMPLETE != OpCode) {
dflet 0:1a07906111ec 591 g_pCB->FlowContCB.TxPoolCnt = ((_SlResponseHeader_t *)uBuf.TempBuf)->TxPoolCnt;
dflet 0:1a07906111ec 592 g_pCB->SocketNonBlocking = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketNonBlocking;
dflet 0:1a07906111ec 593 g_pCB->SocketTXFailure = ((_SlResponseHeader_t *)uBuf.TempBuf)->SocketTXFailure;
dflet 0:1a07906111ec 594
dflet 0:1a07906111ec 595 if(g_pCB->FlowContCB.TxPoolCnt > FLOW_CONT_MIN) {
dflet 0:1a07906111ec 596 _SlDrvSyncObjSignal(&g_pCB->FlowContCB.TxSyncObj);
dflet 0:1a07906111ec 597 }
dflet 0:1a07906111ec 598 }
dflet 0:1a07906111ec 599
dflet 0:1a07906111ec 600 /* Find the RX messaage class and set its async event handler */
dflet 0:1a07906111ec 601 _SlDrvClassifyRxMsg(OpCode);
dflet 0:1a07906111ec 602
dflet 0:1a07906111ec 603 RxMsgClass = g_pCB->FunctionParams.AsyncExt.RxMsgClass;
dflet 0:1a07906111ec 604
dflet 0:1a07906111ec 605
dflet 0:1a07906111ec 606 switch(RxMsgClass)
dflet 0:1a07906111ec 607 {
dflet 0:1a07906111ec 608 case ASYNC_EVT_CLASS:
dflet 0:1a07906111ec 609
dflet 0:1a07906111ec 610 VERIFY_PROTOCOL(NULL == pAsyncBuf);
dflet 0:1a07906111ec 611
dflet 0:1a07906111ec 612 #ifdef SL_MEMORY_MGMT_DYNAMIC
dflet 0:1a07906111ec 613 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = sl_Malloc(SL_ASYNC_MAX_MSG_LEN);
dflet 0:1a07906111ec 614 #else
dflet 0:1a07906111ec 615 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = g_StatMem.AsyncRespBuf;
dflet 0:1a07906111ec 616 #endif
dflet 0:1a07906111ec 617 /* set the local pointer to the allocated one */
dflet 0:1a07906111ec 618 pAsyncBuf = g_pCB->FunctionParams.AsyncExt.pAsyncBuf;
dflet 0:1a07906111ec 619
dflet 0:1a07906111ec 620 /* clear the async buffer */
dflet 0:1a07906111ec 621 _SlDrvMemZero(pAsyncBuf, SL_ASYNC_MAX_MSG_LEN);
dflet 0:1a07906111ec 622
dflet 0:1a07906111ec 623 MALLOC_OK_CHECK(pAsyncBuf);
dflet 0:1a07906111ec 624
dflet 0:1a07906111ec 625 memcpy(pAsyncBuf, uBuf.TempBuf, _SL_RESP_HDR_SIZE);
dflet 0:1a07906111ec 626 if (_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) <= SL_ASYNC_MAX_PAYLOAD_LEN)
dflet 0:1a07906111ec 627 {
dflet 0:1a07906111ec 628 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen);
dflet 0:1a07906111ec 629 }
dflet 0:1a07906111ec 630 else
dflet 0:1a07906111ec 631 {
dflet 0:1a07906111ec 632 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(SL_ASYNC_MAX_PAYLOAD_LEN);
dflet 0:1a07906111ec 633 }
dflet 0:1a07906111ec 634 if (RespPayloadLen > 0)
dflet 0:1a07906111ec 635 {
dflet 0:1a07906111ec 636 _spi.spi_Read(g_pCB->FD, pAsyncBuf + _SL_RESP_HDR_SIZE, AlignedLengthRecv);
dflet 0:1a07906111ec 637 }
dflet 0:1a07906111ec 638 /* In case ASYNC RX buffer length is smaller then the received data length, dump the rest */
dflet 0:1a07906111ec 639 if ((_SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) > SL_ASYNC_MAX_PAYLOAD_LEN))
dflet 0:1a07906111ec 640 {
dflet 0:1a07906111ec 641 AlignedLengthRecv = _SL_PROTOCOL_ALIGN_SIZE(RespPayloadLen) - SL_ASYNC_MAX_PAYLOAD_LEN;
dflet 0:1a07906111ec 642 while (AlignedLengthRecv > 0)
dflet 0:1a07906111ec 643 {
dflet 0:1a07906111ec 644 _spi.spi_Read(g_pCB->FD,TailBuffer,4);
dflet 0:1a07906111ec 645 AlignedLengthRecv = AlignedLengthRecv - 4;
dflet 0:1a07906111ec 646 }
dflet 0:1a07906111ec 647 }
dflet 0:1a07906111ec 648
dflet 0:1a07906111ec 649 _SlDrvProtectionObjLockWaitForever();
dflet 0:1a07906111ec 650
dflet 0:1a07906111ec 651 if (
dflet 0:1a07906111ec 652 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 653 (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE == OpCode) || (SL_OPCODE_SOCKET_ACCEPTASYNCRESPONSE_V6 == OpCode) ||
dflet 0:1a07906111ec 654 #endif
dflet 0:1a07906111ec 655 (SL_OPCODE_SOCKET_CONNECTASYNCRESPONSE == OpCode)
dflet 0:1a07906111ec 656 )
dflet 0:1a07906111ec 657 {
dflet 0:1a07906111ec 658 /* go over the active list if exist to find obj waiting for this Async event */
dflet 0:1a07906111ec 659 sd = ((((_SocketResponse_t *)(pAsyncBuf + _SL_RESP_HDR_SIZE))->sd) & BSD_SOCKET_ID_MASK);
dflet 0:1a07906111ec 660 }
dflet 0:1a07906111ec 661 _SlFindAndSetActiveObj(OpCode, sd);
dflet 0:1a07906111ec 662 _SlDrvProtectionObjUnLock();
dflet 0:1a07906111ec 663
dflet 0:1a07906111ec 664 break;
dflet 0:1a07906111ec 665 case RECV_RESP_CLASS:
dflet 0:1a07906111ec 666 {
dflet 0:1a07906111ec 667 uint8_t ExpArgSize; /* Expected size of Recv/Recvfrom arguments */
dflet 0:1a07906111ec 668
dflet 0:1a07906111ec 669 switch(OpCode)
dflet 0:1a07906111ec 670 {
dflet 0:1a07906111ec 671 case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE:
dflet 0:1a07906111ec 672 ExpArgSize = RECVFROM_IPV4_ARGS_SIZE;
dflet 0:1a07906111ec 673 break;
dflet 0:1a07906111ec 674 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 675 case SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6:
dflet 0:1a07906111ec 676 ExpArgSize = RECVFROM_IPV6_ARGS_SIZE;
dflet 0:1a07906111ec 677 break;
dflet 0:1a07906111ec 678 #endif
dflet 0:1a07906111ec 679 default:
dflet 0:1a07906111ec 680 /* SL_OPCODE_SOCKET_RECVASYNCRESPONSE: */
dflet 0:1a07906111ec 681 ExpArgSize = RECV_ARGS_SIZE;
dflet 0:1a07906111ec 682 }
dflet 0:1a07906111ec 683
dflet 0:1a07906111ec 684 /* Read first 4 bytes of Recv/Recvfrom response to get SocketId and actual */
dflet 0:1a07906111ec 685 /* response data length */
dflet 0:1a07906111ec 686 _spi.spi_Read(g_pCB->FD, &uBuf.TempBuf[4], RECV_ARGS_SIZE);
dflet 0:1a07906111ec 687
dflet 0:1a07906111ec 688 /* Validate Socket ID and Received Length value. */
dflet 0:1a07906111ec 689 VERIFY_PROTOCOL((SD(&uBuf.TempBuf[4])& BSD_SOCKET_ID_MASK) < SL_MAX_SOCKETS);
dflet 0:1a07906111ec 690
dflet 0:1a07906111ec 691 _SlDrvProtectionObjLockWaitForever();
dflet 0:1a07906111ec 692
dflet 0:1a07906111ec 693 /* go over the active list if exist to find obj waiting for this Async event */
dflet 0:1a07906111ec 694 VERIFY_RET_OK(_SlFindAndSetActiveObj(OpCode,SD(&uBuf.TempBuf[4]) & BSD_SOCKET_ID_MASK));
dflet 0:1a07906111ec 695
dflet 0:1a07906111ec 696 /* Verify data is waited on this socket. The pArgs should have been set by _SlDrvDataReadOp(). */
dflet 0:1a07906111ec 697 VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData))->pArgs);
dflet 0:1a07906111ec 698
dflet 0:1a07906111ec 699 memcpy( ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs, &uBuf.TempBuf[4], RECV_ARGS_SIZE);
dflet 0:1a07906111ec 700
dflet 0:1a07906111ec 701 if(ExpArgSize > RECV_ARGS_SIZE)
dflet 0:1a07906111ec 702 {
dflet 0:1a07906111ec 703 _spi.spi_Read(g_pCB->FD,
dflet 0:1a07906111ec 704 ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pArgs + RECV_ARGS_SIZE,
dflet 0:1a07906111ec 705 ExpArgSize - RECV_ARGS_SIZE);
dflet 0:1a07906111ec 706 }
dflet 0:1a07906111ec 707
dflet 0:1a07906111ec 708 /* Here g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pData contains requested(expected) Recv/Recvfrom DataSize. */
dflet 0:1a07906111ec 709 /* Overwrite requested DataSize with actual one. */
dflet 0:1a07906111ec 710 /* If error is received, this information will be read from arguments. */
dflet 0:1a07906111ec 711 if(ACT_DATA_SIZE(&uBuf.TempBuf[4]) > 0)
dflet 0:1a07906111ec 712 {
dflet 0:1a07906111ec 713 VERIFY_SOCKET_CB(NULL != ((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData);
dflet 0:1a07906111ec 714
dflet 0:1a07906111ec 715 /* Read 4 bytes aligned from interface */
dflet 0:1a07906111ec 716 /* therefore check the requested length and read only */
dflet 0:1a07906111ec 717 /* 4 bytes aligned data. The rest unaligned (if any) will be read */
dflet 0:1a07906111ec 718 /* and copied to a TailBuffer */
dflet 0:1a07906111ec 719 LengthToCopy = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (3);
dflet 0:1a07906111ec 720 AlignedLengthRecv = ACT_DATA_SIZE(&uBuf.TempBuf[4]) & (~3);
dflet 0:1a07906111ec 721 if( AlignedLengthRecv >= 4)
dflet 0:1a07906111ec 722 {
dflet 0:1a07906111ec 723 _spi.spi_Read(g_pCB->FD,((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData,AlignedLengthRecv );
dflet 0:1a07906111ec 724 }
dflet 0:1a07906111ec 725 /* copy the unaligned part, if any */
dflet 0:1a07906111ec 726 if( LengthToCopy > 0)
dflet 0:1a07906111ec 727 {
dflet 0:1a07906111ec 728 _spi.spi_Read(g_pCB->FD,TailBuffer,4);
dflet 0:1a07906111ec 729 /* copy TailBuffer unaligned part (1/2/3 bytes) */
dflet 0:1a07906111ec 730 memcpy(((_SlArgsData_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->pData + AlignedLengthRecv,TailBuffer,LengthToCopy);
dflet 0:1a07906111ec 731 }
dflet 0:1a07906111ec 732 }
dflet 0:1a07906111ec 733 _SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
dflet 0:1a07906111ec 734 _SlDrvProtectionObjUnLock();
dflet 0:1a07906111ec 735 }
dflet 0:1a07906111ec 736 break;
dflet 0:1a07906111ec 737
dflet 0:1a07906111ec 738 case CMD_RESP_CLASS:
dflet 0:1a07906111ec 739
dflet 0:1a07906111ec 740 /* Some commands pass a maximum arguments size. */
dflet 0:1a07906111ec 741 /* In this case Driver will send extra dummy patterns to NWP if */
dflet 0:1a07906111ec 742 /* the response message is smaller than maximum. */
dflet 0:1a07906111ec 743 /* When RxDescLen is not exact, using RxPayloadLen is forbidden! */
dflet 0:1a07906111ec 744 /* If such case cannot be avoided - parse message here to detect */
dflet 0:1a07906111ec 745 /* arguments/payload border. */
dflet 0:1a07906111ec 746 _spi.spi_Read(g_pCB->FD, g_pCB->FunctionParams.pTxRxDescBuff, _SL_PROTOCOL_ALIGN_SIZE(g_pCB->FunctionParams.pCmdCtrl->RxDescLen));
dflet 0:1a07906111ec 747
dflet 0:1a07906111ec 748 if((NULL != g_pCB->FunctionParams.pCmdExt) && (0 != g_pCB->FunctionParams.pCmdExt->RxPayloadLen)) {
dflet 0:1a07906111ec 749 /* Actual size of command's response payload: <msg_payload_len> - <rsp_args_len> */
dflet 0:1a07906111ec 750 int16_t ActDataSize = RSP_PAYLOAD_LEN(uBuf.TempBuf) - g_pCB->FunctionParams.pCmdCtrl->RxDescLen;
dflet 0:1a07906111ec 751
dflet 0:1a07906111ec 752 g_pCB->FunctionParams.pCmdExt->ActualRxPayloadLen = ActDataSize;
dflet 0:1a07906111ec 753
dflet 0:1a07906111ec 754 /* Check that the space prepared by user for the response data is sufficient. */
dflet 0:1a07906111ec 755 if(ActDataSize <= 0) {
dflet 0:1a07906111ec 756 g_pCB->FunctionParams.pCmdExt->RxPayloadLen = 0;
dflet 0:1a07906111ec 757 } else {
dflet 0:1a07906111ec 758 /* In case the user supplied Rx buffer length which is smaller then the received data length, copy according to user length */
dflet 0:1a07906111ec 759 if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) {
dflet 0:1a07906111ec 760 LengthToCopy = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (3);
dflet 0:1a07906111ec 761 AlignedLengthRecv = g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3);
dflet 0:1a07906111ec 762 } else {
dflet 0:1a07906111ec 763 LengthToCopy = ActDataSize & (3);
dflet 0:1a07906111ec 764 AlignedLengthRecv = ActDataSize & (~3);
dflet 0:1a07906111ec 765 }
dflet 0:1a07906111ec 766 /* Read 4 bytes aligned from interface */
dflet 0:1a07906111ec 767 /* therefore check the requested length and read only */
dflet 0:1a07906111ec 768 /* 4 bytes aligned data. The rest unaligned (if any) will be read */
dflet 0:1a07906111ec 769 /* and copied to a TailBuffer */
dflet 0:1a07906111ec 770
dflet 0:1a07906111ec 771 if( AlignedLengthRecv >= 4) {
dflet 0:1a07906111ec 772 _spi.spi_Read(g_pCB->FD,
dflet 0:1a07906111ec 773 g_pCB->FunctionParams.pCmdExt->pRxPayload,
dflet 0:1a07906111ec 774 AlignedLengthRecv );
dflet 0:1a07906111ec 775
dflet 0:1a07906111ec 776 }
dflet 0:1a07906111ec 777 /* copy the unaligned part, if any */
dflet 0:1a07906111ec 778 if( LengthToCopy > 0) {
dflet 0:1a07906111ec 779 _spi.spi_Read(g_pCB->FD,TailBuffer,4);
dflet 0:1a07906111ec 780 /* copy TailBuffer unaligned part (1/2/3 bytes) */
dflet 0:1a07906111ec 781 memcpy(g_pCB->FunctionParams.pCmdExt->pRxPayload + AlignedLengthRecv,
dflet 0:1a07906111ec 782 TailBuffer,
dflet 0:1a07906111ec 783 LengthToCopy);
dflet 0:1a07906111ec 784 ActDataSize = ActDataSize-4;
dflet 0:1a07906111ec 785 }
dflet 0:1a07906111ec 786 /* In case the user supplied Rx buffer length which is smaller then the received data length, dump the rest */
dflet 0:1a07906111ec 787 if (ActDataSize > g_pCB->FunctionParams.pCmdExt->RxPayloadLen) {
dflet 0:1a07906111ec 788 /* calculate the rest of the data size to dump */
dflet 0:1a07906111ec 789 AlignedLengthRecv = ActDataSize - (g_pCB->FunctionParams.pCmdExt->RxPayloadLen & (~3));
dflet 0:1a07906111ec 790 while( AlignedLengthRecv > 0) {
dflet 0:1a07906111ec 791 _spi.spi_Read(g_pCB->FD,TailBuffer, 4 );
dflet 0:1a07906111ec 792 AlignedLengthRecv = AlignedLengthRecv - 4;
dflet 0:1a07906111ec 793 }
dflet 0:1a07906111ec 794 }
dflet 0:1a07906111ec 795 }
dflet 0:1a07906111ec 796 }
dflet 0:1a07906111ec 797 break;
dflet 0:1a07906111ec 798
dflet 0:1a07906111ec 799 default:
dflet 0:1a07906111ec 800 /* DUMMY_MSG_CLASS: Flow control message has no payload. */
dflet 0:1a07906111ec 801 break;
dflet 0:1a07906111ec 802 }
dflet 0:1a07906111ec 803
dflet 0:1a07906111ec 804 if(AlignSize > 0) {
dflet 0:1a07906111ec 805 _spi.spi_Read(g_pCB->FD, uBuf.TempBuf, AlignSize);
dflet 0:1a07906111ec 806 }
dflet 0:1a07906111ec 807
dflet 0:1a07906111ec 808 _SL_DBG_CNT_INC(MsgCnt.Read);
dflet 0:1a07906111ec 809
dflet 0:1a07906111ec 810 /* Unmask Interrupt call */
dflet 0:1a07906111ec 811 _spi.UnMaskIntHdlr();
dflet 0:1a07906111ec 812
dflet 0:1a07906111ec 813 return SL_OS_RET_CODE_OK;
dflet 0:1a07906111ec 814 }
dflet 0:1a07906111ec 815
dflet 0:1a07906111ec 816 /* ******************************************************************************/
dflet 0:1a07906111ec 817 /* _SlAsyncEventGenericHandler */
dflet 0:1a07906111ec 818 /* ******************************************************************************/
dflet 0:1a07906111ec 819 void cc3100_driver::_SlAsyncEventGenericHandler(void)
dflet 0:1a07906111ec 820 {
dflet 0:1a07906111ec 821 uint32_t SlAsyncEvent = 0;
dflet 0:1a07906111ec 822 uint8_t OpcodeFound = FALSE;
dflet 0:1a07906111ec 823 uint8_t i;
dflet 0:1a07906111ec 824
dflet 0:1a07906111ec 825 uint32_t* pEventLocation = NULL; /* This pointer will override the async buffer with the translated event type */
dflet 0:1a07906111ec 826 _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)g_pCB->FunctionParams.AsyncExt.pAsyncBuf;
dflet 0:1a07906111ec 827
dflet 0:1a07906111ec 828
dflet 0:1a07906111ec 829 /* if no async event registered nothing to do..*/
dflet 0:1a07906111ec 830 if (g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler == NULL)
dflet 0:1a07906111ec 831 return;
dflet 0:1a07906111ec 832
dflet 0:1a07906111ec 833 /* Iterate through all the opcode in the table */
dflet 0:1a07906111ec 834 for (i=0; i< (sizeof(OpcodeTranslateTable) / sizeof(OpcodeKeyVal_t)); i++)
dflet 0:1a07906111ec 835 {
dflet 0:1a07906111ec 836 if (OpcodeTranslateTable[i].opcode == pHdr->GenHeader.Opcode)
dflet 0:1a07906111ec 837 {
dflet 0:1a07906111ec 838 SlAsyncEvent = OpcodeTranslateTable[i].event;
dflet 0:1a07906111ec 839 OpcodeFound = TRUE;
dflet 0:1a07906111ec 840 break;
dflet 0:1a07906111ec 841 }
dflet 0:1a07906111ec 842 }
dflet 0:1a07906111ec 843
dflet 0:1a07906111ec 844 /* No Async event found in the table */
dflet 0:1a07906111ec 845 if (OpcodeFound == FALSE)
dflet 0:1a07906111ec 846 {
dflet 0:1a07906111ec 847 /* This case handles all the async events handlers of the DEVICE & SOCK Silos which are handled internally.
dflet 0:1a07906111ec 848 For these cases we send the async even buffer as is */
dflet 0:1a07906111ec 849 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(g_pCB->FunctionParams.AsyncExt.pAsyncBuf);
dflet 0:1a07906111ec 850 }
dflet 0:1a07906111ec 851 else
dflet 0:1a07906111ec 852 {
dflet 0:1a07906111ec 853 /* calculate the event type location to be filled in the async buffer */
dflet 0:1a07906111ec 854 pEventLocation = (uint32_t*)(g_pCB->FunctionParams.AsyncExt.pAsyncBuf + sizeof (_SlResponseHeader_t) - sizeof(SlAsyncEvent) );
dflet 0:1a07906111ec 855
dflet 0:1a07906111ec 856 /* Override the async buffer (before the data starts ) with our event type */
dflet 0:1a07906111ec 857 *pEventLocation = SlAsyncEvent;
dflet 0:1a07906111ec 858
dflet 0:1a07906111ec 859 /* call the event handler registered by the user with our async buffer which now holds
dflet 0:1a07906111ec 860 the User's event type and its related data */
dflet 0:1a07906111ec 861 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler(pEventLocation);
dflet 0:1a07906111ec 862 }
dflet 0:1a07906111ec 863
dflet 0:1a07906111ec 864 }
dflet 0:1a07906111ec 865
dflet 0:1a07906111ec 866
dflet 0:1a07906111ec 867 /* ******************************************************************************/
dflet 0:1a07906111ec 868 /* _SlDrvMsgReadCmdCtx */
dflet 0:1a07906111ec 869 /* ******************************************************************************/
dflet 0:1a07906111ec 870 _SlReturnVal_t cc3100_driver::_SlDrvMsgReadCmdCtx(void)
dflet 0:1a07906111ec 871 {
dflet 0:1a07906111ec 872
dflet 0:1a07906111ec 873 /* after command response is received and isCmdRespWaited */
dflet 0:1a07906111ec 874 /* flag is set FALSE, it is necessary to read out all */
dflet 0:1a07906111ec 875 /* Async messages in Commands context, because ssiDma_IsrHandleSignalFromSlave */
dflet 0:1a07906111ec 876 /* could have dispatched some Async messages to g_NwpIf.CmdSyncObj */
dflet 0:1a07906111ec 877 /* after command response but before this response has been processed */
dflet 0:1a07906111ec 878 /* by spi_singleRead and isCmdRespWaited was set FALSE. */
dflet 0:1a07906111ec 879
dflet 0:1a07906111ec 880 while (TRUE == g_pCB->IsCmdRespWaited) {
dflet 0:1a07906111ec 881
dflet 0:1a07906111ec 882 if(_SL_PENDING_RX_MSG(g_pCB)) {
dflet 0:1a07906111ec 883
dflet 0:1a07906111ec 884 VERIFY_RET_OK(_SlDrvMsgRead());
dflet 0:1a07906111ec 885 g_pCB->RxDoneCnt++;
dflet 0:1a07906111ec 886
dflet 0:1a07906111ec 887 if (CMD_RESP_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) {
dflet 0:1a07906111ec 888 g_pCB->IsCmdRespWaited = FALSE;
dflet 0:1a07906111ec 889
dflet 0:1a07906111ec 890 /* In case CmdResp has been read without waiting on CmdSyncObj - that */
dflet 0:1a07906111ec 891 /* Sync object. That to prevent old signal to be processed. */
dflet 0:1a07906111ec 892 _nonos.sl_SyncObjClear(&g_pCB->CmdSyncObj);
dflet 0:1a07906111ec 893 } else if (ASYNC_EVT_CLASS == g_pCB->FunctionParams.AsyncExt.RxMsgClass) {
dflet 0:1a07906111ec 894 /* If Async event has been read in CmdResp context, check whether */
dflet 0:1a07906111ec 895 /* there is a handler for this event. If there is, spawn specific */
dflet 0:1a07906111ec 896 /* handler. Otherwise free the event's buffer. */
dflet 0:1a07906111ec 897 /* This way there will be no "dry shots" from CmdResp context to */
dflet 0:1a07906111ec 898 /* temporary context, i.e less waste of CPU and faster buffer */
dflet 0:1a07906111ec 899 /* release. */
dflet 0:1a07906111ec 900 _SlAsyncEventGenericHandler();
dflet 0:1a07906111ec 901
dflet 0:1a07906111ec 902 #ifdef SL_MEMORY_MGMT_DYNAMIC
dflet 0:1a07906111ec 903 sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf);
dflet 0:1a07906111ec 904 #else
dflet 0:1a07906111ec 905 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;
dflet 0:1a07906111ec 906 #endif
dflet 0:1a07906111ec 907 }
dflet 0:1a07906111ec 908 } else {
dflet 0:1a07906111ec 909 /* CmdSyncObj will be signaled by IRQ */
dflet 0:1a07906111ec 910 _SlDrvSyncObjWaitForever(&g_pCB->CmdSyncObj);
dflet 0:1a07906111ec 911 }
dflet 0:1a07906111ec 912 }
dflet 0:1a07906111ec 913
dflet 0:1a07906111ec 914 /* If there are more pending Rx Msgs after CmdResp is received, */
dflet 0:1a07906111ec 915 /* that means that these are Async, Dummy or Read Data Msgs. */
dflet 0:1a07906111ec 916 /* Spawn _SlDrvMsgReadSpawnCtx to trigger reading these messages from */
dflet 0:1a07906111ec 917 /* Temporary context. */
dflet 0:1a07906111ec 918 /* sl_Spawn is activated, using a different context */
dflet 0:1a07906111ec 919 _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
dflet 0:1a07906111ec 920
dflet 0:1a07906111ec 921 if(_SL_PENDING_RX_MSG(g_pCB)) {
dflet 0:1a07906111ec 922 _nonos._SlNonOsSpawn((_SlSpawnEntryFunc_t)&_SlDrvMsgReadSpawnCtx, NULL, 0);
dflet 0:1a07906111ec 923 }
dflet 0:1a07906111ec 924
dflet 0:1a07906111ec 925 return SL_OS_RET_CODE_OK;
dflet 0:1a07906111ec 926 }
dflet 0:1a07906111ec 927
dflet 0:1a07906111ec 928 /* ******************************************************************************/
dflet 0:1a07906111ec 929 /* _SlDrvMsgReadSpawnCtx */
dflet 0:1a07906111ec 930 /* ******************************************************************************/
dflet 0:1a07906111ec 931 /*
dflet 0:1a07906111ec 932 _SlReturnVal_t cc3100_driver::_SlDrvMsgReadSpawnCtx_(void *pValue)
dflet 0:1a07906111ec 933 {
dflet 0:1a07906111ec 934
dflet 0:1a07906111ec 935 #ifdef SL_POLLING_MODE_USED
dflet 0:1a07906111ec 936 int16_t retCode = OSI_OK;
dflet 0:1a07906111ec 937 // for polling based systems
dflet 0:1a07906111ec 938 do {
dflet 0:1a07906111ec 939 retCode = sl_LockObjLock(&g_pCB->GlobalLockObj, 0);
dflet 0:1a07906111ec 940 if ( OSI_OK != retCode ) {
dflet 0:1a07906111ec 941 if (TRUE == g_pCB->IsCmdRespWaited) {
dflet 0:1a07906111ec 942 _SlDrvSyncObjSignal(&g_pCB->CmdSyncObj);
dflet 0:1a07906111ec 943 return SL_RET_CODE_OK;
dflet 0:1a07906111ec 944 }
dflet 0:1a07906111ec 945 }
dflet 0:1a07906111ec 946
dflet 0:1a07906111ec 947 } while (OSI_OK != retCode);
dflet 0:1a07906111ec 948
dflet 0:1a07906111ec 949 #else
dflet 0:1a07906111ec 950 _SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj);
dflet 0:1a07906111ec 951 #endif
dflet 0:1a07906111ec 952
dflet 0:1a07906111ec 953 // Messages might have been read by CmdResp context. Therefore after
dflet 0:1a07906111ec 954 // getting LockObj, check again where the Pending Rx Msg is still present.
dflet 0:1a07906111ec 955 if(FALSE == (_SL_PENDING_RX_MSG(g_pCB))) {
dflet 0:1a07906111ec 956 _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
dflet 0:1a07906111ec 957 return SL_RET_CODE_OK;
dflet 0:1a07906111ec 958 }
dflet 0:1a07906111ec 959
dflet 0:1a07906111ec 960 VERIFY_RET_OK(_SlDrvMsgRead());
dflet 0:1a07906111ec 961
dflet 0:1a07906111ec 962 g_pCB->RxDoneCnt++;
dflet 0:1a07906111ec 963
dflet 0:1a07906111ec 964 switch(g_pCB->FunctionParams.AsyncExt.RxMsgClass) {
dflet 0:1a07906111ec 965 case ASYNC_EVT_CLASS:
dflet 0:1a07906111ec 966 // If got here and protected by LockObj a message is waiting
dflet 0:1a07906111ec 967 // to be read
dflet 0:1a07906111ec 968 VERIFY_PROTOCOL(NULL != g_pCB->FunctionParams.AsyncExt.pAsyncBuf);
dflet 0:1a07906111ec 969
dflet 0:1a07906111ec 970 _SlAsyncEventGenericHandler();
dflet 0:1a07906111ec 971
dflet 0:1a07906111ec 972 #ifdef SL_MEMORY_MGMT_DYNAMIC
dflet 0:1a07906111ec 973 sl_Free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf);
dflet 0:1a07906111ec 974 #else
dflet 0:1a07906111ec 975 g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;
dflet 0:1a07906111ec 976 #endif
dflet 0:1a07906111ec 977 break;
dflet 0:1a07906111ec 978 case DUMMY_MSG_CLASS:
dflet 0:1a07906111ec 979 case RECV_RESP_CLASS:
dflet 0:1a07906111ec 980 // These types are legal in this context. Do nothing
dflet 0:1a07906111ec 981 break;
dflet 0:1a07906111ec 982 case CMD_RESP_CLASS:
dflet 0:1a07906111ec 983 // Command response is illegal in this context.
dflet 0:1a07906111ec 984 // No 'break' here: Assert!
dflet 0:1a07906111ec 985 default:
dflet 0:1a07906111ec 986 VERIFY_PROTOCOL(0);
dflet 0:1a07906111ec 987 }
dflet 0:1a07906111ec 988
dflet 0:1a07906111ec 989 _SlDrvObjUnLock(&g_pCB->GlobalLockObj);
dflet 0:1a07906111ec 990
dflet 0:1a07906111ec 991 return(SL_RET_CODE_OK);
dflet 0:1a07906111ec 992 }
dflet 0:1a07906111ec 993 */
dflet 0:1a07906111ec 994 /* ******************************************************************************/
dflet 0:1a07906111ec 995 /* _SlDrvClassifyRxMsg */
dflet 0:1a07906111ec 996 /* ******************************************************************************/
dflet 0:1a07906111ec 997 void cc3100_driver::_SlDrvClassifyRxMsg(_SlOpcode_t Opcode)
dflet 0:1a07906111ec 998 {
dflet 0:1a07906111ec 999 _SlSpawnEntryFunc_t AsyncEvtHandler = NULL;
dflet 0:1a07906111ec 1000 _SlRxMsgClass_e RxMsgClass = CMD_RESP_CLASS;
dflet 0:1a07906111ec 1001 uint8_t Silo;
dflet 0:1a07906111ec 1002
dflet 0:1a07906111ec 1003
dflet 0:1a07906111ec 1004 if (0 == (SL_OPCODE_SYNC & Opcode))
dflet 0:1a07906111ec 1005 { /* Async event has received */
dflet 0:1a07906111ec 1006
dflet 0:1a07906111ec 1007 if (SL_OPCODE_DEVICE_DEVICEASYNCDUMMY == Opcode)
dflet 0:1a07906111ec 1008 {
dflet 0:1a07906111ec 1009 RxMsgClass = DUMMY_MSG_CLASS;
dflet 0:1a07906111ec 1010 }
dflet 0:1a07906111ec 1011 else if ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode)
dflet 0:1a07906111ec 1012 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1013 || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode)
dflet 0:1a07906111ec 1014 #endif
dflet 0:1a07906111ec 1015 )
dflet 0:1a07906111ec 1016 {
dflet 0:1a07906111ec 1017 RxMsgClass = RECV_RESP_CLASS;
dflet 0:1a07906111ec 1018 }
dflet 0:1a07906111ec 1019 else
dflet 0:1a07906111ec 1020 {
dflet 0:1a07906111ec 1021 /* This is Async Event class message */
dflet 0:1a07906111ec 1022 RxMsgClass = ASYNC_EVT_CLASS;
dflet 0:1a07906111ec 1023
dflet 0:1a07906111ec 1024 /* Despite the fact that 4 bits are allocated in the SILO field, we actually have only 6 SILOs
dflet 0:1a07906111ec 1025 So we can use the 8 options of SILO in look up table */
dflet 0:1a07906111ec 1026 Silo = ((Opcode >> SL_OPCODE_SILO_OFFSET) & 0x7);
dflet 0:1a07906111ec 1027
dflet 0:1a07906111ec 1028 VERIFY_PROTOCOL(Silo < (sizeof(RxMsgClassLUT)/sizeof(_SlSpawnEntryFunc_t)));
dflet 0:1a07906111ec 1029
dflet 0:1a07906111ec 1030 /* Set the async event hander according to the LUT */
dflet 0:1a07906111ec 1031 AsyncEvtHandler = RxMsgClassLUT[Silo];
dflet 0:1a07906111ec 1032
dflet 0:1a07906111ec 1033 if ((SL_OPCODE_NETAPP_HTTPGETTOKENVALUE == Opcode) || (SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE == Opcode))
dflet 0:1a07906111ec 1034 {
dflet 0:1a07906111ec 1035 AsyncEvtHandler = _SlDrvNetAppEventHandler;
dflet 0:1a07906111ec 1036 }
dflet 0:1a07906111ec 1037 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1038 else if (SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE == Opcode)
dflet 0:1a07906111ec 1039 {
dflet 0:1a07906111ec 1040 AsyncEvtHandler = (_SlSpawnEntryFunc_t)_sl_HandleAsync_PingResponse;
dflet 0:1a07906111ec 1041 }
dflet 0:1a07906111ec 1042 #endif
dflet 0:1a07906111ec 1043 }
dflet 0:1a07906111ec 1044 }
dflet 0:1a07906111ec 1045
dflet 0:1a07906111ec 1046 g_pCB->FunctionParams.AsyncExt.RxMsgClass = RxMsgClass;
dflet 0:1a07906111ec 1047 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = AsyncEvtHandler;
dflet 0:1a07906111ec 1048
dflet 0:1a07906111ec 1049 }
dflet 0:1a07906111ec 1050
dflet 0:1a07906111ec 1051 /* ******************************************************************************/
dflet 0:1a07906111ec 1052 /* _SlDrvRxHdrRead */
dflet 0:1a07906111ec 1053 /* ******************************************************************************/
dflet 0:1a07906111ec 1054 _SlReturnVal_t cc3100_driver::_SlDrvRxHdrRead(uint8_t *pBuf, uint8_t *pAlignSize)
dflet 0:1a07906111ec 1055 {
dflet 0:1a07906111ec 1056 uint32_t SyncCnt = 0;
dflet 0:1a07906111ec 1057 uint8_t ShiftIdx;
dflet 0:1a07906111ec 1058
dflet 0:1a07906111ec 1059 #ifndef SL_IF_TYPE_UART
dflet 0:1a07906111ec 1060 /* 1. Write CNYS pattern to NWP when working in SPI mode only */
dflet 0:1a07906111ec 1061 _spi.spi_Write(g_pCB->FD, (uint8_t *)&g_H2NCnysPattern.Short, SYNC_PATTERN_LEN);
dflet 0:1a07906111ec 1062 #endif
dflet 0:1a07906111ec 1063
dflet 0:1a07906111ec 1064 /* 2. Read 4 bytes (protocol aligned) */
dflet 0:1a07906111ec 1065 _spi.spi_Read(g_pCB->FD, &pBuf[0], 4);
dflet 0:1a07906111ec 1066 _SL_DBG_SYNC_LOG(SyncCnt,pBuf);
dflet 0:1a07906111ec 1067
dflet 0:1a07906111ec 1068 /* Wait for SYNC_PATTERN_LEN from the device */
dflet 0:1a07906111ec 1069 while ( ! N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) {
dflet 0:1a07906111ec 1070 /* 3. Debug limit of scan */
dflet 0:1a07906111ec 1071 VERIFY_PROTOCOL(SyncCnt < SL_SYNC_SCAN_THRESHOLD);
dflet 0:1a07906111ec 1072
dflet 0:1a07906111ec 1073 /* 4. Read next 4 bytes to Low 4 bytes of buffer */
dflet 0:1a07906111ec 1074 if(0 == (SyncCnt % (uint32_t)SYNC_PATTERN_LEN)) {
dflet 0:1a07906111ec 1075 _spi.spi_Read(g_pCB->FD, &pBuf[4], 4);
dflet 0:1a07906111ec 1076 _SL_DBG_SYNC_LOG(SyncCnt,pBuf);
dflet 0:1a07906111ec 1077 }
dflet 0:1a07906111ec 1078
dflet 0:1a07906111ec 1079 /* 5. Shift Buffer Up for checking if the sync is shifted */
dflet 0:1a07906111ec 1080 for(ShiftIdx = 0; ShiftIdx< 7; ShiftIdx++)
dflet 0:1a07906111ec 1081 {
dflet 0:1a07906111ec 1082 pBuf[ShiftIdx] = pBuf[ShiftIdx+1];
dflet 0:1a07906111ec 1083 }
dflet 0:1a07906111ec 1084 pBuf[7] = 0;
dflet 0:1a07906111ec 1085
dflet 0:1a07906111ec 1086 SyncCnt++;
dflet 0:1a07906111ec 1087 }
dflet 0:1a07906111ec 1088
dflet 0:1a07906111ec 1089 /* 5. Sync pattern found. If needed, complete number of read bytes to multiple of 4 (protocol align) */
dflet 0:1a07906111ec 1090 SyncCnt %= SYNC_PATTERN_LEN;
dflet 0:1a07906111ec 1091
dflet 0:1a07906111ec 1092 if(SyncCnt > 0) {
dflet 0:1a07906111ec 1093 *(uint32_t *)&pBuf[0] = *(uint32_t *)&pBuf[4];
dflet 0:1a07906111ec 1094 _spi.spi_Read(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN - SyncCnt], (uint16_t)SyncCnt);
dflet 0:1a07906111ec 1095 } else {
dflet 0:1a07906111ec 1096 _spi.spi_Read(g_pCB->FD, &pBuf[0], 4);
dflet 0:1a07906111ec 1097 }
dflet 0:1a07906111ec 1098
dflet 0:1a07906111ec 1099 /* 6. Scan for Double pattern. */
dflet 0:1a07906111ec 1100 while ( N2H_SYNC_PATTERN_MATCH(pBuf, g_pCB->TxSeqNum) ) {
dflet 0:1a07906111ec 1101 _SL_DBG_CNT_INC(Work.DoubleSyncPattern);
dflet 0:1a07906111ec 1102 _spi.spi_Read(g_pCB->FD, &pBuf[0], SYNC_PATTERN_LEN);
dflet 0:1a07906111ec 1103 }
dflet 0:1a07906111ec 1104 g_pCB->TxSeqNum++;
dflet 0:1a07906111ec 1105
dflet 0:1a07906111ec 1106 /* 7. Here we've read Generic Header (4 bytes). Read the Resp Specific header (4 more bytes). */
dflet 0:1a07906111ec 1107 _spi.spi_Read(g_pCB->FD, &pBuf[SYNC_PATTERN_LEN], _SL_RESP_SPEC_HDR_SIZE);
dflet 0:1a07906111ec 1108
dflet 0:1a07906111ec 1109 /* 8. Here we've read the entire Resp Header. */
dflet 0:1a07906111ec 1110 /* Return number bytes needed to be sent after read for NWP Rx 4-byte alignment (protocol alignment) */
dflet 0:1a07906111ec 1111 *pAlignSize = (uint8_t)((SyncCnt > 0) ? (SYNC_PATTERN_LEN - SyncCnt) : 0);
dflet 0:1a07906111ec 1112
dflet 0:1a07906111ec 1113 return SL_RET_CODE_OK;
dflet 0:1a07906111ec 1114 }
dflet 0:1a07906111ec 1115
dflet 0:1a07906111ec 1116 /* ***************************************************************************** */
dflet 0:1a07906111ec 1117 /* _SlDrvBasicCmd */
dflet 0:1a07906111ec 1118 /* ***************************************************************************** */
dflet 0:1a07906111ec 1119 typedef union {
dflet 0:1a07906111ec 1120 _BasicResponse_t Rsp;
dflet 0:1a07906111ec 1121 } _SlBasicCmdMsg_u;
dflet 0:1a07906111ec 1122
dflet 0:1a07906111ec 1123 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1124 int16_t cc3100_driver::_SlDrvBasicCmd(_SlOpcode_t Opcode)
dflet 0:1a07906111ec 1125 {
dflet 0:1a07906111ec 1126 _SlBasicCmdMsg_u Msg = {0};
dflet 0:1a07906111ec 1127 _SlCmdCtrl_t CmdCtrl;
dflet 0:1a07906111ec 1128
dflet 0:1a07906111ec 1129 CmdCtrl.Opcode = Opcode;
dflet 0:1a07906111ec 1130 CmdCtrl.TxDescLen = 0;
dflet 0:1a07906111ec 1131 CmdCtrl.RxDescLen = sizeof(_BasicResponse_t);
dflet 0:1a07906111ec 1132
dflet 0:1a07906111ec 1133
dflet 0:1a07906111ec 1134 VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&CmdCtrl, &Msg, NULL));
dflet 0:1a07906111ec 1135
dflet 0:1a07906111ec 1136 return (int16_t)Msg.Rsp.status;
dflet 0:1a07906111ec 1137 }
dflet 0:1a07906111ec 1138
dflet 0:1a07906111ec 1139 /*****************************************************************************
dflet 0:1a07906111ec 1140 _SlDrvCmdSend
dflet 0:1a07906111ec 1141 Send SL command without waiting for command response
dflet 0:1a07906111ec 1142 This function is unprotected and the caller should make
dflet 0:1a07906111ec 1143 sure global lock is active
dflet 0:1a07906111ec 1144 *****************************************************************************/
dflet 0:1a07906111ec 1145 _SlReturnVal_t cc3100_driver::_SlDrvCmdSend(_SlCmdCtrl_t *pCmdCtrl, void *pTxRxDescBuff, _SlCmdExt_t *pCmdExt)
dflet 0:1a07906111ec 1146 {
dflet 0:1a07906111ec 1147 _SlReturnVal_t RetVal;
dflet 0:1a07906111ec 1148 uint8_t IsCmdRespWaitedOriginalVal;
dflet 0:1a07906111ec 1149
dflet 0:1a07906111ec 1150 _SlFunctionParams_t originalFuncParms;
dflet 0:1a07906111ec 1151
dflet 0:1a07906111ec 1152 /* save the current RespWait flag before clearing it */
dflet 0:1a07906111ec 1153 IsCmdRespWaitedOriginalVal = g_pCB->IsCmdRespWaited;
dflet 0:1a07906111ec 1154
dflet 0:1a07906111ec 1155 /* save the current command parameters */
dflet 0:1a07906111ec 1156 memcpy(&originalFuncParms, &g_pCB->FunctionParams, sizeof(_SlFunctionParams_t));
dflet 0:1a07906111ec 1157
dflet 0:1a07906111ec 1158 g_pCB->IsCmdRespWaited = FALSE;
dflet 0:1a07906111ec 1159
dflet 0:1a07906111ec 1160 SL_TRACE0(DBG_MSG, MSG_312, "_SlDrvCmdSend: call _SlDrvMsgWrite");
dflet 0:1a07906111ec 1161
dflet 0:1a07906111ec 1162 /* send the message */
dflet 0:1a07906111ec 1163 RetVal = _SlDrvMsgWrite(pCmdCtrl, pCmdExt, (uint8_t*)pTxRxDescBuff);
dflet 0:1a07906111ec 1164
dflet 0:1a07906111ec 1165 /* restore the original RespWait flag */
dflet 0:1a07906111ec 1166 g_pCB->IsCmdRespWaited = IsCmdRespWaitedOriginalVal;
dflet 0:1a07906111ec 1167
dflet 0:1a07906111ec 1168 /* restore the original command parameters */
dflet 0:1a07906111ec 1169 memcpy(&g_pCB->FunctionParams, &originalFuncParms, sizeof(_SlFunctionParams_t));
dflet 0:1a07906111ec 1170
dflet 0:1a07906111ec 1171 return RetVal;
dflet 0:1a07906111ec 1172
dflet 0:1a07906111ec 1173
dflet 0:1a07906111ec 1174 }
dflet 0:1a07906111ec 1175 #endif
dflet 0:1a07906111ec 1176
dflet 0:1a07906111ec 1177 /* ***************************************************************************** */
dflet 0:1a07906111ec 1178 /* _SlDrvWaitForPoolObj */
dflet 0:1a07906111ec 1179 /* ***************************************************************************** */
dflet 0:1a07906111ec 1180 uint8_t cc3100_driver::_SlDrvWaitForPoolObj(uint8_t ActionID, uint8_t SocketID)
dflet 0:1a07906111ec 1181 {
dflet 0:1a07906111ec 1182 uint8_t CurrObjIndex = MAX_CONCURRENT_ACTIONS;
dflet 0:1a07906111ec 1183
dflet 0:1a07906111ec 1184 /* Get free object */
dflet 0:1a07906111ec 1185 _SlDrvProtectionObjLockWaitForever();
dflet 0:1a07906111ec 1186 if (MAX_CONCURRENT_ACTIONS > g_pCB->FreePoolIdx) {
dflet 0:1a07906111ec 1187 /* save the current obj index */
dflet 0:1a07906111ec 1188 CurrObjIndex = g_pCB->FreePoolIdx;
dflet 0:1a07906111ec 1189 /* set the new free index */
dflet 0:1a07906111ec 1190 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1191 if (MAX_CONCURRENT_ACTIONS > g_pCB->ObjPool[CurrObjIndex].NextIndex) {
dflet 0:1a07906111ec 1192 g_pCB->FreePoolIdx = g_pCB->ObjPool[CurrObjIndex].NextIndex;
dflet 0:1a07906111ec 1193 }
dflet 0:1a07906111ec 1194 else
dflet 0:1a07906111ec 1195 #endif
dflet 0:1a07906111ec 1196 {
dflet 0:1a07906111ec 1197 /* No further free actions available */
dflet 0:1a07906111ec 1198 g_pCB->FreePoolIdx = MAX_CONCURRENT_ACTIONS;
dflet 0:1a07906111ec 1199 }
dflet 0:1a07906111ec 1200 } else {
dflet 0:1a07906111ec 1201 _SlDrvProtectionObjUnLock();
dflet 0:1a07906111ec 1202 return CurrObjIndex;
dflet 0:1a07906111ec 1203 }
dflet 0:1a07906111ec 1204 g_pCB->ObjPool[CurrObjIndex].ActionID = (uint8_t)ActionID;
dflet 0:1a07906111ec 1205 if (SL_MAX_SOCKETS > SocketID) {
dflet 0:1a07906111ec 1206 g_pCB->ObjPool[CurrObjIndex].AdditionalData = SocketID;
dflet 0:1a07906111ec 1207 }
dflet 0:1a07906111ec 1208 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1209 /*In case this action is socket related, SocketID bit will be on
dflet 0:1a07906111ec 1210 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 */
dflet 0:1a07906111ec 1211 while ( ( (SL_MAX_SOCKETS > SocketID) && (g_pCB->ActiveActionsBitmap & (1<<SocketID)) ) ||
dflet 0:1a07906111ec 1212 ( (g_pCB->ActiveActionsBitmap & (1<<ActionID)) && (SL_MAX_SOCKETS == SocketID) ) )
dflet 0:1a07906111ec 1213 {
dflet 0:1a07906111ec 1214 /* action in progress - move to pending list */
dflet 0:1a07906111ec 1215 g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->PendingPoolIdx;
dflet 0:1a07906111ec 1216 g_pCB->PendingPoolIdx = CurrObjIndex;
dflet 0:1a07906111ec 1217 _SlDrvProtectionObjUnLock();
dflet 0:1a07906111ec 1218
dflet 0:1a07906111ec 1219 /* wait for action to be free */
dflet 0:1a07906111ec 1220 _SlDrvSyncObjWaitForever(&g_pCB->ObjPool[CurrObjIndex].SyncObj);
dflet 0:1a07906111ec 1221
dflet 0:1a07906111ec 1222 /* set params and move to active (remove from pending list at _SlDrvReleasePoolObj) */
dflet 0:1a07906111ec 1223 _SlDrvProtectionObjLockWaitForever();
dflet 0:1a07906111ec 1224 }
dflet 0:1a07906111ec 1225 #endif
dflet 0:1a07906111ec 1226 /* mark as active. Set socket as active if action is on socket, otherwise mark action as active */
dflet 0:1a07906111ec 1227 if (SL_MAX_SOCKETS > SocketID) {
dflet 0:1a07906111ec 1228 g_pCB->ActiveActionsBitmap |= (1<<SocketID);
dflet 0:1a07906111ec 1229 } else {
dflet 0:1a07906111ec 1230 g_pCB->ActiveActionsBitmap |= (1<<ActionID);
dflet 0:1a07906111ec 1231 }
dflet 0:1a07906111ec 1232 /* move to active list */
dflet 0:1a07906111ec 1233 g_pCB->ObjPool[CurrObjIndex].NextIndex = g_pCB->ActivePoolIdx;
dflet 0:1a07906111ec 1234 g_pCB->ActivePoolIdx = CurrObjIndex;
dflet 0:1a07906111ec 1235 /* unlock */
dflet 0:1a07906111ec 1236 _SlDrvProtectionObjUnLock();
dflet 0:1a07906111ec 1237 return CurrObjIndex;
dflet 0:1a07906111ec 1238 }
dflet 0:1a07906111ec 1239
dflet 0:1a07906111ec 1240 /* ******************************************************************************/
dflet 0:1a07906111ec 1241 /* _SlDrvReleasePoolObj */
dflet 0:1a07906111ec 1242 /* ******************************************************************************/
dflet 0:1a07906111ec 1243 void cc3100_driver::_SlDrvReleasePoolObj(uint8_t ObjIdx)
dflet 0:1a07906111ec 1244 {
dflet 0:1a07906111ec 1245 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1246 uint8_t PendingIndex;
dflet 0:1a07906111ec 1247 #endif
dflet 0:1a07906111ec 1248
dflet 0:1a07906111ec 1249 _SlDrvProtectionObjLockWaitForever();
dflet 0:1a07906111ec 1250
dflet 0:1a07906111ec 1251 /* In Tiny mode, there is only one object pool so no pending actions are available */
dflet 0:1a07906111ec 1252 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1253 /* go over the pending list and release other pending action if needed */
dflet 0:1a07906111ec 1254 PendingIndex = g_pCB->PendingPoolIdx;
dflet 0:1a07906111ec 1255
dflet 0:1a07906111ec 1256 while(MAX_CONCURRENT_ACTIONS > PendingIndex)
dflet 0:1a07906111ec 1257 {
dflet 0:1a07906111ec 1258 /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */
dflet 0:1a07906111ec 1259 if ( (g_pCB->ObjPool[PendingIndex].ActionID == g_pCB->ObjPool[ObjIdx].ActionID) &&
dflet 0:1a07906111ec 1260 ( (SL_MAX_SOCKETS == (g_pCB->ObjPool[PendingIndex].AdditionalData & BSD_SOCKET_ID_MASK)) ||
dflet 0:1a07906111ec 1261 ((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) ))) )
dflet 0:1a07906111ec 1262 {
dflet 0:1a07906111ec 1263 /* remove from pending list */
dflet 0:1a07906111ec 1264 _SlRemoveFromList(&g_pCB->PendingPoolIdx, PendingIndex);
dflet 0:1a07906111ec 1265 _SlDrvSyncObjSignal(&g_pCB->ObjPool[PendingIndex].SyncObj);
dflet 0:1a07906111ec 1266 break;
dflet 0:1a07906111ec 1267 }
dflet 0:1a07906111ec 1268 PendingIndex = g_pCB->ObjPool[PendingIndex].NextIndex;
dflet 0:1a07906111ec 1269 }
dflet 0:1a07906111ec 1270 #endif
dflet 0:1a07906111ec 1271
dflet 0:1a07906111ec 1272 if (SL_MAX_SOCKETS > (g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK))
dflet 0:1a07906111ec 1273 {
dflet 0:1a07906111ec 1274 /* unset socketID */
dflet 0:1a07906111ec 1275 g_pCB->ActiveActionsBitmap &= ~(1<<(g_pCB->ObjPool[ObjIdx].AdditionalData & BSD_SOCKET_ID_MASK));
dflet 0:1a07906111ec 1276 }
dflet 0:1a07906111ec 1277 else
dflet 0:1a07906111ec 1278 {
dflet 0:1a07906111ec 1279 /* unset actionID */
dflet 0:1a07906111ec 1280 g_pCB->ActiveActionsBitmap &= ~(1<<g_pCB->ObjPool[ObjIdx].ActionID);
dflet 0:1a07906111ec 1281 }
dflet 0:1a07906111ec 1282
dflet 0:1a07906111ec 1283 /* delete old data */
dflet 0:1a07906111ec 1284 g_pCB->ObjPool[ObjIdx].pRespArgs = NULL;
dflet 0:1a07906111ec 1285 g_pCB->ObjPool[ObjIdx].ActionID = 0;
dflet 0:1a07906111ec 1286 g_pCB->ObjPool[ObjIdx].AdditionalData = SL_MAX_SOCKETS;
dflet 0:1a07906111ec 1287
dflet 0:1a07906111ec 1288 /* remove from active list */
dflet 0:1a07906111ec 1289 _SlRemoveFromList(&g_pCB->ActivePoolIdx, ObjIdx);
dflet 0:1a07906111ec 1290 /* move to free list */
dflet 0:1a07906111ec 1291 g_pCB->ObjPool[ObjIdx].NextIndex = g_pCB->FreePoolIdx;
dflet 0:1a07906111ec 1292 g_pCB->FreePoolIdx = ObjIdx;
dflet 0:1a07906111ec 1293
dflet 0:1a07906111ec 1294 _SlDrvProtectionObjUnLock();
dflet 0:1a07906111ec 1295 }
dflet 0:1a07906111ec 1296
dflet 0:1a07906111ec 1297 /* ******************************************************************************/
dflet 0:1a07906111ec 1298 /* _SlRemoveFromList */
dflet 0:1a07906111ec 1299 /* ******************************************************************************/
dflet 0:1a07906111ec 1300 void cc3100_driver::_SlRemoveFromList(uint8_t *ListIndex, uint8_t ItemIndex)
dflet 0:1a07906111ec 1301 {
dflet 0:1a07906111ec 1302 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1303 uint8_t Idx;
dflet 0:1a07906111ec 1304 #endif
dflet 0:1a07906111ec 1305
dflet 0:1a07906111ec 1306 if (MAX_CONCURRENT_ACTIONS == g_pCB->ObjPool[*ListIndex].NextIndex)
dflet 0:1a07906111ec 1307 {
dflet 0:1a07906111ec 1308 *ListIndex = MAX_CONCURRENT_ACTIONS;
dflet 0:1a07906111ec 1309 }
dflet 0:1a07906111ec 1310 /* As MAX_CONCURRENT_ACTIONS is equal to 1 in Tiny mode */
dflet 0:1a07906111ec 1311 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1312 /* need to remove the first item in the list and therefore update the global which holds this index */
dflet 0:1a07906111ec 1313 else if (*ListIndex == ItemIndex)
dflet 0:1a07906111ec 1314 {
dflet 0:1a07906111ec 1315 *ListIndex = g_pCB->ObjPool[ItemIndex].NextIndex;
dflet 0:1a07906111ec 1316 }
dflet 0:1a07906111ec 1317 else
dflet 0:1a07906111ec 1318 {
dflet 0:1a07906111ec 1319 Idx = *ListIndex;
dflet 0:1a07906111ec 1320
dflet 0:1a07906111ec 1321 while(MAX_CONCURRENT_ACTIONS > Idx)
dflet 0:1a07906111ec 1322 {
dflet 0:1a07906111ec 1323 /* remove from list */
dflet 0:1a07906111ec 1324 if (g_pCB->ObjPool[Idx].NextIndex == ItemIndex)
dflet 0:1a07906111ec 1325 {
dflet 0:1a07906111ec 1326 g_pCB->ObjPool[Idx].NextIndex = g_pCB->ObjPool[ItemIndex].NextIndex;
dflet 0:1a07906111ec 1327 break;
dflet 0:1a07906111ec 1328 }
dflet 0:1a07906111ec 1329
dflet 0:1a07906111ec 1330 Idx = g_pCB->ObjPool[Idx].NextIndex;
dflet 0:1a07906111ec 1331 }
dflet 0:1a07906111ec 1332 }
dflet 0:1a07906111ec 1333 #endif
dflet 0:1a07906111ec 1334 }
dflet 0:1a07906111ec 1335
dflet 0:1a07906111ec 1336 /* ******************************************************************************/
dflet 0:1a07906111ec 1337 /* _SlFindAndSetActiveObj */
dflet 0:1a07906111ec 1338 /* ******************************************************************************/
dflet 0:1a07906111ec 1339 _SlReturnVal_t cc3100_driver::_SlFindAndSetActiveObj(_SlOpcode_t Opcode, uint8_t Sd)
dflet 0:1a07906111ec 1340 {
dflet 0:1a07906111ec 1341 uint8_t ActiveIndex;
dflet 0:1a07906111ec 1342
dflet 0:1a07906111ec 1343 ActiveIndex = g_pCB->ActivePoolIdx;
dflet 0:1a07906111ec 1344 /* go over the active list if exist to find obj waiting for this Async event */
dflet 0:1a07906111ec 1345 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1346 while (MAX_CONCURRENT_ACTIONS > ActiveIndex){
dflet 0:1a07906111ec 1347 #else
dflet 0:1a07906111ec 1348 /* Only one Active action is availabe in tiny mode, so we can replace the loop with if condition */
dflet 0:1a07906111ec 1349 if (MAX_CONCURRENT_ACTIONS > ActiveIndex)
dflet 0:1a07906111ec 1350 #endif
dflet 0:1a07906111ec 1351 /* unset the Ipv4\IPv6 bit in the opcode if family bit was set */
dflet 0:1a07906111ec 1352 if (g_pCB->ObjPool[ActiveIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) {
dflet 0:1a07906111ec 1353 Opcode &= ~SL_OPCODE_IPV6;
dflet 0:1a07906111ec 1354 }
dflet 0:1a07906111ec 1355
dflet 0:1a07906111ec 1356 if ((g_pCB->ObjPool[ActiveIndex].ActionID == RECV_ID) && (Sd == g_pCB->ObjPool[ActiveIndex].AdditionalData) &&
dflet 0:1a07906111ec 1357 ( (SL_OPCODE_SOCKET_RECVASYNCRESPONSE == Opcode) || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE == Opcode)
dflet 0:1a07906111ec 1358 #ifndef SL_TINY_EXT
dflet 0:1a07906111ec 1359 || (SL_OPCODE_SOCKET_RECVFROMASYNCRESPONSE_V6 == Opcode)
dflet 0:1a07906111ec 1360 #endif
dflet 0:1a07906111ec 1361 )
dflet 0:1a07906111ec 1362
dflet 0:1a07906111ec 1363 )
dflet 0:1a07906111ec 1364 {
dflet 0:1a07906111ec 1365 g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex;
dflet 0:1a07906111ec 1366 return SL_RET_CODE_OK;
dflet 0:1a07906111ec 1367 }
dflet 0:1a07906111ec 1368 /* In case this action is socket related, SocketID is in use, otherwise will be set to SL_MAX_SOCKETS */
dflet 0:1a07906111ec 1369 if ( (_SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].ActionAsyncOpcode == Opcode) &&
dflet 0:1a07906111ec 1370 ( ((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)) ) ) {
dflet 0:1a07906111ec 1371 /* set handler */
dflet 0:1a07906111ec 1372 g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler = _SlActionLookupTable[ g_pCB->ObjPool[ActiveIndex].ActionID - MAX_SOCKET_ENUM_IDX].AsyncEventHandler;
dflet 0:1a07906111ec 1373 g_pCB->FunctionParams.AsyncExt.ActionIndex = ActiveIndex;
dflet 0:1a07906111ec 1374 return SL_RET_CODE_OK;
dflet 0:1a07906111ec 1375 }
dflet 0:1a07906111ec 1376 ActiveIndex = g_pCB->ObjPool[ActiveIndex].NextIndex;
dflet 0:1a07906111ec 1377 }
dflet 0:1a07906111ec 1378
dflet 0:1a07906111ec 1379 return SL_RET_CODE_SELF_ERROR;
dflet 0:1a07906111ec 1380
dflet 0:1a07906111ec 1381 }
dflet 0:1a07906111ec 1382
dflet 0:1a07906111ec 1383 /* Wrappers for the object functions */
dflet 0:1a07906111ec 1384
dflet 0:1a07906111ec 1385 void cc3100_driver::_SlDrvSyncObjWaitForever(_SlSyncObj_t *pSyncObj)
dflet 0:1a07906111ec 1386 {
dflet 0:1a07906111ec 1387 OSI_RET_OK_CHECK(_nonos.sl_SyncObjWait(pSyncObj, NON_OS_SYNC_OBJ_SIGNAL_VALUE, NON_OS_SYNC_OBJ_CLEAR_VALUE, SL_OS_WAIT_FOREVER));
dflet 0:1a07906111ec 1388 }
dflet 0:1a07906111ec 1389
dflet 0:1a07906111ec 1390 void cc3100_driver::_SlDrvSyncObjSignal(_SlSyncObj_t *pSyncObj)
dflet 0:1a07906111ec 1391 {
dflet 0:1a07906111ec 1392 OSI_RET_OK_CHECK(_nonos.sl_SyncObjSignal(pSyncObj, NON_OS_SYNC_OBJ_SIGNAL_VALUE));
dflet 0:1a07906111ec 1393 }
dflet 0:1a07906111ec 1394
dflet 0:1a07906111ec 1395 void cc3100_driver::_SlDrvObjLockWaitForever(_SlLockObj_t *pLockObj)
dflet 0:1a07906111ec 1396 {
dflet 0:1a07906111ec 1397 OSI_RET_OK_CHECK(_nonos.sl_LockObjLock(pLockObj, NON_OS_LOCK_OBJ_UNLOCK_VALUE, NON_OS_LOCK_OBJ_LOCK_VALUE, SL_OS_WAIT_FOREVER));
dflet 0:1a07906111ec 1398
dflet 0:1a07906111ec 1399 }
dflet 0:1a07906111ec 1400
dflet 0:1a07906111ec 1401 void cc3100_driver::_SlDrvProtectionObjLockWaitForever()
dflet 0:1a07906111ec 1402 {
dflet 0:1a07906111ec 1403 OSI_RET_OK_CHECK(_nonos.sl_LockObjLock(&g_pCB->ProtectionLockObj, NON_OS_LOCK_OBJ_UNLOCK_VALUE, NON_OS_LOCK_OBJ_LOCK_VALUE, SL_OS_WAIT_FOREVER));
dflet 0:1a07906111ec 1404
dflet 0:1a07906111ec 1405 }
dflet 0:1a07906111ec 1406
dflet 0:1a07906111ec 1407 void cc3100_driver::_SlDrvObjUnLock(_SlLockObj_t *pLockObj)
dflet 0:1a07906111ec 1408 {
dflet 0:1a07906111ec 1409 OSI_RET_OK_CHECK(_nonos.sl_LockObjUnlock(pLockObj, NON_OS_LOCK_OBJ_UNLOCK_VALUE));
dflet 0:1a07906111ec 1410
dflet 0:1a07906111ec 1411 }
dflet 0:1a07906111ec 1412
dflet 0:1a07906111ec 1413 void cc3100_driver::_SlDrvProtectionObjUnLock()
dflet 0:1a07906111ec 1414 {
dflet 0:1a07906111ec 1415 OSI_RET_OK_CHECK(_nonos.sl_LockObjUnlock(&g_pCB->ProtectionLockObj, NON_OS_LOCK_OBJ_UNLOCK_VALUE));
dflet 0:1a07906111ec 1416 }
dflet 0:1a07906111ec 1417
dflet 0:1a07906111ec 1418
dflet 0:1a07906111ec 1419 void cc3100_driver::_SlDrvMemZero(void* Addr, uint16_t size)
dflet 0:1a07906111ec 1420 {
dflet 0:1a07906111ec 1421 memset(Addr, 0, size);
dflet 0:1a07906111ec 1422 }
dflet 0:1a07906111ec 1423
dflet 0:1a07906111ec 1424
dflet 0:1a07906111ec 1425 void cc3100_driver::_SlDrvResetCmdExt(_SlCmdExt_t* pCmdExt)
dflet 0:1a07906111ec 1426 {
dflet 0:1a07906111ec 1427 _SlDrvMemZero(pCmdExt, sizeof (_SlCmdExt_t));
dflet 0:1a07906111ec 1428 }
dflet 0:1a07906111ec 1429
dflet 0:1a07906111ec 1430 }//namespace mbed_cc3100
dflet 0:1a07906111ec 1431
dflet 0:1a07906111ec 1432