stmhal: Reinstate CC3000 driver from old stm/ port.
It's not enabled by default because it doesn't fully work. It can connect to an AP, get an IP address and do a host-lookup, but not yet do send or recv on a socket.
This commit is contained in:
parent
cab23051d9
commit
4ae52d454c
|
@ -11,7 +11,7 @@ HAL_DIR=hal
|
|||
USBDEV_DIR=usbdev
|
||||
#USBHOST_DIR=usbhost
|
||||
FATFS_DIR=fatfs
|
||||
#CC3K_DIR=cc3k
|
||||
CC3K_DIR=cc3k
|
||||
DFU=../tools/dfu.py
|
||||
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
|
@ -25,7 +25,7 @@ INC += -I$(HAL_DIR)/inc
|
|||
INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/cdc_msc_hid/inc
|
||||
#INC += -I$(USBHOST_DIR)
|
||||
INC += -I$(FATFS_DIR)/src
|
||||
#INC += -I$(CC3K_DIR)
|
||||
INC += -I$(CC3K_DIR)
|
||||
|
||||
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mabi=aapcs-linux -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion
|
||||
CFLAGS = $(INC) -Wall -Werror -ansi -std=gnu99 $(CFLAGS_CORTEX_M4) $(COPT)
|
||||
|
@ -100,8 +100,7 @@ SRC_C = \
|
|||
servo.c \
|
||||
dac.c \
|
||||
adc.c \
|
||||
|
||||
# pybwlan.c \
|
||||
pybwlan.c \
|
||||
|
||||
SRC_S = \
|
||||
startup_stm32f40xx.s \
|
||||
|
@ -185,7 +184,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
|
|||
OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_USBDEV:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_FATFS:.c=.o))
|
||||
#OBJ += $(addprefix $(BUILD)/, $(SRC_CC3K:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_CC3K:.c=.o))
|
||||
OBJ += $(BUILD)/pins_$(BOARD).o
|
||||
|
||||
all: $(BUILD)/flash.dfu
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#define MICROPY_HW_HAS_MMA7660 (1)
|
||||
#define MICROPY_HW_HAS_LIS3DSH (0)
|
||||
#define MICROPY_HW_HAS_LCD (1)
|
||||
#define MICROPY_HW_HAS_WLAN (0)
|
||||
#define MICROPY_HW_HAS_WLAN (1)
|
||||
#define MICROPY_HW_ENABLE_RNG (1)
|
||||
#define MICROPY_HW_ENABLE_RTC (1)
|
||||
#define MICROPY_HW_ENABLE_TIMER (1)
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* cc3000_common.c.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
/******************************************************************************
|
||||
*
|
||||
* Include files
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cc3000_common.h"
|
||||
#include "socket.h"
|
||||
#include "wlan.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "ccdebug.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
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32)
|
||||
{
|
||||
*(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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16)
|
||||
{
|
||||
*(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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
uint16_t STREAM_TO_UINT16_f(char* cp, uint16_t offset)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)cp;
|
||||
/*
|
||||
DEBUGPRINT_F("Stream2u16: ");
|
||||
DEBUGPRINT_HEX(cp[offset+1]);
|
||||
DEBUGPRINT_F(" + ");
|
||||
DEBUGPRINT_HEX(cp[offset]);
|
||||
DEBUGPRINT_F("\n\r");
|
||||
*/
|
||||
|
||||
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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
uint32_t STREAM_TO_UINT32_f(char * cp, uint16_t offset)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)cp;
|
||||
|
||||
/*
|
||||
DEBUGPRINT_F("\tStream2u32: ");
|
||||
DEBUGPRINT_HEX(cp[offset+3]); DEBUGPRINT_F(" + ");
|
||||
DEBUGPRINT_HEX(cp[offset+2]); DEBUGPRINT_F(" + ");
|
||||
DEBUGPRINT_HEX(cp[offset+1]); DEBUGPRINT_F(" + ");
|
||||
DEBUGPRINT_HEX(cp[offset]);
|
||||
DEBUGPRINT_F("\n\r");
|
||||
*/
|
||||
|
||||
return (uint32_t)((uint32_t)((uint32_t)
|
||||
(*(p + offset + 3)) << 24) + (uint32_t)((uint32_t)
|
||||
(*(p + offset + 2)) << 16) + (uint32_t)((uint32_t)
|
||||
(*(p + offset + 1)) << 8) + (uint32_t)(*(p + offset)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
|
@ -0,0 +1,385 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* cc3000_common.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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 __COMMON_H__
|
||||
#define __COMMON_H__
|
||||
|
||||
//******************************************************************************
|
||||
// Include files
|
||||
//******************************************************************************
|
||||
//#include <stdlib.h>
|
||||
//#include <errno.h>
|
||||
//#include <stdint.h>
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
// ERROR CODES
|
||||
//*****************************************************************************
|
||||
#define ESUCCESS 0
|
||||
#define EFAIL -1
|
||||
#define EERROR EFAIL
|
||||
|
||||
//*****************************************************************************
|
||||
// COMMON DEFINES
|
||||
//*****************************************************************************
|
||||
#define ERROR_SOCKET_INACTIVE -57
|
||||
|
||||
#define WLAN_ENABLE (1)
|
||||
#define WLAN_DISABLE (0)
|
||||
|
||||
#define MAC_ADDR_LEN (6)
|
||||
|
||||
#define SP_PORTION_SIZE (32)
|
||||
|
||||
// #define CC3000_TINY_DRIVER
|
||||
|
||||
/*Defines for minimal and maximal RX buffer size. This size includes the spi
|
||||
header and hci header.
|
||||
The maximal buffer size derives from:
|
||||
MTU + HCI header + SPI header + sendto() agrs size
|
||||
The minimum buffer size derives from:
|
||||
HCI header + SPI header + max args size
|
||||
|
||||
This buffer is used for receiving events and data.
|
||||
The packet can not be longer than MTU size and CC3000 does not support
|
||||
fragmentation. Note that the same buffer is used for reception of the data
|
||||
and events from CC3000. That is why the minimum is defined.
|
||||
The calculation for the actual size of buffer for reception is:
|
||||
Given the maximal data size MAX_DATA that is expected to be received by
|
||||
application, the required buffer is:
|
||||
Using recv() or recvfrom():
|
||||
|
||||
max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen
|
||||
+ ucArgsize + 1)
|
||||
|
||||
Using gethostbyname() with minimal buffer size will limit the host name
|
||||
returned to 99 bytes only.
|
||||
The 1 is used for the overrun detection
|
||||
|
||||
Buffer size increased to 130 following the add_profile() with WEP security
|
||||
which requires TX buffer size of 130 bytes:
|
||||
HEADERS_SIZE_EVNT + WLAN_ADD_PROFILE_WEP_PARAM_LEN + MAX SSID LEN + 4 * MAX KEY LEN = 130
|
||||
MAX SSID LEN = 32
|
||||
MAX SSID LEN = 13 (with add_profile only ascii key setting is supported,
|
||||
therfore maximum key size is 13)
|
||||
*/
|
||||
|
||||
#define CC3000_MINIMAL_RX_SIZE (130 + 1)
|
||||
#define CC3000_MAXIMAL_RX_SIZE (1519 + 1)
|
||||
|
||||
/*Defines for minimal and maximal TX buffer size.
|
||||
This buffer is used for sending events and data.
|
||||
The packet can not be longer than MTU size and CC3000 does not support
|
||||
fragmentation. Note that the same buffer is used for transmission of the data
|
||||
and commands. That is why the minimum is defined.
|
||||
The calculation for the actual size of buffer for transmission is:
|
||||
Given the maximal data size MAX_DATA, the required buffer is:
|
||||
Using Sendto():
|
||||
|
||||
max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
|
||||
+ SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
|
||||
|
||||
Using Send():
|
||||
|
||||
max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE
|
||||
+ HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1)
|
||||
|
||||
The 1 is used for the overrun detection */
|
||||
|
||||
#define CC3000_MINIMAL_TX_SIZE (130 + 1)
|
||||
#define CC3000_MAXIMAL_TX_SIZE (1519 + 1)
|
||||
|
||||
//TX and RX buffer sizes, allow to receive and transmit maximum data at length 8.
|
||||
#ifdef CC3000_TINY_DRIVER
|
||||
#define TINY_CC3000_MAXIMAL_RX_SIZE 44
|
||||
#define TINY_CC3000_MAXIMAL_TX_SIZE 59
|
||||
#endif
|
||||
|
||||
/*In order to determine your preferred buffer size,
|
||||
change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between
|
||||
the minimal and maximal specified above.
|
||||
Note that the buffers are allocated by SPI.
|
||||
In case you change the size of those buffers, you might need also to change
|
||||
the linker file, since for example on MSP430 FRAM devices the buffers are
|
||||
allocated in the FRAM section that is allocated manually and not by IDE.
|
||||
*/
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
|
||||
#define CC3000_RX_BUFFER_SIZE (CC3000_MINIMAL_RX_SIZE)
|
||||
#define CC3000_TX_BUFFER_SIZE (CC3000_MINIMAL_TX_SIZE)
|
||||
|
||||
//if defined TINY DRIVER we use smaller RX and TX buffer in order to minimize RAM consumption
|
||||
#else
|
||||
#define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE)
|
||||
#define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE)
|
||||
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
// Compound Types
|
||||
//*****************************************************************************
|
||||
#ifdef __AVR__
|
||||
typedef unsigned long time_t; /* KTown: Updated to be compatible with Arduino Time.h */
|
||||
#else
|
||||
typedef long time_t;
|
||||
#endif
|
||||
typedef unsigned long clock_t;
|
||||
typedef long suseconds_t;
|
||||
|
||||
typedef struct timeval timeval;
|
||||
|
||||
struct timeval
|
||||
{
|
||||
time_t tv_sec; /* seconds */
|
||||
suseconds_t tv_usec; /* microseconds */
|
||||
};
|
||||
|
||||
typedef char *(*tFWPatches)(unsigned long *usLength);
|
||||
|
||||
typedef char *(*tDriverPatches)(unsigned long *usLength);
|
||||
|
||||
typedef char *(*tBootLoaderPatches)(unsigned long *usLength);
|
||||
|
||||
typedef void (*tWlanCB)(long event_type, char * data, unsigned char length );
|
||||
|
||||
typedef long (*tWlanReadInteruptPin)(void);
|
||||
|
||||
typedef void (*tWlanInterruptEnable)(void);
|
||||
|
||||
typedef void (*tWlanInterruptDisable)(void);
|
||||
|
||||
typedef void (*tWriteWlanPin)(unsigned char val);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usRxEventOpcode;
|
||||
unsigned short usEventOrDataReceived;
|
||||
unsigned char *pucReceivedData;
|
||||
unsigned char *pucTxCommandBuffer;
|
||||
|
||||
tFWPatches sFWPatches;
|
||||
tDriverPatches sDriverPatches;
|
||||
tBootLoaderPatches sBootLoaderPatches;
|
||||
tWlanCB sWlanCB;
|
||||
tWlanReadInteruptPin ReadWlanInterruptPin;
|
||||
tWlanInterruptEnable WlanInterruptEnable;
|
||||
tWlanInterruptDisable WlanInterruptDisable;
|
||||
tWriteWlanPin WriteWlanPin;
|
||||
|
||||
signed long slTransmitDataError;
|
||||
unsigned short usNumberOfFreeBuffers;
|
||||
unsigned short usSlBufferLength;
|
||||
unsigned short usBufferSize;
|
||||
unsigned short usRxDataPending;
|
||||
|
||||
unsigned long NumberOfSentPackets;
|
||||
unsigned long NumberOfReleasedPackets;
|
||||
|
||||
unsigned char InformHostOnTxComplete;
|
||||
}sSimplLinkInformation;
|
||||
|
||||
extern volatile sSimplLinkInformation tSLInformation;
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Prototypes for the APIs.
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! SimpleLinkWaitEvent
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param pRetParams command return parameters
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Wait for event, pass it to the hci_event_handler and
|
||||
//! update the event opcode in a global variable.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern void SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! SimpleLinkWaitData
|
||||
//!
|
||||
//! @param pBuf data buffer
|
||||
//! @param from from information
|
||||
//! @param fromlen from information length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Wait for data, pass it to the hci_event_handler
|
||||
//! and update in a global variable that there is
|
||||
//! data to read.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern uint16_t STREAM_TO_UINT16_f(char* p, uint16_t 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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern uint32_t STREAM_TO_UINT32_f(char* p, uint16_t offset);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! cc3k_int_poll
|
||||
//!
|
||||
//! \brief checks if the interrupt pin is low
|
||||
//! just in case the hardware missed a falling edge
|
||||
//! function is in ccspi.cpp
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern void cc3k_int_poll();
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// COMMON MACROs
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//This macro is used for copying 8 bit to stream while converting to little endian format.
|
||||
#define UINT8_TO_STREAM(_p, _val) {*(_p)++ = (_val);}
|
||||
//This macro is used for copying 16 bit to stream while converting to little endian format.
|
||||
#define UINT16_TO_STREAM(_p, _u16) (UINT16_TO_STREAM_f(_p, _u16))
|
||||
//This macro is used for copying 32 bit to stream while converting to little endian format.
|
||||
#define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32))
|
||||
//This macro is used for copying a specified value length bits (l) to stream while converting to little endian format.
|
||||
#define ARRAY_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(p)++ = ((uint8_t *) a)[_i];}
|
||||
//This macro is used for copying received stream to 8 bit in little endian format.
|
||||
#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (uint8_t)(*(_p + _offset));}
|
||||
//This macro is used for copying received stream to 16 bit in little endian format.
|
||||
#define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);}
|
||||
//This macro is used for copying received stream to 32 bit in little endian format.
|
||||
#define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);}
|
||||
#define STREAM_TO_STREAM(p, a, l) {register short _i; for (_i = 0; _i < l; _i++) *(a)++= ((uint8_t *) p)[_i];}
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __COMMON_H__
|
|
@ -0,0 +1,56 @@
|
|||
/**************************************************************************/
|
||||
/*!
|
||||
@file Adafruit_CC3000.cpp
|
||||
@author KTOWN (Kevin Townsend for Adafruit Industries)
|
||||
@license BSD (see license.txt)
|
||||
|
||||
This is a library for the Adafruit CC3000 WiFi breakout board
|
||||
This library works with the Adafruit CC3000 breakout
|
||||
----> https://www.adafruit.com/products/1469
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams
|
||||
These chips use SPI to communicate.
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
@section HISTORY
|
||||
|
||||
v1.0 - Initial release
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
//#include <Arduino.h>
|
||||
|
||||
#ifndef _CC3000_DEBUG
|
||||
#define _CC3000_DEBUG
|
||||
|
||||
#define DEBUG_MODE (0)
|
||||
|
||||
#define PRINT_F(__s) DEBUGPRINT(FLASHIFY(__s))
|
||||
|
||||
#if (DEBUG_MODE != 0)
|
||||
#define DEBUGPRINT_F(__s) DEBUGPRINT(FLASHIFY(__s))
|
||||
#define DEBUGPRINT_DEC(x) printDec(x)
|
||||
#define DEBUGPRINT_DEC16(x) printDec16(x)
|
||||
#define DEBUGPRINT_HEX(x) printHex(x)
|
||||
#define DEBUGPRINT_HEX16(x) printHex16(x)
|
||||
#else
|
||||
#define DEBUGPRINT_F(__s) /* do nothing! */
|
||||
#define DEBUGPRINT_DEC(x)
|
||||
#define DEBUGPRINT_DEC16(x)
|
||||
#define DEBUGPRINT_HEX(x)
|
||||
#define DEBUGPRINT_HEX16(x)
|
||||
#endif
|
||||
|
||||
#if 1 // print debugging info
|
||||
#define DEBUG_PRINT (1)
|
||||
#define DEBUG_printf(args...) printf(args)
|
||||
#else // don't print debugging info
|
||||
#define DEBUG_printf(args...) (void)0
|
||||
#endif
|
||||
|
||||
int printf(const char *fmt, ...);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,737 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* spi.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include <string.h> // for memset
|
||||
|
||||
#include "ccspi.h"
|
||||
#include "hci.h"
|
||||
#include "netapp.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "cc3000_common.h"
|
||||
#include "ccdebug.h"
|
||||
#include "pybcc3k.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)
|
||||
|
||||
// CC3000 chip select
|
||||
#define CC3000_ASSERT_CS() pyb_cc3000_set_cs(0)
|
||||
// CC3000 chip deselect
|
||||
#define CC3000_DEASSERT_CS() pyb_cc3000_set_cs(1)
|
||||
|
||||
/* smartconfig flags (defined in Adafruit_CC3000.cpp) */
|
||||
// extern unsigned long ulSmartConfigFinished, ulCC3000DHCP;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gcSpiHandleRx SPIRxHandler;
|
||||
|
||||
unsigned short usTxPacketLength;
|
||||
unsigned short usRxPacketLength;
|
||||
unsigned long ulSpiState;
|
||||
unsigned char *pTxPacket;
|
||||
unsigned char *pRxPacket;
|
||||
|
||||
} tSpiInformation;
|
||||
|
||||
tSpiInformation sSpiInformation;
|
||||
|
||||
/* Static buffer for 5 bytes of SPI HEADER */
|
||||
//unsigned char tSpiReadHeader[] = {READ, 0, 0, 0, 0};
|
||||
|
||||
void SpiWriteDataSynchronous(unsigned char *data, unsigned short size);
|
||||
void SpiWriteAsync(const unsigned char *data, unsigned short size);
|
||||
void SpiPauseSpi(void);
|
||||
void SpiResumeSpi(void);
|
||||
void SSIContReadOperation(void);
|
||||
void cc3k_int_poll(void);
|
||||
|
||||
// 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];
|
||||
unsigned char wlan_tx_buffer[CC3000_TX_BUFFER_SIZE];
|
||||
|
||||
static volatile char ccspi_is_in_irq = 0;
|
||||
static volatile char ccspi_int_enabled = 0;
|
||||
|
||||
/* Mandatory functions are:
|
||||
- SpiOpen
|
||||
- SpiWrite
|
||||
- SpiRead
|
||||
- SpiClose
|
||||
- SpiResumeSpi
|
||||
- ReadWlanInterruptPin
|
||||
- WlanInterruptEnable
|
||||
- WlanInterruptDisable
|
||||
- WriteWlanPin
|
||||
*/
|
||||
|
||||
void SpiInit(void)
|
||||
{
|
||||
pyb_cc3000_spi_init();
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiClose(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiClose");
|
||||
|
||||
if (sSpiInformation.pRxPacket)
|
||||
{
|
||||
sSpiInformation.pRxPacket = 0;
|
||||
}
|
||||
|
||||
/* Disable Interrupt in GPIOA module... */
|
||||
tSLInformation.WlanInterruptDisable();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiOpen(gcSpiHandleRx pfRxHandler)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiOpen");
|
||||
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_POWERUP;
|
||||
|
||||
memset(spi_buffer, 0, sizeof(spi_buffer));
|
||||
memset(wlan_tx_buffer, 0, sizeof(spi_buffer));
|
||||
|
||||
sSpiInformation.SPIRxHandler = pfRxHandler;
|
||||
sSpiInformation.usTxPacketLength = 0;
|
||||
sSpiInformation.pTxPacket = NULL;
|
||||
sSpiInformation.pRxPacket = (unsigned char *)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;
|
||||
|
||||
/* Enable interrupt on the GPIO pin of WLAN IRQ */
|
||||
tSLInformation.WlanInterruptEnable();
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: Finished SpiOpen\n\r");
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
#if 0
|
||||
extern uint8_t g_csPin, g_irqPin, g_vbatPin, g_IRQnum, g_SPIspeed;
|
||||
|
||||
int init_spi(void)
|
||||
{
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: init_spi\n\r");
|
||||
|
||||
/* Set POWER_EN pin to output and disable the CC3000 by default */
|
||||
pinMode(g_vbatPin, OUTPUT);
|
||||
digitalWrite(g_vbatPin, 0);
|
||||
delay(500);
|
||||
|
||||
/* Set CS pin to output (don't de-assert yet) */
|
||||
pinMode(g_csPin, OUTPUT);
|
||||
|
||||
/* Set interrupt/gpio pin to input */
|
||||
#if defined(INPUT_PULLUP)
|
||||
pinMode(g_irqPin, INPUT_PULLUP);
|
||||
#else
|
||||
pinMode(g_irqPin, INPUT);
|
||||
digitalWrite(g_irqPin, HIGH); // w/weak pullup
|
||||
#endif
|
||||
|
||||
/* Initialise SPI (Mode 1) */
|
||||
SPI.begin();
|
||||
SPI.setDataMode(SPI_MODE1);
|
||||
SPI.setBitOrder(MSBFIRST);
|
||||
SPI.setClockDivider(g_SPIspeed);
|
||||
|
||||
// Newly-initialized SPI is in the same state that ASSERT_CS will set it
|
||||
// to. Invoke DEASSERT (which also restores SPI registers) so the next
|
||||
// ASSERT call won't clobber the ccspi_old* values -- we need those!
|
||||
CC3000_DEASSERT_CS();
|
||||
|
||||
/* ToDo: Configure IRQ interrupt! */
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: Finished init_spi\n\r");
|
||||
|
||||
return(ESUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
long SpiFirstWrite(unsigned char *ucBuf, unsigned short usLength)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiWriteFirst\n\r");
|
||||
|
||||
/* Workaround for the first transaction */
|
||||
CC3000_ASSERT_CS();
|
||||
|
||||
/* delay (stay low) for ~50us */
|
||||
pyb_delay_us(50);
|
||||
|
||||
/* SPI writes first 4 bytes of data */
|
||||
SpiWriteDataSynchronous(ucBuf, 4);
|
||||
|
||||
pyb_delay_us(50);
|
||||
|
||||
SpiWriteDataSynchronous(ucBuf + 4, usLength - 4);
|
||||
|
||||
/* From this point on - operate in a regular manner */
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
|
||||
|
||||
CC3000_DEASSERT_CS();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength)
|
||||
{
|
||||
unsigned char ucPad = 0;
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: SpiWrite\n\r");
|
||||
|
||||
/* 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)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: Error - No magic number found in SpiWrite\n\r");
|
||||
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 */
|
||||
CC3000_ASSERT_CS();
|
||||
|
||||
/* 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;
|
||||
|
||||
CC3000_DEASSERT_CS();
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiWriteDataSynchronous(unsigned char *data, unsigned short size)
|
||||
{
|
||||
int bSend = 0, bRecv = 0;
|
||||
while (bSend<size || bRecv<size) {
|
||||
int r = pyb_cc3000_spi_send((bSend<size)?data[bSend]:-1);
|
||||
bSend++;
|
||||
if (bSend>0 && r>=0) bRecv++;
|
||||
}
|
||||
|
||||
pyb_delay_us(10); // because of final clock pulse
|
||||
|
||||
DEBUG_printf("SpiWriteDataSynchronous: data=%p size=%u bSend=%d bRecv=%d [%x %x %x %x]\n", data, size, bSend, bRecv, data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiReadDataSynchronous(unsigned char *data, unsigned short size)
|
||||
{
|
||||
int bSend = 0, bRecv = 0;
|
||||
while (bSend<size || bRecv<size) {
|
||||
int r = pyb_cc3000_spi_send((bSend<size)?READ:-1);
|
||||
bSend++;
|
||||
if (bSend>0 && r>=0) data[bRecv++] = r;
|
||||
}
|
||||
|
||||
pyb_delay_us(10); // because of final clock pulse
|
||||
|
||||
DEBUG_printf("SpiReadDataSynchronous: data=%p size=%u bSend=%d bRecv=%d [%x %x %x %x]\n", data, size, bSend, bRecv, data[0], data[1], data[2], data[3]);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiReadHeader(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiReadHeader\n\r");
|
||||
|
||||
SpiReadDataSynchronous(sSpiInformation.pRxPacket, HEADERS_SIZE_EVNT);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
long SpiReadDataCont(void)
|
||||
{
|
||||
long data_to_recv;
|
||||
unsigned char *evnt_buff, type;
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: SpiReadDataCont\n\r");
|
||||
|
||||
/* Determine what type of packet we have */
|
||||
evnt_buff = sSpiInformation.pRxPacket;
|
||||
data_to_recv = 0;
|
||||
STREAM_TO_UINT8((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case HCI_TYPE_DATA:
|
||||
{
|
||||
/* 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 + HEADERS_SIZE_EVNT, 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 + HEADERS_SIZE_EVNT, data_to_recv);
|
||||
}
|
||||
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiPauseSpi(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiPauseSpi\n\r");
|
||||
|
||||
ccspi_int_enabled = 0;
|
||||
pyb_cc3000_pause_spi();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiResumeSpi(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiResumeSpi\n\r");
|
||||
|
||||
ccspi_int_enabled = 1;
|
||||
pyb_cc3000_resume_spi();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SpiTriggerRxProcessing(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiTriggerRxProcessing\n\r");
|
||||
|
||||
/* Trigger Rx processing */
|
||||
SpiPauseSpi();
|
||||
CC3000_DEASSERT_CS();
|
||||
|
||||
//DEBUGPRINT_F("Magic?\n\r");
|
||||
/* 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)
|
||||
{
|
||||
/* You've got problems if you're here! */
|
||||
DEBUGPRINT_F("\tCC3000: ERROR - magic number missing!\n\r");
|
||||
while (1);
|
||||
}
|
||||
|
||||
//DEBUGPRINT_F("OK!\n\r");
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
|
||||
sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket + SPI_HEADER_SIZE);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void SSIContReadOperation(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: SpiContReadOperation\n\r");
|
||||
|
||||
/* 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 */
|
||||
//DEBUGPRINT_F("SPItrig\n\r");
|
||||
SpiTriggerRxProcessing();
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void WriteWlanPin( unsigned char val )
|
||||
{
|
||||
#if 0
|
||||
if (DEBUG_MODE)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: WriteWlanPin - ");
|
||||
DEBUGPRINT_DEC(val);
|
||||
DEBUGPRINT_F("\n\r");
|
||||
delay(1);
|
||||
}
|
||||
if (val)
|
||||
{
|
||||
digitalWrite(g_vbatPin, HIGH);
|
||||
}
|
||||
else
|
||||
{
|
||||
digitalWrite(g_vbatPin, LOW);
|
||||
}
|
||||
#endif
|
||||
pyb_cc3000_set_en(val == WLAN_ENABLE);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
long ReadWlanInterruptPin(void)
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: ReadWlanInterruptPin - ");
|
||||
DEBUGPRINT_DEC(digitalRead(g_irqPin));
|
||||
DEBUGPRINT_F("\n\r");
|
||||
|
||||
return pyb_cc3000_get_irq();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void WlanInterruptEnable()
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: WlanInterruptEnable.\n\r");
|
||||
// delay(100);
|
||||
ccspi_int_enabled = 1;
|
||||
pyb_cc3000_enable_irq();
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void WlanInterruptDisable()
|
||||
{
|
||||
DEBUGPRINT_F("\tCC3000: WlanInterruptDisable\n\r");
|
||||
ccspi_int_enabled = 0;
|
||||
pyb_cc3000_disable_irq();
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! sendDriverPatch
|
||||
//!
|
||||
//! @param pointer to the length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief The function returns a pointer to the driver patch:
|
||||
//! since there is no patch in the host - it returns 0
|
||||
//
|
||||
//*****************************************************************************
|
||||
char *sendDriverPatch(unsigned long *Length) {
|
||||
*Length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! sendBootLoaderPatch
|
||||
//!
|
||||
//! @param pointer to the length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief The function returns a pointer to the boot loader patch:
|
||||
//! since there is no patch in the host - it returns 0
|
||||
//
|
||||
//*****************************************************************************
|
||||
char *sendBootLoaderPatch(unsigned long *Length) {
|
||||
*Length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! sendWLFWPatch
|
||||
//!
|
||||
//! @param pointer to the length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief The function returns a pointer to the FW patch:
|
||||
//! since there is no patch in the host - it returns 0
|
||||
//
|
||||
//*****************************************************************************
|
||||
char *sendWLFWPatch(unsigned long *Length) {
|
||||
*Length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
||||
*/
|
||||
/**************************************************************************/
|
||||
|
||||
void SpiIntGPIOHandler(void)
|
||||
{
|
||||
DEBUG_printf("SpiIntGPIOHandler\n");
|
||||
|
||||
ccspi_is_in_irq = 1;
|
||||
|
||||
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 - we are start reception */
|
||||
CC3000_ASSERT_CS();
|
||||
|
||||
// Wait for TX/RX Compete 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;
|
||||
|
||||
CC3000_DEASSERT_CS();
|
||||
}
|
||||
ccspi_is_in_irq = 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void SPI_IRQ(void)
|
||||
{
|
||||
ccspi_is_in_irq = 1;
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: Entering SPI_IRQ\n\r");
|
||||
|
||||
if (sSpiInformation.ulSpiState == eSPI_STATE_POWERUP)
|
||||
{
|
||||
/* IRQ line was low ... perform a callback on the HCI Layer */
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_INITIALIZED;
|
||||
}
|
||||
else if (sSpiInformation.ulSpiState == eSPI_STATE_IDLE)
|
||||
{
|
||||
//DEBUGPRINT_F("IDLE\n\r");
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_READ_IRQ;
|
||||
/* IRQ line goes down - start reception */
|
||||
|
||||
CC3000_ASSERT_CS();
|
||||
|
||||
// Wait for TX/RX Compete which will come as DMA interrupt
|
||||
SpiReadHeader();
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_READ_EOT;
|
||||
//DEBUGPRINT_F("SSICont\n\r");
|
||||
SSIContReadOperation();
|
||||
}
|
||||
else if (sSpiInformation.ulSpiState == eSPI_STATE_WRITE_IRQ)
|
||||
{
|
||||
SpiWriteDataSynchronous(sSpiInformation.pTxPacket, sSpiInformation.usTxPacketLength);
|
||||
sSpiInformation.ulSpiState = eSPI_STATE_IDLE;
|
||||
CC3000_DEASSERT_CS();
|
||||
}
|
||||
|
||||
DEBUGPRINT_F("\tCC3000: Leaving SPI_IRQ\n\r");
|
||||
|
||||
ccspi_is_in_irq = 0;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! cc3k_int_poll
|
||||
//!
|
||||
//! \brief checks if the interrupt pin is low
|
||||
//! just in case the hardware missed a falling edge
|
||||
//! function is in ccspi.cpp
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void cc3k_int_poll()
|
||||
{
|
||||
if (pyb_cc3000_get_irq() == 0 && ccspi_is_in_irq == 0 && ccspi_int_enabled != 0) {
|
||||
SpiIntGPIOHandler();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* spi.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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_H__
|
||||
#define __SPI_H__
|
||||
|
||||
//#include <string.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <stdio.h>
|
||||
|
||||
//#include "wlan.h"
|
||||
|
||||
typedef void (*gcSpiHandleRx)(void *p);
|
||||
typedef void (*gcSpiHandleTx)(void);
|
||||
|
||||
extern unsigned char wlan_tx_buffer[];
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void SpiInit(void);
|
||||
extern void SpiOpen(gcSpiHandleRx pfRxHandler);
|
||||
extern void SpiClose(void);
|
||||
extern long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength);
|
||||
extern void SpiResumeSpi(void);
|
||||
extern void SpiCleanGPIOISR(void);
|
||||
extern long TXBufferIsEmpty(void);
|
||||
extern long RXBufferIsEmpty(void);
|
||||
extern void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length);
|
||||
extern void WriteWlanPin( unsigned char val );
|
||||
extern long ReadWlanInterruptPin(void);
|
||||
extern void WlanInterruptEnable();
|
||||
extern void WlanInterruptDisable();
|
||||
extern char *sendDriverPatch(unsigned long *Length);
|
||||
extern char *sendBootLoaderPatch(unsigned long *Length);
|
||||
extern char *sendWLFWPatch(unsigned long *Length);
|
||||
extern void SpiIntGPIOHandler(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,873 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* evnt_handler.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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 evnt_handler_api
|
||||
//! @{
|
||||
//
|
||||
//******************************************************************************
|
||||
|
||||
//******************************************************************************
|
||||
// INCLUDE FILES
|
||||
//******************************************************************************
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cc3000_common.h"
|
||||
#include "string.h"
|
||||
#include "hci.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "wlan.h"
|
||||
#include "socket.h"
|
||||
#include "netapp.h"
|
||||
#include "ccspi.h"
|
||||
#include "ccdebug.h"
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// COMMON DEFINES
|
||||
//*****************************************************************************
|
||||
|
||||
#define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0)
|
||||
#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1)
|
||||
#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2)
|
||||
#define FLOW_CONTROL_EVENT_SIZE (4)
|
||||
|
||||
#define BSD_RSP_PARAMS_SOCKET_OFFSET (0)
|
||||
#define BSD_RSP_PARAMS_STATUS_OFFSET (4)
|
||||
|
||||
#define GET_HOST_BY_NAME_RETVAL_OFFSET (0)
|
||||
#define GET_HOST_BY_NAME_ADDR_OFFSET (4)
|
||||
|
||||
#define ACCEPT_SD_OFFSET (0)
|
||||
#define ACCEPT_RETURN_STATUS_OFFSET (4)
|
||||
#define ACCEPT_ADDRESS__OFFSET (8)
|
||||
|
||||
#define SL_RECEIVE_SD_OFFSET (0)
|
||||
#define SL_RECEIVE_NUM_BYTES_OFFSET (4)
|
||||
#define SL_RECEIVE__FLAGS__OFFSET (8)
|
||||
|
||||
|
||||
#define SELECT_STATUS_OFFSET (0)
|
||||
#define SELECT_READFD_OFFSET (4)
|
||||
#define SELECT_WRITEFD_OFFSET (8)
|
||||
#define SELECT_EXFD_OFFSET (12)
|
||||
|
||||
|
||||
#define NETAPP_IPCONFIG_IP_OFFSET (0)
|
||||
#define NETAPP_IPCONFIG_SUBNET_OFFSET (4)
|
||||
#define NETAPP_IPCONFIG_GW_OFFSET (8)
|
||||
#define NETAPP_IPCONFIG_DHCP_OFFSET (12)
|
||||
#define NETAPP_IPCONFIG_DNS_OFFSET (16)
|
||||
#define NETAPP_IPCONFIG_MAC_OFFSET (20)
|
||||
#define NETAPP_IPCONFIG_SSID_OFFSET (26)
|
||||
|
||||
#define NETAPP_IPCONFIG_IP_LENGTH (4)
|
||||
#define NETAPP_IPCONFIG_MAC_LENGTH (6)
|
||||
#define NETAPP_IPCONFIG_SSID_LENGTH (32)
|
||||
|
||||
|
||||
#define NETAPP_PING_PACKETS_SENT_OFFSET (0)
|
||||
#define NETAPP_PING_PACKETS_RCVD_OFFSET (4)
|
||||
#define NETAPP_PING_MIN_RTT_OFFSET (8)
|
||||
#define NETAPP_PING_MAX_RTT_OFFSET (12)
|
||||
#define NETAPP_PING_AVG_RTT_OFFSET (16)
|
||||
|
||||
#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0)
|
||||
#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4)
|
||||
#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8)
|
||||
#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10)
|
||||
#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38)
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// GLOBAL VARAIABLES
|
||||
//*****************************************************************************
|
||||
|
||||
unsigned long socket_active_status = SOCKET_STATUS_INIT_VAL;
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// Prototypes for the static functions
|
||||
//*****************************************************************************
|
||||
|
||||
static long hci_event_unsol_flowcontrol_handler(char *pEvent);
|
||||
|
||||
static void update_socket_active_status(char *resp_params);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_unsol_handle_patch_request
|
||||
//!
|
||||
//! @param event_hdr event header
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Handle unsolicited event from type patch request
|
||||
//
|
||||
//*****************************************************************************
|
||||
void hci_unsol_handle_patch_request(char *event_hdr)
|
||||
{
|
||||
char *params = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
|
||||
unsigned long ucLength = 0;
|
||||
char *patch;
|
||||
|
||||
switch (*params)
|
||||
{
|
||||
case HCI_EVENT_PATCHES_DRV_REQ:
|
||||
|
||||
if (tSLInformation.sDriverPatches)
|
||||
{
|
||||
patch = tSLInformation.sDriverPatches(&ucLength);
|
||||
|
||||
if (patch)
|
||||
{
|
||||
hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, patch, ucLength);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Send 0 length Patches response event
|
||||
hci_patch_send(HCI_EVENT_PATCHES_DRV_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, 0, 0);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PATCHES_FW_REQ:
|
||||
|
||||
if (tSLInformation.sFWPatches)
|
||||
{
|
||||
patch = tSLInformation.sFWPatches(&ucLength);
|
||||
|
||||
// Build and send a patch
|
||||
if (patch)
|
||||
{
|
||||
hci_patch_send(HCI_EVENT_PATCHES_FW_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, patch, ucLength);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Send 0 length Patches response event
|
||||
hci_patch_send(HCI_EVENT_PATCHES_FW_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, 0, 0);
|
||||
break;
|
||||
|
||||
case HCI_EVENT_PATCHES_BOOTLOAD_REQ:
|
||||
|
||||
if (tSLInformation.sBootLoaderPatches)
|
||||
{
|
||||
patch = tSLInformation.sBootLoaderPatches(&ucLength);
|
||||
|
||||
if (patch)
|
||||
{
|
||||
hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, patch, ucLength);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Send 0 length Patches response event
|
||||
hci_patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ,
|
||||
tSLInformation.pucTxCommandBuffer, 0, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_event_handler
|
||||
//!
|
||||
//! @param pRetParams incoming data buffer
|
||||
//! @param from from information (in case of data received)
|
||||
//! @param fromlen from information length (in case of data received)
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Parse the incoming events packets and issues corresponding
|
||||
//! event handler from global array of handlers pointers
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
unsigned char *
|
||||
hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
|
||||
{
|
||||
unsigned char *pucReceivedData, ucArgsize;
|
||||
unsigned short usLength;
|
||||
unsigned char *pucReceivedParams;
|
||||
unsigned short usReceivedEventOpcode = 0;
|
||||
unsigned long retValue32;
|
||||
unsigned char * RecvParams;
|
||||
unsigned char *RetParams;
|
||||
|
||||
while (1)
|
||||
{
|
||||
cc3k_int_poll();
|
||||
|
||||
if (tSLInformation.usEventOrDataReceived != 0)
|
||||
{
|
||||
|
||||
pucReceivedData = (tSLInformation.pucReceivedData);
|
||||
|
||||
if (*pucReceivedData == HCI_TYPE_EVNT)
|
||||
{
|
||||
// Event Received
|
||||
STREAM_TO_UINT16((char *)pucReceivedData,
|
||||
HCI_EVENT_OPCODE_OFFSET,
|
||||
usReceivedEventOpcode);
|
||||
pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE;
|
||||
RecvParams = pucReceivedParams;
|
||||
RetParams = (unsigned char *)pRetParams;
|
||||
|
||||
// In case unsolicited event received - here the handling finished
|
||||
if (hci_unsol_event_handler((char *)pucReceivedData) == 0)
|
||||
{
|
||||
STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength);
|
||||
|
||||
switch(usReceivedEventOpcode)
|
||||
{
|
||||
case HCI_CMND_READ_BUFFER_SIZE:
|
||||
{
|
||||
STREAM_TO_UINT8((char *)pucReceivedParams, 0,
|
||||
tSLInformation.usNumberOfFreeBuffers);
|
||||
STREAM_TO_UINT16((char *)pucReceivedParams, 1,
|
||||
tSLInformation.usSlBufferLength);
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_CMND_WLAN_CONFIGURE_PATCH:
|
||||
case HCI_NETAPP_DHCP:
|
||||
case HCI_NETAPP_PING_SEND:
|
||||
case HCI_NETAPP_PING_STOP:
|
||||
case HCI_NETAPP_ARP_FLUSH:
|
||||
case HCI_NETAPP_SET_DEBUG_LEVEL:
|
||||
case HCI_NETAPP_SET_TIMERS:
|
||||
case HCI_EVNT_NVMEM_READ:
|
||||
case HCI_EVNT_NVMEM_CREATE_ENTRY:
|
||||
case HCI_CMND_NVMEM_WRITE_PATCH:
|
||||
case HCI_NETAPP_PING_REPORT:
|
||||
case HCI_EVNT_MDNS_ADVERTISE:
|
||||
|
||||
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
|
||||
,*(unsigned char *)pRetParams);
|
||||
break;
|
||||
|
||||
case HCI_CMND_SETSOCKOPT:
|
||||
case HCI_CMND_WLAN_CONNECT:
|
||||
case HCI_CMND_WLAN_IOCTL_STATUSGET:
|
||||
case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
|
||||
case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
|
||||
case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
|
||||
case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
|
||||
case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
|
||||
case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
|
||||
case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
|
||||
case HCI_CMND_EVENT_MASK:
|
||||
case HCI_EVNT_WLAN_DISCONNECT:
|
||||
case HCI_EVNT_SOCKET:
|
||||
case HCI_EVNT_BIND:
|
||||
case HCI_CMND_LISTEN:
|
||||
case HCI_EVNT_CLOSE_SOCKET:
|
||||
case HCI_EVNT_CONNECT:
|
||||
case HCI_EVNT_NVMEM_WRITE:
|
||||
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,0
|
||||
,*(unsigned long *)pRetParams);
|
||||
break;
|
||||
|
||||
case HCI_EVNT_READ_SP_VERSION:
|
||||
|
||||
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
|
||||
,*(unsigned char *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 1;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32);
|
||||
UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32);
|
||||
break;
|
||||
|
||||
case HCI_EVNT_BSD_GETHOSTBYNAME:
|
||||
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams
|
||||
,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams
|
||||
,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams);
|
||||
break;
|
||||
|
||||
case HCI_EVNT_ACCEPT:
|
||||
{
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET
|
||||
,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams
|
||||
,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
|
||||
//This argument returns in network order
|
||||
memcpy((unsigned char *)pRetParams,
|
||||
pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
|
||||
break;
|
||||
}
|
||||
|
||||
case HCI_EVNT_RECV:
|
||||
case HCI_EVNT_RECVFROM:
|
||||
{
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams);
|
||||
//tBsdReadReturnParams *tread = (tBsdReadReturnParams *)pRetParams; // unused
|
||||
if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
|
||||
{
|
||||
set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case HCI_EVNT_SEND:
|
||||
case HCI_EVNT_SENDTO:
|
||||
{
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case HCI_EVNT_SELECT:
|
||||
{
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams);
|
||||
break;
|
||||
}
|
||||
|
||||
case HCI_CMND_GETSOCKOPT:
|
||||
|
||||
STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus);
|
||||
//This argument returns in network order
|
||||
memcpy((unsigned char *)pRetParams, pucReceivedParams, 4);
|
||||
break;
|
||||
|
||||
case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
|
||||
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 4;
|
||||
STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 2;
|
||||
STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams);
|
||||
pRetParams = ((char *)pRetParams) + 2;
|
||||
memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);
|
||||
break;
|
||||
|
||||
case HCI_CMND_SIMPLE_LINK_START:
|
||||
break;
|
||||
|
||||
case HCI_NETAPP_IPCONFIG:
|
||||
|
||||
//Read IP address
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
RecvParams += 4;
|
||||
|
||||
//Read subnet
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
RecvParams += 4;
|
||||
|
||||
//Read default GW
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
RecvParams += 4;
|
||||
|
||||
//Read DHCP server
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
RecvParams += 4;
|
||||
|
||||
//Read DNS server
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
RecvParams += 4;
|
||||
|
||||
//Read Mac address
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
|
||||
RecvParams += 6;
|
||||
|
||||
//Read SSID
|
||||
STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode)
|
||||
{
|
||||
tSLInformation.usRxEventOpcode = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pucReceivedParams = pucReceivedData;
|
||||
STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize);
|
||||
|
||||
STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength);
|
||||
|
||||
// Data received: note that the only case where from and from length
|
||||
// are not null is in recv from, so fill the args accordingly
|
||||
if (from)
|
||||
{
|
||||
STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen);
|
||||
memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
|
||||
}
|
||||
|
||||
memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize,
|
||||
usLength - ucArgsize);
|
||||
|
||||
tSLInformation.usRxDataPending = 0;
|
||||
}
|
||||
|
||||
tSLInformation.usEventOrDataReceived = 0;
|
||||
|
||||
SpiResumeSpi();
|
||||
|
||||
// Since we are going to TX - we need to handle this event after the
|
||||
// ResumeSPi since we need interrupts
|
||||
if ((*pucReceivedData == HCI_TYPE_EVNT) &&
|
||||
(usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ))
|
||||
{
|
||||
hci_unsol_handle_patch_request((char *)pucReceivedData);
|
||||
}
|
||||
|
||||
if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_unsol_event_handler
|
||||
//!
|
||||
//! @param event_hdr event header
|
||||
//!
|
||||
//! @return 1 if event supported and handled
|
||||
//! 0 if event is not supported
|
||||
//!
|
||||
//! @brief Handle unsolicited events
|
||||
//
|
||||
//*****************************************************************************
|
||||
long
|
||||
hci_unsol_event_handler(char *event_hdr)
|
||||
{
|
||||
char * data = NULL;
|
||||
long event_type;
|
||||
unsigned long NumberOfReleasedPackets;
|
||||
unsigned long NumberOfSentPackets;
|
||||
|
||||
STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type);
|
||||
|
||||
DEBUGPRINT_F("\tHCI_UNSOL_EVT: ");
|
||||
DEBUGPRINT_HEX16(event_type);
|
||||
|
||||
if (event_type & HCI_EVNT_UNSOL_BASE)
|
||||
{
|
||||
switch(event_type)
|
||||
{
|
||||
|
||||
case HCI_EVNT_DATA_UNSOL_FREE_BUFF:
|
||||
{
|
||||
hci_event_unsol_flowcontrol_handler(event_hdr);
|
||||
|
||||
NumberOfReleasedPackets = tSLInformation.NumberOfReleasedPackets;
|
||||
NumberOfSentPackets = tSLInformation.NumberOfSentPackets;
|
||||
|
||||
if (NumberOfReleasedPackets == NumberOfSentPackets)
|
||||
{
|
||||
if (tSLInformation.InformHostOnTxComplete)
|
||||
{
|
||||
tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(event_type & HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
{
|
||||
switch(event_type)
|
||||
{
|
||||
case HCI_EVNT_WLAN_KEEPALIVE:
|
||||
case HCI_EVNT_WLAN_UNSOL_CONNECT:
|
||||
case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
|
||||
case HCI_EVNT_WLAN_UNSOL_INIT:
|
||||
case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:
|
||||
|
||||
if( tSLInformation.sWlanCB )
|
||||
{
|
||||
tSLInformation.sWlanCB(event_type, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVNT_WLAN_UNSOL_DHCP:
|
||||
{
|
||||
unsigned char params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status
|
||||
unsigned char *recParams = params;
|
||||
|
||||
data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
|
||||
|
||||
//Read IP address
|
||||
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
data += 4;
|
||||
//Read subnet
|
||||
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
data += 4;
|
||||
//Read default GW
|
||||
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
data += 4;
|
||||
//Read DHCP server
|
||||
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
data += 4;
|
||||
//Read DNS server
|
||||
STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH);
|
||||
// read the status
|
||||
STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);
|
||||
|
||||
|
||||
if( tSLInformation.sWlanCB )
|
||||
{
|
||||
tSLInformation.sWlanCB(event_type, (char *)params, sizeof(params));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
|
||||
{
|
||||
netapp_pingreport_args_t params;
|
||||
data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
|
||||
STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
|
||||
STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
|
||||
STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
|
||||
STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
|
||||
STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);
|
||||
|
||||
if( tSLInformation.sWlanCB )
|
||||
{
|
||||
tSLInformation.sWlanCB(event_type, (char *)¶ms, sizeof(params));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
|
||||
{
|
||||
DEBUGPRINT_F("\tTCP Close Wait\n\r");
|
||||
uint8_t socketnum;
|
||||
data = (char*)(event_hdr) + HCI_EVENT_HEADER_SIZE;
|
||||
/*
|
||||
printHex(data[0]); PRINT_F("\t");
|
||||
printHex(data[1]); PRINT_F("\t");
|
||||
printHex(data[2]); PRINT_F("\t");
|
||||
printHex(data[3]); PRINT_F("\t");
|
||||
printHex(data[4]); PRINT_F("\t");
|
||||
printHex(data[5]); PRINT_F("\t");
|
||||
*/
|
||||
socketnum = data[0];
|
||||
//STREAM_TO_UINT16(data, 0, socketnum);
|
||||
if( tSLInformation.sWlanCB )
|
||||
{
|
||||
tSLInformation.sWlanCB(event_type, (char *)&socketnum, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//'default' case which means "event not supported"
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO)
|
||||
|| (event_type == HCI_EVNT_WRITE))
|
||||
{
|
||||
char *pArg;
|
||||
long status;
|
||||
|
||||
DEBUGPRINT_F("\tSEND event response\n\r");
|
||||
|
||||
pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
|
||||
STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status);
|
||||
|
||||
if (ERROR_SOCKET_INACTIVE == status)
|
||||
{
|
||||
// The only synchronous event that can come from SL device in form of
|
||||
// command complete is "Command Complete" on data sent, in case SL device
|
||||
// was unable to transmit
|
||||
STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, tSLInformation.slTransmitDataError);
|
||||
update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));
|
||||
|
||||
return (1);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_unsolicited_event_handler
|
||||
//!
|
||||
//! @param None
|
||||
//!
|
||||
//! @return ESUCCESS if successful, EFAIL if an error occurred
|
||||
//!
|
||||
//! @brief Parse the incoming unsolicited event packets and issues
|
||||
//! corresponding event handler.
|
||||
//
|
||||
//*****************************************************************************
|
||||
long
|
||||
hci_unsolicited_event_handler(void)
|
||||
{
|
||||
unsigned long res = 0;
|
||||
unsigned char *pucReceivedData;
|
||||
|
||||
if (tSLInformation.usEventOrDataReceived != 0)
|
||||
{
|
||||
pucReceivedData = (tSLInformation.pucReceivedData);
|
||||
|
||||
if (*pucReceivedData == HCI_TYPE_EVNT)
|
||||
{
|
||||
|
||||
// In case unsolicited event received - here the handling finished
|
||||
if (hci_unsol_event_handler((char *)pucReceivedData) == 1)
|
||||
{
|
||||
|
||||
// There was an unsolicited event received - we can release the buffer
|
||||
// and clean the event received
|
||||
tSLInformation.usEventOrDataReceived = 0;
|
||||
|
||||
res = 1;
|
||||
SpiResumeSpi();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! set_socket_active_status
|
||||
//!
|
||||
//! @param Sd
|
||||
//! @param Status
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Check if the socket ID and status are valid and set
|
||||
//! accordingly the global socket status
|
||||
//
|
||||
//*****************************************************************************
|
||||
void set_socket_active_status(long Sd, long Status)
|
||||
{
|
||||
if(M_IS_VALID_SD(Sd) && M_IS_VALID_STATUS(Status))
|
||||
{
|
||||
socket_active_status &= ~(1 << Sd); /* clean socket's mask */
|
||||
socket_active_status |= (Status << Sd); /* set new socket's mask */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_event_unsol_flowcontrol_handler
|
||||
//!
|
||||
//! @param pEvent pointer to the string contains parameters for IPERF
|
||||
//! @return ESUCCESS if successful, EFAIL if an error occurred
|
||||
//!
|
||||
//! @brief Called in case unsolicited event from type
|
||||
//! HCI_EVNT_DATA_UNSOL_FREE_BUFF has received.
|
||||
//! Keep track on the number of packets transmitted and update the
|
||||
//! number of free buffer in the SL device.
|
||||
//
|
||||
//*****************************************************************************
|
||||
long
|
||||
hci_event_unsol_flowcontrol_handler(char *pEvent)
|
||||
{
|
||||
|
||||
long temp, value;
|
||||
unsigned short i;
|
||||
unsigned short pusNumberOfHandles=0;
|
||||
char *pReadPayload;
|
||||
|
||||
STREAM_TO_UINT16((char *)pEvent,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles);
|
||||
pReadPayload = ((char *)pEvent +
|
||||
HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles));
|
||||
temp = 0;
|
||||
|
||||
for(i = 0; i < pusNumberOfHandles ; i++)
|
||||
{
|
||||
STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value);
|
||||
temp += value;
|
||||
pReadPayload += FLOW_CONTROL_EVENT_SIZE;
|
||||
}
|
||||
|
||||
tSLInformation.usNumberOfFreeBuffers += temp;
|
||||
tSLInformation.NumberOfReleasedPackets += temp;
|
||||
|
||||
return(ESUCCESS);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! get_socket_active_status
|
||||
//!
|
||||
//! @param Sd Socket IS
|
||||
//! @return Current status of the socket.
|
||||
//!
|
||||
//! @brief Retrieve socket status
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
long
|
||||
get_socket_active_status(long Sd)
|
||||
{
|
||||
if(M_IS_VALID_SD(Sd))
|
||||
{
|
||||
return (socket_active_status & (1 << Sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE;
|
||||
}
|
||||
return SOCKET_STATUS_INACTIVE;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! update_socket_active_status
|
||||
//!
|
||||
//! @param resp_params Socket IS
|
||||
//! @return Current status of the socket.
|
||||
//!
|
||||
//! @brief Retrieve socket status
|
||||
//
|
||||
//*****************************************************************************
|
||||
void
|
||||
update_socket_active_status(char *resp_params)
|
||||
{
|
||||
long status, sd;
|
||||
|
||||
STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd);
|
||||
STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status);
|
||||
|
||||
if(ERROR_SOCKET_INACTIVE == status)
|
||||
{
|
||||
set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! SimpleLinkWaitEvent
|
||||
//!
|
||||
//! @param usOpcode command operation code
|
||||
//! @param pRetParams command return parameters
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Wait for event, pass it to the hci_event_handler and
|
||||
//! update the event opcode in a global variable.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void
|
||||
SimpleLinkWaitEvent(unsigned short usOpcode, void *pRetParams)
|
||||
{
|
||||
// In the blocking implementation the control to caller will be returned only
|
||||
// after the end of current transaction
|
||||
tSLInformation.usRxEventOpcode = usOpcode;
|
||||
hci_event_handler(pRetParams, 0, 0);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! SimpleLinkWaitData
|
||||
//!
|
||||
//! @param pBuf data buffer
|
||||
//! @param from from information
|
||||
//! @param fromlen from information length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Wait for data, pass it to the hci_event_handler
|
||||
//! and update in a global variable that there is
|
||||
//! data to read.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
void
|
||||
SimpleLinkWaitData(unsigned char *pBuf, unsigned char *from,
|
||||
unsigned char *fromlen)
|
||||
{
|
||||
// In the blocking implementation the control to caller will be returned only
|
||||
// after the end of current transaction, i.e. only after data will be received
|
||||
tSLInformation.usRxDataPending = 1;
|
||||
hci_event_handler(pBuf, from, fromlen);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
|
@ -0,0 +1,175 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* evnt_handler.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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 __EVENT_HANDLER_H__
|
||||
#define __EVENT_HANDLER_H__
|
||||
|
||||
#include "hci.h"
|
||||
#include "socket.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_event_handler
|
||||
//!
|
||||
//! @param pRetParams incoming data buffer
|
||||
//! @param from from information (in case of data received)
|
||||
//! @param fromlen from information length (in case of data received)
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Parse the incoming events packets and issues corresponding
|
||||
//! event handler from global array of handlers pointers
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern unsigned char *hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_unsol_event_handler
|
||||
//!
|
||||
//! @param event_hdr event header
|
||||
//!
|
||||
//! @return 1 if event supported and handled
|
||||
//! 0 if event is not supported
|
||||
//!
|
||||
//! @brief Handle unsolicited events
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long hci_unsol_event_handler(char *event_hdr);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! hci_unsolicited_event_handler
|
||||
//!
|
||||
//! @param None
|
||||
//!
|
||||
//! @return ESUCCESS if successful, EFAIL if an error occurred
|
||||
//!
|
||||
//! @brief Parse the incoming unsolicited event packets and issues
|
||||
//! corresponding event handler.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long hci_unsolicited_event_handler(void);
|
||||
|
||||
#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((char *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE)
|
||||
|
||||
#define SOCKET_STATUS_ACTIVE 0
|
||||
#define SOCKET_STATUS_INACTIVE 1
|
||||
/* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE.
|
||||
Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */
|
||||
#define SOCKET_STATUS_INIT_VAL 0xFFFF
|
||||
#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7))
|
||||
#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE))
|
||||
|
||||
extern unsigned long socket_active_status;
|
||||
|
||||
extern void set_socket_active_status(long Sd, long Status);
|
||||
extern long get_socket_active_status(long Sd);
|
||||
|
||||
typedef struct _bsd_accept_return_t
|
||||
{
|
||||
long iSocketDescriptor;
|
||||
long iStatus;
|
||||
sockaddr tSocketAddress;
|
||||
|
||||
} tBsdReturnParams;
|
||||
|
||||
|
||||
typedef struct _bsd_read_return_t
|
||||
{
|
||||
long iSocketDescriptor;
|
||||
long iNumberOfBytes;
|
||||
unsigned long uiFlags;
|
||||
} tBsdReadReturnParams;
|
||||
|
||||
#define BSD_RECV_FROM_FROMLEN_OFFSET (4)
|
||||
#define BSD_RECV_FROM_FROM_OFFSET (16)
|
||||
|
||||
|
||||
typedef struct _bsd_select_return_t
|
||||
{
|
||||
long iStatus;
|
||||
unsigned long uiRdfd;
|
||||
unsigned long uiWrfd;
|
||||
unsigned long uiExfd;
|
||||
} tBsdSelectRecvParams;
|
||||
|
||||
|
||||
typedef struct _bsd_getsockopt_return_t
|
||||
{
|
||||
unsigned char ucOptValue[4];
|
||||
char iStatus;
|
||||
} tBsdGetSockOptReturnParams;
|
||||
|
||||
typedef struct _bsd_gethostbyname_return_t
|
||||
{
|
||||
long retVal;
|
||||
long outputAddress;
|
||||
} tBsdGethostbynameParams;
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __EVENT_HANDLER_H__
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* hci.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
#include "cc3000_common.h"
|
||||
#include "hci.h"
|
||||
#include "ccspi.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "wlan.h"
|
||||
|
||||
#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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
unsigned short
|
||||
hci_command_send(unsigned short usOpcode, unsigned char *pucBuff,
|
||||
unsigned char ucArgsLength)
|
||||
{
|
||||
unsigned char *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);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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(unsigned char ucOpcode,
|
||||
unsigned char *ucArgs,
|
||||
unsigned short usArgsLength,
|
||||
unsigned short usDataLength,
|
||||
const unsigned char *ucTail,
|
||||
unsigned short usTailLength)
|
||||
{
|
||||
unsigned char *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);
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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(unsigned short usOpcode, unsigned char *pucBuff,
|
||||
unsigned char ucArgsLength,unsigned short ucDataLength)
|
||||
{
|
||||
unsigned char *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;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength)
|
||||
{
|
||||
unsigned char *data_ptr = (pucBuff + SPI_HEADER_SIZE);
|
||||
unsigned short usTransLength;
|
||||
unsigned char *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)
|
||||
{
|
||||
cc3k_int_poll();
|
||||
|
||||
if (usDataLength <= SL_PATCH_PORTION_SIZE)
|
||||
{
|
||||
usTransLength = usDataLength;
|
||||
usDataLength = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
usTransLength = SL_PATCH_PORTION_SIZE;
|
||||
usDataLength -= usTransLength;
|
||||
}
|
||||
|
||||
*(unsigned short *)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((unsigned char *)data_ptr, usTransLength + sizeof(usTransLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//
|
||||
//*****************************************************************************
|
|
@ -0,0 +1,336 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* hci.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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 __HCI_H__
|
||||
#define __HCI_H__
|
||||
|
||||
#include "cc3000_common.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define SPI_HEADER_SIZE (5)
|
||||
#define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4)
|
||||
#define HEADERS_SIZE_CMD (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE)
|
||||
#define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE (5)
|
||||
#define SIMPLE_LINK_HCI_DATA_HEADER_SIZE (5)
|
||||
#define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE (2)
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be used as HCI Commands and HCI Packet header defines
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define HCI_TYPE_CMND 0x1
|
||||
#define HCI_TYPE_DATA 0x2
|
||||
#define HCI_TYPE_PATCH 0x3
|
||||
#define HCI_TYPE_EVNT 0x4
|
||||
|
||||
|
||||
#define HCI_EVENT_PATCHES_DRV_REQ (1)
|
||||
#define HCI_EVENT_PATCHES_FW_REQ (2)
|
||||
#define HCI_EVENT_PATCHES_BOOTLOAD_REQ (3)
|
||||
|
||||
|
||||
#define HCI_CMND_WLAN_BASE (0x0000)
|
||||
#define HCI_CMND_WLAN_CONNECT 0x0001
|
||||
#define HCI_CMND_WLAN_DISCONNECT 0x0002
|
||||
#define HCI_CMND_WLAN_IOCTL_SET_SCANPARAM 0x0003
|
||||
#define HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY 0x0004
|
||||
#define HCI_CMND_WLAN_IOCTL_ADD_PROFILE 0x0005
|
||||
#define HCI_CMND_WLAN_IOCTL_DEL_PROFILE 0x0006
|
||||
#define HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS 0x0007
|
||||
#define HCI_CMND_EVENT_MASK 0x0008
|
||||
#define HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009
|
||||
#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START 0x000A
|
||||
#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP 0x000B
|
||||
#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX 0x000C
|
||||
#define HCI_CMND_WLAN_CONFIGURE_PATCH 0x000D
|
||||
|
||||
|
||||
#define HCI_CMND_SOCKET_BASE 0x1000
|
||||
#define HCI_CMND_SOCKET 0x1001
|
||||
#define HCI_CMND_BIND 0x1002
|
||||
#define HCI_CMND_RECV 0x1004
|
||||
#define HCI_CMND_ACCEPT 0x1005
|
||||
#define HCI_CMND_LISTEN 0x1006
|
||||
#define HCI_CMND_CONNECT 0x1007
|
||||
#define HCI_CMND_BSD_SELECT 0x1008
|
||||
#define HCI_CMND_SETSOCKOPT 0x1009
|
||||
#define HCI_CMND_GETSOCKOPT 0x100A
|
||||
#define HCI_CMND_CLOSE_SOCKET 0x100B
|
||||
#define HCI_CMND_RECVFROM 0x100D
|
||||
#define HCI_CMND_GETHOSTNAME 0x1010
|
||||
#define HCI_CMND_MDNS_ADVERTISE 0x1011
|
||||
|
||||
|
||||
#define HCI_DATA_BASE 0x80
|
||||
|
||||
#define HCI_CMND_SEND (0x01 + HCI_DATA_BASE)
|
||||
#define HCI_CMND_SENDTO (0x03 + HCI_DATA_BASE)
|
||||
#define HCI_DATA_BSD_RECVFROM (0x04 + HCI_DATA_BASE)
|
||||
#define HCI_DATA_BSD_RECV (0x05 + HCI_DATA_BASE)
|
||||
|
||||
|
||||
#define HCI_CMND_NVMEM_CBASE (0x0200)
|
||||
|
||||
|
||||
#define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203)
|
||||
#define HCI_CMND_NVMEM_SWAP_ENTRY (0x0205)
|
||||
#define HCI_CMND_NVMEM_READ (0x0201)
|
||||
#define HCI_CMND_NVMEM_WRITE (0x0090)
|
||||
#define HCI_CMND_NVMEM_WRITE_PATCH (0x0204)
|
||||
#define HCI_CMND_READ_SP_VERSION (0x0207)
|
||||
|
||||
#define HCI_CMND_READ_BUFFER_SIZE 0x400B
|
||||
#define HCI_CMND_SIMPLE_LINK_START 0x4000
|
||||
|
||||
#define HCI_CMND_NETAPP_BASE 0x2000
|
||||
|
||||
#define HCI_NETAPP_DHCP (0x0001 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_PING_SEND (0x0002 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_PING_REPORT (0x0003 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_PING_STOP (0x0004 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_IPCONFIG (0x0005 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_ARP_FLUSH (0x0006 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_SET_DEBUG_LEVEL (0x0008 + HCI_CMND_NETAPP_BASE)
|
||||
#define HCI_NETAPP_SET_TIMERS (0x0009 + HCI_CMND_NETAPP_BASE)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Values that can be used as HCI Events defines
|
||||
//
|
||||
//*****************************************************************************
|
||||
#define HCI_EVNT_WLAN_BASE 0x0000
|
||||
#define HCI_EVNT_WLAN_CONNECT 0x0001
|
||||
#define HCI_EVNT_WLAN_DISCONNECT \
|
||||
0x0002
|
||||
#define HCI_EVNT_WLAN_IOCTL_ADD_PROFILE \
|
||||
0x0005
|
||||
|
||||
|
||||
#define HCI_EVNT_SOCKET HCI_CMND_SOCKET
|
||||
#define HCI_EVNT_BIND HCI_CMND_BIND
|
||||
#define HCI_EVNT_RECV HCI_CMND_RECV
|
||||
#define HCI_EVNT_ACCEPT HCI_CMND_ACCEPT
|
||||
#define HCI_EVNT_LISTEN HCI_CMND_LISTEN
|
||||
#define HCI_EVNT_CONNECT HCI_CMND_CONNECT
|
||||
#define HCI_EVNT_SELECT HCI_CMND_BSD_SELECT
|
||||
#define HCI_EVNT_CLOSE_SOCKET HCI_CMND_CLOSE_SOCKET
|
||||
#define HCI_EVNT_RECVFROM HCI_CMND_RECVFROM
|
||||
#define HCI_EVNT_SETSOCKOPT HCI_CMND_SETSOCKOPT
|
||||
#define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT
|
||||
#define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME
|
||||
#define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE
|
||||
|
||||
#define HCI_EVNT_SEND 0x1003
|
||||
#define HCI_EVNT_WRITE 0x100E
|
||||
#define HCI_EVNT_SENDTO 0x100F
|
||||
|
||||
#define HCI_EVNT_PATCHES_REQ 0x1000
|
||||
|
||||
#define HCI_EVNT_UNSOL_BASE 0x4000
|
||||
|
||||
#define HCI_EVNT_WLAN_UNSOL_BASE (0x8000)
|
||||
|
||||
#define HCI_EVNT_WLAN_UNSOL_CONNECT (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_UNSOL_DISCONNECT (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_UNSOL_INIT (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_TX_COMPLETE (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_UNSOL_DHCP (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_ASYNC_PING_REPORT (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_WLAN_KEEPALIVE (0x0200 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
#define HCI_EVNT_BSD_TCP_CLOSE_WAIT (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE)
|
||||
|
||||
#define HCI_EVNT_DATA_UNSOL_FREE_BUFF \
|
||||
0x4100
|
||||
|
||||
#define HCI_EVNT_NVMEM_CREATE_ENTRY \
|
||||
HCI_CMND_NVMEM_CREATE_ENTRY
|
||||
#define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY
|
||||
|
||||
#define HCI_EVNT_NVMEM_READ HCI_CMND_NVMEM_READ
|
||||
#define HCI_EVNT_NVMEM_WRITE (0x0202)
|
||||
|
||||
#define HCI_EVNT_READ_SP_VERSION \
|
||||
HCI_CMND_READ_SP_VERSION
|
||||
|
||||
#define HCI_EVNT_INPROGRESS 0xFFFF
|
||||
|
||||
|
||||
#define HCI_DATA_RECVFROM 0x84
|
||||
#define HCI_DATA_RECV 0x85
|
||||
#define HCI_DATA_NVMEM 0x91
|
||||
|
||||
#define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the structures for APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#define HCI_DATA_HEADER_SIZE (5)
|
||||
#define HCI_EVENT_HEADER_SIZE (5)
|
||||
#define HCI_DATA_CMD_HEADER_SIZE (5)
|
||||
#define HCI_PATCH_HEADER_SIZE (6)
|
||||
|
||||
#define HCI_PACKET_TYPE_OFFSET (0)
|
||||
#define HCI_PACKET_ARGSIZE_OFFSET (2)
|
||||
#define HCI_PACKET_LENGTH_OFFSET (3)
|
||||
|
||||
|
||||
#define HCI_EVENT_OPCODE_OFFSET (1)
|
||||
#define HCI_EVENT_LENGTH_OFFSET (3)
|
||||
#define HCI_EVENT_STATUS_OFFSET (4)
|
||||
#define HCI_DATA_LENGTH_OFFSET (3)
|
||||
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern unsigned short hci_command_send(unsigned short usOpcode,
|
||||
unsigned char *ucArgs,
|
||||
unsigned char ucArgsLength);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long hci_data_send(unsigned char ucOpcode,
|
||||
unsigned char *ucArgs,
|
||||
unsigned short usArgsLength,
|
||||
unsigned short usDataLength,
|
||||
const unsigned char *ucTail,
|
||||
unsigned short usTailLength);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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 Prepare HCI header and initiate an HCI data write operation
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void hci_data_command_send(unsigned short usOpcode, unsigned char *pucBuff,
|
||||
unsigned char ucArgsLength, unsigned short ucDataLength);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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 Prepare HCI header and initiate an HCI patch write operation
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void hci_patch_send(unsigned char ucOpcode, unsigned char *pucBuff, char *patch, unsigned short usDataLength);
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __HCI_H__
|
|
@ -0,0 +1,55 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* host_driver_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 __HOST_DRIVER_VERSION_H__
|
||||
#define __HOST_DRIVER_VERSION_H__
|
||||
|
||||
#define DRIVER_VERSION_NUMBER 13
|
||||
|
||||
|
||||
|
||||
#endif // __VERSION_H__
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,477 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* netapp.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* Neither the name of Texas Instruments Incorporated nor the names of
|
||||
* its contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <stdint.h>
|
||||
|
||||
#include "netapp.h"
|
||||
#include "hci.h"
|
||||
#include "socket.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "nvmem.h"
|
||||
|
||||
#define MIN_TIMER_VAL_SECONDS 20
|
||||
#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \
|
||||
{ \
|
||||
t = MIN_TIMER_VAL_SECONDS; \
|
||||
}
|
||||
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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(unsigned char * 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)
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *ptr;
|
||||
unsigned char *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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long
|
||||
netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity)
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *ptr;
|
||||
unsigned char *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.
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long
|
||||
netapp_ping_send(uint32_t *ip, uint32_t ulPingAttempts, uint32_t ulPingSize, uint32_t ulPingTimeout)
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *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);
|
||||
|
||||
/*
|
||||
if (CC3KPrinter != 0)
|
||||
{
|
||||
for(uint8_t i=0; i<4+4+4+4; i++) {
|
||||
CC3KPrinter->print(" 0x"); CC3KPrinter->( (ptr + HEADERS_SIZE_CMD)[i], HEX);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// 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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
void netapp_ping_report()
|
||||
{
|
||||
unsigned char *ptr;
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
signed char 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.
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long netapp_ping_stop()
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig )
|
||||
{
|
||||
unsigned char *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 )
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_arp_flush
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Flushes ARP table
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long netapp_arp_flush(void)
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *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
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long netapp_set_debug_level(unsigned long ulLevel)
|
||||
{
|
||||
signed char scRet;
|
||||
unsigned char *ptr, *args;
|
||||
|
||||
scRet = EFAIL;
|
||||
ptr = tSLInformation.pucTxCommandBuffer;
|
||||
args = (ptr + HEADERS_SIZE_CMD);
|
||||
|
||||
//
|
||||
// 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);
|
||||
|
||||
//
|
||||
// Wait for command complete event
|
||||
//
|
||||
SimpleLinkWaitEvent(HCI_NETAPP_SET_DEBUG_LEVEL, &scRet);
|
||||
|
||||
return(scRet);
|
||||
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,349 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* netapp.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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 __NETAPP_H__
|
||||
#define __NETAPP_H__
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup netapp_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct _netapp_dhcp_ret_args_t
|
||||
{
|
||||
unsigned char aucIP[4];
|
||||
unsigned char aucSubnetMask[4];
|
||||
unsigned char aucDefaultGateway[4];
|
||||
unsigned char aucDHCPServer[4];
|
||||
unsigned char aucDNSServer[4];
|
||||
}tNetappDhcpParams;
|
||||
|
||||
typedef struct _netapp_ipconfig_ret_args_t
|
||||
{
|
||||
unsigned char aucIP[4];
|
||||
unsigned char aucSubnetMask[4];
|
||||
unsigned char aucDefaultGateway[4];
|
||||
unsigned char aucDHCPServer[4];
|
||||
unsigned char aucDNSServer[4];
|
||||
unsigned char uaMacAddr[6];
|
||||
unsigned char uaSSID[32];
|
||||
}tNetappIpconfigRetArgs;
|
||||
|
||||
|
||||
/*Ping send report parameters*/
|
||||
typedef struct _netapp_pingreport_args
|
||||
{
|
||||
unsigned long packets_sent;
|
||||
unsigned long packets_received;
|
||||
unsigned long min_round_time;
|
||||
unsigned long max_round_time;
|
||||
unsigned long avg_round_time;
|
||||
} netapp_pingreport_args_t;
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long netapp_config_mac_adrress( unsigned char *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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern long netapp_dhcp(unsigned long *aucIP, unsigned long *aucSubnetMask,unsigned long *aucDefaultGateway, unsigned long *aucDNSServer);
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern long netapp_timeout_values(unsigned long *aucDHCP, unsigned long *aucARP,unsigned long *aucKeepalive, unsigned long *aucInactivity);
|
||||
#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.
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern long netapp_ping_send(uint32_t *ip, uint32_t ulPingAttempts, uint32_t ulPingSize, uint32_t ulPingTimeout);
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_ping_stop
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief Stop any ping request.
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern long netapp_ping_stop();
|
||||
#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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern void netapp_ping_report();
|
||||
#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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
extern void netapp_ipconfig( tNetappIpconfigRetArgs * ipconfig );
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! netapp_arp_flush
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Flushes ARP table
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern long netapp_arp_flush();
|
||||
#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
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
long netapp_set_debug_level(unsigned long ulLevel);
|
||||
#endif
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __NETAPP_H__
|
||||
|
|
@ -0,0 +1,366 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* nvmem.c - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nvmem.h"
|
||||
#include "hci.h"
|
||||
#include "socket.h"
|
||||
#include "evnt_handler.h"
|
||||
#include "ccdebug.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the structures for APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
signed long
|
||||
nvmem_read(unsigned long ulFileId, unsigned long ulLength, unsigned long ulOffset, unsigned char *buff)
|
||||
{
|
||||
unsigned char ucStatus = 0xFF;
|
||||
unsigned char *ptr;
|
||||
unsigned char *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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
signed long
|
||||
nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long
|
||||
ulEntryOffset, unsigned char *buff)
|
||||
{
|
||||
long iRes;
|
||||
unsigned char *ptr;
|
||||
unsigned char *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);
|
||||
#if (DEBUG_MODE == 1)
|
||||
PRINT_F("Writing:\t");
|
||||
for (uint8_t i=0; i<ulLength; i++) {
|
||||
PRINT_F("0x");
|
||||
printHex(buff[i]);
|
||||
PRINT_F(", ");
|
||||
}
|
||||
PRINT_F("\n\r");
|
||||
#endif
|
||||
// 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)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
unsigned char nvmem_set_mac_address(unsigned char *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)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
unsigned char nvmem_get_mac_address(unsigned char *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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const uint8_t *spData)
|
||||
{
|
||||
unsigned char status = 0;
|
||||
unsigned short offset = 0;
|
||||
unsigned char* spDataPtr = (unsigned char*)spData;
|
||||
|
||||
while ((status == 0) && (spLength >= SP_PORTION_SIZE))
|
||||
{
|
||||
#if (DEBUG_MODE == 1)
|
||||
PRINT_F("Writing: "); printDec16(offset); PRINT_F("\t");
|
||||
for (uint8_t i=0; i<SP_PORTION_SIZE; i++) {
|
||||
PRINT_F("0x");
|
||||
printHex(spDataPtr[i]);
|
||||
PRINT_F(", ");
|
||||
}
|
||||
PRINT_F("\n\r");
|
||||
#endif
|
||||
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)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
#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]);
|
||||
}
|
||||
#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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
int8_t
|
||||
nvmem_create_entry(unsigned long ulFileId, unsigned long ulNewLen)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
unsigned char *args;
|
||||
int8_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.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* nvmem.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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 __NVRAM_H__
|
||||
#define __NVRAM_H__
|
||||
|
||||
#include "cc3000_common.h"
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup nvmem_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Definitions for File IDs
|
||||
**
|
||||
****************************************************************************/
|
||||
/* NVMEM file ID - system files*/
|
||||
#define NVMEM_NVS_FILEID (0)
|
||||
#define NVMEM_NVS_SHADOW_FILEID (1)
|
||||
#define NVMEM_WLAN_CONFIG_FILEID (2)
|
||||
#define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3)
|
||||
#define NVMEM_WLAN_DRIVER_SP_FILEID (4)
|
||||
#define NVMEM_WLAN_FW_SP_FILEID (5)
|
||||
#define NVMEM_MAC_FILEID (6)
|
||||
#define NVMEM_FRONTEND_VARS_FILEID (7)
|
||||
#define NVMEM_IP_CONFIG_FILEID (8)
|
||||
#define NVMEM_IP_CONFIG_SHADOW_FILEID (9)
|
||||
#define NVMEM_BOOTLOADER_SP_FILEID (10)
|
||||
#define NVMEM_RM_FILEID (11)
|
||||
|
||||
/* NVMEM file ID - user files*/
|
||||
#define NVMEM_AES128_KEY_FILEID (12)
|
||||
#define NVMEM_SHARED_MEM_FILEID (13)
|
||||
|
||||
/* max entry in order to invalid nvmem */
|
||||
#define NVMEM_MAX_ENTRY (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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
extern signed long nvmem_read(unsigned long file_id, unsigned long length, unsigned long offset, unsigned char *buff);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
extern signed long nvmem_write(unsigned long ulFileId, unsigned long ulLength, unsigned long ulEntryOffset, unsigned char *buff);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern unsigned char nvmem_set_mac_address(unsigned char *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)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern unsigned char nvmem_get_mac_address(unsigned char *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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern unsigned char nvmem_write_patch(unsigned long ulFileId, unsigned long spLength, const unsigned char *spData);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! 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)
|
||||
//!
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern unsigned char nvmem_read_sp_version(unsigned char* patchVer);
|
||||
#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.
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern int8_t nvmem_create_entry(unsigned long file_id, unsigned long newlen);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __NVRAM_H__
|
|
@ -0,0 +1,167 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "pin.h"
|
||||
#include "genhdr/pins.h"
|
||||
#include "led.h"
|
||||
#include "extint.h"
|
||||
#include "spi.h"
|
||||
#include "ccspi.h"
|
||||
#include "ccdebug.h"
|
||||
#include "pybcc3k.h"
|
||||
|
||||
// IRQ on PA14, input, pulled up, active low
|
||||
// EN on PC7, output, active high
|
||||
// CS on PC6, output, active low
|
||||
// SPI2 on PB15=MOSI, PB14=MISO, PB13=SCK
|
||||
// SCK for CC3000: max 16MHz, low when idle, data sampled on falling edge
|
||||
|
||||
#define PIN_CS pin_B12 // Y5
|
||||
#define PIN_EN pin_B9 // Y4
|
||||
#define PIN_IRQ pin_B8 // Y3
|
||||
#define SPI_HANDLE SPIHandle2
|
||||
|
||||
// TODO this could be really wrong wrt calibration
|
||||
void pyb_delay_us(uint32_t usec) {
|
||||
volatile uint32_t count = 0;
|
||||
const uint32_t utime = (160 * usec / 5);
|
||||
do {
|
||||
if (++count > utime) {
|
||||
return;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
void pyb_cc3000_set_en(int val) {
|
||||
DEBUG_printf("pyb_cc3000_set_en val=%d\n", val);
|
||||
if (val) {
|
||||
PIN_EN.gpio->BSRRL = PIN_EN.pin_mask; // set pin high
|
||||
} else {
|
||||
PIN_EN.gpio->BSRRH = PIN_EN.pin_mask; // set pin low
|
||||
}
|
||||
}
|
||||
|
||||
void pyb_cc3000_set_cs(int val) {
|
||||
DEBUG_printf("pyb_cc3000_set_cs val=%d\n", val);
|
||||
if (val) {
|
||||
PIN_CS.gpio->BSRRL = PIN_CS.pin_mask; // set pin high
|
||||
} else {
|
||||
PIN_CS.gpio->BSRRH = PIN_CS.pin_mask; // set pin low
|
||||
}
|
||||
}
|
||||
|
||||
int pyb_cc3000_get_irq(void) {
|
||||
if ((PIN_IRQ.gpio->IDR & PIN_IRQ.pin_mask) == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t exti14_enabled = 0; // TODO hack; do it properly!
|
||||
uint32_t exti14_missed = 0; // TODO hack; do it properly!
|
||||
|
||||
void pyb_cc3000_enable_irq(void) {
|
||||
DEBUG_printf("pyb_cc3000_enable_irq: en=%lu miss=%lu\n", exti14_enabled, exti14_missed);
|
||||
if (exti14_missed) {
|
||||
/* doesn't look like this is needed
|
||||
DEBUG_printf("pyb_cc3000_enable_irq: handling missed IRQ\n");
|
||||
// TODO hack if we have a pending IRQ
|
||||
extern void SpiIntGPIOHandler(void);
|
||||
SpiIntGPIOHandler();
|
||||
*/
|
||||
exti14_missed = 0;
|
||||
}
|
||||
exti14_enabled = 1;
|
||||
}
|
||||
|
||||
void pyb_cc3000_disable_irq(void) {
|
||||
DEBUG_printf("pyb_cc3000_disable_irq: en=%lu miss=%lu\n", exti14_enabled, exti14_missed);
|
||||
exti14_enabled = 0;
|
||||
}
|
||||
|
||||
void pyb_cc3000_pause_spi(void) {
|
||||
DEBUG_printf("pyb_cc3000_pause_spi\n");
|
||||
exti14_enabled = 0;
|
||||
}
|
||||
|
||||
void pyb_cc3000_resume_spi(void) {
|
||||
DEBUG_printf("pyb_cc3000_resume_spi\n");
|
||||
exti14_enabled = 1;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t irq_callback(mp_obj_t line) {
|
||||
led_toggle(2);
|
||||
//extern void SpiIntGPIOHandler(void);
|
||||
//extern uint32_t exti14_enabled;
|
||||
//extern uint32_t exti14_missed;
|
||||
//printf("-> EXTI14 en=%lu miss=%lu\n", exti14_enabled, exti14_missed);
|
||||
if (exti14_enabled) {
|
||||
exti14_missed = 0;
|
||||
SpiIntGPIOHandler(); // CC3000 interrupt
|
||||
} else {
|
||||
exti14_missed = 1;
|
||||
}
|
||||
//printf("<- EXTI14 done\n");
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(irq_callback_obj, irq_callback);
|
||||
|
||||
void pyb_cc3000_spi_init(void) {
|
||||
DEBUG_printf("pyb_cc3000_spi_init\n");
|
||||
|
||||
/*
|
||||
inf.baudRate = 100000; // FIXME - just slow for debug
|
||||
inf.spiMode = SPIF_SPI_MODE_1; // Mode 1 CPOL= 0 CPHA= 1
|
||||
*/
|
||||
|
||||
/*!< SPI configuration */
|
||||
SPI_HANDLE.Init.Mode = SPI_MODE_MASTER;
|
||||
SPI_HANDLE.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
SPI_HANDLE.Init.DataSize = SPI_DATASIZE_8BIT; // should be correct
|
||||
SPI_HANDLE.Init.CLKPolarity = SPI_POLARITY_LOW; // clock is low when idle
|
||||
SPI_HANDLE.Init.CLKPhase = SPI_PHASE_2EDGE; // data latched on second edge, which is falling edge for low-idle
|
||||
SPI_HANDLE.Init.NSS = SPI_NSS_SOFT; // software control
|
||||
SPI_HANDLE.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; // clock freq = f_PCLK / this_prescale_value
|
||||
SPI_HANDLE.Init.FirstBit = SPI_FIRSTBIT_MSB; // should be correct
|
||||
SPI_HANDLE.Init.TIMode = SPI_TIMODE_DISABLED;
|
||||
SPI_HANDLE.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
|
||||
SPI_HANDLE.Init.CRCPolynomial = 7; // unused
|
||||
|
||||
spi_init(&SPI_HANDLE);
|
||||
|
||||
// configure wlan CS and EN pins
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Alternate = 0;
|
||||
|
||||
GPIO_InitStructure.Pin = PIN_CS.pin_mask;
|
||||
HAL_GPIO_Init(PIN_CS.gpio, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pin = PIN_EN.pin_mask;
|
||||
HAL_GPIO_Init(PIN_EN.gpio, &GPIO_InitStructure);
|
||||
|
||||
pyb_cc3000_set_cs(1); // de-assert CS
|
||||
pyb_cc3000_set_en(0); // disable wlan
|
||||
|
||||
// configure EXTI for PIN_IRQ
|
||||
extint_register((mp_obj_t)&PIN_IRQ, GPIO_MODE_IT_FALLING, GPIO_PULLUP, (mp_obj_t)&irq_callback_obj, true, NULL);
|
||||
|
||||
// wait a little (ensure that WLAN takes effect)
|
||||
HAL_Delay(500); // force a 500ms delay! FIXME
|
||||
}
|
||||
|
||||
uint8_t pyb_cc3000_spi_send(uint8_t val) {
|
||||
uint8_t data[1] = {val};
|
||||
HAL_SPI_TransmitReceive(&SPI_HANDLE, data, data, 1, 1000);
|
||||
return data[0];
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
void pyb_delay_us(uint32_t us);
|
||||
|
||||
void pyb_cc3000_set_en(int val);
|
||||
void pyb_cc3000_set_cs(int val);
|
||||
int pyb_cc3000_get_irq(void);
|
||||
void pyb_cc3000_enable_irq(void);
|
||||
void pyb_cc3000_disable_irq(void);
|
||||
void pyb_cc3000_pause_spi(void);
|
||||
void pyb_cc3000_resume_spi(void);
|
||||
|
||||
void pyb_cc3000_spi_init(void);
|
||||
uint8_t pyb_cc3000_spi_send(uint8_t val);
|
|
@ -0,0 +1,535 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* security.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 security_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "security.h"
|
||||
|
||||
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
|
||||
// foreward sbox
|
||||
const unsigned char sbox[256] = {
|
||||
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, //0
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, //1
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, //2
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, //3
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, //4
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, //5
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, //6
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, //7
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, //8
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, //9
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; //F
|
||||
// inverse sbox
|
||||
const unsigned char rsbox[256] =
|
||||
{ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
|
||||
, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
|
||||
, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
|
||||
, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
|
||||
, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
|
||||
, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
|
||||
, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
|
||||
, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
|
||||
, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
|
||||
, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
|
||||
, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
|
||||
, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
|
||||
, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
|
||||
, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
|
||||
, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
|
||||
, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d };
|
||||
// round constant
|
||||
const unsigned char Rcon[11] = {
|
||||
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
|
||||
|
||||
|
||||
unsigned char expandedKey[176];
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! expandKey
|
||||
//!
|
||||
//! @param key AES128 key - 16 bytes
|
||||
//! @param expandedKey expanded AES128 key
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief expend a 16 bytes key for AES128 implementation
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
void expandKey(unsigned char *expandedKey,
|
||||
unsigned char *key)
|
||||
{
|
||||
unsigned short ii, buf1;
|
||||
for (ii=0;ii<16;ii++)
|
||||
expandedKey[ii] = key[ii];
|
||||
for (ii=1;ii<11;ii++){
|
||||
buf1 = expandedKey[ii*16 - 4];
|
||||
expandedKey[ii*16 + 0] = sbox[expandedKey[ii*16 - 3]]^expandedKey[(ii-1)*16 + 0]^Rcon[ii];
|
||||
expandedKey[ii*16 + 1] = sbox[expandedKey[ii*16 - 2]]^expandedKey[(ii-1)*16 + 1];
|
||||
expandedKey[ii*16 + 2] = sbox[expandedKey[ii*16 - 1]]^expandedKey[(ii-1)*16 + 2];
|
||||
expandedKey[ii*16 + 3] = sbox[buf1 ]^expandedKey[(ii-1)*16 + 3];
|
||||
expandedKey[ii*16 + 4] = expandedKey[(ii-1)*16 + 4]^expandedKey[ii*16 + 0];
|
||||
expandedKey[ii*16 + 5] = expandedKey[(ii-1)*16 + 5]^expandedKey[ii*16 + 1];
|
||||
expandedKey[ii*16 + 6] = expandedKey[(ii-1)*16 + 6]^expandedKey[ii*16 + 2];
|
||||
expandedKey[ii*16 + 7] = expandedKey[(ii-1)*16 + 7]^expandedKey[ii*16 + 3];
|
||||
expandedKey[ii*16 + 8] = expandedKey[(ii-1)*16 + 8]^expandedKey[ii*16 + 4];
|
||||
expandedKey[ii*16 + 9] = expandedKey[(ii-1)*16 + 9]^expandedKey[ii*16 + 5];
|
||||
expandedKey[ii*16 +10] = expandedKey[(ii-1)*16 +10]^expandedKey[ii*16 + 6];
|
||||
expandedKey[ii*16 +11] = expandedKey[(ii-1)*16 +11]^expandedKey[ii*16 + 7];
|
||||
expandedKey[ii*16 +12] = expandedKey[(ii-1)*16 +12]^expandedKey[ii*16 + 8];
|
||||
expandedKey[ii*16 +13] = expandedKey[(ii-1)*16 +13]^expandedKey[ii*16 + 9];
|
||||
expandedKey[ii*16 +14] = expandedKey[(ii-1)*16 +14]^expandedKey[ii*16 +10];
|
||||
expandedKey[ii*16 +15] = expandedKey[(ii-1)*16 +15]^expandedKey[ii*16 +11];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! galois_mul2
|
||||
//!
|
||||
//! @param value argument to multiply
|
||||
//!
|
||||
//! @return multiplied argument
|
||||
//!
|
||||
//! @brief multiply by 2 in the galois field
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
unsigned char galois_mul2(unsigned char value)
|
||||
{
|
||||
if (value>>7)
|
||||
{
|
||||
value = value << 1;
|
||||
return (value^0x1b);
|
||||
} else
|
||||
return value<<1;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_encr
|
||||
//!
|
||||
//! @param[in] expandedKey expanded AES128 key
|
||||
//! @param[in/out] state 16 bytes of plain text and cipher text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief internal implementation of AES128 encryption.
|
||||
//! straight forward aes encryption implementation
|
||||
//! first the group of operations
|
||||
//! - addRoundKey
|
||||
//! - subbytes
|
||||
//! - shiftrows
|
||||
//! - mixcolums
|
||||
//! is executed 9 times, after this addroundkey to finish the 9th
|
||||
//! round, after that the 10th round without mixcolums
|
||||
//! no further subfunctions to save cycles for function calls
|
||||
//! no structuring with "for (....)" to save cycles.
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
void aes_encr(unsigned char *state, unsigned char *expandedKey)
|
||||
{
|
||||
unsigned char buf1, buf2, buf3, round;
|
||||
|
||||
for (round = 0; round < 9; round ++){
|
||||
// addroundkey, sbox and shiftrows
|
||||
// row 0
|
||||
state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])];
|
||||
state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])];
|
||||
state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])];
|
||||
state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])];
|
||||
// row 1
|
||||
buf1 = state[1] ^ expandedKey[(round*16) + 1];
|
||||
state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])];
|
||||
state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])];
|
||||
state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])];
|
||||
state[13] = sbox[buf1];
|
||||
// row 2
|
||||
buf1 = state[2] ^ expandedKey[(round*16) + 2];
|
||||
buf2 = state[6] ^ expandedKey[(round*16) + 6];
|
||||
state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])];
|
||||
state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])];
|
||||
state[10] = sbox[buf1];
|
||||
state[14] = sbox[buf2];
|
||||
// row 3
|
||||
buf1 = state[15] ^ expandedKey[(round*16) + 15];
|
||||
state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])];
|
||||
state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])];
|
||||
state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])];
|
||||
state[ 3] = sbox[buf1];
|
||||
|
||||
// mixcolums //////////
|
||||
// col1
|
||||
buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
|
||||
buf2 = state[0];
|
||||
buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
|
||||
buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
|
||||
buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
|
||||
buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
|
||||
// col2
|
||||
buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
|
||||
buf2 = state[4];
|
||||
buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
|
||||
buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
|
||||
buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
|
||||
buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
|
||||
// col3
|
||||
buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
|
||||
buf2 = state[8];
|
||||
buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
|
||||
buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
|
||||
buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
|
||||
buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
|
||||
// col4
|
||||
buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
|
||||
buf2 = state[12];
|
||||
buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
|
||||
buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
|
||||
buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
|
||||
buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
|
||||
|
||||
}
|
||||
// 10th round without mixcols
|
||||
state[ 0] = sbox[(state[ 0] ^ expandedKey[(round*16) ])];
|
||||
state[ 4] = sbox[(state[ 4] ^ expandedKey[(round*16) + 4])];
|
||||
state[ 8] = sbox[(state[ 8] ^ expandedKey[(round*16) + 8])];
|
||||
state[12] = sbox[(state[12] ^ expandedKey[(round*16) + 12])];
|
||||
// row 1
|
||||
buf1 = state[1] ^ expandedKey[(round*16) + 1];
|
||||
state[ 1] = sbox[(state[ 5] ^ expandedKey[(round*16) + 5])];
|
||||
state[ 5] = sbox[(state[ 9] ^ expandedKey[(round*16) + 9])];
|
||||
state[ 9] = sbox[(state[13] ^ expandedKey[(round*16) + 13])];
|
||||
state[13] = sbox[buf1];
|
||||
// row 2
|
||||
buf1 = state[2] ^ expandedKey[(round*16) + 2];
|
||||
buf2 = state[6] ^ expandedKey[(round*16) + 6];
|
||||
state[ 2] = sbox[(state[10] ^ expandedKey[(round*16) + 10])];
|
||||
state[ 6] = sbox[(state[14] ^ expandedKey[(round*16) + 14])];
|
||||
state[10] = sbox[buf1];
|
||||
state[14] = sbox[buf2];
|
||||
// row 3
|
||||
buf1 = state[15] ^ expandedKey[(round*16) + 15];
|
||||
state[15] = sbox[(state[11] ^ expandedKey[(round*16) + 11])];
|
||||
state[11] = sbox[(state[ 7] ^ expandedKey[(round*16) + 7])];
|
||||
state[ 7] = sbox[(state[ 3] ^ expandedKey[(round*16) + 3])];
|
||||
state[ 3] = sbox[buf1];
|
||||
// last addroundkey
|
||||
state[ 0]^=expandedKey[160];
|
||||
state[ 1]^=expandedKey[161];
|
||||
state[ 2]^=expandedKey[162];
|
||||
state[ 3]^=expandedKey[163];
|
||||
state[ 4]^=expandedKey[164];
|
||||
state[ 5]^=expandedKey[165];
|
||||
state[ 6]^=expandedKey[166];
|
||||
state[ 7]^=expandedKey[167];
|
||||
state[ 8]^=expandedKey[168];
|
||||
state[ 9]^=expandedKey[169];
|
||||
state[10]^=expandedKey[170];
|
||||
state[11]^=expandedKey[171];
|
||||
state[12]^=expandedKey[172];
|
||||
state[13]^=expandedKey[173];
|
||||
state[14]^=expandedKey[174];
|
||||
state[15]^=expandedKey[175];
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_decr
|
||||
//!
|
||||
//! @param[in] expandedKey expanded AES128 key
|
||||
//! @param[in\out] state 16 bytes of cipher text and plain text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief internal implementation of AES128 decryption.
|
||||
//! straight forward aes decryption implementation
|
||||
//! the order of substeps is the exact reverse of decryption
|
||||
//! inverse functions:
|
||||
//! - addRoundKey is its own inverse
|
||||
//! - rsbox is inverse of sbox
|
||||
//! - rightshift instead of leftshift
|
||||
//! - invMixColumns = barreto + mixColumns
|
||||
//! no further subfunctions to save cycles for function calls
|
||||
//! no structuring with "for (....)" to save cycles
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
void aes_decr(unsigned char *state, unsigned char *expandedKey)
|
||||
{
|
||||
unsigned char buf1, buf2, buf3;
|
||||
signed char round;
|
||||
round = 9;
|
||||
|
||||
// initial addroundkey
|
||||
state[ 0]^=expandedKey[160];
|
||||
state[ 1]^=expandedKey[161];
|
||||
state[ 2]^=expandedKey[162];
|
||||
state[ 3]^=expandedKey[163];
|
||||
state[ 4]^=expandedKey[164];
|
||||
state[ 5]^=expandedKey[165];
|
||||
state[ 6]^=expandedKey[166];
|
||||
state[ 7]^=expandedKey[167];
|
||||
state[ 8]^=expandedKey[168];
|
||||
state[ 9]^=expandedKey[169];
|
||||
state[10]^=expandedKey[170];
|
||||
state[11]^=expandedKey[171];
|
||||
state[12]^=expandedKey[172];
|
||||
state[13]^=expandedKey[173];
|
||||
state[14]^=expandedKey[174];
|
||||
state[15]^=expandedKey[175];
|
||||
|
||||
// 10th round without mixcols
|
||||
state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ];
|
||||
state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4];
|
||||
state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8];
|
||||
state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12];
|
||||
// row 1
|
||||
buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1];
|
||||
state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13];
|
||||
state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9];
|
||||
state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5];
|
||||
state[ 1] = buf1;
|
||||
// row 2
|
||||
buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10];
|
||||
buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14];
|
||||
state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2];
|
||||
state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6];
|
||||
state[10] = buf1;
|
||||
state[14] = buf2;
|
||||
// row 3
|
||||
buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15];
|
||||
state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3];
|
||||
state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7];
|
||||
state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11];
|
||||
state[15] = buf1;
|
||||
|
||||
for (round = 8; round >= 0; round--){
|
||||
// barreto
|
||||
//col1
|
||||
buf1 = galois_mul2(galois_mul2(state[0]^state[2]));
|
||||
buf2 = galois_mul2(galois_mul2(state[1]^state[3]));
|
||||
state[0] ^= buf1; state[1] ^= buf2; state[2] ^= buf1; state[3] ^= buf2;
|
||||
//col2
|
||||
buf1 = galois_mul2(galois_mul2(state[4]^state[6]));
|
||||
buf2 = galois_mul2(galois_mul2(state[5]^state[7]));
|
||||
state[4] ^= buf1; state[5] ^= buf2; state[6] ^= buf1; state[7] ^= buf2;
|
||||
//col3
|
||||
buf1 = galois_mul2(galois_mul2(state[8]^state[10]));
|
||||
buf2 = galois_mul2(galois_mul2(state[9]^state[11]));
|
||||
state[8] ^= buf1; state[9] ^= buf2; state[10] ^= buf1; state[11] ^= buf2;
|
||||
//col4
|
||||
buf1 = galois_mul2(galois_mul2(state[12]^state[14]));
|
||||
buf2 = galois_mul2(galois_mul2(state[13]^state[15]));
|
||||
state[12] ^= buf1; state[13] ^= buf2; state[14] ^= buf1; state[15] ^= buf2;
|
||||
// mixcolums //////////
|
||||
// col1
|
||||
buf1 = state[0] ^ state[1] ^ state[2] ^ state[3];
|
||||
buf2 = state[0];
|
||||
buf3 = state[0]^state[1]; buf3=galois_mul2(buf3); state[0] = state[0] ^ buf3 ^ buf1;
|
||||
buf3 = state[1]^state[2]; buf3=galois_mul2(buf3); state[1] = state[1] ^ buf3 ^ buf1;
|
||||
buf3 = state[2]^state[3]; buf3=galois_mul2(buf3); state[2] = state[2] ^ buf3 ^ buf1;
|
||||
buf3 = state[3]^buf2; buf3=galois_mul2(buf3); state[3] = state[3] ^ buf3 ^ buf1;
|
||||
// col2
|
||||
buf1 = state[4] ^ state[5] ^ state[6] ^ state[7];
|
||||
buf2 = state[4];
|
||||
buf3 = state[4]^state[5]; buf3=galois_mul2(buf3); state[4] = state[4] ^ buf3 ^ buf1;
|
||||
buf3 = state[5]^state[6]; buf3=galois_mul2(buf3); state[5] = state[5] ^ buf3 ^ buf1;
|
||||
buf3 = state[6]^state[7]; buf3=galois_mul2(buf3); state[6] = state[6] ^ buf3 ^ buf1;
|
||||
buf3 = state[7]^buf2; buf3=galois_mul2(buf3); state[7] = state[7] ^ buf3 ^ buf1;
|
||||
// col3
|
||||
buf1 = state[8] ^ state[9] ^ state[10] ^ state[11];
|
||||
buf2 = state[8];
|
||||
buf3 = state[8]^state[9]; buf3=galois_mul2(buf3); state[8] = state[8] ^ buf3 ^ buf1;
|
||||
buf3 = state[9]^state[10]; buf3=galois_mul2(buf3); state[9] = state[9] ^ buf3 ^ buf1;
|
||||
buf3 = state[10]^state[11]; buf3=galois_mul2(buf3); state[10] = state[10] ^ buf3 ^ buf1;
|
||||
buf3 = state[11]^buf2; buf3=galois_mul2(buf3); state[11] = state[11] ^ buf3 ^ buf1;
|
||||
// col4
|
||||
buf1 = state[12] ^ state[13] ^ state[14] ^ state[15];
|
||||
buf2 = state[12];
|
||||
buf3 = state[12]^state[13]; buf3=galois_mul2(buf3); state[12] = state[12] ^ buf3 ^ buf1;
|
||||
buf3 = state[13]^state[14]; buf3=galois_mul2(buf3); state[13] = state[13] ^ buf3 ^ buf1;
|
||||
buf3 = state[14]^state[15]; buf3=galois_mul2(buf3); state[14] = state[14] ^ buf3 ^ buf1;
|
||||
buf3 = state[15]^buf2; buf3=galois_mul2(buf3); state[15] = state[15] ^ buf3 ^ buf1;
|
||||
|
||||
// addroundkey, rsbox and shiftrows
|
||||
// row 0
|
||||
state[ 0] = rsbox[state[ 0]] ^ expandedKey[(round*16) ];
|
||||
state[ 4] = rsbox[state[ 4]] ^ expandedKey[(round*16) + 4];
|
||||
state[ 8] = rsbox[state[ 8]] ^ expandedKey[(round*16) + 8];
|
||||
state[12] = rsbox[state[12]] ^ expandedKey[(round*16) + 12];
|
||||
// row 1
|
||||
buf1 = rsbox[state[13]] ^ expandedKey[(round*16) + 1];
|
||||
state[13] = rsbox[state[ 9]] ^ expandedKey[(round*16) + 13];
|
||||
state[ 9] = rsbox[state[ 5]] ^ expandedKey[(round*16) + 9];
|
||||
state[ 5] = rsbox[state[ 1]] ^ expandedKey[(round*16) + 5];
|
||||
state[ 1] = buf1;
|
||||
// row 2
|
||||
buf1 = rsbox[state[ 2]] ^ expandedKey[(round*16) + 10];
|
||||
buf2 = rsbox[state[ 6]] ^ expandedKey[(round*16) + 14];
|
||||
state[ 2] = rsbox[state[10]] ^ expandedKey[(round*16) + 2];
|
||||
state[ 6] = rsbox[state[14]] ^ expandedKey[(round*16) + 6];
|
||||
state[10] = buf1;
|
||||
state[14] = buf2;
|
||||
// row 3
|
||||
buf1 = rsbox[state[ 3]] ^ expandedKey[(round*16) + 15];
|
||||
state[ 3] = rsbox[state[ 7]] ^ expandedKey[(round*16) + 3];
|
||||
state[ 7] = rsbox[state[11]] ^ expandedKey[(round*16) + 7];
|
||||
state[11] = rsbox[state[15]] ^ expandedKey[(round*16) + 11];
|
||||
state[15] = buf1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_encrypt
|
||||
//!
|
||||
//! @param[in] key AES128 key of size 16 bytes
|
||||
//! @param[in\out] state 16 bytes of plain text and cipher text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief AES128 encryption:
|
||||
//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes
|
||||
//! is computed. The AES implementation is in mode ECB (Electronic
|
||||
//! Code Book).
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
void aes_encrypt(unsigned char *state,
|
||||
unsigned char *key)
|
||||
{
|
||||
// expand the key into 176 bytes
|
||||
expandKey(expandedKey, key);
|
||||
aes_encr(state, expandedKey);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_decrypt
|
||||
//!
|
||||
//! @param[in] key AES128 key of size 16 bytes
|
||||
//! @param[in\out] state 16 bytes of cipher text and plain text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief AES128 decryption:
|
||||
//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes
|
||||
//! is computed The AES implementation is in mode ECB
|
||||
//! (Electronic Code Book).
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
void aes_decrypt(unsigned char *state,
|
||||
unsigned char *key)
|
||||
{
|
||||
expandKey(expandedKey, key); // expand the key into 176 bytes
|
||||
aes_decr(state, expandedKey);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_read_key
|
||||
//!
|
||||
//! @param[out] key AES128 key of size 16 bytes
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Reads AES128 key from EEPROM
|
||||
//! Reads the AES128 key from fileID #12 in EEPROM
|
||||
//! returns an error if the key does not exist.
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
signed long aes_read_key(unsigned char *key)
|
||||
{
|
||||
signed long returnValue;
|
||||
|
||||
returnValue = nvmem_read(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_write_key
|
||||
//!
|
||||
//! @param[out] key AES128 key of size 16 bytes
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief writes AES128 key from EEPROM
|
||||
//! Writes the AES128 key to fileID #12 in EEPROM
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
|
||||
signed long aes_write_key(unsigned char *key)
|
||||
{
|
||||
signed long returnValue;
|
||||
|
||||
returnValue = nvmem_write(NVMEM_AES128_KEY_FILEID, AES128_KEY_SIZE, 0, key);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
#endif //CC3000_UNENCRYPTED_SMART_CONFIG
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
|
@ -0,0 +1,135 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* security.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 __SECURITY__
|
||||
#define __SECURITY__
|
||||
|
||||
#include "nvmem.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define AES128_KEY_SIZE 16
|
||||
|
||||
#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_encrypt
|
||||
//!
|
||||
//! @param[in] key AES128 key of size 16 bytes
|
||||
//! @param[in\out] state 16 bytes of plain text and cipher text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief AES128 encryption:
|
||||
//! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes
|
||||
//! is computed. The AES implementation is in mode ECB (Electronic
|
||||
//! Code Book).
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern void aes_encrypt(unsigned char *state, unsigned char *key);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_decrypt
|
||||
//!
|
||||
//! @param[in] key AES128 key of size 16 bytes
|
||||
//! @param[in\out] state 16 bytes of cipher text and plain text
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief AES128 decryption:
|
||||
//! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes
|
||||
//! is computed The AES implementation is in mode ECB
|
||||
//! (Electronic Code Book).
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern void aes_decrypt(unsigned char *state, unsigned char *key);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_read_key
|
||||
//!
|
||||
//! @param[out] key AES128 key of size 16 bytes
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief Reads AES128 key from EEPROM
|
||||
//! Reads the AES128 key from fileID #12 in EEPROM
|
||||
//! returns an error if the key does not exist.
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern signed long aes_read_key(unsigned char *key);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! aes_write_key
|
||||
//!
|
||||
//! @param[out] key AES128 key of size 16 bytes
|
||||
//!
|
||||
//! @return on success 0, error otherwise.
|
||||
//!
|
||||
//! @brief writes AES128 key from EEPROM
|
||||
//! Writes the AES128 key to fileID #12 in EEPROM
|
||||
//!
|
||||
//!
|
||||
//*****************************************************************************
|
||||
extern signed long aes_write_key(unsigned char *key);
|
||||
|
||||
#endif //CC3000_UNENCRYPTED_SMART_CONFIG
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,691 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* socket.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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 __SOCKET_H__
|
||||
#define __SOCKET_H__
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup socket_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HOSTNAME_MAX_LENGTH (230) // 230 bytes + header shouldn't exceed 8 bit value
|
||||
|
||||
//--------- Address Families --------
|
||||
|
||||
#define AF_INET 2
|
||||
#define AF_INET6 23
|
||||
|
||||
//------------ Socket Types ------------
|
||||
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
#define SOCK_RAW 3 // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers
|
||||
#define SOCK_RDM 4
|
||||
#define SOCK_SEQPACKET 5
|
||||
|
||||
//----------- Socket Protocol ----------
|
||||
|
||||
#define IPPROTO_IP 0 // dummy for IP
|
||||
#define IPPROTO_ICMP 1 // control message protocol
|
||||
#define IPPROTO_IPV4 IPPROTO_IP // IP inside IP
|
||||
#define IPPROTO_TCP 6 // tcp
|
||||
#define IPPROTO_UDP 17 // user datagram protocol
|
||||
#define IPPROTO_IPV6 41 // IPv6 in IPv6
|
||||
#define IPPROTO_NONE 59 // No next header
|
||||
#define IPPROTO_RAW 255 // raw IP packet
|
||||
#define IPPROTO_MAX 256
|
||||
|
||||
//----------- Socket retunr codes -----------
|
||||
|
||||
#define SOC_ERROR (-1) // error
|
||||
#define SOC_IN_PROGRESS (-2) // socket in progress
|
||||
|
||||
//----------- Socket Options -----------
|
||||
#define SOL_SOCKET 0xffff // socket level
|
||||
#define SOCKOPT_RECV_NONBLOCK 0 // recv non block mode, set SOCK_ON or SOCK_OFF (default block mode)
|
||||
#define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout
|
||||
#define SOCKOPT_ACCEPT_NONBLOCK 2 // accept non block mode, set SOCK_ON or SOCK_OFF (default block mode)
|
||||
#define SOCK_ON 0 // socket non-blocking mode is enabled
|
||||
#define SOCK_OFF 1 // socket blocking mode is enabled
|
||||
|
||||
#define TCP_NODELAY 0x0001
|
||||
#define TCP_BSDURGENT 0x7000
|
||||
|
||||
#define MAX_PACKET_SIZE 1500
|
||||
#define MAX_LISTEN_QUEUE 4
|
||||
|
||||
#define IOCTL_SOCKET_EVENTMASK
|
||||
|
||||
#ifdef ENOBUFS
|
||||
#undef ENOBUFS
|
||||
#endif
|
||||
#define ENOBUFS 55 // No buffer space available
|
||||
|
||||
#define __FD_SETSIZE 32
|
||||
|
||||
#define ASIC_ADDR_LEN 8
|
||||
|
||||
#define NO_QUERY_RECIVED -3
|
||||
|
||||
|
||||
typedef struct _in_addr_t
|
||||
{
|
||||
unsigned long s_addr; // load with inet_aton()
|
||||
} in_addr;
|
||||
|
||||
typedef struct _sockaddr_t
|
||||
{
|
||||
unsigned short int sa_family;
|
||||
unsigned char sa_data[14];
|
||||
} sockaddr;
|
||||
|
||||
typedef struct _sockaddr_in_t
|
||||
{
|
||||
short sin_family; // e.g. AF_INET
|
||||
unsigned short sin_port; // e.g. htons(3490)
|
||||
in_addr sin_addr; // see struct in_addr, below
|
||||
char sin_zero[8]; // zero this if you want to
|
||||
} sockaddr_in;
|
||||
|
||||
typedef unsigned long socklen_t;
|
||||
|
||||
// The fd_set member is required to be an array of longs.
|
||||
typedef long int __fd_mask;
|
||||
|
||||
// It's easier to assume 8-bit bytes than to get CHAR_BIT.
|
||||
#define __NFDBITS (8 * sizeof (__fd_mask))
|
||||
#define __FDELT(d) ((d) / __NFDBITS)
|
||||
#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS))
|
||||
|
||||
#ifdef fd_set
|
||||
#undef fd_set // for compatibility with newlib, which defines fd_set
|
||||
#endif
|
||||
|
||||
// fd_set for select and pselect.
|
||||
typedef struct
|
||||
{
|
||||
__fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
|
||||
#define __FDS_BITS(set) ((set)->fds_bits)
|
||||
} fd_set;
|
||||
|
||||
// We don't use `memset' because this would require a prototype and
|
||||
// the array isn't too big.
|
||||
#define __FD_ZERO(set) \
|
||||
do { \
|
||||
unsigned int __i; \
|
||||
fd_set *__arr = (set); \
|
||||
for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \
|
||||
__FDS_BITS (__arr)[__i] = 0; \
|
||||
} while (0)
|
||||
#define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d))
|
||||
#define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d))
|
||||
#define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d))
|
||||
|
||||
// Access macros for 'fd_set'.
|
||||
#ifdef FD_SET
|
||||
#undef FD_SET
|
||||
#endif
|
||||
#ifdef FD_CLR
|
||||
#undef FD_CLR
|
||||
#endif
|
||||
#ifdef FD_ISSET
|
||||
#undef FD_ISSET
|
||||
#endif
|
||||
#ifdef FD_ZERO
|
||||
#undef FD_ZERO
|
||||
#endif
|
||||
#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp)
|
||||
#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp)
|
||||
#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp)
|
||||
#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp)
|
||||
|
||||
//Use in case of Big Endian only
|
||||
|
||||
#define htonl(A) ((((unsigned long)(A) & 0xff000000) >> 24) | \
|
||||
(((unsigned long)(A) & 0x00ff0000) >> 8) | \
|
||||
(((unsigned long)(A) & 0x0000ff00) << 8) | \
|
||||
(((unsigned long)(A) & 0x000000ff) << 24))
|
||||
|
||||
#define ntohl htonl
|
||||
|
||||
//Use in case of Big Endian only
|
||||
#define htons(A) ((((unsigned long)(A) & 0xff00) >> 8) | \
|
||||
(((unsigned long)(A) & 0x00ff) << 8))
|
||||
|
||||
|
||||
#define ntohs htons
|
||||
|
||||
// mDNS port - 5353 mDNS multicast address - 224.0.0.251
|
||||
#define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \
|
||||
sockaddr.sa_data[1] = 0xe9; \
|
||||
sockaddr.sa_data[2] = 0xe0; \
|
||||
sockaddr.sa_data[3] = 0x0; \
|
||||
sockaddr.sa_data[4] = 0x0; \
|
||||
sockaddr.sa_data[5] = 0xfb;
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Prototypes for the APIs.
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! socket
|
||||
//!
|
||||
//! @param domain selects the protocol family which will be used for
|
||||
//! communication. On this version only AF_INET is supported
|
||||
//! @param type specifies the communication semantics. On this version
|
||||
//! only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported
|
||||
//! @param protocol specifies a particular protocol to be used with the
|
||||
//! socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are
|
||||
//! supported.
|
||||
//!
|
||||
//! @return On success, socket handle that is used for consequent socket
|
||||
//! operations. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief create an endpoint for communication
|
||||
//! The socket function creates a socket that is bound to a specific
|
||||
//! transport service provider. This function is called by the
|
||||
//! application layer to obtain a socket handle.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int socket(long domain, long type, long protocol);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! closesocket
|
||||
//!
|
||||
//! @param sd socket handle.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief The socket function closes a created socket.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long closesocket(long sd);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! accept
|
||||
//!
|
||||
//! @param[in] sd socket descriptor (handle)
|
||||
//! @param[out] addr the argument addr is a pointer to a sockaddr structure
|
||||
//! This structure is filled in with the address of the
|
||||
//! peer socket, as known to the communications layer.
|
||||
//! determined. The exact format of the address returned
|
||||
//! addr is by the socket's address sockaddr.
|
||||
//! On this version only AF_INET is supported.
|
||||
//! This argument returns in network order.
|
||||
//! @param[out] addrlen the addrlen argument is a value-result argument:
|
||||
//! it should initially contain the size of the structure
|
||||
//! pointed to by addr.
|
||||
//!
|
||||
//! @return For socket in blocking mode:
|
||||
//! On success, socket handle. on failure negative
|
||||
//! For socket in non-blocking mode:
|
||||
//! - On connection establishment, socket handle
|
||||
//! - On connection pending, SOC_IN_PROGRESS (-2)
|
||||
//! - On failure, SOC_ERROR (-1)
|
||||
//!
|
||||
//! @brief accept a connection on a socket:
|
||||
//! This function is used with connection-based socket types
|
||||
//! (SOCK_STREAM). It extracts the first connection request on the
|
||||
//! queue of pending connections, creates a new connected socket, and
|
||||
//! returns a new file descriptor referring to that socket.
|
||||
//! The newly created socket is not in the listening state.
|
||||
//! The original socket sd is unaffected by this call.
|
||||
//! The argument sd is a socket that has been created with socket(),
|
||||
//! bound to a local address with bind(), and is listening for
|
||||
//! connections after a listen(). The argument addr is a pointer
|
||||
//! to a sockaddr structure. This structure is filled in with the
|
||||
//! address of the peer socket, as known to the communications layer.
|
||||
//! The exact format of the address returned addr is determined by the
|
||||
//! socket's address family. The addrlen argument is a value-result
|
||||
//! argument: it should initially contain the size of the structure
|
||||
//! pointed to by addr, on return it will contain the actual
|
||||
//! length (in bytes) of the address returned.
|
||||
//!
|
||||
//! @sa socket ; bind ; listen
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long accept(long sd, sockaddr *addr, socklen_t *addrlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! bind
|
||||
//!
|
||||
//! @param[in] sd socket descriptor (handle)
|
||||
//! @param[out] addr specifies the destination address. On this version
|
||||
//! only AF_INET is supported.
|
||||
//! @param[out] addrlen contains the size of the structure pointed to by addr.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief assign a name to a socket
|
||||
//! This function gives the socket the local address addr.
|
||||
//! addr is addrlen bytes long. Traditionally, this is called when a
|
||||
//! socket is created with socket, it exists in a name space (address
|
||||
//! family) but has no name assigned.
|
||||
//! It is necessary to assign a local address before a SOCK_STREAM
|
||||
//! socket may receive connections.
|
||||
//!
|
||||
//! @sa socket ; accept ; listen
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long bind(long sd, const sockaddr *addr, long addrlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! listen
|
||||
//!
|
||||
//! @param[in] sd socket descriptor (handle)
|
||||
//! @param[in] backlog specifies the listen queue depth. On this version
|
||||
//! backlog is not supported.
|
||||
//! @return On success, zero is returned. On error, -1 is returned.
|
||||
//!
|
||||
//! @brief listen for connections on a socket
|
||||
//! The willingness to accept incoming connections and a queue
|
||||
//! limit for incoming connections are specified with listen(),
|
||||
//! and then the connections are accepted with accept.
|
||||
//! The listen() call applies only to sockets of type SOCK_STREAM
|
||||
//! The backlog parameter defines the maximum length the queue of
|
||||
//! pending connections may grow to.
|
||||
//!
|
||||
//! @sa socket ; accept ; bind
|
||||
//!
|
||||
//! @note On this version, backlog is not supported
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long listen(long sd, long backlog);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! gethostbyname
|
||||
//!
|
||||
//! @param[in] hostname host name
|
||||
//! @param[in] usNameLen name length
|
||||
//! @param[out] out_ip_addr This parameter is filled in with host IP address.
|
||||
//! In case that host name is not resolved,
|
||||
//! out_ip_addr is zero.
|
||||
//! @return On success, positive is returned. On error, negative is returned
|
||||
//!
|
||||
//! @brief Get host IP by name. Obtain the IP Address of machine on network,
|
||||
//! by its name.
|
||||
//!
|
||||
//! @note On this version, only blocking mode is supported. Also note that
|
||||
//! the function requires DNS server to be configured prior to its usage.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern int gethostbyname(const char * hostname, uint8_t usNameLen, uint32_t* out_ip_addr);
|
||||
#endif
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! connect
|
||||
//!
|
||||
//! @param[in] sd socket descriptor (handle)
|
||||
//! @param[in] addr specifies the destination addr. On this version
|
||||
//! only AF_INET is supported.
|
||||
//! @param[out] addrlen contains the size of the structure pointed to by addr
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief initiate a connection on a socket
|
||||
//! Function connects the socket referred to by the socket descriptor
|
||||
//! sd, to the address specified by addr. The addrlen argument
|
||||
//! specifies the size of addr. The format of the address in addr is
|
||||
//! determined by the address space of the socket. If it is of type
|
||||
//! SOCK_DGRAM, this call specifies the peer with which the socket is
|
||||
//! to be associated; this address is that to which datagrams are to be
|
||||
//! sent, and the only address from which datagrams are to be received.
|
||||
//! If the socket is of type SOCK_STREAM, this call attempts to make a
|
||||
//! connection to another socket. The other socket is specified by
|
||||
//! address, which is an address in the communications space of the
|
||||
//! socket. Note that the function implements only blocking behavior
|
||||
//! thus the caller will be waiting either for the connection
|
||||
//! establishment or for the connection establishment failure.
|
||||
//!
|
||||
//! @sa socket
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long connect(long sd, const sockaddr *addr, long addrlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! select
|
||||
//!
|
||||
//! @param[in] nfds the highest-numbered file descriptor in any of the
|
||||
//! three sets, plus 1.
|
||||
//! @param[out] writesds socket descriptors list for write monitoring
|
||||
//! @param[out] readsds socket descriptors list for read monitoring
|
||||
//! @param[out] exceptsds socket descriptors list for exception monitoring
|
||||
//! @param[in] timeout is an upper bound on the amount of time elapsed
|
||||
//! before select() returns. Null means infinity
|
||||
//! timeout. The minimum timeout is 5 milliseconds,
|
||||
//! less than 5 milliseconds will be set
|
||||
//! automatically to 5 milliseconds.
|
||||
//! @return On success, select() returns the number of file descriptors
|
||||
//! contained in the three returned descriptor sets (that is, the
|
||||
//! total number of bits that are set in readfds, writefds,
|
||||
//! exceptfds) which may be zero if the timeout expires before
|
||||
//! anything interesting happens.
|
||||
//! On error, -1 is returned.
|
||||
//! *readsds - return the sockets on which Read request will
|
||||
//! return without delay with valid data.
|
||||
//! *writesds - return the sockets on which Write request
|
||||
//! will return without delay.
|
||||
//! *exceptsds - return the sockets which closed recently.
|
||||
//!
|
||||
//! @brief Monitor socket activity
|
||||
//! Select allow a program to monitor multiple file descriptors,
|
||||
//! waiting until one or more of the file descriptors become
|
||||
//! "ready" for some class of I/O operation
|
||||
//!
|
||||
//! @Note If the timeout value set to less than 5ms it will automatically set
|
||||
//! to 5ms to prevent overload of the system
|
||||
//!
|
||||
//! @sa socket
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int select(long nfds, fd_set *readsds, fd_set *writesds,
|
||||
fd_set *exceptsds, struct timeval *timeout);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! setsockopt
|
||||
//!
|
||||
//! @param[in] sd socket handle
|
||||
//! @param[in] level defines the protocol level for this option
|
||||
//! @param[in] optname defines the option name to Interrogate
|
||||
//! @param[in] optval specifies a value for the option
|
||||
//! @param[in] optlen specifies the length of the option value
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief set socket options
|
||||
//! This function manipulate the options associated with a socket.
|
||||
//! Options may exist at multiple protocol levels; they are always
|
||||
//! present at the uppermost socket level.
|
||||
//! When manipulating socket options the level at which the option
|
||||
//! resides and the name of the option must be specified.
|
||||
//! To manipulate options at the socket level, level is specified as
|
||||
//! SOL_SOCKET. To manipulate options at any other level the protocol
|
||||
//! number of the appropriate protocol controlling the option is
|
||||
//! supplied. For example, to indicate that an option is to be
|
||||
//! interpreted by the TCP protocol, level should be set to the
|
||||
//! protocol number of TCP;
|
||||
//! The parameters optval and optlen are used to access optval -
|
||||
//! use for setsockopt(). For getsockopt() they identify a buffer
|
||||
//! in which the value for the requested option(s) are to
|
||||
//! be returned. For getsockopt(), optlen is a value-result
|
||||
//! parameter, initially containing the size of the buffer
|
||||
//! pointed to by option_value, and modified on return to
|
||||
//! indicate the actual size of the value returned. If no option
|
||||
//! value is to be supplied or returned, option_value may be NULL.
|
||||
//!
|
||||
//! @Note On this version the following two socket options are enabled:
|
||||
//! The only protocol level supported in this version
|
||||
//! is SOL_SOCKET (level).
|
||||
//! 1. SOCKOPT_RECV_TIMEOUT (optname)
|
||||
//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
|
||||
//! in milliseconds.
|
||||
//! In that case optval should be pointer to unsigned long.
|
||||
//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
|
||||
//! or off.
|
||||
//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
|
||||
//!
|
||||
//! @sa getsockopt
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern int setsockopt(long sd, long level, long optname, const void *optval,
|
||||
socklen_t optlen);
|
||||
#endif
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! getsockopt
|
||||
//!
|
||||
//! @param[in] sd socket handle
|
||||
//! @param[in] level defines the protocol level for this option
|
||||
//! @param[in] optname defines the option name to Interrogate
|
||||
//! @param[out] optval specifies a value for the option
|
||||
//! @param[out] optlen specifies the length of the option value
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief set socket options
|
||||
//! This function manipulate the options associated with a socket.
|
||||
//! Options may exist at multiple protocol levels; they are always
|
||||
//! present at the uppermost socket level.
|
||||
//! When manipulating socket options the level at which the option
|
||||
//! resides and the name of the option must be specified.
|
||||
//! To manipulate options at the socket level, level is specified as
|
||||
//! SOL_SOCKET. To manipulate options at any other level the protocol
|
||||
//! number of the appropriate protocol controlling the option is
|
||||
//! supplied. For example, to indicate that an option is to be
|
||||
//! interpreted by the TCP protocol, level should be set to the
|
||||
//! protocol number of TCP;
|
||||
//! The parameters optval and optlen are used to access optval -
|
||||
//! use for setsockopt(). For getsockopt() they identify a buffer
|
||||
//! in which the value for the requested option(s) are to
|
||||
//! be returned. For getsockopt(), optlen is a value-result
|
||||
//! parameter, initially containing the size of the buffer
|
||||
//! pointed to by option_value, and modified on return to
|
||||
//! indicate the actual size of the value returned. If no option
|
||||
//! value is to be supplied or returned, option_value may be NULL.
|
||||
//!
|
||||
//! @Note On this version the following two socket options are enabled:
|
||||
//! The only protocol level supported in this version
|
||||
//! is SOL_SOCKET (level).
|
||||
//! 1. SOCKOPT_RECV_TIMEOUT (optname)
|
||||
//! SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout
|
||||
//! in milliseconds.
|
||||
//! In that case optval should be pointer to unsigned long.
|
||||
//! 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on
|
||||
//! or off.
|
||||
//! In that case optval should be SOCK_ON or SOCK_OFF (optval).
|
||||
//!
|
||||
//! @sa setsockopt
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int getsockopt(long sd, long level, long optname, void *optval,
|
||||
socklen_t *optlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! recv
|
||||
//!
|
||||
//! @param[in] sd socket handle
|
||||
//! @param[out] buf Points to the buffer where the message should be stored
|
||||
//! @param[in] len Specifies the length in bytes of the buffer pointed to
|
||||
//! by the buffer argument.
|
||||
//! @param[in] flags Specifies the type of message reception.
|
||||
//! On this version, this parameter is not supported.
|
||||
//!
|
||||
//! @return Return the number of bytes received, or -1 if an error
|
||||
//! occurred
|
||||
//!
|
||||
//! @brief function receives a message from a connection-mode socket
|
||||
//!
|
||||
//! @sa recvfrom
|
||||
//!
|
||||
//! @Note On this version, only blocking mode is supported.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int recv(long sd, void *buf, long len, long flags);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! recvfrom
|
||||
//!
|
||||
//! @param[in] sd socket handle
|
||||
//! @param[out] buf Points to the buffer where the message should be stored
|
||||
//! @param[in] len Specifies the length in bytes of the buffer pointed to
|
||||
//! by the buffer argument.
|
||||
//! @param[in] flags Specifies the type of message reception.
|
||||
//! On this version, this parameter is not supported.
|
||||
//! @param[in] from pointer to an address structure indicating the source
|
||||
//! address: sockaddr. On this version only AF_INET is
|
||||
//! supported.
|
||||
//! @param[in] fromlen source address structure size
|
||||
//!
|
||||
//! @return Return the number of bytes received, or -1 if an error
|
||||
//! occurred
|
||||
//!
|
||||
//! @brief read data from socket
|
||||
//! function receives a message from a connection-mode or
|
||||
//! connectionless-mode socket. Note that raw sockets are not
|
||||
//! supported.
|
||||
//!
|
||||
//! @sa recv
|
||||
//!
|
||||
//! @Note On this version, only blocking mode is supported.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int recvfrom(long sd, void *buf, long len, long flags, sockaddr *from,
|
||||
socklen_t *fromlen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! send
|
||||
//!
|
||||
//! @param sd socket handle
|
||||
//! @param buf Points to a buffer containing the message to be sent
|
||||
//! @param len message size in bytes
|
||||
//! @param flags On this version, this parameter is not supported
|
||||
//!
|
||||
//! @return Return the number of bytes transmitted, or -1 if an
|
||||
//! error occurred
|
||||
//!
|
||||
//! @brief Write data to TCP socket
|
||||
//! This function is used to transmit a message to another
|
||||
//! socket.
|
||||
//!
|
||||
//! @Note On this version, only blocking mode is supported.
|
||||
//!
|
||||
//! @sa sendto
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern int send(long sd, const void *buf, long len, long flags);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! sendto
|
||||
//!
|
||||
//! @param sd socket handle
|
||||
//! @param buf Points to a buffer containing the message to be sent
|
||||
//! @param len message size in bytes
|
||||
//! @param flags On this version, this parameter is not supported
|
||||
//! @param to pointer to an address structure indicating the destination
|
||||
//! address: sockaddr. On this version only AF_INET is
|
||||
//! supported.
|
||||
//! @param tolen destination address structure size
|
||||
//!
|
||||
//! @return Return the number of bytes transmitted, or -1 if an
|
||||
//! error occurred
|
||||
//!
|
||||
//! @brief Write data to TCP socket
|
||||
//! This function is used to transmit a message to another
|
||||
//! socket.
|
||||
//!
|
||||
//! @Note On this version, only blocking mode is supported.
|
||||
//!
|
||||
//! @sa send
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern int sendto(long sd, const void *buf, long len, long flags,
|
||||
const sockaddr *to, socklen_t tolen);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! mdnsAdvertiser
|
||||
//!
|
||||
//! @param[in] mdnsEnabled flag to enable/disable the mDNS feature
|
||||
//! @param[in] deviceServiceName Service name as part of the published
|
||||
//! canonical domain name
|
||||
//! @param[in] deviceServiceNameLength Length of the service name
|
||||
//!
|
||||
//!
|
||||
//! @return On success, zero is returned, return SOC_ERROR if socket was not
|
||||
//! opened successfully, or if an error occurred.
|
||||
//!
|
||||
//! @brief Set CC3000 in mDNS advertiser mode in order to advertise itself.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern int mdnsAdvertiser(unsigned short mdnsEnabled, char * deviceServiceName, unsigned short deviceServiceNameLength);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __SOCKET_H__
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,533 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* wlan.h - CC3000 Host Driver Implementation.
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*
|
||||
* Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
|
||||
* & Limor Fried for Adafruit Industries
|
||||
* This library works with the Adafruit CC3000 breakout
|
||||
* ----> https://www.adafruit.com/products/1469
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
|
||||
Adapted for use with the Arduino/AVR by KTOWN for Adafruit Industries
|
||||
This library works with the Adafruit CC3000 breakout
|
||||
----> https://www.adafruit.com/products/1469
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
*****************************************************************************/
|
||||
#ifndef __WLAN_H__
|
||||
#define __WLAN_H__
|
||||
|
||||
#include "cc3000_common.h"
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// If building with a C++ compiler, make all of the definitions in this header
|
||||
// have a C binding.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WLAN_SEC_UNSEC (0)
|
||||
#define WLAN_SEC_WEP (1)
|
||||
#define WLAN_SEC_WPA (2)
|
||||
#define WLAN_SEC_WPA2 (3)
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! \addtogroup wlan_api
|
||||
//! @{
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_init
|
||||
//!
|
||||
//! @param sWlanCB Asynchronous events callback.
|
||||
//! 0 no event call back.
|
||||
//! -call back parameters:
|
||||
//! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event,
|
||||
//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event,
|
||||
//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done,
|
||||
//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report,
|
||||
//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR
|
||||
//! HCI_EVNT_WLAN_KEEPALIVE keepalive.
|
||||
//! 2) data: pointer to extra data that received by the event
|
||||
//! (NULL no data).
|
||||
//! 3) length: data length.
|
||||
//! -Events with extra data:
|
||||
//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask,
|
||||
//! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes
|
||||
//! for DNS server.
|
||||
//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent,
|
||||
//! 4 bytes Packets received, 4 bytes Min round time,
|
||||
//! 4 bytes Max round time and 4 bytes for Avg round time.
|
||||
//!
|
||||
//! @param sFWPatches 0 no patch or pointer to FW patches
|
||||
//! @param sDriverPatches 0 no patch or pointer to driver patches
|
||||
//! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches
|
||||
//! @param sReadWlanInterruptPin init callback. the callback read wlan
|
||||
//! interrupt status.
|
||||
//! @param sWlanInterruptEnable init callback. the callback enable wlan
|
||||
//! interrupt.
|
||||
//! @param sWlanInterruptDisable init callback. the callback disable wlan
|
||||
//! interrupt.
|
||||
//! @param sWriteWlanPin init callback. the callback write value
|
||||
//! to device pin.
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @sa wlan_set_event_mask , wlan_start , wlan_stop
|
||||
//!
|
||||
//! @brief Initialize wlan driver
|
||||
//!
|
||||
//! @warning This function must be called before ANY other wlan driver function
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void wlan_init( tWlanCB sWlanCB,
|
||||
tFWPatches sFWPatches,
|
||||
tDriverPatches sDriverPatches,
|
||||
tBootLoaderPatches sBootLoaderPatches,
|
||||
tWlanReadInteruptPin sReadWlanInterruptPin,
|
||||
tWlanInterruptEnable sWlanInterruptEnable,
|
||||
tWlanInterruptDisable sWlanInterruptDisable,
|
||||
tWriteWlanPin sWriteWlanPin);
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_start
|
||||
//!
|
||||
//! @param usPatchesAvailableAtHost - flag to indicate if patches available
|
||||
//! from host or from EEPROM. Due to the
|
||||
//! fact the patches are burn to the EEPROM
|
||||
//! using the patch programmer utility, the
|
||||
//! patches will be available from the EEPROM
|
||||
//! and not from the host.
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Start WLAN device. This function asserts the enable pin of
|
||||
//! the device (WLAN_EN), starting the HW initialization process.
|
||||
//! The function blocked until device Initialization is completed.
|
||||
//! Function also configure patches (FW, driver or bootloader)
|
||||
//! and calls appropriate device callbacks.
|
||||
//!
|
||||
//! @Note Prior calling the function wlan_init shall be called.
|
||||
//! @Warning This function must be called after wlan_init and before any
|
||||
//! other wlan API
|
||||
//! @sa wlan_init , wlan_stop
|
||||
//!
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void wlan_start(unsigned short usPatchesAvailableAtHost);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_stop
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief Stop WLAN device by putting it into reset state.
|
||||
//!
|
||||
//! @sa wlan_start
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern void wlan_stop(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_connect
|
||||
//!
|
||||
//! @param sec_type security options:
|
||||
//! WLAN_SEC_UNSEC,
|
||||
//! WLAN_SEC_WEP (ASCII support only),
|
||||
//! WLAN_SEC_WPA or WLAN_SEC_WPA2
|
||||
//! @param ssid up to 32 bytes and is ASCII SSID of the AP
|
||||
//! @param ssid_len length of the SSID
|
||||
//! @param bssid 6 bytes specified the AP bssid
|
||||
//! @param key up to 16 bytes specified the AP security key
|
||||
//! @param key_len key length
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, negative is returned.
|
||||
//! Note that even though a zero is returned on success to trigger
|
||||
//! connection operation, it does not mean that CCC3000 is already
|
||||
//! connected. An asynchronous "Connected" event is generated when
|
||||
//! actual association process finishes and CC3000 is connected to
|
||||
//! the AP. If DHCP is set, An asynchronous "DHCP" event is
|
||||
//! generated when DHCP process is finish.
|
||||
//!
|
||||
//!
|
||||
//! @brief Connect to AP
|
||||
//! @warning Please Note that when connection to AP configured with security
|
||||
//! type WEP, please confirm that the key is set as ASCII and not
|
||||
//! as HEX.
|
||||
//! @sa wlan_disconnect
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifndef CC3000_TINY_DRIVER
|
||||
extern long wlan_connect(unsigned long ulSecType, const char *ssid, long ssid_len,
|
||||
unsigned char *bssid, unsigned char *key, long key_len);
|
||||
#else
|
||||
extern long wlan_connect(const char *ssid, long ssid_len);
|
||||
|
||||
#endif
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_disconnect
|
||||
//!
|
||||
//! @return 0 disconnected done, other CC3000 already disconnected
|
||||
//!
|
||||
//! @brief Disconnect connection from AP.
|
||||
//!
|
||||
//! @sa wlan_connect
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern long wlan_disconnect(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_add_profile
|
||||
//!
|
||||
//! @param ulSecType WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2
|
||||
//! @param ucSsid ssid SSID up to 32 bytes
|
||||
//! @param ulSsidLen ssid length
|
||||
//! @param ucBssid bssid 6 bytes
|
||||
//! @param ulPriority ulPriority profile priority. Lowest priority:0.
|
||||
//! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security
|
||||
//! @param ulGroupCipher_TxKeyIndex key index
|
||||
//! @param ulKeyMgmt KEY management
|
||||
//! @param ucPf_OrKey security key
|
||||
//! @param ulPassPhraseLen security key length for WPA\WPA2
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief When auto start is enabled, the device connects to
|
||||
//! station from the profiles table. Up to 7 profiles are supported.
|
||||
//! If several profiles configured the device choose the highest
|
||||
//! priority profile, within each priority group, device will choose
|
||||
//! profile based on security policy, signal strength, etc
|
||||
//! parameters. All the profiles are stored in CC3000 NVMEM.
|
||||
//!
|
||||
//! @sa wlan_ioctl_del_profile
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
extern long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid,
|
||||
unsigned long ulSsidLen,
|
||||
unsigned char *ucBssid,
|
||||
unsigned long ulPriority,
|
||||
unsigned long ulPairwiseCipher_Or_Key,
|
||||
unsigned long ulGroupCipher_TxKeyLen,
|
||||
unsigned long ulKeyMgmt,
|
||||
unsigned char* ucPf_OrKey,
|
||||
unsigned long ulPassPhraseLen);
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_ioctl_del_profile
|
||||
//!
|
||||
//! @param index number of profile to delete
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Delete WLAN profile
|
||||
//!
|
||||
//! @Note In order to delete all stored profile, set index to 255.
|
||||
//!
|
||||
//! @sa wlan_add_profile
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_ioctl_del_profile(unsigned long ulIndex);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_set_event_mask
|
||||
//!
|
||||
//! @param mask mask option:
|
||||
//! HCI_EVNT_WLAN_UNSOL_CONNECT connect event
|
||||
//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event
|
||||
//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE smart config done
|
||||
//! HCI_EVNT_WLAN_UNSOL_INIT init done
|
||||
//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report
|
||||
//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report
|
||||
//! HCI_EVNT_WLAN_KEEPALIVE keepalive
|
||||
//! HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission
|
||||
//! Saved: no.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Mask event according to bit mask. In case that event is
|
||||
//! masked (1), the device will not send the masked event to host.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_set_event_mask(unsigned long ulMask);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_ioctl_statusget
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING,
|
||||
//! STATUS_CONNECTING or WLAN_STATUS_CONNECTED
|
||||
//!
|
||||
//! @brief get wlan status: disconnected, scanning, connecting or connected
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_ioctl_statusget(void);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_ioctl_set_connection_policy
|
||||
//!
|
||||
//! @param should_connect_to_open_ap enable(1), disable(0) connect to any
|
||||
//! available AP. This parameter corresponds to the configuration of
|
||||
//! item # 3 in the brief description.
|
||||
//! @param should_use_fast_connect enable(1), disable(0). if enabled, tries
|
||||
//! to connect to the last connected AP. This parameter corresponds
|
||||
//! to the configuration of item # 1 in the brief description.
|
||||
//! @param auto_start enable(1), disable(0) auto connect
|
||||
//! after reset and periodically reconnect if needed. This
|
||||
//! configuration configures option 2 in the above description.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief When auto is enabled, the device tries to connect according
|
||||
//! the following policy:
|
||||
//! 1) If fast connect is enabled and last connection is valid,
|
||||
//! the device will try to connect to it without the scanning
|
||||
//! procedure (fast). The last connection will be marked as
|
||||
//! invalid, due to adding/removing profile.
|
||||
//! 2) If profile exists, the device will try to connect it
|
||||
//! (Up to seven profiles).
|
||||
//! 3) If fast and profiles are not found, and open mode is
|
||||
//! enabled, the device will try to connect to any AP.
|
||||
//! * Note that the policy settings are stored in the CC3000 NVMEM.
|
||||
//!
|
||||
//! @sa wlan_add_profile , wlan_ioctl_del_profile
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_ioctl_set_connection_policy(
|
||||
unsigned long should_connect_to_open_ap,
|
||||
unsigned long should_use_fast_connect,
|
||||
unsigned long ulUseProfiles);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_ioctl_get_scan_results
|
||||
//!
|
||||
//! @param[in] scan_timeout parameter not supported
|
||||
//! @param[out] ucResults scan result (_wlan_full_scan_results_args_t)
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Gets entry from scan result table.
|
||||
//! The scan results are returned one by one, and each entry
|
||||
//! represents a single AP found in the area. The following is a
|
||||
//! format of the scan result:
|
||||
//! - 4 Bytes: number of networks found
|
||||
//! - 4 Bytes: The status of the scan: 0 - aged results,
|
||||
//! 1 - results valid, 2 - no results
|
||||
//! - 42 bytes: Result entry, where the bytes are arranged as follows:
|
||||
//!
|
||||
//! - 1 bit isValid - is result valid or not
|
||||
//! - 7 bits rssi - RSSI value;
|
||||
//! - 2 bits: securityMode - security mode of the AP:
|
||||
//! 0 - Open, 1 - WEP, 2 WPA, 3 WPA2
|
||||
//! - 6 bits: SSID name length
|
||||
//! - 2 bytes: the time at which the entry has entered into
|
||||
//! scans result table
|
||||
//! - 32 bytes: SSID name
|
||||
//! - 6 bytes: BSSID
|
||||
//!
|
||||
//! @Note scan_timeout, is not supported on this version.
|
||||
//!
|
||||
//! @sa wlan_ioctl_set_scan_params
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
extern long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout,
|
||||
unsigned char *ucResults);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_ioctl_set_scan_params
|
||||
//!
|
||||
//! @param uiEnable - start/stop application scan:
|
||||
//! 1 = start scan with default interval value of 10 min.
|
||||
//! in order to set a different scan interval value apply the value
|
||||
//! in milliseconds. minimum 1 second. 0=stop). Wlan reset
|
||||
//! (wlan_stop() wlan_start()) is needed when changing scan interval
|
||||
//! value. Saved: No
|
||||
//! @param uiMinDwellTime minimum dwell time value to be used for each
|
||||
//! channel, in milliseconds. Saved: yes
|
||||
//! Recommended Value: 100 (Default: 20)
|
||||
//! @param uiMaxDwellTime maximum dwell time value to be used for each
|
||||
//! channel, in milliseconds. Saved: yes
|
||||
//! Recommended Value: 100 (Default: 30)
|
||||
//! @param uiNumOfProbeRequests max probe request between dwell time.
|
||||
//! Saved: yes. Recommended Value: 5 (Default:2)
|
||||
//! @param uiChannelMask bitwise, up to 13 channels (0x1fff).
|
||||
//! Saved: yes. Default: 0x7ff
|
||||
//! @param uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80)
|
||||
//! @param uiSNRThreshold NSR threshold. Saved: yes (Default: 0)
|
||||
//! @param uiDefaultTxPower probe Tx power. Saved: yes (Default: 205)
|
||||
//! @param aiIntervalList pointer to array with 16 entries (16 channels)
|
||||
//! each entry (unsigned long) holds timeout between periodic scan
|
||||
//! (connection scan) - in milliseconds. Saved: yes. Default 2000ms.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief start and stop scan procedure. Set scan parameters.
|
||||
//!
|
||||
//! @Note uiDefaultTxPower, is not supported on this version.
|
||||
//!
|
||||
//! @sa wlan_ioctl_get_scan_results
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long
|
||||
uiMinDwellTime,unsigned long uiMaxDwellTime,
|
||||
unsigned long uiNumOfProbeRequests,
|
||||
unsigned long uiChannelMask,
|
||||
long iRSSIThreshold,unsigned long uiSNRThreshold,
|
||||
unsigned long uiDefaultTxPower,
|
||||
unsigned long *aiIntervalList);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_smart_config_start
|
||||
//!
|
||||
//! @param algoEncryptedFlag indicates whether the information is encrypted
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Start to acquire device profile. The device acquire its own
|
||||
//! profile, if profile message is found. The acquired AP information
|
||||
//! is stored in CC3000 EEPROM only in case AES128 encryption is used.
|
||||
//! In case AES128 encryption is not used, a profile is created by
|
||||
//! CC3000 internally.
|
||||
//!
|
||||
//! @Note An asynchronous event - Smart Config Done will be generated as soon
|
||||
//! as the process finishes successfully.
|
||||
//!
|
||||
//! @sa wlan_smart_config_set_prefix , wlan_smart_config_stop
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_smart_config_start(unsigned long algoEncryptedFlag);
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_smart_config_stop
|
||||
//!
|
||||
//! @param algoEncryptedFlag indicates whether the information is encrypted
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Stop the acquire profile procedure
|
||||
//!
|
||||
//! @sa wlan_smart_config_start , wlan_smart_config_set_prefix
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_smart_config_stop(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_smart_config_set_prefix
|
||||
//!
|
||||
//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config.
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief Configure station ssid prefix. The prefix is used internally
|
||||
//! in CC3000. It should always be TTT.
|
||||
//!
|
||||
//! @Note The prefix is stored in CC3000 NVMEM
|
||||
//!
|
||||
//! @sa wlan_smart_config_start , wlan_smart_config_stop
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_smart_config_set_prefix(char* cNewPrefix);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! wlan_smart_config_process
|
||||
//!
|
||||
//! @param none
|
||||
//!
|
||||
//! @return On success, zero is returned. On error, -1 is returned
|
||||
//!
|
||||
//! @brief process the acquired data and store it as a profile. The acquired
|
||||
//! AP information is stored in CC3000 EEPROM encrypted.
|
||||
//! The encrypted data is decrypted and stored as a profile.
|
||||
//! behavior is as defined by connection policy.
|
||||
//
|
||||
//*****************************************************************************
|
||||
extern long wlan_smart_config_process(void);
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Close the Doxygen group.
|
||||
//! @}
|
||||
//
|
||||
//*****************************************************************************
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
// Mark the end of the C bindings section for C++ compilers.
|
||||
//
|
||||
//*****************************************************************************
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // __WLAN_H__
|
|
@ -36,9 +36,7 @@
|
|||
#include "accel.h"
|
||||
#include "servo.h"
|
||||
#include "dac.h"
|
||||
#if 0
|
||||
#include "pybwlan.h"
|
||||
#endif
|
||||
|
||||
void SystemClock_Config(void);
|
||||
|
||||
|
|
|
@ -0,0 +1,379 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
|
||||
#include "cc3k/ccspi.h"
|
||||
#include "cc3k/hci.h"
|
||||
#include "cc3k/socket.h"
|
||||
#include "cc3k/netapp.h"
|
||||
#include "cc3k/wlan.h"
|
||||
#include "cc3k/nvmem.h"
|
||||
|
||||
mp_obj_t pyb_wlan_connect(uint n_args, const mp_obj_t *args) {
|
||||
const char *ap;
|
||||
const char *key;
|
||||
if (n_args == 2) {
|
||||
ap = mp_obj_str_get_str(args[0]);
|
||||
key = mp_obj_str_get_str(args[1]);
|
||||
} else {
|
||||
ap = "your-ssid";
|
||||
key = "your-password";
|
||||
}
|
||||
// might want to set wlan_ioctl_set_connection_policy
|
||||
int ret = wlan_connect(WLAN_SEC_WPA2, ap, strlen(ap), NULL, (byte*)key, strlen(key));
|
||||
return mp_obj_new_int(ret);
|
||||
}
|
||||
|
||||
mp_obj_t pyb_wlan_disconnect(void) {
|
||||
int ret = wlan_disconnect();
|
||||
return mp_obj_new_int(ret);
|
||||
}
|
||||
|
||||
mp_obj_t decode_addr(unsigned char *ip, int n_bytes) {
|
||||
char data[64] = "";
|
||||
if (n_bytes == 4) {
|
||||
snprintf(data, 64, "%u.%u.%u.%u", ip[3], ip[2], ip[1], ip[0]);
|
||||
} else if (n_bytes == 6) {
|
||||
snprintf(data, 64, "%02x:%02x:%02x:%02x:%02x:%02x", ip[5], ip[4], ip[3], ip[2], ip[1], ip[0]);
|
||||
} else if (n_bytes == 32) {
|
||||
snprintf(data, 64, "%s", ip);
|
||||
}
|
||||
return mp_obj_new_str((byte*)data, strlen(data), false);
|
||||
}
|
||||
|
||||
void decode_addr_and_store(mp_obj_t object, qstr q_attr, unsigned char *ip, int n_bytes) {
|
||||
mp_store_attr(object, q_attr, decode_addr(ip, n_bytes));
|
||||
}
|
||||
|
||||
static mp_obj_t net_address_type = MP_OBJ_NULL;
|
||||
|
||||
mp_obj_t pyb_wlan_get_ip(void) {
|
||||
tNetappIpconfigRetArgs ipconfig;
|
||||
netapp_ipconfig(&ipconfig);
|
||||
|
||||
// If byte 1 is 0 we don't have a valid address
|
||||
if (ipconfig.aucIP[3] == 0) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// if it doesn't already exist, make a new empty class for NetAddress objects
|
||||
if (net_address_type == MP_OBJ_NULL) {
|
||||
net_address_type = mp_obj_new_type(QSTR_FROM_STR_STATIC("NetAddress"), mp_const_empty_tuple, mp_obj_new_dict(0));
|
||||
}
|
||||
|
||||
// make a new NetAddress object
|
||||
mp_obj_t net_addr = mp_call_function_0(net_address_type);
|
||||
|
||||
// fill the NetAddress object with data
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("ip"), &ipconfig.aucIP[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("subnet"), &ipconfig.aucSubnetMask[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("gateway"), &ipconfig.aucDefaultGateway[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("dhcp"), &ipconfig.aucDHCPServer[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("dns"), &ipconfig.aucDNSServer[0], 4);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("mac"), &ipconfig.uaMacAddr[0], 6);
|
||||
decode_addr_and_store(net_addr, QSTR_FROM_STR_STATIC("ssid"), &ipconfig.uaSSID[0], 32);
|
||||
|
||||
return net_addr;
|
||||
}
|
||||
|
||||
uint32_t last_ip = 0; // XXX such a hack!
|
||||
mp_obj_t pyb_wlan_get_host(mp_obj_t host_name) {
|
||||
const char *host = mp_obj_str_get_str(host_name);
|
||||
uint32_t ip;
|
||||
if (gethostbyname(host, strlen(host), &ip) < 0) {
|
||||
printf("gethostbyname failed\n");
|
||||
return mp_const_none;
|
||||
}
|
||||
if (ip == 0) {
|
||||
// unknown host
|
||||
return mp_const_none;
|
||||
}
|
||||
last_ip = ip;
|
||||
byte ip_data[4];
|
||||
ip_data[0] = ((ip >> 0) & 0xff);
|
||||
ip_data[1] = ((ip >> 8) & 0xff);
|
||||
ip_data[2] = ((ip >> 16) & 0xff);
|
||||
ip_data[3] = ((ip >> 24) & 0xff);
|
||||
return decode_addr(ip_data, 4);
|
||||
}
|
||||
|
||||
mp_obj_t pyb_wlan_http_get(mp_obj_t host_name, mp_obj_t host_path) {
|
||||
if (host_name == mp_const_none) {
|
||||
last_ip = (192 << 24) | (168 << 16) | (0 << 8) | (3);
|
||||
} else {
|
||||
if (pyb_wlan_get_host(host_name) == mp_const_none) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "unknown host"));
|
||||
}
|
||||
}
|
||||
int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (sd < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "socket failed: %d", sd));
|
||||
}
|
||||
//printf("socket seemed to work\n");
|
||||
//HAL_Delay(200);
|
||||
sockaddr_in remote;
|
||||
memset(&remote, 0, sizeof(sockaddr_in));
|
||||
remote.sin_family = AF_INET;
|
||||
remote.sin_port = htons(80);
|
||||
remote.sin_addr.s_addr = htonl(last_ip);
|
||||
int ret = connect(sd, (sockaddr*)&remote, sizeof(sockaddr));
|
||||
if (ret != 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "connect failed: %d", ret));
|
||||
}
|
||||
//printf("connect seemed to work\n");
|
||||
//HAL_Delay(200);
|
||||
|
||||
vstr_t *vstr = vstr_new();
|
||||
vstr_printf(vstr, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: PYBv2\r\n\r\n", mp_obj_str_get_str(host_path), mp_obj_str_get_qstr(host_name));
|
||||
const char *query = vstr_str(vstr);
|
||||
|
||||
// send query
|
||||
{
|
||||
int sent = 0;
|
||||
while (sent < strlen(query)) {
|
||||
/*
|
||||
extern void SpiIntGPIOHandler(void);
|
||||
SpiIntGPIOHandler();
|
||||
*/
|
||||
//printf("sending %d bytes\n", strlen(query + sent));
|
||||
ret = send(sd, query + sent, strlen(query + sent), 0);
|
||||
//printf("sent %d bytes\n", ret);
|
||||
if (ret < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "send failed"));
|
||||
}
|
||||
sent += ret;
|
||||
//HAL_Delay(200);
|
||||
}
|
||||
}
|
||||
|
||||
//printf("send seemed to work!\n");
|
||||
//HAL_Delay(5000);
|
||||
|
||||
// receive reply
|
||||
mp_obj_t mp_ret = mp_const_none;
|
||||
{
|
||||
//printf("doing receive\n");
|
||||
char buf[64];
|
||||
vstr_reset(vstr);
|
||||
|
||||
for (;;) {
|
||||
// do a select() call on this socket
|
||||
timeval timeout;
|
||||
fd_set fd_read;
|
||||
|
||||
memset(&fd_read, 0, sizeof(fd_read));
|
||||
FD_SET(sd, &fd_read);
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 500000; // 500 millisec
|
||||
|
||||
int s = select(sd+1, &fd_read, NULL, NULL, &timeout);
|
||||
if (s == 0) {
|
||||
// no data available
|
||||
break;
|
||||
}
|
||||
|
||||
// read data
|
||||
ret = recv(sd, buf, 64, 0);
|
||||
if (ret < 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "recv failed %d", ret));
|
||||
}
|
||||
vstr_add_strn(vstr, buf, ret);
|
||||
}
|
||||
|
||||
mp_ret = mp_obj_new_str((byte*)vstr->buf, vstr->len, false);
|
||||
}
|
||||
|
||||
closesocket(sd);
|
||||
vstr_free(vstr);
|
||||
|
||||
return mp_ret;
|
||||
}
|
||||
|
||||
mp_obj_t pyb_wlan_serve(void) {
|
||||
printf("serve socket\n");
|
||||
int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
printf("serve socket got %d\n", sd);
|
||||
HAL_Delay(500);
|
||||
if (sd < 0) {
|
||||
printf("socket fail\n");
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "socket failed: %d", sd));
|
||||
}
|
||||
|
||||
/*
|
||||
if (setsockopt(sd, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, SOCK_ON, sizeof(SOCK_ON)) < 0) {
|
||||
printf("couldn't set socket as non-blocking\n");
|
||||
return mp_const_none;
|
||||
}
|
||||
*/
|
||||
|
||||
sockaddr_in remote;
|
||||
memset(&remote, 0, sizeof(sockaddr_in));
|
||||
remote.sin_family = AF_INET;
|
||||
remote.sin_port = htons(8080);
|
||||
remote.sin_addr.s_addr = htonl(0);
|
||||
printf("serve bind\n");
|
||||
int ret = bind(sd, (sockaddr*)&remote, sizeof(sockaddr));
|
||||
printf("serve bind got %d\n", ret);
|
||||
HAL_Delay(100);
|
||||
if (ret != 0) {
|
||||
printf("bind fail\n");
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "bind failed: %d", ret));
|
||||
}
|
||||
printf("bind seemed to work\n");
|
||||
|
||||
// listen
|
||||
ret = listen(sd, 0);
|
||||
printf("listen = %d\n", ret);
|
||||
HAL_Delay(100);
|
||||
|
||||
// accept connections
|
||||
int fd = -1;
|
||||
for (;;) {
|
||||
sockaddr accept_addr;
|
||||
socklen_t accept_len;
|
||||
fd = accept(sd, &accept_addr, &accept_len);
|
||||
printf("accept = %d\n", fd);
|
||||
HAL_Delay(500);
|
||||
if (fd >= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// receive some data
|
||||
{
|
||||
printf("receiving on sd=%d fd=%d\n", sd, fd);
|
||||
char buf[64];
|
||||
ret = recv(fd, buf, 64, 0);
|
||||
printf("recv = %d\n", ret);
|
||||
if (ret > 0) {
|
||||
printf("****%.*s****\n", ret, buf);
|
||||
}
|
||||
HAL_Delay(100);
|
||||
}
|
||||
|
||||
// send some data
|
||||
ret = send(fd, "test data!", 10, 0);
|
||||
printf("send = %d\n", ret);
|
||||
HAL_Delay(100);
|
||||
|
||||
closesocket(fd);
|
||||
closesocket(sd);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//
|
||||
//! CC3000_UsynchCallback
|
||||
//!
|
||||
//! @param lEventType Event type
|
||||
//! @param data
|
||||
//! @param length
|
||||
//!
|
||||
//! @return none
|
||||
//!
|
||||
//! @brief The function handles asynchronous events that come from CC3000
|
||||
//! device and operates a led for indicate
|
||||
//
|
||||
//*****************************************************************************
|
||||
void CC3000_UsynchCallback(long lEventType, char * data, unsigned char length)
|
||||
{
|
||||
if (lEventType == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE)
|
||||
{
|
||||
//ulSmartConfigFinished = 1;
|
||||
//ucStopSmartConfig = 1;
|
||||
printf("WLAN: simple config done\n");
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVNT_WLAN_UNSOL_CONNECT)
|
||||
{
|
||||
//ulCC3000Connected = 1;
|
||||
printf("WLAN unsol connect\n");
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVNT_WLAN_UNSOL_DISCONNECT)
|
||||
{
|
||||
//ulCC3000Connected = 0;
|
||||
//ulCC3000DHCP = 0;
|
||||
//ulCC3000DHCP_configured = 0;
|
||||
printf("WLAN unsol disconnect\n");
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVNT_WLAN_UNSOL_DHCP)
|
||||
{
|
||||
//ulCC3000DHCP = 1;
|
||||
printf("WLAN unsol DHCP\n");
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVENT_CC3000_CAN_SHUT_DOWN)
|
||||
{
|
||||
//OkToDoShutDown = 1;
|
||||
printf("WLAN can shut down\n");
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVNT_WLAN_ASYNC_PING_REPORT)
|
||||
{
|
||||
printf("WLAN async ping report\n");
|
||||
//PRINT_F("CC3000: Ping report\n\r");
|
||||
//pingReportnum++;
|
||||
//memcpy(&pingReport, data, length);
|
||||
}
|
||||
|
||||
if (lEventType == HCI_EVNT_BSD_TCP_CLOSE_WAIT) {
|
||||
printf("WLAN bsd tcp close wait\n");
|
||||
/*
|
||||
uint8_t socketnum;
|
||||
socketnum = data[0];
|
||||
//PRINT_F("TCP Close wait #"); printDec(socketnum);
|
||||
if (socketnum < MAX_SOCKETS)
|
||||
closed_sockets[socketnum] = true;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void pyb_wlan_init(void) {
|
||||
SpiInit();
|
||||
wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch, ReadWlanInterruptPin, WlanInterruptEnable, WlanInterruptDisable, WriteWlanPin);
|
||||
|
||||
mp_obj_t m = mp_obj_new_module(QSTR_FROM_STR_STATIC("wlan"));
|
||||
mp_store_attr(m, QSTR_FROM_STR_STATIC("connect"), mp_make_function_var(0, pyb_wlan_connect));
|
||||
mp_store_attr(m, QSTR_FROM_STR_STATIC("disconnect"), mp_make_function_n(0, pyb_wlan_disconnect));
|
||||
mp_store_attr(m, QSTR_FROM_STR_STATIC("ip"), mp_make_function_n(0, pyb_wlan_get_ip));
|
||||
mp_store_attr(m, QSTR_FROM_STR_STATIC("get_host"), mp_make_function_n(1, pyb_wlan_get_host));
|
||||
mp_store_attr(m, QSTR_FROM_STR_STATIC("http_get"), mp_make_function_n(2, pyb_wlan_http_get));
|
||||
mp_store_attr(m, QSTR_FROM_STR_STATIC("serve"), mp_make_function_n(0, pyb_wlan_serve));
|
||||
mp_store_name(QSTR_FROM_STR_STATIC("wlan"), m);
|
||||
}
|
||||
|
||||
void pyb_wlan_start(void) {
|
||||
wlan_start(0);
|
||||
|
||||
// TODO: check return value !=0
|
||||
|
||||
wlan_ioctl_set_connection_policy(0, 0, 0); // don't auto-connect
|
||||
wlan_ioctl_del_profile(255); // delete stored eeprom data
|
||||
|
||||
// Mask out all non-required events from CC3000
|
||||
wlan_set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT |
|
||||
//HCI_EVNT_WLAN_ASYNC_PING_REPORT |// we want ping reports
|
||||
//HCI_EVNT_BSD_TCP_CLOSE_WAIT |
|
||||
//HCI_EVNT_WLAN_TX_COMPLETE |
|
||||
HCI_EVNT_WLAN_KEEPALIVE);
|
||||
|
||||
/*
|
||||
byte ver[2];
|
||||
int ret = nvmem_read_sp_version(ver);
|
||||
printf("nvmem_read_sp_version=%d; %02x %02x\n", ret, ver[0], ver[1]);
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
void pyb_wlan_init(void);
|
||||
void pyb_wlan_start(void);
|
Loading…
Reference in New Issue