diff --git a/ChangeLog b/ChangeLog index 08f1df472d2..37a4b8cd75b 100755 --- a/ChangeLog +++ b/ChangeLog @@ -10780,3 +10780,20 @@ OS. It is a non-standard but more efficient version of sem_timedwait() for use in higher performance device drivers (2015-08-01). * drivers/net/slip.c: Fix another compilation error (2015-08-02). + * drivers/can.c include/nuttx/can.h, and fs/fs.h: Add CAN IOCTL command + definitions to manage CAN message filtering (2015-08-05) + * drivers/Kconfig and can.c: Add configuration to support DLC to byte + conversions needed for CAN FD mode (2015-08-05). + * arch/arm/src/samv7: Add an MCAN driver for the SAMV7 platform + (2015-08-06). + * drivers/sensors/lm92.c and include/nuttx/sensors/lm92.h: Add a driver + for the LM92 temperature sensor. Contributed by Paul Patience + (2015-08-06). + * drivers/sensors/as5048b.c and include/nuttx/sensors/as5048b.h: Add + support for an AS5048B rotary magnetic sensor. From Paul Patience + (2015-08-06). + * include/nuttx/spi/slave.h: Add a definition of an SPI slave + interface (2015-08-08). + * arch/arm/src/samv7: Add the framework for an SPI slave drvier. This + driver has a lot of missing logic on initial commit (2015-08-09). + diff --git a/TODO b/TODO index 66ae1cedbe6..b63ea6f6464 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated July 26, 2015) +NuttX TODO List (Last updated August 6, 2015) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -20,7 +20,7 @@ nuttx/ (4) USB (drivers/usbdev, drivers/usbhost) (12) Libraries (libc/, libm/) (11) File system/Generic drivers (fs/, drivers/) - (7) Graphics subsystem (graphics/) + (8) Graphics subsystem (graphics/) (1) Pascal add-on (pcode/) (2) Build system / Toolchains (3) Linux/Cywgin simulation (arch/sim) @@ -1536,6 +1536,15 @@ o Graphics subsystem (graphics/) Status: Open Priority: Low, of mostly strategic value. + Title: VERTICAL ANTI-ALIASING + Description: Anti-aliasing is implemented along the horizontal raster line + with fractional pixels at the ends of each line. There is no + accounting for fractional pixels in the vertical direction. + As a result lines closer to vertical receive better anti- + aliasing than lines closer to horizontal. + Status: Open + Priority: Low, not a serious issue but worth noting. There is no plan + to change this behavior. o Pascal Add-On (pcode/) ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/arch b/arch index d99e8ced384..1efba67cba0 160000 --- a/arch +++ b/arch @@ -1 +1 @@ -Subproject commit d99e8ced38440ef61bebfd1507269b9072aba355 +Subproject commit 1efba67cba08b28a2a4a1a4649daf2df93b2d596 diff --git a/configs b/configs index bba0b5c9b5e..ac4035687c8 160000 --- a/configs +++ b/configs @@ -1 +1 @@ -Subproject commit bba0b5c9b5e62c8d1f8d69cdd96c960e042bf82c +Subproject commit ac4035687c824bb4a573e06feb017cb4f3ce7626 diff --git a/drivers/Kconfig b/drivers/Kconfig index b94ad60f990..263001d9cca 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -99,13 +99,20 @@ menuconfig CAN See include/nuttx/can.h for further CAN driver information. if CAN + config CAN_EXTID bool "CAN extended IDs" default n ---help--- - Enables support for the 29-bit extended ID. Default Standard 11-bit + Enables support for the 28-bit extended ID. Default Standard 11-bit IDs. +config CAN_FD + bool "CAN FD" + default n + ---help--- + Enables support for the CAN_FD mode. + config CAN_FIFOSIZE int "CAN driver I/O buffer size" default 8 diff --git a/drivers/can.c b/drivers/can.c index 4f2e5f95440..f37557205bd 100644 --- a/drivers/can.c +++ b/drivers/can.c @@ -89,6 +89,15 @@ * Private Function Prototypes ****************************************************************************/ +/* CAN helpers */ + +static uint8_t can_dlc2bytes(uint8_t dlc); +#if 0 /* Not used */ +static uint8_t can_bytes2dlc(uint8_t nbytes); +#endif + +/* Character driver methods */ + static int can_open(FAR struct file *filep); static int can_close(FAR struct file *filep); static ssize_t can_read(FAR struct file *filep, FAR char *buffer, @@ -97,7 +106,7 @@ static int can_xmit(FAR struct can_dev_s *dev); static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, size_t buflen); static inline ssize_t can_rtrread(FAR struct can_dev_s *dev, - FAR struct canioctl_rtr_s *rtr); + FAR struct canioc_rtr_s *rtr); static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg); @@ -125,6 +134,118 @@ static const struct file_operations g_canops = * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: can_dlc2bytes + * + * Description: + * In the CAN FD format, the coding of the DLC differs from the standard + * CAN format. The DLC codes 0 to 8 have the same coding as in standard + * CAN. But the codes 9 to 15 all imply a data field of 8 bytes with + * standard CAN. In CAN FD mode, the values 9 to 15 are encoded to values + * in the range 12 to 64. + * + * Input Parameter: + * dlc - the DLC value to convert to a byte count + * + * Returned Value: + * The number of bytes corresponding to the DLC value. + * + ****************************************************************************/ + +static uint8_t can_dlc2bytes(uint8_t dlc) +{ + if (dlc > 8) + { +#ifdef CONFIG_CAN_FD + switch (dlc) + { + case 9: + return 12; + case 10: + return 16; + case 11: + return 20; + case 12: + return 24; + case 13: + return 32; + case 14: + return 48; + default: + case 15: + return 64; + } +#else + return 8; +#endif + } + + return dlc; +} + +/**************************************************************************** + * Name: can_bytes2dlc + * + * Description: + * In the CAN FD format, the coding of the DLC differs from the standard + * CAN format. The DLC codes 0 to 8 have the same coding as in standard + * CAN. But the codes 9 to 15 all imply a data field of 8 bytes with + * standard CAN. In CAN FD mode, the values 9 to 15 are encoded to values + * in the range 12 to 64. + * + * Input Parameter: + * nbytes - the byte count to convert to a DLC value + * + * Returned Value: + * The encoded DLC value corresponding to at least that number of bytes. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static uint8_t can_bytes2dlc(FAR struct sam_can_s *priv, uint8_t nbytes) +{ + if (nbytes <= 8) + { + return nbytes; + } +#ifdef CONFIG_CAN_FD + else if (nbytes <= 12) + { + return 9; + } + else if (nbytes <= 16) + { + return 10; + } + else if (nbytes <= 20) + { + return 11; + } + else if (nbytes <= 24) + { + return 12; + } + else if (nbytes <= 32) + { + return 13; + } + else if (nbytes <= 48) + { + return 14; + } + else /* if (nbytes <= 64) */ + { + return 15; + } +#else + else + { + return 8; + } +#endif +} +#endif + /**************************************************************************** * Name: can_open * @@ -351,7 +472,8 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer, /* Will the next message in the FIFO fit into the user buffer? */ FAR struct can_msg_s *msg = &dev->cd_recv.rx_buffer[dev->cd_recv.rx_head]; - int msglen = CAN_MSGLEN(msg->cm_hdr.ch_dlc); + int nbytes = can_dlc2bytes(msg->cm_hdr.ch_dlc); + int msglen = CAN_MSGLEN(nbytes); if (nread + msglen > buflen) { @@ -472,6 +594,7 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, ssize_t nsent = 0; irqstate_t flags; int nexttail; + int nbytes; int msglen; int ret = 0; @@ -562,7 +685,8 @@ static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, */ msg = (FAR struct can_msg_s *)&buffer[nsent]; - msglen = CAN_MSGLEN(msg->cm_hdr.ch_dlc); + nbytes = can_dlc2bytes(msg->cm_hdr.ch_dlc); + msglen = CAN_MSGLEN(nbytes); memcpy(&fifo->tx_buffer[fifo->tx_tail], msg, msglen); /* Increment the tail of the circular buffer */ @@ -604,7 +728,7 @@ return_with_irqdisabled: ****************************************************************************/ static inline ssize_t can_rtrread(FAR struct can_dev_s *dev, - FAR struct canioctl_rtr_s *rtr) + FAR struct canioc_rtr_s *rtr) { FAR struct can_rtrwait_s *wait = NULL; irqstate_t flags; @@ -663,19 +787,19 @@ static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg) switch (cmd) { - /* CANIOCTL_RTR: Send the remote transmission request and wait for the - * response. Argument is a reference to struct canioctl_rtr_s + /* CANIOC_RTR: Send the remote transmission request and wait for the + * response. Argument is a reference to struct canioc_rtr_s * (casting to uintptr_t first eliminates complaints on some * architectures where the sizeof long is different from the size of * a pointer). */ - case CANIOCTL_RTR: - ret = can_rtrread(dev, (struct canioctl_rtr_s*)((uintptr_t)arg)); + case CANIOC_RTR: + ret = can_rtrread(dev, (struct canioc_rtr_s*)((uintptr_t)arg)); break; /* Not a "built-in" ioctl command.. perhaps it is unique to this - * device driver. + * lower-half, device driver. */ default: @@ -787,10 +911,14 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, if (msg && hdr->ch_id == rtr->cr_id) { + int nbytes; + /* We have the response... copy the data to the user's buffer */ memcpy(&msg->cm_hdr, hdr, sizeof(struct can_hdr_s)); - for (i = 0, dest = msg->cm_data; i < hdr->ch_dlc; i++) + + nbytes = can_dlc2bytes(hdr->ch_dlc); + for (i = 0, dest = msg->cm_data; i < nbytes; i++) { *dest++ = *data++; } @@ -811,10 +939,22 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, if (nexttail != fifo->rx_head) { - /* Add the new, decoded CAN message at the tail of the FIFO */ + int nbytes; + + /* Add the new, decoded CAN message at the tail of the FIFO. + * + * REVISIT: In the CAN FD format, the coding of the DLC differs from + * the standard CAN format. The DLC codes 0 to 8 have the same coding + * as in standard CAN, the codes 9 to 15, which in standard CAN all + * code a data field of 8 bytes, are encoded: + * + * 9->12, 10->16, 11->20, 12->24, 13->32, 14->48, 15->64 + */ memcpy(&fifo->rx_buffer[fifo->rx_tail].cm_hdr, hdr, sizeof(struct can_hdr_s)); - for (i = 0, dest = fifo->rx_buffer[fifo->rx_tail].cm_data; i < hdr->ch_dlc; i++) + + nbytes = can_dlc2bytes(hdr->ch_dlc); + for (i = 0, dest = fifo->rx_buffer[fifo->rx_tail].cm_data; i < nbytes; i++) { *dest++ = *data++; } diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index dc9890ee64f..32c87c7e0c7 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -52,7 +52,7 @@ config NET_DUMPPACKET comment "External Ethernet MAC Device Support" -config NET_DM90x0 +menuconfig NET_DM90x0 bool "Davicom dm9000/dm9010 support" default n ---help--- @@ -132,7 +132,7 @@ config NET_CS89x0 ---help--- Under construction -- do not use -config ENC28J60 +menuconfig ENC28J60 bool "Microchip ENC28J60 support" default n select SPI @@ -142,6 +142,7 @@ config ENC28J60 DS39662C, 2008 Microchip Technology Inc. if ENC28J60 + config ENC28J60_NINTERFACES int "Number of physical ENC28J60" default 1 @@ -192,9 +193,9 @@ config ENC28J60_REGDEBUG ---help--- Enable very low-level register access debug. Depends on DEBUG and DEBUG_NET. -endif +endif # ENC28J60 -config ENCX24J600 +menuconfig ENCX24J600 bool "Microchip ENCX24J600 support" default n select SPI @@ -205,6 +206,7 @@ config ENCX24J600 with SPI or Parallel Interface DS39935B, 2009 Microchip Technology Inc. if ENCX24J600 + config ENC28J60_NINTERFACES int "Number of physical ENCX24J600" default 1 @@ -258,9 +260,9 @@ config ENCX24J600_REGDEBUG ---help--- Enable very low-level register access debug. Depends on DEBUG and DEBUG_NET. -endif +endif # ENCX24J600 -config NET_E1000 +menuconfig NET_E1000 bool "E1000 support" default n @@ -280,13 +282,52 @@ config E1000_BUFF_SIZE endif # NET_E1000 -config NET_SLIP +menuconfig NET_SLIP bool "SLIP (serial line) support" default n ---help--- Reference: RFC 1055 -config NET_FTMAC100 +if NET_SLIP + +config NET_SLIP_STACKSIZE + int "Daemon stack size" + default 2048 + ---help--- + Provides the stack size for SLIP RX and TX. + +config NET_SLIP_DEFPRIO + int "Daemon priority" + default 128 + ---help--- + Provides the priority for SLIP RX and TX threads. + +config NET_SLIP_MTU + int "Packet size (MTU)" + default 296 + ---help--- + Provides the size of the SLIP packet buffers. + + The Linux slip module hard-codes its MTU size to 296 (40 bytes for + the IP+TPC headers plus 256 bytes of data). So you might as well + set CONFIG_NET_SLIP_MTU to 296 as well. + + There may be an issue with this setting, however. I see that Linux + uses a MTU of 296 and window of 256, but actually only sends 168 + bytes of data: 40 + 128. I believe that is to allow for the 2x + worst cast packet expansion. Ideally we would like to advertise the + 256 MSS, but restrict transfers to 128 bytes (possibly by modifying + the tcp_mss() macro). + +config NET_SLIP_NINTERFACES + int "Number of SLIP interfaces" + default 1 + ---help--- + Determines the number of physical interfaces that will be supported. + +endif + +menuconfig NET_FTMAC100 bool "Faraday 10/100 Ethernet" default n ---help--- @@ -316,7 +357,7 @@ config FTMAC100_MAC0_ENV_ADDR endif # NET_FTMAC100 -config NET_VNET +menuconfig NET_VNET bool "VNET support" default n diff --git a/drivers/net/slip.c b/drivers/net/slip.c index a8e50343bbf..bbabc1527e8 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -83,12 +83,12 @@ # warning "CONFIG_NET_MULTIBUFFER must be set" #endif -#ifndef CONFIG_SLIP_STACKSIZE -# define CONFIG_SLIP_STACKSIZE 2048 +#ifndef CONFIG_NET_SLIP_STACKSIZE +# define CONFIG_NET_SLIP_STACKSIZE 2048 #endif -#ifndef CONFIG_SLIP_DEFPRIO -# define CONFIG_SLIP_DEFPRIO 128 +#ifndef CONFIG_NET_SLIP_DEFPRIO +# define CONFIG_NET_SLIP_DEFPRIO 128 #endif /* The Linux slip module hard-codes its MTU size to 296 (40 bytes for the @@ -99,7 +99,7 @@ * a MTU of 296 and window of 256, but actually only sends 168 bytes of data: * 40 + 128. I believe that is to allow for the 2x worst cast packet * expansion. Ideally we would like to advertise the 256 MSS, but restrict - * uIP to 128 bytes (possibly by modifying the tcp_mss() macro). + * transfers to 128 bytes (possibly by modifying the tcp_mss() macro). */ #if CONFIG_NET_SLIP_MTU < 296 @@ -108,12 +108,12 @@ # warning "CONFIG_NET_SLIP_MTU == 296 is optimal" #endif -/* CONFIG_SLIP_NINTERFACES determines the number of physical interfaces +/* CONFIG_NET_SLIP_NINTERFACES determines the number of physical interfaces * that will be supported. */ -#ifndef CONFIG_SLIP_NINTERFACES -# define CONFIG_SLIP_NINTERFACES 1 +#ifndef CONFIG_NET_SLIP_NINTERFACES +# define CONFIG_NET_SLIP_NINTERFACES 1 #endif /* SLIP special character codes *******************************************/ @@ -183,11 +183,11 @@ struct slip_driver_s * Private Data ****************************************************************************/ - /* We really should get rid of CONFIG_SLIP_NINTERFACES and, instead, + /* We really should get rid of CONFIG_NET_SLIP_NINTERFACES and, instead, * kmm_malloc() new interface instances as needed. */ -static struct slip_driver_s g_slip[CONFIG_SLIP_NINTERFACES]; +static struct slip_driver_s g_slip[CONFIG_NET_SLIP_NINTERFACES]; /**************************************************************************** * Private Function Prototypes @@ -250,7 +250,7 @@ static void slip_semtake(FAR struct slip_driver_s *priv) * Description: * Just an inline wrapper around fwrite with error checking. * - * Parameters: + * Input Parameters: * priv - Reference to the driver state structure * buffer - Buffer data to send * len - Buffer length in bytes @@ -274,7 +274,7 @@ static inline void slip_write(FAR struct slip_driver_s *priv, * Description: * Just an inline wrapper around putc with error checking. * - * Parameters: + * Input Parameters: * priv - Reference to the driver state structure * ch - The character to send * @@ -293,7 +293,7 @@ static inline void slip_putc(FAR struct slip_driver_s *priv, int ch) * Start hardware transmission. Called either from the txdone interrupt * handling or from watchdog based polling. * - * Parameters: + * Input Parameters: * priv - Reference to the driver state structure * * Returned Value: @@ -407,7 +407,7 @@ static int slip_transmit(FAR struct slip_driver_s *priv) * 1. When the preceding TX packet send is complete, or * 2. During normal periodic polling * - * Parameters: + * Input Parameters: * dev - Reference to the NuttX driver state structure * * Returned Value: @@ -444,7 +444,7 @@ static int slip_txpoll(FAR struct net_driver_s *dev) * Description: * Polling and transmission is performed on tx thread. * - * Parameters: + * Input Parameters: * arg - Reference to the NuttX driver state structure * * Returned Value: @@ -462,7 +462,7 @@ static void slip_txtask(int argc, FAR char *argv[]) unsigned int hsec; ndbg("index: %d\n", index); - DEBUGASSERT(index < CONFIG_SLIP_NINTERFACES); + DEBUGASSERT(index < CONFIG_NET_SLIP_NINTERFACES); /* Get our private data structure instance and wake up the waiting * initialization logic. @@ -535,7 +535,7 @@ static void slip_txtask(int argc, FAR char *argv[]) * Description: * Get one byte from the serial input. * - * Parameters: + * Input Parameters: * priv - Reference to the driver state structure * * Returned Value: @@ -561,7 +561,7 @@ static inline int slip_getc(FAR struct slip_driver_s *priv) * Description: * Read a packet from the serial input * - * Parameters: + * Input Parameters: * priv - Reference to the driver state structure * * Returned Value: @@ -666,7 +666,7 @@ static inline void slip_receive(FAR struct slip_driver_s *priv) * Description: * Wait for incoming data. * - * Parameters: + * Input Parameters: * argc * argv * @@ -685,7 +685,7 @@ static int slip_rxtask(int argc, FAR char *argv[]) int ch; ndbg("index: %d\n", index); - DEBUGASSERT(index < CONFIG_SLIP_NINTERFACES); + DEBUGASSERT(index < CONFIG_NET_SLIP_NINTERFACES); /* Get our private data structure instance and wake up the waiting * initialization logic. @@ -786,7 +786,7 @@ static int slip_rxtask(int argc, FAR char *argv[]) * NuttX Callback: Bring up the Ethernet interface when an IP address is * provided * - * Parameters: + * Input Parameters: * dev - Reference to the NuttX driver state structure * * Returned Value: @@ -816,7 +816,7 @@ static int slip_ifup(FAR struct net_driver_s *dev) * Description: * NuttX Callback: Stop the interface. * - * Parameters: + * Input Parameters: * dev - Reference to the NuttX driver state structure * * Returned Value: @@ -844,7 +844,7 @@ static int slip_ifdown(FAR struct net_driver_s *dev) * stimulus perform an out-of-cycle poll and, thereby, reduce the TX * latency. * - * Parameters: + * Input Parameters: * dev - Reference to the NuttX driver state structure * * Returned Value: @@ -876,7 +876,7 @@ static int slip_txavail(FAR struct net_driver_s *dev) * NuttX Callback: Add the specified MAC address to the hardware multicast * address filtering * - * Parameters: + * Input Parameters: * dev - Reference to the NuttX driver state structure * mac - The MAC address to be added * @@ -905,7 +905,7 @@ static int slip_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac) * NuttX Callback: Remove the specified MAC address from the hardware multicast * address filtering * - * Parameters: + * Input Parameters: * dev - Reference to the NuttX driver state structure * mac - The MAC address to be removed * @@ -937,10 +937,12 @@ static int slip_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac) * Description: * Instantiate a SLIP network interface. * - * Parameters: - * intf - In the case where there are multiple SLIP interfaces, this value - * identifies which is to be initialized. The network name will be, - * for example, "/dev/slip5" for intf == 5 + * Input Parameters: + * intf - In the case where there are multiple SLIP interfaces, this + * value identifies which is to be initialized. The number of + * possible SLIP interfaces is determined by + * devname - This is the path to the serial device that will support SLIP. + * For example, this might be "/dev/ttyS1" * * Returned Value: * OK on success; Negated errno on failure. @@ -957,7 +959,7 @@ int slip_initialize(int intf, FAR const char *devname) /* Get the interface structure associated with this interface number. */ - DEBUGASSERT(intf < CONFIG_SLIP_NINTERFACES); + DEBUGASSERT(intf < CONFIG_NET_SLIP_NINTERFACES); priv = &g_slip[intf]; /* Initialize the driver structure */ @@ -997,9 +999,9 @@ int slip_initialize(int intf, FAR const char *devname) argv[0] = buffer; argv[1] = NULL; - priv->rxpid = task_create("rxslip", CONFIG_SLIP_DEFPRIO, - CONFIG_SLIP_STACKSIZE, (main_t)slip_rxtask, - (FAR char * const *)argv); + priv->rxpid = task_create("rxslip", CONFIG_NET_SLIP_DEFPRIO, + CONFIG_NET_SLIP_STACKSIZE, (main_t)slip_rxtask, + (FAR char * const *)argv); if (priv->rxpid < 0) { ndbg("ERROR: Failed to start receiver task\n"); @@ -1012,8 +1014,8 @@ int slip_initialize(int intf, FAR const char *devname) /* Start the SLIP transmitter task */ - priv->txpid = task_create("txslip", CONFIG_SLIP_DEFPRIO, - CONFIG_SLIP_STACKSIZE, (main_t)slip_txtask, + priv->txpid = task_create("txslip", CONFIG_NET_SLIP_DEFPRIO, + CONFIG_NET_SLIP_STACKSIZE, (main_t)slip_txtask, (FAR char * const *)argv); if (priv->txpid < 0) { diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index c7137c3c124..19bdedae26d 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -3,6 +3,13 @@ # see the file kconfig-language.txt in the NuttX tools repository. # +config AS5048B + bool "AMS AS5048B Magnetic Rotary Encoder support" + default n + select I2C + ---help--- + Enable driver support for the AMS AS5048B magnetic rotary encoder. + config BMP180 bool "Bosch BMP180 Barometer Sensor support" default n @@ -79,6 +86,13 @@ config LM75 This should also work with compatible temperature sensors such as the TI TMP100/101. +config LM92 + bool "TI LM92 Temperature Sensor support" + default n + select I2C + ---help--- + Enable driver support for the TI LM92 Temperature Sensor. + config QENCODER bool "Qencoder" default n diff --git a/drivers/sensors/Make.defs b/drivers/sensors/Make.defs index ce887cdd1b0..0d86e8e9f7a 100644 --- a/drivers/sensors/Make.defs +++ b/drivers/sensors/Make.defs @@ -45,6 +45,10 @@ endif ifeq ($(CONFIG_I2C),y) +ifeq ($(CONFIG_AS5048B),y) + CSRCS += as5048b.c +endif + ifeq ($(CONFIG_LIS331DL),y) CSRCS += lis331dl.c endif @@ -60,6 +64,11 @@ endif ifeq ($(CONFIG_I2C_LM75),y) CSRCS += lm75.c endif + +ifeq ($(CONFIG_LM92),y) + CSRCS += lm92.c +endif + endif # CONFIG_I2C # These drivers depend on SPI support diff --git a/drivers/sensors/as5048b.c b/drivers/sensors/as5048b.c new file mode 100644 index 00000000000..ffa96a47f21 --- /dev/null +++ b/drivers/sensors/as5048b.c @@ -0,0 +1,616 @@ +/**************************************************************************** + * drivers/sensors/as5048b.c + * Character driver for the AMS AS5048B Magnetic Rotary Encoder + * + * Copyright (C) 2015 Alexandru Duru. All rights reserved. + * Author: Alexandru Duru + * + * 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 + +#if defined(CONFIG_I2C) && defined(CONFIG_AS5048B) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct as5048b_dev_s +{ + FAR struct i2c_dev_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* I2C Helpers */ + +static int as5048b_readb8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, + FAR uint8_t *regval); +static int as5048b_readb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, + uint8_t regaddrlo, FAR uint16_t *regval); +static int as5048b_writeb8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, + uint8_t regval); +static int as5048b_writeb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, + uint8_t regaddrlo, uint16_t regval); +static int as5048b_readzero(FAR struct as5048b_dev_s *priv, + FAR uint16_t *zero); +static int as5048b_writezero(FAR struct as5048b_dev_s *priv, uint16_t zero); +static int as5048b_readagc(FAR struct as5048b_dev_s *priv, FAR uint8_t *agc); +static int as5048b_readdiag(FAR struct as5048b_dev_s *priv, + FAR uint8_t *diag); +static int as5048b_readmag(FAR struct as5048b_dev_s *priv, FAR uint16_t *mag); +static int as5048b_readang(FAR struct as5048b_dev_s *priv, FAR uint16_t *ang); + +/* Character Driver Methods */ + +static int as5048b_open(FAR struct file *filep); +static int as5048b_close(FAR struct file *filep); +static ssize_t as5048b_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t as5048b_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int as5048b_ioctl(FAR struct file *filep, int cmd, + unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_as5048bfops = +{ + as5048b_open, + as5048b_close, + as5048b_read, + as5048b_write, + NULL, + as5048b_ioctl +#ifndef CONFIG_DISABLE_POLL + , NULL +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: as5048b_readb8 + * + * Description: + * Read from an 8-bit register + * + ****************************************************************************/ + +static int as5048b_readb8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, + FAR uint8_t *regval) +{ + uint8_t buffer; + int ret; + + /* Write the register address */ + + I2C_SETADDRESS(priv->i2c, priv->addr, 7); + ret = I2C_WRITE(priv->i2c, ®addr, sizeof(regaddr)); + if (ret < 0) + { + sndbg("I2C_WRITE failed: %d\n", ret); + return ret; + } + + /* Restart and read 8 bits from the register */ + + ret = I2C_READ(priv->i2c, &buffer, sizeof(buffer)); + if (ret < 0) + { + sndbg("I2C_READ failed: %d\n", ret); + return ret; + } + + *regval = buffer; + sndbg("addr: %02x value: %02x ret: %d\n", regaddr, *regval, ret); + return ret; +} + +/**************************************************************************** + * Name: as5048b_readb16 + * + * Description: + * Read from two 8-bit registers + * + ****************************************************************************/ + +static int as5048b_readb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, + uint8_t regaddrlo, FAR uint16_t *regval) +{ + uint8_t hi, lo; + int ret; + + /* Read the high 8 bits of the 13-bit value */ + + ret = as5048b_readb8(priv, regaddrhi, &hi); + if (ret < 0) + { + sndbg("as5048b_readb8 failed: %d\n", ret); + return ret; + } + + /* Read the low 5 bits of the 13-bit value */ + + ret = as5048b_readb8(priv, regaddrlo, &lo); + if (ret < 0) + { + sndbg("as5048b_readb8 failed: %d\n", ret); + return ret; + } + + *regval = (uint16_t)hi << 6 | (uint16_t)lo; + sndbg("addrhi: %02x addrlo: %02x value: %04x ret: %d\n", + regaddrhi, regaddrlo, *regval, ret); + return ret; +} + +/**************************************************************************** + * Name: as5048b_writeb8 + * + * Description: + * Write from an 8-bit register + * + ****************************************************************************/ + +static int as5048b_writeb8(FAR struct as5048b_dev_s *priv, uint8_t regaddr, + uint8_t regval) +{ + uint8_t buffer[2]; + int ret; + + sndbg("addr: %02x value: %02x\n", regaddr, regval); + + /* Set up a 2-byte message to send */ + + buffer[0] = regaddr; + buffer[1] = regval; + + /* Write the register address followed by the data (no RESTART) */ + + I2C_SETADDRESS(priv->i2c, priv->addr, 7); + ret = I2C_WRITE(priv->i2c, buffer, sizeof(buffer)); + if (ret < 0) + { + sndbg("I2C_WRITE failed: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Name: as5048b_writeb16 + * + * Description: + * Write to two 8-bit registers + * + ****************************************************************************/ + +static int as5048b_writeb16(FAR struct as5048b_dev_s *priv, uint8_t regaddrhi, + uint8_t regaddrlo, uint16_t regval) +{ + int ret; + + sndbg("addrhi: %02x addrlo: %02x value: %04x\n", + regaddrhi, regaddrlo, regval); + + /* Write the high 8 bits of the 13-bit value */ + + ret = as5048b_writeb8(priv, regaddrhi, (uint8_t)(regval >> 6)); + if (ret < 0) + { + sndbg("as5048b_writeb8 failed: %d\n", ret); + return ret; + } + + /* Write the low 5 bits of the 13-bit value */ + + ret = as5048b_writeb8(priv, regaddrhi, (uint8_t)regval); + if (ret < 0) + { + sndbg("as5048b_writeb8 failed: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Name: as5048b_readzero + * + * Description: + * Read from the zero position registers + * + ****************************************************************************/ + +static int as5048b_readzero(FAR struct as5048b_dev_s *priv, + FAR uint16_t *zero) +{ + uint16_t buffer; + int ret; + + ret = as5048b_readb16(priv, AS5048B_ZEROHI_REG, AS5048B_ZEROLO_REG, + &buffer); + if (ret < 0) + { + sndbg("as5048b_readb16 failed: %d\n", ret); + return ret; + } + + *zero = buffer; + sndbg("zero: %04x ret: %d\n", *zero, ret); + return ret; +} + +/**************************************************************************** + * Name: as5048b_writezero + * + * Description: + * Write to the zero position registers + * + ****************************************************************************/ + +static int as5048b_writezero(FAR struct as5048b_dev_s *priv, uint16_t zero) +{ + int ret; + + sndbg("zero: %04x\n", zero); + + ret = as5048b_writeb16(priv, AS5048B_ZEROHI_REG, AS5048B_ZEROLO_REG, zero); + if (ret < 0) + { + sndbg("as5048b_writeb16 failed: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Name: as5048b_readagc + * + * Description: + * Read from the automatic gain control register + * + ****************************************************************************/ + +static int as5048b_readagc(FAR struct as5048b_dev_s *priv, FAR uint8_t *agc) +{ + uint8_t buffer; + int ret; + + ret = as5048b_readb8(priv, AS5048B_AGC_REG, &buffer); + if (ret < 0) + { + sndbg("as5048b_readb8 failed: %d\n", ret); + return ret; + } + + *agc = buffer; + sndbg("agc: %02x ret: %d\n", *agc, ret); + return ret; +} + +/**************************************************************************** + * Name: as5048b_readdiag + * + * Description: + * Read from the diagnostics register + * + ****************************************************************************/ + +static int as5048b_readdiag(FAR struct as5048b_dev_s *priv, FAR uint8_t *diag) +{ + uint8_t buffer; + int ret; + + ret = as5048b_readb8(priv, AS5048B_DIAG_REG, &buffer); + if (ret < 0) + { + sndbg("as5048b_readb8 failed: %d\n", ret); + return ret; + } + + *diag = buffer; + sndbg("diag: %02x ret: %d\n", *diag, ret); + return ret; +} + +/**************************************************************************** + * Name: as5048b_readmag + * + * Description: + * Read from the magnitude registers + * + ****************************************************************************/ + +static int as5048b_readmag(FAR struct as5048b_dev_s *priv, FAR uint16_t *mag) +{ + uint16_t buffer; + int ret; + + ret = as5048b_readb16(priv, AS5048B_MAGHI_REG, AS5048B_MAGLO_REG, &buffer); + if (ret < 0) + { + sndbg("as5048b_readb16 failed: %d\n", ret); + return ret; + } + + *mag = buffer; + sndbg("mag: %04x ret: %d\n", *mag, ret); + return ret; +} + +/**************************************************************************** + * Name: as5048b_readang + * + * Description: + * Read from the angle registers + * + ****************************************************************************/ + +static int as5048b_readang(FAR struct as5048b_dev_s *priv, FAR uint16_t *ang) +{ + uint16_t buffer; + int ret; + + ret = as5048b_readb16(priv, AS5048B_ANGHI_REG, AS5048B_ANGLO_REG, &buffer); + if (ret < 0) + { + sndbg("as5048b_readb16 failed: %d\n", ret); + return ret; + } + + *ang = buffer; + sndbg("ang: %04x ret: %d\n", *ang, ret); + return ret; +} + +/**************************************************************************** + * Name: as5048b_open + * + * Description: + * This function is called whenever the device is opened + * + ****************************************************************************/ + +static int as5048b_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: as5048b_close + * + * Description: + * This function is called whenever the device is closed + * + ****************************************************************************/ + +static int as5048b_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: as5048b_read + ****************************************************************************/ + +static ssize_t as5048b_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct as5048b_dev_s *priv = inode->i_private; + FAR uint16_t *ptr; + ssize_t nsamples; + ssize_t i; + int ret; + + /* How many samples were requested? */ + + ptr = (FAR uint16_t *)buffer; + nsamples = buflen / sizeof(*ptr); + + sndbg("buflen: %u nsamples: %d\n", buflen, nsamples); + + /* Get the requested number of samples */ + + for (i = 0; i < nsamples; i++) + { + uint16_t ang = 0; + + /* Read the next uint16_t angle value */ + + ret = as5048b_readang(priv, &ang); + if (ret < 0) + { + sndbg("as5048b_readang failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Save the angle value in the user buffer */ + + *ptr++ = ang; + } + + return nsamples * sizeof(*ptr); +} + +/**************************************************************************** + * Name: as5048b_write + ****************************************************************************/ + +static ssize_t as5048b_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: as5048b_ioctl + ****************************************************************************/ + +static int as5048b_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct as5048b_dev_s *priv = inode->i_private; + int ret = OK; + + switch (cmd) + { + /* Read from the zero position registers. Arg: uint16_t* pointer. */ + + case SNIOC_READZERO: + { + FAR uint16_t *ptr = (FAR uint16_t *)((uintptr_t)arg); + ret = as5048b_readzero(priv, ptr); + sndbg("zero: %04x ret: %d\n", *ptr, ret); + } + break; + + /* Write to the zero position registers. Arg: uint16_t value. */ + + case SNIOC_WRITEZERO: + ret = as5048b_writezero(priv, (uint16_t)arg); + sndbg("zero: %04x ret: %d\n", *(uint16_t *)arg, ret); + break; + + /* Read from the automatic gain control register. Arg: uint8_t* pointer. */ + + case SNIOC_READAGC: + { + FAR uint8_t *ptr = (FAR uint8_t *)((uintptr_t)arg); + ret = as5048b_readagc(priv, ptr); + sndbg("agc: %02x ret: %d\n", *ptr, ret); + } + break; + + /* Read from the diagnostics register. Arg: uint8_t* pointer. */ + + case SNIOC_READDIAG: + { + FAR uint8_t *ptr = (FAR uint8_t *)((uintptr_t)arg); + ret = as5048b_readdiag(priv, ptr); + sndbg("diag: %02x ret: %d\n", *ptr, ret); + } + break; + + /* Read from the magnitude registers. Arg: uint16_t* pointer. */ + + case SNIOC_READMAG: + { + FAR uint16_t *ptr = (FAR uint16_t *)((uintptr_t)arg); + ret = as5048b_readmag(priv, ptr); + sndbg("mag: %04x ret: %d\n", *ptr, ret); + } + break; + + default: + sndbg("Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: as5048b_register + * + * Description: + * Register the AS5048B character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, + * for example "/dev/angle0". + * i2c - An instance of the I2C interface to use to communicate + * with the AS5048B. + * addr - The I2C address of the AS5048B. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int as5048b_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, + uint8_t addr) +{ + FAR struct as5048b_dev_s *priv; + int ret; + + /* Initialize the device's structure */ + + priv = (FAR struct as5048b_dev_s *)kmm_malloc(sizeof(*priv)); + if (priv == NULL) + { + sndbg("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = addr; + + /* Register the character driver */ + + ret = register_driver(devpath, &g_as5048bfops, 0666, priv); + if (ret < 0) + { + sndbg("Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + return ret; +} + +#endif /* CONFIG_I2C && CONFIG_AS5048B */ diff --git a/drivers/sensors/lm92.c b/drivers/sensors/lm92.c new file mode 100644 index 00000000000..8d75e017713 --- /dev/null +++ b/drivers/sensors/lm92.c @@ -0,0 +1,622 @@ +/**************************************************************************** + * drivers/sensors/lm92.c + * Character driver for the TI LM92 Temperature Sensor + * + * Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2015 Alexandru Duru. All rights reserved. + * Author: Gregory Nutt + * Alexandru Duru + * + * 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 + +#if defined(CONFIG_I2C) && defined(CONFIG_LM92) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Centigrade to Fahrenheit conversion: F = 9*C/5 + 32 */ + +#define B16_9DIV5 (9 * 65536 / 5) +#define B16_32 (32 * 65536) + +/**************************************************************************** + * Private + ****************************************************************************/ + +struct lm92_dev_s +{ + FAR struct i2c_dev_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ + bool fahrenheit; /* true: temperature will be reported in Fahrenheit */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/* I2C Helpers */ + +static int lm92_readb16(FAR struct lm92_dev_s *priv, uint8_t regaddr, + FAR b16_t *regvalue); +static int lm92_writeb16(FAR struct lm92_dev_s *priv, uint8_t regaddr, + b16_t regval); +static int lm92_readtemp(FAR struct lm92_dev_s *priv, FAR b16_t *temp); +static int lm92_readconf(FAR struct lm92_dev_s *priv, FAR uint8_t *conf); +static int lm92_writeconf(FAR struct lm92_dev_s *priv, uint8_t conf); + +/* Character driver methods */ + +static int lm92_open(FAR struct file *filep); +static int lm92_close(FAR struct file *filep); +static ssize_t lm92_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t lm92_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int lm92_ioctl(FAR struct file *filep, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_lm92fops = +{ + lm92_open, + lm92_close, + lm92_read, + lm92_write, + 0, + lm92_ioctl +#ifndef CONFIG_DISABLE_POLL + , 0 +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ +/**************************************************************************** + * Name: lm92_readb16 + * + * Description: + * Read a 16-bit register (LM92_TEMP_REG, LM92_THYS_REG, LM92_TCRIT_REG, + * LM92_TLOW_REG, LM92_THIGH_REG, or LM92_ID_REG) + * + ****************************************************************************/ + +static int lm92_readb16(FAR struct lm92_dev_s *priv, uint8_t regaddr, + FAR b16_t *regvalue) +{ + uint8_t buffer[2]; + int ret; + + /* Write the register address */ + + I2C_SETADDRESS(priv->i2c, priv->addr, 7); + ret = I2C_WRITE(priv->i2c, ®addr, 1); + if (ret < 0) + { + sndbg("I2C_WRITE failed: %d\n", ret); + return ret; + } + + /* Restart and read 16 bits from the register (discarding 3) */ + + ret = I2C_READ(priv->i2c, buffer, 2); + if (ret < 0) + { + sndbg("I2C_READ failed: %d\n", ret); + return ret; + } + + /* Data format is: TTTTTTTT TTTTTxxx where TTTTTTTTTTTTT is a thirteen-bit, + * signed temperature value with LSB = 0.0625 degrees Centigrade. + */ + + *regvalue = (b16_t)((uint32_t)(buffer[0] & (1 << 7)) << 24 | + (uint32_t)(buffer[0] & ~(1 << 7)) << 17 | + (uint32_t)(buffer[1] & ~7) << 9); + sndbg("addr: %02x value: %08x ret: %d\n", regaddr, *regvalue, ret); + return OK; +} + +/**************************************************************************** + * Name: lm92_writeb16 + * + * Description: + * Write to a 16-bit register (LM92_TEMP_REG, LM92_THYS_REG, LM92_TCRIT_REG, + * LM92_TLOW_REG, LM92_THIGH_REG, or LM92_ID_REG) + * + ****************************************************************************/ + +static int lm92_writeb16(FAR struct lm92_dev_s *priv, uint8_t regaddr, + b16_t regval) +{ + uint8_t buffer[3]; + + sndbg("addr: %02x value: %08x\n", regaddr, regval); + + /* Set up a 3-byte message to send */ + + buffer[0] = regaddr; + buffer[1] = (uint8_t)(((uint32_t)regval & (1 << 31)) >> 24 | + ((uint32_t)regval & ~(1 << 31)) >> 17); + buffer[2] = (uint8_t)(((uint32_t)regval & ~(1 << 31)) >> 9); + + /* Write the register address followed by the data (no RESTART) */ + + I2C_SETADDRESS(priv->i2c, priv->addr, 7); + return I2C_WRITE(priv->i2c, buffer, 3); +} + +/**************************************************************************** + * Name: lm92_readtemp + * + * Description: + * Read the temperature register with special scaling (LM92_TEMP_REG) + * + ****************************************************************************/ + +static int lm92_readtemp(FAR struct lm92_dev_s *priv, FAR b16_t *temp) +{ + b16_t temp16; + int ret; + + /* Read the raw temperature data (b16_t) */ + + ret = lm92_readb16(priv, LM92_TEMP_REG, &temp16); + if (ret < 0) + { + sndbg("lm92_readb16 failed: %d\n", ret); + return ret; + } + + sndbg("Centigrade: %08x\n", temp16); + + /* Was Fahrenheit requested? */ + + if (priv->fahrenheit) + { + /* Centigrade to Fahrenheit conversion: F = 9*C/5 + 32 */ + + temp16 = b16mulb16(temp16, B16_9DIV5) + B16_32; + sndbg("Fahrenheit: %08x\n", temp16); + } + + *temp = temp16; + return OK; +} + +/**************************************************************************** + * Name: lm92_readconf + * + * Description: + * Read the 8-bit LM92 configuration register + * + ****************************************************************************/ + +static int lm92_readconf(FAR struct lm92_dev_s *priv, FAR uint8_t *conf) +{ + uint8_t buffer; + int ret; + + /* Write the configuration register address */ + + I2C_SETADDRESS(priv->i2c, priv->addr, 7); + + buffer = LM92_CONF_REG; + ret = I2C_WRITE(priv->i2c, &buffer, 1); + if (ret < 0) + { + sndbg("I2C_WRITE failed: %d\n", ret); + return ret; + } + + /* Restart and read 8 bits from the register */ + + ret = I2C_READ(priv->i2c, conf, 1); + sndbg("conf: %02x ret: %d\n", *conf, ret); + return ret; +} + +/**************************************************************************** + * Name: lm92_writeconf + * + * Description: + * Write to a 8-bit LM92 configuration register. + * + ****************************************************************************/ + +static int lm92_writeconf(FAR struct lm92_dev_s *priv, uint8_t conf) +{ + uint8_t buffer[2]; + + sndbg("conf: %02x\n", conf); + + /* Set up a 2-byte message to send */ + + buffer[0] = LM92_CONF_REG; + buffer[1] = conf; + + /* Write the register address followed by the data (no RESTART) */ + + I2C_SETADDRESS(priv->i2c, priv->addr, 7); + return I2C_WRITE(priv->i2c, buffer, 2); +} + +/**************************************************************************** + * Name: lm92_readid + * + * Description: + * Read the 16-bit LM92 identification register + * + ****************************************************************************/ + +static int lm92_readid(FAR struct lm92_dev_s *priv, FAR uint16_t *id) +{ + uint8_t buffer[2]; + uint8_t regaddr; + int ret; + + /* Write the identification register address */ + + I2C_SETADDRESS(priv->i2c, priv->addr, 7); + + regaddr = LM92_ID_REG; + ret = I2C_WRITE(priv->i2c, ®addr, 1); + if (ret < 0) + { + sndbg("I2C_WRITE failed: %d\n", ret); + return ret; + } + + /* Restart and read 16 bits from the register */ + + ret = I2C_READ(priv->i2c, buffer, 2); + if (ret < 0) + { + sndbg("I2C_READ failed: %d\n", ret); + return ret; + } + + *id = (uint16_t)buffer[0] << 8 | (uint16_t)buffer[1]; + sndbg("id: %04x ret: %d\n", *id, ret); + return OK; +} + +/**************************************************************************** + * Name: lm92_open + * + * Description: + * This function is called whenever the LM92 device is opened. + * + ****************************************************************************/ + +static int lm92_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: lm92_close + * + * Description: + * This function is called whenever the LM92 device is closed. + * + ****************************************************************************/ + +static int lm92_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: lm92_read + ****************************************************************************/ + +static ssize_t lm92_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct lm92_dev_s *priv = inode->i_private; + FAR b16_t *ptr; + ssize_t nsamples; + int i; + int ret; + + /* How many samples were requested to get? */ + + nsamples = buflen / sizeof(b16_t); + ptr = (FAR b16_t *)buffer; + + sndbg("buflen: %d nsamples: %d\n", buflen, nsamples); + + /* Get the requested number of samples */ + + for (i = 0; i < nsamples; i++) + { + b16_t temp = 0; + + /* Read the next b16_t temperature value */ + + ret = lm92_readtemp(priv, &temp); + if (ret < 0) + { + sndbg("lm92_readtemp failed: %d\n",ret); + return (ssize_t)ret; + } + + /* Save the temperature value in the user buffer */ + + *ptr++ = temp; + } + + return nsamples * sizeof(b16_t); +} + +/**************************************************************************** + * Name: lm92_write + ****************************************************************************/ + +static ssize_t lm92_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: lm92_ioctl + ****************************************************************************/ + +static int lm92_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct lm92_dev_s *priv = inode->i_private; + int ret = OK; + + switch (cmd) + { + /* Read from the configuration register. Arg: uint8_t* pointer */ + + case SNIOC_READCONF: + { + FAR uint8_t *ptr = (FAR uint8_t *)((uintptr_t)arg); + ret = lm92_readconf(priv, ptr); + sndbg("conf: %02x ret: %d\n", *ptr, ret); + } + break; + + /* Write to the configuration register. Arg: uint8_t value */ + + case SNIOC_WRITECONF: + ret = lm92_writeconf(priv, (uint8_t)arg); + sndbg("conf: %02x ret: %d\n", *(uint8_t *)arg, ret); + break; + + /* Shutdown the LM92. Arg: None */ + + case SNIOC_SHUTDOWN: + { + uint8_t conf; + ret = lm92_readconf(priv, &conf); + if (ret == OK) + { + ret = lm92_writeconf(priv, conf | LM92_CONF_SHUTDOWN); + } + + sndbg("conf: %02x ret: %d\n", conf | LM92_CONF_SHUTDOWN, ret); + } + break; + + /* Powerup the LM92. Arg: None */ + + case SNIOC_POWERUP: + { + uint8_t conf; + ret = lm92_readconf(priv, &conf); + if (ret == OK) + { + ret = lm92_writeconf(priv, conf & ~LM92_CONF_SHUTDOWN); + } + + sndbg("conf: %02x ret: %d\n", conf & ~LM92_CONF_SHUTDOWN, ret); + } + break; + + /* Report samples in Fahrenheit. Arg: None */ + + case SNIOC_FAHRENHEIT: + priv->fahrenheit = true; + sndbg("Fahrenheit\n"); + break; + + /* Report samples in Centigrade. Arg: None */ + + case SNIOC_CENTIGRADE: + priv->fahrenheit = false; + sndbg("Centigrade\n"); + break; + + /* Read THYS temperature register. Arg: b16_t* pointer */ + + case SNIOC_READTHYS: + { + FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg); + ret = lm92_readb16(priv, LM92_THYS_REG, ptr); + sndbg("THYS: %08x ret: %d\n", *ptr, ret); + } + break; + + /* Write THYS temperature register. Arg: b16_t value */ + + case SNIOC_WRITETHYS: + ret = lm92_writeb16(priv, LM92_THYS_REG, (b16_t)arg); + sndbg("THYS: %08x ret: %d\n", (b16_t)arg, ret); + break; + + /* Read TCRIT temperature register. Arg: b16_t* pointer */ + + case SNIOC_READTCRIT: + { + FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg); + ret = lm92_readb16(priv, LM92_TCRIT_REG, ptr); + sndbg("TCRIT: %08x ret: %d\n", *ptr, ret); + } + break; + + /* Write TCRIT temperature register. Arg: b16_t value */ + + case SNIOC_WRITETCRIT: + ret = lm92_writeb16(priv, LM92_TCRIT_REG, (b16_t)arg); + sndbg("TCRIT: %08x ret: %d\n", (b16_t)arg, ret); + break; + + /* Read TLOW temperature register. Arg: b16_t* pointer */ + + case SNIOC_READTLOW: + { + FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg); + ret = lm92_readb16(priv, LM92_TLOW_REG, ptr); + sndbg("TLOW: %08x ret: %d\n", *ptr, ret); + } + break; + + /* Write TLOW temperature register. Arg: b16_t value */ + + case SNIOC_WRITETLOW: + ret = lm92_writeb16(priv, LM92_TLOW_REG, (b16_t)arg); + sndbg("TLOW: %08x ret: %d\n", (b16_t)arg, ret); + break; + + /* Read THIGH temperature register. Arg: b16_t* pointer */ + + case SNIOC_READTHIGH: + { + FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg); + ret = lm92_readb16(priv, LM92_THIGH_REG, ptr); + sndbg("THIGH: %08x ret: %d\n", *ptr, ret); + } + break; + + /* Write THIGH temperature register. Arg: b16_t value */ + + case SNIOC_WRITETHIGH: + ret = lm92_writeb16(priv, LM92_THIGH_REG, (b16_t)arg); + sndbg("THIGH: %08x ret: %d\n", (b16_t)arg, ret); + break; + + /* Read from the identification register. Arg: uint16_t* pointer */ + + case SNIOC_READID: + { + FAR uint16_t *ptr = (FAR uint16_t *)((uintptr_t)arg); + ret = lm92_readid(priv, ptr); + sndbg("id: %04x ret: %d\n", *ptr, ret); + } + break; + + default: + sndbg("Unrecognized cmd: %d\n", cmd); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lm92_register + * + * Description: + * Register the LM92 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/temp0". + * i2c - An instance of the I2C interface to use to communicate + * with the LM92. + * addr - The I2C address of the LM92. The base I2C address of the LM92 + * is 0x48. Bits 0-2 can be controlled to get 4 unique addresses + * from 0x48 through 0x4b. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int lm92_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, + uint8_t addr) +{ + FAR struct lm92_dev_s *priv; + int ret; + + /* Initialize the LM92 device structure */ + + priv = (FAR struct lm92_dev_s *)kmm_malloc(sizeof(struct lm92_dev_s)); + if (!priv) + { + sndbg("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = addr; + priv->fahrenheit = false; + + /* Register the character driver */ + + ret = register_driver(devpath, &g_lm92fops, 0666, priv); + if (ret < 0) + { + sndbg("Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + return ret; +} +#endif /* CONFIG_I2C && CONFIG_LM92 */ diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 6bef9b56948..488c08c2513 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -5,6 +5,23 @@ if SPI +config SPI_SLAVE + bool "SPI slave" + default n + ---help--- + Enable support for SPI slave features + +if SPI_SLAVE + +config SPI_SLAVE_DMA + bool "SPI slave DMA" + default n + depends on ARCH_DMA && EXPERIMENTAL + ---help--- + Enable support for DMA data transfers (not yet implemented). + +endif + config SPI_OWNBUS bool "SPI single device" default n diff --git a/include/errno.h b/include/errno.h index 08f76e4d321..f215269c731 100644 --- a/include/errno.h +++ b/include/errno.h @@ -379,11 +379,11 @@ #define ECANCELED_STR "Operation cancelled" /************************************************************************ - * Type Declarations + * Public Type Definitions ************************************************************************/ /************************************************************************ - * Global Function Prototypes + * Public Function Prototypes ************************************************************************/ #undef EXTERN diff --git a/include/mqueue.h b/include/mqueue.h index 6719cbd42f8..b1f2abaea38 100644 --- a/include/mqueue.h +++ b/include/mqueue.h @@ -51,7 +51,7 @@ #define MQ_NONBLOCK O_NONBLOCK /******************************************************************************** - * Global Type Declarations + * Public Type Declarations ********************************************************************************/ /* Message queue attributes */ diff --git a/include/nuttx/can.h b/include/nuttx/can.h index 98ce0e416cd..3235b9de544 100644 --- a/include/nuttx/can.h +++ b/include/nuttx/can.h @@ -1,7 +1,7 @@ /************************************************************************************ * include/nuttx/can.h * - * Copyright (C) 2008, 2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2008, 2009, 2011-2012, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,7 @@ #include #include +#include #ifdef CONFIG_CAN @@ -60,6 +61,8 @@ * CONFIG_STM32_CAN2 must also be defined) * CONFIG_CAN_EXTID - Enables support for the 29-bit extended ID. Default * Standard 11-bit IDs. + * CONFIG_CAN_FD - Enable support for CAN FD mode. For the upper half driver, this + * just means handling encoded DLC values (for values of DLC > 9). * CONFIG_CAN_FIFOSIZE - The size of the circular buffer of CAN messages. * Default: 8 * CONFIG_CAN_NPENDINGRTR - The size of the list of pending RTR requests. @@ -88,7 +91,63 @@ # define CONFIG_CAN_NPENDINGRTR 255 #endif -/* Convenience macros */ +/* Ioctl Commands *******************************************************************/ +/* Ioctl commands supported by the upper half CAN driver. + * + * CANIOC_RTR: + * Description: Send the remote transmission request and wait for the response. + * Argument: A reference to struct canioc_rtr_s + * + * Ioctl commands that may or may not be supported by the lower half CAN driver. + * + * CANIOC_ADD_STDFILTER: + * Description: Add an address filter for a standard 11 bit address. + * Argument: A reference to struct canioc_stdfilter_s + * Returned Value: A non-negative filter ID is returned on success. + * Otherwise -1 (ERROR) is returned with the errno + * variable set to indicate the nature of the error. + * Dependencies: Requires CONFIG_CAN_EXID *not* defined + * + * CANIOC_ADD_EXTFILTER: + * Description: Add an address filter for a extended 29 bit address. + * Argument: A reference to struct canioc_extfilter_s + * Returned Value: A non-negative filter ID is returned on success. + * Otherwise -1 (ERROR) is returned with the errno + * variable set to indicate the nature of the error. + * Dependencies: Requires CONFIG_CAN_EXID=y + * + * CANIOC_DEL_STDFILTER: + * Description: Remove an address filter for a standard 11 bit address. + * Argument: The filter index previously returned by the + * CANIOC_ADD_STDFILTER command + * Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + * Dependencies: Requires CONFIG_CAN_EXID *not* defined + * + * CANIOC_DEL_EXTFILTER: + * Description: Remove an address filter for a standard 29 bit address. + * Argument: The filter index previously returned by the + * CANIOC_ADD_EXTFILTER command + * Returned Value: Zero (OK) is returned on success. Otherwise -1 (ERROR) + * is returned with the errno variable set to indicate the + * nature of the error. + * Dependencies: Requires CONFIG_CAN_EXID=y + */ + +#define CANIOC_RTR _CANIOC(1) +#define CANIOC_ADD_STDFILTER _CANIOC(2) +#define CANIOC_ADD_EXTFILTER _CANIOC(3) +#define CANIOC_DEL_STDFILTER _CANIOC(4) +#define CANIOC_DEL_EXTFILTER _CANIOC(5) + +/* CANIOC_USER: Device specific ioctl calls can be supported with cmds greater + * than this value + */ + +#define CANIOC_USER _CANIOC(6) + +/* Convenience macros ***************************************************************/ #define dev_reset(dev) dev->cd_ops->co_reset(dev) #define dev_setup(dev) dev->cd_ops->co_setup(dev) @@ -101,50 +160,57 @@ #define dev_txready(dev) dev->cd_ops->co_txready(dev) #define dev_txempty(dev) dev->cd_ops->co_txempty(dev) -/* CAN message support */ +/* CAN message support **************************************************************/ -#define CAN_MAXDATALEN 8 -#define CAN_MAX_MSGID 0x07ff +#ifdef CONFIG_CAN_FD +# define CAN_MAXDATALEN 64 +#else +# define CAN_MAXDATALEN 8 +#endif + +#define CAN_MAX_STDMSGID 0x07ff #define CAN_MAX_EXTMSGID 0x1fffffff #define CAN_MSGLEN(nbytes) (sizeof(struct can_msg_s) - CAN_MAXDATALEN + (nbytes)) -/* Built-in ioctl commands - * - * CANIOCTL_RTR: Send the remote transmission request and wait for the response. +/* CAN filter support ***************************************************************/ +/* Some CAN hardware supports a notion of prioritizing messages that match filters. + * Only two priority levels are currently supported and are encoded as defined + * below: */ -#define CANIOCTL_RTR 1 /* Argument is a reference to struct canioctl_rtr_s */ +#define CAN_MSGPRIO_LOW 0 +#define CAN_MSGPRIO_HIGH 1 -/* CANIOCTL_USER: Device specific ioctl calls can be supported with cmds greater - * than this value - */ +/* Filter type. Not all CAN hardware will support all filter types. */ -#define CANIOCTL_USER 2 +#define CAN_FILTER_MASK 0 /* Address match under a mask */ +#define CAN_FILTER_DUAL 1 /* Dual address match */ +#define CAN_FILTER_RANGE 2 /* Match a range of addresses */ /************************************************************************************ * Public Types ************************************************************************************/ -/* CAN-message Format (without Extended ID suppport) +/* CAN-message Format (without Extended ID support) * * One based CAN-message is represented with a maximum of 10 bytes. A message is * composed of at least the first 2 bytes (when there are no data bytes present). * * Bytes 0-1: Hold a 16-bit value in host byte order * Bits 0-3: Data Length Code (DLC) - * Bit 4: Remote Tranmission Request (RTR) + * Bit 4: Remote Transmission Request (RTR) * Bits 5-15: The 11-bit CAN identifier * * Bytes 2-9: CAN data * - * CAN-message Format (with Extended ID suppport) + * CAN-message Format (with Extended ID support) * * One CAN-message consists of a maximum of 13 bytes. A message is composed of at * least the first 5 bytes (when there are no data bytes). * * Bytes 0-3: Hold 11- or 29-bit CAN ID in host byte order * Byte 4: Bits 0-3: Data Length Code (DLC) - * Bit 4: Remote Tranmission Request (RTR) + * Bit 4: Remote Transmission Request (RTR) * Bit 5: Extended ID indication * Bits 6-7: Unused * Bytes 5-12: CAN data @@ -158,7 +224,7 @@ #ifdef CONFIG_CAN_EXTID struct can_hdr_s { - uint32_t ch_id; /* 11- or 29-bit ID (3-bits unsed) */ + uint32_t ch_id; /* 11- or 29-bit ID (3-bits unused) */ uint8_t ch_dlc : 4; /* 4-bit DLC */ uint8_t ch_rtr : 1; /* RTR indication */ uint8_t ch_extid : 1; /* Extended ID indication */ @@ -167,7 +233,7 @@ struct can_hdr_s #else struct can_hdr_s { - uint16_t ch_dlc : 4; /* 4-bit DLC */ + uint16_t ch_dlc : 4; /* 4-bit DLC. May be encoded in CAN_FD mode. */ uint16_t ch_rtr : 1; /* RTR indication */ uint16_t ch_id : 11; /* 11-bit standard ID */ } packed_struct; @@ -296,12 +362,34 @@ struct can_dev_s /* Structures used with ioctl calls */ -struct canioctl_rtr_s +struct canioc_rtr_s { uint16_t ci_id; /* The 11-bit ID to use in the RTR message */ FAR struct can_msg_s *ci_msg; /* The location to return the RTR response */ }; +#ifdef CONFIG_CAN_EXTID +struct canioc_extfilter_s +{ + uint32_t xf_id1; /* 29-bit ID. For dual match or for the + * lower address in a range of addresses */ + uint32_t xf_id2; /* 29-bit ID. For dual match, address mask + * or for upper address in address range */ + uint8_t xf_type; /* See CAN_FILTER_* definitions */ + uint8_t xf_prio; /* See CAN_MSGPRIO_* definitions */ +}; +#else +struct canioc_stdfilter_s +{ + uint16_t sf_id1; /* 11-bit ID. For dual match or for the + * lower address in a range of addresses */ + uint16_t sf_id2; /* 11-bit ID. For dual match, address mask + * or for upper address in address range */ + uint8_t sf_type; /* See CAN_FILTER_* definitions */ + uint8_t sf_prio; /* See CAN_MSGPRIO_* definitions */ +}; +#endif + /************************************************************************************ * Public Data ************************************************************************************/ diff --git a/include/nuttx/fs/ioctl.h b/include/nuttx/fs/ioctl.h index 65bc85b45bd..f047d389068 100644 --- a/include/nuttx/fs/ioctl.h +++ b/include/nuttx/fs/ioctl.h @@ -76,7 +76,8 @@ #define _PIPEBASE (0x1700) /* FIFO/pipe ioctl commands */ #define _RTCBASE (0x1800) /* RTC ioctl commands */ #define _RELAYBASE (0x1900) /* Relay devices ioctl commands */ -#define _BOARDBASE (0x1a00) /* boardctl commands */ +#define _CANBASE (0x1a00) /* CAN ioctl commands */ +#define _BOARDBASE (0x1b00) /* boardctl ioctl commands */ /* Macros used to manage ioctl commands */ @@ -348,6 +349,12 @@ #define _RELAYIOCVALID(c) (_IOC_TYPE(c)==_RELAYBASE) #define _RELAYIOC(nr) _IOC(_RELAYBASE,nr) +/* CAN driver ioctl definitions *********************************************/ +/* (see nuttx/can.h */ + +#define _CANIOCVALID(c) (_IOC_TYPE(c)==_CANBASE) +#define _CANIOC(nr) _IOC(_CANBASE,nr) + /* boardctl() command definitions *******************************************/ #define _BOARDIOCVALID(c) (_IOC_TYPE(c)==_BOARDBASE) diff --git a/include/nuttx/net/slip.h b/include/nuttx/net/slip.h index 020f8e302f1..1fb2e46514c 100644 --- a/include/nuttx/net/slip.h +++ b/include/nuttx/net/slip.h @@ -48,8 +48,38 @@ #ifdef CONFIG_NET_SLIP /**************************************************************************** - * Public Type Definitions + * Pre-processor Definitions ****************************************************************************/ +/* Configuration ***********************************************************/ +/* Dependencies: + * + * CONFIG_NET_NOINTS - Required. + * CONFIG_NET_MULTIBUFFER - Required. + * + * SLIP Configuration: + * + * CONFIG_NET_SLIP - Enables building of the SLIP driver + * CONFIG_NET_SLIP_STACKSIZE - Provides the stack size for SLIP RX and TX + * threads. Default: 2048 + * CONFIG_NET_SLIP_DEFPRIO - Provides the priority for SLIP RX and TX + * threads. Default 128. + * CONFIG_NET_NET_SLIP_MTU - Provides the size of the SLIP packet buffers. + * Default 296 + * + * The Linux slip module hard-codes its MTU size to 296 (40 bytes for the + * IP+TPC headers plus 256 bytes of data). So you might as well set + * CONFIG_NET_SLIP_MTU to 296 as well. + * + * There may be an issue with this setting, however. I see that Linux + * uses a MTU of 296 and window of 256, but actually only sends 168 bytes + * of data: 40 + 128. I believe that is to allow for the 2x worst cast + * packet expansion. Ideally we would like to advertise the 256 MSS, + * but restrict transfers to 128 bytes (possibly by modifying the + * tcp_mss() macro). + * + * CONFIG_NET_SLIP_NINTERFACES determines the number of physical interfaces + * that will be supported. + */ /**************************************************************************** * Public Data @@ -73,10 +103,12 @@ extern "C" * Description: * Instantiate a SLIP network interface. * - * Parameters: - * intf - In the case where there are multiple SLIP interfaces, this value - * identifies which is to be initialized. The network name will be, - * for example, "/dev/slip5" for intf == 5 + * Input Parameters: + * intf - In the case where there are multiple SLIP interfaces, this + * value identifies which is to be initialized. The number of + * possible SLIP interfaces is determined by + * devname - This is the path to the serial device that will support SLIP. + * For example, this might be "/dev/ttyS1" * * Returned Value: * OK on success; Negated errno on failure. diff --git a/include/nuttx/sensors/as5048b.h b/include/nuttx/sensors/as5048b.h new file mode 100644 index 00000000000..6e8c0c3aaed --- /dev/null +++ b/include/nuttx/sensors/as5048b.h @@ -0,0 +1,136 @@ +/**************************************************************************** + * include/nuttx/sensors/as5048b.h + * + * Copyright (C) 2015 Alexandru Duru. All rights reserved. + * Author: Alexandru Duru + * + * 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_SENSORS_AS5048B +#define __INCLUDE_NUTTX_SENSORS_AS5048B + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************ + * Prerequisites: + * + * CONFIG_I2C + * Enables support for I2C drivers + * CONFIG_AS5048B + * Enables support for the AS5048B driver + */ + +/* IOCTL Commands ***********************************************************/ + +#define SNIOC_READZERO _SNIOC(0x0001) /* Arg: uint16_t* pointer */ +#define SNIOC_WRITEZERO _SNIOC(0x0002) /* Arg: uint16_t value */ +#define SNIOC_READAGC _SNIOC(0x0004) /* Arg: uint8_t* pointer */ +#define SNIOC_READDIAG _SNIOC(0x0005) /* Arg: uint8_t* pointer */ +#define SNIOC_READMAG _SNIOC(0x0006) /* Arg: uint16_t* pointer */ + +/* Resolution ***************************************************************/ + +#define AS5048B_MAX 0x3fff /* Maximum value (14 bits) */ + +/* Register Definitions *****************************************************/ +/* Register Addresses */ + +#define AS5048B_PROG_REG 0x03 /* Programming Control Register */ +#define AS5048B_ADDR_REG 0x15 /* I2C Slave Address Register */ +#define AS5048B_ZEROLO_REG 0x16 /* Zero Position Register Bits 0 to 5 */ +#define AS5048B_ZEROHI_REG 0x17 /* Zero Position Register Bits 6 to 13 */ +#define AS5048B_AGC_REG 0xfa /* Automatic Gain Control Register */ +#define AS5048B_DIAG_REG 0xfb /* Diagnostics Register */ +#define AS5048B_MAGLO_REG 0xfc /* Magnitude Register Bits 0 to 5 */ +#define AS5048B_MAGHI_REG 0xfd /* Magnitude Register Bits 6 to 13 */ +#define AS5048B_ANGLO_REG 0xfe /* Angle Register Bits 0 to 5 */ +#define AS5048B_ANGHI_REG 0xff /* Angle Register Bits 6 to 13 */ + +/* Programming Control Register Bit Definitions */ + +#define AS5048B_PROG_ENABLE (1 << 0) +#define AS5048B_PROG_BURN (1 << 3) +#define AS5048B_PROG_VERIFY (1 << 6) + +/* Diagnostics Register Bit Definitions */ + +#define AS5048B_DIAG_OCF (1 << 0) /* Offset Compensation Finished */ +#define AS5048B_DIAG_COF (1 << 1) /* Cordic Overflow */ +#define AS5048B_DIAG_COMPLOW (1 << 2) /* High Magnetic Field */ +#define AS5048B_DIAG_COMPHIGH (1 << 3) /* Low Magnetic Field */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: as5048b_register + * + * Description: + * Register the AS5048B character device as 'devpath'. + * + * Input Parameters: + * devpath - The full path to the driver to register, + * for example "/dev/angle0". + * i2c - An instance of the I2C interface to use to communicate + * with the AS5048B. + * addr - The I2C address of the AS5048B. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int as5048b_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, + uint8_t addr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_SENSORS_AS5048B */ diff --git a/include/nuttx/sensors/lm92.h b/include/nuttx/sensors/lm92.h new file mode 100644 index 00000000000..7db294dfdf0 --- /dev/null +++ b/include/nuttx/sensors/lm92.h @@ -0,0 +1,150 @@ +/**************************************************************************** + * include/nuttx/sensors/lm92.h + * + * Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015 Alexandru Duru. All rights reserved. + * Author: Gregory Nutt + * Alexandru Duru + * + * 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_SENSORS_LM92_H +#define __INCLUDE_NUTTX_SENSORS_LM92_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************ + * CONFIG_I2C - Enables support for I2C drivers + * CONFIG_LM92 - Enables support for the LM92 driver + */ + +#define CONFIG_LM92_BASEADDR 0x48 +#define CONFIG_LM92_ADDR0 (CONFIG_LM92_BASEADDR + 0) +#define CONFIG_LM92_ADDR1 (CONFIG_LM92_BASEADDR + 1) +#define CONFIG_LM92_ADDR2 (CONFIG_LM92_BASEADDR + 2) +#define CONFIG_LM92_ADDR3 (CONFIG_LM92_BASEADDR + 3) + +/* IOCTL Commands ***********************************************************/ + +#define SNIOC_READCONF _SNIOC(0x0001) /* Arg: uint8_t* pointer */ +#define SNIOC_WRITECONF _SNIOC(0x0002) /* Arg: uint8_t value */ +#define SNIOC_SHUTDOWN _SNIOC(0x0003) /* Arg: None */ +#define SNIOC_POWERUP _SNIOC(0x0004) /* Arg: None */ +#define SNIOC_FAHRENHEIT _SNIOC(0x0005) /* Arg: None */ +#define SNIOC_CENTIGRADE _SNIOC(0x0006) /* Arg: None */ +#define SNIOC_READTHYS _SNIOC(0x0007) /* Arg: b16_t* pointer */ +#define SNIOC_WRITETHYS _SNIOC(0x0008) /* Arg: b16_t value */ +#define SNIOC_READTCRIT _SNIOC(0x0009) /* Arg: b16_t* pointer */ +#define SNIOC_WRITETCRIT _SNIOC(0x000a) /* Arg: b16_t value */ +#define SNIOC_READTLOW _SNIOC(0x000b) /* Arg: b16_t* pointer */ +#define SNIOC_WRITETLOW _SNIOC(0x000c) /* Arg: b16_t value */ +#define SNIOC_READTHIGH _SNIOC(0x000d) /* Arg: b16_t* pointer */ +#define SNIOC_WRITETHIGH _SNIOC(0x000e) /* Arg: b16_t value */ +#define SNIOC_READID _SNIOC(0x000f) /* Arg: uint16_t* pointer */ + +/* LM92 Register Definitions ***********************************************/ +/* LM92 Register Addresses */ + +#define LM92_TEMP_REG 0x00 /* Temperature Register */ +#define LM92_CONF_REG 0x01 /* Configuration Register */ +#define LM92_THYS_REG 0x02 /* Temperature Register */ +#define LM92_TCRIT_REG 0x03 /* Critical Temperature Register */ +#define LM92_TLOW_REG 0x04 /* Low Temperature Register */ +#define LM92_THIGH_REG 0x05 /* High Temperature Register */ +#define LM92_ID_REG 0x07 /* Manufacturer's Identification Register */ + +/* Configuration Register Bit Definitions */ + +#define LM92_CONF_SHUTDOWN (1 << 0) /* Bit 0: Put LM92 goes in low power shutdown mode */ +#define LM92_CONF_INTMODE (1 << 1) /* Bit 1: 0=Comparator 1=Interrupt mode */ +#define LM92_CONF_TCRITPOLARITY (1 << 2) /* Bit 2: 0=Active low 1=Active high */ +#define LM92_CONF_INTPOLARITY (1 << 3) /* Bit 3: 0=Active low 1=Active high */ +#define LM92_CONF_FAULTQ (1 << 4) /* Bit 4: 0=Disabled 1=Enabled */ + +/* NOTE: When temperature values are read, they are returned as b16_t, fixed + * precision integer values (see include/fixedmath.h). + */ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: lm92_register + * + * Description: + * Register the LM92 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/temp0". + * i2c - An instance of the I2C interface to use to communicate + * with the LM92. + * addr - The I2C address of the LM92. The base I2C address of the LM92 + * is 0x48. Bits 0-2 can be controlled to get 4 unique addresses + * from 0x48 through 0x4b. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int lm92_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, + uint8_t addr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_SENSORS_LM92_H */ diff --git a/include/nuttx/spi/slave.h b/include/nuttx/spi/slave.h new file mode 100644 index 00000000000..f57493fa53b --- /dev/null +++ b/include/nuttx/spi/slave.h @@ -0,0 +1,474 @@ +/**************************************************************************** + * include/nuttx/spi/slave.h + * + * Copyright(C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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_SPI_SLAVE_H +#define __INCLUDE_NUTTX_SPI_SLAVE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* CONFIG_SPI_SLAVE - Enable support for SPI slave features + * CONFIG_SPI_SLAVE_DMA - Enable support for DMA data transfers (not + * implemented in initial version). + */ + +/* Access macros ************************************************************/ + +/**************************************************************************** + * Name: SPI_SCTRLR_BIND + * + * Description: + * Bind the SPI slave device interface to the SPI slave controller + * interface and configure the SPI interface. Upon return, the SPI + * slave controller driver is fully operational and ready to perform + * transfers. + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * sdev - SPI slave device interface instance + * mode - The SPI mode requested + * nbits - The number of bits requests. + * If value is greater > 0 then it implies MSB first + * If value is below < 0, then it implies LSB first with -nbits + * + * Returned Value: + * none + * + ****************************************************************************/ + +#define SPI_SCTRLR_BIND(c,d,m,n) ((c)->ops->bind(c,d,m,n)) + +/**************************************************************************** + * Name: SPI_SCTRLR_UNBIND + * + * Description: + * Un-bind the SPI slave device interface from the SPI slave controller + * interface. Reset the SPI interface and restore the SPI slave + * controller driver to its initial state, + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * + * Returned Value: + * none + * + ****************************************************************************/ + +#define SPI_SCTRLR_UNBIND(c) ((c)->ops->unbind(c)) + +/**************************************************************************** + * Name: SPI_SCTRLR_ENQUEUE + * + * Description: + * Enqueue the next value to be shifted out from the interface. This adds + * the word the controller driver for a subsequent transfer but has no + * effect on any in-process or currently "committed" transfers + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * data - Command/data mode data value to be shifted out. The width of + * the data must be the same as the nbits parameter previously + * provided to the bind() methods. + * + * Returned Value: + * Zero if the word was successfully queue; A negated errno valid is + * returned on any failure to enqueue the word (such as if the queue is + * full). + * + ****************************************************************************/ + +#define SPI_SCTRLR_ENQUEUE(c,v) ((c)->ops->enqueue(c,v)) + +/**************************************************************************** + * Name: SPI_SCTRLR_QFULL + * + * Description: + * Return true if the queue is full or false if there is space to add an + * additional word to the queue. + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * + * Returned Value: + * true if the output wueue is full + * + ****************************************************************************/ + +#define SPI_SCTRLR_QFULL(c) ((c)->ops->qfull(c)) + +/**************************************************************************** + * Name: SPI_SCTRLR_QFLUSH + * + * Description: + * Discard all saved values in the output queue. On return from this + * function the output queue will be empty. Any in-progress or otherwise + * "committed" output values may not be flushed. + * + * Input Parameters: + * sctrlr - SPI slave controller interface instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +#define SPI_SCTRLR_QFLUSH(c) ((c)->ops->qflush(c)) + +/**************************************************************************** + * Name: SPI_SDEV_SELECT + * + * Description: + * This is a SPI device callback that used when the SPI device controller + * driver detects any change in the chip select pin. + * + * Input Parameters: + * sdev - SPI device interface instance + * selected - True: chip select is low (selected); + * + * Returned Value: + * none + * + * Assumptions: + * May be called from an interrupt handler. + * + ****************************************************************************/ + +#define SPI_SDEV_SELECT(d,s) ((c)->ops->select(d,s)) + +/**************************************************************************** + * Name: SPI_SDEV_CMDDATA + * + * Description: + * This is a SPI device callback that used when the SPI device controller + * driver detects any change command/data condition. + * + * Normally only LCD devices distinguish command and data. For devices + * that do not distinguish between command and data, this method may be + * a stub.; For devices that do make that distinction, they should treat + * all subsequent calls to enqueue() or rece() appropriately for the + * current command/data selection. + * + * Input Parameters: + * sdev - SPI device interface instance + * data - True: Data is selected + * + * Returned Value: + * none + * + * Assumptions: + * May be called from an interrupt handler. + * + ****************************************************************************/ + +#define SPI_SDEV_CMDDATA(d,i) ((d)->ops->cmddata(d,i)) + +/**************************************************************************** + * Name: SPI_SDEV_GETDATA + * + * Description: + * This is a SPI device callback that used when the SPI device controller + * requires data be shifted out at the next leading clock edge. This + * is necessary to "prime the pump" so that the SPI controller driver + * can keep pace with the shifted-in data. + * + * The SPI controller driver will prime for both command and data + * transfers as determined by a preceding call to the device cmddata() + * method. Normally only LCD devices distinguish command and data. + * + * Input Parameters: + * sdev - SPI device interface instance + * + * Returned Value: + * The next data value to be shifted out + * + * Assumptions: + * May be called from an interrupt handler. + * + ****************************************************************************/ + +#define SPI_SDEV_GETDATA(d) ((d)->ops->getdata(d)) + +/**************************************************************************** + * Name: SPI_SDEV_RECEIVE + * + * Description: + * This is a SPI device callback that used when the SPI device controller + * receives a new value shifted in and requires the next value to be + * shifted out. Notice that these values my be out of synchronization by + * several words. + * + * Input Parameters: + * sdev - SPI device interface instance + * data - The last command/data value that was shifted in + * + * Returned Value: + * None + * + * Assumptions: + * May be called from an interrupt handler. + * + ****************************************************************************/ + +#define SPI_SDEV_RECEIVE(d,v) ((d)->ops->receive(d,v)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* There are two interfaces defined for the implementation of SPI slave: + * + * 1) struct spi_sctrlr_s: Defines one interface between the SPI + * slave device and the SPI slave controller hardware. This interface + * is implemented by the SPI slave device controller lower-half driver + * and is provided to the the SPI slave device driver when that driver + * is initialized. That SPI slave device initialization function has + * the prototype: + * + * FAR struct spi_sctrlr_s *up_spi_slave_initialize(int port); + * + * Given an SPI port number, this function returns an instance of the + * SPI slave controller interface. + * + * 2) struct spi_sdev_s: Defines the second interface between the SPI + * slave device and the SPI slave controller hardware. This interface + * is implemented by the SPI slave device. The slave device passes this + * interface to the struct spi_sctrlr_s during initialization + * be calling the bind() method of the struct spi_sctrlr_s + * interface. + * + * The basic initialization steps are: + * + * 1) Board-specific logic calls board- or chip-specific logic to create an + * instance of the SPI slave controller interface, struct spi_sctrlr_s. + * + * 2) Board-specific logic then calls up_dev_initialize() to initialize + * the SPI slave device. The board-specific logic passes the instance + * of struct spi_sctrlr_s to support the initialization. + * + * 3) The SPI slave device driver creates and initializes an instance of + * struct spi_sdev_s; it passes this instance to the bind() method of + * of the SPI slave controller interface. + * + * 4) The SPI slave controller will (1) call the slaved device's select() + * and cmddata() methods to indicate the initial state of the chip select + * and any command/data selection, then (2) call the slave device's + * getdata() method to get the value that will be shifted out the SPI + * clock is detected. The kind of data returned the getdata() method + * may be contingent on the current command/data setting reported the + * device cmddata() method. The driver may enqueue additional words + * to be shifted out at any time by The calling the SPI slave + * controller's enqueue() method. + * + * 5) Upon return from the bind method, the SPI slave controller will be + * fully "armed" and ready to begin normal SPI data transfers. + * + * A typical (non-DMA) data transfer proceeds as follows: + * + * 1) Internally, the SPI slave driver detects that the SPI chip select + * has gone low, selecting this device for data transfer. The SPI + * slave controller will notify the slave device by called its + * select() method. + * + * 2) If a change in the command/data state changes any time before, + * during, or after the chip is selected, that new command/data state + * will reported to the device driver via the cmddata() method. + * + * 3) As the first word is shifted in, the command or data word obtained + * by the initial call to getdata() will be shifted out. As soon as + * the clock is detected, the SPI controller driver will call the + * getdata() method again to get a default second word to be shifted + * out. NOTES: (1) the SPI slave device has only one word in bit + * times to provide this value! (2) The SPI device probably cannot + * really output anything meaning until it receives a decodes the + * first word received from the master. + * + * 4) When the first word from the master is shifted in, the SPI + * controller driver will call the device's receive() method to + * provide the master with the command word that was just shifted + * in. + * + * For the case of bi-directional data transfer or of a transfer of + * data from the SPI device to the master, the SPI device driver + * should call the controller's enqueue() method to provide the next + * value(s) to be shifted out. If the SPI device responds with this + * value before clocking begins for the next word, that that value + * will be used. Otherwise, the value obtained from getdata() in + * step 3 will be shifted out. + * + * 5) The SPI device's receive() method will be called in a similar + * way after each subsequent word is clocked in. + * + * For the case of bi-directional data transfer or of a uni-directional + * transfer of data from the SPI device to the master, the SPI device + * driver can call the enqueue() methods as it has new data to be shifted + * out. The goal of the SPI device driver for this kind of transfer is + * to supply valid output data at such a rate that data underruns do not + * occur. In the event of a data underrun, the SPI slave controller + * driver will fallback to the default output value obtained from the + * last getdata() call. + * + * The SPI device driver can detect if there is space to enqueue + * additional data by calling the qfull() method. + * + * For the case of uni-directional transfer of data from the master to + * the SPI device, there is no need to call the enqueue() method at all; + * the value that is shifted out is not important that fallback behavior + * is suficient. + * + * 6) The activity of 5) will continue until the master raises the chip + * select signal. In that case, the SPI slave controller driver will + * again call the SPI device's select() method. At this point, the SPI + * controller driver may have several words enqueued. It will not + * discard these unless the SPI device driver calls the qflush() + * method. + * + * Some master side implementations may simply tie the chip select signal + * to ground if there are no other devices on the SPI bus. In that case, + * the initial indication of chip selected will be the only call to the + * select() method that is made. + * + * A typical DMA data transfer processes as follows: + * To be provided + */ + +enum spi_smode_e +{ + SPISLAVE_MODE0 = 0, /* CPOL=0 CHPHA=0 */ + SPISLAVE_MODE1, /* CPOL=0 CHPHA=1 */ + SPISLAVE_MODE2, /* CPOL=1 CHPHA=0 */ + SPISLAVE_MODE3 /* CPOL=1 CHPHA=1 */ +}; + +/* The SPI slave controller driver vtable */ + +struct spi_sctrlr_s; /* Forward reference */ +struct spi_sdev_s; /* Forward reference */ + +struct spi_sctrlrops_s +{ + CODE void (*bind)(FAR struct spi_sctrlr_s *sctrlr, + FAR struct spi_sdev_s *sdev, enum spi_smode_e mode, + int nbits); + CODE void (*unbind)(FAR struct spi_sctrlr_s *sctrlr); + CODE int (*enqueue)(FAR struct spi_sctrlr_s *sctrlr, uint16_t data); + CODE bool (*qfull)(FAR struct spi_sctrlr_s *sctrlr); + CODE void (*qflush)(FAR struct spi_sctrlr_s *sctrlr); +}; + +/* SPI slave controller private data. This structure only defines the + * initial fields of the structure visible to the SPI device driver. The + * specific implementation may add additional, device specific fields after + * the vtable structure pointer. + */ + +struct spi_sctrlr_s +{ + FAR const struct spi_sctrlrops_s *ops; + + /* Private SPI slave controller driver data may follow */ +}; + +/* The SPI slave device driver vtable */ + +struct spi_sdevops_s +{ + CODE void (*select)(FAR struct spi_sdev_s *sdev, bool selected); + CODE void (*cmddata)(FAR struct spi_sdev_s *sdev, bool data); + CODE uint16_t (*getdata)(FAR struct spi_sdev_s *sdev); + CODE void (*receive)(FAR struct spi_sdev_s *sdev, uint16_t cmd); +}; + +/* SPI slave device private data. This structure only defines the initial + * fields of the structure visible to the SPI slave controller driver. The + * specific implementation may add additional, device specific fields after + * the vtable structure pointer. + */ + +struct spi_sdev_s +{ + FAR const struct spi_sdevops_s *ops; + + /* Private SPI slave device driver data may follow */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_spi_slave_initialize + * + * Description: + * Initialize the selected SPI port in slave mode. + * + * Input Parameter: + * port - Chip select number identifying the "logical" SPI port. Includes + * encoded port and chip select information. + * + * Returned Value: + * Valid SPI device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +FAR struct spi_sctrlr_s *up_spi_slave_initialize(int port); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __INCLUDE_NUTTX_SPI_SLAVE_H */ diff --git a/include/nuttx/spi/spi.h b/include/nuttx/spi/spi.h index 544afaa3ca8..2a6e25ed034 100644 --- a/include/nuttx/spi/spi.h +++ b/include/nuttx/spi/spi.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/spi/spi.h * - * Copyright(C) 2008-2013 Gregory Nutt. All rights reserved. + * Copyright(C) 2008-2013, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -271,7 +271,7 @@ * * Input Parameters: * dev - Device-specific state data - * buffer - A pointer to the buffer in which to recieve data + * buffer - A pointer to the buffer in which to receive data * nwords - the length of data that can be received in the buffer in number * of words. The wordsize is determined by the number of bits- * per-word selected for the SPI interface. If nbits <= 8, the @@ -298,7 +298,7 @@ * Input Parameters: * dev - Device-specific state data * txbuffer - A pointer to the buffer of data to be sent - * rxbuffer - A pointer to the buffer in which to recieve data + * rxbuffer - A pointer to the buffer in which to receive data * nwords - the length of data that to be exchanged in units of words. * The wordsize is determined by the number of bits-per-word * selected for the SPI interface. If nbits <= 8, the data is @@ -324,7 +324,7 @@ * * Input Parameters: * dev - Device-specific state data - * callback - The funtion to call on the media change + * callback - The function to call on the media change * arg - A caller provided value to return with the callback * * Returned Value: @@ -367,7 +367,7 @@ enum spi_dev_e SPIDEV_USER /* Board-specific values start here */ }; -/* Certain SPI devices may required differnt clocking modes */ +/* Certain SPI devices may required different clocking modes */ enum spi_mode_e { @@ -383,29 +383,31 @@ struct spi_dev_s; struct spi_ops_s { #ifndef CONFIG_SPI_OWNBUS - int (*lock)(FAR struct spi_dev_s *dev, bool lock); + CODE int (*lock)(FAR struct spi_dev_s *dev, bool lock); #endif - void (*select)(FAR struct spi_dev_s *dev, enum spi_dev_e devid, - bool selected); - uint32_t (*setfrequency)(FAR struct spi_dev_s *dev, uint32_t frequency); - void (*setmode)(FAR struct spi_dev_s *dev, enum spi_mode_e mode); - void (*setbits)(FAR struct spi_dev_s *dev, int nbits); - uint8_t (*status)(FAR struct spi_dev_s *dev, enum spi_dev_e devid); + CODE void (*select)(FAR struct spi_dev_s *dev, enum spi_dev_e devid, + bool selected); + CODE uint32_t (*setfrequency)(FAR struct spi_dev_s *dev, uint32_t frequency); + CODE void (*setmode)(FAR struct spi_dev_s *dev, enum spi_mode_e mode); + CODE void (*setbits)(FAR struct spi_dev_s *dev, int nbits); + CODE uint8_t (*status)(FAR struct spi_dev_s *dev, enum spi_dev_e devid); #ifdef CONFIG_SPI_CMDDATA - int (*cmddata)(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); + CODE int (*cmddata)(FAR struct spi_dev_s *dev, enum spi_dev_e devid + bool cmd); #endif - uint16_t (*send)(FAR struct spi_dev_s *dev, uint16_t wd); + CODE uint16_t (*send)(FAR struct spi_dev_s *dev, uint16_t wd); #ifdef CONFIG_SPI_EXCHANGE - void (*exchange)(FAR struct spi_dev_s *dev, FAR const void *txbuffer, - FAR void *rxbuffer, size_t nwords); + CODE void (*exchange)(FAR struct spi_dev_s *dev, + FAR const void *txbuffer, FAR void *rxbuffer, + size_t nwords); #else - void (*sndblock)(FAR struct spi_dev_s *dev, FAR const void *buffer, - size_t nwords); - void (*recvblock)(FAR struct spi_dev_s *dev, FAR void *buffer, - size_t nwords); + CODE void (*sndblock)(FAR struct spi_dev_s *dev, + FAR const void *buffer, size_t nwords); + CODE void (*recvblock)(FAR struct spi_dev_s *dev, FAR void *buffer, + size_t nwords); #endif - int (*registercallback)(FAR struct spi_dev_s *dev, spi_mediachange_t callback, - void *arg); + CODE int (*registercallback)(FAR struct spi_dev_s *dev, + spi_mediachange_t callback, void *arg); }; /* SPI private data. This structure only defines the initial fields of the @@ -435,7 +437,7 @@ extern "C" * Name: up_spiinitialize * * Description: - * Initialize the selected SPI port. + * Initialize the selected SPI port in master mode. * * This is a generic prototype for the SPI initialize logic. Specific * architectures may support different SPI initialization functions if, @@ -454,14 +456,14 @@ extern "C" * * Another example would be the STM32 families that support both SPI * blocks as well as USARTs that can be configured to perform the SPI - * function as well (the STM32 USARTs do not suppor SPI as of this + * function as well (the STM32 USARTs do not support SPI as of this * writing). * * Input Parameter: - * Port number (for hardware that has mutiple SPI interfaces) + * Port number (for hardware that has multiple SPI interfaces) * * Returned Value: - * Valid SPI device structure reference on succcess; a NULL on failure + * Valid SPI device structure reference on success; a NULL on failure * ****************************************************************************/ diff --git a/include/pthread.h b/include/pthread.h index d65f6d50804..4de07d62a22 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -148,7 +148,7 @@ prctl((int)PR_GET_NAME, (char*)name, (int)thread) /******************************************************************************** - * Global Type Declarations + * Public Type Definitions ********************************************************************************/ #ifdef __cplusplus @@ -241,11 +241,11 @@ typedef bool pthread_once_t; struct sched_param; /* Defined in sched.h */ /******************************************************************************** - * Global Variables + * Public Data ********************************************************************************/ /******************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ********************************************************************************/ /* Initializes a thread attributes object (attr) with default values for all of @@ -414,4 +414,3 @@ int pthread_sigmask(int how, FAR const sigset_t *set, FAR sigset_t *oset); #endif #endif /* __INCLUDE_PTHREAD_H */ - diff --git a/include/queue.h b/include/queue.h index 7d10e86e1d2..56c87469a77 100644 --- a/include/queue.h +++ b/include/queue.h @@ -60,7 +60,7 @@ #define dq_peek(q) ((q)->head) /**************************************************************************** - * Global Type Declarations + * Public Type Definitions ****************************************************************************/ struct sq_entry_s @@ -91,7 +91,7 @@ struct dq_queue_s typedef struct dq_queue_s dq_queue_t; /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ #ifdef __cplusplus diff --git a/include/sched.h b/include/sched.h index cb89b056640..4fe16542d60 100644 --- a/include/sched.h +++ b/include/sched.h @@ -53,10 +53,14 @@ /* POSIX-like scheduling policies */ -#define SCHED_FIFO 1 /* FIFO per priority scheduling policy */ -#define SCHED_RR 2 /* Round robin scheduling policy */ -#define SCHED_SPORADIC 3 /* Sporadic scheduling policy */ -#define SCHED_OTHER 4 /* Not supported */ +#define SCHED_FIFO 1 /* FIFO priority scheduling policy */ +#define SCHED_RR 2 /* Round robin scheduling policy */ +#define SCHED_SPORADIC 3 /* Sporadic scheduling policy */ +#define SCHED_OTHER 4 /* Not supported */ + +/* Maximum number of SCHED_SPORADIC replenishments */ + +#define SS_REPL_MAX CONFIG_SCHED_SPORADIC_MAXREPL /* Pthread definitions **********************************************************/ diff --git a/include/signal.h b/include/signal.h index 492ce416c08..30f97ef687d 100644 --- a/include/signal.h +++ b/include/signal.h @@ -183,7 +183,7 @@ #endif /******************************************************************************** - * Global Type Declarations + * Public Type Definitions ********************************************************************************/ /* This defines a set of 32 signals (numbered 0 through 31). */ @@ -251,11 +251,11 @@ struct sigaction #define sa_sigaction sa_u._sa_sigaction /******************************************************************************** - * Global Variables + * Public Data ********************************************************************************/ /******************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ********************************************************************************/ #ifdef __cplusplus @@ -297,4 +297,3 @@ int sigqueue(int pid, int signo, FAR void *sival_ptr); #endif #endif /* __INCLUDE_SIGNAL_H */ - diff --git a/include/stdlib.h b/include/stdlib.h index 14b06f88aee..70e9f707e75 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -49,9 +49,9 @@ * Pre-processor Definitions ****************************************************************************/ -/* The C standard specifies two constants, EXIT_SUCCESS and - * EXIT_FAILURE, that may be passed to exit() to indicate - * successful or unsucessful termination, respectively. +/* The C standard specifies two constants, EXIT_SUCCESS and EXIT_FAILURE, + * that may be passed to exit() to indicate successful or unsuccessful + * termination, respectively. */ #define EXIT_SUCCESS 0 @@ -71,9 +71,8 @@ #define MB_CUR_MAX 1 -/* The environ variable, normally 'extern char **environ;' is - * not implemented as a function call. However, get_environ_ptr() - * can be used in its place. +/* The environ variable, normally 'char **environ;' is not implemented as a + * function call. However, get_environ_ptr() can be used in its place. */ #ifndef CONFIG_DISABLE_ENVIRON @@ -81,7 +80,7 @@ #endif /**************************************************************************** - * Global Type Definitions + * Public Type Definitions ****************************************************************************/ struct mallinfo @@ -97,11 +96,7 @@ struct mallinfo }; /**************************************************************************** - * Global Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ #undef EXTERN diff --git a/include/string.h b/include/string.h index 79849e4a96f..396f440872c 100644 --- a/include/string.h +++ b/include/string.h @@ -56,7 +56,7 @@ #define bcopy(b1,b2,len) (void)memmove(b2,b1,len) /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ #undef EXTERN diff --git a/include/unistd.h b/include/unistd.h index 7816fb36c38..e482109f5c1 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -113,7 +113,7 @@ #define HOST_NAME_MAX 32 /**************************************************************************** - * Global Variables + * Public Data ****************************************************************************/ #undef EXTERN @@ -133,7 +133,7 @@ extern "C" #ifndef __NXFLAT__ EXTERN FAR char *optarg; /* Optional argument following option */ EXTERN int optind; /* Index into argv */ -EXTERN int optopt; /* unrecognized option character */ +EXTERN int optopt; /* Unrecognized option character */ #else # define optarg (*(getoptargp())) # define optind (*(getoptindp())) @@ -141,7 +141,7 @@ EXTERN int optopt; /* unrecognized option character */ #endif /**************************************************************************** - * Global Function Prototypes + * Public Function Prototypes ****************************************************************************/ /* Task Control Interfaces */ @@ -205,7 +205,7 @@ int getopt(int argc, FAR char *const argv[], FAR const char *optstring); FAR char **getoptargp(void); /* Optional argument following option */ int *getoptindp(void); /* Index into argv */ -int *getoptoptp(void); /* unrecognized option character */ +int *getoptoptp(void); /* Unrecognized option character */ #ifdef CONFIG_NET int gethostname(FAR char *name, size_t size);