CC3000 driver updates from David Sidrane
This commit is contained in:
parent
212b5f504c
commit
4cf9540563
File diff suppressed because it is too large
Load Diff
@ -9,8 +9,8 @@
|
|||||||
* CC30000 from Texas Instruments http://processors.wiki.ti.com/index.php/CC3000
|
* CC30000 from Texas Instruments http://processors.wiki.ti.com/index.php/CC3000
|
||||||
*
|
*
|
||||||
* See also:
|
* See also:
|
||||||
* http://processors.wiki.ti.com/index.php/CC3000_Host_Driver_Porting_Guide
|
* http://processors.wiki.ti.com/index.php/CC3000_Host_Driver_Porting_Guide
|
||||||
* http://processors.wiki.ti.com/index.php/CC3000_Host_Programming_Guide
|
* http://processors.wiki.ti.com/index.php/CC3000_Host_Programming_Guide
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -61,19 +61,15 @@
|
|||||||
* Pre-Processor Definitions
|
* Pre-Processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* CC3000 Interfaces *********************************************************************/
|
/* CC3000 Interfaces ********************************************************/
|
||||||
|
|
||||||
/* Driver support **************************************************************************/
|
/* Driver support ***********************************************************/
|
||||||
/* This format is used to construct the /dev/input[n] device driver path. It
|
/* This format is used to construct the /dev/input[n] device driver path. It
|
||||||
* defined here so that it will be used consistently in all places.
|
* defined here so that it will be used consistently in all places.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/********************************************************************************************
|
|
||||||
* Public Types
|
|
||||||
********************************************************************************************/
|
|
||||||
#define READ 3
|
#define READ 3
|
||||||
#define READ_COMMAND {READ, 0 , 0 , 0 , 0}
|
#define READ_COMMAND {READ, 0 , 0 , 0 , 0}
|
||||||
#define READ_OFFSET_TO_LENGTH 3 //cmd dmy dmy lh ll
|
#define READ_OFFSET_TO_LENGTH 3 //cmd dmy dmy lh ll
|
||||||
#define WRITE 1
|
#define WRITE 1
|
||||||
|
|
||||||
@ -82,38 +78,44 @@
|
|||||||
|
|
||||||
#define SPI_HEADER_SIZE (5)
|
#define SPI_HEADER_SIZE (5)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Types
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
/* This structure describes the state of one CC3000 driver instance */
|
/* This structure describes the state of one CC3000 driver instance */
|
||||||
typedef enum {
|
|
||||||
eSPI_STATE_POWERUP = 0,
|
|
||||||
eSPI_STATE_INITIALIZED,
|
|
||||||
eSPI_STATE_IDLE,
|
|
||||||
eSPI_STATE_WRITE_WAIT_IRQ,
|
|
||||||
eSPI_STATE_WRITE_PROCEED,
|
|
||||||
eSPI_STATE_WRITE_DONE,
|
|
||||||
eSPI_STATE_READ_IRQ,
|
|
||||||
eSPI_STATE_READ_PROCEED,
|
|
||||||
eSPI_STATE_READ_READY,
|
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
eSPI_STATE_POWERUP = 0,
|
||||||
|
eSPI_STATE_INITIALIZED,
|
||||||
|
eSPI_STATE_IDLE,
|
||||||
|
eSPI_STATE_WRITE_WAIT_IRQ,
|
||||||
|
eSPI_STATE_WRITE_PROCEED,
|
||||||
|
eSPI_STATE_WRITE_DONE,
|
||||||
|
eSPI_STATE_READ_IRQ,
|
||||||
|
eSPI_STATE_READ_PROCEED,
|
||||||
|
eSPI_STATE_READ_READY,
|
||||||
} eDeviceStates;
|
} eDeviceStates;
|
||||||
|
|
||||||
struct cc3000_dev_s
|
struct cc3000_dev_s
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_CC3000_MULTIPLE
|
#ifdef CONFIG_CC3000_MULTIPLE
|
||||||
FAR struct cc3000_dev_s *flink; /* Supports a singly linked list of drivers */
|
FAR struct cc3000_dev_s *flink; /* Supports a singly linked list of drivers */
|
||||||
#endif
|
#endif
|
||||||
|
pthread_t workertid; /* Handle for the worker thread */
|
||||||
uint8_t crefs; /* Number of times the device has been opened */
|
uint8_t crefs; /* Number of times the device has been opened */
|
||||||
uint8_t nwaiters; /* Number of threads waiting for CC3000 data */
|
uint8_t nwaiters; /* Number of threads waiting for CC3000 data */
|
||||||
uint8_t minor; /* minor */
|
uint8_t minor; /* minor */
|
||||||
sem_t devsem; /* Manages exclusive access to this structure */
|
sem_t devsem; /* Manages exclusive access to this structure */
|
||||||
|
sem_t wrkwaitsem; /* Suspend and resume the delivery of messages */
|
||||||
sem_t waitsem; /* Used to wait for the availability of data */
|
sem_t waitsem; /* Used to wait for the availability of data */
|
||||||
sem_t readysem; /* Used to wait for Ready Condition from the cc3000 */
|
sem_t irqsem; /* Used to signal irq from cc3000 */
|
||||||
|
sem_t readysem; /* Used to wait for Ready Condition from the cc3000 */
|
||||||
|
|
||||||
FAR struct cc3000_config_s *config; /* Board configuration data */
|
FAR struct cc3000_config_s *config; /* Board configuration data */
|
||||||
FAR struct spi_dev_s *spi; /* Saved SPI driver instance */
|
FAR struct spi_dev_s *spi; /* Saved SPI driver instance */
|
||||||
struct work_s work; /* Supports the interrupt handling "bottom half" */
|
mqd_t queue; /* For unsolicited data delivery */
|
||||||
mqd_t queue; /* For unsolicited data delivery */
|
eDeviceStates state; /* The device state */
|
||||||
eDeviceStates state; /* The device state */
|
|
||||||
uint8_t rx_buffer[CC3000_RX_BUFFER_SIZE];
|
uint8_t rx_buffer[CC3000_RX_BUFFER_SIZE];
|
||||||
ssize_t rx_buffer_len;
|
ssize_t rx_buffer_len;
|
||||||
|
|
||||||
|
@ -36,8 +36,11 @@
|
|||||||
* Included Files
|
* Included Files
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include <nuttx/config.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/wireless/cc3000/cc3000_common.h>
|
#include <nuttx/wireless/cc3000/cc3000_common.h>
|
||||||
#include <nuttx/wireless/cc3000/hci.h>
|
#include <nuttx/wireless/cc3000/hci.h>
|
||||||
@ -234,8 +237,7 @@ uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (tSLInformation.usEventOrDataReceived != 0)
|
if (tSLInformation.usEventOrDataReceived != 0) {
|
||||||
{
|
|
||||||
pucReceivedData = (tSLInformation.pucReceivedData);
|
pucReceivedData = (tSLInformation.pucReceivedData);
|
||||||
|
|
||||||
if (*pucReceivedData == HCI_TYPE_EVNT)
|
if (*pucReceivedData == HCI_TYPE_EVNT)
|
||||||
@ -363,10 +365,11 @@ uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen)
|
|||||||
|
|
||||||
if (((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes ==
|
if (((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes ==
|
||||||
ERROR_SOCKET_INACTIVE)
|
ERROR_SOCKET_INACTIVE)
|
||||||
{
|
{
|
||||||
set_socket_active_status
|
set_socket_active_status
|
||||||
(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
|
(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,
|
||||||
}
|
SOCKET_STATUS_INACTIVE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -435,7 +438,7 @@ uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen)
|
|||||||
pRetParams = ((char *)pRetParams) + 2;
|
pRetParams = ((char *)pRetParams) + 2;
|
||||||
memcpy((uint8_t *)pRetParams,
|
memcpy((uint8_t *)pRetParams,
|
||||||
(char *)(pucReceivedParams +
|
(char *)(pucReceivedParams +
|
||||||
GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2),
|
GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2),
|
||||||
GET_SCAN_RESULTS_SSID_MAC_LENGTH);
|
GET_SCAN_RESULTS_SSID_MAC_LENGTH);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -902,7 +905,36 @@ void SimpleLinkWaitEvent(uint16_t usOpcode, void *pRetParams)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
tSLInformation.usRxEventOpcode = usOpcode;
|
tSLInformation.usRxEventOpcode = usOpcode;
|
||||||
hci_event_handler(pRetParams, 0, 0);
|
nllvdbg("Looking for usOpcode 0x%x\n",usOpcode);
|
||||||
|
uint16_t event_type;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
tSLInformation.pucReceivedData = SpiWait();
|
||||||
|
tSLInformation.usEventOrDataReceived = 1;
|
||||||
|
STREAM_TO_UINT16((char *)tSLInformation.pucReceivedData, HCI_EVENT_OPCODE_OFFSET,event_type);
|
||||||
|
|
||||||
|
if (*tSLInformation.pucReceivedData == HCI_TYPE_EVNT)
|
||||||
|
{
|
||||||
|
nllvdbg("Evtn:0x%x\n",event_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event_type != usOpcode)
|
||||||
|
{
|
||||||
|
if (hci_unsolicited_event_handler() == 1)
|
||||||
|
{
|
||||||
|
nllvdbg("Processed Event 0x%x want 0x%x\n",event_type, usOpcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nllvdbg("Processing usOpcode 0x%x\n",usOpcode);
|
||||||
|
hci_event_handler(pRetParams, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(tSLInformation.usRxEventOpcode != 0);
|
||||||
|
|
||||||
|
nllvdbg("Done for usOpcode 0x%x\n",usOpcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -928,6 +960,37 @@ void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen)
|
|||||||
* after the end of current transaction, i.e. only after data will be received
|
* after the end of current transaction, i.e. only after data will be received
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tSLInformation.usRxDataPending = 1;
|
nllvdbg("Looking for Data\n");
|
||||||
hci_event_handler(pBuf, from, fromlen);
|
uint16_t event_type;
|
||||||
|
uint16_t usOpcode = tSLInformation.usRxEventOpcode;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
tSLInformation.pucReceivedData = SpiWait();
|
||||||
|
tSLInformation.usEventOrDataReceived = 1;
|
||||||
|
|
||||||
|
if (*tSLInformation.pucReceivedData == HCI_TYPE_DATA)
|
||||||
|
{
|
||||||
|
tSLInformation.usRxDataPending = 1;
|
||||||
|
hci_event_handler(pBuf, from, fromlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
STREAM_TO_UINT16((char *)tSLInformation.pucReceivedData, HCI_EVENT_OPCODE_OFFSET,event_type);
|
||||||
|
nllvdbg("Evtn:0x%x\n",event_type);
|
||||||
|
|
||||||
|
if (hci_unsolicited_event_handler() == 1)
|
||||||
|
{
|
||||||
|
nllvdbg("Processed Event 0x%x want Data! Opcode 0x%x\n",event_type, usOpcode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nllvdbg("!!!!!usOpcode 0x%x\n",usOpcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(*tSLInformation.pucReceivedData == HCI_TYPE_EVNT);
|
||||||
|
|
||||||
|
nllvdbg("Done for Data 0x%x\n",usOpcode);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <debug.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <nuttx/wireless/cc3000/hci.h>
|
#include <nuttx/wireless/cc3000/hci.h>
|
||||||
#include <nuttx/wireless/cc3000/include/sys/socket.h>
|
#include <nuttx/wireless/cc3000/include/sys/socket.h>
|
||||||
@ -139,7 +141,14 @@ int HostFlowControlConsumeBuff(int sd)
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} while (0 == tSLInformation.usNumberOfFreeBuffers);
|
|
||||||
|
/* We must yield here for the the Event to get processed that returns
|
||||||
|
* the buffers
|
||||||
|
*/
|
||||||
|
|
||||||
|
usleep(100000);
|
||||||
|
}
|
||||||
|
while (0 == tSLInformation.usNumberOfFreeBuffers);
|
||||||
|
|
||||||
tSLInformation.usNumberOfFreeBuffers--;
|
tSLInformation.usNumberOfFreeBuffers--;
|
||||||
|
|
||||||
@ -1213,8 +1222,9 @@ int sendto(long sd, const void *buf, long len, long flags, const sockaddr *to,
|
|||||||
int mdnsAdvertiser(uint16_t mdnsEnabled, char * deviceServiceName,
|
int mdnsAdvertiser(uint16_t mdnsEnabled, char * deviceServiceName,
|
||||||
uint16_t deviceServiceNameLength)
|
uint16_t deviceServiceNameLength)
|
||||||
{
|
{
|
||||||
|
uint8_t *pTxBuffer;
|
||||||
|
uint8_t *pArgs;
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t *pTxBuffer, *pArgs;
|
|
||||||
|
|
||||||
if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH)
|
if (deviceServiceNameLength > MDNS_DEVICE_SERVICE_MAX_LENGTH)
|
||||||
{
|
{
|
||||||
|
@ -59,6 +59,10 @@
|
|||||||
# define spivdbg(x...)
|
# define spivdbg(x...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Private Types
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
int cc3000fd;
|
int cc3000fd;
|
||||||
@ -66,6 +70,7 @@ static struct
|
|||||||
pthread_t unsoliced_thread;
|
pthread_t unsoliced_thread;
|
||||||
bool run;
|
bool run;
|
||||||
uint8_t rx_buffer[CC3000_RX_BUFFER_SIZE];
|
uint8_t rx_buffer[CC3000_RX_BUFFER_SIZE];
|
||||||
|
mqd_t queue;
|
||||||
|
|
||||||
} spiconf;
|
} spiconf;
|
||||||
|
|
||||||
@ -139,6 +144,27 @@ long SpiRead(uint8_t *pUserBuffer, uint16_t usLength)
|
|||||||
return read(spiconf.cc3000fd,pUserBuffer,usLength);
|
return read(spiconf.cc3000fd,pUserBuffer,usLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Name: SpiRead
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
uint8_t *SpiWait(void)
|
||||||
|
{
|
||||||
|
int nbytes;
|
||||||
|
DEBUGASSERT(spiconf.cc3000fd);
|
||||||
|
|
||||||
|
nbytes = mq_receive(spiconf.queue, spiconf.rx_buffer, CC3000_RX_BUFFER_SIZE, 0);
|
||||||
|
return spiconf.rx_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* Name: unsoliced_thread_func
|
* Name: unsoliced_thread_func
|
||||||
*
|
*
|
||||||
@ -162,19 +188,20 @@ static void *unsoliced_thread_func(void *parameter)
|
|||||||
|
|
||||||
ioctl(spiconf.cc3000fd, CC3000IOC_GETQUEID, (unsigned long)&minor);
|
ioctl(spiconf.cc3000fd, CC3000IOC_GETQUEID, (unsigned long)&minor);
|
||||||
snprintf(queuename, QUEUE_NAMELEN, QUEUE_FORMAT, minor);
|
snprintf(queuename, QUEUE_NAMELEN, QUEUE_FORMAT, minor);
|
||||||
mqd_t queue = mq_open(queuename,O_RDONLY);
|
spiconf.queue = mq_open(queuename,O_RDONLY);
|
||||||
|
|
||||||
while(spiconf.run)
|
while(spiconf.run)
|
||||||
{
|
{
|
||||||
memset(spiconf.rx_buffer,0,sizeof(spiconf.rx_buffer));
|
memset(spiconf.rx_buffer,0,sizeof(spiconf.rx_buffer));
|
||||||
nbytes = mq_receive(queue, spiconf.rx_buffer, CC3000_RX_BUFFER_SIZE, 0);
|
nbytes = mq_receive(spiconf.queue, spiconf.rx_buffer, CC3000_RX_BUFFER_SIZE, 0);
|
||||||
if (nbytes > 0)
|
if (nbytes > 0)
|
||||||
{
|
{
|
||||||
|
spivdbg("%d Processed\n",nbytes);
|
||||||
spiconf.pfRxHandler(spiconf.rx_buffer);
|
spiconf.pfRxHandler(spiconf.rx_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mq_close(queue);
|
mq_close(spiconf.queue);
|
||||||
pthread_exit((pthread_addr_t)status);
|
pthread_exit((pthread_addr_t)status);
|
||||||
return (pthread_addr_t)status;
|
return (pthread_addr_t)status;
|
||||||
}
|
}
|
||||||
@ -205,7 +232,12 @@ void SpiOpen(gcSpiHandleRx pfRxHandler)
|
|||||||
spiconf.cc3000fd = fd;
|
spiconf.cc3000fd = fd;
|
||||||
spiconf.run = true;
|
spiconf.run = true;
|
||||||
|
|
||||||
status = pthread_create(&spiconf.unsoliced_thread,NULL,
|
pthread_attr_t attr;
|
||||||
|
struct sched_param param;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
param.sched_priority = SCHED_PRIORITY_DEFAULT-10;
|
||||||
|
pthread_attr_setschedparam(&attr, ¶m);
|
||||||
|
status = pthread_create(&spiconf.unsoliced_thread, &attr,
|
||||||
unsoliced_thread_func, NULL);
|
unsoliced_thread_func, NULL);
|
||||||
DEBUGASSERT(status == 0)
|
DEBUGASSERT(status == 0)
|
||||||
}
|
}
|
||||||
@ -227,15 +259,15 @@ void SpiOpen(gcSpiHandleRx pfRxHandler)
|
|||||||
|
|
||||||
void SpiClose(void)
|
void SpiClose(void)
|
||||||
{
|
{
|
||||||
if (spiconf.cc3000fd)
|
if (spiconf.cc3000fd)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
spiconf.run = false;
|
spiconf.run = false;
|
||||||
|
|
||||||
pthread_cancel(spiconf.unsoliced_thread);
|
pthread_cancel(spiconf.unsoliced_thread);
|
||||||
pthread_join(spiconf.unsoliced_thread, (pthread_addr_t*)&status);
|
pthread_join(spiconf.unsoliced_thread, (pthread_addr_t*)&status);
|
||||||
|
|
||||||
close(spiconf.cc3000fd);
|
close(spiconf.cc3000fd);
|
||||||
spiconf.cc3000fd = 0;
|
spiconf.cc3000fd = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ typedef void (*gcSpiHandleRx)(void *p);
|
|||||||
void SpiOpen(gcSpiHandleRx pfRxHandler);
|
void SpiOpen(gcSpiHandleRx pfRxHandler);
|
||||||
void SpiClose(void);
|
void SpiClose(void);
|
||||||
long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength);
|
long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength);
|
||||||
|
uint8_t *SpiWait(void);
|
||||||
long SpiRead(uint8_t *pUserBuffer, uint16_t usLength);
|
long SpiRead(uint8_t *pUserBuffer, uint16_t usLength);
|
||||||
void SpiResumeSpi(void);
|
void SpiResumeSpi(void);
|
||||||
int CC3000InterruptHandler(int irq, void *context);
|
int CC3000InterruptHandler(int irq, void *context);
|
||||||
|
Loading…
Reference in New Issue
Block a user