mirror of
https://github.com/apache/nuttx.git
synced 2026-05-18 08:43:28 +08:00
Updated CC3000 driver from David Sidrane
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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, ¶m);
|
||||
|
||||
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, ¶m);
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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, ¶m);
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
****************************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user