TI's CC3100 websocket camera demo with Arducam mini ov5642 and freertos. Should work with other M3's. Work in progress test demo.

Dependencies:   mbed

Committer:
dflet
Date:
Sun Sep 06 15:19:36 2015 +0000
Revision:
0:400d8e75a8d0
Child:
1:e448e81c416f
TI's websocket Camera demo, also uses Arducam mini 0v5642 camera.

Who changed what in which revision?

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