David Fletcher / Mbed 2 deprecated cc3100_test

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3100_device.cpp Source File

cc3100_device.cpp

00001 /*
00002 * device.c - CC31xx/CC32xx Host Driver Implementation
00003 *
00004 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 
00005 * 
00006 * 
00007 *  Redistribution and use in source and binary forms, with or without 
00008 *  modification, are permitted provided that the following conditions 
00009 *  are met:
00010 *
00011 *    Redistributions of source code must retain the above copyright 
00012 *    notice, this list of conditions and the following disclaimer.
00013 *
00014 *    Redistributions in binary form must reproduce the above copyright
00015 *    notice, this list of conditions and the following disclaimer in the 
00016 *    documentation and/or other materials provided with the   
00017 *    distribution.
00018 *
00019 *    Neither the name of Texas Instruments Incorporated nor the names of
00020 *    its contributors may be used to endorse or promote products derived
00021 *    from this software without specific prior written permission.
00022 *
00023 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00024 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
00025 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00026 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
00027 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
00028 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00029 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00032 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00033 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 *
00035 */
00036 
00037 
00038 
00039 /*****************************************************************************/
00040 /* Include files                                                             */
00041 /*****************************************************************************/
00042 #include "cc3100_simplelink.h"
00043 #include "cc3100_protocol.h"
00044 #include "cc3100_flowcont.h"
00045 #include "cc3100_driver.h"
00046 
00047 
00048 /*****************************************************************************/
00049 /* Internal functions                                                        */
00050 /*****************************************************************************/
00051 
00052 _i16 _sl_GetStartResponseConvert(_u32 Status)
00053 {
00054     switch(Status)
00055     {
00056     case INIT_STA_OK:
00057         return ROLE_STA;
00058     case INIT_STA_ERR:
00059         return ROLE_STA_ERR;
00060     case INIT_AP_OK:
00061         return ROLE_AP;
00062     case INIT_AP_ERR:
00063         return ROLE_AP_ERR;
00064     case INIT_P2P_OK:
00065         return ROLE_P2P;
00066     case INIT_P2P_ERR:
00067         return ROLE_P2P_ERR;
00068     default:
00069         return (_i16)Status;
00070     }
00071 }
00072 
00073 /*****************************************************************************/
00074 /* API Functions                                                             */
00075 /*****************************************************************************/
00076 
00077 
00078 
00079 /*****************************************************************************/
00080 /* sl_Task                                                                   */
00081 /*****************************************************************************/
00082 #if _SL_INCLUDE_FUNC(sl_Task)
00083 void sl_Task(void)
00084 {
00085 #ifdef _SlTaskEntry
00086     _SlTaskEntry();
00087 #endif
00088 }
00089 #endif
00090 
00091 /*****************************************************************************/
00092 /* sl_Start                                                                  */
00093 /*****************************************************************************/
00094 #if _SL_INCLUDE_FUNC(sl_Start)
00095 _i16 sl_Start(const void* pIfHdl, _i8*  pDevName, const P_INIT_CALLBACK pInitCallBack)
00096 {
00097     _i16 ObjIdx = MAX_CONCURRENT_ACTIONS;
00098     InitComplete_t  AsyncRsp;
00099 
00100     /* Perform any preprocessing before enable networking services */
00101     sl_DeviceEnablePreamble();
00102 
00103     /* ControlBlock init */
00104     _SlDrvDriverCBInit();
00105 
00106     /* open the interface: usually SPI or UART */
00107     if (NULL == pIfHdl)
00108     {
00109         g_pCB->FD = sl_IfOpen((char *)pDevName, 0);//char* replaced void*
00110     }
00111     else
00112     {
00113         g_pCB->FD = (_SlFd_t)pIfHdl;
00114     }
00115     /* Use Obj to issue the command, if not available try later */
00116     ObjIdx = _SlDrvWaitForPoolObj(START_STOP_ID,SL_MAX_SOCKETS);
00117     if (MAX_CONCURRENT_ACTIONS == ObjIdx)
00118     {
00119         return SL_POOL_IS_EMPTY;
00120     }
00121     OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER));
00122     g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp;
00123     OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj));
00124 
00125     if( g_pCB->FD >= 0)
00126     {
00127         sl_DeviceDisable();
00128 
00129         sl_IfRegIntHdlr((SL_P_EVENT_HANDLER)_SlDrvRxIrqHandler, NULL);
00130 
00131         if(NULL != pInitCallBack)
00132         {
00133             g_pCB->pInitCallback = pInitCallBack;
00134         }
00135         sl_DeviceEnable();
00136 
00137         if (NULL == pInitCallBack)
00138         {
00139             OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER));
00140             /*release Pool Object*/
00141             _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);
00142             return _sl_GetStartResponseConvert(AsyncRsp.Status);
00143         }
00144     }
00145 
00146     return (_i16)g_pCB->FD;
00147 
00148 }
00149 #endif
00150 
00151 /***************************************************************************
00152 _sl_HandleAsync_InitComplete - handles init complete signalling to 
00153 a waiting object
00154 ****************************************************************************/
00155 void _sl_HandleAsync_InitComplete(void *pVoidBuf)
00156 {
00157     InitComplete_t     *pMsgArgs   = (InitComplete_t *)_SL_RESP_ARGS_START(pVoidBuf);
00158 
00159     OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER));
00160 
00161     if(g_pCB->pInitCallback)
00162     {
00163         g_pCB->pInitCallback(_sl_GetStartResponseConvert(pMsgArgs->Status));
00164     }
00165     else
00166     {
00167         sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(InitComplete_t));
00168         OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj));
00169     }
00170     OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj));
00171 
00172     if(g_pCB->pInitCallback)
00173     {
00174         _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex);
00175     }
00176 
00177 }
00178 
00179 /***************************************************************************
00180 _sl_HandleAsync_Stop - handles stop signalling to 
00181 a waiting object
00182 ****************************************************************************/
00183 void _sl_HandleAsync_Stop(void *pVoidBuf)
00184 {
00185     _BasicResponse_t     *pMsgArgs   = (_BasicResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);
00186 
00187     VERIFY_SOCKET_CB(NULL != g_pCB->StopCB.pAsyncRsp);
00188 
00189     OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER));
00190 
00191     sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_BasicResponse_t));
00192     OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj));
00193     OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj));
00194     return;
00195 }
00196 
00197 
00198 /*****************************************************************************
00199 sl_stop
00200 ******************************************************************************/
00201 typedef union
00202 {
00203     _DevStopCommand_t  Cmd;
00204     _BasicResponse_t   Rsp;    
00205 }_SlStopMsg_u;
00206 
00207 const _SlCmdCtrl_t _SlStopCmdCtrl =
00208 {
00209     SL_OPCODE_DEVICE_STOP_COMMAND,
00210     sizeof(_DevStopCommand_t),
00211     sizeof(_BasicResponse_t)
00212 };
00213 
00214 #if _SL_INCLUDE_FUNC(sl_Stop)
00215 _i16 sl_Stop(_u16 timeout)
00216 {
00217     _i16 RetVal=0;
00218     _SlStopMsg_u      Msg;
00219     _BasicResponse_t  AsyncRsp;
00220     _i16 ObjIdx = MAX_CONCURRENT_ACTIONS;
00221     /* if timeout is 0 the shutdown is forced immediately */
00222     if( 0 == timeout ) 
00223     {
00224         sl_IfRegIntHdlr(NULL, NULL);
00225         sl_DeviceDisable();
00226         RetVal = sl_IfClose(g_pCB->FD);
00227 
00228     }
00229     else
00230     {
00231         /* let the device make the shutdown using the defined timeout */
00232         Msg.Cmd.Timeout = timeout;
00233         /* Use Obj to issue the command, if not available try later */
00234         ObjIdx = _SlDrvWaitForPoolObj(START_STOP_ID,SL_MAX_SOCKETS);
00235         if (MAX_CONCURRENT_ACTIONS == ObjIdx)
00236         {
00237             return SL_POOL_IS_EMPTY;
00238         }
00239         OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER));
00240 
00241         g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp;
00242 
00243         OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj));
00244 
00245         VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlStopCmdCtrl, &Msg, NULL));
00246 
00247         if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status)
00248         {
00249             OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER));
00250             Msg.Rsp.status = AsyncRsp.status;
00251             RetVal = Msg.Rsp.status;
00252         }
00253 
00254         _SlDrvReleasePoolObj((_u8)ObjIdx);
00255 
00256         sl_IfRegIntHdlr(NULL, NULL);
00257         sl_DeviceDisable();
00258         sl_IfClose(g_pCB->FD);
00259     }
00260     _SlDrvDriverCBDeinit();
00261 
00262     return RetVal;
00263 }
00264 #endif
00265 
00266 
00267 /*****************************************************************************
00268 sl_EventMaskSet
00269 *****************************************************************************/
00270 typedef union
00271 {
00272     _DevMaskEventSetCommand_t       Cmd;
00273     _BasicResponse_t                Rsp;
00274 }_SlEventMaskSetMsg_u;
00275 
00276 const _SlCmdCtrl_t _SlEventMaskSetCmdCtrl =
00277 {
00278     SL_OPCODE_DEVICE_EVENTMASKSET,
00279     sizeof(_DevMaskEventSetCommand_t),
00280     sizeof(_BasicResponse_t)
00281 };
00282 
00283 #if _SL_INCLUDE_FUNC(sl_EventMaskSet)
00284 _i16 sl_EventMaskSet(_u8 EventClass , _u32 Mask)
00285 {
00286     _SlEventMaskSetMsg_u Msg;
00287 
00288     Msg.Cmd.group = EventClass;
00289     Msg.Cmd.mask = Mask;
00290 
00291     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskSetCmdCtrl, &Msg, NULL));
00292 
00293     return (_i16)Msg.Rsp.status;
00294 }
00295 #endif
00296 
00297 /******************************************************************************
00298 sl_EventMaskGet
00299 ******************************************************************************/
00300 typedef union
00301 {
00302     _DevMaskEventGetCommand_t       Cmd;
00303     _DevMaskEventGetResponse_t      Rsp;
00304 }_SlEventMaskGetMsg_u;
00305 
00306 const _SlCmdCtrl_t _SlEventMaskGetCmdCtrl =
00307 {
00308     SL_OPCODE_DEVICE_EVENTMASKGET,
00309     sizeof(_DevMaskEventGetCommand_t),
00310     sizeof(_DevMaskEventGetResponse_t)
00311 };
00312 
00313 #if _SL_INCLUDE_FUNC(sl_EventMaskGet)
00314 _i16 sl_EventMaskGet(_u8 EventClass, _u32 *pMask)
00315 {
00316     _SlEventMaskGetMsg_u Msg;
00317 
00318     Msg.Cmd.group = EventClass;
00319 
00320     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskGetCmdCtrl, &Msg, NULL));
00321 
00322     *pMask = Msg.Rsp.mask;
00323     return SL_RET_CODE_OK;
00324 }
00325 #endif
00326 
00327 
00328 
00329 /******************************************************************************
00330 sl_DevGet
00331 ******************************************************************************/
00332 
00333 typedef union
00334 {
00335     _DeviceSetGet_t     Cmd;
00336     _DeviceSetGet_t     Rsp;
00337 }_SlDeviceMsgGet_u;
00338 
00339 const _SlCmdCtrl_t _SlDeviceGetCmdCtrl =
00340 {
00341     SL_OPCODE_DEVICE_DEVICEGET,
00342     sizeof(_DeviceSetGet_t),
00343     sizeof(_DeviceSetGet_t)
00344 };
00345 
00346 #if _SL_INCLUDE_FUNC(sl_DevGet)
00347 _i32 sl_DevGet(_u8 DeviceGetId, _u8 *pOption,_u8 *pConfigLen, _u8 *pValues)
00348 {
00349     _SlDeviceMsgGet_u         Msg;
00350     _SlCmdExt_t               CmdExt;
00351 
00352     if (*pConfigLen == 0)
00353     {
00354         return SL_EZEROLEN;
00355     }
00356 
00357     if( pOption )
00358     {
00359         CmdExt.TxPayloadLen = 0;
00360         CmdExt.RxPayloadLen = *pConfigLen;
00361         CmdExt.pTxPayload = NULL;
00362         CmdExt.pRxPayload = (_u8 *)pValues;
00363         CmdExt.ActualRxPayloadLen = 0;
00364 
00365         Msg.Cmd.DeviceSetId = DeviceGetId;
00366 
00367         Msg.Cmd.Option   = (_u16)*pOption;
00368 
00369         VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceGetCmdCtrl, &Msg, &CmdExt));
00370 
00371         if( pOption )
00372         {
00373             *pOption = (_u8)Msg.Rsp.Option;
00374         }
00375 
00376         if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) 
00377         {
00378             *pConfigLen = (_u8)CmdExt.RxPayloadLen;
00379             return SL_ESMALLBUF;
00380         }
00381         else
00382         {
00383             *pConfigLen = (_u8)CmdExt.ActualRxPayloadLen;
00384         }
00385 
00386         return (_i16)Msg.Rsp.Status;
00387     }
00388     else
00389     {
00390         return -1;
00391     }
00392 }
00393 #endif
00394 
00395 /******************************************************************************
00396 sl_DevSet
00397 ******************************************************************************/
00398 typedef union
00399 {
00400     _DeviceSetGet_t    Cmd;
00401     _BasicResponse_t   Rsp;
00402 }_SlDeviceMsgSet_u;
00403 
00404 const _SlCmdCtrl_t _SlDeviceSetCmdCtrl =
00405 {
00406     SL_OPCODE_DEVICE_DEVICESET,
00407     sizeof(_DeviceSetGet_t),
00408     sizeof(_BasicResponse_t)
00409 };
00410 
00411 #if _SL_INCLUDE_FUNC(sl_DevSet)
00412 _i32 sl_DevSet(_u8 DeviceSetId ,_u8 Option,_u8 ConfigLen, _u8 *pValues)
00413 {
00414     _SlDeviceMsgSet_u         Msg;
00415     _SlCmdExt_t               CmdExt;
00416 
00417     CmdExt.TxPayloadLen = (ConfigLen+3) & (~3);
00418     CmdExt.RxPayloadLen = 0;
00419     CmdExt.pTxPayload = (_u8 *)pValues;
00420     CmdExt.pRxPayload = NULL;
00421 
00422 
00423     Msg.Cmd.DeviceSetId    = DeviceSetId;
00424     Msg.Cmd.ConfigLen   = ConfigLen;
00425     Msg.Cmd.Option   = Option;
00426 
00427     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceSetCmdCtrl, &Msg, &CmdExt));
00428 
00429     return (_i16)Msg.Rsp.status;
00430 }
00431 #endif
00432 
00433 
00434 /******************************************************************************
00435 _SlDrvDeviceEventHandler - handles internally device async events
00436 ******************************************************************************/
00437 void _SlDrvDeviceEventHandler(void *pArgs)
00438 {
00439     _SlResponseHeader_t      *pHdr       = (_SlResponseHeader_t *)pArgs;
00440 
00441     switch(pHdr->GenHeader.Opcode)
00442     {
00443     case SL_OPCODE_DEVICE_INITCOMPLETE:
00444         _sl_HandleAsync_InitComplete(pHdr);
00445         break;
00446     case SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE:
00447         _sl_HandleAsync_Stop(pHdr);
00448         break;
00449     case  SL_OPCODE_DEVICE_DEVICEASYNCFATALERROR:
00450 #ifdef sl_GeneralEvtHdlr
00451         {
00452             _BasicResponse_t     *pMsgArgs   = (_BasicResponse_t *)_SL_RESP_ARGS_START(pHdr);
00453             SlDeviceEvent_t      devHandler;
00454             devHandler.Event = SL_DEVICE_FATAL_ERROR_EVENT;
00455             devHandler.EventData.deviceEvent.status = pMsgArgs->status & 0xFF;
00456             devHandler.EventData.deviceEvent.sender = (SlErrorSender_e)((pMsgArgs->status >> 8) & 0xFF);
00457             sl_GeneralEvtHdlr(&devHandler);
00458         }
00459 #endif
00460         break;
00461     default:
00462         SL_ERROR_TRACE2(MSG_306, "ASSERT: _SlDrvDeviceEventHandler : invalid opcode = 0x%x = %1", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode);
00463         VERIFY_PROTOCOL(0);
00464     }
00465 }
00466 
00467 
00468 /******************************************************************************
00469 sl_UartSetMode 
00470 ******************************************************************************/
00471 #ifdef SL_IF_TYPE_UART
00472 typedef union
00473 {
00474     _DevUartSetModeCommand_t      Cmd;
00475     _DevUartSetModeResponse_t     Rsp;
00476 }_SlUartSetModeMsg_u;
00477 
00478 const _SlCmdCtrl_t _SlUartSetModeCmdCtrl =
00479 {
00480     SL_OPCODE_DEVICE_SETUARTMODECOMMAND,
00481     sizeof(_DevUartSetModeCommand_t),
00482     sizeof(_DevUartSetModeResponse_t)
00483 };
00484 
00485 
00486 #if _SL_INCLUDE_FUNC(sl_UartSetMode)
00487 _i16 sl_UartSetMode(const SlUartIfParams_t* pUartParams)
00488 {
00489     _SlUartSetModeMsg_u Msg;
00490     _u32 magicCode = 0xFFFFFFFF;
00491 
00492     Msg.Cmd.BaudRate = pUartParams->BaudRate;
00493     Msg.Cmd.FlowControlEnable = pUartParams->FlowControlEnable;
00494 
00495 
00496     VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlUartSetModeCmdCtrl, &Msg, NULL));
00497 
00498     /* cmd response OK, we can continue with the handshake */
00499     if (SL_RET_CODE_OK == Msg.Rsp.status)
00500     {
00501         sl_IfMaskIntHdlr();
00502 
00503         /* Close the comm port */
00504         sl_IfClose(g_pCB->FD);
00505 
00506         /* Re-open the comm port */
00507         sl_IfOpen((void * )pUartParams, UART_IF_OPEN_FLAG_RE_OPEN);
00508 
00509         sl_IfUnMaskIntHdlr();
00510 
00511         /* send the magic code and wait for the response */
00512         sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4);
00513 
00514         magicCode = UART_SET_MODE_MAGIC_CODE;
00515         sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4);
00516 
00517         /* clear magic code */
00518         magicCode = 0;
00519 
00520         /* wait (blocking) till the magic code to be returned from device */
00521         sl_IfRead(g_pCB->FD, (_u8* )&magicCode, 4);
00522 
00523         /* check for the received magic code matching */
00524         if (UART_SET_MODE_MAGIC_CODE != magicCode)
00525         {
00526             _SL_ASSERT(0);
00527         }
00528     }
00529 
00530     return (_i16)Msg.Rsp.status;
00531 }
00532 #endif
00533 #endif
00534 
00535 /*!
00536     \brief This function handles general error events indication
00537 
00538     \param[in]      pDevEvent is the event passed to the handler
00539 
00540     \return         None
00541 */
00542 void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
00543 {
00544     /*
00545      * Most of the general errors are not FATAL are are to be handled
00546      * appropriately by the application
00547      */
00548 //    CLI_Write((_u8 *)" [GENERAL EVENT] \n\r");
00549     printf(" [GENERAL EVENT] \n\r");
00550 }