Update revision to use TI's mqtt and Freertos.

Dependencies:   mbed client server

Fork of cc3100_Test_mqtt_CM3 by David Fletcher

Committer:
dflet
Date:
Thu Sep 03 14:02:37 2015 +0000
Revision:
3:a8c249046181
SPI Mode change 1 to 0

Who changed what in which revision?

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