diff options
author | Damien George <damien.p.george@gmail.com> | 2015-02-21 19:52:07 +0000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2015-02-21 19:52:07 +0000 |
commit | 49c2ad4fb417b8f0a9d815ff3295fb1af94965f7 (patch) | |
tree | c8509c73c23216f937a7aaad7b2257e1c5d6a7b5 /drivers/cc3100/src/device.c | |
parent | 36e2845e3616de8de96741e9608fbb65ccd8091d (diff) | |
download | micropython-49c2ad4fb417b8f0a9d815ff3295fb1af94965f7.tar.gz micropython-49c2ad4fb417b8f0a9d815ff3295fb1af94965f7.zip |
cc3200: Move CC3100 driver from cc3200/simplelink to drivers/cc3100.
This commit will not build, it exists just to track changes.
Diffstat (limited to 'drivers/cc3100/src/device.c')
-rw-r--r-- | drivers/cc3100/src/device.c | 535 |
1 files changed, 535 insertions, 0 deletions
diff --git a/drivers/cc3100/src/device.c b/drivers/cc3100/src/device.c new file mode 100644 index 0000000000..95907cf7f9 --- /dev/null +++ b/drivers/cc3100/src/device.c @@ -0,0 +1,535 @@ +/* +* device.c - CC31xx/CC32xx Host Driver Implementation +* +* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + + + +/*****************************************************************************/ +/* Include files */ +/*****************************************************************************/ +#include "simplelink.h" +#include "protocol.h" +#include "flowcont.h" +#include "driver.h" + + +/*****************************************************************************/ +/* Internal functions */ +/*****************************************************************************/ + +_i16 _sl_GetStartResponseConvert(_u32 Status) +{ + switch(Status) + { + case INIT_STA_OK: + return ROLE_STA; + case INIT_STA_ERR: + return ROLE_STA_ERR; + case INIT_AP_OK: + return ROLE_AP; + case INIT_AP_ERR: + return ROLE_AP_ERR; + case INIT_P2P_OK: + return ROLE_P2P; + case INIT_P2P_ERR: + return ROLE_P2P_ERR; + default: + return (_i16)Status; + } +} + +/*****************************************************************************/ +/* API Functions */ +/*****************************************************************************/ + + + +/*****************************************************************************/ +/* sl_Task */ +/*****************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_Task) +void sl_Task(void) +{ +#ifdef _SlTaskEntry + _SlTaskEntry(); +#endif +} +#endif + +/*****************************************************************************/ +/* sl_Start */ +/*****************************************************************************/ +#if _SL_INCLUDE_FUNC(sl_Start) +_i16 sl_Start(const void* pIfHdl, _i8* pDevName, const P_INIT_CALLBACK pInitCallBack) +{ + _i16 ObjIdx = MAX_CONCURRENT_ACTIONS; + InitComplete_t AsyncRsp; + + /* Perform any preprocessing before enable networking services */ + sl_DeviceEnablePreamble(); + + /* ControlBlock init */ + _SlDrvDriverCBInit(); + + /* open the interface: usually SPI or UART */ + if (NULL == pIfHdl) + { + g_pCB->FD = sl_IfOpen((void *)pDevName, 0); + } + else + { + g_pCB->FD = (_SlFd_t)pIfHdl; + } + /* Use Obj to issue the command, if not available try later */ + ObjIdx = _SlDrvWaitForPoolObj(START_STOP_ID,SL_MAX_SOCKETS); + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp; + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + + if( g_pCB->FD >= 0) + { + sl_DeviceDisable(); + + sl_IfRegIntHdlr((SL_P_EVENT_HANDLER)_SlDrvRxIrqHandler, NULL); + + if(NULL != pInitCallBack) + { + g_pCB->pInitCallback = pInitCallBack; + } + sl_DeviceEnable(); + + if (NULL == pInitCallBack) + { + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + /*release Pool Object*/ + _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex); + return _sl_GetStartResponseConvert(AsyncRsp.Status); + } + } + + return (_i16)g_pCB->FD; + +} +#endif + +/*************************************************************************** +_sl_HandleAsync_InitComplete - handles init complete signalling to +a waiting object +****************************************************************************/ +void _sl_HandleAsync_InitComplete(void *pVoidBuf) +{ + InitComplete_t *pMsgArgs = (InitComplete_t *)_SL_RESP_ARGS_START(pVoidBuf); + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + if(g_pCB->pInitCallback) + { + g_pCB->pInitCallback(_sl_GetStartResponseConvert(pMsgArgs->Status)); + } + else + { + sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(InitComplete_t)); + OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj)); + } + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + + if(g_pCB->pInitCallback) + { + _SlDrvReleasePoolObj(g_pCB->FunctionParams.AsyncExt.ActionIndex); + } + +} + +/*************************************************************************** +_sl_HandleAsync_Stop - handles stop signalling to +a waiting object +****************************************************************************/ +void _sl_HandleAsync_Stop(void *pVoidBuf) +{ + _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pVoidBuf); + + VERIFY_SOCKET_CB(NULL != g_pCB->StopCB.pAsyncRsp); + + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + sl_Memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_BasicResponse_t)); + OSI_RET_OK_CHECK(sl_SyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj)); + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + return; +} + + +/***************************************************************************** +sl_stop +******************************************************************************/ +typedef union +{ + _DevStopCommand_t Cmd; + _BasicResponse_t Rsp; +}_SlStopMsg_u; + +const _SlCmdCtrl_t _SlStopCmdCtrl = +{ + SL_OPCODE_DEVICE_STOP_COMMAND, + sizeof(_DevStopCommand_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_Stop) +_i16 sl_Stop(_u16 timeout) +{ + _i16 RetVal=0; + _SlStopMsg_u Msg; + _BasicResponse_t AsyncRsp; + _i16 ObjIdx = MAX_CONCURRENT_ACTIONS; + /* if timeout is 0 the shutdown is forced immediately */ + if( 0 == timeout ) + { + sl_IfRegIntHdlr(NULL, NULL); + sl_DeviceDisable(); + RetVal = sl_IfClose(g_pCB->FD); + + } + else + { + /* let the device make the shutdown using the defined timeout */ + Msg.Cmd.Timeout = timeout; + /* Use Obj to issue the command, if not available try later */ + ObjIdx = _SlDrvWaitForPoolObj(START_STOP_ID,SL_MAX_SOCKETS); + if (MAX_CONCURRENT_ACTIONS == ObjIdx) + { + return SL_POOL_IS_EMPTY; + } + OSI_RET_OK_CHECK(sl_LockObjLock(&g_pCB->ProtectionLockObj, SL_OS_WAIT_FOREVER)); + + g_pCB->ObjPool[ObjIdx].pRespArgs = (_u8 *)&AsyncRsp; + + OSI_RET_OK_CHECK(sl_LockObjUnlock(&g_pCB->ProtectionLockObj)); + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlStopCmdCtrl, &Msg, NULL)); + + if(SL_OS_RET_CODE_OK == (_i16)Msg.Rsp.status) + { + OSI_RET_OK_CHECK(sl_SyncObjWait(&g_pCB->ObjPool[ObjIdx].SyncObj, SL_OS_WAIT_FOREVER)); + Msg.Rsp.status = AsyncRsp.status; + RetVal = Msg.Rsp.status; + } + + _SlDrvReleasePoolObj((_u8)ObjIdx); + + sl_IfRegIntHdlr(NULL, NULL); + sl_DeviceDisable(); + sl_IfClose(g_pCB->FD); + } + _SlDrvDriverCBDeinit(); + + return RetVal; +} +#endif + + +/***************************************************************************** +sl_EventMaskSet +*****************************************************************************/ +typedef union +{ + _DevMaskEventSetCommand_t Cmd; + _BasicResponse_t Rsp; +}_SlEventMaskSetMsg_u; + +const _SlCmdCtrl_t _SlEventMaskSetCmdCtrl = +{ + SL_OPCODE_DEVICE_EVENTMASKSET, + sizeof(_DevMaskEventSetCommand_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_EventMaskSet) +_i16 sl_EventMaskSet(_u8 EventClass , _u32 Mask) +{ + _SlEventMaskSetMsg_u Msg; + + Msg.Cmd.group = EventClass; + Msg.Cmd.mask = Mask; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskSetCmdCtrl, &Msg, NULL)); + + return (_i16)Msg.Rsp.status; +} +#endif + +/****************************************************************************** +sl_EventMaskGet +******************************************************************************/ +typedef union +{ + _DevMaskEventGetCommand_t Cmd; + _DevMaskEventGetResponse_t Rsp; +}_SlEventMaskGetMsg_u; + +const _SlCmdCtrl_t _SlEventMaskGetCmdCtrl = +{ + SL_OPCODE_DEVICE_EVENTMASKGET, + sizeof(_DevMaskEventGetCommand_t), + sizeof(_DevMaskEventGetResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_EventMaskGet) +_i16 sl_EventMaskGet(_u8 EventClass, _u32 *pMask) +{ + _SlEventMaskGetMsg_u Msg; + + Msg.Cmd.group = EventClass; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlEventMaskGetCmdCtrl, &Msg, NULL)); + + *pMask = Msg.Rsp.mask; + return SL_RET_CODE_OK; +} +#endif + + + +/****************************************************************************** +sl_DevGet +******************************************************************************/ + +typedef union +{ + _DeviceSetGet_t Cmd; + _DeviceSetGet_t Rsp; +}_SlDeviceMsgGet_u; + +const _SlCmdCtrl_t _SlDeviceGetCmdCtrl = +{ + SL_OPCODE_DEVICE_DEVICEGET, + sizeof(_DeviceSetGet_t), + sizeof(_DeviceSetGet_t) +}; + +#if _SL_INCLUDE_FUNC(sl_DevGet) +_i32 sl_DevGet(_u8 DeviceGetId, _u8 *pOption,_u8 *pConfigLen, _u8 *pValues) +{ + _SlDeviceMsgGet_u Msg; + _SlCmdExt_t CmdExt; + + if (*pConfigLen == 0) + { + return SL_EZEROLEN; + } + + if( pOption ) + { + CmdExt.TxPayloadLen = 0; + CmdExt.RxPayloadLen = *pConfigLen; + CmdExt.pTxPayload = NULL; + CmdExt.pRxPayload = (_u8 *)pValues; + CmdExt.ActualRxPayloadLen = 0; + + Msg.Cmd.DeviceSetId = DeviceGetId; + + Msg.Cmd.Option = (_u16)*pOption; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceGetCmdCtrl, &Msg, &CmdExt)); + + if( pOption ) + { + *pOption = (_u8)Msg.Rsp.Option; + } + + if (CmdExt.RxPayloadLen < CmdExt.ActualRxPayloadLen) + { + *pConfigLen = (_u8)CmdExt.RxPayloadLen; + return SL_ESMALLBUF; + } + else + { + *pConfigLen = (_u8)CmdExt.ActualRxPayloadLen; + } + + return (_i16)Msg.Rsp.Status; + } + else + { + return -1; + } +} +#endif + +/****************************************************************************** +sl_DevSet +******************************************************************************/ +typedef union +{ + _DeviceSetGet_t Cmd; + _BasicResponse_t Rsp; +}_SlDeviceMsgSet_u; + +const _SlCmdCtrl_t _SlDeviceSetCmdCtrl = +{ + SL_OPCODE_DEVICE_DEVICESET, + sizeof(_DeviceSetGet_t), + sizeof(_BasicResponse_t) +}; + +#if _SL_INCLUDE_FUNC(sl_DevSet) +_i32 sl_DevSet(_u8 DeviceSetId ,_u8 Option,_u8 ConfigLen, _u8 *pValues) +{ + _SlDeviceMsgSet_u Msg; + _SlCmdExt_t CmdExt; + + CmdExt.TxPayloadLen = (ConfigLen+3) & (~3); + CmdExt.RxPayloadLen = 0; + CmdExt.pTxPayload = (_u8 *)pValues; + CmdExt.pRxPayload = NULL; + + + Msg.Cmd.DeviceSetId = DeviceSetId; + Msg.Cmd.ConfigLen = ConfigLen; + Msg.Cmd.Option = Option; + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlDeviceSetCmdCtrl, &Msg, &CmdExt)); + + return (_i16)Msg.Rsp.status; +} +#endif + + +/****************************************************************************** +_SlDrvDeviceEventHandler - handles internally device async events +******************************************************************************/ +void _SlDrvDeviceEventHandler(void *pArgs) +{ + _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)pArgs; + + switch(pHdr->GenHeader.Opcode) + { + case SL_OPCODE_DEVICE_INITCOMPLETE: + _sl_HandleAsync_InitComplete(pHdr); + break; + case SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE: + _sl_HandleAsync_Stop(pHdr); + break; + case SL_OPCODE_DEVICE_DEVICEASYNCFATALERROR: +#ifdef sl_GeneralEvtHdlr + { + _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pHdr); + SlDeviceEvent_t devHandler; + devHandler.Event = SL_DEVICE_FATAL_ERROR_EVENT; + devHandler.EventData.deviceEvent.status = pMsgArgs->status & 0xFF; + devHandler.EventData.deviceEvent.sender = (SlErrorSender_e)((pMsgArgs->status >> 8) & 0xFF); + sl_GeneralEvtHdlr(&devHandler); + } +#endif + break; + default: + SL_ERROR_TRACE1(MSG_306, "ASSERT: _SlDrvDeviceEventHandler : invalid opcode = 0x%x", pHdr->GenHeader.Opcode); + VERIFY_PROTOCOL(0); + } +} + + +/****************************************************************************** +sl_UartSetMode +******************************************************************************/ +#ifdef SL_IF_TYPE_UART +typedef union +{ + _DevUartSetModeCommand_t Cmd; + _DevUartSetModeResponse_t Rsp; +}_SlUartSetModeMsg_u; + +const _SlCmdCtrl_t _SlUartSetModeCmdCtrl = +{ + SL_OPCODE_DEVICE_SETUARTMODECOMMAND, + sizeof(_DevUartSetModeCommand_t), + sizeof(_DevUartSetModeResponse_t) +}; + + +#if _SL_INCLUDE_FUNC(sl_UartSetMode) +_i16 sl_UartSetMode(const SlUartIfParams_t* pUartParams) +{ + _SlUartSetModeMsg_u Msg; + _u32 magicCode = 0xFFFFFFFF; + + Msg.Cmd.BaudRate = pUartParams->BaudRate; + Msg.Cmd.FlowControlEnable = pUartParams->FlowControlEnable; + + + VERIFY_RET_OK(_SlDrvCmdOp((_SlCmdCtrl_t *)&_SlUartSetModeCmdCtrl, &Msg, NULL)); + + /* cmd response OK, we can continue with the handshake */ + if (SL_RET_CODE_OK == Msg.Rsp.status) + { + sl_IfMaskIntHdlr(); + + /* Close the comm port */ + sl_IfClose(g_pCB->FD); + + /* Re-open the comm port */ + sl_IfOpen((void * )pUartParams, UART_IF_OPEN_FLAG_RE_OPEN); + + sl_IfUnMaskIntHdlr(); + + /* send the magic code and wait for the response */ + sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4); + + magicCode = UART_SET_MODE_MAGIC_CODE; + sl_IfWrite(g_pCB->FD, (_u8* )&magicCode, 4); + + /* clear magic code */ + magicCode = 0; + + /* wait (blocking) till the magic code to be returned from device */ + sl_IfRead(g_pCB->FD, (_u8* )&magicCode, 4); + + /* check for the received magic code matching */ + if (UART_SET_MODE_MAGIC_CODE != magicCode) + { + _SL_ASSERT(0); + } + } + + return (_i16)Msg.Rsp.status; +} +#endif +#endif + + |