Updated CC3000 driver from David Sidrane

This commit is contained in:
Gregory Nutt
2013-10-30 14:37:13 -06:00
parent 6b8c1cc480
commit 85e90b0064
10 changed files with 168 additions and 455 deletions
+2 -2
View File
@@ -37,8 +37,8 @@ ifeq ($(CONFIG_WL_CC3000),y)
# Include cc3000 drivers
CSRCS += cc3000.c cc3000_common.c evnt_handler.c hci.c netapp.c nvmem.c
CSRCS += security.c socket.c socket_imp.c spi.c wlan.c
CSRCS += cc3000.c cc3000_common.c cc3000drv.c evnt_handler.c hci.c netapp.c
CSRCS += nvmem.c security.c socket.c socket_imp.c wlan.c
# Include wireless devices build support
+116 -84
View File
@@ -85,10 +85,18 @@
#error "CONFIG_MQ_MAXMSGSIZE needs to be >= CC3000_RX_BUFFER_SIZE"
#endif
#ifndef CONFIG_CC3000_WORKER_THREAD_PRIORITY
# define CONFIG_CC3000_WORKER_THREAD_PRIORITY (SCHED_PRIORITY_MAX)
#endif
#ifndef CONFIG_CC3000_WORKER_STACKSIZE
# define CONFIG_CC3000_WORKER_STACKSIZE 240
#endif
#ifndef CONFIG_CC3000_SELECT_THREAD_PRIORITY
# define CONFIG_CC3000_SELECT_THREAD_PRIORITY (SCHED_PRIORITY_DEFAULT+10)
#endif
#ifndef CONFIG_CC3000_SELECT_STACKSIZE
# define CONFIG_CC3000_SELECT_STACKSIZE 368
#endif
@@ -101,9 +109,14 @@
#define FREE_SLOT -1
#if defined(CONFIG_CC3000_PROBES)
#define PROBE(pin,state) priv->config->probe(priv->config,pin, state)
# define CC3000_GUARD (0xc35aa53c)
# define INIT_GUARD(p) p->guard = CC3000_GUARD
# define CHECK_GUARD(p) DEBUGASSERT(p->guard == CC3000_GUARD)
# define PROBE(pin,state) priv->config->probe(priv->config,pin, state)
#else
#define PROBE(pin,state)
# define INIT_GUARD(p)
# define CHECK_GUARD(p)
# define PROBE(pin,state)
#endif
/****************************************************************************
@@ -129,13 +142,23 @@ static int cc3000_interrupt(int irq, FAR void *context);
static int cc3000_open(FAR struct file *filep);
static int cc3000_close(FAR struct file *filep);
static ssize_t cc3000_read(FAR struct file *filep, FAR char *buffer, size_t len);
static ssize_t cc3000_write(FAR struct file *filep, FAR const char *buffer, size_t len);
static ssize_t cc3000_read(FAR struct file *filep, FAR char *buffer,
size_t len);
static ssize_t cc3000_write(FAR struct file *filep,
FAR const char *buffer, size_t len);
static int cc3000_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
#ifndef CONFIG_DISABLE_POLL
static int cc3000_poll(FAR struct file *filep, struct pollfd *fds, bool setup);
static int cc3000_poll(FAR struct file *filep, struct pollfd *fds,
bool setup);
#endif
static int cc3000_wait_data(FAR struct cc3000_dev_s *priv, int sockfd);
static int cc3000_accept_socket(FAR struct cc3000_dev_s *priv, int sd,
FAR struct sockaddr *addr,
socklen_t *addrlen);
static int cc3000_add_socket(FAR struct cc3000_dev_s *priv, int sd);
static int cc3000_remove_socket(FAR struct cc3000_dev_s *priv, int sd);
/****************************************************************************
* Private Data
****************************************************************************/
@@ -474,13 +497,15 @@ static void * select_thread_func(FAR void *arg)
int s = 0;
memset(&timeout, 0, sizeof(struct timeval));
timeout.tv_sec = 0;
timeout.tv_usec = (500 * 1000); /* 500 msecs */
timeout.tv_sec = 0;
timeout.tv_usec = (100); /* .1 msecs */
while (1)
{
sem_wait(&priv->selectsem);
CHECK_GUARD(priv);
/* Increase the count back by one to be decreased by the original caller */
sem_post(&priv->selectsem);
@@ -521,28 +546,22 @@ static void * select_thread_func(FAR void *arg)
priv->sockets[s].sd != priv->accepting_socket.acc.sd && /* Verify this is not an accept socket */
CC3000_FD_ISSET(priv->sockets[s].sd, &readsds)) /* and has pending data */
{
sem_post(&priv->sockets[s].semwait); /* release the semaphore */
sem_post(&priv->sockets[s].semwait); /* release the waiting thread */
}
}
}
if (priv->accepting_socket.acc.sd != FREE_SLOT) /* if accept polling in needed */
if (priv->accepting_socket.acc.sd != FREE_SLOT) /* If accept polling in needed */
{
ret = cc3000_do_accept(priv->accepting_socket.acc.sd,
&priv->accepting_socket.addr,
ret = cc3000_do_accept(priv->accepting_socket.acc.sd, /* Send the select command on non blocking */
&priv->accepting_socket.addr, /* Set up in ioctl */
&priv->accepting_socket.addrlen);
if (ret != CC3000_SOC_IN_PROGRESS)
if (ret != CC3000_SOC_IN_PROGRESS) /* Not waiting => error or accepted */
{
priv->accepting_socket.acc.sd = FREE_SLOT;
priv->accepting_socket.acc.status = ret;
if (ret != CC3000_SOC_ERROR)
{
/* New Socket */
cc3000_add_socket(ret,priv->minor);
}
sem_post(&priv->accepting_socket.acc.semwait); /* release the semaphore */
sem_post(&priv->accepting_socket.acc.semwait); /* Release the waiting thread */
}
}
}
@@ -575,6 +594,7 @@ static void * cc3000_worker(FAR void *arg)
while(1)
{
PROBE(0,1);
CHECK_GUARD(priv);
cc3000_devtake(priv);
/* Done ? */
@@ -739,6 +759,8 @@ static int cc3000_open(FAR struct file *filep)
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct cc3000_dev_s *)inode->i_private;
CHECK_GUARD(priv);
nllvdbg("crefs: %d\n", priv->crefs);
/* Get exclusive access to the driver data structure */
@@ -796,7 +818,7 @@ static int cc3000_open(FAR struct file *filep)
pthread_attr_init(&tattr);
tattr.stacksize = CONFIG_CC3000_WORKER_STACKSIZE;
param.sched_priority = SCHED_PRIORITY_MAX;
param.sched_priority = CONFIG_CC3000_WORKER_THREAD_PRIORITY;
pthread_attr_setschedparam(&tattr, &param);
ret = pthread_create(&priv->workertid, &tattr, cc3000_worker,
@@ -811,7 +833,7 @@ static int cc3000_open(FAR struct file *filep)
pthread_attr_init(&tattr);
tattr.stacksize = CONFIG_CC3000_SELECT_STACKSIZE;
param.sched_priority = SCHED_PRIORITY_DEFAULT+10;
param.sched_priority = CONFIG_CC3000_SELECT_THREAD_PRIORITY;
pthread_attr_setschedparam(&tattr, &param);
ret = pthread_create(&priv->selecttid, &tattr, select_thread_func,
(pthread_addr_t)priv);
@@ -864,6 +886,8 @@ static int cc3000_close(FAR struct file *filep)
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct cc3000_dev_s *)inode->i_private;
CHECK_GUARD(priv);
nllvdbg("crefs: %d\n", priv->crefs);
/* Get exclusive access to the driver data structure */
@@ -927,6 +951,8 @@ static ssize_t cc3000_read(FAR struct file *filep, FAR char *buffer, size_t len)
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct cc3000_dev_s *)inode->i_private;
CHECK_GUARD(priv);
/* Verify that the caller has provided a buffer large enough to receive
* the maximum data.
*/
@@ -1075,6 +1101,8 @@ static ssize_t cc3000_write(FAR struct file *filep, FAR const char *buffer, size
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct cc3000_dev_s *)inode->i_private;
CHECK_GUARD(priv);
/* Get exclusive access to the driver data structure */
ret = cc3000_devtake(priv);
@@ -1188,6 +1216,8 @@ static int cc3000_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct cc3000_dev_s *)inode->i_private;
CHECK_GUARD(priv);
/* Get exclusive access to the driver data structure */
ret = cc3000_devtake(priv);
@@ -1205,9 +1235,41 @@ static int cc3000_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
case CC3000IOC_GETQUESEMID:
{
FAR int *pid = (FAR int *)(arg);
DEBUGASSERT(pid != NULL);
*pid = priv->minor;
FAR int *pminor = (FAR int *)(arg);
DEBUGASSERT(pminor != NULL);
*pminor = priv->minor;
break;
}
case CC3000IOC_ADDSOCKET:
{
FAR int *pfd = (FAR int *)(arg);
DEBUGASSERT(pfd != NULL);
*pfd = cc3000_add_socket(priv, *pfd);
break;
}
case CC3000IOC_REMOVESOCKET:
{
FAR int *pfd = (FAR int *)(arg);
DEBUGASSERT(pfd != NULL);
*pfd = cc3000_remove_socket(priv, *pfd);
break;
}
case CC3000IOC_SELECTDATA:
{
FAR int *pfd = (FAR int *)(arg);
DEBUGASSERT(pfd != NULL);
*pfd = cc3000_wait_data(priv, *pfd);
break;
}
case CC3000IOC_SELECTACCEPT:
{
FAR cc3000_acceptcfg *pcfg = (FAR cc3000_acceptcfg *)(arg);
DEBUGASSERT(pcfg != NULL);
pcfg->sockfd = cc3000_accept_socket(priv, pcfg->sockfd, pcfg->addr, pcfg->addrlen);
break;
}
@@ -1240,6 +1302,8 @@ static int cc3000_poll(FAR struct file *filep, FAR struct pollfd *fds,
DEBUGASSERT(inode && inode->i_private);
priv = (FAR struct cc3000_dev_s *)inode->i_private;
CHECK_GUARD(priv);
/* Are we setting up the poll? Or tearing it down? */
ret = cc3000_devtake(priv);
@@ -1371,7 +1435,7 @@ int cc3000_register(FAR struct spi_dev_s *spi,
/* Initialize the CC3000 device driver instance */
memset(priv, 0, sizeof(struct cc3000_dev_s));
INIT_GUARD(priv);
priv->minor = minor; /* Save the minor number */
priv->spi = spi; /* Save the SPI device handle */
priv->config = config; /* Save the board configuration */
@@ -1443,9 +1507,11 @@ errout_with_priv:
sem_destroy(&priv->readysem);
sem_close(priv->wrkwaitsem);
sem_unlink(semname);
#ifdef CONFIG_CC3000_MT
pthread_mutex_destroy(&g_cc3000_mut);
sem_destroy(&priv->accepting_socket.acc.semwait);
for (s = 0; s < CONFIG_WL_MAX_SOCKETS; s++)
{
sem_destroy(&priv->sockets[s].semwait);
@@ -1459,43 +1525,36 @@ errout_with_priv:
}
/****************************************************************************
* Name: cc3000_accept_socket
* Name: cc3000_wait_data
*
* Description:
* Adds this socket for monitoring for the accept operation
* Adds this socket for monitoring for the data available
*
* Input Parameters:
* sd cc3000 socket handle or -1 tp remove it
* minor - The input device minor number
* priv - The device cc3000_dev_s instance
* sockfd cc3000 socket handle
*
* Returned Value:
* Zero is returned on success. Otherwise, a -1 value is
* returned to indicate socket not found.
* returned to indicate socket not found or shut down occured.
*
****************************************************************************/
int cc3000_wait_data(int sockfd, int minor)
static int cc3000_wait_data(FAR struct cc3000_dev_s *priv, int sockfd)
{
FAR struct cc3000_dev_s *priv;
int s;
#ifndef CONFIG_CC3000_MULTIPLE
priv = &g_cc3000;
#else
for (priv = g_cc3000list;
priv && priv->minor != minor;
priv = priv->flink);
ASSERT(priv != NULL);
#endif
for (s = 0; s < CONFIG_WL_MAX_SOCKETS; s++)
{
if (priv->sockets[s].sd == sockfd)
{
sched_lock();
cc3000_devgive(priv);
sem_post(&priv->selectsem); /* Wake select thread if need be */
sem_wait(&priv->sockets[s].semwait); /* Wait caller on select to finish */
sem_wait(&priv->selectsem); /* Sleep select thread */
cc3000_devtake(priv);
sched_unlock();
break;
}
}
@@ -1510,40 +1569,35 @@ int cc3000_wait_data(int sockfd, int minor)
* Adds this socket for monitoring for the accept operation
*
* Input Parameters:
* sd cc3000 socket handle or -1 tp remove it
* minor - The input device minor number
* priv - The device cc3000_dev_s instance
* sockfd - cc3000 socket handle to monitor
*
* Returned Value:
* Zero is returned on success. Otherwise, a -1 value is
* returned to indicate socket not found.
* Zero is returned on success. Otherwise, a negative value is
* returned to indicate an error.
*
****************************************************************************/
int cc3000_accept_socket(int sd, int minor, struct sockaddr *addr,
static int cc3000_accept_socket(FAR struct cc3000_dev_s *priv, int sd, struct sockaddr *addr,
socklen_t *addrlen)
{
FAR struct cc3000_dev_s *priv;
#ifndef CONFIG_CC3000_MULTIPLE
priv = &g_cc3000;
#else
for (priv = g_cc3000list;
priv && priv->minor != minor;
priv = priv->flink);
ASSERT(priv != NULL);
#endif
priv->accepting_socket.acc.status = CC3000_SOC_ERROR;
priv->accepting_socket.acc.sd = sd;
sched_lock();
cc3000_devgive(priv);
sem_post(&priv->selectsem); /* Wake select thread if need be */
sem_wait(&priv->accepting_socket.acc.semwait); /* Wait caller on select to finish */
sem_wait(&priv->selectsem); /* Sleep select thread */
sem_wait(&priv->selectsem); /* Sleep the Thread */
cc3000_devtake(priv);
sched_unlock();
if (priv->accepting_socket.acc.status != CC3000_SOC_ERROR)
{
*addr = priv->accepting_socket.addr;
*addrlen = priv->accepting_socket.addrlen;
cc3000_add_socket(priv, priv->accepting_socket.acc.status);
}
return priv->accepting_socket.acc.status;
@@ -1565,9 +1619,8 @@ int cc3000_accept_socket(int sd, int minor, struct sockaddr *addr,
*
****************************************************************************/
int cc3000_add_socket(int sd, int minor)
static int cc3000_add_socket(FAR struct cc3000_dev_s *priv, int sd)
{
FAR struct cc3000_dev_s *priv;
irqstate_t flags;
int s;
@@ -1576,16 +1629,6 @@ int cc3000_add_socket(int sd, int minor)
return sd;
}
#ifndef CONFIG_CC3000_MULTIPLE
priv = &g_cc3000;
#else
for (priv = g_cc3000list;
priv && priv->minor != minor;
priv = priv->flink);
ASSERT(priv != NULL);
#endif
flags = irqsave();
for (s = 0; s < CONFIG_WL_MAX_SOCKETS; s++)
{
@@ -1616,9 +1659,8 @@ int cc3000_add_socket(int sd, int minor)
*
****************************************************************************/
int cc3000_remove_socket(int sd, int minor)
static int cc3000_remove_socket(FAR struct cc3000_dev_s *priv, int sd)
{
FAR struct cc3000_dev_s *priv;
irqstate_t flags;
int s;
@@ -1627,16 +1669,6 @@ int cc3000_remove_socket(int sd, int minor)
return sd;
}
#ifndef CONFIG_CC3000_MULTIPLE
priv = &g_cc3000;
#else
for (priv = g_cc3000list;
priv && priv->minor != minor;
priv = priv->flink);
ASSERT(priv != NULL);
#endif
flags = irqsave();
if (priv->accepting_socket.acc.sd == sd)
{
+5 -5
View File
@@ -58,7 +58,6 @@
#include <nuttx/wireless/wireless.h>
#include <nuttx/wireless/cc3000.h>
#include <nuttx/wireless/cc3000/cc3000_common.h>
#include "spi.h"
/****************************************************************************
* Pre-Processor Definitions
@@ -166,6 +165,11 @@ struct cc3000_dev_s
#ifndef CONFIG_DISABLE_POLL
struct pollfd *fds[CONFIG_CC3000_NPOLLWAITERS];
#endif
#if defined(CONFIG_DEBUG) && defined(CONFIG_CC3000_PROBES)
long guard;
#endif
};
/********************************************************************************************
@@ -196,10 +200,6 @@ static inline void cc3000_lib_unlock(void)
}
int cc3000_do_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int cc3000_wait_data(int sockfd, int minor);
int cc3000_accept_socket(int sd, int minor, struct sockaddr *addr, socklen_t *addrlen);
int cc3000_add_socket(int sd, int minor);
int cc3000_remove_socket(int sd, int minor);
#undef EXTERN
#ifdef __cplusplus
+6 -7
View File
@@ -48,10 +48,9 @@
#include <nuttx/wireless/cc3000/evnt_handler.h>
#include <nuttx/wireless/cc3000/wlan.h>
#include "cc3000_socket.h"
#include "cc3000drv.h"
#include <nuttx/wireless/cc3000/netapp.h>
#include "spi.h"
/*****************************************************************************
* Pre-processor Definitions
*****************************************************************************/
@@ -525,7 +524,7 @@ uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen)
tSLInformation.usEventOrDataReceived = 0;
SpiResumeSpi();
cc3000_resume();
/* Since we are going to TX - we need to handle this event after the
* ResumeSPi since we need interrupts
@@ -757,7 +756,7 @@ long hci_unsolicited_event_handler(void)
tSLInformation.usEventOrDataReceived = 0;
res = 1;
SpiResumeSpi();
cc3000_resume();
}
}
}
@@ -911,8 +910,8 @@ void SimpleLinkWaitEvent(uint16_t usOpcode, void *pRetParams)
do
{
nllvdbg("SpiWait\n");
tSLInformation.pucReceivedData = SpiWait();
nllvdbg("cc3000_wait\n");
tSLInformation.pucReceivedData = cc3000_wait();
tSLInformation.usEventOrDataReceived = 1;
STREAM_TO_UINT16((char *)tSLInformation.pucReceivedData, HCI_EVENT_OPCODE_OFFSET,event_type);
@@ -968,7 +967,7 @@ void SimpleLinkWaitData(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen)
do
{
tSLInformation.pucReceivedData = SpiWait();
tSLInformation.pucReceivedData = cc3000_wait();
tSLInformation.usEventOrDataReceived = 1;
if (*tSLInformation.pucReceivedData == HCI_TYPE_DATA)
+17 -11
View File
@@ -43,7 +43,7 @@
#include <nuttx/wireless/cc3000/cc3000_common.h>
#include <nuttx/wireless/cc3000/hci.h>
#include "spi.h"
#include "cc3000drv.h"
#include <nuttx/wireless/cc3000/evnt_handler.h>
#include <nuttx/wireless/cc3000/wlan.h>
@@ -72,7 +72,8 @@
*
*****************************************************************************/
uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, uint8_t ucArgsLength)
uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff,
uint8_t ucArgsLength)
{
uint8_t *stream;
@@ -85,7 +86,7 @@ uint16_t hci_command_send(uint16_t usOpcode, uint8_t *pucBuff, uint8_t ucArgsLen
/* Update the opcode of the event we will be waiting for */
SpiWrite(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE);
cc3000_write(pucBuff, ucArgsLength + SIMPLE_LINK_HCI_CMND_HEADER_SIZE);
nllvdbg("Send of 0x%x Completed\n",usOpcode);
return 0;
@@ -124,7 +125,9 @@ long hci_data_send(uint8_t ucOpcode, uint8_t *ucArgs, uint16_t usArgsLength,
/* Send the packet over the SPI */
SpiWrite(ucArgs, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength + usDataLength + usTailLength);
cc3000_write(ucArgs,
SIMPLE_LINK_HCI_DATA_HEADER_SIZE + usArgsLength +
usDataLength + usTailLength);
return ESUCCESS;
}
@@ -158,8 +161,9 @@ void hci_data_command_send(uint16_t usOpcode, uint8_t *pucBuff,
/* Send the command over SPI on data channel */
SpiWrite(pucBuff,
ucArgsLength + ucDataLength + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE);
cc3000_write(pucBuff,
ucArgsLength + ucDataLength +
SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE);
}
/******************************************************************************
@@ -188,17 +192,19 @@ void hci_patch_send(uint8_t ucOpcode, uint8_t *pucBuff, char *patch,
UINT8_TO_STREAM(stream, HCI_TYPE_PATCH);
UINT8_TO_STREAM(stream, ucOpcode);
stream = UINT16_TO_STREAM(stream, usDataLength + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE);
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);
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);
cc3000_write(pucBuff, usDataLength + HCI_PATCH_HEADER_SIZE);
}
else
{
@@ -214,7 +220,7 @@ void hci_patch_send(uint8_t ucOpcode, uint8_t *pucBuff, char *patch,
/* Update the opcode of the event we will be waiting for */
SpiWrite(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE);
cc3000_write(pucBuff, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE);
while (usDataLength)
{
@@ -236,7 +242,7 @@ void hci_patch_send(uint8_t ucOpcode, uint8_t *pucBuff, char *patch,
/* Update the opcode of the event we will be waiting for */
SpiWrite((uint8_t *)data_ptr, usTransLength + sizeof(usTransLength));
cc3000_write((uint8_t *)data_ptr, usTransLength + sizeof(usTransLength));
}
}
}
+6 -5
View File
@@ -50,6 +50,7 @@
#include <nuttx/wireless/cc3000/include/sys/socket.h>
#include "cc3000_socket.h"
#include "cc3000drv.h"
#include "cc3000.h"
/*****************************************************************************
@@ -162,7 +163,7 @@ int cc3000_socket(int domain, int type, int protocol)
type = bsd2ti_types[type];
sd = cc3000_socket_impl(domain,type,protocol);
#ifdef CONFIG_CC3000_MT
cc3000_add_socket(sd, 0);
cc3000_add_socket(sd);
#endif
cc3000_lib_unlock();
return sd;
@@ -188,7 +189,7 @@ int cc3000_closesocket(int sockfd)
cc3000_lib_lock();
ret = cc3000_closesocket_impl(sockfd);
#ifdef CONFIG_CC3000_MT
cc3000_remove_socket(sockfd, 0);
cc3000_remove_socket(sockfd);
#endif
cc3000_lib_unlock();
return ret;
@@ -260,7 +261,7 @@ int cc3000_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
}
memset(addr,0,*addrlen);
return cc3000_accept_socket(sockfd,0,addr,addrlen);
return cc3000_accept_socket(sockfd,addr,addrlen);
}
#else
{
@@ -586,7 +587,7 @@ ssize_t cc3000_recv(int sockfd, FAR void *buf, size_t len, int flags)
ssize_t ret = OK;
#ifdef CONFIG_CC3000_MT
ret = cc3000_wait_data(sockfd, 0);
ret = cc3000_wait_data(sockfd);
if (ret != OK )
{
return -1;
@@ -634,7 +635,7 @@ ssize_t cc3000_recvfrom(int sockfd, FAR void *buf, size_t len, int flags,
ssize_t ret = OK;
#ifdef CONFIG_CC3000_MT
ret = cc3000_wait_data(sockfd, 0);
ret = cc3000_wait_data(sockfd);
if (ret != OK )
{
return -1;
-285
View File
@@ -1,285 +0,0 @@
/**************************************************************************
* spi. - SPI functions to connect an Arduidno to the TI CC3000
*
* This code uses the Arduino hardware SPI library (or a bit-banged
* SPI for the Teensy 3.0) to send & receive data between the library
* API calls and the CC3000 hardware. Every
*
* Version 1.0.1b
*
* Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Don't sue me if my code blows up your board and burns down your house
*
****************************************************************************/
/*****************************************************************************
* Included Files
*****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdint.h>
#include <pthread.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <debug.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "spi.h"
#include <nuttx/wireless/cc3000.h>
#include <nuttx/wireless/cc3000/cc3000_common.h>
/*****************************************************************************
* Pre-processor Definitions
*****************************************************************************/
#ifndef CONFIG_CC3000_UNSOLICED_STACKSIZE
# define CONFIG_CC3000_UNSOLICED_STACKSIZE 264
#endif
#undef SPI_DEBUG /* Define to enable debug */
#undef SPI_VERBOSE /* Define to enable verbose debug */
#ifdef SPI_DEBUG
# define spidbg lldbg
# ifdef SPI_VERBOSE
# define spivdbg lldbg
# else
# define spivdbg(x...)
# endif
#else
# undef SPI_VERBOSE
# define spidbg(x...)
# define spivdbg(x...)
#endif
/*****************************************************************************
* Private Types
*****************************************************************************/
static struct
{
int cc3000fd;
gcSpiHandleRx pfRxHandler;
pthread_t unsoliced_thread;
bool run;
uint8_t rx_buffer[CC3000_RX_BUFFER_SIZE];
mqd_t queue;
sem_t *done;
} spiconf;
/*****************************************************************************
* Public Functions
*****************************************************************************/
/*****************************************************************************
* Name: SpiResumeSpi
*
* Description:
* Will re enable the SPI_IRQ'a ability to create interrupts. It is used to
* resume processing after the code passed to SpiOpen is Called
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
*****************************************************************************/
void SpiResumeSpi(void)
{
DEBUGASSERT(spiconf.cc3000fd && spiconf.done);
sem_post(spiconf.done);
nllvdbg("Done\n");
}
/*****************************************************************************
* Name: SpiWrite
*
* Description:
* This function enter point for write flow
*
* Input Parameters:
* pUserBuffer
* usLength
*
* Returned Value:
*
*****************************************************************************/
long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength)
{
DEBUGASSERT(spiconf.cc3000fd);
return write(spiconf.cc3000fd,pUserBuffer,usLength) == usLength ? 0 : -errno;
}
/*****************************************************************************
* Name: SpiRead
*
* Description:
* This function enter point for read flow. This function will block the
* caller untinlthere is data Available
*
* Input Parameters:
* pUserBuffer
* usLength
*
* Returned Value:
*
*****************************************************************************/
long SpiRead(uint8_t *pUserBuffer, uint16_t usLength)
{
DEBUGASSERT(spiconf.cc3000fd);
return read(spiconf.cc3000fd,pUserBuffer,usLength);
}
/*****************************************************************************
* Name: SpiRead
*
* Description:
*
* Input Parameters:
* None
*
* Returned Value:
*
*****************************************************************************/
uint8_t *SpiWait(void)
{
DEBUGASSERT(spiconf.cc3000fd);
mq_receive(spiconf.queue, spiconf.rx_buffer, CC3000_RX_BUFFER_SIZE, 0);
return spiconf.rx_buffer;
}
/*****************************************************************************
* Name: unsoliced_thread_func
*
* Description:
* This is the thread for unsolicited events. This function will block the
* caller untinlthere is data Available
*
* Input Parameters:
* parameter
*
* Returned Value:
*
*****************************************************************************/
static void *unsoliced_thread_func(void *parameter)
{
char buff[QUEUE_NAMELEN];
int status = 0;
int nbytes = 0;
int minor = 0;
ioctl(spiconf.cc3000fd, CC3000IOC_GETQUESEMID, (unsigned long)&minor);
snprintf(buff, QUEUE_NAMELEN, QUEUE_FORMAT, minor);
spiconf.queue = mq_open(buff,O_RDONLY);
DEBUGASSERT(spiconf.queue != (mqd_t) -1);
DEBUGASSERT(SEM_NAMELEN == QUEUE_NAMELEN);
snprintf(buff, SEM_NAMELEN, SEM_FORMAT, minor);
spiconf.done = sem_open(buff,O_RDONLY);
DEBUGASSERT(spiconf.done != (sem_t *)-1);
while(spiconf.run)
{
memset(spiconf.rx_buffer,0,sizeof(spiconf.rx_buffer));
nbytes = mq_receive(spiconf.queue, spiconf.rx_buffer,
CC3000_RX_BUFFER_SIZE, 0);
if (nbytes > 0)
{
nlldbg("%d Processed\n",nbytes);
spiconf.pfRxHandler(spiconf.rx_buffer);
}
}
mq_close(spiconf.queue);
sem_close(spiconf.done);
pthread_exit((pthread_addr_t)status);
return (pthread_addr_t)status;
}
/*****************************************************************************
* Name: SpiOpen
*
* Description:
* Configure the SPI
*
* Input Parameters:
* pfRxHandler the Rx handler for SPI
*
* Returned Value:
* None
*
*****************************************************************************/
void SpiOpen(gcSpiHandleRx pfRxHandler)
{
int status;
int fd;
DEBUGASSERT(spiconf.cc3000fd == 0);
fd = open("/dev/wireless0",O_RDWR|O_BINARY);
if (fd > 0)
{
spiconf.pfRxHandler = pfRxHandler;
spiconf.cc3000fd = fd;
spiconf.run = true;
pthread_attr_t attr;
struct sched_param param;
pthread_attr_init(&attr);
attr.stacksize = CONFIG_CC3000_UNSOLICED_STACKSIZE;
param.sched_priority = SCHED_PRIORITY_DEFAULT-10;
pthread_attr_setschedparam(&attr, &param);
status = pthread_create(&spiconf.unsoliced_thread, &attr,
unsoliced_thread_func, NULL);
DEBUGASSERT(status == 0)
}
DEBUGASSERT(spiconf.cc3000fd);
}
/*****************************************************************************
* Name: SpiClose
*
* Description:
* Configure the SPI
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
*****************************************************************************/
void SpiClose(void)
{
if (spiconf.cc3000fd)
{
int status;
spiconf.run = false;
pthread_cancel(spiconf.unsoliced_thread);
pthread_join(spiconf.unsoliced_thread, (pthread_addr_t*)&status);
close(spiconf.cc3000fd);
spiconf.cc3000fd = 0;
}
}
-52
View File
@@ -1,52 +0,0 @@
/**************************************************************************
* ArduinoCC3000SPI.h - SPI functions to connect an Arduidno to the TI
* CC3000
*
* This code uses the Arduino hardware SPI library (or a bit-banged
* SPI for the Teensy 3.0) to send & receive data between the library
* API calls and the CC3000 hardware. Every
*
* Version 1.0.1b
*
* Copyright (C) 2013 Chris Magagna - cmagagna@yahoo.com
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Don't sue me if my code blows up your board and burns down your house
*
****************************************************************************/
#ifndef __DRIVERS_WIRELESS_CC3000_SPI_H
#define __DRIVERS_WIRELESS_CC3000_SPI_H
/*****************************************************************************
* Included Files
*****************************************************************************/
#include <stdint.h>
/*****************************************************************************
* Public Types
*****************************************************************************/
typedef void (*gcSpiHandleRx)(void *p);
/*****************************************************************************
* Public Data
*****************************************************************************/
/*****************************************************************************
* Public Function Prototypes
*****************************************************************************/
void SpiOpen(gcSpiHandleRx pfRxHandler);
void SpiClose(void);
long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength);
uint8_t *SpiWait(void);
long SpiRead(uint8_t *pUserBuffer, uint16_t usLength);
void SpiResumeSpi(void);
int CC3000InterruptHandler(int irq, void *context);
#endif /* __DRIVERS_WIRELESS_CC3000_SPI_H */
+3 -3
View File
@@ -50,8 +50,8 @@
#include <nuttx/wireless/cc3000/security.h>
#include <nuttx/wireless/cc3000/evnt_handler.h>
#include "spi.h"
#include "cc3000.h"
#include "cc3000drv.h"
/*****************************************************************************
* Preprocessor Definitions
@@ -282,7 +282,7 @@ void wlan_start(uint16_t usPatchesAvailableAtHost)
/* Init spi */
SpiOpen(SpiReceiveHandler);
cc3000_open(SpiReceiveHandler);
SimpleLink_Init_Start(usPatchesAvailableAtHost);
@@ -310,7 +310,7 @@ void wlan_start(uint16_t usPatchesAvailableAtHost)
void wlan_stop(void)
{
cc3000_lib_lock();
SpiClose();
cc3000_close();
cc3000_lib_unlock();
}
+13 -1
View File
@@ -66,7 +66,11 @@
/* IOCTL commands */
#define CC3000IOC_GETQUESEMID _WLIOC_USER(0x0001) /* arg: Address of int for number*/
#define CC3000IOC_GETQUESEMID _WLIOC_USER(0x0001) /* arg: Address of int for number*/
#define CC3000IOC_ADDSOCKET _WLIOC_USER(0x0002) /* arg: Address of int for result*/
#define CC3000IOC_REMOVESOCKET _WLIOC_USER(0x0003) /* arg: Address of int for result*/
#define CC3000IOC_SELECTDATA _WLIOC_USER(0x0004) /* arg: Address of int for result*/
#define CC3000IOC_SELECTACCEPT _WLIOC_USER(0x0005) /* arg: Address of struct cc3000_acceptcfg_s */
/****************************************************************************
* Public Types
@@ -77,6 +81,14 @@ typedef char *(*tDriverPatches)(unsigned long *usLength);
typedef char *(*tBootLoaderPatches)(unsigned long *usLength);
typedef void (*tWlanCB)(long event_type, char * data, unsigned char length);
typedef struct cc3000_acceptcfg_s
{
int sockfd;
struct sockaddr *addr;
socklen_t *addrlen;
} cc3000_acceptcfg;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/