From ec6d95c60178b90a1386f70937347f5798ea5b6a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 16 Oct 2013 11:59:22 -0600 Subject: CC3000 driver changes from David Sidrane --- nuttx/drivers/wireless/cc3000/cc3000.c | 1142 ++++++++++++++++++++ nuttx/drivers/wireless/cc3000/cc3000.h | 149 +++ nuttx/drivers/wireless/cc3000/spi.h | 45 + nuttx/include/nuttx/wireless/cc3000.h | 160 +++ .../nuttx/wireless/cc3000/include/cc3000_upif.h | 193 ++++ .../nuttx/wireless/cc3000/include/sys/socket.h | 662 ++++++++++++ nuttx/include/nuttx/wireless/cc3000/spi.h | 45 - 7 files changed, 2351 insertions(+), 45 deletions(-) create mode 100644 nuttx/drivers/wireless/cc3000/cc3000.c create mode 100644 nuttx/drivers/wireless/cc3000/cc3000.h create mode 100644 nuttx/drivers/wireless/cc3000/spi.h create mode 100644 nuttx/include/nuttx/wireless/cc3000.h create mode 100644 nuttx/include/nuttx/wireless/cc3000/include/cc3000_upif.h create mode 100644 nuttx/include/nuttx/wireless/cc3000/include/sys/socket.h delete mode 100644 nuttx/include/nuttx/wireless/cc3000/spi.h diff --git a/nuttx/drivers/wireless/cc3000/cc3000.c b/nuttx/drivers/wireless/cc3000/cc3000.c new file mode 100644 index 000000000..21ef594b7 --- /dev/null +++ b/nuttx/drivers/wireless/cc3000/cc3000.c @@ -0,0 +1,1142 @@ +/**************************************************************************** + * drivers/wireless/cc3000.c + * + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David_s5 + * + * References: + * CC30000 from Texas Instruments http://processors.wiki.ti.com/index.php/CC3000 + * + * See also: + * http://processors.wiki.ti.com/index.php/CC3000_Host_Driver_Porting_Guide + * http://processors.wiki.ti.com/index.php/CC3000_Host_Programming_Guide + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include // For Lowevel SPI config +#include +#include +#include "cc3000.h" + + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* Low-level SPI helpers */ + + +#ifdef CONFIG_SPI_OWNBUS +# define cc3000_lock(spi) +# define cc3000_unlock(spi) +#else +static void cc3000_lock(FAR struct spi_dev_s *spi); +static void cc3000_unlock(FAR struct spi_dev_s *spi); +#endif + + +/* Interrupts and data sampling */ + +static void cc3000_notify(FAR struct cc3000_dev_s *priv); +static void cc3000_worker(FAR void *arg); +static int cc3000_interrupt(int irq, FAR void *context); + +/* Character driver methods */ + +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 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); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This the vtable that supports the character driver interface */ + +static const struct file_operations cc3000_fops = +{ + cc3000_open, /* open */ + cc3000_close, /* close */ + cc3000_read, /* read */ + cc3000_write, /* write */ + 0, /* seek */ + cc3000_ioctl, /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + cc3000_poll /* poll */ +#endif +}; + +/* If only a single CC3000 device is supported, then the driver state + * structure may as well be pre-allocated. + */ + +#ifndef CONFIG_CC3000_MULTIPLE +static struct cc3000_dev_s g_cc3000; + +/* Otherwise, we will need to maintain allocated driver instances in a list */ + +#else +static struct cc3000_dev_s *g_cc3000list; +#endif + +uint8_t spi_readCommand[] = READ_COMMAND; + + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Function: cc3000_configspi + * + * Description: + * Configure the SPI for use with the CC3000. This function should be + * called to configure the SPI + * bus. + * + * Parameters: + * spi - Reference to the SPI driver structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ +static inline void cc3000_configspi(FAR struct spi_dev_s *spi) +{ + idbg("Mode: %d Bits: 8 Frequency: %d\n",CONFIG_CC3000_SPIMODE, CONFIG_CC3000_FREQUENCY); + SPI_SELECT(spi, SPIDEV_WIRELESS, true); + SPI_SETMODE(spi, CONFIG_CC3000_SPIMODE); + SPI_SETBITS(spi, 8); + SPI_SETFREQUENCY(spi, CONFIG_CC3000_SPI_FREQUENCY); + SPI_SELECT(spi, SPIDEV_WIRELESS, false); + +} + + +/**************************************************************************** + * Function: cc3000_lock + * + * Description: + * Lock the SPI bus and re-configure as necessary. This function must be + * to assure: (1) exclusive access to the SPI bus, and (2) to assure that + * the shared bus is properly configured for the cc3000 module. + * + * Parameters: + * spi - Reference to the SPI driver structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_OWNBUS +static void cc3000_lock(FAR struct spi_dev_s *spi) +{ + /* Lock the SPI bus because there are multiple devices competing for the + * SPI bus + */ + + /* Lock the SPI bus so that we have exclusive access */ + (void)SPI_LOCK(spi, true); + + /* We have the lock. Now make sure that the SPI bus is configured for the + * CC3000 (it might have gotten configured for a different device while + * unlocked) + */ + cc3000_configspi(spi); +} +#endif + +/**************************************************************************** + * Function: cc3000_unlock + * + * Description: + * If we are sharing the SPI bus with other devices (CONFIG_SPI_OWNBUS + * undefined) then we need to un-lock the SPI bus for each transfer, + * possibly losing the current configuration. + * + * Parameters: + * spi - Reference to the SPI driver structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +#ifndef CONFIG_SPI_OWNBUS +static void cc3000_unlock(FAR struct spi_dev_s *spi) +{ + /* Relinquish the SPI bus. */ + + (void)SPI_LOCK(spi, false); +} +#endif + +/**************************************************************************** + * Function: cc3000_wait_irq + * + * Description: + * Helper function to wait on the readysem signaled by the interrupt + * + * Parameters: + * priv - Reference to the CC3000 driver structure + * + * Returned Value: + * 0 - Semaphore signaled and devsem retaken + * < 0 - Some Error occurred + * Assumptions: + * Own the devsem on entry + * + ****************************************************************************/ +static int cc3000_wait_irq(FAR struct cc3000_dev_s *priv) +{ + int ret; + + // Give up + sched_lock(); + sem_post(&priv->devsem); + + // Wait on first IRQ t come after Power Up + ret = sem_wait(&priv->readysem); + sched_unlock(); + + if (ret >= 0) + { + /* Yes... then retake the mutual exclusion semaphore */ + + ret = sem_wait(&priv->devsem); + } + +/* Was the semaphore wait successful? Did we successful re-take the + * mutual exclusion semaphore? + */ + + if (ret < 0) + { + /* No.. One of the two sem_wait's failed. */ + ret = -errno; + } + return ret; +} + +/**************************************************************************** + * Name: cc3000_notify + ****************************************************************************/ + +static void cc3000_notify(FAR struct cc3000_dev_s *priv) +{ +#ifndef CONFIG_DISABLE_POLL + int i; +#endif + + /* If there are threads waiting for read data, then signal one of them + * that the read data is available. + */ + + if (priv->nwaiters > 0) + { + /* After posting this semaphore, we need to exit because the CC3000 + * is no longer available. + */ + + sem_post(&priv->waitsem); + } + + /* If there are threads waiting on poll() for CC3000 data to become available, + * then wake them up now. NOTE: we wake up all waiting threads because we + * do not know that they are going to do. If they all try to read the data, + * then some make end up blocking after all. + */ + +#ifndef CONFIG_DISABLE_POLL + for (i = 0; i < CONFIG_CC3000_NPOLLWAITERS; i++) + { + struct pollfd *fds = priv->fds[i]; + if (fds) + { + fds->revents |= POLLIN; + ivdbg("Report events: %02x\n", fds->revents); + sem_post(fds->sem); + } + } +#endif +} + + +/**************************************************************************** + * Name: cc3000_schedule + ****************************************************************************/ + +static int cc3000_schedule(FAR struct cc3000_dev_s *priv) +{ + FAR struct cc3000_config_s *config; + int ret; + + /* Get a pointer the callbacks for convenience (and so the code is not so + * ugly). + */ + + config = priv->config; + DEBUGASSERT(config != NULL); + + DEBUGASSERT(priv->work.worker == NULL); + ret = work_queue(HPWORK, &priv->work, cc3000_worker, priv, 0); + if (ret != 0) + { + illdbg("Failed to queue work: %d\n", ret); + } + + return OK; +} + + +/**************************************************************************** + * Name: cc3000_worker + ****************************************************************************/ + +static void cc3000_worker(FAR void *arg) +{ + FAR struct cc3000_dev_s *priv = (FAR struct cc3000_dev_s *)arg; + FAR struct cc3000_config_s *config; + int ret; + + ASSERT(priv != NULL); + + /* Get a pointer the callbacks for convenience (and so the code is not so + * ugly). + */ + + config = priv->config; + DEBUGASSERT(config != NULL); + + /* Get exclusive access to the driver data structure */ + + do + { + ret = sem_wait(&priv->devsem); + + /* This should only fail if the wait was canceled by an signal + * (and the worker thread will receive a lot of signals). + */ + + DEBUGASSERT(ret == OK || errno == EINTR); + } + while (ret < 0); + + switch (priv->state) { + + case eSPI_STATE_POWERUP: + // Signal the device has interrupted after power up + priv->state = eSPI_STATE_INITIALIZED; + sem_post(&priv->readysem); + break; + + case eSPI_STATE_WRITE_WAIT_IRQ: + // Signal the device has interrupted after Chip Select During a write operation + priv->state = eSPI_STATE_WRITE_PROCEED; + sem_post(&priv->readysem); + break; + + + case eSPI_STATE_WRITE_DONE: // IRQ post a write => Solicited + case eSPI_STATE_IDLE: // IRQ when Idel => cc3000 has data for the hosts Unsolicited + { + uint16_t data_to_recv; + priv->state = eSPI_STATE_READ_IRQ; + // Issue the read command + cc3000_lock(priv->spi); // Assert CS + priv->state = eSPI_STATE_READ_PROCEED; + SPI_EXCHANGE(priv->spi,spi_readCommand,priv->rx_buffer, ARRAY_SIZE(spi_readCommand)); + // Extract Length bytes from Rx Buffer + STREAM_TO_UINT16((char*)priv->rx_buffer, READ_OFFSET_TO_LENGTH, data_to_recv); + // We will read ARRAY_SIZE(spi_readCommand) + data_to_recv. is it odd? + if ((data_to_recv + ARRAY_SIZE(spi_readCommand)) & 1) { + // odd so make it even + data_to_recv++; + } + // Read the whole payload in at the beginning of the buffer + if (data_to_recv) { + // Will it fit? + DEBUGASSERT(data_to_recv < ARRAY_SIZE(priv->rx_buffer)); + SPI_RECVBLOCK(priv->spi, priv->rx_buffer, data_to_recv); + } + cc3000_unlock(priv->spi); // De assert CS + // Disable IrQ as the wl code will resume via CC3000IOC_COMPLETE + priv->config->irq_enable(priv->config,false); + priv->state = eSPI_STATE_READ_READY; + priv->rx_buffer_len = data_to_recv; + + ret = mq_send(priv->queue, priv->rx_buffer, data_to_recv, 1); + DEBUGASSERT(ret>=0); + + } + break; + default: + PANIC(); + break; + } + + /* Notify any waiters that new CC3000 data is available */ + + cc3000_notify(priv); + + sem_post(&priv->devsem); +} + +/**************************************************************************** + * Name: cc3000_interrupt + ****************************************************************************/ + +static int cc3000_interrupt(int irq, FAR void *context) +{ + FAR struct cc3000_dev_s *priv; + int ret; + + /* Which CC3000 device caused the interrupt? */ + +#ifndef CONFIG_CC3000_MULTIPLE + priv = &g_cc3000; +#else + for (priv = g_cc3000list; + priv && priv->configs->irq != irq; + priv = priv->flink); + + ASSERT(priv != NULL); +#endif + + /* Schedule sampling to occur on the worker thread */ + ret = cc3000_schedule(priv); + + /* Clear any pending interrupts and return success */ + + priv->config->irq_clear(priv->config); + return ret; +} + +/**************************************************************************** + * Name: cc3000_open + ****************************************************************************/ + +static int cc3000_open(FAR struct file *filep) +{ + FAR struct inode *inode; + struct mq_attr attr; + char queuename[QUEUE_NAMELEN]; + FAR struct cc3000_dev_s *priv; + uint8_t tmp; + int ret; + + ivdbg("Opening\n"); + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct cc3000_dev_s *)inode->i_private; + + /* Get exclusive access to the driver data structure */ + + ret = sem_wait(&priv->devsem); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + DEBUGASSERT(errno == EINTR); + return -EINTR; + } + + /* Increment the reference count */ + + tmp = priv->crefs + 1; + if (tmp == 0) + { + /* More than 255 opens; uint8_t overflows to zero */ + + ret = -EMFILE; + goto errout_with_sem; + } + + /* When the reference increments to 1, this is the first open event + * on the driver.. and an opportunity to do any one-time initialization. + */ + + + if (tmp==1) { + + attr.mq_maxmsg = 2; + attr.mq_msgsize = CC3000_RX_BUFFER_SIZE; + attr.mq_flags = 0; + + /* Set the flags for the open of the queue. + * Make it a blocking open on the queue, meaning it will block if + * this process tries to send to the queue and the queue is full. + * + * O_CREAT - the queue will get created if it does not already exist. + * O_WRONLY - we are only planning to write to the queue. + * + * Open the queue, and create it if the receiving process hasn't + * already created it. + */ + snprintf(queuename, QUEUE_NAMELEN, QUEUE_FORMAT, priv->minor); + priv->queue = mq_open(queuename,O_WRONLY|O_CREAT, 0666, &attr); + if (priv->queue < 0) + { + priv->crefs--; + ret = -errno; + goto errout_with_sem; + } + + priv->config->irq_clear(priv->config); + priv->config->irq_enable(priv->config, true); + priv->config->power_enable(priv->config, true); + // Bring the device Online A) on http://processors.wiki.ti.com/index.php/File:CC3000_Master_SPI_Write_Sequence_After_Power_Up.png + } + /* Save the new open count on success */ + + priv->crefs = tmp; + +errout_with_sem: + sem_post(&priv->devsem); + return ret; +} + +/**************************************************************************** + * Name: cc3000_close + ****************************************************************************/ + +static int cc3000_close(FAR struct file *filep) +{ + FAR struct inode *inode; + FAR struct cc3000_dev_s *priv; + int ret; + + ivdbg("Closing\n"); + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct cc3000_dev_s *)inode->i_private; + + /* Get exclusive access to the driver data structure */ + + ret = sem_wait(&priv->devsem); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + DEBUGASSERT(errno == EINTR); + return -EINTR; + } + + /* Decrement the reference count unless it would decrement a negative + * value. When the count decrements to zero, there are no further + * open references to the driver. + */ + + int tmp = priv->crefs; + if (priv->crefs >= 1) + { + priv->crefs--; + } + + if (tmp == 0) + { + priv->config->irq_enable(priv->config, false); + priv->config->irq_clear(priv->config); + priv->config->power_enable(priv->config, false); + mq_close(priv->queue); + priv->queue = 0; + } + + sem_post(&priv->devsem); + return OK; + +} + +/**************************************************************************** + * Name: cc3000_read + ****************************************************************************/ +static ssize_t cc3000_read(FAR struct file *filep, FAR char *buffer, size_t len) +{ + FAR struct inode *inode; + FAR struct cc3000_dev_s *priv; + int ret; + ssize_t nread; + + ivdbg("buffer:%p len:%d\n", buffer, len); + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct cc3000_dev_s *)inode->i_private; + + /* Verify that the caller has provided a buffer large enough to receive + * the maximum data. + */ + + if (len < CC3000_RX_BUFFER_SIZE) + { + idbg("Unsupported read size: %d\n", len); + nread = -ENOSYS; + goto errout_without_sem; + + } + + /* Get exclusive access to the driver data structure */ + + ret = sem_wait(&priv->devsem); + + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + idbg("sem_wait: %d\n", errno); + DEBUGASSERT(errno == EINTR); + nread = -EINTR; + goto errout_without_sem; + } + + for (nread = priv->rx_buffer_len; nread == 0; nread = priv->rx_buffer_len) + { + + if (nread > 0) { + // Yes.. break out to return what we have. + break; + } + + /* data is not available now. We would have to wait to get + * receive sample data. If the user has specified the O_NONBLOCK + * option, then just return an error. + */ + + ivdbg("CC3000 data is not available\n"); + if (filep->f_oflags & O_NONBLOCK) + { + nread = -EAGAIN; + break; + } + + /* Otherwise, wait for something to be written to the + * buffer. Increment the number of waiters so that the notify + * will know that it needs to post the semaphore to wake us up. + */ + + sched_lock(); + priv->nwaiters++; + sem_post(&priv->devsem); + + /* We may now be pre-empted! But that should be okay because we + * have already incremented nwaiters. Pre-emptions is disabled + * but will be re-enabled while we are waiting. + */ + + ivdbg("Waiting..\n"); + ret = sem_wait(&priv->waitsem); + priv->nwaiters--; + sched_unlock(); + + + /* Did we successfully get the waitsem? */ + + if (ret >= 0) + { + /* Yes... then retake the mutual exclusion semaphore */ + + ret = sem_wait(&priv->devsem); + } + + /* Was the semaphore wait successful? Did we successful re-take the + * mutual exclusion semaphore? + */ + + if (ret < 0) + { + /* No.. One of the two sem_wait's failed. */ + + int errval = errno; + + /* Were we awakened by a signal? Did we read anything before + * we received the signal? + */ + + if (errval != EINTR || nread >= 0) + { + /* Yes.. return the error. */ + + nread = -errval; + } + + /* Break out to return what we have. Note, we can't exactly + * "break" out because whichever error occurred, we do not hold + * the exclusion semaphore. + */ + + goto errout_without_sem; + } + } + + sem_post(&priv->devsem); + +errout_without_sem: + ivdbg("Returning: %d\n", nread); +#ifndef CONFIG_DISABLE_POLL + if (nread > 0) + { + cc3000_pollnotify(priv, POLLOUT); + } +#endif + + return nread; +} + +/**************************************************************************** + * Name:cc3000_write + * + * Bit of non standard buffer management ahead + * The buffer is memory allocated in the user space with space for the spi header + ****************************************************************************/ +static ssize_t cc3000_write(FAR struct file *filep, FAR const char *buffer, size_t len) +{ + FAR struct inode *inode; + FAR struct cc3000_dev_s *priv; + int ret; + ssize_t nwritten = 0; + // Set the padding if count(buffer) is even ( as it will be come odd with header) + size_t tx_len = (len & 1) ? len : len +1; + + ivdbg("buffer:%p len:%d tx_len:%d\n", buffer, len, tx_len ); + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct cc3000_dev_s *)inode->i_private; + + /* Get exclusive access to the driver data structure */ + + ret = sem_wait(&priv->devsem); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + idbg("sem_wait: %d\n", errno); + DEBUGASSERT(errno == EINTR); + nwritten = -EINTR; + goto errout_without_sem; + } + + + // + // Figure out the total length of the packet in order to figure out if there is padding or not + // + memcpy(priv->tx_buffer,buffer,tx_len); + priv->tx_buffer[0] = WRITE; + priv->tx_buffer[1] = HI(tx_len); + priv->tx_buffer[2] = LO(tx_len); + priv->tx_buffer[3] = 0; + priv->tx_buffer[4] = 0; + + tx_len += SPI_HEADER_SIZE; + + /* The first write transaction to occur after release of the shutdown has slightly different timing than the others. + * The normal Master SPI write sequence is nCS low, followed by IRQ low (CC3000 host), indicating that + * the CC3000 core device is ready to accept data. However, after power up the sequence is slightly different, + * as shown in the following Figure: http://processors.wiki.ti.com/index.php/File:CC3000_Master_SPI_Write_Sequence_After_Power_Up.png + * The following is a sequence of operations: + * The master detects the IRQ line low: in this case the detection of + * IRQ low does not indicate the intention of the CC3000 device to communicate with the + * master but rather CC3000 readiness after power up. + * The master asserts nCS. + * The master introduces a delay of at least 50 μs before starting actual transmission of data. + * The master transmits the first 4 bytes of the SPI header. + * The master introduces a delay of at least an additional 50 μs. + * The master transmits the rest of the packet. + */ + if (priv->state == eSPI_STATE_POWERUP) + { + ret = cc3000_wait_irq(priv); + if (ret < 0) { + nwritten = ret; + goto errout_without_sem; + } + } + + if (priv->state == eSPI_STATE_INITIALIZED) + { + + cc3000_lock(priv->spi); // Assert CS + usleep(50); + SPI_SNDBLOCK(priv->spi, buffer, 4); + usleep(50); + SPI_SNDBLOCK(priv->spi, buffer+4, tx_len-4); + } + else + { + priv->state = eSPI_STATE_WRITE_WAIT_IRQ; + cc3000_lock(priv->spi); // Assert CS + // Wait on IRQ + ret = cc3000_wait_irq(priv); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + cc3000_unlock(priv->spi); + idbg("sem_wait: %d\n", errno); + DEBUGASSERT(errno == EINTR); + nwritten = ret; + goto errout_without_sem; + } + SPI_SNDBLOCK(priv->spi, buffer, tx_len); + } + priv->state = eSPI_STATE_WRITE_DONE; + cc3000_unlock(priv->spi); + nwritten = tx_len; + sem_post(&priv->devsem); + +errout_without_sem: + ivdbg("Returning: %d\n", ret); + return nwritten; +} + +/**************************************************************************** + * Name:cc3000_ioctl + ****************************************************************************/ + +static int cc3000_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode; + FAR struct cc3000_dev_s *priv; + int ret; + + ivdbg("cmd: %d arg: %ld\n", cmd, arg); + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct cc3000_dev_s *)inode->i_private; + + /* Get exclusive access to the driver data structure */ + + ret = sem_wait(&priv->devsem); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + DEBUGASSERT(errno == EINTR); + return -EINTR; + } + + /* Process the IOCTL by command */ + switch (cmd) + { + case CC3000IOC_COMPLETE: /* arg: Pointer to uint32_t frequency value */ + { + DEBUGASSERT(priv->config); + priv->state = eSPI_STATE_IDLE; + priv->config->irq_enable(priv->config,true); + } + break; + + case CC3000IOC_GETQUEID: + { + FAR int *pid = (FAR int *)(arg); + DEBUGASSERT(pid != NULL); + *pid = priv->minor; + break; + } + + + default: + ret = -ENOTTY; + break; + } + sem_post(&priv->devsem); + return ret; +} + +/**************************************************************************** + * Name: cc3000_poll + ****************************************************************************/ + +#ifndef CONFIG_DISABLE_POLL +static int cc3000_poll(FAR struct file *filep, FAR struct pollfd *fds, + bool setup) +{ + FAR struct inode *inode; + FAR struct cc3000_dev_s *priv; + int ret = OK; + int i; + + ivdbg("setup: %d\n", (int)setup); + DEBUGASSERT(filep && fds); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct cc3000_dev_s *)inode->i_private; + + /* Are we setting up the poll? Or tearing it down? */ + + ret = sem_wait(&priv->devsem); + if (ret < 0) + { + /* This should only happen if the wait was canceled by an signal */ + + DEBUGASSERT(errno == EINTR); + return -EINTR; + } + + if (setup) + { + /* Ignore waits that do not include POLLIN */ + + if ((fds->events & POLLIN) == 0) + { + ret = -EDEADLK; + goto errout; + } + + /* This is a request to set up the poll. Find an available + * slot for the poll structure reference + */ + + for (i = 0; i < CONFIG_CC3000_NPOLLWAITERS; i++) + { + /* Find an available slot */ + + if (!priv->fds[i]) + { + /* Bind the poll structure and this slot */ + + priv->fds[i] = fds; + fds->priv = &priv->fds[i]; + break; + } + } + + if (i >= CONFIG_CC3000_NPOLLWAITERS) + { + fds->priv = NULL; + ret = -EBUSY; + goto errout; + } + + /* Should we immediately notify on any of the requested events? */ + + if (priv->penchange) + { + cc3000_notify(priv); + } + } + else if (fds->priv) + { + /* This is a request to tear down the poll. */ + + struct pollfd **slot = (struct pollfd **)fds->priv; + DEBUGASSERT(slot != NULL); + + /* Remove all memory of the poll setup */ + + *slot = NULL; + fds->priv = NULL; + } + +errout: + sem_post(&priv->devsem); + return ret; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: cc3000_register + * + * Description: + * Configure the CC3000 to use the provided SPI device instance. This + * will register the driver as /dev/inputN where N is the minor device + * number + * + * Input Parameters: + * dev - An SPI driver instance + * config - Persistent board configuration data + * minor - The input device minor number + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int cc3000_register(FAR struct spi_dev_s *spi, + FAR struct cc3000_config_s *config, int minor) +{ + FAR struct cc3000_dev_s *priv; + char devname[DEV_NAMELEN]; + +#ifdef CONFIG_CC3000_MULTIPLE + irqstate_t flags; +#endif + int ret; + + ivdbg("spi: %p minor: %d\n", spi, minor); + + /* Debug-only sanity checks */ + + DEBUGASSERT(spi != NULL && config != NULL && minor >= 0 && minor < 100); + + /* Create and initialize a CC3000 device driver instance */ + +#ifndef CONFIG_CC3000_MULTIPLE + priv = &g_cc3000; +#else + priv = (FAR struct cc3000_dev_s *)kmalloc(sizeof(struct cc3000_dev_s)); + if (!priv) + { + idbg("kmalloc(%d) failed\n", sizeof(struct cc3000_dev_s)); + return -ENOMEM; + } +#endif + + /* Initialize the CC3000 device driver instance */ + + memset(priv, 0, sizeof(struct cc3000_dev_s)); + + priv->minor = minor; /* Save the minor number */ + priv->spi = spi; /* Save the SPI device handle */ + priv->config = config; /* Save the board configuration */ + + sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ + sem_init(&priv->waitsem, 0, 0); /* Initialize event wait semaphore */ + sem_init(&priv->readysem, 0, 0); /* Initialize IRQ Ready semaphore */ + + /* Make sure that interrupts are disabled */ + + config->irq_clear(config); + config->irq_enable(config, false); + + /* Attach the interrupt handler */ + + ret = config->irq_attach(config, cc3000_interrupt); + if (ret < 0) + { + idbg("Failed to attach interrupt\n"); + goto errout_with_priv; + } + + /* Register the device as an input device */ + + (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor); + ivdbg("Registering %s\n", devname); + + ret = register_driver(devname, &cc3000_fops, 0666, priv); + if (ret < 0) + { + idbg("register_driver() failed: %d\n", ret); + goto errout_with_priv; + } + + + /* If multiple CC3000 devices are supported, then we will need to add + * this new instance to a list of device instances so that it can be + * found by the interrupt handler based on the recieved IRQ number. + */ + +#ifdef CONFIG_CC3000_MULTIPLE + priv->flink = g_cc3000list; + g_cc3000list = priv; + irqrestore(flags); +#endif + + /* And return success (?) */ + + return OK; + +errout_with_priv: + sem_destroy(&priv->devsem); +#ifdef CONFIG_CC3000_MULTIPLE + kfree(priv); +#endif + return ret; +} diff --git a/nuttx/drivers/wireless/cc3000/cc3000.h b/nuttx/drivers/wireless/cc3000/cc3000.h new file mode 100644 index 000000000..d0d143959 --- /dev/null +++ b/nuttx/drivers/wireless/cc3000/cc3000.h @@ -0,0 +1,149 @@ +/**************************************************************************** + * drivers//wireless/cc3000.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David Sidrane + * + * References: + * CC30000 from Texas Instruments http://processors.wiki.ti.com/index.php/CC3000 + * + * See also: + * http://processors.wiki.ti.com/index.php/CC3000_Host_Driver_Porting_Guide + * http://processors.wiki.ti.com/index.php/CC3000_Host_Programming_Guide + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __DRIVERS_WIRELESS_WIRELESS_CC3000_H +#define __DRIVERS_WIRELESS_WIRELESS_CC3000_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ +#include + +#include +#include +#include +#include +#include +#include +#include "spi.h" + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/* CC3000 Interfaces *********************************************************************/ + +/* Driver support **************************************************************************/ +/* 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. + */ + + +/******************************************************************************************** + * Public Types + ********************************************************************************************/ +#define READ 3 +#define READ_COMMAND {READ, 0 , 0 , 0 , 0} +#define READ_OFFSET_TO_LENGTH 3 //cmd dmy dmy lh ll +#define WRITE 1 + +#define HI(value) (((value) & 0xFF00) >> 8) +#define LO(value) ((value) & 0x00FF) + +#define SPI_HEADER_SIZE (5) + + +/* 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, + +} eDeviceStates; + +struct cc3000_dev_s +{ +#ifdef CONFIG_CC3000_MULTIPLE + FAR struct cc3000_dev_s *flink; /* Supports a singly linked list of drivers */ +#endif + uint8_t crefs; /* Number of times the device has been opened */ + uint8_t nwaiters; /* Number of threads waiting for CC3000 data */ + uint8_t minor; /* minor */ + sem_t devsem; /* Manages exclusive access to this structure */ + sem_t waitsem; /* Used to wait for the availability of data */ + sem_t readysem; /* Used to wait for Ready Condition from the cc3000 */ + + FAR struct cc3000_config_s *config; /* Board configuration data */ + 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 */ + eDeviceStates state; /* The device state */ + uint8_t rx_buffer[CC3000_RX_BUFFER_SIZE]; + ssize_t rx_buffer_len; + + uint8_t tx_buffer[CC3000_TX_BUFFER_SIZE]; + ssize_t tx_buffer_len; + + /* The following is a list if poll structures of threads waiting for + * driver events. The 'struct pollfd' reference for each open is also + * retained in the f_priv field of the 'struct file'. + */ + +#ifndef CONFIG_DISABLE_POLL + struct pollfd *fds[CONFIG_CC3000_NPOLLWAITERS]; +#endif +}; + +/******************************************************************************************** + * Public Function Prototypes + ********************************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __DRIVERS_WIRELESS_WIRELESS_CC3000_H */ diff --git a/nuttx/drivers/wireless/cc3000/spi.h b/nuttx/drivers/wireless/cc3000/spi.h new file mode 100644 index 000000000..bf68b3eb1 --- /dev/null +++ b/nuttx/drivers/wireless/cc3000/spi.h @@ -0,0 +1,45 @@ +/************************************************************************** +* +* 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 +* +****************************************************************************/ + + + + +typedef void (*gcSpiHandleRx)(void *p); + +//***************************************************************************** +// +// Prototypes for the APIs. +// +//***************************************************************************** + +void SpiOpen(gcSpiHandleRx pfRxHandler); + +void SpiClose(void); + +long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength); + +void SpiResumeSpi(void); + +int CC3000InterruptHandler(int irq, void *context); + +int16_t SPIInterruptsEnabled; + +uint8_t wlan_tx_buffer[]; diff --git a/nuttx/include/nuttx/wireless/cc3000.h b/nuttx/include/nuttx/wireless/cc3000.h new file mode 100644 index 000000000..93da43244 --- /dev/null +++ b/nuttx/include/nuttx/wireless/cc3000.h @@ -0,0 +1,160 @@ +/**************************************************************************** + * include/nuttx/wireless/cc3000.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David Sidrane + * + * References: + * CC30000 from Texas Instruments http://processors.wiki.ti.com/index.php/CC3000 + * + * See also: + * http://processors.wiki.ti.com/index.php/CC3000_Host_Driver_Porting_Guide + * http://processors.wiki.ti.com/index.php/CC3000_Host_Programming_Guide + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX 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 __INCLUDE_NUTTX_WIRELESS_CC3000_H +#define __INCLUDE_NUTTX_WIRELESS_CC3000_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ +#define DEV_FORMAT "/dev/wireless%d" +#define DEV_NAMELEN 16 +#define QUEUE_FORMAT "wlq%d" +#define QUEUE_NAMELEN 6 + + +/* IOCTL commands */ + +#define CC3000IOC_GETQUEID _WLIOC_USER(0x0001) /* arg: Address of int for number*/ +#define CC3000IOC_COMPLETE _WLIOC_USER(0x0002) /* arg: none resumes the Event WL Asynchronous events */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ +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); + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +EXTERN void wlan_init( tWlanCB sWlanCB, + tFWPatches sFWPatches, + tDriverPatches sDriverPatches, + tBootLoaderPatches sBootLoaderPatches, + tWlanReadInteruptPin sReadWlanInterruptPin, + tWlanInterruptEnable sWlanInterruptEnable, + tWlanInterruptDisable sWlanInterruptDisable, + tWriteWlanPin sWriteWlanPin); + + +/***************************************************************************** + * + * CC3000_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 + * + * @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 CC3000_wlan_init(tWlanCB sWlanCB, + tFWPatches sFWPatches, + tDriverPatches sDriverPatches, + tBootLoaderPatches sBootLoaderPatches); + + +/************************************************************************************ + * Name: wireless_archinitialize + * + * Description: + * Called to configure wireless module (wireless_archinitialize). + * + ************************************************************************************/ + +void wireless_archinitialize(void); + + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_WIRELESS_CC3000_H */ diff --git a/nuttx/include/nuttx/wireless/cc3000/include/cc3000_upif.h b/nuttx/include/nuttx/wireless/cc3000/include/cc3000_upif.h new file mode 100644 index 000000000..87f9c2376 --- /dev/null +++ b/nuttx/include/nuttx/wireless/cc3000/include/cc3000_upif.h @@ -0,0 +1,193 @@ +/**************************************************************************** + * include/nuttx/wireless/cc3000/include/cc3000_upif.h + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David Sidrane + * + * This is the definition for the interface to the bottom half of the cc3000 driver. + * it provides the wiring of the board's GPIO and spi to the cc3000 driver. + * + * References: + * CC30000 from Texas Instruments http://processors.wiki.ti.com/index.php/CC3000 + * + * See also: + * http://processors.wiki.ti.com/index.php/CC3000_Host_Driver_Porting_Guide + * http://processors.wiki.ti.com/index.php/CC3000_Host_Programming_Guide + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX 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 __INCLUDE_NUTTX_WIRELESS_CC3000_CC3000_INTERNAL_H +#define __INCLUDE_NUTTX_WIRELESS_CC3000_CC3000_INTERNAL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#if defined(CONFIG_WIRELESS) && defined(CONFIG_WL_CC3000) + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ +/* SPI Frequency. Default: 16MHz */ + +#ifndef CONFIG_CC3000_SPI_FREQUENCY +# define CONFIG_CC3000_SPI_FREQUENCY 16000000 +#endif + +/* Maximum number of threads than can be waiting for POLL events */ + +#ifndef CONFIG_CC3000_NPOLLWAITERS +# define CONFIG_CC3000_NPOLLWAITERS 2 +#endif + +#ifndef CONFIG_CC3000_SPIMODE +// CPOL = 0, CPHA = 1 Sample Data Falling Edge of Clock +// See http://processors.wiki.ti.com/index.php/CC3000_Serial_Port_Interface_(SPI) +# define CONFIG_CC3000_SPIMODE SPIDEV_MODE0 +#endif + + +/* Check for some required settings. This can save the user a lot of time + * in getting the right configuration. + */ + +#ifdef CONFIG_DISABLE_SIGNALS +# error "Signals are required. CONFIG_DISABLE_SIGNALS must not be selected." +#endif + +#ifndef CONFIG_SCHED_WORKQUEUE +# error "Work queue support required. CONFIG_SCHED_WORKQUEUE must be selected." +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* A reference to a structure of this type must be passed to the CC3000 + * driver. This structure provides information about the configuration + * of the CC3000 and provides some board-specific hooks. + * + * Memory for this structure is provided by the caller. It is not copied + * by the driver and is presumed to persist while the driver is active. The + * memory must be writable because, under certain circumstances, the driver + * may modify frequency or X plate resistance values. + */ + +struct cc3000_config_s +{ + /* Device characterization */ + + uint32_t spi_frequency; /* SPI frequency */ + uint32_t spi_mode; /* SPI mode */ + + /* If multiple CC3000 devices are supported, then an IRQ number must + * be provided for each so that their interrupts can be distinguished. + */ + +#ifndef CONFIG_CC3000_MULTIPLE + int irq; /* IRQ number received by interrupt handler. */ +#endif + + /* IRQ/GPIO access callbacks. These operations all hidden behind + * callbacks to isolate the CC3000 driver from differences in GPIO + * interrupt handling by varying boards and MCUs. If possible, + * interrupts should be configured on falling edges to detect the Ready Condition + * At T2: The normal master SPI write sequence is SPI_CS low, followed by SPI_IRQ low + * CC3000 to host, indicating that the CC3000 core module is ready to accept data. + * T2 duration is approximately 7 ms. + * + * irq_attach - Attach the CC3000 interrupt handler to the GPIO interrupt + * irq_enable - Enable or disable the GPIO interrupt + * clear_irq - Acknowledge/clear any pending GPIO interrupt + * power_enable - Enable or disable Module enable. + * chip_select - The Chip Select + * busy - Return the state of the interrupt GPIO input + * + */ + + int (*irq_attach)(FAR struct cc3000_config_s *state, xcpt_t isr); + void (*irq_enable)(FAR struct cc3000_config_s *state, bool enable); + void (*irq_clear)(FAR struct cc3000_config_s *state); + void (*power_enable)(FAR struct cc3000_config_s *state,bool enable); + void (*chip_select)(FAR struct cc3000_config_s *state,bool enable); + bool (*busy)(FAR struct cc3000_config_s *state); +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: CC3000_register + * + * Description: + * Configure the CC3000 to use the provided SPI device instance. This + * will register the driver as /dev/inputN where N is the minor device + * number + * + * Input Parameters: + * spi - An SPI driver instance + * config - Persistent board configuration data + * minor - The CC000 device minor number + * + * Returned Value: + * Pointer to newly allocated cc3000 device structure or NULL on error + * (errno is set accordingly in this case). + * + ****************************************************************************/ + +EXTERN int CC3000_register(FAR struct spi_dev_s *spi, + FAR struct cc3000_config_s *config, + int minor); + + + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_WIRELESS && CONFIG_INPUT_CC3000 */ +#endif /* __INCLUDE_NUTTX_WIRELESS_CC3000_CC3000_INTERNAL_H */ diff --git a/nuttx/include/nuttx/wireless/cc3000/include/sys/socket.h b/nuttx/include/nuttx/wireless/cc3000/include/sys/socket.h new file mode 100644 index 000000000..7dcdba814 --- /dev/null +++ b/nuttx/include/nuttx/wireless/cc3000/include/sys/socket.h @@ -0,0 +1,662 @@ +/***************************************************************************** +* +* socket.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 _INCLUDE_NUTTX_WIRELESS_CC3000__SOCKET_H +#define _INCLUDE_NUTTX_WIRELESS_CC3000__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 + +#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 +{ + uint16_t sa_family; + uint8_t sa_data[14]; +} sockaddr; + +typedef struct _sockaddr_in_t +{ + int16_t sin_family; // e.g. AF_INET + uint16_t 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; //acassis: conflict with previous declaration on nuttx + +// 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)) + +// fd_set for select and pselect. +typedef struct +{ + __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; +#define __FDS_BITS(set) ((set)->fds_bits) +} TICC3000fd_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; \ + TICC3000fd_set *__arr = (set); \ + for (__i = 0; __i < sizeof (TICC3000fd_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 'TICC3000fd_set'. +#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(char * hostname, uint16_t usNameLen, unsigned long* 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, TICC3000fd_set *readsds, TICC3000fd_set *writesds, + TICC3000fd_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(uint16_t mdnsEnabled, char * deviceServiceName, uint16_t deviceServiceNameLength); + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** + + +//***************************************************************************** +// +// Mark the end of the C bindings section for C++ compilers. +// +//***************************************************************************** +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // _INCLUDE_NUTTX_WIRELESS_CC3000__SOCKET_H diff --git a/nuttx/include/nuttx/wireless/cc3000/spi.h b/nuttx/include/nuttx/wireless/cc3000/spi.h deleted file mode 100644 index bf68b3eb1..000000000 --- a/nuttx/include/nuttx/wireless/cc3000/spi.h +++ /dev/null @@ -1,45 +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 -* -****************************************************************************/ - - - - -typedef void (*gcSpiHandleRx)(void *p); - -//***************************************************************************** -// -// Prototypes for the APIs. -// -//***************************************************************************** - -void SpiOpen(gcSpiHandleRx pfRxHandler); - -void SpiClose(void); - -long SpiWrite(uint8_t *pUserBuffer, uint16_t usLength); - -void SpiResumeSpi(void); - -int CC3000InterruptHandler(int irq, void *context); - -int16_t SPIInterruptsEnabled; - -uint8_t wlan_tx_buffer[]; -- cgit v1.2.3