CC3000 driver changes from David Sidrane

This commit is contained in:
Gregory Nutt 2013-10-16 11:59:26 -06:00
parent 48a8364267
commit 4e44868f12
14 changed files with 4593 additions and 4730 deletions

View file

@ -362,7 +362,7 @@ static inline int sst25_readid(struct sst25_dev_s *priv)
priv->nsectors = SST25_VF016_NSECTORS;
return OK;
/* Not implemented yet */
/* Support for this part is not implemented yet */
default:
break;

View file

@ -3,8 +3,54 @@
# see misc/tools/kconfig-language.txt.
#
config WL_CC3000_DUMMY
bool "CC3000 Wireless Module Dummy Test"
default n
config WL_CC3000
bool "CC3000 Wireless Module"
default n
select SPI
---help---
Enable support for the TI CC3000 Wifi Module
if WL_CC3000
config CC3000_MULTIPLE
bool "Multiple CC3000 Devices"
default n
---help---
Can be defined to support multiple CC3000 devices on board.
config CC3000_NPOLLWAITERS
int "Number poll waiters"
default 4
depends on !DISABLE_POLL
---help---
Maximum number of threads that can be waiting on poll()
config CC3000_SPIDEV
int "SPI bus number"
default 2
---help---
Selects the SPI bus number identying that SPI interface that
connects the CC3000 to the MCU.
config CC3000_DEVMINOR
int "Input device minor number"
default 0
---help---
The CC3000 device will be registered as /dev/wirelessN where N is the
value provided by this setting.
config CC3000_SPI_MODE
int "SPI mode"
default 0
range 0 3
---help---
Controls the SPI mode. The device should work in mode 0, but
sometimes you need to experiment.
config CC3000_SPI_FREQUENCY
int "SPI frequency"
default 16000000
---help---
Define to use a different SPI bus frequency.
endif

View file

@ -1,7 +1,7 @@
############################################################################
# drivers/wireless/Make.defs
#
# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
# Copyright (C) 2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -37,7 +37,8 @@ ifeq ($(CONFIG_WL_CC3000),y)
# Include cc3000 drivers
CSRCS += cc3000_common.c evnt_handler.c hci.c netapp.c nvmem.c security.c socket.c spi.c wlan.c
CSRCS += cc3000.c cc3000_common.c evnt_handler.c hci.c netapp.c nvmem.c
CSRCS += security.c socket.c spi.c wlan.c
# Include wireless devices build support

View file

@ -1,164 +1,153 @@
/*****************************************************************************
*
* cc3000_common.c.c - CC3000 Host Driver Implementation.
* Copyright (C) 2011 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.
*
*****************************************************************************/
//*****************************************************************************
//
//! \addtogroup common_api
//! @{
//
//*****************************************************************************
/******************************************************************************
* cc3000_common.c.c - CC3000 Host Driver Implementation.
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* Include files
* 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.
*
*****************************************************************************/
/******************************************************************************
* Included files
*****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <nuttx/wireless/cc3000/cc3000_common.h>
#include <nuttx/wireless/cc3000/socket.h>
#include <nuttx/wireless/cc3000/include/sys/socket.h>
#include <nuttx/wireless/cc3000/wlan.h>
#include <nuttx/wireless/cc3000/evnt_handler.h>
//*****************************************************************************
//
//! __error__
//!
//! @param pcFilename - file name, where error occurred
//! @param ulLine - line number, where error occurred
//!
//! @return none
//!
//! @brief stub function for ASSERT macro
//
//*****************************************************************************
void
__error__(char *pcFilename, unsigned long ulLine)
{
//TODO full up function
}
/*****************************************************************************
* Name:__error__
*
* Description:
* Stub function for ASSERT macro
*
* Input Parameters:
* pcFilename - file name, where error occurred
* ulLine - line number, where error occurred
*
* Returned Value:
* None
*
*****************************************************************************/
//*****************************************************************************
//
//! UINT32_TO_STREAM_f
//!
//! @param p pointer to the new stream
//! @param u32 pointer to the 32 bit
//!
//! @return pointer to the new stream
//!
//! @brief This function is used for copying 32 bit to stream
//! while converting to little endian format.
//
//*****************************************************************************
/*****************************************************************************
* Name: UINT32_TO_STREAM_f
*
* Description:
* This function is used for copying 32 bit to stream while converting to
* little endian format.
*
* Input Parameters:
* p pointer to the new stream
* u32 pointer to the 32 bit
*
* Returned Value:
* Pointer to the new stream
*
*****************************************************************************/
uint8_t* UINT32_TO_STREAM_f (uint8_t *p, unsigned long u32)
{
*(p)++ = (uint8_t)(u32);
*(p)++ = (uint8_t)((u32) >> 8);
*(p)++ = (uint8_t)((u32) >> 16);
*(p)++ = (uint8_t)((u32) >> 24);
return p;
*(p)++ = (uint8_t)(u32);
*(p)++ = (uint8_t)((u32) >> 8);
*(p)++ = (uint8_t)((u32) >> 16);
*(p)++ = (uint8_t)((u32) >> 24);
return p;
}
//*****************************************************************************
//
//! UINT16_TO_STREAM_f
//!
//! @param p pointer to the new stream
//! @param u32 pointer to the 16 bit
//!
//! @return pointer to the new stream
//!
//! @brief This function is used for copying 16 bit to stream
//! while converting to little endian format.
//
//*****************************************************************************
/*****************************************************************************
* Name: UINT16_TO_STREAM_f
*
* Description:
* This function is used for copying 16 bit to stream while converting to
* little endian format.
*
* Input Parameters:
* p pointer to the new stream
* u16 pointer to the 16 bit
*
* Returned Value:
* Pointer to the new stream
*
*****************************************************************************/
uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16)
{
*(p)++ = (uint8_t)(u16);
*(p)++ = (uint8_t)((u16) >> 8);
return p;
*(p)++ = (uint8_t)(u16);
*(p)++ = (uint8_t)((u16) >> 8);
return p;
}
//*****************************************************************************
//
//! STREAM_TO_UINT16_f
//!
//! @param p pointer to the stream
//! @param offset offset in the stream
//!
//! @return pointer to the new 16 bit
//!
//! @brief This function is used for copying received stream to
//! 16 bit in little endian format.
//
//*****************************************************************************
/*****************************************************************************
* Name: STREAM_TO_UINT16_f
*
* Description:
* This function is used for copying received stream to 16 bit in little
* endian format.
*
* Input Parameters:
* p pointer to the stream
* offset offset in the stream
*
* Returned Value:
* Pointer to the new 16 bit
*
*****************************************************************************/
uint16_t STREAM_TO_UINT16_f(char* p, uint16_t offset)
{
return (uint16_t)((uint16_t)((uint16_t)
(*(p + offset + 1)) << 8) + (uint16_t)(*(p + offset)));
return (uint16_t)((uint16_t)((uint16_t)
(*(p + offset + 1)) << 8) + (uint16_t)(*(p + offset)));
}
//*****************************************************************************
//
//! STREAM_TO_UINT32_f
//!
//! @param p pointer to the stream
//! @param offset offset in the stream
//!
//! @return pointer to the new 32 bit
//!
//! @brief This function is used for copying received stream to
//! 32 bit in little endian format.
//
//*****************************************************************************
/*****************************************************************************
* Name: STREAM_TO_UINT32_f
*
* Description:
* This function is used for copying received stream to 32 bit in little
* endian format.
*
* Input Parameters:
* p pointer to the stream
* offset offset in the stream
*
* Returned Value:
* Pointer to the new 32 bit
*
*****************************************************************************/
unsigned long STREAM_TO_UINT32_f(char* p, uint16_t offset)
{
return (unsigned long)((unsigned long)((unsigned long)
(*(p + offset + 3)) << 24) + (unsigned long)((unsigned long)
(*(p + offset + 2)) << 16) + (unsigned long)((unsigned long)
(*(p + offset + 1)) << 8) + (unsigned long)(*(p + offset)));
return (unsigned long)((unsigned long)((unsigned long)
(*(p + offset + 3)) << 24) + (unsigned long)((unsigned long)
(*(p + offset + 2)) << 16) + (unsigned long)((unsigned long)
(*(p + offset + 1)) << 8) + (unsigned long)(*(p + offset)));
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

File diff suppressed because it is too large Load diff

View file

@ -1,230 +1,236 @@
/*****************************************************************************
*
* hci.c - CC3000 Host Driver Implementation.
* Copyright (C) 2011 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.
*
*****************************************************************************/
* hci.c - CC3000 Host Driver Implementation.
* Copyright (C) 2011 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.
*
*****************************************************************************/
//*****************************************************************************
//
//! \addtogroup hci_app
//! @{
//
//*****************************************************************************
/******************************************************************************
* Included Files
******************************************************************************/
#include <string.h>
#include <nuttx/wireless/cc3000/cc3000_common.h>
#include <nuttx/wireless/cc3000/hci.h>
#include <nuttx/wireless/cc3000/spi.h>
#include "spi.h"
#include <nuttx/wireless/cc3000/evnt_handler.h>
#include <nuttx/wireless/cc3000/wlan.h>
#define SL_PATCH_PORTION_SIZE (1000)
/******************************************************************************
* Pre-processor Definitions
******************************************************************************/
#define SL_PATCH_PORTION_SIZE (1000)
//*****************************************************************************
//
//! hci_command_send
//!
//! @param usOpcode command operation code
//! @param pucBuff pointer to the command's arguments buffer
//! @param ucArgsLength length of the arguments
//!
//! @return none
//!
//! @brief Initiate an HCI command.
//
//*****************************************************************************
uint16_t
hci_command_send(uint16_t usOpcode, uint8_t *pucBuff,
uint8_t ucArgsLength)
{
uint8_t *stream;
stream = (pucBuff + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_CMND);
stream = UINT16_TO_STREAM(stream, usOpcode);
UINT8_TO_STREAM(stream, ucArgsLength);
//Update the opcode of the event we will be waiting for
SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE);
return(0);
}
/******************************************************************************
* Public Functions
******************************************************************************/
/******************************************************************************
* Name: hci_command_send
*
* Description:
* Initiate an HCI command.
*
* Input Parameters:
* usOpcode command operation code
* pucBuff pointer to the command's arguments buffer
* ucArgsLength length of the arguments
*
* Returned Value:
* Zero
*
*****************************************************************************/
//*****************************************************************************
//
//! hci_data_send
//!
//! @param usOpcode command operation code
//! @param ucArgs pointer to the command's arguments buffer
//! @param usArgsLength length of the arguments
//! @param ucTail pointer to the data buffer
//! @param usTailLength buffer length
//!
//! @return none
//!
//! @brief Initiate an HCI data write operation
//
//*****************************************************************************
long
hci_data_send(uint8_t ucOpcode,
uint8_t *ucArgs,
uint16_t usArgsLength,
uint16_t usDataLength,
const uint8_t *ucTail,
uint16_t usTailLength)
uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, uint8_t ucArgsLength)
{
uint8_t *stream;
stream = ((ucArgs) + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
UINT8_TO_STREAM(stream, ucOpcode);
UINT8_TO_STREAM(stream, usArgsLength);
stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength);
// Send the packet over the SPI
SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength);
return(ESUCCESS);
uint8_t *stream;
stream = (pucBuff + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_CMND);
stream = UINT16_TO_STREAM(stream, usOpcode);
UINT8_TO_STREAM(stream, ucArgsLength);
/* Update the opcode of the event we will be waiting for */
SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE);
return 0;
}
/******************************************************************************
* Name: hci_data_send
*
* Description:
*
*
* Input Parameters:
* usOpcode command operation code
* ucArgs pointer to the command's arguments buffer
* usArgsLength length of the arguments
* ucTail pointer to the data buffer
* usTailLength buffer length
*
* Returned Value:
* None
*
*****************************************************************************/
long hci_data_send(uint8_t ucOpcode, uint8_t *ucArgs, uint16_t usArgsLength,
uint16_t usDataLength, const uint8_t *ucTail,
uint16_t usTailLength)
{
uint8_t *stream;
stream = ((ucArgs) + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
UINT8_TO_STREAM(stream, ucOpcode);
UINT8_TO_STREAM(stream, usArgsLength);
stream = UINT16_TO_STREAM(stream, usArgsLength + usDataLength + usTailLength);
/* Send the packet over the SPI */
SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength);
return ESUCCESS;
}
/******************************************************************************
* Name: hci_data_command_send
*
* Description:
* Prepeare HCI header and initiate an HCI data write operation
*
* Input Parameters:
* usOpcode command operation code
* pucBuff pointer to the data buffer
* ucArgsLength arguments length
* ucDataLength data length
*
* Returned Value:
* None
*
*****************************************************************************/
//*****************************************************************************
//
//! hci_data_command_send
//!
//! @param usOpcode command operation code
//! @param pucBuff pointer to the data buffer
//! @param ucArgsLength arguments length
//! @param ucDataLength data length
//!
//! @return none
//!
//! @brief Prepeare HCI header and initiate an HCI data write operation
//
//*****************************************************************************
void hci_data_command_send(uint16_t usOpcode, uint8_t *pucBuff,
uint8_t ucArgsLength,uint16_t ucDataLength)
{
uint8_t *stream = (pucBuff + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
UINT8_TO_STREAM(stream, usOpcode);
UINT8_TO_STREAM(stream, ucArgsLength);
stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength);
// Send the command over SPI on data channel
SpiWrite(pucBuff, ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE);
return;
uint8_t ucArgsLength,uint16_t ucDataLength)
{
uint8_t *stream = (pucBuff + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_DATA);
UINT8_TO_STREAM(stream, usOpcode);
UINT8_TO_STREAM(stream, ucArgsLength);
stream = UINT16_TO_STREAM(stream, ucArgsLength + ucDataLength);
/* Send the command over SPI on data channel */
SpiWrite(pucBuff,
ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE);
}
//*****************************************************************************
//
//! hci_patch_send
//!
//! @param usOpcode command operation code
//! @param pucBuff pointer to the command's arguments buffer
//! @param patch pointer to patch content buffer
//! @param usDataLength data length
//!
//! @return none
//!
//! @brief Prepeare HCI header and initiate an HCI patch write operation
//
//*****************************************************************************
void
hci_patch_send(uint8_t ucOpcode, uint8_t *pucBuff, char *patch, uint16_t usDataLength)
{
uint8_t *data_ptr = (pucBuff + SPI_HEADER_SIZE);
uint16_t usTransLength;
uint8_t *stream = (pucBuff + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_PATCH);
UINT8_TO_STREAM(stream, ucOpcode);
stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
if (usDataLength <= SL_PATCH_PORTION_SIZE)
{
UINT16_TO_STREAM(stream, usDataLength);
stream = UINT16_TO_STREAM(stream, usDataLength);
memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength);
// Update the opcode of the event we will be waiting for
SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE);
}
else
{
usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE);
UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE);
memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE);
usDataLength -= SL_PATCH_PORTION_SIZE;
patch += SL_PATCH_PORTION_SIZE;
// Update the opcode of the event we will be waiting for
SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE);
while (usDataLength)
{
if (usDataLength <= SL_PATCH_PORTION_SIZE)
{
usTransLength = usDataLength;
usDataLength = 0;
}
else
{
usTransLength = SL_PATCH_PORTION_SIZE;
usDataLength -= usTransLength;
}
*(uint16_t *)data_ptr = usTransLength;
memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength);
patch += usTransLength;
// Update the opcode of the event we will be waiting for
SpiWrite((uint8_t *)data_ptr, usTransLength + sizeof(usTransLength));
}
}
}
/******************************************************************************
* Name: hci_patch_send
*
* Description:
* Prepeare HCI header and initiate an HCI patch write operation
*
* Input Parameters:
* usOpcode command operation code
* pucBuff pointer to the command's arguments buffer
* patch pointer to patch content buffer
* usDataLength data length
*
* Returned Value:
* None
*
*****************************************************************************/
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//
//*****************************************************************************
void hci_patch_send(uint8_t ucOpcode, uint8_t *pucBuff, char *patch,
uint16_t usDataLength)
{
uint8_t *data_ptr = (pucBuff + SPI_HEADER_SIZE);
uint16_t usTransLength;
uint8_t *stream = (pucBuff + SPI_HEADER_SIZE);
UINT8_TO_STREAM(stream, HCI_TYPE_PATCH);
UINT8_TO_STREAM(stream, ucOpcode);
stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
if (usDataLength <= SL_PATCH_PORTION_SIZE)
{
UINT16_TO_STREAM(stream, usDataLength);
stream = UINT16_TO_STREAM(stream, usDataLength);
memcpy((pucBuff + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, usDataLength);
/* Update the opcode of the event we will be waiting for */
SpiWrite(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE);
}
else
{
usTransLength = (usDataLength/SL_PATCH_PORTION_SIZE);
UINT16_TO_STREAM(stream,
usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE +
usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE);
memcpy(pucBuff + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch,
SL_PATCH_PORTION_SIZE);
usDataLength -= SL_PATCH_PORTION_SIZE;
patch += SL_PATCH_PORTION_SIZE;
/* Update the opcode of the event we will be waiting for */
SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE);
while (usDataLength)
{
if (usDataLength <= SL_PATCH_PORTION_SIZE)
{
usTransLength = usDataLength;
usDataLength = 0;
}
else
{
usTransLength = SL_PATCH_PORTION_SIZE;
usDataLength -= usTransLength;
}
*(uint16_t *)data_ptr = usTransLength;
memcpy(data_ptr + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch,
usTransLength);
patch += usTransLength;
/* Update the opcode of the event we will be waiting for */
SpiWrite((uint8_t *)data_ptr, usTransLength + sizeof(usTransLength));
}
}
}

View file

@ -12,23 +12,23 @@
*
* 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
* 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
* 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
* 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
* 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.
*
*****************************************************************************/

View file

@ -1,44 +1,52 @@
/*****************************************************************************
*
* netapp.c - CC3000 Host Driver Implementation.
* Copyright (C) 2011 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.
*
*****************************************************************************/
* netapp.c - CC3000 Host Driver Implementation.
* Copyright (C) 2011 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.
*
*****************************************************************************/
/******************************************************************************
* Included Files
******************************************************************************/
#include <string.h>
#include <nuttx/wireless/cc3000/netapp.h>
#include <nuttx/wireless/cc3000/hci.h>
#include <nuttx/wireless/cc3000/socket.h>
#include <nuttx/wireless/cc3000/include/sys/socket.h>
#include <nuttx/wireless/cc3000/evnt_handler.h>
#include <nuttx/wireless/cc3000/nvmem.h>
/******************************************************************************
* Pre-processor Definitions
******************************************************************************/
#define MIN_TIMER_VAL_SECONDS 20
#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \
{ \
@ -46,414 +54,452 @@
}
#define NETAPP_DHCP_PARAMS_LEN (20)
#define NETAPP_SET_TIMER_PARAMS_LEN (20)
#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4)
#define NETAPP_PING_SEND_PARAMS_LEN (16)
#define NETAPP_DHCP_PARAMS_LEN (20)
#define NETAPP_SET_TIMER_PARAMS_LEN (20)
#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4)
#define NETAPP_PING_SEND_PARAMS_LEN (16)
/******************************************************************************
* Public Functions
******************************************************************************/
/******************************************************************************
* Name: netapp_config_mac_adrress
*
* Description:
* Configure device MAC address and store it in NVMEM. The value of the MAC
* address configured through the API will be stored in CC3000 non volatile
* memory, thus preserved over resets.
*
* Input Parameters:
* mac device mac address, 6 bytes. Saved: yes
*
* Returned Value:
* Return on success 0, otherwise error.
*
*****************************************************************************/
//*****************************************************************************
//
//! netapp_config_mac_adrress
//!
//! @param mac device mac address, 6 bytes. Saved: yes
//!
//! @return return on success 0, otherwise error.
//!
//! @brief Configure device MAC address and store it in NVMEM.
//! The value of the MAC address configured through the API will
//! be stored in CC3000 non volatile memory, thus preserved
//! over resets.
//
//*****************************************************************************
long netapp_config_mac_adrress(uint8_t * mac)
{
return nvmem_set_mac_address(mac);
return nvmem_set_mac_address(mac);
}
//*****************************************************************************
//
//! netapp_dhcp
//!
//! @param aucIP device mac address, 6 bytes. Saved: yes
//! @param aucSubnetMask device mac address, 6 bytes. Saved: yes
//! @param aucDefaultGateway device mac address, 6 bytes. Saved: yes
//! @param aucDNSServer device mac address, 6 bytes. Saved: yes
//!
//! @return return on success 0, otherwise error.
//!
//! @brief netapp_dhcp is used to configure the network interface,
//! static or dynamic (DHCP).\n In order to activate DHCP mode,
//! aucIP, aucSubnetMask, aucDefaultGateway must be 0.
//! The default mode of CC3000 is DHCP mode.
//! Note that the configuration is saved in non volatile memory
//! and thus preserved over resets.
//!
//! @note If the mode is altered a reset of CC3000 device is required
//! in order to apply changes.\nAlso note that asynchronous event
//! of DHCP_EVENT, which is generated when an IP address is
//! allocated either by the DHCP server or due to static
//! allocation is generated only upon a connection to the
//! AP was established.
//!
//*****************************************************************************
long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer)
/******************************************************************************
* Name: netapp_dhcp
*
* Description:
* netapp_dhcp is used to configure the network interface, static or
* dynamic (DHCP).\n In order to activate DHCP mode, aucIP, aucSubnetMask,
* aucDefaultGateway must be 0. The default mode of CC3000 is DHCP mode. Note
* that the configuration is saved in non volatile memory and thus preserved
* over resets.
*
* NOTE: If the mode is altered a reset of CC3000 device is required in order
* to apply changes.\nAlso note that asynchronous event of DHCP_EVENT, which
* is generated when an IP address is allocated either by the DHCP server or
* due to static allocation is generated only upon a connection to the AP was
* established.
*
* Input Parameters:
* aucIP device mac address, 6 bytes. Saved: yes
* aucSubnetMask device mac address, 6 bytes. Saved: yes
* aucDefaultGateway device mac address, 6 bytes. Saved: yes
* aucDNSServer device mac address, 6 bytes. Saved: yes
*
* Returned Value:
* Return on success 0, otherwise error.
*
*****************************************************************************/
long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,
unsigned long *aucDefaultGateway, unsigned long *aucDNSServer)
{
int8_t scRet;
uint8_t *ptr;
uint8_t *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
ARRAY_TO_STREAM(args,aucIP,4);
ARRAY_TO_STREAM(args,aucSubnetMask,4);
ARRAY_TO_STREAM(args,aucDefaultGateway,4);
args = UINT32_TO_STREAM(args, 0);
ARRAY_TO_STREAM(args,aucDNSServer,4);
// Initiate a HCI command
hci_command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN);
// Wait for command complete event
SimpleLinkWaitEvent(HCI_NETAPP_DHCP, &scRet);
return(scRet);
int8_t scRet;
uint8_t *ptr;
uint8_t *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
/* Fill in temporary command buffer */
ARRAY_TO_STREAM(args,aucIP,4);
ARRAY_TO_STREAM(args,aucSubnetMask,4);
ARRAY_TO_STREAM(args,aucDefaultGateway,4);
args = UINT32_TO_STREAM(args, 0);
ARRAY_TO_STREAM(args,aucDNSServer,4);
/* Initiate a HCI command */
hci_command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN);
/* Wait for command complete event */
SimpleLinkWaitEvent(HCI_NETAPP_DHCP, &scRet);
return(scRet);
}
//*****************************************************************************
//
//! netapp_timeout_values
//!
//! @param aucDHCP DHCP lease time request, also impact
//! the DHCP renew timeout. Range: [0-0xffffffff] seconds,
//! 0 or 0xffffffff == infinity lease timeout.
//! Resolution:10 seconds. Influence: only after
//! reconnecting to the AP.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 14400 seconds.
//!
//! @param aucARP ARP refresh timeout, if ARP entry is not updated by
//! incoming packet, the ARP entry will be deleted by
//! the end of the timeout.
//! Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout
//! Resolution: 10 seconds. Influence: on runtime.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 3600 seconds.
//!
//! @param aucKeepalive Keepalive event sent by the end of keepalive timeout
//! Range: [0-0xffffffff] seconds, 0 == infinity timeout
//! Resolution: 10 seconds.
//! Influence: on runtime.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 10 seconds.
//!
//! @param aucInactivity Socket inactivity timeout, socket timeout is
//! refreshed by incoming or outgoing packet, by the
//! end of the socket timeout the socket will be closed
//! Range: [0-0xffffffff] sec, 0 == infinity timeout.
//! Resolution: 10 seconds. Influence: on runtime.
//! Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
//! The parameter is saved into the CC3000 NVMEM.
//! The default value on CC3000 is 60 seconds.
//!
//! @return return on success 0, otherwise error.
//!
//! @brief Set new timeout values. Function set new timeout values for:
//! DHCP lease timeout, ARP refresh timeout, keepalive event
//! timeout and socket inactivity timeout
//!
//! @note If a parameter set to non zero value which is less than 20s,
//! it will be set automatically to 20s.
//!
//*****************************************************************************
/******************************************************************************
* Name: netapp_timeout_values
*
* Description:
* Set new timeout values. Function set new timeout values for: DHCP lease
* timeout, ARP refresh timeout, keepalive event timeout and socket
* inactivity timeout
*
* NOTE: If a parameter set to non zero value which is less than 20s, it will
* be set automatically to 20s.
*
* Input Parameters:
* aucDHCP DHCP lease time request, also impact the DHCP renew timeout.
* Range: [0-0xffffffff] seconds, 0 or 0xffffffff == infinity
* lease timeout.
* Resolution: 10 seconds.
* Influence: only after reconnecting to the AP
* Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.
* The parameter is saved into the CC3000 NVMEM. The default
* value on CC3000 is 14400 seconds.
* aucARP ARP refresh timeout, if ARP entry is not updated by incoming
* packet, the ARP entry will be deleted by the end of the
* timeout.
* Range: [0-0xffffffff] seconds, 0 == infinity ARP timeout
* Resolution: 10 seconds.
* Influence: on runtime.
* Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.
* The parameter is saved into the CC3000 NVMEM. The default
* value on CC3000 is 3600 seconds.
* aucKeepalive Keepalive event sent by the end of keepalive timeout
* Range: [0-0xffffffff] seconds, 0 == infinity timeout
* Resolution: 10 seconds.
* Influence: on runtime.
* Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
* The parameter is saved into the CC3000 NVMEM. The default
* value on CC3000 is 10 seconds.
* aucInactivity Socket inactivity timeout, socket timeout is refreshed by
* incoming or outgoing packet, by the end of the socket
* timeout the socket will be closed
* Range: [0-0xffffffff] sec, 0 == infinity timeout.
* Resolution: 10 seconds. Influence: on runtime.
* Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec
* The parameter is saved into the CC3000 NVMEM. The default
* value on CC3000 is 60 seconds.
*
* Returned Value:
* Return on success 0, otherwise error.
*
*****************************************************************************/
#ifndef CC3000_TINY_DRIVER
long
netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity)
long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,
unsigned long *aucKeepalive,
unsigned long *aucInactivity)
{
int8_t scRet;
uint8_t *ptr;
uint8_t *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
// Set minimal values of timers
MIN_TIMER_SET(*aucDHCP)
MIN_TIMER_SET(*aucARP)
MIN_TIMER_SET(*aucKeepalive)
MIN_TIMER_SET(*aucInactivity)
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, *aucDHCP);
args = UINT32_TO_STREAM(args, *aucARP);
args = UINT32_TO_STREAM(args, *aucKeepalive);
args = UINT32_TO_STREAM(args, *aucInactivity);
// Initiate a HCI command
hci_command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN);
// Wait for command complete event
SimpleLinkWaitEvent(HCI_NETAPP_SET_TIMERS, &scRet);
return(scRet);
int8_t scRet;
uint8_t *ptr;
uint8_t *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
/* Set minimal values of timers */
MIN_TIMER_SET(*aucDHCP)
MIN_TIMER_SET(*aucARP)
MIN_TIMER_SET(*aucKeepalive)
MIN_TIMER_SET(*aucInactivity)
/* Fill in temporary command buffer */
args = UINT32_TO_STREAM(args, *aucDHCP);
args = UINT32_TO_STREAM(args, *aucARP);
args = UINT32_TO_STREAM(args, *aucKeepalive);
args = UINT32_TO_STREAM(args, *aucInactivity);
/* Initiate a HCI command */
hci_command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN);
/* Wait for command complete event */
SimpleLinkWaitEvent(HCI_NETAPP_SET_TIMERS, &scRet);
return scRet;
}
#endif
//*****************************************************************************
//
//! netapp_ping_send
//!
//! @param ip destination IP address
//! @param pingAttempts number of echo requests to send
//! @param pingSize send buffer size which may be up to 1400 bytes
//! @param pingTimeout Time to wait for a response,in milliseconds.
//!
//! @return return on success 0, otherwise error.
//!
//! @brief send ICMP ECHO_REQUEST to network hosts
//!
//! @note If an operation finished successfully asynchronous ping report
//! event will be generated. The report structure is as defined
//! by structure netapp_pingreport_args_t.
//!
//! @warning Calling this function while a previous Ping Requests are in
//! progress will stop the previous ping request.
//*****************************************************************************
/******************************************************************************
* Name: netapp_ping_send
*
* Description:
* Send ICMP ECHO_REQUEST to network hosts
*
* NOTE: If an operation finished successfully asynchronous ping report event
* will be generated. The report structure is as defined by structure
* netapp_pingreport_args_t.
*
* WARNING: Calling this function while a previous Ping Requests are in
* progress will stop the previous ping request.
*
* Input Parameters:
* ip destination IP address
* pingAttempts number of echo requests to send
* pingSize send buffer size which may be up to 1400 bytes
* pingTimeout Time to wait for a response,in milliseconds.
*
* Returned Value:
* Return on success 0, otherwise error.
*
*****************************************************************************/
#ifndef CC3000_TINY_DRIVER
long
netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts, unsigned long ulPingSize, unsigned long ulPingTimeout)
long netapp_ping_send(unsigned long *ip, unsigned long ulPingAttempts,
unsigned long ulPingSize, unsigned long ulPingTimeout)
{
int8_t scRet;
uint8_t *ptr, *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
// Fill in temporary command buffer
args = UINT32_TO_STREAM(args, *ip);
args = UINT32_TO_STREAM(args, ulPingAttempts);
args = UINT32_TO_STREAM(args, ulPingSize);
args = UINT32_TO_STREAM(args, ulPingTimeout);
// Initiate a HCI command
hci_command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN);
// Wait for command complete event
SimpleLinkWaitEvent(HCI_NETAPP_PING_SEND, &scRet);
return(scRet);
int8_t scRet;
uint8_t *ptr, *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
/* Fill in temporary command buffer */
args = UINT32_TO_STREAM(args, *ip);
args = UINT32_TO_STREAM(args, ulPingAttempts);
args = UINT32_TO_STREAM(args, ulPingSize);
args = UINT32_TO_STREAM(args, ulPingTimeout);
/* Initiate a HCI command */
hci_command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN);
/* Wait for command complete event */
SimpleLinkWaitEvent(HCI_NETAPP_PING_SEND, &scRet);
return scRet;
}
#endif
//*****************************************************************************
//
//! netapp_ping_report
//!
//! @param none
//!
//! @return none
//!
//! @brief Request for ping status. This API triggers the CC3000 to send
//! asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT.
//! This event will carry the report structure:
//! netapp_pingreport_args_t. This structure is filled in with ping
//! results up till point of triggering API.
//! netapp_pingreport_args_t:\n packets_sent - echo sent,
//! packets_received - echo reply, min_round_time - minimum
//! round time, max_round_time - max round time,
//! avg_round_time - average round time
//!
//! @note When a ping operation is not active, the returned structure
//! fields are 0.
//!
//*****************************************************************************
/******************************************************************************
* Name: netapp_ping_report
*
* Description:
* Request for ping status. This API triggers the CC3000 to send asynchronous
* events: HCI_EVNT_WLAN_ASYNC_PING_REPORT. This event will carry the report
* structure: netapp_pingreport_args_t. This structure is filled in with ping
* results up till point of triggering API.
*
* netapp_pingreport_args_t:
* packets_sent - echo sent,
* packets_received - echo reply
* min_round_time - minimum round time,
* max_round_time - max round time,
* avg_round_time - average round time
*
* NOTE: When a ping operation is not active, the returned structure fields
* are 0.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
*****************************************************************************/
#ifndef CC3000_TINY_DRIVER
void netapp_ping_report(void)
{
uint8_t *ptr;
ptr = tSLInformation.pucTxCommandBuffer;
int8_t scRet;
scRet = EFAIL;
// Initiate a HCI command
hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0);
// Wait for command complete event
SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet);
uint8_t *ptr;
ptr = tSLInformation.pucTxCommandBuffer;
int8_t scRet;
scRet = EFAIL;
/* Initiate a HCI command */
hci_command_send(HCI_NETAPP_PING_REPORT, ptr, 0);
/* Wait for command complete event */
SimpleLinkWaitEvent(HCI_NETAPP_PING_REPORT, &scRet);
}
#endif
//*****************************************************************************
//
//! netapp_ping_stop
//!
//! @param none
//!
//! @return On success, zero is returned. On error, -1 is returned.
//!
//! @brief Stop any ping request.
//!
//!
//*****************************************************************************
/******************************************************************************
* Name: netapp_ping_stop
*
* Description:
* Stop any ping request.
*
* Input Parameters:
* None
*
* Returned Value:
* On success, zero is returned. On error, -1 is returned.
*
*****************************************************************************/
#ifndef CC3000_TINY_DRIVER
long netapp_ping_stop(void)
{
int8_t scRet;
uint8_t *ptr;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
// Initiate a HCI command
hci_command_send(HCI_NETAPP_PING_STOP, ptr, 0);
// Wait for command complete event
SimpleLinkWaitEvent(HCI_NETAPP_PING_STOP, &scRet);
return(scRet);
int8_t scRet;
uint8_t *ptr;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
/* Initiate a HCI command */
hci_command_send(HCI_NETAPP_PING_STOP, ptr, 0);
/* Wait for command complete event */
SimpleLinkWaitEvent(HCI_NETAPP_PING_STOP, &scRet);
return(scRet);
}
#endif
//*****************************************************************************
//
//! netapp_ipconfig
//!
//! @param[out] ipconfig This argument is a pointer to a
//! tNetappIpconfigRetArgs structure. This structure is
//! filled in with the network interface configuration.
//! tNetappIpconfigRetArgs:\n aucIP - ip address,
//! aucSubnetMask - mask, aucDefaultGateway - default
//! gateway address, aucDHCPServer - dhcp server address
//! aucDNSServer - dns server address, uaMacAddr - mac
//! address, uaSSID - connected AP ssid
//!
//! @return none
//!
//! @brief Obtain the CC3000 Network interface information.
//! Note that the information is available only after the WLAN
//! connection was established. Calling this function before
//! associated, will cause non-defined values to be returned.
//!
//! @note The function is useful for figuring out the IP Configuration of
//! the device when DHCP is used and for figuring out the SSID of
//! the Wireless network the device is associated with.
//!
//*****************************************************************************
/******************************************************************************
* Name: netapp_ipconfig
*
* Description:
* Obtain the CC3000 Network interface information. Note that the information
* is available only after the WLAN connection was established. Calling this
* function before associated, will cause non-defined values to be returned.
*
* NOTE: The function is useful for figuring out the IP Configuration of the
* device when DHCP is used and for figuring out the SSID of the Wireless
* network the device is associated with.
*
* Input Parameters:
* ipconfig This argument is a pointer to a tNetappIpconfigRetArgs structure.
* This structure is filled in with the network interface configuration.
*
* tNetappIpconfigRetArgs:
* aucIP - ip address,
* aucSubnetMask - mask,
* aucDefaultGateway - default gateway address
* aucDHCPServer - dhcp server address
* aucDNSServer - dns server address
* uaMacAddr - mac
* address, uaSSID - connected AP ssid
*
* Returned Value:
* None
*
*****************************************************************************/
#ifndef CC3000_TINY_DRIVER
void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )
void netapp_ipconfig(tNetappIpconfigRetArgs * ipconfig)
{
uint8_t *ptr;
ptr = tSLInformation.pucTxCommandBuffer;
// Initiate a HCI command
hci_command_send(HCI_NETAPP_IPCONFIG, ptr, 0);
// Wait for command complete event
SimpleLinkWaitEvent(HCI_NETAPP_IPCONFIG, ipconfig );
uint8_t *ptr;
ptr = tSLInformation.pucTxCommandBuffer;
/* Initiate a HCI command */
hci_command_send(HCI_NETAPP_IPCONFIG, ptr, 0);
/* Wait for command complete event */
SimpleLinkWaitEvent(HCI_NETAPP_IPCONFIG, ipconfig);
}
#else
void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )
void netapp_ipconfig(tNetappIpconfigRetArgs * ipconfig)
{
}
#endif
//*****************************************************************************
//
//! netapp_arp_flush
//!
//! @param none
//!
//! @return none
//!
//! @brief Flushes ARP table
//!
//*****************************************************************************
/******************************************************************************
* Name: netapp_arp_flush
*
* Description:
* Flushes ARP table
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
*****************************************************************************/
#ifndef CC3000_TINY_DRIVER
long netapp_arp_flush(void)
{
int8_t scRet;
uint8_t *ptr;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
// Initiate a HCI command
hci_command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0);
// Wait for command complete event
SimpleLinkWaitEvent(HCI_NETAPP_ARP_FLUSH, &scRet);
return(scRet);
int8_t scRet;
uint8_t *ptr;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
/* Initiate a HCI command */
hci_command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0);
/* Wait for command complete event */
SimpleLinkWaitEvent(HCI_NETAPP_ARP_FLUSH, &scRet);
return scRet;
}
#endif
//*****************************************************************************
//
//! netapp_set_debug_level
//!
//! @param[in] level debug level. Bitwise [0-8],
//! 0(disable)or 1(enable).\n Bitwise map: 0 - Critical
//! message, 1 information message, 2 - core messages, 3 -
//! HCI messages, 4 - Network stack messages, 5 - wlan
//! messages, 6 - wlan driver messages, 7 - epprom messages,
//! 8 - general messages. Default: 0x13f. Saved: no
//!
//! @return On success, zero is returned. On error, -1 is returned
//!
//! @brief Debug messages sent via the UART debug channel, this function
//! enable/disable the debug level
//!
//*****************************************************************************
/******************************************************************************
* Name: netapp_set_debug_level
*
* Description:
* Debug messages sent via the UART debug channel, this function enable/disable
* the debug level
*
* Input Parameters:
* level debug level. Bitwise [0-8], 0(disable)or 1(enable).
* Bitwise map:
* 0 - Critical message
* 1 - information message
* 2 - core messages
* 3 - HCI messages
* 4 - Network stack messages
* 5 - wlan messages
* 6 - wlan driver messages
* 7 - epprom messages,
* 8 - general messages.
* Default: 0x13f. Saved: no
*
* Returned Value:
* On success, zero is returned. On error, -1 is returned
*
*****************************************************************************/
#ifndef CC3000_TINY_DRIVER
long netapp_set_debug_level(unsigned long ulLevel)
{
int8_t scRet;
uint8_t *ptr, *args;
int8_t scRet;
uint8_t *ptr, *args;
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
scRet = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
//
// Fill in temporary command buffer
//
args = UINT32_TO_STREAM(args, ulLevel);
/* Fill in temporary command buffer */
args = UINT32_TO_STREAM(args, ulLevel);
//
// Initiate a HCI command
//
hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN);
/* Initiate a HCI command */
//
// Wait for command complete event
//
SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet);
hci_command_send(HCI_NETAPP_SET_DEBUG_LEVEL, ptr, NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN);
return(scRet);
/* Wait for command complete event */
SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet);
return scRet;
}
#endif

View file

@ -1,340 +1,350 @@
/*****************************************************************************
*
* nvmem.c - CC3000 Host Driver Implementation.
* Copyright (C) 2011 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.
*
*****************************************************************************/
* nvmem.c - CC3000 Host Driver Implementation.
* Copyright (C) 2011 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.
*
*****************************************************************************/
//*****************************************************************************
//
//! \addtogroup nvmem_api
//! @{
//
//*****************************************************************************
/******************************************************************************
* Included Files
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <nuttx/wireless/cc3000/nvmem.h>
#include <nuttx/wireless/cc3000/hci.h>
#include <nuttx/wireless/cc3000/socket.h>
#include <nuttx/wireless/cc3000/include/sys/socket.h>
#include <nuttx/wireless/cc3000/evnt_handler.h>
//*****************************************************************************
//
// Prototypes for the structures for APIs.
//
//*****************************************************************************
/******************************************************************************
* Pre-processor Definitions
******************************************************************************/
#define NVMEM_READ_PARAMS_LEN (12)
#define NVMEM_CREATE_PARAMS_LEN (8)
#define NVMEM_READ_PARAMS_LEN (12)
#define NVMEM_CREATE_PARAMS_LEN (8)
#define NVMEM_WRITE_PARAMS_LEN (16)
//*****************************************************************************
//
//! nvmem_read
//!
//! @param ulFileId nvmem file id:\n
//! NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID,
//! NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID,
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
//! NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID,
//! NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID,
//! NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID,
//! and user files 12-15.
//! @param ulLength number of bytes to read
//! @param ulOffset ulOffset in file from where to read
//! @param buff output buffer pointer
//!
//! @return number of bytes read, otherwise error.
//!
//! @brief Reads data from the file referred by the ulFileId parameter.
//! Reads data from file ulOffset till length. Err if the file can't
//! be used, is invalid, or if the read is out of bounds.
//!
//*****************************************************************************
/******************************************************************************
* Public Functions
******************************************************************************/
/******************************************************************************
* Name: nvmem_read
*
* Description:
* Reads data from the file referred by the ulFileId parameter. Reads data
* from file ulOffset till length. Err if the file can't be used, is
* invalid, or if the read is out of bounds.
*
* Input Parameters:
* ulFileId nvmem file id:
* NVMEM_NVS_FILEID, NVMEM_NVS_SHADOW_FILEID,
* NVMEM_WLAN_CONFIG_FILEID, NVMEM_WLAN_CONFIG_SHADOW_FILEID,
* NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
* NVMEM_MAC_FILEID, NVMEM_FRONTEND_VARS_FILEID,
* NVMEM_IP_CONFIG_FILEID, NVMEM_IP_CONFIG_SHADOW_FILEID,
* NVMEM_BOOTLOADER_SP_FILEID, NVMEM_RM_FILEID,
* and user files 12-15.
* ulLength number of bytes to read
* ulOffset ulOffset in file from where to read
* buff output buffer pointer
*
* Returned Value:
* Number of bytes read, otherwise error.
*
*****************************************************************************/
signed long
nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffset, uint8_t *buff)
signed long nvmem_read(unsigned long ulFileId, unsigned long ulLength,
unsigned long ulOffset, uint8_t *buff)
{
uint8_t ucStatus = 0xFF;
uint8_t *ptr;
uint8_t *args;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, ulFileId);
args = UINT32_TO_STREAM(args, ulLength);
args = UINT32_TO_STREAM(args, ulOffset);
// Initiate a HCI command
hci_command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN);
SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus);
// In case there is data - read it - even if an error code is returned
// Note: It is the user responsibility to ignore the data in case of an error code
// Wait for the data in a synchronous way. Here we assume that the buffer is
// big enough to store also parameters of nvmem
SimpleLinkWaitData(buff, 0, 0);
return(ucStatus);
uint8_t ucStatus = 0xff;
uint8_t *ptr;
uint8_t *args;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
/* Fill in HCI packet structure */
args = UINT32_TO_STREAM(args, ulFileId);
args = UINT32_TO_STREAM(args, ulLength);
args = UINT32_TO_STREAM(args, ulOffset);
/* Initiate a HCI command */
hci_command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN);
SimpleLinkWaitEvent(HCI_CMND_NVMEM_READ, &ucStatus);
/* In case there is data - read it - even if an error code is returned
* Note: It is the user responsibility to ignore the data in case of an
* error code
*/
/* Wait for the data in a synchronous way. Here we assume that the buffer is
* big enough to store also parameters of nvmem
*/
SimpleLinkWaitData(buff, 0, 0);
return ucStatus;
}
//*****************************************************************************
//
//! nvmem_write
//!
//! @param ulFileId nvmem file id:\n
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
//! NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID,
//! and user files 12-15.
//! @param ulLength number of bytes to write
//! @param ulEntryOffset offset in file to start write operation from
//! @param buff data to write
//!
//! @return on success 0, error otherwise.
//!
//! @brief Write data to nvmem.
//! writes data to file referred by the ulFileId parameter.
//! Writes data to file ulOffset till ulLength.The file id will be
//! marked invalid till the write is done. The file entry doesn't
//! need to be valid - only allocated.
//!
//*****************************************************************************
/******************************************************************************
* Name: nvmem_write
*
* Description:
* Write data to nvmem. Writes data to file referred by the ulFileId
* parameter. Writes data to file ulOffset till ulLength. The file id will be
* marked invalid till the write is done. The file entry doesn't need to be
* valid - only allocated.
*
* Input Parameters:
* ulFileId nvmem file id:
* NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
* NVMEM_MAC_FILEID, NVMEM_BOOTLOADER_SP_FILEID,
* and user files 12-15.
* ulLength number of bytes to write
* ulEntryOffset offset in file to start write operation from
* buff data to write
*
* Returned Value:
* On success 0, error otherwise.
*
*****************************************************************************/
signed long
nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long
ulEntryOffset, uint8_t *buff)
signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength,
unsigned long ulEntryOffset, uint8_t *buff)
{
long iRes;
uint8_t *ptr;
uint8_t *args;
iRes = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, ulFileId);
args = UINT32_TO_STREAM(args, 12);
args = UINT32_TO_STREAM(args, ulLength);
args = UINT32_TO_STREAM(args, ulEntryOffset);
memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE +
NVMEM_WRITE_PARAMS_LEN),buff,ulLength);
// Initiate a HCI command but it will come on data channel
hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN,
ulLength);
SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes);
return(iRes);
long iRes;
uint8_t *ptr;
uint8_t *args;
iRes = EFAIL;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE);
/* Fill in HCI packet structure */
args = UINT32_TO_STREAM(args, ulFileId);
args = UINT32_TO_STREAM(args, 12);
args = UINT32_TO_STREAM(args, ulLength);
args = UINT32_TO_STREAM(args, ulEntryOffset);
memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE +
NVMEM_WRITE_PARAMS_LEN),buff,ulLength);
/* Initiate a HCI command but it will come on data channel */
hci_data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN,
ulLength);
SimpleLinkWaitEvent(HCI_EVNT_NVMEM_WRITE, &iRes);
return iRes;
}
//*****************************************************************************
//
//! nvmem_set_mac_address
//!
//! @param mac mac address to be set
//!
//! @return on success 0, error otherwise.
//!
//! @brief Write MAC address to EEPROM.
//! mac address as appears over the air (OUI first)
//!
//*****************************************************************************
/******************************************************************************
* Name: nvmem_set_mac_address
*
* Description:
* Write MAC address to EEPROM. mac address as appears over the air (OUI
* first)
*
* Input Parameters:
* mac mac address to be set
*
* Returned Value:
* On success 0, error otherwise.
*
*****************************************************************************/
uint8_t nvmem_set_mac_address(uint8_t *mac)
{
return nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
return nvmem_write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
}
//*****************************************************************************
//
//! nvmem_get_mac_address
//!
//! @param[out] mac mac address
//!
//! @return on success 0, error otherwise.
//!
//! @brief Read MAC address from EEPROM.
//! mac address as appears over the air (OUI first)
//!
//*****************************************************************************
/******************************************************************************
* Name: nvmem_get_mac_address
*
* Description:
* Read MAC address from EEPROM. mac address as appears over the air (OUI
* first)
*
* Input Parameters:
* mac mac address
*
* Returned Value:
* On success 0, error otherwise.
*
*****************************************************************************/
uint8_t nvmem_get_mac_address(uint8_t *mac)
{
return nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
return nvmem_read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac);
}
//*****************************************************************************
//
//! nvmem_write_patch
//!
//! @param ulFileId nvmem file id:\n
//! NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
//! @param spLength number of bytes to write
//! @param spData SP data to write
//!
//! @return on success 0, error otherwise.
//!
//! @brief program a patch to a specific file ID.
//! The SP data is assumed to be organized in 2-dimensional.
//! Each line is SP_PORTION_SIZE bytes long. Actual programming is
//! applied in SP_PORTION_SIZE bytes portions.
//!
//*****************************************************************************
/******************************************************************************
* Name: nvmem_write_patch
*
* Description:
* Program a patch to a specific file ID. The SP data is assumed to be
* organized in 2-dimensional. Each line is SP_PORTION_SIZE bytes long.
* Actual programming is applied in SP_PORTION_SIZE bytes portions.
*
* Input Parameters:
* ulFileId nvmem file id:
* NVMEM_WLAN_DRIVER_SP_FILEID, NVMEM_WLAN_FW_SP_FILEID,
* spLength number of bytes to write
* spData SP data to write
*
* Returned Value:
* On success 0, error otherwise.
*
*****************************************************************************/
uint8_t nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const uint8_t *spData)
uint8_t nvmem_write_patch(unsigned long ulFileId, unsigned long spLength,
const uint8_t *spData)
{
uint8_t status = 0;
uint16_t offset = 0;
uint8_t* spDataPtr = (uint8_t*)spData;
while ((status == 0) && (spLength >= SP_PORTION_SIZE))
{
status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr);
offset += SP_PORTION_SIZE;
spLength -= SP_PORTION_SIZE;
spDataPtr += SP_PORTION_SIZE;
}
if (status !=0)
{
// NVMEM error occurred
return status;
}
if (spLength != 0)
{
// if reached here, a reminder is left
status = nvmem_write(ulFileId, spLength, offset, spDataPtr);
}
return status;
uint8_t status = 0;
uint16_t offset = 0;
uint8_t *spDataPtr = (uint8_t*)spData;
while ((status == 0) && (spLength >= SP_PORTION_SIZE))
{
status = nvmem_write(ulFileId, SP_PORTION_SIZE, offset, spDataPtr);
offset += SP_PORTION_SIZE;
spLength -= SP_PORTION_SIZE;
spDataPtr += SP_PORTION_SIZE;
}
if (status !=0)
{
/* NVMEM error occurred */
return status;
}
if (spLength != 0)
{
/* if reached here, a reminder is left */
status = nvmem_write(ulFileId, spLength, offset, spDataPtr);
}
return status;
}
//*****************************************************************************
//
//! nvmem_read_sp_version
//!
//! @param[out] patchVer first number indicates package ID and the second
//! number indicates package build number
//!
//! @return on success 0, error otherwise.
//!
//! @brief Read patch version. read package version (WiFi FW patch,
//! driver-supplicant-NS patch, bootloader patch)
//!
//*****************************************************************************
/******************************************************************************
* Name: nvmem_read_sp_version
*
* Description:
* Read patch version. read package version (WiFi FW patch,
* driver-supplicant-NS patch, bootloader patch)
*
* Input Parameters:
* patchVer first number indicates package ID and the second
* number indicates package build number
*
* Returned Value:
* On success 0, error otherwise.
*
*****************************************************************************/
#ifndef CC3000_TINY_DRIVER
uint8_t nvmem_read_sp_version(uint8_t* patchVer)
{
uint8_t *ptr;
// 1st byte is the status and the rest is the SP version
uint8_t retBuf[5];
ptr = tSLInformation.pucTxCommandBuffer;
// Initiate a HCI command, no args are required
hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0);
SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf);
// package ID
*patchVer = retBuf[3];
// package build number
*(patchVer+1) = retBuf[4];
return(retBuf[0]);
uint8_t *ptr;
/* 1st byte is the status and the rest is the SP version */
uint8_t retBuf[5];
ptr = tSLInformation.pucTxCommandBuffer;
/* Initiate a HCI command, no args are required */
hci_command_send(HCI_CMND_READ_SP_VERSION, ptr, 0);
SimpleLinkWaitEvent(HCI_CMND_READ_SP_VERSION, retBuf);
/* Package ID */
*patchVer = retBuf[3];
/* Package build number */
*(patchVer+1) = retBuf[4];
return retBuf[0];
}
#endif
//*****************************************************************************
//
//! nvmem_create_entry
//!
//! @param ulFileId nvmem file Id:\n
//! * NVMEM_AES128_KEY_FILEID: 12
//! * NVMEM_SHARED_MEM_FILEID: 13
//! * and fileIDs 14 and 15
//! @param ulNewLen entry ulLength
//!
//! @return on success 0, error otherwise.
//!
//! @brief Create new file entry and allocate space on the NVMEM.
//! Applies only to user files.
//! Modify the size of file.
//! If the entry is unallocated - allocate it to size
//! ulNewLen (marked invalid).
//! If it is allocated then deallocate it first.
//! To just mark the file as invalid without resizing -
//! set ulNewLen=0.
//!
//*****************************************************************************
/******************************************************************************
* Name: nvmem_create_entry
*
* Description:
* Create new file entry and allocate space on the NVMEM. Applies only to
* user files. Modify the size of file. If the entry is unallocated -
* allocate it to size ulNewLen (marked invalid). If it is allocated then
* deallocate it first. To just mark the file as invalid without resizing -
* Set ulNewLen=0.
*
* Input Parameters:
* ulFileId nvmem file Id:
* * NVMEM_AES128_KEY_FILEID: 12
* * NVMEM_SHARED_MEM_FILEID: 13
* * and fileIDs 14 and 15
* ulNewLen entry ulLength
*
* Returned Value:
* On success 0, error otherwise.
*
*****************************************************************************/
signed long
nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen)
signed long nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen)
{
uint8_t *ptr;
uint8_t *args;
uint16_t retval;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
// Fill in HCI packet structure
args = UINT32_TO_STREAM(args, ulFileId);
args = UINT32_TO_STREAM(args, ulNewLen);
// Initiate a HCI command
hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN);
SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval);
return(retval);
uint8_t *ptr;
uint8_t *args;
uint16_t retval;
ptr = tSLInformation.pucTxCommandBuffer;
args = (ptr + HEADERS_SIZE_CMD);
/*( Fill in HCI packet structure */
args = UINT32_TO_STREAM(args, ulFileId);
args = UINT32_TO_STREAM(args, ulNewLen);
/* Initiate a HCI command */
hci_command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN);
SimpleLinkWaitEvent(HCI_CMND_NVMEM_CREATE_ENTRY, &retval);
return retval;
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

File diff suppressed because it is too large Load diff

View file

@ -1,64 +1,47 @@
/**************************************************************************
*
* spi. - SPI functions to connect an Arduidno to the TI CC3000
*
* This code uses the Arduino hardware SPI library (or a bit-banged
* SPI for the Teensy 3.0) to send & receive data between the library
* API calls and the CC3000 hardware. Every
*
* Version 1.0.1b
*
* Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Don't sue me if my code blows up your board and burns down your house
*
****************************************************************************/
* spi. - SPI functions to connect an Arduidno to the TI CC3000
*
* This code uses the Arduino hardware SPI library (or a bit-banged
* SPI for the Teensy 3.0) to send & receive data between the library
* API calls and the CC3000 hardware. Every
*
* Version 1.0.1b
*
* Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Don't sue me if my code blows up your board and burns down your house
*
****************************************************************************/
/*****************************************************************************
* Included Files
*****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <pthread.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <debug.h>
#include <string.h>
#include <unistd.h>
#include <nuttx/config.h>
#include <nuttx/spi/spi.h>
#include <arch/board/kl_wifi.h>
#include <nuttx/wireless/cc3000/hci.h>
#include <nuttx/wireless/cc3000/spi.h>
//#include <nuttx/wireless/cc3000/ArduinoCC3000Core.h>
#include <fcntl.h>
#include "spi.h"
// This flag lets the interrupt handler know if it should respond to
// the WL_SPI_IRQ pin going low or not
int16_t SPIInterruptsEnabled=0;
#include <nuttx/wireless/cc3000.h>
#include <nuttx/wireless/cc3000/cc3000_common.h>
#define READ 3
#define WRITE 1
#define HI(value) (((value) & 0xFF00) >> 8)
#define LO(value) ((value) & 0x00FF)
#define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5)
#define SPI_HEADER_SIZE (5)
#define eSPI_STATE_POWERUP (0)
#define eSPI_STATE_INITIALIZED (1)
#define eSPI_STATE_IDLE (2)
#define eSPI_STATE_WRITE_IRQ (3)
#define eSPI_STATE_WRITE_FIRST_PORTION (4)
#define eSPI_STATE_WRITE_EOT (5)
#define eSPI_STATE_READ_IRQ (6)
#define eSPI_STATE_READ_FIRST_PORTION (7)
#define eSPI_STATE_READ_EOT (8)
/* !!!HACK!!!*/
#define KL_PORTA_ISFR 0x400490a0
#define PIN16 16
#define getreg32(a) (*(volatile uint32_t *)(a))
#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v))
/*****************************************************************************
* Pre-processor Definitions
*****************************************************************************/
#undef SPI_DEBUG /* Define to enable debug */
#undef SPI_VERBOSE /* Define to enable verbose debug */
@ -76,609 +59,187 @@ int16_t SPIInterruptsEnabled=0;
# define spivdbg(x...)
#endif
#ifdef CONFIG_KL_SPI0
void kl_spi0select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected)
static struct
{
spivdbg("devid: %d CS: %s\n",
(int)devid, selected ? "assert" : "de-assert");
}
#endif
int cc3000fd;
gcSpiHandleRx pfRxHandler;
pthread_t unsoliced_thread;
bool run;
uint8_t rx_buffer[CC3000_RX_BUFFER_SIZE];
#ifdef CONFIG_KL_SPI1
void kl_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid,
bool selected)
{
spivdbg("devid: %d CS: %s\n",
(int)devid, selected ? "assert" : "de-assert");
}
#endif
} spiconf;
#ifdef CONFIG_KL_SPI0
uint8_t kl_spi0status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
{
return 0;
}
#endif
/*****************************************************************************
* Public Functions
*****************************************************************************/
#ifdef CONFIG_KL_SPI1
uint8_t kl_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
{
return 0;
}
#endif
typedef struct
{
gcSpiHandleRx SPIRxHandler;
uint16_t usTxPacketLength;
uint16_t usRxPacketLength;
unsigned long ulSpiState;
uint8_t *pTxPacket;
uint8_t *pRxPacket;
} tSpiInformation;
tSpiInformation sSpiInformation;
//
// Static buffer for 5 bytes of SPI HEADER
//
uint8_t tSpiReadHeader[] = {READ, 0, 0, 0, 0};
// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
// for the purpose of detection of the overrun. The location of the memory where the magic number
// resides shall never be written. In case it is written - the overrun occured and either recevie function
// or send function will stuck forever.
#define CC3000_BUFFER_MAGIC_NUMBER (0xDE)
char spi_buffer[CC3000_RX_BUFFER_SIZE];
uint8_t wlan_tx_buffer[CC3000_TX_BUFFER_SIZE];
struct spi_dev_s *spi = NULL;
unsigned int SPIPump(uint8_t data)
{
uint8_t rx;
printf("SPIPump tx = 0x%X ", data);
if (!spi)
{
spi = up_spiinitialize(1);
SPI_SETBITS(spi, 8);
SPI_SETMODE(spi, SPIDEV_MODE1);
}
SPI_EXCHANGE(spi, &data, &rx, 1);
printf(" rx = 0x%X\n", rx);
return rx;
}
//*****************************************************************************
//
//! This function enter point for write flow
//!
//! \param SpiPauseSpi
//!
//! \return none
//!
//! \brief The function triggers a user provided callback for
//
//*****************************************************************************
void SpiPauseSpi(void)
{
SPIInterruptsEnabled = 0;
}
//*****************************************************************************
//
//! This function enter point for write flow
//!
//! \param SpiResumeSpi
//!
//! \return none
//!
//! \brief The function triggers a user provided callback for
//
//*****************************************************************************
/*****************************************************************************
* Name: SpiResumeSpi
*
* Description:
* Will re enable the SPI_IRQ'a ability to create interrupts. It is used to
* resume processing after the code passed to SpiOpen is Called
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
*****************************************************************************/
void SpiResumeSpi(void)
{
SPIInterruptsEnabled = 1;
}
DEBUGASSERT(spiconf.cc3000fd);
//*****************************************************************************
//
//! This function enter point for write flow
//!
//! \param SpiTriggerRxProcessing
//!
//! \return none
//!
//! \brief The function triggers a user provided callback for
//
//*****************************************************************************
void SpiTriggerRxProcessing(void)
{
//
// Trigger Rx processing
//
SpiPauseSpi();
DeassertWlanCS();
// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
// for the purpose of detection of the overrun. If the magic number is overriten - buffer overrun
// occurred - and we will stuck here forever!
if (sSpiInformation.pRxPacket[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
if (ioctl(spiconf.cc3000fd,CC3000IOC_COMPLETE,0))
{
while (1)
;
}
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE);
}
//*****************************************************************************
//
//! This function enter point for write flow
//!
//! \param buffer
//!
//! \return none
//!
//! \brief ...
//
//*****************************************************************************
void SpiReadDataSynchronous(uint8_t *data, uint16_t size)
{
long i = 0;
uint8_t *data_to_send = tSpiReadHeader;
for (i = 0; i < size; i ++)
{
data[i] = SPIPump(data_to_send[0]);
printf("ioctl:CC3000IOC_COMPLETE failed: %s\n", strerror(errno));
}
}
//*****************************************************************************
//
//! This function enter point for write flow
//!
//! \param buffer
//!
//! \return none
//!
//! \brief ...
//
//*****************************************************************************
void SpiWriteDataSynchronous(uint8_t *data, uint16_t size)
{
while (size)
{
SPIPump(*data);
size --;
data++;
}
}
//*****************************************************************************
//
//! This function enter point for write flow
//!
//! \param buffer
//!
//! \return none
//!
//! \brief ...
//
//*****************************************************************************
long SpiFirstWrite(uint8_t *ucBuf, uint16_t usLength)
{
//
// workaround for first transaction
//
AssertWlanCS();
usleep(70);
// SPI writes first 4 bytes of data
SpiWriteDataSynchronous(ucBuf, 4);
usleep(70);
SpiWriteDataSynchronous(ucBuf + 4, usLength - 4);
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
DeassertWlanCS();
//printf("Executed SpiFirstWrite!\n");
return(0);
}
//*****************************************************************************
//
//! This function enter point for write flow
//!
//! \param buffer
//!
//! \return none
//!
//! \brief ...
//
//*****************************************************************************
/*****************************************************************************
* Name: SpiWrite
*
* Description:
* This function enter point for write flow
*
* Input Parameters:
* pUserBuffer
* usLength
*
* Returned Value:
*
*****************************************************************************/
long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength)
{
uint8_t ucPad = 0;
//
// Figure out the total length of the packet in order to figure out if there is padding or not
//
if(!(usLength & 0x0001))
{
ucPad++;
}
pUserBuffer[0] = WRITE;
pUserBuffer[1] = HI(usLength + ucPad);
pUserBuffer[2] = LO(usLength + ucPad);
pUserBuffer[3] = 0;
pUserBuffer[4] = 0;
usLength += (SPI_HEADER_SIZE + ucPad);
// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size)
// for the purpose of overrun detection. If the magic number is overwritten - buffer overrun
// occurred - and we will be stuck here forever!
if (wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER)
{
while (1)
;
}
if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
{
while (sSpiInformation.ulSpiState != eSPI_STATE_INITIALIZED)
{
}
}
if (sSpiInformation.ulSpiState == eSPI_STATE_INITIALIZED)
{
//
// This is time for first TX/RX transactions over SPI:
// the IRQ is down - so need to send read buffer size command
//
SpiFirstWrite(pUserBuffer, usLength);
}
else
{
//
// We need to prevent here race that can occur in case two back to back packets are sent to the
// device, so the state will move to IDLE and once again to not IDLE due to IRQ
//
tSLInformation.WlanInterruptDisable();
while (sSpiInformation.ulSpiState != eSPI_STATE_IDLE)
{
;
}
sSpiInformation.ulSpiState = eSPI_STATE_WRITE_IRQ;
sSpiInformation.pTxPacket = pUserBuffer;
sSpiInformation.usTxPacketLength = usLength;
//
// Assert the CS line and wait till SSI IRQ line is active and then initialize write operation
//
AssertWlanCS();
//
// Re-enable IRQ - if it was not disabled - this is not a problem...
//
tSLInformation.WlanInterruptEnable();
//
// check for a missing interrupt between the CS assertion and enabling back the interrupts
//
if (tSLInformation.ReadWlanInterruptPin() == 0)
{
SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
DeassertWlanCS();
}
}
//
// Due to the fact that we are currently implementing a blocking situation
// here we will wait till end of transaction
//
while (eSPI_STATE_IDLE != sSpiInformation.ulSpiState)
;
return(0);
DEBUGASSERT(spiconf.cc3000fd);
return write(spiconf.cc3000fd,pUserBuffer,usLength) == usLength ? 0 : -errno;
}
//*****************************************************************************
//
//! This function processes received SPI Header and in accordance with it - continues reading
//! the packet
//!
//! \param None
//!
//! \return None
//!
//! \brief ...
//
//*****************************************************************************
/*****************************************************************************
* Name: SpiRead
*
* Description:
* This function enter point for read flow. This function will block the
* caller untinlthere is data Available
*
* Input Parameters:
* pUserBuffer
* usLength
*
* Returned Value:
*
*****************************************************************************/
long SpiReadDataCont(void)
long SpiRead(uint8_t *pUserBuffer, uint16_t usLength)
{
long data_to_recv;
uint8_t *evnt_buff, type;
DEBUGASSERT(spiconf.cc3000fd);
return read(spiconf.cc3000fd,pUserBuffer,usLength);
}
//
//determine what type of packet we have
//
/*****************************************************************************
* Name: unsoliced_thread_func
*
* Description:
* This is the thread for unsolicited events. This function will block the
* caller untinlthere is data Available
*
* Input Parameters:
* parameter
*
* Returned Value:
*
*****************************************************************************/
evnt_buff = sSpiInformation.pRxPacket;
data_to_recv = 0;
STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type);
static void *unsoliced_thread_func(void *parameter)
{
char queuename[QUEUE_NAMELEN];
int status = 0;
int nbytes = 0;
int minor = 0;
switch(type)
ioctl(spiconf.cc3000fd, CC3000IOC_GETQUEID, (unsigned long)&minor);
snprintf(queuename, QUEUE_NAMELEN, QUEUE_FORMAT, minor);
mqd_t queue = mq_open(queuename,O_RDONLY);
while(spiconf.run)
{
case HCI_TYPE_DATA:
memset(spiconf.rx_buffer,0,sizeof(spiconf.rx_buffer));
nbytes = mq_receive(queue, spiconf.rx_buffer, CC3000_RX_BUFFER_SIZE, 0);
if (nbytes > 0)
{
//
// We need to read the rest of data..
//
STREAM_TO_UINT16((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_DATA_LENGTH_OFFSET, data_to_recv);
if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1))
{
data_to_recv++;
}
if (data_to_recv)
{
SpiReadDataSynchronous(evnt_buff + 10, data_to_recv);
}
break;
}
case HCI_TYPE_EVNT:
{
//
// Calculate the rest length of the data
//
STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_EVENT_LENGTH_OFFSET, data_to_recv);
data_to_recv -= 1;
//
// Add padding byte if needed
//
if ((HEADERS_SIZE_EVNT + data_to_recv) & 1)
{
data_to_recv++;
}
if (data_to_recv)
{
SpiReadDataSynchronous(evnt_buff + 10, data_to_recv);
}
sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
break;
spiconf.pfRxHandler(spiconf.rx_buffer);
}
}
return (0);
mq_close(queue);
pthread_exit((pthread_addr_t)status);
return (pthread_addr_t)status;
}
//*****************************************************************************
//
//! This function enter point for write flow
//!
//! \param SSIContReadOperation
//!
//! \return none
//!
//! \brief The function triggers a user provided callback for
//
//*****************************************************************************
void SSIContReadOperation(void)
{
//
// The header was read - continue with the payload read
//
if (!SpiReadDataCont())
{
//
// All the data was read - finalize handling by switching to teh task
// and calling from task Event Handler
//
SpiTriggerRxProcessing();
}
}
//*****************************************************************************
//
//! This function enter point for read flow: first we read minimal 5 SPI header bytes and 5 Event
//! Data bytes
//!
//! \param buffer
//!
//! \return none
//!
//! \brief ...
//
//*****************************************************************************
void SpiReadHeader(void)
{
SpiReadDataSynchronous(sSpiInformation.pRxPacket, 10);
}
//*****************************************************************************
//
//! The IntSpiGPIOHandler interrupt handler
//!
//! \param none
//!
//! \return none
//!
//! \brief GPIO A interrupt handler. When the external SSI WLAN device is
//! ready to interact with Host CPU it generates an interrupt signal.
//! After that Host CPU has registrated this interrupt request
//! it set the corresponding /CS in active state.
//
//*****************************************************************************
//#pragma vector=PORT2_VECTOR
//__interrupt void IntSpiGPIOHandler(void)
int CC3000InterruptHandler(int irq, void *context)
{
uint32_t regval = 0;
regval = getreg32(KL_PORTA_ISFR);
if (regval & (1 << PIN16))
{
//printf("\nAn interrupt was issued!\n");
if (!SPIInterruptsEnabled)
{
goto out;
}
//printf("\nSPIInterrupt was enabled!\n");
if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
{
/* This means IRQ line was low call a callback of HCI Layer to inform on event */
sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED;
}
else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE)
{
sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ;
/* IRQ line goes down - start reception */
AssertWlanCS();
//
// Wait for TX/RX Complete which will come as DMA interrupt
//
SpiReadHeader();
sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
SSIContReadOperation();
}
else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ)
{
SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
DeassertWlanCS();
}
else
{
}
out:
regval = (1 << PIN16);
putreg32(regval, KL_PORTA_ISFR);
}
return 0;
}
//*****************************************************************************
//
//! SpiClose
//!
//! \param none
//!
//! \return none
//!
//! \brief Cofigure the SSI
//
//*****************************************************************************
/*****************************************************************************
* Name: SpiOpen
*
* Description:
* Configure the SPI
*
* Input Parameters:
* pfRxHandler the Rx handler for SPI
*
* Returned Value:
* None
*
*****************************************************************************/
void SpiOpen(gcSpiHandleRx pfRxHandler)
{
sSpiInformation.ulSpiState = eSPI_STATE_POWERUP;
pthread_attr_t attr;
int status;
memset(spi_buffer, 0, sizeof(spi_buffer));
memset(wlan_tx_buffer, 0, sizeof(spi_buffer));
DEBUGASSERT(spiconf.cc3000fd == 0);
int fd = open("/dev/wireless0",O_RDWR|O_BINARY);
if (fd > 0)
{
spiconf.pfRxHandler = pfRxHandler;
spiconf.cc3000fd = fd;
spiconf.run = true;
sSpiInformation.SPIRxHandler = pfRxHandler;
sSpiInformation.usTxPacketLength = 0;
sSpiInformation.pTxPacket = NULL;
sSpiInformation.pRxPacket = (uint8_t *)spi_buffer;
sSpiInformation.usRxPacketLength = 0;
spi_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
wlan_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER;
status = pthread_attr_init(&attr);
DEBUGASSERT(status == 0)
//
// Enable interrupt on the GPIO pin of WLAN IRQ
//
tSLInformation.WlanInterruptEnable();
status = pthread_create(&spiconf.unsoliced_thread, &attr,
unsoliced_thread_func, NULL);
DEBUGASSERT(status == 0)
}
}
//*****************************************************************************
//
//! SpiClose
//!
//! \param none
//!
//! \return none
//!
//! \brief Cofigure the SSI
//
//*****************************************************************************
/*****************************************************************************
* Name: SpiClose
*
* Description:
* Configure the SPI
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
*****************************************************************************/
void SpiClose(void)
{
if (sSpiInformation.pRxPacket)
{
sSpiInformation.pRxPacket = 0;
}
if (spiconf.cc3000fd)
{
int status;
spiconf.run = false;
//
// Disable Interrupt in GPIOA module...
//
pthread_cancel(spiconf.unsoliced_thread);
pthread_join(spiconf.unsoliced_thread, (pthread_addr_t*)&status);
tSLInformation.WlanInterruptDisable();
close(spiconf.cc3000fd);
spiconf.cc3000fd = 0;
}
}

View file

@ -1,45 +1,50 @@
/**************************************************************************
*
* ArduinoCC3000SPI.h - SPI functions to connect an Arduidno to the TI
* CC3000
*
* This code uses the Arduino hardware SPI library (or a bit-banged
* SPI for the Teensy 3.0) to send & receive data between the library
* API calls and the CC3000 hardware. Every
*
* Version 1.0.1b
*
* Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Don't sue me if my code blows up your board and burns down your house
*
****************************************************************************/
* ArduinoCC3000SPI.h - SPI functions to connect an Arduidno to the TI
* CC3000
*
* This code uses the Arduino hardware SPI library (or a bit-banged
* SPI for the Teensy 3.0) to send & receive data between the library
* API calls and the CC3000 hardware. Every
*
* Version 1.0.1b
*
* Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Don't sue me if my code blows up your board and burns down your house
*
****************************************************************************/
#ifndef __DRIVERS_WIRELESS_CC3000_SPI_H
#define __DRIVERS_WIRELESS_CC3000_SPI_H
#include <stdint.h>
/*****************************************************************************
* Public Types
*****************************************************************************/
typedef void (*gcSpiHandleRx)(void *p);
//*****************************************************************************
//
// Prototypes for the APIs.
//
//*****************************************************************************
/*****************************************************************************
* Public Data
*****************************************************************************/
extern uint16_t SPIInterruptsEnabled;
extern uint8_t wlan_tx_buffer[];
/*****************************************************************************
* Public Function Prototypes
*****************************************************************************/
void SpiOpen(gcSpiHandleRx pfRxHandler);
void SpiClose(void);
long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength);
long SpiRead(uint8_t *pUserBuffer, uint16_t usLength);
void SpiResumeSpi(void);
int CC3000InterruptHandler(int irq, void *context);
int16_t SPIInterruptsEnabled;
uint8_t wlan_tx_buffer[];
#endif /* __DRIVERS_WIRELESS_CC3000_SPI_H */

View file

@ -1,53 +1,41 @@
/*****************************************************************************
*
* spi_version.h - CC3000 Host Driver Implementation.
* Copyright (C) 2011 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.
*
*****************************************************************************/
#ifndef __SPI_VERSION_H__
#define __SPI_VERSION_H__
#define SPI_VERSION_NUMBER 7
#endif // __VERSION_H__
/*****************************************************************************
*
* spi_version.h - CC3000 Host Driver Implementation.
* Copyright (C) 2011 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.
*
*****************************************************************************/
#ifndef __DRIVERS_WIRELESS_CC3000_SPI_VERSION_H
#define __DRIVERS_WIRELESS_CC3000_SPI_VERSION_H
#define SPI_VERSION_NUMBER 7
#endif /* __DRIVERS_WIRELESS_CC3000_SPI_VERSION_H */

File diff suppressed because it is too large Load diff