TI's MQTT Demo with freertos CM4F

Dependencies:   mbed

Committer:
dflet
Date:
Thu Sep 03 14:07:01 2015 +0000
Revision:
0:1e7b5dd9edb4
First commit, it's been hanging around for a while. Updated SPI mode change 1 to 0.

Who changed what in which revision?

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