diff --git a/Documentation/components/drivers/block/index.rst b/Documentation/components/drivers/block/index.rst index c27f8d73c0..b79bbdc80b 100644 --- a/Documentation/components/drivers/block/index.rst +++ b/Documentation/components/drivers/block/index.rst @@ -44,3 +44,100 @@ Block device drivers have these properties: Can be used to set up a block of memory or (read-only) FLASH as a block driver that can be mounted as a file system. See include/nuttx/drivers/ramdisk.h. + +EEPROM +====== + +EEPROMs are a form of Memory + Technology Device (MTD). EEPROMs are non-volatile memory like FLASH, but + differ in underlying memory technology and differ in usage in many respects: + They may not be organized into blocks (at least from the standpoint of the + user) and it is not necessary to erase the EEPROM memory before re-writing + it. In addition, EEPROMs tend to be much smaller than FLASH parts, usually + only a few kilobytes vs megabytes for FLASH. EEPROM tends to be used to + retain a small amount of device configuration information; FLASH tends + to be used for program or massive data storage. For these reasons, it may + not be convenient to use the more complex MTD interface but instead use + the simple character interface provided by the EEPROM drivers. + +EEPROM Device Support +--------------------- + +drivers/eeprom/spi_xx25xx.c +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This is a driver for SPI EEPROMs that use the same commands as the +25AA160:: + + Manufacturer Device Bytes PgSize AddrLen + Microchip + 25xx010A 128 16 1 + 25xx020A 256 16 1 + 25AA02UID 256 16 1 + 25AA02E48 256 16 1 + 25AA02E64 256 16 1 + 25xx040 512 16 1+bit + 25xx040A 512 16 1+bit + 25xx080 1024 16 1 + 25xx080A 1024 16 2 + 25xx080B 1024 32 2 + 25xx080C 1024 16 x + 25xx080D 1024 32 x + 25xx160 2048 16 2 + 25xx160A/C 2048 16 2 TESTED + 25xx160B/D 2048 32 2 + 25xx160C 2048 16 2 + 25xx160D 2048 32 2 + 25xx320 4096 32 2 + 25xx320A 4096 32 2 + 25xx640 8192 32 2 + 25xx640A 8192 32 2 + 25xx128 16384 64 2 + 25xx256 32768 64 2 + 25xx512 65536 128 2 + 25xx1024 131072 256 3 + Atmel + AT25010B 128 8 1 + AT25020B 256 8 1 + AT25040B 512 8 1+bit + AT25080B 1024 32 2 + AT25160B 2048 32 2 + AT25320B 4096 32 2 + AT25640B 8192 32 2 + AT25128B 16384 64 2 + AT25256B 32768 64 2 + AT25512 65536 128 2 + AT25M01 131072 256 3 + +drivers/mtd/at24xx.c +~~~~~~~~~~~~~~~~~~~~ + +This is a driver for I2C-based at24cxx EEPROM (at24c32, at24c64, at24c128, +at24c256, at24c512). This driver is currently provided as an MTD driver +but could easily be modified to support the character driver interface. + +File Systems +------------ + +Most EEPROM parts are too small to be candidates for use with a file +system. The character driver interface is optimal for these small parts +because you can open and access the EEPROM part as if it were a single, +fixed size file. + +It is also possible to use these character drivers with a file system. +The character driver can converted to a block device using the NuttX loop +device. The loop device can be found the file drivers/loop.c. Interface +function prototypes can be found in include/nuttx/fs/fs.h:: + + int losetup(FAR const char *devname, FAR const char *filename, + uint16_t sectsize, off_t offset, bool readonly); + +Given a file or character devices at 'filename', losetup will create the +block device 'devname' using a bogus sector size of sectsize. 'offset' is +normally zero but can be used to provide an offset into the EEPROM where +the block driver data starts; The EEPROM block driver can also be read- +only. + +There is a corresponding function that will destroy the loop device:: + + int loteardown(FAR const char *devname); diff --git a/Documentation/components/drivers/special/index.rst b/Documentation/components/drivers/special/index.rst index 5f3d8dc0e4..7f4cb07223 100644 --- a/Documentation/components/drivers/special/index.rst +++ b/Documentation/components/drivers/special/index.rst @@ -35,3 +35,5 @@ following section. usbdev.rst rwbuffer.rst regmap.rst + sensors.rst + video.rst diff --git a/Documentation/components/drivers/special/lcd.rst b/Documentation/components/drivers/special/lcd.rst index 1bea50e7b7..67bc423be7 100644 --- a/Documentation/components/drivers/special/lcd.rst +++ b/Documentation/components/drivers/special/lcd.rst @@ -1,3 +1,5 @@ +.. note:: See also the usage of the LCD driver in the graphics/ directory. + ===================== LCD Character Drivers ===================== @@ -52,6 +54,96 @@ details on how an LCD screen is bound to an LCD character driver. * ``include/nuttx/lcd/lcd.h`` provides structures and APIs needed to work with LCD screens, whether using the framebuffer adapter or the :doc:`lcd`; +Supported devices +================= + +Re-usable LCD drivers reside in the drivers/lcd directory: + +LCDs +---- + +- ``mio283qt2.c`` + + This is a driver for the MI0283QT-2 LCD from Multi-Inno + Technology Co., Ltd. This LCD is based on the Himax HX8347-D LCD + controller. + +- ``mio283qt9a.c`` + + This is a driver for the MI0283QT-9A LCD from Multi-Inno + Technology Co., Ltd. This LCD is based on the Ilitek ILI9341 LCD + controller. + +- ``ssd12989.c`` + + Generic LCD driver for LCDs based on the Solomon Systech + SSD1289 LCD controller. Think of this as a template for an LCD driver + that you will probably have to customize for any particular LCD + hardware. (See also boards/arm/stm32/hymini-stm32v/src/ssd1289.c below). + +- ``st7567.c`` + + LCD Display Module, ST7567, Univision Technology Inc. + Used with the LPCXpresso and Embedded Artists base board. + +- ``memlcd.c`` + + Sharp Memory LCD Suite, LS013B7DH01, LS013B7DH03, etc. + There are some more different models, they are basically controlled + by similar logics, thus this driver can be extended. + +- ``ra8875.c`` + + RAiO Technologies RA8875 LCD controller. Contributed by Marten Svanfeldt. + +OLEDs +----- + +- ``p14201.c`` + + Driver for RiT P14201 series display with SD1329 IC controller. + Based on the SD1329 controller. This OLED is used with + older versions of the TI/Luminary LM3S8962 Evaluation Kit. Example + usage:: + + boards/arm/tiva/lm3s6965-ek/src + boards/arm/tiva/lm3s8962-ek/src + +- ``ug-2864ambag01.c`` + + OLED Display Module, UUG-2864AMBAG01, Univision Technology Inc. + Based on the SH1101A controller. Example usage:: + + boards/arm/stm32/stm32f4discovery + boards/arm/lpc214x/zp214xpa + +- ``ug-9664hswag01.c`` + + OLED Display Module, UG-9664HSWAG01, Univision Technology Inc. + Based on the SSD1305 controller. Used with the + LPC Xpresso and Embedded Artists base board. Example usage:: + + boards/arm/lpc71xx_40xx/lpcxpresso-lpc1768 + +- ``ssd1306.c`` + + OLED Display Modules based on the SSD1306 controllers. + This includes the UG-2864HSWEG01 and UG2832HSWEG04, both from Univision + Technology Inc. The latter is used with the OLED1 module that comes + with the Atmel SAM4l Xplained Pro board. This driver also supports + Densitron Technologies DD-12864WO-4A which is based on SSD1309 LCD + controller. Example usage:: + + boards/arm/stm32/stm32f4discovery + boards/arm/sam34/sam4l-xplained + +Segment LCDS (SLCDs) +-------------------- + +- ``pcf8574_lcd_backpack.c`` + + See pcf8574_lcd_backpack_readme.txt. + Examples ======== @@ -132,3 +224,82 @@ built with the LCD character interface. * The LVGL demo application (``lvgldemo``) makes use of the ``ioctl`` system call to trigger an ``LCDDEVIO_PUTAREA`` request to the higher-level device driver to refresh the LCD screen with data as usual; + +LCD Header files +================ + +``include/nuttx/lcd/lcd.h`` + + Structures and APIs needed to work with LCD drivers are provided in + this header file. This header file also depends on some of the same + definitions used for the frame buffer driver as provided in + include/nuttx/video/fb.h. + +``struct lcd_dev_s`` + + Each LCD device driver must implement an instance of struct lcd_dev_s. + That structure defines a call table with the following methods: + + - Get information about the LCD video controller configuration and the + configuration of each LCD color plane. + + .. code-block:: C + + int (*getvideoinfo)(FAR struct lcd_dev_s *dev, + FAR struct fb_videoinfo_s *vinfo); + int (*getplaneinfo)(FAR struct lcd_dev_s *dev, unsigned int planeno, + FAR struct lcd_planeinfo_s *pinfo); + + + - The following are provided only if the video hardware supports RGB + color mapping: + + .. code-block:: C + + int (*getcmap)(FAR struct lcd_dev_s *dev, + FAR struct fb_cmap_s *cmap); + int (*putcmap)(FAR struct lcd_dev_s *dev, + FAR const struct fb_cmap_s *cmap); + + + - The following are provided only if the video hardware supports a + hardware cursor: + + .. code-block:: C + + int (*getcursor)(FAR struct lcd_dev_s *dev, + FAR struct fb_cursorattrib_s *attrib); + int (*setcursor)(FAR struct lcd_dev_s *dev, + FAR struct fb_setcursor_s *settings); + + + - Get the LCD panel power status (0: full off - CONFIG_LCD_MAXPOWER: + full on). On backlit LCDs, this setting may correspond to the + backlight setting: + + .. code-block:: C + + int (*getpower)(struct lcd_dev_s *dev); + + + - Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: + full on). On backlit LCDs, this setting may correspond to the + backlight setting: + + .. code-block:: C + + int (*setpower)(struct lcd_dev_s *dev, int power); + + + - Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST): + + .. code-block:: C + + int (*getcontrast)(struct lcd_dev_s *dev); + + + - Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST): + + .. code-block:: C + + int (*setcontrast)(struct lcd_dev_s *dev, unsigned int contrast); diff --git a/Documentation/components/drivers/special/sensors.rst b/Documentation/components/drivers/special/sensors.rst new file mode 100644 index 0000000000..55ed308e4a --- /dev/null +++ b/Documentation/components/drivers/special/sensors.rst @@ -0,0 +1,496 @@ +.. warning:: this list is incomplete. See drivers/sensors for ar full list of + supported sensors + +============== +Sensor Drivers +============== + +ADXL345 +======= + +Contributed by Alan Carvalho de Assis + +The ADXL345 accelerometer can operate in I2C or SPI mode. To operate in I2C +mode just connect the CS pin to Vddi/o. + +In order to operate in SPI mode CS need to use connected to microcontroller, +it cannot leave unconnected. + +In SPI mode it works with clock polarity (CPOL) = 1 and clock phase (CPHA) += 1. + +ADXL372 +======= + +Contributed by Bob Feretich + +The ADXL372 is a 200g tri-axis accelerometer that is capable of detecting +and recording shock impact impact events. Recording trigger +characteristics are programmed into the sensor via multiple threshold and +duration registers. The ADXL372 is a SPI only device that can transfer +data at 10 MHz. The data transfer performance of this part permits the +sensor to be sampled "on demand" rather than periodically sampled by a +worker task. + +See the description of the "Common Sensor Register Interface" below for more +details. It also implements the "Sensor Cluster Driver Interface". + +LSM330_SPI +========== + +Contributed by Bob Feretich + +The LSM330 consists of a multi-range tri-axis accelerometer and a +multi-range tri-axis gyroscope. The tri-axis accelerometer features two +state machines that can be firmware programmed for event detection. The +tri-axis gyroscope features threshold and duration registers for event +detection. + +This driver supports the LSM330 in SPI mode. In this mode, the LSM330 +that can transfer data at 10 MHz. The data transfer performance of +this part permits the sensor to be sampled "on demand" rather than +periodically sampled by a worker task. See the description of the "Common +Sensor Register Interface" below for more details. It also implements the +"Sensor Cluster Driver Interface". + +MPL115A +======= + +Contributed by Alan Carvalho de Assis + +This driver has support only for MPL115A1 (SPI), but support to MPL115A2 +(I2C) can be added easily. + +Common Sensor Register Interface +================================ + +Contributed by Bob Feretich + +Background and problem statement: + +The capabilities and performance of modern sensors have grown tremendously. +Most sensors are now capable of some degree of autonomous behavior and +several permit the user to load firmware into them and perform as +nanocontrollers. Other sensors have very sophisticated built-in digital +filters that can be programmed with hundreds of parameters. + +Currently most sensor drivers in the NuttX drivers/sensors +directory implement file_ops open(), close(), and read() functions. +The open() function initializes the sensor and places it in a mode where +it can transfer live data in a default configuration. The close() function +places the sensor in a low power shutdown mode. The read() function +returns the most recent data sample from the sensor's most used data +output registers. The write() function is rarely implemented and when it +is there is no consistency in its use. The lseek() and poll() functions +seem to be completely ignored. This results in the sensors being operated +in only their most primitive modes using a fixed "default configuration". + +To work around this problem sensor drivers have implemented ioctl() +functions to perform configuration, program the sensor, and manage +autonomous activity. Ioctls provide a method where user programs can +tunnel through a high level driver to access and control device specific +features. The problem with using ioctls is that before the ioctl interface +can be used, the sensor driver must be opened; and the open() function +causes the driver to start performing these primitive actions, so before +ioctls can manage the drivers as desired, ioctls must first be used to +undo the generic actions caused by the open() function. Another major +issue is that there is no consistency from sensor to sensor on ioctl +definitions, not even for the most common sensor actions like writing a +sensor control register or reading a sensor status register. + +Purpose: + +The purpose of the "Common Sensor Register Interface" is to implement a +consistent and more useful definition of file_ops interface and to make the +file_ops open() function more flexible in establishing the initial +operational state of the sensor. Compatibility for user applications that +implement the current open(), close(), read() interface will be +maintained; and the much greater capabilities of modern sensors will +become accessible through this interface. + +Scope: + +Applicable to I2C and SPI attached sensors, and some serial port attached +sensors. + +The file_ops interface definition: + +open(): This function performs the below actions... + + 1) Reads the sensors ID register. If the sensor responds with an + unexpected value, then... + + a) The driver's write() function is disabled. + b) The open function initializes the driver instance, so + that read() and lseek() operations may be performed to enable + problem diagnoses, but the sensor hardware is not initialized. + (No write operations are performed to the sensor.) + c) The errno global variable is set to positive ENODEV + ("No such device"). + d) The open() function returns successfully with a file_handle. + Note that the calling routine should clear errno before + calling open(). (The file_ops rules prevent drivers from + setting errno to zero.) + + 2) The other file_ops functions are enabled. + 3) The driver's "current reg address" state variable is set to the + sensor's first sensor data output register. (This will make + calls to read() return live sensor data and maintain compatibility + with existing user programs.) + 4) If the driver supports a default worker task and an interrupt + handler is specified by in the sensor configuration structure, then + the default worker task is bound to the default worker task. + 5) The sensor configuration structure (that was provided to the driver + registration function) is examined to determine whether a custom + sensor configuration is specified. (The custom configuration is + basically an array of (device_reg_address, value) pairs that are + written to the sensor via "single register write" operations. + If a custom sensor configuration was specified, then that + configuration is written to the sensor, otherwise the "default + sensor configuration" is written to the sensor. + (A side effect of writing this data may result in interrupts + occurring and data being transferred to/from the worker task.) + 6) The open() function returns successfully with a file_handle. + +``close()``: This function stops sensor activity and places it in a low + power mode. The file_ops interface functions are disabled for this + instance of the sensor driver. (Except for open()) + +``read()``: The action of this function is dependent on whether a "default + worker task" is running and the value of the driver's "current reg + address" state variable. + + If a "default worker task" is running, + + AND the driver's "current reg address" is equal to the value of + the first sensor data output register, + AND the number of bytes to be read is less than or equal to the + number of bytes in a "default worker task" sample, + + Then data is copied from the "default worker task's" sample memory to + the caller's provided buffer. + + Otherwise, this function transfers data from sensor registers to the + data buffer provided by the caller. The first byte read is from the + sensor register address specified by the sensor's "current reg + address". The addresses of subsequent bytes to be read are context + sensitive. If more than bus transfer is needed to complete the read, + then a "multi-byte" (sometimes called "burst mode") data transfer + will be used to fill the buffer. + See the sensor's datasheet to determine the auto-increment + behavior of a "multi-byte" data transfers. + + Note: That most sensors collect only a few bytes of data per sample. + Small data transfers occurring over a high speed bus (like SPI and some + high speed i2c and serial interfaces) are much more efficient when + collected directly from the sensor hardware than by using a worker task + as an intermediary. + +``write()``: This function transfers data from the data buffer provided by + the caller to sensor registers. The first byte written is to the + sensor register address specified by the sensor's "current reg + address". The addresses of subsequent bytes to be read are context + sensitive. If more than bus transfer is needed to complete the write, + then a "multi-byte" (sometimes called "burst mode") data + transfer will be used to transfer data from the buffer. + + See the sensor's datasheet to determine the auto-increment + behavior of a "multi-byte" data transfers. + + Note: If write() function was disabled, then no writes will be performed + and the function will return 0 (characters transferred) and errno + is set to -EROFS ("read-only file system"). + +``lseek()``: This function sets the value of the sensor's "current reg address" + (seek_address). The open() function initializes the "current reg address" + to the first sensor data output register, so unless the user needs + to change the sensor configuration, lseek() does not need to be + called. Neither read() nor write() change the sensor's "current reg + address". + + The definition of lseek is...:: + + off_t lseek(int fd, off_t offset, int whence); + + For whence == SEEK_SET, the sensor's "current reg address" will be set + to offset. + + For whence == SEEK_CUR, offset will be added to the sensor's "current + reg address". + + For whence == SEEK_END, offset is ignored and the sensor's "current + reg address" is set to the first sensor data output register. + + lseek() will return an error if the resulting "current reg address" + is invalid for the sensor. + +``ioctl()``: Ioctls() may still be used and this interface make no attempt to + regulate them. But, it is expected that far fewer ioctls will be needed. + +The above interface can be used to fully configure a sensor to the needs +of an application, including the ability to load firmware into sensor +state machines + +Sensor Cluster Driver Interface +=============================== + +Contributed by Bob Feretich + +Background and problem statement: + +Most microcontrollers can support SPI bus transfers at 8 MHz or greater. +Most SPI attached sensors can support a 10 MHz SPI bus. Most tri-axis +accelerometers, tri-axis gyroscopes, or tri-axis magnetometers use only 6 +bytes per sample. Many sensors use less than 6 bytes per sample. On an 8 +MHz SPI bus it takes about 8 microseconds to transfer a 6 byte sample. +(This time includes a command byte, 6 data bytes, and chip select select +setup and hold.) So, for the below discussion keep in mind that the sensor +sample collection work we want to perform should ideally take 8 microseconds +per sample. + +The drivers in the drivers/sensors directory support only the user space +file_ops interface (accessing drivers through the POSIX open/read/close +functions using a file descriptor). Also these drivers typically start +their own worker task to perform sensor data collection, even when their +sensors only transfer a few bytes of data per sample and those transfers +are being made over a high performance bus. + +Using the current implementation... + +1) A sensor "data ready" or timer interrupt occurs. +2) Context is saved and and the driver's interrupt handler is scheduled + to run. +3) The NuttX scheduler dispatches the driver's interrupt handler task. +4) The driver's interrupt handler task posts to a semaphore that the + driver's worker task is waiting on. +5) NuttX restores the context for the driver's worker task and starts it + running. +6) The driver's worker task starts the i/o to collect the sample.) (This is + where the 8 microseconds of real work gets performed.) And waits on a + SPI data transfer complete semaphore. +7) The NuttX saves the context of the driver's worker task, and the + scheduler dispatches some other task to run while we are waiting. + Note that this is a good thing. This task is probably performing some + other real work. We want this to happen during the data transfer. +8) The completion of the data transfer causes an interrupt. NuttX saves the + current context and restores the driver's worker task's context. +9) The driver's worker task goes to sleep waiting on the semaphore for the + next sensor "data ready" or timer interrupt. +10) The NuttX saves the context of the driver's worker task, and the + scheduler dispatches some other task to run while we are waiting. + +Independently with the above... + +a) The sensor application program performs a file_ops read() to collect a + sample. +b) The NuttX high level driver receives control, performs a thin layer of + housekeeping and calls the sensor driver's read function. +c) The sensor driver's read function copies the most recent sample from the + worker task's data area to the application's buffer and returns. +d) The NuttX high level driver receives control, performs a thin layer of + housekeeping and returns. +e) The application processes the sample. + +Using a 216 MHz STM32F7 with no other activity occurring, we have timed the +above the elapsed time for the above to be on average 45 microseconds. + +Most sensor applications process data from multiple sensors. (An 9-DoF IMU +is typically represented as three sensors (accelerometer, gyroscope, and +magnetometer). In this case there are three copies of 1-10 occurring in +parallel. + +In applications where live data is being used, the context switch +thrashing and cache pollution of this approach cripples system +performance. In applications where sensor FIFO data is being used and +therefore a large amount of data is collected per iteration, the non "zero +copy" nature of the data collection becomes a performance issue. + +Purpose: + +The "Sensor Cluster Driver Interface" provides a standard mechanism for +an application to collect data from multiple sensor drivers in a much more +efficient manner. It significantly reduces the number of running tasks and +the context thrashing and cache pollution caused by them. It also permits +"zero copy" collection of sensor data. + +The Sensor Cluster Driver Interface uses a single "worker task" to be shared +by an arbitrary number of drivers. This shared worker task is a kernel +task that is registered like a driver, supports a driver interface to +application programs, and collects data from multiple sensors (a cluster of +sensors), we refer to it a "Sensor Cluster Driver". + +Its goal is to change the sequence of events detailed above to... + +1) A sensor "data ready" or timer interrupt occurs. +2) Context is saved and and the cluster driver's interrupt handler is + scheduled to run. +3) The NuttX scheduler dispatches the cluster driver's interrupt handler + task. +4) The cluster driver's interrupt handler task posts to a semaphore that + the cluster driver's worker task is waiting on. +5) NuttX restores the context for the driver's worker task and starts it + running. +6) The cluster driver's worker task starts the i/o to collect the sample. + There are two choices here. Programmed I/O (PIO) or DMA. If PIO is + fastest for a small sample size, but it will lock up the processor for + the full duration of the transfer; it can only transfer from one + sensor at a time; and the worker task should manually yield control + occasionally to permit other tasks to run. DMA has higher start and + completion overhead, but it is much faster for long transfers, can + perform simultaneous transfers from sensors on different buses, and + automatically releases the processor while the transfer is occurring. + For this reason our drivers allows the worker task to choose between + PIO (driver_read()) and DMA (driver_exchange()), a common extension to + the sensor_cluster_operations_s structure. So either way after one or + more transfers we yield control and move to the next step. Note that + the data is being transferred directly into the buffer provided by the + application program; so no copy needs to be performed. +7) The NuttX saves the context of the cluster driver's worker task, and the + scheduler dispatches some other task to run while we are waiting. + Again note that this is a good thing. This task is probably performing + some other real work. We want this to happen during the data transfer. +8) The completion of the last of the previous data transfers causes an + interrupt. NuttX saves the current context and restores the cluster + driver's worker task's context. If there is more sensor data to + collect, then goto Step 6. Otherwise it posts to a semaphore that + will wake the application. +9) The driver's worker task goes to sleep waiting on the semaphore for the + next sensor "data ready" or timer interrupt. +10) The NuttX saves the context of the driver's worker task, and the + scheduler dispatches some other task to run while we are waiting. + +Independently with the above... + +a) The sensor application program performs a file_ops read() to collect a + sample. +b) The NuttX high level driver receives control, performs a thin layer of + housekeeping and calls the sensor driver's read function. +c) The sensor driver's read function copies the most recent sample from the + worker task's data area to the application's buffer and returns. +d) The NuttX high level driver receives control, performs a thin layer of + housekeeping and returns. +e) The application processes the sample. + +So when collecting data from three sensors, this mechanism saved... + +* the handling of 2 sensor "data ready" or timer interrupts (Steps 1 - 4). +* 2 occurrences of waking and scheduling of a worker task (Step 5). +* 2 context switches to other tasks (Step 9 & 10) +* if the three sensors were on separate buses, then 2 occurrences of + +Steps 6 - 8 could have also been saved. + +* An extra copy operation of the collected sensor data. +* The cache pollution caused by 2 competing worker tasks. + +Definitions: + +"Leaf Driver" - a kernel driver that implements the "Sensor Cluster Driver + Interface" so that it can be called by Cluster drivers. + +"Cluster Driver" - a kernel driver that uses the "Sensor Cluster Driver + Interface" to call leaf drivers. + +"Entry-Point Vector" - an array of function addresses to which a leaf driver + will permit calls by a Cluster Driver. + +"Leaf Driver Instance Handle" - a pointer to an opaque Leaf Driver structure + that identifies an instance of the leaf driver. Leaf Drivers store this + handle in its configuration structure during registration. + +Sensor Cluster Interface description: + +* The definition of an entry-point vector. This is similar to the + entry-point vector that is provided to the file-ops high level driver. + This entry-point vector must include the sensor_cluster_operations_s + structure as its first member. +* The the definition of an driver entry-point vector member in the leaf + driver's configuration structure. The leaf driver registration function + must store the address of its entry-point vector in this field. +* The the definition of an instance handle member in the leaf drivers + configuration structure. The leaf driver registration function must store + a handle (opaque pointer) to the instance of the leaf driver being + registered in this field. Note that this should be the same handle that + the leaf driver supplies to NuttX to register itself. The cluster driver + will include this handle as a parameter in calls made to the leaf driver. + +.. code-block:: C + + struct sensor_cluster_operations_s + { + CODE int (*driver_open)(FAR void *instance_handle, int32_t arg); + CODE int (*driver_close)(FAR void *instance_handle, int32_t arg); + CODE ssize_t (*driver_read)(FAR void *instance_handle, FAR char *buffer, + size_t buflen); + CODE ssize_t (*driver_write)(FAR void *instance_handle, + FAR const char *buffer, size_t buflen); + CODE off_t (*driver_seek)(FAR void *instance_handle, off_t offset, + int whence); + CODE int (*driver_ioctl)(FAR void *instance_handle, int cmd, + unsigned long arg); + CODE int (*driver_suspend)(FAR void *instance_handle, int32_t arg); + CODE int (*driver_resume)(FAR void *instance_handle, int32_t arg); + }; + +Note that the sensor_cluster_operations_s strongly resembles the NuttX fs.h +file_operations structures. This permits the current file_operations +functions to become thin wrappers around these functions. + +``driver_open()`` Same as the fs.h open() except that arg can be specify + permitting more flexibility in sensor configuration and initial operation. + when arg = 0 the function of driver_open() must be identical to open(). + +``driver_close()`` Same as the fs.h close() except that arg can be specify + permitting more flexibility in selecting a sensor low power state. + when arg = 0 the function of driver_close() must be identical to close(). + +``driver_read()`` Same as the fs.h read(). + +``driver_write()`` Same as the fs.h write(). Optional. Set to NULL if not + supported. + +``driver_seek()`` Same as the fs.h seek(). Optional. Set to NULL if not + supported. + +``driver_ioctl()`` Same as the fs.h ioctl(). Optional. Set to NULL if not + supported. + +``driver_suspend()`` and ``driver_resume()`` Optional. Set to NULL if not + supported. It is common for sensor applications to conserve power and + send their microcontroller into a low power sleep state. It seems + appropriate to reserve these spots for future use. These driver entry + points exist in Linux and Windows. Since microcontrollers and sensors + get more capable every year, there should soon be a requirement for + these entry points. Discussion on how to standardize their use and + implementation should + be taken up independently from this driver document. + +Note that all drivers are encouraged to extend their entry-point vectors +beyond this common segment. For example it may be beneficial for the +worker task to select between programmed i/o and DMA data transfer +routines. Unregulated extensions to the Entry-Point Vector should be +encouraged to maximize the benefits of a sensor's features. + +Operation: + +Board logic (configs directory) will register the cluster driver. The +cluster driver will register the leaf drivers that it will call. +This means that the cluster driver has access to the leaf driver's +configuration structures and can pass the Leaf Driver Instance Handle to +the leaf driver as a parameter in calls made via the Entry-Point Vector. + +Either board logic or an application program may open() the cluster +driver. The cluster driver open() calls the open() function of the leaf +drivers. The cluster driver open() or read() function can launch the +shared worker task that collects the data. + +The cluster driver close() function calls the close functions of the leaf +drivers. + +ADT7320 +======= + +Contributed by Augusto Fraga Giachero + +The ADT7320 is a SPI temperature sensor with a temperature range of +−40°C to +150°C. diff --git a/Documentation/components/drivers/special/video.rst b/Documentation/components/drivers/special/video.rst new file mode 100644 index 0000000000..7418da269b --- /dev/null +++ b/Documentation/components/drivers/special/video.rst @@ -0,0 +1,70 @@ +==================== +Video Device Drivers +==================== + + +max7456 +------- + +23 March 2019 +Bill Gatliff + +The code in drivers/video/max7456.[ch] is a preliminary device driver for the MAX7456 analog +on-screen-display generator. This SPI slave chip is a popular feature in many +embedded devices due its low cost and power requirements. In particular, you +see it a lot on drone flight-management units. + +I use the term "preliminary" because at present, only the most rudimentary +capabilities of the chip are supported: + + * chip reset and startup + * read and write low-level chip control registers (DEBUG mode only) + * write CA (Character Address) data to the chip's framebuffer memory + +Some key missing features are, in no particular order: + + * VSYNC and HSYNC synchronization (prevents flicker) + * ability to update NVM (define custom character sets) + +If you have a factory-fresh chip, then the datasheet shows you what the factory +character data set looks like. If you've used the chip in other scenarios, +i.e. with Betaflight or similar, then your chip will almost certainly have had +the factory character data replaced with something application-specific. + +Either way, you'll probably want to update your character set before long. I +should probably get that working, unless you want to take a look at it +yoruself... + +The max7456_register() function starts things rolling. The omnibusf4 target +device provides an example (there may be others by the time you read this). + +In normal use, the driver creates a set of interfaces under /dev, i.e.:: + + /dev/osd0/fb + /dev/osd0/raw (*) + /dev/osd0/vsync (*) + +* - not yet implemented + +By writing character data to the "fb" interface, you'll see data appear on the +display. NOTE that the data you write is NOT, for example, ASCII text: it is +the addresses of the characters in the chip's onboard character map. + +For example, if entry 42 in your onboard character map is a bitmap that looks +like "H", then when you write the ASCII "*" (decimal 42, hex 2a), you'll see +that "H" appear on your screen. + +If you build the code with the DEBUG macro defined, you will see a bunch more interfaces:: + + /dev/osd0/VM0 + /dev/osd0/VM1 + /dev/osd/DMM + ... + ... + +These are interfaces to the low-level chip registers, which can be read and/or +written to help you figure out what's going on inside the chip. They're +probably more useful for me than you, but there they are in case I'm wrong +about that. + +b.g.