cc3100_Socket_Wifi_Server version for LPC1768

Dependencies:   mbed

Fork of cc3100_Test_Demo by David Fletcher

Committer:
artpes
Date:
Fri May 26 19:26:11 2017 +0000
Revision:
8:e79bacf664cc
Parent:
6:778b081f6a13
Fork

Who changed what in which revision?

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