aboutsummaryrefslogtreecommitdiff
path: root/nuttx/drivers
diff options
context:
space:
mode:
authorLorenz Meier <lm@inf.ethz.ch>2013-06-01 01:04:32 +0200
committerLorenz Meier <lm@inf.ethz.ch>2013-06-01 01:04:32 +0200
commit5375bb5b86e266157ceceef08c367da711b8144e (patch)
tree88bc81cab11d8f0b2b6f9391f803051c081b2ecb /nuttx/drivers
parent27ee36b2049167a1272122548fe61aa2993d79c1 (diff)
downloadpx4-firmware-5375bb5b86e266157ceceef08c367da711b8144e.tar.gz
px4-firmware-5375bb5b86e266157ceceef08c367da711b8144e.tar.bz2
px4-firmware-5375bb5b86e266157ceceef08c367da711b8144e.zip
Cleanup, WIP, needs a NuttX checkout to Firmware/NuttX now
Diffstat (limited to 'nuttx/drivers')
-rw-r--r--nuttx/drivers/Kconfig445
-rw-r--r--nuttx/drivers/Makefile122
-rw-r--r--nuttx/drivers/README.txt145
-rw-r--r--nuttx/drivers/analog/Kconfig77
-rw-r--r--nuttx/drivers/analog/Make.defs87
-rw-r--r--nuttx/drivers/analog/ad5410.c205
-rw-r--r--nuttx/drivers/analog/adc.c434
-rw-r--r--nuttx/drivers/analog/ads1255.c335
-rw-r--r--nuttx/drivers/analog/dac.c499
-rw-r--r--nuttx/drivers/analog/pga11x.c793
-rw-r--r--nuttx/drivers/bch/Kconfig4
-rw-r--r--nuttx/drivers/bch/Make.defs52
-rw-r--r--nuttx/drivers/bch/bch_internal.h102
-rw-r--r--nuttx/drivers/bch/bchdev_driver.c255
-rw-r--r--nuttx/drivers/bch/bchdev_register.c104
-rw-r--r--nuttx/drivers/bch/bchdev_unregister.c160
-rw-r--r--nuttx/drivers/bch/bchlib_cache.c133
-rw-r--r--nuttx/drivers/bch/bchlib_read.c203
-rw-r--r--nuttx/drivers/bch/bchlib_sem.c84
-rw-r--r--nuttx/drivers/bch/bchlib_setup.c159
-rw-r--r--nuttx/drivers/bch/bchlib_teardown.c113
-rw-r--r--nuttx/drivers/bch/bchlib_write.c216
-rw-r--r--nuttx/drivers/can.c845
-rw-r--r--nuttx/drivers/dev_null.c135
-rw-r--r--nuttx/drivers/dev_zero.c135
-rw-r--r--nuttx/drivers/input/Kconfig228
-rw-r--r--nuttx/drivers/input/Make.defs76
-rw-r--r--nuttx/drivers/input/ads7843e.c1283
-rw-r--r--nuttx/drivers/input/ads7843e.h179
-rw-r--r--nuttx/drivers/input/max11802.c1313
-rw-r--r--nuttx/drivers/input/max11802.h167
-rw-r--r--nuttx/drivers/input/stmpe811.h245
-rw-r--r--nuttx/drivers/input/stmpe811_adc.c266
-rw-r--r--nuttx/drivers/input/stmpe811_base.c546
-rw-r--r--nuttx/drivers/input/stmpe811_gpio.c454
-rw-r--r--nuttx/drivers/input/stmpe811_temp.c174
-rw-r--r--nuttx/drivers/input/stmpe811_tsc.c1144
-rw-r--r--nuttx/drivers/input/tsc2007.c1336
-rw-r--r--nuttx/drivers/input/tsc2007.h120
-rw-r--r--nuttx/drivers/lcd/Kconfig330
-rw-r--r--nuttx/drivers/lcd/Make.defs76
-rw-r--r--nuttx/drivers/lcd/README.txt189
-rw-r--r--nuttx/drivers/lcd/mio283qt2.c1014
-rw-r--r--nuttx/drivers/lcd/nokia6100.c1230
-rw-r--r--nuttx/drivers/lcd/p14201.c1246
-rw-r--r--nuttx/drivers/lcd/pcf8833.h152
-rw-r--r--nuttx/drivers/lcd/s1d15g10.h141
-rw-r--r--nuttx/drivers/lcd/sd1329.h527
-rw-r--r--nuttx/drivers/lcd/skeleton.c401
-rw-r--r--nuttx/drivers/lcd/ssd1289.c1380
-rw-r--r--nuttx/drivers/lcd/ssd1289.h425
-rw-r--r--nuttx/drivers/lcd/ssd1305.h211
-rw-r--r--nuttx/drivers/lcd/ug-2864ambag01.c1161
-rw-r--r--nuttx/drivers/lcd/ug-2864hsweg01.c1218
-rw-r--r--nuttx/drivers/lcd/ug-9664hswag01.c1046
-rw-r--r--nuttx/drivers/loop.c509
-rw-r--r--nuttx/drivers/mmcsd/Kconfig79
-rw-r--r--nuttx/drivers/mmcsd/Make.defs56
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_csd.h424
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_debug.c183
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_internal.h105
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_sdio.c3186
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_sdio.h339
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_spi.c1889
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_spi.h187
-rw-r--r--nuttx/drivers/mtd/Kconfig133
-rw-r--r--nuttx/drivers/mtd/Make.defs65
-rw-r--r--nuttx/drivers/mtd/at24xx.c429
-rw-r--r--nuttx/drivers/mtd/at25.c710
-rw-r--r--nuttx/drivers/mtd/at45db.c899
-rw-r--r--nuttx/drivers/mtd/flash_eraseall.c117
-rw-r--r--nuttx/drivers/mtd/ftl.c601
-rw-r--r--nuttx/drivers/mtd/m25px.c798
-rw-r--r--nuttx/drivers/mtd/rammtd.c417
-rw-r--r--nuttx/drivers/mtd/ramtron.c686
-rw-r--r--nuttx/drivers/mtd/skeleton.c275
-rw-r--r--nuttx/drivers/mtd/sst25.c1250
-rw-r--r--nuttx/drivers/mtd/w25.c1179
-rw-r--r--nuttx/drivers/net/Kconfig95
-rw-r--r--nuttx/drivers/net/Make.defs71
-rw-r--r--nuttx/drivers/net/cs89x0.c959
-rw-r--r--nuttx/drivers/net/cs89x0.h326
-rw-r--r--nuttx/drivers/net/dm90x0.c1815
-rw-r--r--nuttx/drivers/net/e1000.c1042
-rw-r--r--nuttx/drivers/net/e1000.h121
-rw-r--r--nuttx/drivers/net/enc28j60.c2624
-rw-r--r--nuttx/drivers/net/enc28j60.h477
-rw-r--r--nuttx/drivers/net/skeleton.c692
-rw-r--r--nuttx/drivers/net/slip.c1017
-rw-r--r--nuttx/drivers/net/vnet.c672
-rw-r--r--nuttx/drivers/pipes/Kconfig4
-rw-r--r--nuttx/drivers/pipes/Make.defs46
-rw-r--r--nuttx/drivers/pipes/fifo.c139
-rw-r--r--nuttx/drivers/pipes/pipe.c286
-rw-r--r--nuttx/drivers/pipes/pipe_common.c682
-rw-r--r--nuttx/drivers/pipes/pipe_common.h139
-rw-r--r--nuttx/drivers/power/Kconfig23
-rw-r--r--nuttx/drivers/power/Make.defs84
-rw-r--r--nuttx/drivers/power/battery.c254
-rw-r--r--nuttx/drivers/power/max1704x.c564
-rw-r--r--nuttx/drivers/power/pm_activity.c166
-rw-r--r--nuttx/drivers/power/pm_changestate.c227
-rw-r--r--nuttx/drivers/power/pm_checkstate.c161
-rw-r--r--nuttx/drivers/power/pm_initialize.c112
-rw-r--r--nuttx/drivers/power/pm_internal.h210
-rw-r--r--nuttx/drivers/power/pm_register.c112
-rw-r--r--nuttx/drivers/power/pm_update.c334
-rw-r--r--nuttx/drivers/pwm.c676
-rw-r--r--nuttx/drivers/ramdisk.c342
-rw-r--r--nuttx/drivers/rwbuffer.c682
-rw-r--r--nuttx/drivers/sensors/Kconfig33
-rw-r--r--nuttx/drivers/sensors/Make.defs60
-rw-r--r--nuttx/drivers/sensors/lis331dl.c320
-rw-r--r--nuttx/drivers/sensors/lm75.c537
-rw-r--r--nuttx/drivers/sensors/qencoder.c402
-rw-r--r--nuttx/drivers/sercomm/Kconfig4
-rw-r--r--nuttx/drivers/sercomm/Make.defs55
-rw-r--r--nuttx/drivers/sercomm/README.txt19
-rw-r--r--nuttx/drivers/sercomm/console.c182
-rw-r--r--nuttx/drivers/sercomm/loadwriter.py19
-rw-r--r--nuttx/drivers/sercomm/uart.c469
-rw-r--r--nuttx/drivers/sercomm/uart.h32
-rw-r--r--nuttx/drivers/serial/Kconfig1054
-rw-r--r--nuttx/drivers/serial/Make.defs50
-rw-r--r--nuttx/drivers/serial/lowconsole.c132
-rw-r--r--nuttx/drivers/serial/serial.c1377
-rw-r--r--nuttx/drivers/serial/serialirq.c186
-rw-r--r--nuttx/drivers/serial/uart_16550.c1164
-rw-r--r--nuttx/drivers/syslog/Kconfig73
-rw-r--r--nuttx/drivers/syslog/Make.defs68
-rw-r--r--nuttx/drivers/syslog/README.txt64
-rw-r--r--nuttx/drivers/syslog/ramlog.c770
-rw-r--r--nuttx/drivers/usbdev/Kconfig513
-rw-r--r--nuttx/drivers/usbdev/Make.defs63
-rw-r--r--nuttx/drivers/usbdev/cdcacm.c2329
-rw-r--r--nuttx/drivers/usbdev/cdcacm.h350
-rw-r--r--nuttx/drivers/usbdev/cdcacm_desc.c613
-rw-r--r--nuttx/drivers/usbdev/composite.c933
-rw-r--r--nuttx/drivers/usbdev/composite.h326
-rw-r--r--nuttx/drivers/usbdev/composite_desc.c291
-rw-r--r--nuttx/drivers/usbdev/pl2303.c2355
-rw-r--r--nuttx/drivers/usbdev/usbdev_trace.c233
-rw-r--r--nuttx/drivers/usbdev/usbdev_trprintf.c253
-rw-r--r--nuttx/drivers/usbdev/usbmsc.c1778
-rw-r--r--nuttx/drivers/usbdev/usbmsc.h694
-rw-r--r--nuttx/drivers/usbdev/usbmsc_desc.c421
-rw-r--r--nuttx/drivers/usbdev/usbmsc_scsi.c2667
-rw-r--r--nuttx/drivers/usbhost/Kconfig114
-rw-r--r--nuttx/drivers/usbhost/Make.defs57
-rw-r--r--nuttx/drivers/usbhost/hid_parser.c529
-rw-r--r--nuttx/drivers/usbhost/usbhost_enumerate.c518
-rw-r--r--nuttx/drivers/usbhost/usbhost_findclass.c199
-rw-r--r--nuttx/drivers/usbhost/usbhost_hidkbd.c2353
-rw-r--r--nuttx/drivers/usbhost/usbhost_registerclass.c117
-rw-r--r--nuttx/drivers/usbhost/usbhost_registry.c80
-rw-r--r--nuttx/drivers/usbhost/usbhost_registry.h87
-rw-r--r--nuttx/drivers/usbhost/usbhost_skeleton.c1060
-rw-r--r--nuttx/drivers/usbhost/usbhost_storage.c2244
-rw-r--r--nuttx/drivers/watchdog.c575
-rw-r--r--nuttx/drivers/wireless/Kconfig4
-rw-r--r--nuttx/drivers/wireless/Make.defs47
-rw-r--r--nuttx/drivers/wireless/cc1101/ISM1_868MHzGFSK100kbps.c113
-rw-r--r--nuttx/drivers/wireless/cc1101/ISM2_905MHzGFSK250kbps.c111
-rw-r--r--nuttx/drivers/wireless/cc1101/Kconfig4
-rw-r--r--nuttx/drivers/wireless/cc1101/cc1101.c812
165 files changed, 0 insertions, 83703 deletions
diff --git a/nuttx/drivers/Kconfig b/nuttx/drivers/Kconfig
deleted file mode 100644
index f3d2c871a..000000000
--- a/nuttx/drivers/Kconfig
+++ /dev/null
@@ -1,445 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-config DISABLE_POLL
- bool "Disable driver poll interfaces"
- default n
- ---help---
- The sizes of drivers can be reduced if the poll() method is not
- supported. If you do not use poll() or select(), then you can
- select DISABLE_POLL to reduce the code footprint by a small amount.
-
-config DEV_NULL
- bool "Enable /dev/null"
- default y
-
-config DEV_ZERO
- bool "Enable /dev/zero"
- default n
-
-config ARCH_HAVE_RNG
- bool
-
-config DEV_RANDOM
- bool "Enable /dev/random"
- default n
- depends on ARCH_HAVE_RNG
-
-config LOOP
- bool "Enable loop device"
- default n
- ---help---
- Supports the standard loop device that can be used to export a
- file (or character device) as a block device. See losetup() and
- loteardown() in include/nuttx/fs/fs.h.
-
-config RAMDISK
- bool "RAM Disk Support"
- default n
- ---help---
- Can be used to set up a block of memory or (read-only) FLASH as
- a block driver that can be mounted as a files system. See
- include/nuttx/ramdisk.h.
-
-menuconfig CAN
- bool "CAN Driver Support"
- default n
- ---help---
- This selection enables building of the "upper-half" CAN driver.
- 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
- IDs.
-
-config CAN_FIFOSIZE
- int "CAN driver I/O buffer size"
- default 8
- ---help---
- The size of the circular buffer of CAN messages. Default: 8
-
-config CAN_NPENDINGRTR
- int "Number of pending RTRs"
- default 4
- ---help---
- The size of the list of pending RTR requests. Default: 4
-
-config CAN_LOOPBACK
- bool "CAN extended IDs"
- default n
- ---help---
- A CAN driver may or may not support a loopback mode for testing. If the
- driver does support loopback mode, the setting will enable it. (If the
- driver does not, this setting will have no effect).
-
-endif
-
-menuconfig PWM
- bool "PWM Driver Support"
- default n
- ---help---
- This selection enables building of the "upper-half" PWM driver.
- See include/nuttx/pwm.h for further PWM driver information.
-
-if PWM
-config PWM_PULSECOUNT
- bool "PWM Pulse Count Support"
- default n
- ---help---
- Some hardware will support generation of a fixed number of pulses.
- This might be used, for example to support a stepper motor. If the
- hardware will support a fixed pulse count, then this configuration
- should be set to enable the capability.
-
-endif
-
-menuconfig I2C
- bool "I2C Driver Support"
- default n
- ---help---
- This selection enables building of the "upper-half" I2C driver.
- See include/nuttx/i2c.h for further I2C driver information.
-
-config I2C_SLAVE
- bool "I2C Slave"
- default n
- depends on I2C
-
-config I2C_TRANSFER
- bool "Support the I2C transfer() method"
- default n
- depends on I2C
-
-config I2C_WRITEREAD
- bool "Support the I2C writeread() method"
- default n
- depends on I2C
-
-config I2C_POLLED
- bool "Polled I2C (no interrupts)"
- default n
- depends on I2C
-
-config I2C_TRACE
- bool "Enable I2C trace debug"
- default n
- depends on I2C
-
-config I2C_NTRACE
- bool "Enable I2C trace debug"
- default n
- depends on I2C_TRACE
-
-config ARCH_HAVE_I2CRESET
- bool
-
-config I2C_RESET
- bool "Support up_i2creset"
- default n
- depends on I2C && ARCH_HAVE_I2CRESET
-
-menuconfig SPI
- bool "SPI Driver Support"
- default n
- ---help---
- This selection enables selection of common SPI options. This option
- should be enabled by all platforms that support SPI interfaces.
- See include/nuttx/spi.h for further SPI driver information.
-
-if SPI
-config SPI_OWNBUS
- bool "SPI single device"
- default n
- ---help---
- Set if there is only one active device on the SPI bus. No locking or
- SPI configuration will be performed. It is not necessary for clients to
- lock, re-configure, etc..
-
-config SPI_EXCHANGE
- bool "SPI exchange"
- default y
- ---help---
- Driver supports a single exchange method (vs a recvblock() and
- sndblock() methods).
-
-config SPI_CMDDATA
- bool "SPI CMD/DATA"
- default n
- ---help---
- Devices on the SPI bus require out-of-band support to distinguish
- command transfers from data transfers. Such devices will often support
- either 9-bit SPI (yech) or 8-bit SPI and a GPIO output that selects
- between command and data.
-
-endif
-
-menuconfig RTC
- bool "RTC Driver Support"
- default n
- ---help---
- This selection enables configuration of a real time clock (RTCdriver.
- See include/nuttx/rtc.h for further watchdog timer driver information.
- Most RTC drivers are MCU specific and may require other specific
- settings.
-
-config RTC_DATETIME
- bool "Date/Time RTC Support"
- default n
- depends on RTC
- ---help---
- There are two general types of RTC: (1) A simple battery backed
- counter that keeps the time when power is down, and (2) a full
- date / time RTC the provides the date and time information, often in
- BCD format. If RTC_DATETIME is selected, it specifies this second kind
- of RTC. In this case, the RTC is used to "seed" the normal NuttX timer
- and the NuttX system timer provides for higher resolution time.
-
-config RTC_HIRES
- bool "Hi-Res RTC Support"
- default n
- depends on RTC && !RTC_DATETIME
- ---help---
- If RTC_DATETIME not selected, then the simple, battery backed counter
- is used. There are two different implementations of such simple
- counters based on the time resolution of the counter: The typical RTC
- keeps time to resolution of 1 second, usually supporting a 32-bit
- time_t value. In this case, the RTC is used to "seed" the normal NuttX
- timer and the NuttX timer provides for higherresoution time.
-
- If RTC_HIRES is enabled in the NuttX configuration, then the RTC
- provides higher resolution time and completely replaces the system
- timer for purpose of date and time.
-
-config RTC_FREQUENCY
- int "Hi-Res RTC frequency"
- default 1
- depends on RTC && !RTC_DATETIME && RTC_HIRES
- ---help---
- If RTC_HIRES is defined, then the frequency of the high resolution RTC
- must be provided. If RTC_HIRES is not defined, RTC_FREQUENCY is
- assumed to be one Hz.
-
-config RTC_ALARM
- bool "RTC Alarm Support"
- default n
- depends on RTC
- ---help---
- Enable if the RTC hardware supports setting of an alarm. A callback
- function will be executed when the alarm goes off.
-
-menuconfig WATCHDOG
- bool "Watchdog Timer Support"
- default n
- ---help---
- This selection enables building of the "upper-half" watchdog timer
- driver. See include/nuttx/watchdog.h for further watchdog timer driver
- information.
-
-if WATCHDOG
-endif
-
-menuconfig ANALOG
- bool "Analog Device(ADC/DAC) Support"
- default n
- ---help---
- This directory holds implementations of analog device drivers.
- This includes drivers for Analog to Digital Conversion (ADC) as
- well as drivers for Digital to Analog Conversion (DAC).
- See include/nuttx/analog/*.h for registration information.
-
-if ANALOG
-source drivers/analog/Kconfig
-endif
-
-menuconfig BCH
- bool "Block-to-Character (BCH) Support"
- default n
- ---help---
- Contains logic that may be used to convert a block driver into
- a character driver. This is the complementary conversion as that
- performed by loop.c. See include/nuttx/fs/fs.h for registration
- information.
-
-if BCH
-source drivers/bch/Kconfig
-endif
-
-menuconfig INPUT
- bool "Input Device Support"
- default n
- ---help---
- This directory holds implementations of input device drivers.
- This includes such things as touchscreen and keypad drivers.
- See include/nuttx/input/*.h for registration information.
-
-if INPUT
-source drivers/input/Kconfig
-endif
-
-menuconfig LCD
- bool "LCD Driver Support"
- default n
- select NX_LCDDRIVER
- ---help---
- Drivers for parallel and serial LCD and OLED type devices. These
- drivers support interfaces as defined in include/nuttx/lcd/lcd.h
-
- This selection is necessary to enable support for LCD drivers in
- drivers/lcd as well as for board-specific LCD drivers in the configs/
- subdirectories.
-
-if LCD
-source drivers/lcd/Kconfig
-endif
-
-menuconfig MMCSD
- bool "MMC/SD Driver Support"
- default n
- ---help---
- Support for MMC/SD block drivers. MMC/SD block drivers based on
- SPI and SDIO/MCI interfaces are supported. See include/nuttx/mmcsd.h
- and include/nuttx/sdio.h for further information.
-
-if MMCSD
-source drivers/mmcsd/Kconfig
-endif
-
-menuconfig MTD
- bool "Memory Technology Device (MTD) Support"
- default n
- ---help---
- Memory Technology Device (MTD) drivers. Some simple drivers for
- memory technologies like FLASH, EEPROM, NVRAM, etc. See
- include/nuttx/mtd.h
-
- (Note: This is a simple memory interface and should not be
- confused with the "real" MTD developed at infradead.org. This
- logic is unrelated; I just used the name MTD because I am not
- aware of any other common way to refer to this class of devices).
-
-if MTD
-source drivers/mtd/Kconfig
-endif
-
-menuconfig NETDEVICES
- bool "Network Device Support"
- default n
- depends on NET
- ---help---
- Network interface drivers. See also include/nuttx/net/net.h
-
-if NETDEVICES
-source drivers/net/Kconfig
-endif
-
-menuconfig PIPES
- bool "FIFO and named pipe drivers"
- default n
- ---help---
- FIFO and named pipe drivers. Standard interfaces are declared
- in include/unistd.h
-
-if PIPES
-source drivers/pipes/Kconfig
-endif
-
-config PM
- bool "Power management (PM) driver interfaces"
- default n
- ---help---
- Power management (PM) driver interfaces. These interfaces are used
- to manage power usage of a platform by monitoring driver activity
- and by placing drivers into reduce power usage modes when the
- drivers are not active.
-
-menuconfig POWER
- bool "Power Management Support"
- default n
- ---help---
- Enable building of power-related devices (battery monitors, chargers,
- etc).
-
-if POWER
-source drivers/power/Kconfig
-endif
-
-menuconfig SENSORS
- bool "Sensor Device Support"
- default n
- ---help---
- Drivers for various sensors
-
-if SENSORS
-source drivers/sensors/Kconfig
-endif
-
-menuconfig SERCOMM_CONSOLE
- bool "Osmocom-bb Sercomm Driver Support"
- default n
- ---help---
- Sercomm is the transport used by osmocom-bb that runs on top of serial.
- See http://bb.osmocom.org/trac/wiki/nuttx-bb/run for detailed the usage
- of nuttx with sercomm.
-
- drivers/sercomm is only built if SERCOMM_CONSOLE in the NuttX
- configuration file. If you attempt to build this driver without
- osmocom-bb, you will get compilation errors because of header files
- that are needed from the osmocom-bb.
-
-if SERCOMM
-source drivers/sercomm/Kconfig
-endif
-
-menuconfig SERIAL
- bool "Serial Driver Support"
- default y
- ---help---
- Front-end character drivers for chip-specific UARTs. This provide
- some TTY-like functionality and are commonly used (but not required
- for) the NuttX system console. See also include/nuttx/serial/serial.h
-
-if SERIAL
-source drivers/serial/Kconfig
-endif
-
-menuconfig USBDEV
- bool "USB Device Driver Support"
- default n
- ---help---
- USB device drivers. See also include/nuttx/usb/usbdev.h
-
-if USBDEV
-source drivers/usbdev/Kconfig
-endif
-
-menuconfig USBHOST
- bool "USB Host Driver Support"
- default n
- ---help---
- USB host drivers. See also include/nuttx/usb/usbhost.h
-
-if USBHOST
-source drivers/usbhost/Kconfig
-endif
-
-menuconfig WIRELESS
- bool "Wireless Device Support"
- default n
- ---help---
- Drivers for various wireless devices.
-
-if WIRELESS
-source drivers/wireless/Kconfig
-endif
-
-comment "System Logging Device Options"
-
-source drivers/syslog/Kconfig
-
-
diff --git a/nuttx/drivers/Makefile b/nuttx/drivers/Makefile
deleted file mode 100644
index aaaa67bd7..000000000
--- a/nuttx/drivers/Makefile
+++ /dev/null
@@ -1,122 +0,0 @@
-############################################################################
-# drivers/Makefile
-#
-# Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
--include $(TOPDIR)/Make.defs
-DELIM ?= $(strip /)
-
-ifeq ($(WINTOOL),y)
-INCDIROPT = -w
-endif
-
-DEPPATH = --dep-path .
-ASRCS =
-CSRCS =
-VPATH = .
-
-# Include support for various drivers. Each Make.defs file will add its
-# files to the source file list, add its DEPPATH info, and will add
-# the appropriate paths to the VPATH variable
-
-include analog$(DELIM)Make.defs
-include bch$(DELIM)Make.defs
-include input$(DELIM)Make.defs
-include lcd$(DELIM)Make.defs
-include mmcsd$(DELIM)Make.defs
-include mtd$(DELIM)Make.defs
-include net$(DELIM)Make.defs
-include pipes$(DELIM)Make.defs
-include power$(DELIM)Make.defs
-include sensors$(DELIM)Make.defs
-include sercomm$(DELIM)Make.defs
-include serial$(DELIM)Make.defs
-include syslog$(DELIM)Make.defs
-include usbdev$(DELIM)Make.defs
-include usbhost$(DELIM)Make.defs
-include wireless$(DELIM)Make.defs
-
-ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
- CSRCS += dev_null.c dev_zero.c loop.c
-
-ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y)
- CSRCS += ramdisk.c rwbuffer.c
-endif
-
-ifeq ($(CONFIG_CAN),y)
- CSRCS += can.c
-endif
-
-ifeq ($(CONFIG_PWM),y)
- CSRCS += pwm.c
-endif
-
-ifeq ($(CONFIG_WATCHDOG),y)
- CSRCS += watchdog.c
-endif
-endif
-
-AOBJS = $(ASRCS:.S=$(OBJEXT))
-COBJS = $(CSRCS:.c=$(OBJEXT))
-
-SRCS = $(ASRCS) $(CSRCS)
-OBJS = $(AOBJS) $(COBJS)
-
-BIN = libdrivers$(LIBEXT)
-
-all: $(BIN)
-
-$(AOBJS): %$(OBJEXT): %.S
- $(call ASSEMBLE, $<, $@)
-
-$(COBJS): %$(OBJEXT): %.c
- $(call COMPILE, $<, $@)
-
-$(BIN): $(OBJS)
- $(call ARCHIVE, $@, $(OBJS))
-
-.depend: Makefile $(SRCS)
- $(Q) $(MKDEP) $(DEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
- $(Q) touch $@
-
-depend: .depend
-
-clean:
- $(call DELFILE, $(BIN))
- $(call CLEAN)
-
-distclean: clean
- $(call DELFILE, Make.dep)
- $(call DELFILE, .depend)
-
--include Make.dep
diff --git a/nuttx/drivers/README.txt b/nuttx/drivers/README.txt
deleted file mode 100644
index e27e8c583..000000000
--- a/nuttx/drivers/README.txt
+++ /dev/null
@@ -1,145 +0,0 @@
-README
-^^^^^^
-
-This directory contains various device drivers -- both block and
-character drivers as well as other more specialized drivers.
-
-Contents:
- - Files in this directory
- - Subdirectories of this directory
- - Skeleton files
-
-Files in this directory
-^^^^^^^^^^^^^^^^^^^^^^^
-
-can.c
- This is a CAN driver. See include/nuttx/can.h for usage information.
-
-dev_null.c and dev_zero.c
- These files provide the standard /dev/null and /dev/zero devices.
- See include/nuttx/fs/fs.h for functions that should be called if you
- want to register these devices (devnull_register() and
- devzero_register()).
-
-loop.c
- Supports the standard loop device that can be used to export a
- file (or character device) as a block device. See losetup() and
- loteardown() in include/nuttx/fs/fs.h.
-
-pwm.c
- Provides the "upper half" of a pulse width modulation (PWM) driver.
- The "lower half" of the PWM driver is provided by device-specific
- logic. See include/nuttx/pwm.h for usage information.
-
-ramdisk.c
- Can be used to set up a block of memory or (read-only) FLASH as
- a block driver that can be mounted as a files system. See
- include/nuttx/ramdisk.h.
-
-ramlog.c
- This is a driver that was intended to support debugging output,
- aka syslogging, when the normal serial output is not available.
- For example, if you are using a telnet or USB serial console,
- the debug output will get lost.
-
- This driver is similar to a pipe in that it saves the debugging
- output in a FIFO in RAM. It differs from a pipe in numerous
- details as needed to support logging.
-
- This driver is built when CONFIG_RAMLOG is defined in the Nuttx
- configuration.
-
-rwbuffer.c
- A facility that can be use by any block driver in-order to add
- writing buffering and read-ahead buffering.
-
-Subdirectories of this directory:
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-analog/
- This directory holds implementations of analog device drivers.
- This includes drivers for Analog to Digital Conversion (ADC) as
- well as drivers for Digital to Analog Conversion (DAC).
- See include/nuttx/analog/*.h for registration information.
-
-bch/
- Contains logic that may be used to convert a block driver into
- a character driver. This is the complementary conversion as that
- performed by loop.c. See include/nuttx/fs/fs.h for registration
- information.
-
-input/
- This directory holds implementations of input device drivers.
- This includes such things as touchscreen and keypad drivers.
- See include/nuttx/input/*.h for registration information.
-
-lcd/
- Drivers for parallel and serial LCD and OLED type devices. These
- drivers support interfaces as defined in include/nuttx/lcd/lcd.h
-
-mmcsd/
- Support for MMC/SD block drivers. MMC/SD block drivers based on
- SPI and SDIO/MCI interfaces are supported. See include/nuttx/mmcsd.h
- and include/nuttx/sdio.h for further information.
-
-mtd/
- Memory Technology Device (MTD) drivers. Some simple drivers for
- memory technologies like FLASH, EEPROM, NVRAM, etc. See
- include/nuttx/mtd.h
-
- (Note: This is a simple memory interface and should not be
- confused with the "real" MTD developed at infradead.org. This
- logic is unrelated; I just used the name MTD because I am not
- aware of any other common way to refer to this class of devices).
-
-net/
- Network interface drivers. See also include/nuttx/net/net.h
-
-pipes/
- FIFO and named pipe drivers. Standard interfaces are declared
- in include/unistd.h
-
-power/
- Power management (PM) driver interfaces. These interfaces are used
- to manage power usage of a platform by monitoring driver activity
- and by placing drivers into reduce power usage modes when the
- drivers are not active.
-
-sensors/
- Drivers for various sensors
-
-sercomm/
- Sercomm is the transport used by osmocom-bb that runs on top of serial.
- See http://bb.osmocom.org/trac/wiki/nuttx-bb/run for detailed the usage
- of nuttx with sercomm.
-
- drivers/sercomm is only built if CONFIG_SERCOMM_CONSOLE in the NuttX
- configuration file. If you attempt to build this driver without
- osmocom-bb, you will get compilation errors because of header files
- that are needed from the osmocom-bb.
-
-serial/
- Front-end character drivers for chip-specific UARTs. This provide
- some TTY-like functionality and are commonly used (but not required for)
- the NuttX system console. See also include/nuttx/serial/serial.h
-
-usbdev/
- USB device drivers. See also include/nuttx/usb/usbdev.h
-
-usbhost/
- USB host drivers. See also include/nuttx/usb/usbhost.h
-
-wireless/
- Drivers for various wireless devices.
-
-Skeleton Files
-^^^^^^^^^^^^^^
-
-Skeleton files a "empty" frameworks for NuttX drivers. They are provided to
-give you a good starting point if you want to create a new NuttX driver.
-The following skeleton files are available:
-
- drivers/lcd/skeleton.c -- Skeleton LCD driver
- drivers/mtd/skeleton.c -- Skeleton memory technology device drivers
- drivers/net/skeleton.c -- Skeleton network/Ethernet drivers
- drivers/usbhost/usbhost_skeleton.c -- Skeleton USB host class driver
diff --git a/nuttx/drivers/analog/Kconfig b/nuttx/drivers/analog/Kconfig
deleted file mode 100644
index ebed79c78..000000000
--- a/nuttx/drivers/analog/Kconfig
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-config ADC
- bool "Analog-to-Digital Conversion"
- default n
- ---help---
- Select to enable support for analog input device support. This includes
- not only Analog-to-Digital Converters (ADC) but also amplifiers and
- analog multiplexers.
-
-config ADC_ADS125X
- bool "TI ADS1255/ADS1256 support"
- default n
- depends on ADC
- select SPI
-
-config ADS1255_FREQUENCY
- int "ADS1255/ADS1256 SPI frequency"
- default 1000000
- depends on ADC_ADS125X
-
-config ADC_PGA11X
- bool "TI PGA112/3/6/7 support"
- default n
- depends on ADC
- select SPI
- ---help---
- Enables support for the PGA112, PGA113, PGA116, PGA117 Zerø-Drift
- PROGRAMMABLE GAIN AMPLIFIER with MUX
-
-config PGA11X_SPIFREQUENCY
- int "TI PGA112/3/6/7 SPI frequency"
- default 1000000
- depends on ADC_PGA11X
- ---help---
- PGA11x SPI frequency.
-
-config PGA11X_SPIMODE
- int "TI PGA112/3/6/7 SPI mode"
- default 0
- depends on ADC_PGA11X
- ---help---
- PGA11x SPI mode. The specification says that the device operates in Mode 0 or
- Mode 3. But sometimes you need to tinker with this to get things to work
- correctly. Default: Mode 0
-
-config PGA11X_DAISYCHAIN
- bool "TI PGA112/3/6/7 daisy chain mode"
- default n
- depends on ADC_PGA11X
- ---help---
- Enable support to use two PGA116/7's in Daisy Chain configuration.
-
-config PGA11X_MULTIPLE
- bool "Multiple TI PGA112/3/6/7 support"
- default n
- depends on ADC_PGA11X && !PGA11X_DAISYCHAIN
- ---help---
- Can be defined to support multiple PGA11X devices on board with separate
- chip selects (not daisy chained). Each device will require a customized
- SPI interface to distinguish them when SPI_SELECT is called with
- devid=SPIDEV_MUX.
-
-config DAC
- bool "Digital-to-Analog Conversion"
- default n
- ---help---
- Select to enable support for Digital-to-Analog Converters (DACs).
-
-config DAC_AD5410
- bool "AD5410 support"
- default n
- depends on DAC
- select SPI
diff --git a/nuttx/drivers/analog/Make.defs b/nuttx/drivers/analog/Make.defs
deleted file mode 100644
index 89cc5bd3f..000000000
--- a/nuttx/drivers/analog/Make.defs
+++ /dev/null
@@ -1,87 +0,0 @@
-############################################################################
-# drivers/analog/Make.defs
-#
-# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-# Don't build anything if there is no support for analog devices
-
-# Check for DAC devices
-
-ifeq ($(CONFIG_DAC),y)
-
-# Include the common DAC character driver
-
-CSRCS += dac.c
-
-# Include DAC device drivers
-
-ifeq ($(CONFIG_DAC_AD5410),y)
- CSRCS += ad5410.c
-endif
-endif
-
-# Check for ADC devices
-
-ifeq ($(CONFIG_ADC),y)
-
-# Include the common ADC character driver
-
-CSRCS += adc.c
-
-# Amplifiers/multiplexers
-
-ifeq ($(CONFIG_ADC_PGA11X),y)
- CSRCS += pga11x.c
-endif
-
-# Include ADC device drivers
-
-ifeq ($(CONFIG_ADC_ADS125X),y)
- CSRCS += ads1255.c
-endif
-endif
-
-# Add analog driver build support (the nested if-then-else implements an OR)
-
-ifeq ($(CONFIG_DAC),y)
- DEPPATH += --dep-path analog
- VPATH += :analog
- CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)analog}
-else
-ifeq ($(CONFIG_ADC),y)
- DEPPATH += --dep-path analog
- VPATH += :analog
- CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)analog}
-endif
-endif
-
diff --git a/nuttx/drivers/analog/ad5410.c b/nuttx/drivers/analog/ad5410.c
deleted file mode 100644
index 3e925a3a9..000000000
--- a/nuttx/drivers/analog/ad5410.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/************************************************************************************
- * arch/drivers/analog/ad5410.c
- *
- * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
- * Author: Li Zhuoyi <lzyy.cn@gmail.com>
- * History: 0.1 2011-08-05 initial version
- *
- * This file is a part of NuttX:
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- *
- * 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.
- *
- ************************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <semaphore.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <arch/board/board.h>
-#include <nuttx/arch.h>
-#include <nuttx/analog/dac.h>
-#include <nuttx/spi.h>
-
-#if defined(CONFIG_DAC_AD5410)
-
-#define AD5410_REG_NOP 0x00
-#define AD5410_REG_WR 0x01
-#define AD5410_REG_RD 0x02
-#define AD5410_REG_CMD 0x55
-#define AD5410_REG_RST 0x56
-
-#define AD5410_CMD_REXT (1<<13)
-#define AD5410_CMD_OUTEN (1<<12)
-#define AD5410_CMD_SRCLK(x) (x<<8)
-#define AD5410_CMD_SRSTEP(x) (x<<5)
-#define AD5410_CMD_SREN (1<<4)
-#define AD5410_CMD_DCEN (1<<3)
-#define AD5410_CMD_420MA 0x05
-#define AD5410_CMD_020MA 0x06
-#define AD5410_CMD_024MA 0x07
-
-/****************************************************************************
- * ad_private Types
- ****************************************************************************/
-struct up_dev_s
-{
- int devno;
- FAR struct spi_dev_s *spi; /* Cached SPI device reference */
-};
-
-/****************************************************************************
- * ad_private Function Prototypes
- ****************************************************************************/
-
-/* DAC methods */
-
-static void dac_reset(FAR struct dac_dev_s *dev);
-static int dac_setup(FAR struct dac_dev_s *dev);
-static void dac_shutdown(FAR struct dac_dev_s *dev);
-static void dac_txint(FAR struct dac_dev_s *dev, bool enable);
-static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg);
-static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg);
-static int dac_interrupt(int irq, void *context);
-
-/****************************************************************************
- * ad_private Data
- ****************************************************************************/
-
-static const struct dac_ops_s g_dacops =
-{
- .ao_reset =dac_reset,
- .ao_setup = dac_setup,
- .ao_shutdown = dac_shutdown,
- .ao_txint = dac_txint,
- .ao_send = dac_send,
- .ao_ioctl = dac_ioctl,
-};
-
-static struct up_dev_s g_dacpriv;
-static struct dac_dev_s g_dacdev =
-{
- .ad_ops = &g_dacops,
- .ad_priv= &g_dacpriv,
-};
-
-/****************************************************************************
- * ad_private Functions
- ****************************************************************************/
-
-/* Reset the DAC device. Called early to initialize the hardware. This
-* is called, before ao_setup() and on error conditions.
-*/
-static void dac_reset(FAR struct dac_dev_s *dev)
-{
-
-}
-
-/* Configure the DAC. This method is called the first time that the DAC
-* device is opened. This will occur when the port is first opened.
-* This setup includes configuring and attaching DAC interrupts. Interrupts
-* are all disabled upon return.
-*/
-static int dac_setup(FAR struct dac_dev_s *dev)
-{
- FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
- FAR struct spi_dev_s *spi = priv->spi;
- SPI_SELECT(spi, priv->devno, true);
- SPI_SEND(spi,AD5410_REG_CMD);
- SPI_SEND(spi,(AD5410_CMD_OUTEN|AD5410_CMD_420MA)>>8);
- SPI_SEND(spi,AD5410_CMD_OUTEN|AD5410_CMD_420MA);
- SPI_SELECT(spi, priv->devno, false);
- return OK;
-}
-
-/* Disable the DAC. This method is called when the DAC device is closed.
-* This method reverses the operation the setup method.
-*/
-static void dac_shutdown(FAR struct dac_dev_s *dev)
-{
-}
-
-/* Call to enable or disable TX interrupts */
-static void dac_txint(FAR struct dac_dev_s *dev, bool enable)
-{
-}
-
-static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg)
-{
- FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
- FAR struct spi_dev_s *spi = priv->spi;
- SPI_SELECT(spi, priv->devno, true);
- SPI_SEND(spi,AD5410_REG_WR);
- SPI_SEND(spi,(uint8_t)(msg->am_data>>24));
- SPI_SEND(spi,(uint8_t)(msg->am_data>>16));
- SPI_SELECT(spi, priv->devno, false);
- dac_txdone(&g_dacdev);
- return 0;
-}
-
-/* All ioctl calls will be routed through this method */
-static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg)
-{
- dbg("Fix me:Not Implemented\n");
- return 0;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: up_ad5410cinitialize
- *
- * Description:
- * Initialize the selected DAC port
- *
- * Input Parameter:
- * Port number (for hardware that has mutiple DAC interfaces)
- *
- * Returned Value:
- * Valid ad5410 device structure reference on succcess; a NULL on failure
- *
- ****************************************************************************/
-
-FAR struct dac_dev_s *up_ad5410initialize(FAR struct spi_dev_s *spi, unsigned int devno)
-{
- FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_dacdev.ad_priv;
- priv->spi=spi;
- priv->devno=devno;
- return &g_dacdev;
-}
-#endif
-
diff --git a/nuttx/drivers/analog/adc.c b/nuttx/drivers/analog/adc.c
deleted file mode 100644
index 72f19452a..000000000
--- a/nuttx/drivers/analog/adc.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/****************************************************************************
- * drivers/analog/adc.c
- *
- * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
- * Author: Li Zhuoyi <lzyy.cn@gmail.com>
- * History: 0.1 2011-08-04 initial version
- *
- * Derived from drivers/can.c
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <string.h>
-#include <semaphore.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/arch.h>
-#include <nuttx/analog/adc.h>
-
-#include <arch/irq.h>
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int adc_open(FAR struct file *filep);
-static int adc_close(FAR struct file *filep);
-static ssize_t adc_read(FAR struct file *, FAR char *, size_t);
-static ssize_t adc_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
-static int adc_ioctl(FAR struct file *filep,int cmd,unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations adc_fops =
-{
- adc_open, /* open */
- adc_close, /* close */
- adc_read, /* read */
- adc_write, /* write */
- 0, /* seek */
- adc_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , 0 /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-/************************************************************************************
- * Name: adc_open
- *
- * Description:
- * This function is called whenever the ADC device is opened.
- *
- ************************************************************************************/
-
-static int adc_open(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct adc_dev_s *dev = inode->i_private;
- uint8_t tmp;
- int ret = OK;
-
- /* If the port is the middle of closing, wait until the close is finished */
-
- if (sem_wait(&dev->ad_closesem) != OK)
- {
- ret = -errno;
- }
- else
- {
- /* Increment the count of references to the device. If this the first
- * time that the driver has been opened for this device, then initialize
- * the device.
- */
-
- tmp = dev->ad_ocount + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- }
- else
- {
- /* Check if this is the first time that the driver has been opened. */
-
- if (tmp == 1)
- {
- /* Yes.. perform one time hardware initialization. */
-
- irqstate_t flags = irqsave();
- ret = dev->ad_ops->ao_setup(dev);
- if (ret == OK)
- {
- /* Mark the FIFOs empty */
-
- dev->ad_recv.af_head = 0;
- dev->ad_recv.af_tail = 0;
-
- /* Finally, Enable the ADC RX interrupt */
-
- dev->ad_ops->ao_rxint(dev, true);
-
- /* Save the new open count on success */
-
- dev->ad_ocount = tmp;
- }
-
- irqrestore(flags);
- }
- }
-
- sem_post(&dev->ad_closesem);
- }
- return ret;
-}
-
-/************************************************************************************
- * Name: adc_close
- *
- * Description:
- * This routine is called when the ADC device is closed.
- * It waits for the last remaining data to be sent.
- *
- ************************************************************************************/
-
-static int adc_close(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct adc_dev_s *dev = inode->i_private;
- irqstate_t flags;
- int ret = OK;
-
- if (sem_wait(&dev->ad_closesem) != OK)
- {
- ret = -errno;
- }
- else
- {
- /* Decrement the references to the driver. If the reference count will
- * decrement to 0, then uninitialize the driver.
- */
-
- if (dev->ad_ocount > 1)
- {
- dev->ad_ocount--;
- sem_post(&dev->ad_closesem);
- }
- else
- {
- /* There are no more references to the port */
-
- dev->ad_ocount = 0;
-
- /* Free the IRQ and disable the ADC device */
-
- flags = irqsave(); /* Disable interrupts */
- dev->ad_ops->ao_shutdown(dev); /* Disable the ADC */
- irqrestore(flags);
-
- sem_post(&dev->ad_closesem);
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: adc_read
- ****************************************************************************/
-
-static ssize_t adc_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct adc_dev_s *dev = inode->i_private;
- size_t nread;
- irqstate_t flags;
- int ret = 0;
- int msglen;
-
- avdbg("buflen: %d\n", (int)buflen);
-
- if (buflen % 5 == 0)
- msglen = 5;
- else if (buflen % 4 == 0)
- msglen = 4;
- else if (buflen % 3 == 0)
- msglen = 3;
- else if (buflen % 2 == 0)
- msglen = 2;
- else if (buflen == 1)
- msglen = 1;
- else
- msglen = 5;
-
- if (buflen >= msglen)
- {
- /* Interrupts must be disabled while accessing the ad_recv FIFO */
-
- flags = irqsave();
- while (dev->ad_recv.af_head == dev->ad_recv.af_tail)
- {
- /* The receive FIFO is empty -- was non-blocking mode selected? */
-
- if (filep->f_oflags & O_NONBLOCK)
- {
- ret = -EAGAIN;
- goto return_with_irqdisabled;
- }
-
- /* Wait for a message to be received */
-
- dev->ad_nrxwaiters++;
- ret = sem_wait(&dev->ad_recv.af_sem);
- dev->ad_nrxwaiters--;
- if (ret < 0)
- {
- ret = -errno;
- goto return_with_irqdisabled;
- }
- }
-
- /* The ad_recv FIFO is not empty. Copy all buffered data that will fit
- * in the user buffer.
- */
-
- nread = 0;
- do
- {
- FAR struct adc_msg_s *msg = &dev->ad_recv.af_buffer[dev->ad_recv.af_head];
-
- /* Will the next message in the FIFO fit into the user buffer? */
-
- if (nread + msglen > buflen)
- {
- /* No.. break out of the loop now with nread equal to the actual
- * number of bytes transferred.
- */
-
- break;
- }
-
- /* Copy the message to the user buffer */
-
- if (msglen == 1)
- {
- /* Only one channel,read highest 8-bits */
-
- buffer[nread] = msg->am_data >> 24;
- }
- else if (msglen == 2)
- {
- /* Only one channel, read highest 16-bits */
-
- *(int16_t *)&buffer[nread] = msg->am_data >> 16;
- }
- else if (msglen == 3)
- {
- /* Read channel highest 16-bits */
-
- buffer[nread] = msg->am_channel;
- *(int16_t *)&buffer[nread + 1] = msg->am_data >> 16;
- }
- else if (msglen == 4)
- {
- /* read channel highest 24-bits */
-
- *(int32_t *)&buffer[nread] = msg->am_data;
- buffer[nread] = msg->am_channel;
- }
- else
- {
- /* Read all */
-
- *(int32_t *)&buffer[nread + 1] = msg->am_data;
- buffer[nread] = msg->am_channel;
- }
- nread += msglen;
-
- /* Increment the head of the circular message buffer */
-
- if (++dev->ad_recv.af_head >= CONFIG_ADC_FIFOSIZE)
- {
- dev->ad_recv.af_head = 0;
- }
- }
- while (dev->ad_recv.af_head != dev->ad_recv.af_tail);
-
- /* All on the messages have bee transferred. Return the number of bytes
- * that were read.
- */
-
- ret = nread;
-
-return_with_irqdisabled:
- irqrestore(flags);
- }
-
- avdbg("Returning: %d\n", ret);
- return ret;
-}
-
-/************************************************************************************
- * Name: adc_write
- ************************************************************************************/
-
-static ssize_t adc_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
-{
- return 0;
-}
-
-/************************************************************************************
- * Name: adc_ioctl
- ************************************************************************************/
-
-static int adc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct adc_dev_s *dev = inode->i_private;
- int ret = OK;
-
- ret = dev->ad_ops->ao_ioctl(dev, cmd, arg);
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: adc_receive
- ****************************************************************************/
-
-int adc_receive(FAR struct adc_dev_s *dev, uint8_t ch, int32_t data)
-{
- FAR struct adc_fifo_s *fifo = &dev->ad_recv;
- int nexttail;
- int err = -ENOMEM;
-
- /* Check if adding this new message would over-run the drivers ability to enqueue
- * read data.
- */
-
- nexttail = fifo->af_tail + 1;
- if (nexttail >= CONFIG_ADC_FIFOSIZE)
- {
- nexttail = 0;
- }
-
- /* Refuse the new data if the FIFO is full */
-
- if (nexttail != fifo->af_head)
- {
- /* Add the new, decoded ADC sample at the tail of the FIFO */
-
- fifo->af_buffer[fifo->af_tail].am_channel = ch;
- fifo->af_buffer[fifo->af_tail].am_data = data;
-
- /* Increment the tail of the circular buffer */
-
- fifo->af_tail = nexttail;
-
- if (dev->ad_nrxwaiters > 0)
- {
- sem_post(&fifo->af_sem);
- }
-
- err = OK;
- }
- return err;
-}
-
-/****************************************************************************
- * Name: adc_register
- ****************************************************************************/
-
-int adc_register(FAR const char *path, FAR struct adc_dev_s *dev)
-{
- /* Initialize the ADC device structure */
-
- dev->ad_ocount = 0;
-
- sem_init(&dev->ad_recv.af_sem, 0, 0);
- sem_init(&dev->ad_closesem, 0, 1);
-
- dev->ad_ops->ao_reset(dev);
-
- return register_driver(path, &adc_fops, 0444, dev);
-}
diff --git a/nuttx/drivers/analog/ads1255.c b/nuttx/drivers/analog/ads1255.c
deleted file mode 100644
index 374decc54..000000000
--- a/nuttx/drivers/analog/ads1255.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/************************************************************************************
- * arch/drivers/analog/ads1255.c
- *
- * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
- * Author: Li Zhuoyi <lzyy.cn@gmail.com>
- * History: 0.1 2011-08-05 initial version
- * 0.2 2011-08-25 fix bug in g_adcdev (cd_ops -> ad_ops,cd_priv -> ad_priv)
- *
- * This file is a part of NuttX:
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- *
- * 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.
- *
- ************************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <semaphore.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <arch/board/board.h>
-#include <nuttx/arch.h>
-#include <nuttx/spi.h>
-#include <nuttx/analog/adc.h>
-
-#if defined(CONFIG_ADC_ADS1255)
-
-#define ADS125X_BUFON 0x02
-#define ADS125X_BUFOFF 0x00
-
-#define ADS125X_PGA1 0x00
-#define ADS125X_PGA2 0x01
-#define ADS125X_PGA4 0x02
-#define ADS125X_PGA8 0x03
-#define ADS125X_PGA16 0x04
-#define ADS125X_PGA32 0x05
-#define ADS125X_PGA64 0x06
-
-#define ADS125X_RDATA 0x01 //Read Data
-#define ADS125X_RDATAC 0x03 //Read Data Continuously
-#define ADS125X_SDATAC 0x0F //Stop Read Data Continuously
-#define ADS125X_RREG 0x10 //Read from REG
-#define ADS125X_WREG 0x50 //Write to REG
-#define ADS125X_SELFCAL 0xF0 //Offset and Gain Self-Calibration
-#define ADS125X_SELFOCAL 0xF1 //Offset Self-Calibration
-#define ADS125X_SELFGCAL 0xF2 //Gain Self-Calibration
-#define ADS125X_SYSOCAL 0xF3 //System Offset Calibration
-#define ADS125X_SYSGCAL 0xF4 //System Gain Calibration
-#define ADS125X_SYNC 0xFC //Synchronize the A/D Conversion
-#define ADS125X_STANDBY 0xFD //Begin Standby Mode
-#define ADS125X_RESET 0xFE //Reset to Power-Up Values
-#define ADS125X_WAKEUP 0xFF //Completes SYNC and Exits Standby Mode
-
-#ifndef CONFIG_ADS1255_FREQUENCY
-#define CONFIG_ADS1255_FREQUENCY 1000000
-#endif
-#ifndef CONFIG_ADS1255_MUX
-#define CONFIG_ADS1255_MUX 0x01
-#endif
-#ifndef CONFIG_ADS1255_CHMODE
-#define CONFIG_ADS1255_CHMODE 0x00
-#endif
-#ifndef CONFIG_ADS1255_BUFON
-#define CONFIG_ADS1255_BUFON 1
-#endif
-#ifndef CONFIG_ADS1255_PGA
-#define CONFIG_ADS1255_PGA ADS125X_PGA2
-#endif
-#ifndef CONFIG_ADS1255_SPS
-#define CONFIG_ADS1255_SPS 50
-#endif
-
-/****************************************************************************
- * ad_private Types
- ****************************************************************************/
-
-struct up_dev_s
-{
- uint8_t channel;
- uint32_t sps;
- uint8_t pga;
- uint8_t buf;
- const uint8_t *mux;
- int irq;
- int devno;
- FAR struct spi_dev_s *spi; /* Cached SPI device reference */
-};
-
-/****************************************************************************
- * ad_private Function Prototypes
- ****************************************************************************/
-
-/* ADC methods */
-
-static void adc_reset(FAR struct adc_dev_s *dev);
-static int adc_setup(FAR struct adc_dev_s *dev);
-static void adc_shutdown(FAR struct adc_dev_s *dev);
-static void adc_rxint(FAR struct adc_dev_s *dev, bool enable);
-static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg);
-static int adc_interrupt(int irq, void *context);
-
-/****************************************************************************
- * ad_private Data
- ****************************************************************************/
-
-static const struct adc_ops_s g_adcops =
-{
- .ao_reset = adc_reset, /* ao_reset */
- .ao_setup = adc_setup, /* ao_setup */
- .ao_shutdown = adc_shutdown, /* ao_shutdown */
- .ao_rxint = adc_rxint, /* ao_rxint */
- .ao_ioctl = adc_ioctl /* ao_read */
-};
-
-static struct up_dev_s g_adcpriv =
-{
- .mux = (const uint8_t [])
- {
- CONFIG_ADS1255_MUX,0
- },
- .sps = CONFIG_ADS1255_SPS,
- .channel = 0,
- .irq = CONFIG_ADS1255_IRQ,
-};
-
-static struct adc_dev_s g_adcdev =
-{
- .ad_ops = &g_adcops,
- .ad_priv= &g_adcpriv,
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-static uint8_t getspsreg(uint16_t sps)
-{
- static const unsigned short sps_tab[]=
- {
- 3,7,12,20,27,40,55,80,300,750,1500,3000,5000,10000,20000,65535,
- };
- static const unsigned char sps_reg[]=
- {
- 0x03,0x13,0x23,0x33,0x43,0x53,0x63,0x72,0x82,0x92,0xa1,0xb0,0xc0,0xd0,0xe0,0xf0,
- };
- int i;
- for (i=0; i<16; i++)
- {
- if (sps<sps_tab[i])
- break;
- }
- return sps_reg[i];
-}
-
-/****************************************************************************
- * ad_private Functions
- ****************************************************************************/
-/* Reset the ADC device. Called early to initialize the hardware. This
-* is called, before ao_setup() and on error conditions.
-*/
-
-static void adc_reset(FAR struct adc_dev_s *dev)
-{
- FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
- FAR struct spi_dev_s *spi = priv->spi;
-
- SPI_SETMODE(spi, SPIDEV_MODE1);
- SPI_SETBITS(spi, 8);
- SPI_SETFREQUENCY(spi, CONFIG_ADS1255_FREQUENCY);
- usleep(1000);
- SPI_SELECT(spi, priv->devno, true);
- SPI_SEND(spi,ADS125X_WREG+0x03); //WRITE SPS REG
- SPI_SEND(spi,0x00); //count=1
- SPI_SEND(spi,0x63);
- SPI_SELECT(spi, priv->devno, false);
-}
-
-/* Configure the ADC. This method is called the first time that the ADC
-* device is opened. This will occur when the port is first opened.
-* This setup includes configuring and attaching ADC interrupts. Interrupts
-* are all disabled upon return.
-*/
-
-static int adc_setup(FAR struct adc_dev_s *dev)
-{
- FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
- FAR struct spi_dev_s *spi = priv->spi;
- int ret = irq_attach(priv->irq, adc_interrupt);
- if (ret == OK)
- {
- SPI_SELECT(spi, priv->devno, true);
- SPI_SEND(spi,ADS125X_WREG); //WRITE REG from 0
- SPI_SEND(spi,0x03); //count=4+1
- if (priv->buf)
- SPI_SEND(spi,ADS125X_BUFON); //REG0 STATUS BUFFER ON
- else
- SPI_SEND(spi,ADS125X_BUFOFF);
- SPI_SEND(spi,priv->mux[0]);
- SPI_SEND(spi,priv->pga); //REG2 ADCON PGA=2
- SPI_SEND(spi,getspsreg(priv->sps));
- usleep(1000);
- SPI_SEND(spi,ADS125X_SELFCAL);
- SPI_SELECT(spi, priv->devno, false);
- up_enable_irq(priv->irq);
- }
- return ret;
-}
-
-/* Disable the ADC. This method is called when the ADC device is closed.
-* This method reverses the operation the setup method.
-*/
-
-static void adc_shutdown(FAR struct adc_dev_s *dev)
-{
- FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
- up_disable_irq(priv->irq);
- irq_detach(priv->irq);
-}
-
-/* Call to enable or disable RX interrupts */
-
-static void adc_rxint(FAR struct adc_dev_s *dev, bool enable)
-{
- FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
- if (enable)
- up_enable_irq(priv->irq);
- else
- up_disable_irq(priv->irq);
-}
-
-/* All ioctl calls will be routed through this method */
-
-static int adc_ioctl(FAR struct adc_dev_s *dev, int cmd, unsigned long arg)
-{
- dbg("Fix me:Not Implemented\n");
- return 0;
-}
-
-static int adc_interrupt(int irq, void *context)
-{
- uint32_t regval;
- FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv;
- FAR struct spi_dev_s *spi = priv->spi;
- unsigned char buf[4];
- unsigned char ch;
-
- SPI_SELECT(spi, priv->devno, true);
- SPI_SEND(spi,ADS125X_RDATA);
- up_udelay(10);
- buf[3]=SPI_SEND(spi,0xff);
- buf[2]=SPI_SEND(spi,0xff);
- buf[1]=SPI_SEND(spi,0xff);
- buf[0]=0;
-
- priv->channel++;
- ch = priv->mux[priv->channel];
- if ( ch == 0 )
- {
- priv->channel=0;
- ch = priv->mux[0];
- }
-
- SPI_SEND(spi,ADS125X_WREG+0x01);
- SPI_SEND(spi,0x00);
- SPI_SEND(spi,ch);
- SPI_SEND(spi,ADS125X_SYNC);
- up_udelay(2);
- SPI_SEND(spi,ADS125X_WAKEUP);
- SPI_SELECT(spi, priv->devno, false);
-
- adc_receive(&g_adcdev,priv->channel,*(int32_t *)buf);
- return OK;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: up_ads1255initialize
- *
- * Description:
- * Initialize the selected adc port
- *
- * Input Parameter:
- * Port number (for hardware that has mutiple adc interfaces)
- *
- * Returned Value:
- * Valid can device structure reference on succcess; a NULL on failure
- *
- ****************************************************************************/
-
-FAR struct adc_dev_s *up_ads1255initialize(FAR struct spi_dev_s *spi, unsigned int devno)
-{
- FAR struct up_dev_s *priv = (FAR struct up_dev_s *)g_adcdev.ad_priv;
-
- /* Driver state data */
-
- priv->spi = spi;
- priv->devno = devno;
- return &g_adcdev;
-}
-#endif
-
diff --git a/nuttx/drivers/analog/dac.c b/nuttx/drivers/analog/dac.c
deleted file mode 100644
index e1fc3049f..000000000
--- a/nuttx/drivers/analog/dac.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/****************************************************************************
- * drivers/analog/dac.c
- *
- * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
- * Author: Li Zhuoyi <lzyy.cn@gmail.com>
- * History: 0.1 2011-08-04 initial version
- *
- * Derived from drivers/can.c
- *
- * Copyright (C) 2008-2009Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <string.h>
-#include <semaphore.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/arch.h>
-#include <nuttx/analog/dac.h>
-
-#include <arch/irq.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#define HALF_SECOND_MSEC 500
-#define HALF_SECOND_USEC 500000L
-
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int dac_open(FAR struct file *filep);
-static int dac_close(FAR struct file *filep);
-static ssize_t dac_read(FAR struct file *, FAR char *, size_t);
-static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
-static int dac_ioctl(FAR struct file *filep,int cmd,unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations dac_fops =
-{
- dac_open,
- dac_close,
- dac_read,
- dac_write,
- 0,
- dac_ioctl
-#ifndef CONFIG_DISABLE_POLL
- , 0
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-/************************************************************************************
- * Name: dac_open
- *
- * Description:
- * This function is called whenever the DAC device is opened.
- *
- ************************************************************************************/
-
-static int dac_open(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct dac_dev_s *dev = inode->i_private;
- uint8_t tmp;
- int ret = OK;
-
- /* If the port is the middle of closing, wait until the close is finished */
-
- if (sem_wait(&dev->ad_closesem) != OK)
- {
- ret = -errno;
- }
- else
- {
- /* Increment the count of references to the device. If this the first
- * time that the driver has been opened for this device, then initialize
- * the device.
- */
-
- tmp = dev->ad_ocount + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- }
- else
- {
- /* Check if this is the first time that the driver has been opened. */
-
- if (tmp == 1)
- {
- /* Yes.. perform one time hardware initialization. */
-
- irqstate_t flags = irqsave();
- ret = dev->ad_ops->ao_setup(dev);
- if (ret == OK)
- {
- /* Mark the FIFOs empty */
-
- dev->ad_xmit.af_head = 0;
- dev->ad_xmit.af_tail = 0;
-
- /* Save the new open count on success */
-
- dev->ad_ocount = tmp;
- }
- irqrestore(flags);
- }
- }
- sem_post(&dev->ad_closesem);
- }
- return ret;
-}
-
-/************************************************************************************
- * Name: dac_close
- *
- * Description:
- * This routine is called when the DAC device is closed.
- * It waits for the last remaining data to be sent.
- *
- ************************************************************************************/
-
-static int dac_close(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct dac_dev_s *dev = inode->i_private;
- irqstate_t flags;
- int ret = OK;
-
- if (sem_wait(&dev->ad_closesem) != OK)
- {
- ret = -errno;
- }
- else
- {
- /* Decrement the references to the driver. If the reference count will
- * decrement to 0, then uninitialize the driver.
- */
-
- if (dev->ad_ocount > 1)
- {
- dev->ad_ocount--;
- sem_post(&dev->ad_closesem);
- }
- else
- {
- /* There are no more references to the port */
-
- dev->ad_ocount = 0;
-
- /* Now we wait for the transmit FIFO to clear */
-
- while (dev->ad_xmit.af_head != dev->ad_xmit.af_tail)
- {
-#ifndef CONFIG_DISABLE_SIGNALS
- usleep(HALF_SECOND_USEC);
-#else
- up_mdelay(HALF_SECOND_MSEC);
-#endif
- }
-
- /* Free the IRQ and disable the DAC device */
-
- flags = irqsave(); /* Disable interrupts */
- dev->ad_ops->ao_shutdown(dev); /* Disable the DAC */
- irqrestore(flags);
-
- sem_post(&dev->ad_closesem);
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: dac_read
- ****************************************************************************/
-
-static ssize_t dac_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- return 0;
-}
-
-/************************************************************************************
- * Name: dac_xmit
- *
- * Description:
- * Send the message at the head of the ad_xmit FIFO
- *
- * Assumptions:
- * Called with interrupts disabled
- *
- ************************************************************************************/
-
-static int dac_xmit(FAR struct dac_dev_s *dev)
-{
- bool enable = false;
- int ret = OK;
-
- /* Check if the xmit FIFO is empty */
-
- if (dev->ad_xmit.af_head != dev->ad_xmit.af_tail)
- {
- /* Send the next message at the head of the FIFO */
-
- ret = dev->ad_ops->ao_send(dev, &dev->ad_xmit.af_buffer[dev->ad_xmit.af_head]);
-
- /* Make sure the TX done interrupts are enabled */
-
- enable = (ret == OK ? true : false);
- }
- dev->ad_ops->ao_txint(dev, enable);
- return ret;
-}
-
-/************************************************************************************
- * Name: dac_write
- ************************************************************************************/
-
-static ssize_t dac_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct dac_dev_s *dev = inode->i_private;
- FAR struct dac_fifo_s *fifo = &dev->ad_xmit;
- FAR struct dac_msg_s *msg;
- bool empty = false;
- ssize_t nsent = 0;
- irqstate_t flags;
- int nexttail;
- int msglen;
- int ret = 0;
-
- /* Interrupts must disabled throughout the following */
-
- flags = irqsave();
-
- /* Check if the TX FIFO was empty when we started. That is a clue that we have
- * to kick off a new TX sequence.
- */
-
- empty = (fifo->af_head == fifo->af_tail);
-
- /* Add the messages to the FIFO. Ignore any trailing messages that are
- * shorter than the minimum.
- */
-
- if (buflen % 5 ==0 )
- msglen=5;
- else if (buflen % 4 ==0 )
- msglen=4;
- else if (buflen % 3 ==0 )
- msglen=3;
- else if (buflen % 2 ==0 )
- msglen=2;
- else if (buflen == 1)
- msglen=1;
- else
- msglen=5;
-
- while ((buflen - nsent) >= msglen )
- {
- /* Check if adding this new message would over-run the drivers ability to enqueue
- * xmit data.
- */
-
- nexttail = fifo->af_tail + 1;
- if (nexttail >= CONFIG_DAC_FIFOSIZE)
- {
- nexttail = 0;
- }
-
- /* If the XMIT fifo becomes full, then wait for space to become available */
-
- while (nexttail == fifo->af_head)
- {
- /* The transmit FIFO is full -- was non-blocking mode selected? */
-
- if (filep->f_oflags & O_NONBLOCK)
- {
- if (nsent == 0)
- {
- ret = -EAGAIN;
- }
- else
- {
- ret = nsent;
- }
- goto return_with_irqdisabled;
- }
-
- /* If the FIFO was empty when we started, then we will have
- * start the XMIT sequence to clear the FIFO.
- */
-
- if (empty)
- {
- dac_xmit(dev);
- }
-
- /* Wait for a message to be sent */
-
- do
- {
- ret = sem_wait(&fifo->af_sem);
- if (ret < 0 && errno != EINTR)
- {
- ret = -errno;
- goto return_with_irqdisabled;
- }
- }
- while (ret < 0);
-
- /* Re-check the FIFO state */
-
- empty = (fifo->af_head == fifo->af_tail);
- }
-
- /* We get here if there is space at the end of the FIFO. Add the new
- * CAN message at the tail of the FIFO.
- */
-
- if (msglen==5)
- {
- msg = (FAR struct dac_msg_s *)&buffer[nsent];
- memcpy(&fifo->af_buffer[fifo->af_tail], msg, msglen);
- }
- else if(msglen == 4)
- {
- fifo->af_buffer[fifo->af_tail].am_channel=buffer[nsent];
- fifo->af_buffer[fifo->af_tail].am_data=*(uint32_t *)&buffer[nsent];
- fifo->af_buffer[fifo->af_tail].am_data&=0xffffff00;
- }
- else if(msglen == 3)
- {
- fifo->af_buffer[fifo->af_tail].am_channel=buffer[nsent];
- fifo->af_buffer[fifo->af_tail].am_data=(*(uint16_t *)&buffer[nsent+1]);
- fifo->af_buffer[fifo->af_tail].am_data<<=16;
- }
- else if(msglen == 2)
- {
- fifo->af_buffer[fifo->af_tail].am_channel=0;
- fifo->af_buffer[fifo->af_tail].am_data=(*(uint16_t *)&buffer[nsent]);
- fifo->af_buffer[fifo->af_tail].am_data<<=16;
- }
- else if(msglen == 1)
- {
- fifo->af_buffer[fifo->af_tail].am_channel=0;
- fifo->af_buffer[fifo->af_tail].am_data=buffer[nsent];
- fifo->af_buffer[fifo->af_tail].am_data<<=24;
- }
- /* Increment the tail of the circular buffer */
-
- fifo->af_tail = nexttail;
-
- /* Increment the number of bytes that were sent */
-
- nsent += msglen;
- }
-
- /* We get here after all messages have been added to the FIFO. Check if
- * we need to kick of the XMIT sequence.
- */
-
- if (empty)
- {
- dac_xmit(dev);
- }
-
- /* Return the number of bytes that were sent */
-
- ret = nsent;
-
-return_with_irqdisabled:
- irqrestore(flags);
- return ret;
-}
-
-/************************************************************************************
- * Name: dac_ioctl
- ************************************************************************************/
-
-static int dac_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct dac_dev_s *dev = inode->i_private;
- int ret = OK;
-
- ret = dev->ad_ops->ao_ioctl(dev, cmd, arg);
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/************************************************************************************
- * Name: dac_txdone
- *
- * Description:
- * Called from the DAC interrupt handler at the completion of a send operation.
- *
- * Return:
- * OK on success; a negated errno on failure.
- *
- ************************************************************************************/
-
-int dac_txdone(FAR struct dac_dev_s *dev)
-{
- int ret = -ENOENT;
-
- /* Verify that the xmit FIFO is not empty */
-
- if (dev->ad_xmit.af_head != dev->ad_xmit.af_tail)
- {
- /* Remove the message at the head of the xmit FIFO */
-
- if (++dev->ad_xmit.af_head >= CONFIG_DAC_FIFOSIZE)
- {
- dev->ad_xmit.af_head = 0;
- }
-
- /* Send the next message in the FIFO */
-
- ret = dac_xmit(dev);
- if (ret == OK)
- {
- /* Inform any waiting threads that new xmit space is available */
-
- ret = sem_post(&dev->ad_xmit.af_sem);
- }
- }
- return ret;
-}
-
-int dac_register(FAR const char *path, FAR struct dac_dev_s *dev)
-{
- /* Initialize the DAC device structure */
-
- dev->ad_ocount = 0;
-
- sem_init(&dev->ad_xmit.af_sem, 0, 0);
- sem_init(&dev->ad_closesem, 0, 1);
-
- dev->ad_ops->ao_reset(dev);
-
- return register_driver(path, &dac_fops, 0555, dev);
-}
-
diff --git a/nuttx/drivers/analog/pga11x.c b/nuttx/drivers/analog/pga11x.c
deleted file mode 100644
index 7bb4a11bb..000000000
--- a/nuttx/drivers/analog/pga11x.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/****************************************************************************
- * drivers/analog/pga11x.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "PGA112, PGA113, PGA116, PGA117: Zerø-Drift PROGRAMMABLE GAIN AMPLIFIER
- * with MUX", SBOS424B, March 2008, Revised September 2008, Texas
- * Instruments Incorporated"
- *
- * 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 <nuttx/config.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/analog/pga11x.h>
-
-#if defined(CONFIG_ADC) && defined(CONFIG_ADC_PGA11X)
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* The PGA112/PGA113 have a three-wire SPI digital interface; the
- * PGA116/PGA117 have a four-wire SPI digital interface. The PGA116/117 also
- * have daisy-chain capability (The PGA112/PGA113 can be used as the last device
- * in a daisy-chain as shown if write-only communication is acceptable).
- */
-
-/* PGA11x commands (PGA112/PGA113) */
-
-#define PGA11X_CMD_READ 0x6a00
-#define PGA11X_CMD_WRITE 0x2a00
-#define PGA11X_CMD_NOOP 0x0000
-#define PGA11X_CMD_SDN_DIS 0xe100
-#define PGA11X_CMD_SDN_EN 0xe1f1
-
-/* SPI Daisy-Chain Commands (PGA116/PGA117) */
-
-#define PGA11X_DCCMD_SELECTOR 0x8000
-#define PGA11X_DCCMD_NOOP (PGA11X_DCCMD_SELECTOR | PGA11X_CMD_NOOP)
-#define PGA11X_DCCMD_SDN_DIS (PGA11X_DCCMD_SELECTOR | PGA11X_CMD_SDN_DIS)
-#define PGA11X_DCCMD_SDN_EN (PGA11X_DCCMD_SELECTOR | PGA11X_CMD_SDN_EN)
-#define PGA11X_DCCMD_READ (PGA11X_DCCMD_SELECTOR | PGA11X_CMD_READ)
-#define PGA11X_DCCMD_WRITE (PGA11X_DCCMD_SELECTOR | PGA11X_CMD_WRITE)
-
-/* Write command Gain Selection Bits (PGA112/PGA113)
- *
- * the PGA112 and PGA116 provide binary gain selections (1, 2, 4, 8, 16, 32,
- * 64, 128); the PGA113 and PGA117 provide scope gain selections (1, 2, 5, 10,
- * 20, 50, 100, 200).
- */
-
-#define PGA11X_GAIN_SHIFT (4) /* Bits 4-7: Gain Selection Bits */
-#define PGA11X_GAIN_MASK (15 << PGA11X_GAIN_SHIFT)
-
-/* Write command Mux Channel Selection Bits
- *
- * The PGA112/PGA113 have a two-channel input MUX; the PGA116/PGA117 have a
- * 10-channel input MUX.
- */
-
-#define PGA11X_CHAN_SHIFT (0) /* Bits 0-3: Channel Selection Bits */
-#define PGA11X_CHAN_MASK (15 << PGA11X_CHAN_SHIFT)
-
-/* Other definitions ********************************************************/
-
-#define SPI_DUMMY 0xff
-
-/* Debug ********************************************************************/
-/* Check if (non-standard) SPI debug is enabled */
-
-#ifndef CONFIG_DEBUG
-# undef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_DEBUG_SPI
-#endif
-
-#ifdef CONFIG_DEBUG_SPI
-# define spidbg dbg
-# ifdef CONFIG_DEBUG_VERBOSE
-# define spivdbg dbg
-# else
-# define spivdbg(x...)
-# endif
-#else
-# define spidbg(x...)
-# define spivdbg(x...)
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pga11x_configure
- *
- * Description:
- * Configure the SPI bus as needed for the PGA11x device.
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-static void pga11x_configure(FAR struct spi_dev_s *spi)
-{
- spivdbg("MODE: %d BITS: 8 Frequency: %d\n",
- CONFIG_PGA11X_SPIMODE, CONFIG_PGA11X_SPIFREQUENCY);
-
- /* Call the setfrequency, setbits, and setmode methods to make sure that
- * the SPI is properly configured for the device.
- */
-
- SPI_SETMODE(spi, CONFIG_PGA11X_SPIMODE);
- SPI_SETBITS(spi, 8);
- (void)SPI_SETFREQUENCY(spi, CONFIG_PGA11X_SPIFREQUENCY);
-}
-
-/****************************************************************************
- * Name: pga11x_lock
- *
- * Description:
- * Lock the SPI bus and configure it as needed for the PGA11x device.
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static void pga11x_lock(FAR struct spi_dev_s *spi)
-{
- spivdbg("Locking\n");
-
- /* On SPI busses where there are multiple devices, it will be necessary to
- * lock SPI to have exclusive access to the busses for a sequence of
- * transfers. The bus should be locked before the chip is selected.
- *
- * This is a blocking call and will not return until we have exclusiv access to
- * the SPI buss. We will retain that exclusive access until the bus is unlocked.
- */
-
- SPI_LOCK(spi, true);
-
- /* After locking the SPI bus, the we also need call the setfrequency, setbits, and
- * setmode methods to make sure that the SPI is properly configured for the device.
- * If the SPI buss is being shared, then it may have been left in an incompatible
- * state.
- */
-
- pga11x_configure(spi);
-}
-#else
-# define pga11x_lock(spi)
-#endif
-
-/****************************************************************************
- * Name: pga11x_unlock
- *
- * Description:
- * Lock the SPI bus and configure it as needed for the PGA11x device.
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static inline void pga11x_unlock(FAR struct spi_dev_s *spi)
-{
- spivdbg("Unlocking\n");
-
- SPI_LOCK(spi, false);
-}
-#else
-# define pga11x_unlock(spi)
-#endif
-
-/****************************************************************************
- * Name: pga11x_send16
- *
- * Description:
- * Send 16 bits of data, ignoring any returned data
- *
- * Input Parameters:
- * spi - PGA11X driver instance
- * word - The data to send
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * The bus is locked and the device is selected
- *
- ****************************************************************************/
-
-static void pga11x_send16(FAR struct spi_dev_s *spi, uint16_t word)
-{
- spivdbg("Send %04x\n", word);
-
- /* The logical interface is 16-bits wide. However, this driver uses a
- * 8-bit configuration for greaer portability.
- *
- * Send the MS byte first. Then the LS byte.
- */
-
- SPI_SEND(spi, word >> 8);
- SPI_SEND(spi, word & 0xff);
-}
-
-/****************************************************************************
- * Name: pga11x_recv16
- *
- * Description:
- * Receive 16 bits of data.
- *
- * Input Parameters:
- * spi - PGA11X driver instance
- *
- * Returned Value:
- * The received 16-bit value
- *
- * Assumptions:
- * The bus is locked and the device is selected
- *
- ****************************************************************************/
-
-static uint16_t pga11x_recv16(FAR struct spi_dev_s *spi)
-{
- uint8_t msb;
- uint8_t lsb;
-
- /* The logical interface is 16-bits wide. However, this driver uses a
- * 8-bit configuration for greaer portability.
- *
- * Send a dummy byte and receive MS byte first. Then the LS byte.
- */
-
- msb = SPI_SEND(spi, SPI_DUMMY);
- lsb = SPI_SEND(spi, SPI_DUMMY);
- spivdbg("Received %02x %02x\n", msb, lsb);
-
- return ((uint16_t)msb << 8) | (uint16_t)lsb;
-}
-
-/****************************************************************************
- * Name: pga11x_write
- *
- * Description:
- * Send a 16-bit command.
- *
- * Input Parameters:
- * spi - PGA11X driver instance
- * cmd - PGA11X command (non-daisy chained)
- * u1cmd - PGA11X U1 command (daisy chained)
- * u2cmd - PGA11X U2 command (daisy chained)
- *
- * Returned Value:
- * The received 16-bit value
- *
- * Assumptions:
- * The device is NOT selected and the NOT bus is locked.
- *
- ****************************************************************************/
-
-#ifndef CONFIG_PGA11X_DAISYCHAIN
-static void pga11x_write(FAR struct spi_dev_s *spi, uint16_t cmd)
-{
- spivdbg("cmd %04x\n", cmd);
-
- /* Lock, select, send the 16-bit command, de-select, and un-lock. */
-
- pga11x_lock(spi);
- SPI_SELECT(spi, SPIDEV_MUX, true);
- pga11x_send16(spi, cmd);
- SPI_SELECT(spi, SPIDEV_MUX, false);
- pga11x_unlock(spi);
-}
-#else
-static void pga11x_write(FAR struct spi_dev_s *spi, uint16_t u1cmd, uint16_t u2cmd)
-{
- spivdbg("U1 cmd: %04x U2 cmd: %04x\n", u1cmd, u2cmd);
-
- /* Lock, select, send the U2 16-bit command, the U1 16-bit command, de-select,
- * and un-lock.
- */
-
- pga11x_lock(spi);
- SPI_SELECT(spi, SPIDEV_MUX, true);
- pga11x_send16(spi, u2cmd);
- pga11x_send16(spi, u1cmd);
- SPI_SELECT(spi, SPIDEV_MUX, false);
- pga11x_unlock(spi);
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pga11x_initialize
- *
- * Description:
- * Initialize the PGA117 amplifier/multiplexer(s).
- *
- * Input Parameters:
- * spi - An SPI "bottom half" device driver instance
- *
- * Returned Value:
- * On success, a non-NULL opaque handle is returned; a NULL is returned
- * on any failure. This handle may be used with the other PGA117 interface
- * functions to control the multiplexer
- *
- ****************************************************************************/
-
-PGA11X_HANDLE pga11x_initialize(FAR struct spi_dev_s *spi)
-{
- spivdbg("Entry\n");
-
- /* Configure the SPI us for the device. Do this now only if the PGA11X is
- * the only device on the bus.
- */
-
-#ifdef CONFIG_SPI_OWNBUS
- pga11x_configure(spi);
-#endif
-
- /* No other special state is required, just return the SPI driver instance
- * as the handle. This gives us a place to extend functionality in the
- * future if neccessary.
- */
-
- return (PGA11X_HANDLE)spi;
-}
-
-/****************************************************************************
- * Name: pga11x_select
- *
- * Description:
- * Select an input channel and gain for all PGA11xs.
- *
- * If CONFIG_PGA11X_DAISYCHAIN is defined, then pga11x_select() configures
- * both chips in the daisy-chain. pga11x_uselect() is provided to support
- * configuring the parts in the daisychain independently.
- *
- * Input Parameters:
- * spi - An SPI "bottom half" device driver instance
- * settings - New channel and gain settings
- *
- * Returned Value:
- * Zero on sucess; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int pga11x_select(PGA11X_HANDLE handle,
- FAR const struct pga11x_settings_s *settings)
-{
-#ifndef CONFIG_PGA11X_DAISYCHAIN
- FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle;
- uint16_t cmd;
-
- DEBUGASSERT(handle && settings);
- spivdbg("channel: %d gain: %d\n", settings->channel, settings->gain);
-
- /* Format the command */
-
- cmd = PGA11X_CMD_WRITE |
- ((uint16_t)settings->channel << PGA11X_CHAN_SHIFT) |
- ((uint16_t)settings->gain << PGA11X_GAIN_SHIFT);
-
- /* Send the command */
-
- pga11x_write(spi, cmd);
- return OK;
-#else
- FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle;
- uint16_t u1cmd;
- uint16_t u2cmd;
-
- DEBUGASSERT(handle && settings);
- spivdbg("U1 channel: %d gain: %d\n", settings->u1.channel, settings->u1.gain);
- spivdbg("U1 channel: %d gain: %d\n", settings->u1.channel, settings->u1.gain);
-
- /* Format the commands */
-
- u1cmd = PGA11X_CMD_WRITE |
- ((uint16_t)settings->u1.channel << PGA11X_CHAN_SHIFT) |
- ((uint16_t)settings->u1.gain << PGA11X_GAIN_SHIFT);
-
- u2cmd = PGA11X_DCCMD_WRITE |
- ((uint16_t)settings->u2.channel << PGA11X_CHAN_SHIFT) |
- ((uint16_t)settings->u2.gain << PGA11X_GAIN_SHIFT);
-
- /* Send the command */
-
- pga11x_write(spi, u1cmd, u2cmd);
- return OK;
-#endif
-}
-
-/****************************************************************************
- * Name: pga11x_uselect
- *
- * Description:
- * Select an input channel and gain for one PGA11x.
- *
- * If CONFIG_PGA11X_DAISYCHAIN is defined, then pga11x_uselect() configures
- * one chips in the daisy-chain.
- *
- * Input Parameters:
- * spi - An SPI "bottom half" device driver instance
- * pos - Position of the chip in the daisy chain (0 or 1)
- * settings - New channel and gain settings
- *
- * Returned Value:
- * Zero on sucess; a negated errno value on failure.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_PGA11X_DAISYCHAIN
-int pga11x_uselect(PGA11X_HANDLE handle, int pos,
- FAR const struct pga11x_usettings_s *settings)
-{
- FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle;
- uint16_t u1cmd;
- uint16_t u2cmd;
-
- spivdbg("channel: %d gain: %d\n", settings->channel, settings->gain);
- DEBUGASSERT(handle);
-
- /* Format the commands */
-
- if (pos == 0)
- {
- u1cmd = PGA11X_CMD_WRITE |
- ((uint16_t)settings->channel << PGA11X_CHAN_SHIFT) |
- ((uint16_t)settings->gain << PGA11X_GAIN_SHIFT);
- u2cmd = PGA11X_DCCMD_NOOP;
- }
- else /* if (pos == 1) */
- {
- u1cmd = PGA11X_CMD_NOOP;
- u2cmd = PGA11X_DCCMD_WRITE |
- ((uint16_t)settings->channel << PGA11X_CHAN_SHIFT) |
- ((uint16_t)settings->gain << PGA11X_GAIN_SHIFT);
- }
-
- /* Send the command */
-
- pga11x_write(spi, u1cmd, u2cmd);
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Name: pga11x_read
- *
- * Description:
- * Read from all PGA117 amplifier/multiplexers.
- *
- * If CONFIG_PGA11X_DAISYCHAIN is defined, then pga11x_read() reads from
- * both chips in the daisy-chain. pga11x_uread() is provided to support
- * accessing the parts independently.
- *
- * Input Parameters:
- * spi - An SPI "bottom half" device driver instance
- * settings - Returned channel and gain settings
- *
- * Returned Value:
- * Zero on sucess; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int pga11x_read(PGA11X_HANDLE handle, FAR struct pga11x_settings_s *settings)
-{
-#ifdef CONFIG_PGA11X_DAISYCHAIN
- FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle;
- uint16_t u1value;
- uint16_t u2value;
-
- spivdbg("Entry\n");
- DEBUGASSERT(handle && settings);
-
- /* Lock the bus and read the configuration */
-
- pga11x_lock(spi);
-
- /* Select, send the 16-bit command, the 16-bit daisy-chain command, and
- * then de-select the part. I do not know if de-selection between word
- * transfers is required. However, it is shown in the timing diagrams
- * for the part.
- */
-
- SPI_SELECT(spi, SPIDEV_MUX, true);
- pga11x_send16(spi, PGA11X_CMD_READ);
- pga11x_send16(spi, PGA11X_DCCMD_READ);
- SPI_SELECT(spi, SPIDEV_MUX, false);
-
- /* Re-select, get the returned values, de-select, and unlock */
-
- SPI_SELECT(spi, SPIDEV_MUX, true);
- u2value = pga11x_recv16(spi);
- u1value = pga11x_recv16(spi);
- SPI_SELECT(spi, SPIDEV_MUX, false);
- pga11x_unlock(spi);
-
- /* Decode the returned value */
-
- spivdbg("Returning %04x %04x\n", u2value, u1value);
- settings->u1.channel = (uint8_t)((u1value & PGA11X_CHAN_MASK) >> PGA11X_CHAN_SHIFT);
- settings->u1.gain = (uint8_t)((u1value & PGA11X_GAIN_MASK) >> PGA11X_GAIN_SHIFT);
- settings->u2.channel = (uint8_t)((u2value & PGA11X_CHAN_MASK) >> PGA11X_CHAN_SHIFT);
- settings->u2.gain = (uint8_t)((u2value & PGA11X_GAIN_MASK) >> PGA11X_GAIN_SHIFT);
- return OK;
-#else
- FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle;
- uint16_t value;
-
- spivdbg("Entry\n");
- DEBUGASSERT(handle);
-
- /* Lock the bus and read the configuration */
-
- pga11x_lock(spi);
-
- /* Select, send the 16-bit PGA11X_CMD_READ command, and de-select. I do
- * not know if de-selection between word transfers is required. However,
- * it is shown in the timing diagrams for the part.
- */
-
- SPI_SELECT(spi, SPIDEV_MUX, true);
- pga11x_send16(spi, PGA11X_CMD_READ);
- SPI_SELECT(spi, SPIDEV_MUX, false);
-
- /* Re-select, get the returned value, de-select, and unlock */
-
- SPI_SELECT(spi, SPIDEV_MUX, true);
- value = pga11x_recv16(spi);
- SPI_SELECT(spi, SPIDEV_MUX, false);
- pga11x_unlock(spi);
-
- /* Decode the returned value */
-
- spivdbg("Returning: %04x\n", value);
- settings->channel = (uint8_t)((value & PGA11X_CHAN_MASK) >> PGA11X_CHAN_SHIFT);
- settings->gain = (uint8_t)((value & PGA11X_GAIN_MASK) >> PGA11X_GAIN_SHIFT);
- return OK;
-#endif
-}
-
-/****************************************************************************
- * Name: pga11x_uread
- *
- * Description:
- * Read from one PGA117 amplifier/multiplexer.
- *
- * If CONFIG_PGA11X_DAISYCHAIN is defined, then pga11x_read() reads
- * the parts independently.
- *
- * Input Parameters:
- * spi - An SPI "bottom half" device driver instance
- * pos - Position of the chip in the daisy chain (0 or 1)
- * settings - Returned channel and gain settings
- *
- * Returned Value:
- * Zero on sucess; a negated errno value on failure.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_PGA11X_DAISYCHAIN
-int pga11x_uread(PGA11X_HANDLE handle, int pos,
- FAR struct pga11x_usettings_s *settings)
-{
- struct pga11x_settings_s both;
- int ret = pga11x_read(handle, &both);
- if (ret == OK)
- {
- if (pos == 0)
- {
- settings->channel = both.u1.channel;
- settings->gain = both.u1.gain;
- }
- else /* if (pos == 1) */
- {
- settings->channel = both.u2.channel;
- settings->gain = both.u2.gain;
- }
- }
-
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Name: pga11x_shutdown
- *
- * Description:
- * Put all PGA11x's in shutdown down mode.
- *
- * If CONFIG_PGA11X_DAISYCHAIN is defined, then pga11x_shutdown() controls
- * both chips in the daisy-chain. pga11x_ushutdown() is provided to
- * control the parts independently.
- *
- * Input Parameters:
- * spi - An SPI "bottom half" device driver instance
- *
- * Returned Value:
- * Zero on sucess; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int pga11x_shutdown(PGA11X_HANDLE handle)
-{
- FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle;
-
- spivdbg("Entry\n");
- DEBUGASSERT(handle);
-
- /* Enter shutdown mode by issuing an SDN_EN command */
-
-#ifdef CONFIG_PGA11X_DAISYCHAIN
- pga11x_write(spi, PGA11X_CMD_SDN_EN, PGA11X_DCCMD_SDN_EN);
-#else
- pga11x_write(spi, PGA11X_CMD_SDN_EN);
-#endif
- return OK;
-}
-
-/****************************************************************************
- * Name: pga11x_ushutdown
- *
- * Description:
- * Put one PGA11x in shutdown down mode.
- *
- * If CONFIG_PGA11X_DAISYCHAIN is defined, then pga11x_ushutdown() is
- * provided to shutdown the parts independently.
- *
- * Input Parameters:
- * spi - An SPI "bottom half" device driver instance
- * pos - Position of the chip in the daisy chain (0 or 1)
- *
- * Returned Value:
- * Zero on sucess; a negated errno value on failure.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_PGA11X_DAISYCHAIN
-int pga11x_ushutdown(PGA11X_HANDLE handle, int pos)
-{
- FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle;
-
- spivdbg("Entry\n");
- DEBUGASSERT(handle);
-
- /* Enter shutdown mode by issuing an SDN_EN command */
-
- if (pos == 0)
- {
- pga11x_write(spi, PGA11X_CMD_SDN_EN, PGA11X_DCCMD_NOOP);
- }
- else
- {
- pga11x_write(spi, PGA11X_CMD_NOOP, PGA11X_DCCMD_SDN_EN);
- }
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Name: pga11x_enable
- *
- * Description:
- * Take all PGA11x's out of shutdown down mode.
- *
- * If CONFIG_PGA11X_DAISYCHAIN is defined, then pga11x_enable() controls
- * both chips in the daisy-chain. pga11x_uenable() is provided to
- * control the parts independently.
- *
- * Input Parameters:
- * spi - An SPI "bottom half" device driver instance
- *
- * Returned Value:
- * Zero on sucess; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int pga11x_enable(PGA11X_HANDLE handle)
-{
- FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle;
-
- spivdbg("Entry\n");
- DEBUGASSERT(handle);
-
- /* Lock the bus and send the shutdown disable command. Shutdown mode is
- * cleared (returned to the last valid write configuration) by the SDN_DIS
- * command or by any valid Write command
- */
-
-#ifdef CONFIG_PGA11X_DAISYCHAIN
- pga11x_write(spi, PGA11X_CMD_SDN_DIS, PGA11X_DCCMD_SDN_DIS);
-#else
- pga11x_write(spi, PGA11X_CMD_SDN_DIS);
-#endif
- return OK;
-}
-
-/****************************************************************************
- * Name: pga11x_uenable
- *
- * Description:
- * Take one PGA11x out of shutdown down mode.
- *
- * If CONFIG_PGA11X_DAISYCHAIN is defined, then pga11x_uenable() is
- * provided to enable the parts independently.
- *
- * Input Parameters:
- * spi - An SPI "bottom half" device driver instance
- * pos - Position of the chip in the daisy chain (0 or 1)
- *
- * Returned Value:
- * Zero on sucess; a negated errno value on failure.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_PGA11X_DAISYCHAIN
-int pga11x_uenable(PGA11X_HANDLE handle, int pos)
-{
- FAR struct spi_dev_s *spi = (FAR struct spi_dev_s *)handle;
-
- spivdbg("Entry\n");
- DEBUGASSERT(handle);
-
- /* Enter shutdown mode by issuing an SDN_EN command */
-
- if (pos == 0)
- {
- pga11x_write(spi, PGA11X_CMD_SDN_DIS, PGA11X_DCCMD_NOOP);
- }
- else
- {
- pga11x_write(spi, PGA11X_CMD_NOOP, PGA11X_DCCMD_SDN_DIS);
- }
-
- return OK;
-}
-#endif
-
-#endif /* CONFIG_ADC && CONFIG_ADC_PGA11X */
-
diff --git a/nuttx/drivers/bch/Kconfig b/nuttx/drivers/bch/Kconfig
deleted file mode 100644
index ae2bf3130..000000000
--- a/nuttx/drivers/bch/Kconfig
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
diff --git a/nuttx/drivers/bch/Make.defs b/nuttx/drivers/bch/Make.defs
deleted file mode 100644
index 78dfbff30..000000000
--- a/nuttx/drivers/bch/Make.defs
+++ /dev/null
@@ -1,52 +0,0 @@
-############################################################################
-# drivers/bch/Make.defs
-#
-# Copyright (C) 2008, 2011-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
-ifneq ($(CONFIG_DISABLE_MOUNTPOINT),y)
-
-# Include BCH driver
-
-CSRCS += bchlib_setup.c bchlib_teardown.c bchlib_read.c bchlib_write.c \
- bchlib_cache.c bchlib_sem.c bchdev_register.c bchdev_unregister.c \
- bchdev_driver.c
-
-# Include BCH driver build support
-
-DEPPATH += --dep-path bch
-VPATH += :bch
-CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)bch}
-
-endif
-endif
diff --git a/nuttx/drivers/bch/bch_internal.h b/nuttx/drivers/bch/bch_internal.h
deleted file mode 100644
index fb1c64236..000000000
--- a/nuttx/drivers/bch/bch_internal.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
- * drivers/bch/bch_internal.h
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 __FS_BCH_INTERNAL_H
-#define __FS_BCH_INTERNAL_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <semaphore.h>
-#include <nuttx/fs/fs.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#define bchlib_semgive(d) sem_post(&(d)->sem) /* To match bchlib_semtake */
-#define MAX_OPENCNT (255) /* Limit of uint8_t */
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-struct bchlib_s
-{
- struct inode *inode; /* I-node of the block driver */
- sem_t sem; /* For atomic accesses to this structure */
- size_t nsectors; /* Number of sectors supported by the device */
- size_t sector; /* The current sector in the buffer */
- uint16_t sectsize; /* The size of one sector on the device */
- uint8_t refs; /* Number of references */
- bool dirty; /* Data has been written to the buffer */
- bool readonly; /* true: Only read operations are supported */
- FAR uint8_t *buffer; /* One sector buffer */
-};
-
-/****************************************************************************
- * Global Variables
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-EXTERN const struct file_operations bch_fops;
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-EXTERN void bchlib_semtake(FAR struct bchlib_s *bch);
-EXTERN int bchlib_flushsector(FAR struct bchlib_s *bch);
-EXTERN int bchlib_readsector(FAR struct bchlib_s *bch, size_t sector);
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* __FS_BCH_INTERNAL_H */
diff --git a/nuttx/drivers/bch/bchdev_driver.c b/nuttx/drivers/bch/bchdev_driver.c
deleted file mode 100644
index 262a0af46..000000000
--- a/nuttx/drivers/bch/bchdev_driver.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/****************************************************************************
- * drivers/bch/bchdev_driver.c
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Compilation Switches
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sched.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/fs/ioctl.h>
-
-#include "bch_internal.h"
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int bch_open(FAR struct file *filp);
-static int bch_close(FAR struct file *filp);
-static ssize_t bch_read(FAR struct file *, FAR char *, size_t);
-static ssize_t bch_write(FAR struct file *, FAR const char *, size_t);
-static int bch_ioctl(FAR struct file *filp, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-const struct file_operations bch_fops =
-{
- bch_open, /* open */
- bch_close, /* close */
- bch_read, /* read */
- bch_write, /* write */
- 0, /* seek */
- bch_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , 0 /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: bch_open
- *
- * Description: Open the block device
- *
- ****************************************************************************/
-
-static int bch_open(FAR struct file *filp)
-{
- FAR struct inode *inode = filp->f_inode;
- FAR struct bchlib_s *bch;
-
- DEBUGASSERT(inode && inode->i_private);
- bch = (FAR struct bchlib_s *)inode->i_private;
-
- /* Increment the reference count */
-
- bchlib_semtake(bch);
- if (bch->refs == MAX_OPENCNT)
- {
- return -EMFILE;
- }
- else
- {
- bch->refs++;
- }
- bchlib_semgive(bch);
-
- return OK;
-}
-
-/****************************************************************************
- * Name: bch_close
- *
- * Description: close the block device
- *
- ****************************************************************************/
-
-static int bch_close(FAR struct file *filp)
-{
- FAR struct inode *inode = filp->f_inode;
- FAR struct bchlib_s *bch;
- int ret = OK;
-
- DEBUGASSERT(inode && inode->i_private);
- bch = (FAR struct bchlib_s *)inode->i_private;
-
- /* Flush any dirty pages remaining in the cache */
-
- bchlib_semtake(bch);
- (void)bchlib_flushsector(bch);
-
- /* Decrement the reference count (I don't use bchlib_decref() because I
- * want the entire close operation to be atomic wrt other driver operations.
- */
-
- if (bch->refs == 0)
- {
- ret = -EIO;
- }
- else
- {
- bch->refs--;
- }
- bchlib_semgive(bch);
-
- return ret;
-}
-
-/****************************************************************************
- * Name:bch_read
- ****************************************************************************/
-
-static ssize_t bch_read(FAR struct file *filp, FAR char *buffer, size_t len)
-{
- FAR struct inode *inode = filp->f_inode;
- FAR struct bchlib_s *bch;
- int ret;
-
- DEBUGASSERT(inode && inode->i_private);
- bch = (FAR struct bchlib_s *)inode->i_private;
-
- bchlib_semtake(bch);
- ret = bchlib_read(bch, buffer, filp->f_pos, len);
- if (ret > 0)
- {
- filp->f_pos += len;
- }
- bchlib_semgive(bch);
- return ret;
-}
-
-/****************************************************************************
- * Name:bch_write
- ****************************************************************************/
-
-static ssize_t bch_write(FAR struct file *filp, FAR const char *buffer, size_t len)
-{
- FAR struct inode *inode = filp->f_inode;
- FAR struct bchlib_s *bch;
- int ret = -EACCES;
-
- DEBUGASSERT(inode && inode->i_private);
- bch = (FAR struct bchlib_s *)inode->i_private;
-
- if (!bch->readonly)
- {
- bchlib_semtake(bch);
- ret = bchlib_write(bch, buffer, filp->f_pos, len);
- if (ret > 0)
- {
- filp->f_pos += len;
- }
- bchlib_semgive(bch);
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: bch_ioctl
- *
- * Description: Return device geometry
- *
- ****************************************************************************/
-
-static int bch_ioctl(FAR struct file *filp, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filp->f_inode;
- FAR struct bchlib_s *bch;
- int ret = -ENOTTY;
-
- DEBUGASSERT(inode && inode->i_private);
- bch = (FAR struct bchlib_s *)inode->i_private;
-
- if (cmd == DIOC_GETPRIV)
- {
- FAR struct bchlib_s **bchr = (FAR struct bchlib_s **)((uintptr_t)arg);
-
- bchlib_semtake(bch);
- if (!bchr && bch->refs < 255)
- {
- ret = -EINVAL;
- }
- else
- {
- bch->refs++;
- *bchr = bch;
- }
- bchlib_semgive(bch);
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
diff --git a/nuttx/drivers/bch/bchdev_register.c b/nuttx/drivers/bch/bchdev_register.c
deleted file mode 100644
index 924977371..000000000
--- a/nuttx/drivers/bch/bchdev_register.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
- * drivers/bch/bchdev_register.c
- *
- * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <stdbool.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include "bch_internal.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: bchdev_register
- *
- * Description:
- * Setup so that it exports the block driver referenced by 'blkdev' as a
- * character device 'chardev'
- *
- ****************************************************************************/
-
-int bchdev_register(FAR const char *blkdev, FAR const char *chardev,
- bool readonly)
-{
- FAR void *handle;
- int ret;
-
- /* Setup the BCH lib functions */
-
- ret = bchlib_setup(blkdev, readonly, &handle);
- if (ret < 0)
- {
- fdbg("bchlib_setup failed: %d\n", -ret);
- return ret;
- }
-
- /* Then setup the character device */
-
- ret = register_driver(chardev, &bch_fops, 0666, handle);
- if (ret < 0)
- {
- fdbg("register_driver failed: %d\n", -ret);
- bchlib_teardown(handle);
- handle = NULL;
- }
-
- return ret;
-}
diff --git a/nuttx/drivers/bch/bchdev_unregister.c b/nuttx/drivers/bch/bchdev_unregister.c
deleted file mode 100644
index 8c7360882..000000000
--- a/nuttx/drivers/bch/bchdev_unregister.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/****************************************************************************
- * drivers/bch/bchdev_unregister.c
- *
- * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <sched.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/fs/ioctl.h>
-
-#include "bch_internal.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: bchdev_unregister
- *
- * Description:
- * Unregister character driver access to a block device that was created
- * by a previous call to bchdev_register().
- *
- ****************************************************************************/
-
-int bchdev_unregister(FAR const char *chardev)
-{
- FAR struct bchlib_s *bch;
- int fd;
- int ret;
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (!chardev)
- {
- return -EINVAL;
- }
-#endif
-
- /* Open the character driver associated with chardev */
-
- fd = open(chardev, O_RDONLY);
- if (fd < 0)
- {
- dbg("Failed to open %s: %d\n", chardev, errno);
- return -errno;
- }
-
- /* Get a reference to the internal data structure. On success, we
- * will hold a reference count on the state structure.
- */
-
- ret = ioctl(fd, DIOC_GETPRIV, (unsigned long)((uintptr_t)&bch));
- (void)close(fd);
-
- if (ret < 0)
- {
- dbg("ioctl failed: %d\n", errno);
- return -errno;
- }
-
- /* Lock out context switches. If there are no other references
- * and no context switches, then we can assume that we can safely
- * teardown the driver.
- */
-
- sched_lock();
-
- /* Check if the internal structure is non-busy (we hold one reference). */
-
- if (bch->refs > 1)
- {
- ret = -EBUSY;
- goto errout_with_lock;
- }
-
- /* Unregister the driver (this cannot suspend or we lose our non-preemptive
- * state!). Once the driver is successfully unregistered, we can assume
- * we have exclusive access to the state instance.
- */
-
- ret = unregister_driver(chardev);
- if (ret < 0)
- {
- goto errout_with_lock;
- }
-
- sched_unlock();
-
- /* Release the internal structure */
-
- bch->refs = 0;
- return bchlib_teardown(bch);
-
-errout_with_lock:
- bch->refs--;
- sched_unlock();
- return ret;
-}
diff --git a/nuttx/drivers/bch/bchlib_cache.c b/nuttx/drivers/bch/bchlib_cache.c
deleted file mode 100644
index 3b8212a13..000000000
--- a/nuttx/drivers/bch/bchlib_cache.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/****************************************************************************
- * drivers/bch/bchlib_cache.c
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-
-#include "bch_internal.h"
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: bchlib_flushsector
- *
- * Description:
- * Flush the current contents of the sector buffer (if dirty)
- *
- * Assumptions:
- * Caller must assume mutual exclusion
- *
- ****************************************************************************/
-
-int bchlib_flushsector(FAR struct bchlib_s *bch)
-{
- FAR struct inode *inode;
- ssize_t ret = OK;
-
- if (bch->dirty)
- {
- inode = bch->inode;
- ret = inode->u.i_bops->write(inode, bch->buffer, bch->sector, 1);
- if (ret < 0)
- {
- fdbg("Write failed: %d\n");
- }
- bch->dirty = false;
- }
- return (int)ret;
-}
-
-/****************************************************************************
- * Name: bchlib_readsector
- *
- * Description:
- * Flush the current contents of the sector buffer (if dirty)
- *
- * Assumptions:
- * Caller must assume mutual exclusion
- *
- ****************************************************************************/
-
-int bchlib_readsector(FAR struct bchlib_s *bch, size_t sector)
-{
- FAR struct inode *inode;
- ssize_t ret = OK;
-
- if (bch->sector != sector)
- {
- inode = bch->inode;
-
- (void)bchlib_flushsector(bch);
- bch->sector = (size_t)-1;
-
- ret = inode->u.i_bops->read(inode, bch->buffer, sector, 1);
- if (ret < 0)
- {
- fdbg("Read failed: %d\n");
- }
- bch->sector = sector;
- }
- return (int)ret;
-}
-
diff --git a/nuttx/drivers/bch/bchlib_read.c b/nuttx/drivers/bch/bchlib_read.c
deleted file mode 100644
index f4fad1096..000000000
--- a/nuttx/drivers/bch/bchlib_read.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/****************************************************************************
- * drivers/bch/bchlib_read.c
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-
-#include "bch_internal.h"
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: bchlib_read
- *
- * Description:
- * Read from the block device set-up by bchlib_setup as if it were a character
- * device.
- *
- ****************************************************************************/
-
-ssize_t bchlib_read(FAR void *handle, FAR char *buffer, size_t offset, size_t len)
-{
- FAR struct bchlib_s *bch = (FAR struct bchlib_s *)handle;
- size_t nsectors;
- size_t sector;
- uint16_t sectoffset;
- size_t nbytes;
- size_t bytesread;
- int ret;
-
- /* Get rid of this special case right away */
-
- if (len < 1)
- {
- return 0;
- }
-
- /* Convert the file position into a sector number an offset. */
-
- sector = offset / bch->sectsize;
- sectoffset = offset - sector * bch->sectsize;
-
- if (sector >= bch->nsectors)
- {
- /* Return end-of-file */
-
- return 0;
- }
-
- /* Read the initial partial sector */
-
- bytesread = 0;
- if (sectoffset > 0)
- {
- /* Read the sector into the sector buffer */
-
- bchlib_readsector(bch, sector);
-
- /* Copy the tail end of the sector to the user buffer */
-
- if (sectoffset + len > bch->sectsize)
- {
- nbytes = bch->sectsize - sectoffset;
- }
- else
- {
- nbytes = len;
- }
-
- memcpy(buffer, &bch->buffer[sectoffset], nbytes);
-
- /* Adjust pointers and counts */
-
- sectoffset = 0;
- sector++;
-
- if (sector >= bch->nsectors)
- {
- return nbytes;
- }
-
- bytesread = nbytes;
- buffer += nbytes;
- len -= nbytes;
- }
-
- /* Then read all of the full sectors following the partial sector directly
- * into the user buffer.
- */
-
- if (len >= bch->sectsize )
- {
- nsectors = len / bch->sectsize;
- if (sector + nsectors > bch->nsectors)
- {
- nsectors = bch->nsectors - sector;
- }
-
- ret = bch->inode->u.i_bops->read(bch->inode, (FAR uint8_t *)buffer,
- sector, nsectors);
- if (ret < 0)
- {
- fdbg("Read failed: %d\n");
- return ret;
- }
-
- /* Adjust pointers and counts */
-
- sectoffset = 0;
- sector += nsectors;
-
- nbytes = nsectors * bch->sectsize;
- bytesread += nbytes;
-
- if (sector >= bch->nsectors)
- {
- return bytesread;
- }
-
- buffer += nbytes;
- len -= nbytes;
- }
-
- /* Then read any partial final sector */
-
- if (len > 0)
- {
- /* Read the sector into the sector buffer */
-
- bchlib_readsector(bch, sector);
-
- /* Copy the head end of the sector to the user buffer */
-
- memcpy(buffer, bch->buffer, len);
-
- /* Adjust counts */
-
- bytesread += len;
- }
-
- return bytesread;
-}
diff --git a/nuttx/drivers/bch/bchlib_sem.c b/nuttx/drivers/bch/bchlib_sem.c
deleted file mode 100644
index 1698ed0a5..000000000
--- a/nuttx/drivers/bch/bchlib_sem.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
- * drivers/bch/bchlib_sem.c
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include "bch_internal.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: bch_semtake
- ****************************************************************************/
-
-void bchlib_semtake(FAR struct bchlib_s *bch)
-{
- /* Take the semaphore (perhaps waiting) */
-
- while (sem_wait(&bch->sem) != 0)
- {
- /* The only case that an error should occur here is if
- * the wait was awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-}
diff --git a/nuttx/drivers/bch/bchlib_setup.c b/nuttx/drivers/bch/bchlib_setup.c
deleted file mode 100644
index 1026248b5..000000000
--- a/nuttx/drivers/bch/bchlib_setup.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/****************************************************************************
- * drivers/bch/bchlib_setup.c
- *
- * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <sys/mount.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-
-#include "bch_internal.h"
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: bchlib_setup
- *
- * Description:
- * Setup so that the block driver referenced by 'blkdev' can be accessed
- * similar to a character device.
- *
- ****************************************************************************/
-
-int bchlib_setup(const char *blkdev, bool readonly, FAR void **handle)
-{
- FAR struct bchlib_s *bch;
- struct geometry geo;
- int ret;
-
- DEBUGASSERT(blkdev);
-
- /* Allocate the BCH state structure */
-
- bch = (FAR struct bchlib_s*)kzalloc(sizeof(struct bchlib_s));
- if (!bch)
- {
- fdbg("Failed to allocate BCH structure\n");
- return -ENOMEM;
- }
-
- /* Open the block driver */
-
- ret = open_blockdriver(blkdev, readonly ? MS_RDONLY : 0, &bch->inode);
- if (ret < 0)
- {
- fdbg("Failed to open driver %s: %d\n", blkdev, -ret);
- goto errout_with_bch;
- }
-
- DEBUGASSERT(bch->inode && bch->inode->u.i_bops && bch->inode->u.i_bops->geometry);
-
- ret = bch->inode->u.i_bops->geometry(bch->inode, &geo);
- if (ret < 0)
- {
- fdbg("geometry failed: %d\n", -ret);
- goto errout_with_bch;
- }
-
- if (!geo.geo_available)
- {
- fdbg("geometry failed: %d\n", -ret);
- ret = -ENODEV;
- goto errout_with_bch;
- }
-
- if (!readonly && (!bch->inode->u.i_bops->write || !geo.geo_writeenabled))
- {
- fdbg("write access not supported\n");
- ret = -EACCES;
- goto errout_with_bch;
- }
-
- /* Save the geometry info and complete initialization of the structure */
-
- sem_init(&bch->sem, 0, 1);
- bch->nsectors = geo.geo_nsectors;
- bch->sectsize = geo.geo_sectorsize;
- bch->sector = (size_t)-1;
- bch->readonly = readonly;
-
- /* Allocate the sector I/O buffer */
-
- bch->buffer = (FAR uint8_t *)kmalloc(bch->sectsize);
- if (!bch->buffer)
- {
- fdbg("Failed to allocate sector buffer\n");
- ret = -ENOMEM;
- goto errout_with_bch;
- }
-
- *handle = bch;
- return OK;
-
-errout_with_bch:
- kfree(bch);
- return ret;
-}
diff --git a/nuttx/drivers/bch/bchlib_teardown.c b/nuttx/drivers/bch/bchlib_teardown.c
deleted file mode 100644
index 8657c4a69..000000000
--- a/nuttx/drivers/bch/bchlib_teardown.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
- * drivers/bch/bchlib_teardown.c
- *
- * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <stdlib.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-
-#include "bch_internal.h"
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: bchlib_teardown
- *
- * Description:
- * Setup so that the block driver referenced by 'blkdev' can be accessed
- * similar to a character device.
- *
- ****************************************************************************/
-
-int bchlib_teardown(FAR void *handle)
-{
- FAR struct bchlib_s *bch = (FAR struct bchlib_s *)handle;
-
- DEBUGASSERT(handle);
-
- /* Check that there are not outstanding reference counts on the object */
-
- if (bch->refs > 0)
- {
- return -EBUSY;
- }
-
- /* Flush any pending data to the block driver */
-
- bchlib_flushsector(bch);
-
- /* Close the block driver */
-
- (void)close_blockdriver(bch->inode);
-
- /* Free the BCH state structure */
-
- if (bch->buffer)
- {
- kfree(bch->buffer);
- }
-
- sem_destroy(&bch->sem);
- kfree(bch);
- return OK;
-}
-
diff --git a/nuttx/drivers/bch/bchlib_write.c b/nuttx/drivers/bch/bchlib_write.c
deleted file mode 100644
index 8d7dcf26f..000000000
--- a/nuttx/drivers/bch/bchlib_write.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/****************************************************************************
- * drivers/bch/bchlib_write.c
- *
- * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-
-#include "bch_internal.h"
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: bchlib_write
- *
- * Description:
- * Write to the block device set-up by bchlib_setup as if it were a character
- * device.
- *
- ****************************************************************************/
-
-ssize_t bchlib_write(FAR void *handle, FAR const char *buffer, size_t offset, size_t len)
-{
- FAR struct bchlib_s *bch = (FAR struct bchlib_s *)handle;
- size_t nsectors;
- size_t sector;
- uint16_t sectoffset;
- size_t nbytes;
- size_t byteswritten;
- int ret;
-
- /* Get rid of this special case right away */
-
- if (len < 1)
- {
- return 0;
- }
-
- /* Convert the file position into a sector number an offset. */
-
- sector = offset / bch->sectsize;
- sectoffset = offset - sector * bch->sectsize;
-
- if (sector >= bch->nsectors)
- {
- return -EFBIG;
- }
-
- /* Write the initial partial sector */
-
- byteswritten = 0;
- if (sectoffset > 0)
- {
- /* Read the full sector into the sector buffer */
-
- bchlib_readsector(bch, sector);
-
- /* Copy the tail end of the sector from the user buffer */
-
- if (sectoffset + len > bch->sectsize)
- {
- nbytes = bch->sectsize - sectoffset;
- }
- else
- {
- nbytes = len;
- }
-
- memcpy(&bch->buffer[sectoffset], buffer, nbytes);
- bch->dirty = true;
-
- /* Adjust pointers and counts */
-
- sectoffset = 0;
- sector++;
-
- if (sector >= bch->nsectors)
- {
- return nbytes;
- }
-
- byteswritten = nbytes;
- buffer += nbytes;
- len -= nbytes;
- }
-
- /* Then write all of the full sectors following the partial sector
- * directly from the user buffer.
- */
-
- if (len >= bch->sectsize )
- {
- nsectors = len / bch->sectsize;
- if (sector + nsectors > bch->nsectors)
- {
- nsectors = bch->nsectors - sector;
- }
-
- /* Write the contiguous sectors */
-
- ret = bch->inode->u.i_bops->write(bch->inode, (FAR uint8_t *)buffer,
- sector, nsectors);
- if (ret < 0)
- {
- fdbg("Write failed: %d\n", ret);
- return ret;
- }
-
- /* Adjust pointers and counts */
-
- sectoffset = 0;
- sector += nsectors;
-
- nbytes = nsectors * bch->sectsize;
- byteswritten += nbytes;
-
- if (sector >= bch->nsectors)
- {
- return byteswritten;
- }
-
- buffer += nbytes;
- len -= nbytes;
- }
-
- /* Then write any partial final sector */
-
- if (len > 0)
- {
- /* Read the sector into the sector buffer */
-
- bchlib_readsector(bch, sector);
-
- /* Copy the head end of the sector from the user buffer */
-
- memcpy(bch->buffer, buffer, len);
- bch->dirty = true;
-
- /* Adjust counts */
-
- byteswritten += len;
- }
-
- /* Finally, flush any cached writes to the device as well */
-
- ret = bchlib_flushsector(bch);
- if (ret < 0)
- {
- fdbg("Flush failed: %d\n", ret);
- return ret;
- }
-
- return byteswritten;
-}
-
diff --git a/nuttx/drivers/can.c b/nuttx/drivers/can.c
deleted file mode 100644
index 2c1567781..000000000
--- a/nuttx/drivers/can.c
+++ /dev/null
@@ -1,845 +0,0 @@
-/****************************************************************************
- * drivers/can.c
- *
- * Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <string.h>
-#include <semaphore.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/arch.h>
-#include <nuttx/can.h>
-
-#include <arch/irq.h>
-
-#ifdef CONFIG_CAN
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Debug ********************************************************************/
-/* Non-standard debug that may be enabled just for testing CAN */
-
-#ifdef CONFIG_DEBUG_CAN
-# define candbg dbg
-# define canvdbg vdbg
-# define canlldbg lldbg
-# define canllvdbg llvdbg
-#else
-# define candbg(x...)
-# define canvdbg(x...)
-# define canlldbg(x...)
-# define canllvdbg(x...)
-#endif
-
-/* Timing Definitions *******************************************************/
-
-#define HALF_SECOND_MSEC 500
-#define HALF_SECOND_USEC 500000L
-
-/****************************************************************************
- * Private Type Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-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, size_t buflen);
-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);
-static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations g_canops =
-{
- can_open, /* open */
- can_close, /* close */
- can_read, /* read */
- can_write, /* write */
- 0, /* seek */
- can_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , 0 /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/************************************************************************************
- * Name: can_open
- *
- * Description:
- * This function is called whenever the CAN device is opened.
- *
- ************************************************************************************/
-
-static int can_open(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct can_dev_s *dev = inode->i_private;
- uint8_t tmp;
- int ret = OK;
-
- canvdbg("ocount: %d\n", dev->cd_ocount);
-
- /* If the port is the middle of closing, wait until the close is finished */
-
- if (sem_wait(&dev->cd_closesem) != OK)
- {
- ret = -errno;
- }
- else
- {
- /* Increment the count of references to the device. If this the first
- * time that the driver has been opened for this device, then initialize
- * the device.
- */
-
- tmp = dev->cd_ocount + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- }
- else
- {
- /* Check if this is the first time that the driver has been opened. */
-
- if (tmp == 1)
- {
- /* Yes.. perform one time hardware initialization. */
-
- irqstate_t flags = irqsave();
- ret = dev_setup(dev);
- if (ret == OK)
- {
- /* Mark the FIFOs empty */
-
- dev->cd_xmit.tx_head = 0;
- dev->cd_xmit.tx_queue = 0;
- dev->cd_xmit.tx_tail = 0;
- dev->cd_recv.rx_head = 0;
- dev->cd_recv.rx_tail = 0;
-
- /* Finally, Enable the CAN RX interrupt */
-
- dev_rxint(dev, true);
-
- /* Save the new open count on success */
-
- dev->cd_ocount = tmp;
- }
- irqrestore(flags);
- }
- }
- sem_post(&dev->cd_closesem);
- }
- return ret;
-}
-
-/************************************************************************************
- * Name: can_close
- *
- * Description:
- * This routine is called when the CAN device is closed.
- * It waits for the last remaining data to be sent.
- *
- ************************************************************************************/
-
-static int can_close(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct can_dev_s *dev = inode->i_private;
- irqstate_t flags;
- int ret = OK;
-
- canvdbg("ocount: %d\n", dev->cd_ocount);
-
- if (sem_wait(&dev->cd_closesem) != OK)
- {
- ret = -errno;
- }
- else
- {
- /* Decrement the references to the driver. If the reference count will
- * decrement to 0, then uninitialize the driver.
- */
-
- if (dev->cd_ocount > 1)
- {
- dev->cd_ocount--;
- sem_post(&dev->cd_closesem);
- }
- else
- {
- /* There are no more references to the port */
-
- dev->cd_ocount = 0;
-
- /* Stop accepting input */
-
- dev_rxint(dev, false);
-
- /* Now we wait for the transmit FIFO to clear */
-
- while (dev->cd_xmit.tx_head != dev->cd_xmit.tx_tail)
- {
-#ifndef CONFIG_DISABLE_SIGNALS
- usleep(HALF_SECOND_USEC);
-#else
- up_mdelay(HALF_SECOND_MSEC);
-#endif
- }
-
- /* And wait for the TX hardware FIFO to drain */
-
- while (!dev_txempty(dev))
- {
-#ifndef CONFIG_DISABLE_SIGNALS
- usleep(HALF_SECOND_USEC);
-#else
- up_mdelay(HALF_SECOND_MSEC);
-#endif
- }
-
- /* Free the IRQ and disable the CAN device */
-
- flags = irqsave(); /* Disable interrupts */
- dev_shutdown(dev); /* Disable the CAN */
- irqrestore(flags);
-
- sem_post(&dev->cd_closesem);
- }
- }
- return ret;
-}
-
-/************************************************************************************
- * Name: can_read
- *
- * Description:
- * Read standard CAN messages
- *
- ************************************************************************************/
-
-static ssize_t can_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct can_dev_s *dev = inode->i_private;
- size_t nread;
- irqstate_t flags;
- int ret = 0;
-
- canvdbg("buflen: %d\n", buflen);
-
- /* The caller must provide enough memory to catch the smallest possible message
- * This is not a system error condition, but we won't permit it, Hence we return 0.
- */
-
- if (buflen >= CAN_MSGLEN(0))
- {
- /* Interrupts must be disabled while accessing the cd_recv FIFO */
-
- flags = irqsave();
- while (dev->cd_recv.rx_head == dev->cd_recv.rx_tail)
- {
- /* The receive FIFO is empty -- was non-blocking mode selected? */
-
- if (filep->f_oflags & O_NONBLOCK)
- {
- ret = -EAGAIN;
- goto return_with_irqdisabled;
- }
-
- /* Wait for a message to be received */
-
- ret = sem_wait(&dev->cd_recv.rx_sem);
- if (ret < 0)
- {
- ret = -errno;
- goto return_with_irqdisabled;
- }
- }
-
- /* The cd_recv FIFO is not empty. Copy all buffered data that will fit
- * in the user buffer.
- */
-
- nread = 0;
- do
- {
- /* 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);
-
- if (nread + msglen > buflen)
- {
- break;
- }
-
- /* Copy the message to the user buffer */
-
- memcpy(&buffer[nread], msg, msglen);
- nread += msglen;
-
- /* Increment the head of the circular message buffer */
-
- if (++dev->cd_recv.rx_head >= CONFIG_CAN_FIFOSIZE)
- {
- dev->cd_recv.rx_head = 0;
- }
- }
- while (dev->cd_recv.rx_head != dev->cd_recv.rx_tail);
-
- /* All on the messages have bee transferred. Return the number of bytes
- * that were read.
- */
-
- ret = nread;
-
-return_with_irqdisabled:
- irqrestore(flags);
- }
- return ret;
-}
-
-/************************************************************************************
- * Name: can_xmit
- *
- * Description:
- * Send the message at the head of the cd_xmit FIFO
- *
- * Assumptions:
- * Called with interrupts disabled
- *
- ************************************************************************************/
-
-static int can_xmit(FAR struct can_dev_s *dev)
-{
- int tmpndx;
- int ret = -EBUSY;
-
- canllvdbg("xmit head: %d queue: %d tail: %d\n",
- dev->cd_xmit.tx_head, dev->cd_xmit.tx_queue, dev->cd_xmit.tx_tail);
-
- /* If there is nothing to send, then just disable interrupts and return */
-
- if (dev->cd_xmit.tx_head == dev->cd_xmit.tx_tail)
- {
- DEBUGASSERT(dev->cd_xmit.tx_queue == dev->cd_xmit.tx_head);
- dev_txint(dev, false);
- return -EIO;
- }
-
- /* Check if we have already queued all of the data in the TX fifo.
- *
- * tx_tail: Incremented in can_write each time a message is queued in the FIFO
- * tx_head: Incremented in can_txdone each time a message completes
- * tx_queue: Incremented each time that a message is sent to the hardware.
- *
- * Logically (ignoring buffer wrap-around): tx_head <= tx_queue <= tx_tail
- * tx_head == tx_queue == tx_tail means that the FIFO is empty
- * tx_head < tx_queue == tx_tail means that all data has been queued, but
- * we are still waiting for transmissions to complete.
- */
-
- while (dev->cd_xmit.tx_queue != dev->cd_xmit.tx_tail && dev_txready(dev))
- {
- /* No.. The fifo should not be empty in this case */
-
- DEBUGASSERT(dev->cd_xmit.tx_head != dev->cd_xmit.tx_tail);
-
- /* Increment the FIFO queue index before sending (because dev_send()
- * might call can_txdone().
- */
-
- tmpndx = dev->cd_xmit.tx_queue;
- if (++dev->cd_xmit.tx_queue >= CONFIG_CAN_FIFOSIZE)
- {
- dev->cd_xmit.tx_queue = 0;
- }
-
- /* Send the next message at the FIFO queue index */
-
- ret = dev_send(dev, &dev->cd_xmit.tx_buffer[tmpndx]);
- if (ret != OK)
- {
- candbg("dev_send failed: %d\n", ret);
- break;
- }
- }
-
- /* Make sure that TX interrupts are enabled */
-
- dev_txint(dev, true);
- return ret;
-}
-
-/************************************************************************************
- * Name: can_write
- ************************************************************************************/
-
-static ssize_t can_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct can_dev_s *dev = inode->i_private;
- FAR struct can_txfifo_s *fifo = &dev->cd_xmit;
- FAR struct can_msg_s *msg;
- bool inactive;
- ssize_t nsent = 0;
- irqstate_t flags;
- int nexttail;
- int msglen;
- int ret = 0;
-
- canvdbg("buflen: %d\n", buflen);
-
- /* Interrupts must disabled throughout the following */
-
- flags = irqsave();
-
- /* Check if the TX is inactive when we started. In certain race conditionas, there
- * may be a pending interrupt to kick things back off, but we will here that there
- * is not. That the hardware is IDLE and will need to be kick-started.
- */
-
- inactive = dev_txempty(dev);
-
- /* Add the messages to the FIFO. Ignore any trailing messages that are
- * shorter than the minimum.
- */
-
- while ((buflen - nsent) >= CAN_MSGLEN(0))
- {
- /* Check if adding this new message would over-run the drivers ability to enqueue
- * xmit data.
- */
-
- nexttail = fifo->tx_tail + 1;
- if (nexttail >= CONFIG_CAN_FIFOSIZE)
- {
- nexttail = 0;
- }
-
- /* If the XMIT fifo becomes full, then wait for space to become available */
-
- while (nexttail == fifo->tx_head)
- {
- /* The transmit FIFO is full -- was non-blocking mode selected? */
-
- if (filep->f_oflags & O_NONBLOCK)
- {
- if (nsent == 0)
- {
- ret = -EAGAIN;
- }
- else
- {
- ret = nsent;
- }
- goto return_with_irqdisabled;
- }
-
- /* If the TX hardware was inactive when we started, then we will have
- * start the XMIT sequence generate the TX done interrrupts needed
- * to clear the FIFO.
- */
-
- if (inactive)
- {
- can_xmit(dev);
- }
-
- /* Wait for a message to be sent */
-
- do
- {
- DEBUGASSERT(dev->cd_ntxwaiters < 255);
- dev->cd_ntxwaiters++;
- ret = sem_wait(&fifo->tx_sem);
- dev->cd_ntxwaiters--;
-
- if (ret < 0 && errno != EINTR)
- {
- ret = -errno;
- goto return_with_irqdisabled;
- }
- }
- while (ret < 0);
-
- /* Re-check the FIFO state */
-
- inactive = dev_txempty(dev);
- }
-
- /* We get here if there is space at the end of the FIFO. Add the new
- * CAN message at the tail of the FIFO.
- */
-
- msg = (FAR struct can_msg_s *)&buffer[nsent];
- msglen = CAN_MSGLEN(msg->cm_hdr.ch_dlc);
- memcpy(&fifo->tx_buffer[fifo->tx_tail], msg, msglen);
-
- /* Increment the tail of the circular buffer */
-
- fifo->tx_tail = nexttail;
-
- /* Increment the number of bytes that were sent */
-
- nsent += msglen;
- }
-
- /* We get here after all messages have been added to the FIFO. Check if
- * we need to kick of the XMIT sequence.
- */
-
- if (inactive)
- {
- can_xmit(dev);
- }
-
- /* Return the number of bytes that were sent */
-
- ret = nsent;
-
-return_with_irqdisabled:
- irqrestore(flags);
- return ret;
-}
-
-/************************************************************************************
- * Name: can_rtrread
- *
- * Description:
- * Read RTR messages. The RTR message is a special message -- it is an outgoing
- * message that says "Please re-transmit the message with the same identifier as
- * this message. So the RTR read is really a send-wait-receive operation.
- *
- ************************************************************************************/
-
-static inline ssize_t can_rtrread(FAR struct can_dev_s *dev, FAR struct canioctl_rtr_s *rtr)
-{
- FAR struct can_rtrwait_s *wait = NULL;
- irqstate_t flags;
- int i;
- int ret = -ENOMEM;
-
- /* Disable interrupts through this operation */
-
- flags = irqsave();
-
- /* Find an avaiable slot in the pending RTR list */
-
- for (i = 0; i < CONFIG_CAN_NPENDINGRTR; i++)
- {
- FAR struct can_rtrwait_s *tmp = &dev->cd_rtr[i];
- if (!rtr->ci_msg)
- {
- tmp->cr_id = rtr->ci_id;
- tmp->cr_msg = rtr->ci_msg;
- dev->cd_npendrtr++;
- wait = tmp;
- break;
- }
- }
-
- if (wait)
- {
- /* Send the remote transmission request */
-
- ret = dev_remoterequest(dev, wait->cr_id);
- if (ret == OK)
- {
- /* Then wait for the response */
-
- ret = sem_wait(&wait->cr_sem);
- }
- }
- irqrestore(flags);
- return ret;
-}
-
-/************************************************************************************
- * Name: can_ioctl
- ************************************************************************************/
-
-static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct can_dev_s *dev = inode->i_private;
- int ret = OK;
-
- canvdbg("cmd: %d arg: %ld\n", cmd, arg);
-
- /* Handle built-in ioctl commands */
-
- switch (cmd)
- {
- /* CANIOCTL_RTR: Send the remote transmission request and wait for the response.
- * Argument is a reference to struct canioctl_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));
- break;
-
- /* Not a "built-in" ioctl command.. perhaps it is unique to this device driver */
-
- default:
- ret = dev_ioctl(dev, cmd, arg);
- break;
- }
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/************************************************************************************
- * Name: can_register
- *
- * Description:
- * Register serial console and serial ports.
- *
- ************************************************************************************/
-
-int can_register(FAR const char *path, FAR struct can_dev_s *dev)
-{
- int i;
-
- /* Initialize the CAN device structure */
-
- dev->cd_ocount = 0;
-
- sem_init(&dev->cd_xmit.tx_sem, 0, 0);
- sem_init(&dev->cd_recv.rx_sem, 0, 0);
- sem_init(&dev->cd_closesem, 0, 1);
-
- for (i = 0; i < CONFIG_CAN_NPENDINGRTR; i++)
- {
- sem_init(&dev->cd_rtr[i].cr_sem, 0, 0);
- dev->cd_rtr[i].cr_msg = NULL;
- dev->cd_npendrtr--;
- }
-
- /* Initialize/reset the CAN hardware */
-
- dev_reset(dev);
-
- /* Register the CAN device */
-
- canvdbg("Registering %s\n", path);
- return register_driver(path, &g_canops, 0666, dev);
-}
-
-/************************************************************************************
- * Name: can_receive
- *
- * Description:
- * Called from the CAN interrupt handler when new read data is available
- *
- * Parameters:
- * dev - CAN driver state structure
- * hdr - CAN message header
- * data - CAN message data (if DLC > 0)
- *
- * Assumptions:
- * CAN interrupts are disabled.
- *
- ************************************************************************************/
-
-int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr, FAR uint8_t *data)
-{
- FAR struct can_rxfifo_s *fifo = &dev->cd_recv;
- FAR uint8_t *dest;
- int nexttail;
- int err = -ENOMEM;
- int i;
-
- canllvdbg("ID: %d DLC: %d\n", hdr->ch_id, hdr->ch_dlc);
-
- /* Check if adding this new message would over-run the drivers ability to enqueue
- * read data.
- */
-
- nexttail = fifo->rx_tail + 1;
- if (nexttail >= CONFIG_CAN_FIFOSIZE)
- {
- nexttail = 0;
- }
-
- /* First, check if this response matches any RTR response that we may be waiting for */
-
- if (dev->cd_npendrtr > 0)
- {
- /* There are pending RTR requests -- search the lists of requests
- * and see any any matches this new message.
- */
-
- for (i = 0; i < CONFIG_CAN_NPENDINGRTR; i++)
- {
- FAR struct can_rtrwait_s *rtr = &dev->cd_rtr[i];
- FAR struct can_msg_s *msg = rtr->cr_msg;
-
- /* Check if the entry is valid and if the ID matches. A valid entry has
- * a non-NULL receiving address
- */
-
- if (msg && hdr->ch_id == rtr->cr_id)
- {
- /* 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++)
- {
- *dest++ = *data++;
- }
-
- /* Mark the entry unused */
-
- rtr->cr_msg = NULL;
-
- /* And restart the waiting thread */
-
- sem_post(&rtr->cr_sem);
- }
- }
- }
-
- /* Refuse the new data if the FIFO is full */
-
- if (nexttail != fifo->rx_head)
- {
- /* Add the new, decoded CAN message at the tail of the FIFO */
-
- 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++)
- {
- *dest++ = *data++;
- }
-
- /* Increment the tail of the circular buffer */
-
- fifo->rx_tail = nexttail;
-
- /* The increment the counting semaphore. The maximum value should be
- * CONFIG_CAN_FIFOSIZE -- one possible count for each allocated message buffer.
- */
-
- sem_post(&fifo->rx_sem);
- err = OK;
- }
- return err;
-}
-
-/************************************************************************************
- * Name: can_txdone
- *
- * Description:
- * Called from the CAN interrupt handler at the completion of a send operation.
- *
- * Parameters:
- * dev - The specific CAN device
- * hdr - The 16-bit CAN header
- * data - An array contain the CAN data.
- *
- * Return:
- * OK on success; a negated errno on failure.
- *
- ************************************************************************************/
-
-int can_txdone(FAR struct can_dev_s *dev)
-{
- int ret = -ENOENT;
-
- canllvdbg("xmit head: %d queue: %d tail: %d\n",
- dev->cd_xmit.tx_head, dev->cd_xmit.tx_queue, dev->cd_xmit.tx_tail);
-
- /* Verify that the xmit FIFO is not empty */
-
- if (dev->cd_xmit.tx_head != dev->cd_xmit.tx_tail)
- {
- DEBUGASSERT(dev->cd_xmit.tx_head != dev->cd_xmit.tx_queue);
-
- /* Remove the message at the head of the xmit FIFO */
-
- if (++dev->cd_xmit.tx_head >= CONFIG_CAN_FIFOSIZE)
- {
- dev->cd_xmit.tx_head = 0;
- }
-
- /* Send the next message in the FIFO */
-
- ret = can_xmit(dev);
-
- /* Are there any threads waiting for space in the TX FIFO? */
-
- if (ret == OK && dev->cd_ntxwaiters > 0)
- {
- /* Yes.. Inform them that new xmit space is available */
-
- ret = sem_post(&dev->cd_xmit.tx_sem);
- }
- }
- return ret;
-}
-
-#endif /* CONFIG_CAN */
diff --git a/nuttx/drivers/dev_null.c b/nuttx/drivers/dev_null.c
deleted file mode 100644
index c70370e1e..000000000
--- a/nuttx/drivers/dev_null.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
- * drivers/dev_null.c
- *
- * Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdbool.h>
-#include <string.h>
-#include <poll.h>
-#include <errno.h>
-#include <nuttx/fs/fs.h>
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static ssize_t devnull_read(FAR struct file *, FAR char *, size_t);
-static ssize_t devnull_write(FAR struct file *, FAR const char *, size_t);
-#ifndef CONFIG_DISABLE_POLL
-static int devnull_poll(FAR struct file *filp, FAR struct pollfd *fds,
- bool setup);
-#endif
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations devnull_fops =
-{
- 0, /* open */
- 0, /* close */
- devnull_read, /* read */
- devnull_write, /* write */
- 0, /* seek */
- 0 /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , devnull_poll /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: devnull_read
- ****************************************************************************/
-
-static ssize_t devnull_read(FAR struct file *filp, FAR char *buffer, size_t len)
-{
- return 0; /* Return EOF */
-}
-
-/****************************************************************************
- * Name: devnull_write
- ****************************************************************************/
-
-static ssize_t devnull_write(FAR struct file *filp, FAR const char *buffer, size_t len)
-{
- return len; /* Say that everything was written */
-}
-
-/****************************************************************************
- * Name: devnull_poll
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static int devnull_poll(FAR struct file *filp, FAR struct pollfd *fds,
- bool setup)
-{
- if (setup)
- {
- fds->revents |= (fds->events & (POLLIN|POLLOUT));
- if (fds->revents != 0)
- {
- sem_post(fds->sem);
- }
- }
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: devnull_register
- *
- * Description:
- * Register /dev/null
- *
- ****************************************************************************/
-
-void devnull_register(void)
-{
- (void)register_driver("/dev/null", &devnull_fops, 0666, NULL);
-}
diff --git a/nuttx/drivers/dev_zero.c b/nuttx/drivers/dev_zero.c
deleted file mode 100644
index 5435f80ea..000000000
--- a/nuttx/drivers/dev_zero.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
- * drivers/dev_null.c
- *
- * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdbool.h>
-#include <string.h>
-#include <poll.h>
-#include <errno.h>
-#include <nuttx/fs/fs.h>
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static ssize_t devzero_read(FAR struct file *, FAR char *, size_t);
-static ssize_t devzero_write(FAR struct file *, FAR const char *, size_t);
-#ifndef CONFIG_DISABLE_POLL
-static int devzero_poll(FAR struct file *filp, FAR struct pollfd *fds,
- bool setup);
-#endif
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations devzero_fops =
-{
- 0, /* open */
- 0, /* close */
- devzero_read, /* read */
- devzero_write, /* write */
- 0, /* seek */
- 0 /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , devzero_poll /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: devzero_read
- ****************************************************************************/
-
-static ssize_t devzero_read(FAR struct file *filp, FAR char *buffer, size_t len)
-{
- memset(buffer, 0, len);
- return len;
-}
-
-/****************************************************************************
- * Name: devzero_write
- ****************************************************************************/
-
-static ssize_t devzero_write(FAR struct file *filp, FAR const char *buffer, size_t len)
-{
- return len;
-}
-
-/****************************************************************************
- * Name: devzero_poll
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static int devzero_poll(FAR struct file *filp, FAR struct pollfd *fds,
- bool setup)
-{
- if (setup)
- {
- fds->revents |= (fds->events & (POLLIN|POLLOUT));
- if (fds->revents != 0)
- {
- sem_post(fds->sem);
- }
- }
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: devzero_register
- *
- * Description:
- * Register /dev/zero
- *
- ****************************************************************************/
-
-void devzero_register(void)
-{
- (void)register_driver("/dev/zero", &devzero_fops, 0666, NULL);
-}
diff --git a/nuttx/drivers/input/Kconfig b/nuttx/drivers/input/Kconfig
deleted file mode 100644
index 6da3a9f39..000000000
--- a/nuttx/drivers/input/Kconfig
+++ /dev/null
@@ -1,228 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-config INPUT_TSC2007
- bool "TI TSC2007 touchscreen controller"
- default n
- select I2C
- ---help---
- Enable support for the TI TSC2007 touchscreen controller
-
-if INPUT_TSC2007
-
-config TSC2007_8BIT
- bool "8-bit Conversions"
- default n
- ---help---
- Use faster, but less accurate, 8-bit conversions. Default: 12-bit conversions.
-
-config TSC2007_MULTIPLE
- bool "Multiple TSC2007 Devices"
- default n
- ---help---
- Can be defined to support multiple TSC2007 devices on board.
-
-config TSC2007_NPOLLWAITERS
- int "Number poll waiters"
- default 4
- depends on !DISABLE_POLL
- ---help---
- Maximum number of threads that can be waiting on poll()
-
-endif
-
-config INPUT_ADS7843E
- bool "TI ADS7843/TSC2046 touchscreen controller"
- default n
- select SPI
- ---help---
- Enable support for the TI/Burr-Brown ADS7842 touchscreen controller. I believe
- that driver should be compatibile with the TI/Burr-Brown TSC2046 and XPT2046
- touchscreen controllers as well.
-
-if INPUT_ADS7843E
-
-config ADS7843E_MULTIPLE
- bool "Multiple ADS7843E Devices"
- default n
- ---help---
- Can be defined to support multiple ADS7843E devices on board.
-
-config ADS7843E_NPOLLWAITERS
- int "Number poll waiters"
- default 4
- depends on !DISABLE_POLL
- ---help---
- Maximum number of threads that can be waiting on poll()
-
-config ADS7843E_SPIMODE
- int "SPI mode"
- default 0
- range 0,3
- ---help---
- Controls the SPI mode. The device should work in mode 0, but sometimes
- you need to experiment.
-
-config ADS7843E_FREQUENCY
- int "SPI frequency"
- default 100000
- ---help---
- Define to use a different SPI bus frequency.
-
-config ADS7843E_SWAPXY
- bool "Swap X/Y"
- default n
- ---help---
- Reverse the meaning of X and Y to handle different LCD orientations.
-
-config ADS7843E_THRESHX
- int "X threshold"
- default 12
- ---help---
- New touch positions will only be reported when the X or Y data changes by these
- thresholds. This trades reduces data rate for some loss in dragging accuracy. For
- 12-bit values so the raw ranges are 0-4095. So for example, if your display is
- 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12
-
-config ADS7843E_THRESHY
- int "Y threshold"
- default 12
- ---help---
- New touch positions will only be reported when the X or Y data changes by these
- thresholds. This trades reduces data rate for some loss in dragging accuracy. For
- 12-bit values so the raw ranges are 0-4095. So for example, if your display is
- 320x240, then THRESHX=13 and THRESHY=17 would correspond to one pixel. Default: 12
-
-endif
-
-config INPUT_STMPE811
- bool "STMicro STMPE811 Driver"
- default n
- ---help---
- Enables support for the STMPE811 driver
-
-if INPUT_STMPE811
-
-choice
- prompt "STMPE Interface"
- default STMPE811_I2C
-
-config STMPE811_SPI
- bool "SPI Interface"
- select SPI
- ---help---
- Enables support for the SPI interface (not currently supported)
-
-config STMPE811_I2C
- bool "STMPE811 I2C Interface"
- select I2C
- ---help---
- Enables support for the I2C interface
-
-endchoice
-
-config STMPE811_ACTIVELOW
- bool "Active Low Interrupt"
- default n
- ---help---
- The STMPE811 interrupt is provided by a discrete input (usually a
- GPIO interrupt on most MCU architectures). This setting determines
- whether the interrupt is active high (or rising edge triggered) or
- active low (or falling edge triggered). Default: Active
- high/rising edge.
-
-config STMPE811_EDGE
- bool "Edge triggered Interrupt"
- default n
- ---help---
- The STMPE811 interrupt is provided by a discrete input (usually a
- GPIO interrupt on most MCU architectures). This setting determines
- whether the interrupt is edge or level triggered. Default: Level
- triggered.
-
-config STMPE811_MULTIPLE
- bool "Multiple STMPE811 Devices"
- default n
- ---help---
- Can be defined to support multiple STMPE811 devices on board.
-
-config STMPE811_NPOLLWAITERS
- int "Number poll waiters"
- default 4
- depends on !DISABLE_POLL
- ---help---
- Maximum number of threads that can be waiting on poll()
-
-config STMPE811_TSC_DISABLE
- bool "Disable STMPE811 Touchscreen Support"
- default n
- ---help---
- Disable driver touchscreen functionality.
-
-config STMPE811_SWAPXY
- bool "Swap X/Y"
- default n
- depends on !STMPE811_TSC_DISABLE
- ---help---
- Reverse the meaning of X and Y to handle different LCD orientations.
-
-config STMPE811_THRESHX
- int "X threshold"
- default 12
- depends on !STMPE811_TSC_DISABLE
- ---help---
- STMPE811 touchscreen data comes in a a very high rate. New touch positions
- will only be reported when the X or Y data changes by these thresholds.
- This trades reduces data rate for some loss in dragging accuracy. The
- STMPE811 is configure for 12-bit values so the raw ranges are 0-4095. So
- for example, if your display is 320x240, then THRESHX=13 and THRESHY=17
- would correspond to one pixel. Default: 12
-
-config STMPE811_THRESHY
- int "Y threshold"
- default 12
- depends on !STMPE811_TSC_DISABLE
- ---help---
- STMPE811 touchscreen data comes in a a very high rate. New touch positions
- will only be reported when the X or Y data changes by these thresholds.
- This trades reduces data rate for some loss in dragging accuracy. The
- STMPE811 is configure for 12-bit values so the raw ranges are 0-4095. So
- for example, if your display is 320x240, then THRESHX=13 and THRESHY=17
- would correspond to one pixel. Default: 12
-
-config STMPE811_ADC_DISABLE
- bool "Disable STMPE811 ADC Support"
- default y
- ---help---
- Disable driver ADC functionality.
-
-config STMPE811_GPIO_DISABLE
- bool "Disable STMPE811 GPIO Support"
- default y
- ---help---
- Disable driver GPIO functionality.
-
-config STMPE811_GPIOINT_DISABLE
- bool "Disable STMPE811 GPIO Interrupt Support"
- default y
- depends on !STMPE811_GPIO_DISABLE
- ---help---
- Disable driver GPIO interrupt functionlality (ignored if GPIO functionality is
- disabled).
-
-config STMPE811_TEMP_DISABLE
- bool "Disable STMPE811 Temperature Sensor Support"
- default y
- ---help---
- Disable driver temperature sensor functionality.
-
-config STMPE811_REGDEBUG
- bool "Enable Register-Level STMPE811 Debug"
- default n
- depends on DEBUG
- ---help---
- Enable very low register-level debug output.
-
-endif
diff --git a/nuttx/drivers/input/Make.defs b/nuttx/drivers/input/Make.defs
deleted file mode 100644
index 10e6db62f..000000000
--- a/nuttx/drivers/input/Make.defs
+++ /dev/null
@@ -1,76 +0,0 @@
-############################################################################
-# drivers/input/Make.defs
-#
-# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-# Don't build anything if there is no NX support for input devices
-
-ifeq ($(CONFIG_INPUT),y)
-
-# Include the selected touchscreen drivers
-
-ifeq ($(CONFIG_INPUT_TSC2007),y)
- CSRCS += tsc2007.c
-endif
-
-ifeq ($(CONFIG_INPUT_ADS7843E),y)
- CSRCS += ads7843e.c
-endif
-
-ifeq ($(CONFIG_INPUT_MAX11802),y)
- CSRCS += max11802.c
-endif
-
-ifeq ($(CONFIG_INPUT_STMPE811),y)
- CSRCS += stmpe811_base.c
-ifneq ($(CONFIG_INPUT_STMPE811_TSC_DISABLE),y)
- CSRCS += stmpe811_tsc.c
-endif
-ifneq ($(CONFIG_INPUT_STMPE811_GPIO_DISABLE),y)
- CSRCS += stmpe811_gpio.c
-endif
-ifneq ($(CONFIG_INPUT_STMPE811_ADC_DISABLE),y)
- CSRCS += stmpe811_adc.c
-endif
-ifneq ($(CONFIG_INPUT_STMPE811_TEMP_DISABLE),y)
- CSRCS += stmpe811_temp.c
-endif
-endif
-
-# Include input device driver build support
-
-DEPPATH += --dep-path input
-VPATH += :input
-CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)input}
-endif
-
diff --git a/nuttx/drivers/input/ads7843e.c b/nuttx/drivers/input/ads7843e.c
deleted file mode 100644
index 06969e6d2..000000000
--- a/nuttx/drivers/input/ads7843e.c
+++ /dev/null
@@ -1,1283 +0,0 @@
-/****************************************************************************
- * drivers/input/ads7843e.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Authors: Gregory Nutt <gnutt@nuttx.org>
- * Diego Sanchez <dsanchez@nx-engineering.com>
- *
- * References:
- * "Touch Screen Controller, ADS7843," Burr-Brown Products from Texas
- * Instruments, SBAS090B, September 2000, Revised May 2002"
- *
- * See also:
- * "Low Voltage I/O Touch Screen Controller, TSC2046," Burr-Brown Products
- * from Texas Instruments, SBAS265F, October 2002, Revised August 2007.
- *
- * "XPT2046 Data Sheet," Shenzhen XPTek Technology Co., Ltd, 2007
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <semaphore.h>
-#include <poll.h>
-#include <wdog.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/arch.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/spi.h>
-#include <nuttx/wqueue.h>
-
-#include <nuttx/input/touchscreen.h>
-#include <nuttx/input/ads7843e.h>
-
-#include "ads7843e.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* This is a value for the threshold that guantees a big difference on the
- * first pendown (but can't overflow).
- */
-
-#define INVALID_THRESHOLD 0x1000
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-/* Low-level SPI helpers */
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void ads7843e_configspi(FAR struct spi_dev_s *spi);
-# define ads7843e_lock(spi)
-# define ads7843e_unlock(spi)
-#else
-# define ads7843e_configspi(spi);
-static void ads7843e_lock(FAR struct spi_dev_s *spi);
-static void ads7843e_unlock(FAR struct spi_dev_s *spi);
-#endif
-
-static inline void ads7843e_waitbusy(FAR struct ads7843e_dev_s *priv);
-static uint16_t ads7843e_sendcmd(FAR struct ads7843e_dev_s *priv, uint8_t cmd);
-
-/* Interrupts and data sampling */
-
-static void ads7843e_notify(FAR struct ads7843e_dev_s *priv);
-static int ads7843e_sample(FAR struct ads7843e_dev_s *priv,
- FAR struct ads7843e_sample_s *sample);
-static int ads7843e_waitsample(FAR struct ads7843e_dev_s *priv,
- FAR struct ads7843e_sample_s *sample);
-static void ads7843e_worker(FAR void *arg);
-static int ads7843e_interrupt(int irq, FAR void *context);
-
-/* Character driver methods */
-
-static int ads7843e_open(FAR struct file *filep);
-static int ads7843e_close(FAR struct file *filep);
-static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer, size_t len);
-static int ads7843e_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-#ifndef CONFIG_DISABLE_POLL
-static int ads7843e_poll(FAR struct file *filep, struct pollfd *fds, bool setup);
-#endif
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* This the the vtable that supports the character driver interface */
-
-static const struct file_operations ads7843e_fops =
-{
- ads7843e_open, /* open */
- ads7843e_close, /* close */
- ads7843e_read, /* read */
- 0, /* write */
- 0, /* seek */
- ads7843e_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , ads7843e_poll /* poll */
-#endif
-};
-
-/* If only a single ADS7843E device is supported, then the driver state
- * structure may as well be pre-allocated.
- */
-
-#ifndef CONFIG_ADS7843E_MULTIPLE
-static struct ads7843e_dev_s g_ads7843e;
-
-/* Otherwise, we will need to maintain allocated driver instances in a list */
-
-#else
-static struct ads7843e_dev_s *g_ads7843elist;
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: ads7843e_lock
- *
- * Description:
- * Lock the SPI bus and re-configure as necessary. This function must be
- * to assure: (1) exclusive access to the SPI bus, and (2) to assure that
- * the shared bus is properly configured for the touchscreen controller.
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static void ads7843e_lock(FAR struct spi_dev_s *spi)
-{
- /* Lock the SPI bus because there are multiple devices competing for the
- * SPI bus
- */
-
- (void)SPI_LOCK(spi, true);
-
- /* We have the lock. Now make sure that the SPI bus is configured for the
- * ADS7843 (it might have gotten configured for a different device while
- * unlocked)
- */
-
- SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, true);
- SPI_SETMODE(spi, CONFIG_ADS7843E_SPIMODE);
- SPI_SETBITS(spi, 8);
- SPI_SETFREQUENCY(spi, CONFIG_ADS7843E_FREQUENCY);
- SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, false);
-}
-#endif
-
-/****************************************************************************
- * Function: ads7843e_unlock
- *
- * Description:
- * If we are sharing the SPI bus with other devices (CONFIG_SPI_OWNBUS
- * undefined) then we need to un-lock the SPI bus for each transfer,
- * possibly losing the current configuration.
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static void ads7843e_unlock(FAR struct spi_dev_s *spi)
-{
- /* Relinquish the SPI bus. */
-
- (void)SPI_LOCK(spi, false);
-}
-#endif
-
-/****************************************************************************
- * Function: ads7843e_configspi
- *
- * Description:
- * Configure the SPI for use with the ADS7843E. This function should be
- * called once during touchscreen initialization to configure the SPI
- * bus. Note that if CONFIG_SPI_OWNBUS is not defined, then this function
- * does nothing.
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void ads7843e_configspi(FAR struct spi_dev_s *spi)
-{
- /* Configure SPI for the ADS7843. But only if we own the SPI bus. Otherwise, don't
- * bother because it might change.
- */
-
- SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, true);
- SPI_SETMODE(spi, CONFIG_ADS7843E_SPIMODE);
- SPI_SETBITS(spi, 8);
- SPI_SETFREQUENCY(spi, CONFIG_ADS7843E_FREQUENCY);
- SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, false);
-}
-#endif
-
-/****************************************************************************
- * Name: ads7843e_waitbusy
- ****************************************************************************/
-
-static inline void ads7843e_waitbusy(FAR struct ads7843e_dev_s *priv)
-{
- while (priv->config->busy(priv->config));
-}
-
-/****************************************************************************
- * Name: ads7843e_sendcmd
- ****************************************************************************/
-
-static uint16_t ads7843e_sendcmd(FAR struct ads7843e_dev_s *priv, uint8_t cmd)
-{
- uint8_t buffer[2];
- uint16_t result;
-
- /* Select the ADS7843E */
-
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, true);
-
- /* Send the command */
-
- (void)SPI_SEND(priv->spi, cmd);
- ads7843e_waitbusy(priv);
-
- /* Read the data */
-
- SPI_RECVBLOCK(priv->spi, buffer, 2);
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, false);
-
- result = ((uint16_t)buffer[0] << 8) | (uint16_t)buffer[1];
- result = result >> 4;
-
- ivdbg("cmd:%02x response:%04x\n", cmd, result);
- return result;
-}
-
-/****************************************************************************
- * Name: ads7843e_notify
- ****************************************************************************/
-
-static void ads7843e_notify(FAR struct ads7843e_dev_s *priv)
-{
-#ifndef CONFIG_DISABLE_POLL
- int i;
-#endif
-
- /* If there are threads waiting for read data, then signal one of them
- * that the read data is available.
- */
-
- if (priv->nwaiters > 0)
- {
- /* After posting this semaphore, we need to exit because the ADS7843E
- * is no longer available.
- */
-
- sem_post(&priv->waitsem);
- }
-
- /* If there are threads waiting on poll() for ADS7843E data to become available,
- * then wake them up now. NOTE: we wake up all waiting threads because we
- * do not know that they are going to do. If they all try to read the data,
- * then some make end up blocking after all.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- for (i = 0; i < CONFIG_ADS7843E_NPOLLWAITERS; i++)
- {
- struct pollfd *fds = priv->fds[i];
- if (fds)
- {
- fds->revents |= POLLIN;
- ivdbg("Report events: %02x\n", fds->revents);
- sem_post(fds->sem);
- }
- }
-#endif
-}
-
-/****************************************************************************
- * Name: ads7843e_sample
- ****************************************************************************/
-
-static int ads7843e_sample(FAR struct ads7843e_dev_s *priv,
- FAR struct ads7843e_sample_s *sample)
-{
- irqstate_t flags;
- int ret = -EAGAIN;
-
- /* Interrupts me be disabled when this is called to (1) prevent posting
- * of semaphores from interrupt handlers, and (2) to prevent sampled data
- * from changing until it has been reported.
- */
-
- flags = irqsave();
-
- /* Is there new ADS7843E sample data available? */
-
- if (priv->penchange)
- {
- /* Yes.. the state has changed in some way. Return a copy of the
- * sampled data.
- */
-
- memcpy(sample, &priv->sample, sizeof(struct ads7843e_sample_s ));
-
- /* Now manage state transitions */
-
- if (sample->contact == CONTACT_UP)
- {
- /* Next.. no contact. Increment the ID so that next contact ID
- * will be unique. X/Y positions are no longer valid.
- */
-
- priv->sample.contact = CONTACT_NONE;
- priv->sample.valid = false;
- priv->id++;
- }
- else if (sample->contact == CONTACT_DOWN)
- {
- /* First report -- next report will be a movement */
-
- priv->sample.contact = CONTACT_MOVE;
- }
-
- priv->penchange = false;
- ret = OK;
- }
-
- irqrestore(flags);
- return ret;
-}
-
-/****************************************************************************
- * Name: ads7843e_waitsample
- ****************************************************************************/
-
-static int ads7843e_waitsample(FAR struct ads7843e_dev_s *priv,
- FAR struct ads7843e_sample_s *sample)
-{
- irqstate_t flags;
- int ret;
-
- /* Interrupts me be disabled when this is called to (1) prevent posting
- * of semaphores from interrupt handlers, and (2) to prevent sampled data
- * from changing until it has been reported.
- *
- * In addition, we will also disable pre-emption to prevent other threads
- * from getting control while we muck with the semaphores.
- */
-
- sched_lock();
- flags = irqsave();
-
- /* Now release the semaphore that manages mutually exclusive access to
- * the device structure. This may cause other tasks to become ready to
- * run, but they cannot run yet because pre-emption is disabled.
- */
-
- sem_post(&priv->devsem);
-
- /* Try to get the a sample... if we cannot, then wait on the semaphore
- * that is posted when new sample data is available.
- */
-
- while (ads7843e_sample(priv, sample) < 0)
- {
- /* Wait for a change in the ADS7843E state */
-
- ivdbg("Waiting..\n");
- priv->nwaiters++;
- ret = sem_wait(&priv->waitsem);
- priv->nwaiters--;
-
- if (ret < 0)
- {
- /* If we are awakened by a signal, then we need to return
- * the failure now.
- */
-
- idbg("sem_wait: %d\n", errno);
- DEBUGASSERT(errno == EINTR);
- ret = -EINTR;
- goto errout;
- }
- }
-
- ivdbg("Sampled\n");
-
- /* Re-acquire the the semaphore that manages mutually exclusive access to
- * the device structure. We may have to wait here. But we have our sample.
- * Interrupts and pre-emption will be re-enabled while we wait.
- */
-
- ret = sem_wait(&priv->devsem);
-
-errout:
- /* Then re-enable interrupts. We might get interrupt here and there
- * could be a new sample. But no new threads will run because we still
- * have pre-emption disabled.
- */
-
- irqrestore(flags);
-
- /* Restore pre-emption. We might get suspended here but that is okay
- * because we already have our sample. Note: this means that if there
- * were two threads reading from the ADS7843E for some reason, the data
- * might be read out of order.
- */
-
- sched_unlock();
- return ret;
-}
-
-/****************************************************************************
- * Name: ads7843e_schedule
- ****************************************************************************/
-
-static int ads7843e_schedule(FAR struct ads7843e_dev_s *priv)
-{
- FAR struct ads7843e_config_s *config;
- int ret;
-
- /* Get a pointer the callbacks for convenience (and so the code is not so
- * ugly).
- */
-
- config = priv->config;
- DEBUGASSERT(config != NULL);
-
- /* Disable further interrupts. ADS7843E interrupts will be re-enabled
- * after the worker thread executes.
- */
-
- config->enable(config, false);
-
- /* Disable the watchdog timer. It will be re-enabled in the worker thread
- * while the pen remains down.
- */
-
- wd_cancel(priv->wdog);
-
- /* Transfer processing to the worker thread. Since ADS7843E interrupts are
- * disabled while the work is pending, no special action should be required
- * to protected the work queue.
- */
-
- DEBUGASSERT(priv->work.worker == NULL);
- ret = work_queue(HPWORK, &priv->work, ads7843e_worker, priv, 0);
- if (ret != 0)
- {
- illdbg("Failed to queue work: %d\n", ret);
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: ads7843e_wdog
- ****************************************************************************/
-
-static void ads7843e_wdog(int argc, uint32_t arg1, ...)
-{
- FAR struct ads7843e_dev_s *priv = (FAR struct ads7843e_dev_s *)((uintptr_t)arg1);
- (void)ads7843e_schedule(priv);
-}
-
-/****************************************************************************
- * Name: ads7843e_worker
- ****************************************************************************/
-
-static void ads7843e_worker(FAR void *arg)
-{
- FAR struct ads7843e_dev_s *priv = (FAR struct ads7843e_dev_s *)arg;
- FAR struct ads7843e_config_s *config;
- uint16_t x;
- uint16_t y;
- uint16_t xdiff;
- uint16_t ydiff;
- bool pendown;
- int ret;
-
- ASSERT(priv != NULL);
-
- /* Get a pointer the callbacks for convenience (and so the code is not so
- * ugly).
- */
-
- config = priv->config;
- DEBUGASSERT(config != NULL);
-
- /* Disable the watchdog timer. This is safe because it is started only
- * by this function and this function is serialized on the worker thread.
- */
-
- wd_cancel(priv->wdog);
-
- /* Lock the SPI bus so that we have exclusive access */
-
- ads7843e_lock(priv->spi);
-
- /* Get exclusive access to the driver data structure */
-
- do
- {
- ret = sem_wait(&priv->devsem);
-
- /* This should only fail if the wait was canceled by an signal
- * (and the worker thread will receive a lot of signals).
- */
-
- DEBUGASSERT(ret == OK || errno == EINTR);
- }
- while (ret < 0);
-
- /* Check for pen up or down by reading the PENIRQ GPIO. */
-
- pendown = config->pendown(config);
-
- /* Handle the change from pen down to pen up */
-
- if (!pendown)
- {
- /* The pen is up.. reset thresholding variables. */
-
- priv->threshx = INVALID_THRESHOLD;
- priv->threshy = INVALID_THRESHOLD;
-
- /* Ignore the interrupt if the pen was already up (CONTACT_NONE == pen up
- * and already reported; CONTACT_UP == pen up, but not reported)
- */
-
- if (priv->sample.contact == CONTACT_NONE ||
- priv->sample.contact == CONTACT_UP)
-
- {
- goto ignored;
- }
-
- /* The pen is up. NOTE: We know from a previous test, that this is a
- * loss of contact condition. This will be changed to CONTACT_NONE
- * after the loss of contact is sampled.
- */
-
- priv->sample.contact = CONTACT_UP;
- }
-
- /* It is a pen down event. If the last loss-of-contact event has not been
- * processed yet, then we have to ignore the pen down event (or else it will
- * look like a drag event)
- */
-
- else if (priv->sample.contact == CONTACT_UP)
- {
- /* If we have not yet processed the last pen up event, then we
- * cannot handle this pen down event. We will have to discard it. That
- * should be okay because we will set the timer to to sample again
- * later.
- */
-
- wd_start(priv->wdog, ADS7843E_WDOG_DELAY, ads7843e_wdog, 1, (uint32_t)priv);
- goto ignored;
- }
- else
- {
- /* Handle pen down events. First, sample positional values. */
-
-#ifdef CONFIG_ADS7843E_SWAPXY
- x = ads7843e_sendcmd(priv, ADS7843_CMD_YPOSITION);
- y = ads7843e_sendcmd(priv, ADS7843_CMD_XPOSITION);
-#else
- x = ads7843e_sendcmd(priv, ADS7843_CMD_XPOSITION);
- y = ads7843e_sendcmd(priv, ADS7843_CMD_YPOSITION);
-#endif
-
- /* Perform a thresholding operation so that the results will be more stable.
- * If the difference from the last sample is small, then ignore the event.
- * REVISIT: Should a large change in pressure also generate a event?
- */
-
- xdiff = x > priv->threshx ? (x - priv->threshx) : (priv->threshx - x);
- ydiff = y > priv->threshy ? (y - priv->threshy) : (priv->threshy - y);
-
- /* Continue to sample the position while the pen is down */
-
- wd_start(priv->wdog, ADS7843E_WDOG_DELAY, ads7843e_wdog, 1, (uint32_t)priv);
-
- /* Check the thresholds. Bail if there is no significant difference */
-
- if (xdiff < CONFIG_ADS7843E_THRESHX && ydiff < CONFIG_ADS7843E_THRESHY)
- {
- /* Little or no change in either direction ... don't report anything. */
-
- goto ignored;
- }
-
- /* When we see a big difference, snap to the new x/y thresholds */
-
- priv->threshx = x;
- priv->threshy = y;
-
- /* Update the x/y position in the sample data */
-
- priv->sample.x = priv->threshx;
- priv->sample.y = priv->threshy;
-
- /* The X/Y positional data is now valid */
-
- priv->sample.valid = true;
-
- /* If this is the first (acknowledged) pen down report, then report
- * this as the first contact. If contact == CONTACT_DOWN, it will be
- * set to set to CONTACT_MOVE after the contact is first sampled.
- */
-
- if (priv->sample.contact != CONTACT_MOVE)
- {
- /* First contact */
-
- priv->sample.contact = CONTACT_DOWN;
- }
- }
-
- /* Indicate the availability of new sample data for this ID */
-
- priv->sample.id = priv->id;
- priv->penchange = true;
-
- /* Notify any waiters that new ADS7843E data is available */
-
- ads7843e_notify(priv);
-
- /* Exit, re-enabling ADS7843E interrupts */
-
-ignored:
-
- (void)ads7843e_sendcmd(priv, ADS7843_CMD_ENABPINIRQ);
- config->enable(config, true);
-
- /* Release our lock on the state structure and unlock the SPI bus */
-
- sem_post(&priv->devsem);
- ads7843e_unlock(priv->spi);
-}
-
-/****************************************************************************
- * Name: ads7843e_interrupt
- ****************************************************************************/
-
-static int ads7843e_interrupt(int irq, FAR void *context)
-{
- FAR struct ads7843e_dev_s *priv;
- FAR struct ads7843e_config_s *config;
- int ret;
-
- /* Which ADS7843E device caused the interrupt? */
-
-#ifndef CONFIG_ADS7843E_MULTIPLE
- priv = &g_ads7843e;
-#else
- for (priv = g_ads7843elist;
- priv && priv->configs->irq != irq;
- priv = priv->flink);
-
- ASSERT(priv != NULL);
-#endif
-
- /* Get a pointer the callbacks for convenience (and so the code is not so
- * ugly).
- */
-
- config = priv->config;
- DEBUGASSERT(config != NULL);
-
- /* Schedule sampling to occur on the worker thread */
-
- ret = ads7843e_schedule(priv);
-
- /* Clear any pending interrupts and return success */
-
- config->clear(config);
- return ret;
-}
-
-/****************************************************************************
- * Name: ads7843e_open
- ****************************************************************************/
-
-static int ads7843e_open(FAR struct file *filep)
-{
-#ifdef CONFIG_ADS7843E_REFCNT
- FAR struct inode *inode;
- FAR struct ads7843e_dev_s *priv;
- uint8_t tmp;
- int ret;
-
- ivdbg("Opening\n");
-
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct ads7843e_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Increment the reference count */
-
- tmp = priv->crefs + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- goto errout_with_sem;
- }
-
- /* When the reference increments to 1, this is the first open event
- * on the driver.. and an opportunity to do any one-time initialization.
- */
-
- /* Save the new open count on success */
-
- priv->crefs = tmp;
-
-errout_with_sem:
- sem_post(&priv->devsem);
- return ret;
-#else
- ivdbg("Opening\n");
- return OK;
-#endif
-}
-
-/****************************************************************************
- * Name: ads7843e_close
- ****************************************************************************/
-
-static int ads7843e_close(FAR struct file *filep)
-{
-#ifdef CONFIG_ADS7843E_REFCNT
- FAR struct inode *inode;
- FAR struct ads7843e_dev_s *priv;
- int ret;
-
- ivdbg("Closing\n");
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct ads7843e_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Decrement the reference count unless it would decrement a negative
- * value. When the count decrements to zero, there are no further
- * open references to the driver.
- */
-
- if (priv->crefs >= 1)
- {
- priv->crefs--;
- }
-
- sem_post(&priv->devsem);
-#endif
- ivdbg("Closing\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: ads7843e_read
- ****************************************************************************/
-
-static ssize_t ads7843e_read(FAR struct file *filep, FAR char *buffer, size_t len)
-{
- FAR struct inode *inode;
- FAR struct ads7843e_dev_s *priv;
- FAR struct touch_sample_s *report;
- struct ads7843e_sample_s sample;
- int ret;
-
- ivdbg("buffer:%p len:%d\n", buffer, len);
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct ads7843e_dev_s *)inode->i_private;
-
- /* Verify that the caller has provided a buffer large enough to receive
- * the touch data.
- */
-
- if (len < SIZEOF_TOUCH_SAMPLE_S(1))
- {
- /* We could provide logic to break up a touch report into segments and
- * handle smaller reads... but why?
- */
-
- idbg("Unsupported read size: %d\n", len);
- return -ENOSYS;
- }
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- idbg("sem_wait: %d\n", errno);
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Try to read sample data. */
-
- ret = ads7843e_sample(priv, &sample);
- if (ret < 0)
- {
- /* Sample data is not available now. We would ave to wait to get
- * receive sample data. If the user has specified the O_NONBLOCK
- * option, then just return an error.
- */
-
- ivdbg("Sample data is not available\n");
- if (filep->f_oflags & O_NONBLOCK)
- {
- ret = -EAGAIN;
- goto errout;
- }
-
- /* Wait for sample data */
-
- ret = ads7843e_waitsample(priv, &sample);
- if (ret < 0)
- {
- /* We might have been awakened by a signal */
-
- idbg("ads7843e_waitsample: %d\n", ret);
- goto errout;
- }
- }
-
- /* In any event, we now have sampled ADS7843E data that we can report
- * to the caller.
- */
-
- report = (FAR struct touch_sample_s *)buffer;
- memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1));
- report->npoints = 1;
- report->point[0].id = sample.id;
- report->point[0].x = sample.x;
- report->point[0].y = sample.y;
-
- /* Report the appropriate flags */
-
- if (sample.contact == CONTACT_UP)
- {
- /* Pen is now up. Is the positional data valid? This is important to
- * know because the release will be sent to the window based on its
- * last positional data.
- */
-
- if (sample.valid)
- {
- report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID | TOUCH_POS_VALID;
- }
- else
- {
- report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID;
- }
- }
- else if (sample.contact == CONTACT_DOWN)
- {
- /* First contact */
-
- report->point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID;
- }
- else /* if (sample->contact == CONTACT_MOVE) */
- {
- /* Movement of the same contact */
-
- report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID;
- }
-
- ivdbg(" id: %d\n", report->point[0].id);
- ivdbg(" flags: %02x\n", report->point[0].flags);
- ivdbg(" x: %d\n", report->point[0].x);
- ivdbg(" y: %d\n", report->point[0].y);
-
- ret = SIZEOF_TOUCH_SAMPLE_S(1);
-
-errout:
- sem_post(&priv->devsem);
- ivdbg("Returning: %d\n", ret);
- return ret;
-}
-
-/****************************************************************************
- * Name:ads7843e_ioctl
- ****************************************************************************/
-
-static int ads7843e_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode;
- FAR struct ads7843e_dev_s *priv;
- int ret;
-
- ivdbg("cmd: %d arg: %ld\n", cmd, arg);
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct ads7843e_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Process the IOCTL by command */
-
- switch (cmd)
- {
- case TSIOC_SETFREQUENCY: /* arg: Pointer to uint32_t frequency value */
- {
- FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
- DEBUGASSERT(priv->config != NULL && ptr != NULL);
- priv->config->frequency = SPI_SETFREQUENCY(priv->spi, *ptr);
- }
- break;
-
- case TSIOC_GETFREQUENCY: /* arg: Pointer to uint32_t frequency value */
- {
- FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
- DEBUGASSERT(priv->config != NULL && ptr != NULL);
- *ptr = priv->config->frequency;
- }
- break;
-
- default:
- ret = -ENOTTY;
- break;
- }
-
- sem_post(&priv->devsem);
- return ret;
-}
-
-/****************************************************************************
- * Name: ads7843e_poll
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static int ads7843e_poll(FAR struct file *filep, FAR struct pollfd *fds,
- bool setup)
-{
- FAR struct inode *inode;
- FAR struct ads7843e_dev_s *priv;
- pollevent_t eventset;
- int ndx;
- int ret = OK;
- int i;
-
- ivdbg("setup: %d\n", (int)setup);
- DEBUGASSERT(filep && fds);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct ads7843e_dev_s *)inode->i_private;
-
- /* Are we setting up the poll? Or tearing it down? */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- if (setup)
- {
- /* Ignore waits that do not include POLLIN */
-
- if ((fds->events & POLLIN) == 0)
- {
- ret = -EDEADLK;
- goto errout;
- }
-
- /* This is a request to set up the poll. Find an available
- * slot for the poll structure reference
- */
-
- for (i = 0; i < CONFIG_ADS7843E_NPOLLWAITERS; i++)
- {
- /* Find an available slot */
-
- if (!priv->fds[i])
- {
- /* Bind the poll structure and this slot */
-
- priv->fds[i] = fds;
- fds->priv = &priv->fds[i];
- break;
- }
- }
-
- if (i >= CONFIG_ADS7843E_NPOLLWAITERS)
- {
- fds->priv = NULL;
- ret = -EBUSY;
- goto errout;
- }
-
- /* Should we immediately notify on any of the requested events? */
-
- if (priv->penchange)
- {
- ads7843e_notify(priv);
- }
- }
- else if (fds->priv)
- {
- /* This is a request to tear down the poll. */
-
- struct pollfd **slot = (struct pollfd **)fds->priv;
- DEBUGASSERT(slot != NULL);
-
- /* Remove all memory of the poll setup */
-
- *slot = NULL;
- fds->priv = NULL;
- }
-
-errout:
- sem_post(&priv->devsem);
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: ads7843e_register
- *
- * Description:
- * Configure the ADS7843E to use the provided SPI device instance. This
- * will register the driver as /dev/inputN where N is the minor device
- * number
- *
- * Input Parameters:
- * dev - An SPI driver instance
- * config - Persistent board configuration data
- * minor - The input device minor number
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-int ads7843e_register(FAR struct spi_dev_s *spi,
- FAR struct ads7843e_config_s *config, int minor)
-{
- FAR struct ads7843e_dev_s *priv;
- char devname[DEV_NAMELEN];
-#ifdef CONFIG_ADS7843E_MULTIPLE
- irqstate_t flags;
-#endif
- int ret;
-
- ivdbg("spi: %p minor: %d\n", spi, minor);
-
- /* Debug-only sanity checks */
-
- DEBUGASSERT(spi != NULL && config != NULL && minor >= 0 && minor < 100);
-
- /* Create and initialize a ADS7843E device driver instance */
-
-#ifndef CONFIG_ADS7843E_MULTIPLE
- priv = &g_ads7843e;
-#else
- priv = (FAR struct ads7843e_dev_s *)kmalloc(sizeof(struct ads7843e_dev_s));
- if (!priv)
- {
- idbg("kmalloc(%d) failed\n", sizeof(struct ads7843e_dev_s));
- return -ENOMEM;
- }
-#endif
-
- /* Initialize the ADS7843E device driver instance */
-
- memset(priv, 0, sizeof(struct ads7843e_dev_s));
- priv->spi = spi; /* Save the SPI device handle */
- priv->config = config; /* Save the board configuration */
- priv->wdog = wd_create(); /* Create a watchdog timer */
- priv->threshx = INVALID_THRESHOLD; /* Initialize thresholding logic */
- priv->threshy = INVALID_THRESHOLD; /* Initialize thresholding logic */
-
- sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */
- sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */
-
- /* Make sure that interrupts are disabled */
-
- config->clear(config);
- config->enable(config, false);
-
- /* Attach the interrupt handler */
-
- ret = config->attach(config, ads7843e_interrupt);
- if (ret < 0)
- {
- idbg("Failed to attach interrupt\n");
- goto errout_with_priv;
- }
-
- idbg("Mode: %d Bits: 8 Frequency: %d\n",
- CONFIG_ADS7843E_SPIMODE, CONFIG_ADS7843E_FREQUENCY);
-
- /* Lock the SPI bus so that we have exclusive access */
-
- ads7843e_lock(spi);
-
- /* Configure the SPI interface */
-
- ads7843e_configspi(spi);
-
- /* Enable the PEN IRQ */
-
- ads7843e_sendcmd(priv, ADS7843_CMD_ENABPINIRQ);
-
- /* Unlock the bus */
-
- ads7843e_unlock(spi);
-
- /* Register the device as an input device */
-
- (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor);
- ivdbg("Registering %s\n", devname);
-
- ret = register_driver(devname, &ads7843e_fops, 0666, priv);
- if (ret < 0)
- {
- idbg("register_driver() failed: %d\n", ret);
- goto errout_with_priv;
- }
-
- /* If multiple ADS7843E devices are supported, then we will need to add
- * this new instance to a list of device instances so that it can be
- * found by the interrupt handler based on the recieved IRQ number.
- */
-
-#ifdef CONFIG_ADS7843E_MULTIPLE
- priv->flink = g_ads7843elist;
- g_ads7843elist = priv;
- irqrestore(flags);
-#endif
-
- /* Schedule work to perform the initial sampling and to set the data
- * availability conditions.
- */
-
- ret = work_queue(HPWORK, &priv->work, ads7843e_worker, priv, 0);
- if (ret != 0)
- {
- idbg("Failed to queue work: %d\n", ret);
- goto errout_with_priv;
- }
-
- /* And return success (?) */
-
- return OK;
-
-errout_with_priv:
- sem_destroy(&priv->devsem);
-#ifdef CONFIG_ADS7843E_MULTIPLE
- kfree(priv);
-#endif
- return ret;
-}
diff --git a/nuttx/drivers/input/ads7843e.h b/nuttx/drivers/input/ads7843e.h
deleted file mode 100644
index 6fd70d98b..000000000
--- a/nuttx/drivers/input/ads7843e.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/********************************************************************************************
- * drivers/input/ads7843e.h
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "Touch Screen Controller, ADS7843," Burr-Brown Products from Texas
- * Instruments, SBAS090B, September 2000, Revised May 2002"
- *
- * See also:
- * "Low Voltage I/O Touch Screen Controller, TSC2046," Burr-Brown Products
- * from Texas Instruments, SBAS265F, October 2002, Revised August 2007."
- *
- * "XPT2046 Data Sheet," Shenzhen XPTek Technology Co., Ltd, 2007
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ********************************************************************************************/
-
-#ifndef __DRIVERS_INPUT_ADS7843E_H
-#define __DRIVERS_INPUT_ADS7843E_H
-
-/********************************************************************************************
- * Included Files
- ********************************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdint.h>
-#include <semaphore.h>
-#include <poll.h>
-#include <wdog.h>
-#include <nuttx/wqueue.h>
-
-#include <nuttx/spi.h>
-#include <nuttx/clock.h>
-#include <nuttx/input/ads7843e.h>
-
-/********************************************************************************************
- * Pre-Processor Definitions
- ********************************************************************************************/
-/* Configuration ****************************************************************************/
-/* Reference counting is partially implemented, but not needed in the current design. */
-
-#undef CONFIG_ADS7843E_REFCNT
-
-/* ADS7843E Interfaces *********************************************************************/
-/* ADS7843E command bit settings */
-
-#define ADS7843E_CMD_PD0 (1 << 0) /* PD0 */
-#define ADS7843E_CMD_PD1 (1 << 1) /* PD1 */
-#define ADS7843E_CMD_DFR (1 << 2) /* SER/DFR */
-#define ADS7843E_CMD_EIGHT_BITS_MOD (1 << 3) /* Mode */
-#define ADS7843E_CMD_START (1 << 7) /* Start Bit */
-#define ADS7843E_CMD_SWITCH_SHIFT 4 /* Address setting */
-
-/* ADS7843E Commands */
-
-#define ADS7843_CMD_YPOSITION \
- ((1 << ADS7843E_CMD_SWITCH_SHIFT)|ADS7843E_CMD_START|ADS7843E_CMD_PD0|ADS7843E_CMD_PD1)
-#define ADS7843_CMD_XPOSITION \
- ((5 << ADS7843E_CMD_SWITCH_SHIFT)|ADS7843E_CMD_START|ADS7843E_CMD_PD0|ADS7843E_CMD_PD1)
-#define ADS7843_CMD_ENABPINIRQ \
- ((1 << ADS7843E_CMD_SWITCH_SHIFT)|ADS7843E_CMD_START)
-
-/* Driver support **************************************************************************/
-/* This format is used to construct the /dev/input[n] device driver path. It
- * defined here so that it will be used consistently in all places.
- */
-
-#define DEV_FORMAT "/dev/input%d"
-#define DEV_NAMELEN 16
-
-/* Poll the pen position while the pen is down at this rate (50MS): */
-
-#define ADS7843E_WDOG_DELAY ((50 + (MSEC_PER_TICK-1))/ MSEC_PER_TICK)
-
-/********************************************************************************************
- * Public Types
- ********************************************************************************************/
-
-/* This describes the state of one contact */
-
-enum ads7843e_contact_3
-{
- CONTACT_NONE = 0, /* No contact */
- CONTACT_DOWN, /* First contact */
- CONTACT_MOVE, /* Same contact, possibly different position */
- CONTACT_UP, /* Contact lost */
-};
-
-/* This structure describes the results of one ADS7843E sample */
-
-struct ads7843e_sample_s
-{
- uint8_t id; /* Sampled touch point ID */
- uint8_t contact; /* Contact state (see enum ads7843e_contact_e) */
- bool valid; /* True: x,y contain valid, sampled data */
- uint16_t x; /* Measured X position */
- uint16_t y; /* Measured Y position */
-};
-
-/* This structure describes the state of one ADS7843E driver instance */
-
-struct ads7843e_dev_s
-{
-#ifdef CONFIG_ADS7843E_MULTIPLE
- FAR struct ads7843e_dev_s *flink; /* Supports a singly linked list of drivers */
-#endif
-#ifdef CONFIG_ADS7843E_REFCNT
- uint8_t crefs; /* Number of times the device has been opened */
-#endif
- uint8_t nwaiters; /* Number of threads waiting for ADS7843E data */
- uint8_t id; /* Current touch point ID */
- volatile bool penchange; /* An unreported event is buffered */
- uint16_t threshx; /* Thresholding X value */
- uint16_t threshy; /* Thresholding Y value */
- sem_t devsem; /* Manages exclusive access to this structure */
- sem_t waitsem; /* Used to wait for the availability of data */
-
- FAR struct ads7843e_config_s *config; /* Board configuration data */
- FAR struct spi_dev_s *spi; /* Saved SPI driver instance */
- struct work_s work; /* Supports the interrupt handling "bottom half" */
- struct ads7843e_sample_s sample; /* Last sampled touch point data */
- WDOG_ID wdog; /* Poll the position while the pen is down */
-
- /* The following is a list if poll structures of threads waiting for
- * driver events. The 'struct pollfd' reference for each open is also
- * retained in the f_priv field of the 'struct file'.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- struct pollfd *fds[CONFIG_ADS7843E_NPOLLWAITERS];
-#endif
-};
-
-/********************************************************************************************
- * Public Function Prototypes
- ********************************************************************************************/
-
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DRIVERS_INPUT_ADS7843E_H */
diff --git a/nuttx/drivers/input/max11802.c b/nuttx/drivers/input/max11802.c
deleted file mode 100644
index ea3883cd0..000000000
--- a/nuttx/drivers/input/max11802.c
+++ /dev/null
@@ -1,1313 +0,0 @@
-/****************************************************************************
- * drivers/input/max11802.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Authors: Gregory Nutt <gnutt@nuttx.org>
- * Petteri Aimonen <jpa@nx.mail.kapsi.fi>
- *
- * References:
- * "Low-Power, Ultra-Small Resistive Touch-Screen Controllers
- * with I2C/SPI Interface" Maxim IC, Rev 3, 10/2010
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <semaphore.h>
-#include <poll.h>
-#include <wdog.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/arch.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/spi.h>
-#include <nuttx/wqueue.h>
-
-#include <nuttx/input/touchscreen.h>
-#include <nuttx/input/max11802.h>
-
-#include "max11802.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* This is a value for the threshold that guantees a big difference on the
- * first pendown (but can't overflow).
- */
-
-#define INVALID_THRESHOLD 0x1000
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-/* Low-level SPI helpers */
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void max11802_configspi(FAR struct spi_dev_s *spi);
-# define max11802_lock(spi)
-# define max11802_unlock(spi)
-#else
-# define max11802_configspi(spi);
-static void max11802_lock(FAR struct spi_dev_s *spi);
-static void max11802_unlock(FAR struct spi_dev_s *spi);
-#endif
-
-static uint16_t max11802_sendcmd(FAR struct max11802_dev_s *priv, uint8_t cmd, int *tags);
-
-/* Interrupts and data sampling */
-
-static void max11802_notify(FAR struct max11802_dev_s *priv);
-static int max11802_sample(FAR struct max11802_dev_s *priv,
- FAR struct max11802_sample_s *sample);
-static int max11802_waitsample(FAR struct max11802_dev_s *priv,
- FAR struct max11802_sample_s *sample);
-static void max11802_worker(FAR void *arg);
-static int max11802_interrupt(int irq, FAR void *context);
-
-/* Character driver methods */
-
-static int max11802_open(FAR struct file *filep);
-static int max11802_close(FAR struct file *filep);
-static ssize_t max11802_read(FAR struct file *filep, FAR char *buffer, size_t len);
-static int max11802_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-#ifndef CONFIG_DISABLE_POLL
-static int max11802_poll(FAR struct file *filep, struct pollfd *fds, bool setup);
-#endif
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* This the the vtable that supports the character driver interface */
-
-static const struct file_operations max11802_fops =
-{
- max11802_open, /* open */
- max11802_close, /* close */
- max11802_read, /* read */
- 0, /* write */
- 0, /* seek */
- max11802_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , max11802_poll /* poll */
-#endif
-};
-
-/* If only a single MAX11802 device is supported, then the driver state
- * structure may as well be pre-allocated.
- */
-
-#ifndef CONFIG_MAX11802_MULTIPLE
-static struct max11802_dev_s g_max11802;
-
-/* Otherwise, we will need to maintain allocated driver instances in a list */
-
-#else
-static struct max11802_dev_s *g_max11802list;
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: max11802_lock
- *
- * Description:
- * Lock the SPI bus and re-configure as necessary. This function must be
- * to assure: (1) exclusive access to the SPI bus, and (2) to assure that
- * the shared bus is properly configured for the touchscreen controller.
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static void max11802_lock(FAR struct spi_dev_s *spi)
-{
- /* Lock the SPI bus because there are multiple devices competing for the
- * SPI bus
- */
-
- (void)SPI_LOCK(spi, true);
-
- /* We have the lock. Now make sure that the SPI bus is configured for the
- * MAX11802 (it might have gotten configured for a different device while
- * unlocked)
- */
-
- SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, true);
- SPI_SETMODE(spi, CONFIG_MAX11802_SPIMODE);
- SPI_SETBITS(spi, 8);
- SPI_SETFREQUENCY(spi, CONFIG_MAX11802_FREQUENCY);
- SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, false);
-}
-#endif
-
-/****************************************************************************
- * Function: max11802_unlock
- *
- * Description:
- * If we are sharing the SPI bus with other devices (CONFIG_SPI_OWNBUS
- * undefined) then we need to un-lock the SPI bus for each transfer,
- * possibly losing the current configuration.
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static void max11802_unlock(FAR struct spi_dev_s *spi)
-{
- /* Relinquish the SPI bus. */
-
- (void)SPI_LOCK(spi, false);
-}
-#endif
-
-/****************************************************************************
- * Function: max11802_configspi
- *
- * Description:
- * Configure the SPI for use with the MAX11802. This function should be
- * called once during touchscreen initialization to configure the SPI
- * bus. Note that if CONFIG_SPI_OWNBUS is not defined, then this function
- * does nothing.
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void max11802_configspi(FAR struct spi_dev_s *spi)
-{
- /* Configure SPI for the MAX11802. But only if we own the SPI bus. Otherwise, don't
- * bother because it might change.
- */
-
- SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, true);
- SPI_SETMODE(spi, CONFIG_MAX11802_SPIMODE);
- SPI_SETBITS(spi, 8);
- SPI_SETFREQUENCY(spi, CONFIG_MAX11802_FREQUENCY);
- SPI_SELECT(spi, SPIDEV_TOUCHSCREEN, false);
-}
-#endif
-
-/****************************************************************************
- * Name: max11802_sendcmd
- ****************************************************************************/
-
-static uint16_t max11802_sendcmd(FAR struct max11802_dev_s *priv, uint8_t cmd, int *tags)
-{
- uint8_t buffer[2];
- uint16_t result;
-
- /* Select the MAX11802 */
-
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, true);
-
- /* Send the command */
-
- (void)SPI_SEND(priv->spi, cmd);
-
- /* Read the data */
-
- SPI_RECVBLOCK(priv->spi, buffer, 2);
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, false);
-
- result = ((uint16_t)buffer[0] << 8) | (uint16_t)buffer[1];
- *tags = result & 0xF;
- result >>= 4; // Get rid of tags
-
- ivdbg("cmd:%02x response:%04x\n", cmd, result);
- return result;
-}
-
-/****************************************************************************
- * Name: max11802_notify
- ****************************************************************************/
-
-static void max11802_notify(FAR struct max11802_dev_s *priv)
-{
-#ifndef CONFIG_DISABLE_POLL
- int i;
-#endif
-
- /* If there are threads waiting for read data, then signal one of them
- * that the read data is available.
- */
-
- if (priv->nwaiters > 0)
- {
- /* After posting this semaphore, we need to exit because the sample
- * is no longer available.
- */
-
- sem_post(&priv->waitsem);
- }
-
- /* If there are threads waiting on poll() for MAX11802 data to become available,
- * then wake them up now. NOTE: we wake up all waiting threads because we
- * do not know that they are going to do. If they all try to read the data,
- * then some make end up blocking after all.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- for (i = 0; i < CONFIG_MAX11802_NPOLLWAITERS; i++)
- {
- struct pollfd *fds = priv->fds[i];
- if (fds)
- {
- fds->revents |= POLLIN;
- ivdbg("Report events: %02x\n", fds->revents);
- sem_post(fds->sem);
- }
- }
-#endif
-}
-
-/****************************************************************************
- * Name: max11802_sample
- ****************************************************************************/
-
-static int max11802_sample(FAR struct max11802_dev_s *priv,
- FAR struct max11802_sample_s *sample)
-{
- irqstate_t flags;
- int ret = -EAGAIN;
-
- /* Interrupts must be disabled when this is called to (1) prevent posting
- * of semaphores from interrupt handlers, and (2) to prevent sampled data
- * from changing until it has been reported.
- */
-
- flags = irqsave();
-
- /* Is there new MAX11802 sample data available? */
-
- if (priv->penchange)
- {
- /* Yes.. the state has changed in some way. Return a copy of the
- * sampled data.
- */
-
- memcpy(sample, &priv->sample, sizeof(struct max11802_sample_s ));
-
- /* Now manage state transitions */
-
- if (sample->contact == CONTACT_UP)
- {
- /* Next.. no contact. Increment the ID so that next contact ID
- * will be unique. X/Y positions are no longer valid.
- */
-
- priv->sample.contact = CONTACT_NONE;
- priv->sample.valid = false;
- priv->id++;
- }
- else if (sample->contact == CONTACT_DOWN)
- {
- /* First report -- next report will be a movement */
-
- priv->sample.contact = CONTACT_MOVE;
- }
-
- priv->penchange = false;
- ret = OK;
- }
-
- irqrestore(flags);
- return ret;
-}
-
-/****************************************************************************
- * Name: max11802_waitsample
- ****************************************************************************/
-
-static int max11802_waitsample(FAR struct max11802_dev_s *priv,
- FAR struct max11802_sample_s *sample)
-{
- irqstate_t flags;
- int ret;
-
- /* Interrupts must be disabled when this is called to (1) prevent posting
- * of semaphores from interrupt handlers, and (2) to prevent sampled data
- * from changing until it has been reported.
- *
- * In addition, we will also disable pre-emption to prevent other threads
- * from getting control while we muck with the semaphores.
- */
-
- sched_lock();
- flags = irqsave();
-
- /* Now release the semaphore that manages mutually exclusive access to
- * the device structure. This may cause other tasks to become ready to
- * run, but they cannot run yet because pre-emption is disabled.
- */
-
- sem_post(&priv->devsem);
-
- /* Try to get the a sample... if we cannot, then wait on the semaphore
- * that is posted when new sample data is available.
- */
-
- while (max11802_sample(priv, sample) < 0)
- {
- /* Wait for a change in the MAX11802 state */
-
- ivdbg("Waiting..\n");
- priv->nwaiters++;
- ret = sem_wait(&priv->waitsem);
- priv->nwaiters--;
-
- if (ret < 0)
- {
- /* If we are awakened by a signal, then we need to return
- * the failure now.
- */
-
- idbg("sem_wait: %d\n", errno);
- DEBUGASSERT(errno == EINTR);
- ret = -EINTR;
- goto errout;
- }
- }
-
- ivdbg("Sampled\n");
-
- /* Re-acquire the the semaphore that manages mutually exclusive access to
- * the device structure. We may have to wait here. But we have our sample.
- * Interrupts and pre-emption will be re-enabled while we wait.
- */
-
- ret = sem_wait(&priv->devsem);
-
-errout:
- /* Then re-enable interrupts. We might get interrupt here and there
- * could be a new sample. But no new threads will run because we still
- * have pre-emption disabled.
- */
-
- irqrestore(flags);
-
- /* Restore pre-emption. We might get suspended here but that is okay
- * because we already have our sample. Note: this means that if there
- * were two threads reading from the MAX11802 for some reason, the data
- * might be read out of order.
- */
-
- sched_unlock();
- return ret;
-}
-
-/****************************************************************************
- * Name: max11802_schedule
- ****************************************************************************/
-
-static int max11802_schedule(FAR struct max11802_dev_s *priv)
-{
- FAR struct max11802_config_s *config;
- int ret;
-
- /* Get a pointer the callbacks for convenience (and so the code is not so
- * ugly).
- */
-
- config = priv->config;
- DEBUGASSERT(config != NULL);
-
- /* Disable further interrupts. MAX11802 interrupts will be re-enabled
- * after the worker thread executes.
- */
-
- config->enable(config, false);
-
- /* Disable the watchdog timer. It will be re-enabled in the worker thread
- * while the pen remains down.
- */
-
- wd_cancel(priv->wdog);
-
- /* Transfer processing to the worker thread. Since MAX11802 interrupts are
- * disabled while the work is pending, no special action should be required
- * to protected the work queue.
- */
-
- DEBUGASSERT(priv->work.worker == NULL);
- ret = work_queue(HPWORK, &priv->work, max11802_worker, priv, 0);
- if (ret != 0)
- {
- illdbg("Failed to queue work: %d\n", ret);
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: max11802_wdog
- ****************************************************************************/
-
-static void max11802_wdog(int argc, uint32_t arg1, ...)
-{
- FAR struct max11802_dev_s *priv = (FAR struct max11802_dev_s *)((uintptr_t)arg1);
- (void)max11802_schedule(priv);
-}
-
-/****************************************************************************
- * Name: max11802_worker
- ****************************************************************************/
-
-static void max11802_worker(FAR void *arg)
-{
- FAR struct max11802_dev_s *priv = (FAR struct max11802_dev_s *)arg;
- FAR struct max11802_config_s *config;
- uint16_t x;
- uint16_t y;
- uint16_t xdiff;
- uint16_t ydiff;
- bool pendown;
- int ret;
- int tags, tags2;
-
- ASSERT(priv != NULL);
-
- /* Get a pointer the callbacks for convenience (and so the code is not so
- * ugly).
- */
-
- config = priv->config;
- DEBUGASSERT(config != NULL);
-
- /* Disable the watchdog timer. This is safe because it is started only
- * by this function and this function is serialized on the worker thread.
- */
-
- wd_cancel(priv->wdog);
-
- /* Lock the SPI bus so that we have exclusive access */
-
- max11802_lock(priv->spi);
-
- /* Start coordinate measurement */
- (void)max11802_sendcmd(priv, MAX11802_CMD_MEASUREXY, &tags);
-
- /* Get exclusive access to the driver data structure */
-
- do
- {
- ret = sem_wait(&priv->devsem);
-
- /* This should only fail if the wait was canceled by an signal
- * (and the worker thread will receive a lot of signals).
- */
-
- DEBUGASSERT(ret == OK || errno == EINTR);
- }
- while (ret < 0);
-
- /* Check for pen up or down by reading the PENIRQ GPIO. */
-
- pendown = config->pendown(config);
-
- /* Handle the change from pen down to pen up */
-
- if (pendown)
- ivdbg("\nPD\n");
- else
- ivdbg("\nPU\n");
-
- if (!pendown)
- {
- /* The pen is up.. reset thresholding variables. */
-
- priv->threshx = INVALID_THRESHOLD;
- priv->threshy = INVALID_THRESHOLD;
-
- /* Ignore the interrupt if the pen was already up (CONTACT_NONE == pen up
- * and already reported; CONTACT_UP == pen up, but not reported)
- */
-
- ivdbg("\nPC%d\n", priv->sample.contact);
-
- if (priv->sample.contact == CONTACT_NONE ||
- priv->sample.contact == CONTACT_UP)
-
- {
- goto ignored;
- }
-
- /* The pen is up. NOTE: We know from a previous test, that this is a
- * loss of contact condition. This will be changed to CONTACT_NONE
- * after the loss of contact is sampled.
- */
-
- priv->sample.contact = CONTACT_UP;
- }
-
- /* It is a pen down event. If the last loss-of-contact event has not been
- * processed yet, then we have to ignore the pen down event (or else it will
- * look like a drag event)
- */
-
- else if (priv->sample.contact == CONTACT_UP)
- {
- /* If we have not yet processed the last pen up event, then we
- * cannot handle this pen down event. We will have to discard it. That
- * should be okay because we will set the timer to to sample again
- * later.
- */
-
- ivdbg("Previous pen up event still in buffer\n");
- max11802_notify(priv);
- wd_start(priv->wdog, MAX11802_WDOG_DELAY, max11802_wdog, 1, (uint32_t)priv);
- goto ignored;
- }
- else
- {
- /* Wait for data ready */
- do {
- /* Handle pen down events. First, sample positional values. */
-
-#ifdef CONFIG_MAX11802_SWAPXY
- x = max11802_sendcmd(priv, MAX11802_CMD_YPOSITION, &tags);
- y = max11802_sendcmd(priv, MAX11802_CMD_XPOSITION, &tags2);
-#else
- x = max11802_sendcmd(priv, MAX11802_CMD_XPOSITION, &tags);
- y = max11802_sendcmd(priv, MAX11802_CMD_YPOSITION, &tags2);
-#endif
- } while (tags == 0xF || tags2 == 0xF);
-
- /* Continue to sample the position while the pen is down */
- wd_start(priv->wdog, MAX11802_WDOG_DELAY, max11802_wdog, 1, (uint32_t)priv);
-
- /* Check if data is valid */
- if ((tags & 0x03) != 0)
- {
- ivdbg("Touch ended before measurement\n");
- goto ignored;
- }
-
- /* Perform a thresholding operation so that the results will be more stable.
- * If the difference from the last sample is small, then ignore the event.
- * REVISIT: Should a large change in pressure also generate a event?
- */
-
- xdiff = x > priv->threshx ? (x - priv->threshx) : (priv->threshx - x);
- ydiff = y > priv->threshy ? (y - priv->threshy) : (priv->threshy - y);
-
- /* Check the thresholds. Bail if there is no significant difference */
-
- if (xdiff < CONFIG_MAX11802_THRESHX && ydiff < CONFIG_MAX11802_THRESHY)
- {
- /* Little or no change in either direction ... don't report anything. */
-
- goto ignored;
- }
-
- /* When we see a big difference, snap to the new x/y thresholds */
-
- priv->threshx = x;
- priv->threshy = y;
-
- /* Update the x/y position in the sample data */
-
- priv->sample.x = priv->threshx;
- priv->sample.y = priv->threshy;
-
- /* The X/Y positional data is now valid */
-
- priv->sample.valid = true;
-
- /* If this is the first (acknowledged) pen down report, then report
- * this as the first contact. If contact == CONTACT_DOWN, it will be
- * set to set to CONTACT_MOVE after the contact is first sampled.
- */
-
- if (priv->sample.contact != CONTACT_MOVE)
- {
- /* First contact */
-
- priv->sample.contact = CONTACT_DOWN;
- }
- }
-
- /* Indicate the availability of new sample data for this ID */
-
- priv->sample.id = priv->id;
- priv->penchange = true;
-
- /* Notify any waiters that new MAX11802 data is available */
-
- max11802_notify(priv);
-
-ignored:
- config->enable(config, true);
-
- /* Release our lock on the state structure and unlock the SPI bus */
-
- sem_post(&priv->devsem);
- max11802_unlock(priv->spi);
-}
-
-/****************************************************************************
- * Name: max11802_interrupt
- ****************************************************************************/
-
-static int max11802_interrupt(int irq, FAR void *context)
-{
- FAR struct max11802_dev_s *priv;
- FAR struct max11802_config_s *config;
- int ret;
-
- /* Which MAX11802 device caused the interrupt? */
-
-#ifndef CONFIG_MAX11802_MULTIPLE
- priv = &g_max11802;
-#else
- for (priv = g_max11802list;
- priv && priv->configs->irq != irq;
- priv = priv->flink);
-
- ASSERT(priv != NULL);
-#endif
-
- /* Get a pointer the callbacks for convenience (and so the code is not so
- * ugly).
- */
-
- config = priv->config;
- DEBUGASSERT(config != NULL);
-
- /* Schedule sampling to occur on the worker thread */
-
- ret = max11802_schedule(priv);
-
- /* Clear any pending interrupts and return success */
-
- config->clear(config);
- return ret;
-}
-
-/****************************************************************************
- * Name: max11802_open
- ****************************************************************************/
-
-static int max11802_open(FAR struct file *filep)
-{
-#ifdef CONFIG_MAX11802_REFCNT
- FAR struct inode *inode;
- FAR struct max11802_dev_s *priv;
- uint8_t tmp;
- int ret;
-
- ivdbg("Opening\n");
-
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct max11802_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Increment the reference count */
-
- tmp = priv->crefs + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- goto errout_with_sem;
- }
-
- /* When the reference increments to 1, this is the first open event
- * on the driver.. and an opportunity to do any one-time initialization.
- */
-
- /* Save the new open count on success */
-
- priv->crefs = tmp;
-
-errout_with_sem:
- sem_post(&priv->devsem);
- return ret;
-#else
- ivdbg("Opening\n");
- return OK;
-#endif
-}
-
-/****************************************************************************
- * Name: max11802_close
- ****************************************************************************/
-
-static int max11802_close(FAR struct file *filep)
-{
-#ifdef CONFIG_MAX11802_REFCNT
- FAR struct inode *inode;
- FAR struct max11802_dev_s *priv;
- int ret;
-
- ivdbg("Closing\n");
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct max11802_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Decrement the reference count unless it would decrement a negative
- * value. When the count decrements to zero, there are no further
- * open references to the driver.
- */
-
- if (priv->crefs >= 1)
- {
- priv->crefs--;
- }
-
- sem_post(&priv->devsem);
-#endif
- ivdbg("Closing\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: max11802_read
- ****************************************************************************/
-
-static ssize_t max11802_read(FAR struct file *filep, FAR char *buffer, size_t len)
-{
- FAR struct inode *inode;
- FAR struct max11802_dev_s *priv;
- FAR struct touch_sample_s *report;
- struct max11802_sample_s sample;
- int ret;
-
- ivdbg("buffer:%p len:%d\n", buffer, len);
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct max11802_dev_s *)inode->i_private;
-
- /* Verify that the caller has provided a buffer large enough to receive
- * the touch data.
- */
-
- if (len < SIZEOF_TOUCH_SAMPLE_S(1))
- {
- /* We could provide logic to break up a touch report into segments and
- * handle smaller reads... but why?
- */
-
- idbg("Unsupported read size: %d\n", len);
- return -ENOSYS;
- }
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- idbg("sem_wait: %d\n", errno);
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Try to read sample data. */
-
- ret = max11802_sample(priv, &sample);
- if (ret < 0)
- {
- /* Sample data is not available now. We would ave to wait to get
- * receive sample data. If the user has specified the O_NONBLOCK
- * option, then just return an error.
- */
-
- ivdbg("Sample data is not available\n");
- if (filep->f_oflags & O_NONBLOCK)
- {
- ret = -EAGAIN;
- goto errout;
- }
-
- /* Wait for sample data */
-
- ret = max11802_waitsample(priv, &sample);
- if (ret < 0)
- {
- /* We might have been awakened by a signal */
-
- idbg("max11802_waitsample: %d\n", ret);
- goto errout;
- }
- }
-
- /* In any event, we now have sampled MAX11802 data that we can report
- * to the caller.
- */
-
- report = (FAR struct touch_sample_s *)buffer;
- memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1));
- report->npoints = 1;
- report->point[0].id = sample.id;
- report->point[0].x = sample.x;
- report->point[0].y = sample.y;
-
- /* Report the appropriate flags */
-
- if (sample.contact == CONTACT_UP)
- {
- /* Pen is now up. Is the positional data valid? This is important to
- * know because the release will be sent to the window based on its
- * last positional data.
- */
-
- if (sample.valid)
- {
- report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID | TOUCH_POS_VALID;
- }
- else
- {
- report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID;
- }
- }
- else if (sample.contact == CONTACT_DOWN)
- {
- /* First contact */
-
- report->point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID;
- }
- else /* if (sample->contact == CONTACT_MOVE) */
- {
- /* Movement of the same contact */
-
- report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID;
- }
-
- ivdbg(" id: %d\n", report->point[0].id);
- ivdbg(" flags: %02x\n", report->point[0].flags);
- ivdbg(" x: %d\n", report->point[0].x);
- ivdbg(" y: %d\n", report->point[0].y);
-
- ret = SIZEOF_TOUCH_SAMPLE_S(1);
-
-errout:
- sem_post(&priv->devsem);
- ivdbg("Returning: %d\n", ret);
- return ret;
-}
-
-/****************************************************************************
- * Name:max11802_ioctl
- ****************************************************************************/
-
-static int max11802_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode;
- FAR struct max11802_dev_s *priv;
- int ret;
-
- ivdbg("cmd: %d arg: %ld\n", cmd, arg);
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct max11802_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Process the IOCTL by command */
-
- switch (cmd)
- {
- case TSIOC_SETFREQUENCY: /* arg: Pointer to uint32_t frequency value */
- {
- FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
- DEBUGASSERT(priv->config != NULL && ptr != NULL);
- priv->config->frequency = SPI_SETFREQUENCY(priv->spi, *ptr);
- }
- break;
-
- case TSIOC_GETFREQUENCY: /* arg: Pointer to uint32_t frequency value */
- {
- FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
- DEBUGASSERT(priv->config != NULL && ptr != NULL);
- *ptr = priv->config->frequency;
- }
- break;
-
- default:
- ret = -ENOTTY;
- break;
- }
-
- sem_post(&priv->devsem);
- return ret;
-}
-
-/****************************************************************************
- * Name: max11802_poll
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static int max11802_poll(FAR struct file *filep, FAR struct pollfd *fds,
- bool setup)
-{
- FAR struct inode *inode;
- FAR struct max11802_dev_s *priv;
- pollevent_t eventset;
- int ndx;
- int ret = OK;
- int i;
-
- ivdbg("setup: %d\n", (int)setup);
- DEBUGASSERT(filep && fds);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct max11802_dev_s *)inode->i_private;
-
- /* Are we setting up the poll? Or tearing it down? */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- if (setup)
- {
- /* Ignore waits that do not include POLLIN */
-
- if ((fds->events & POLLIN) == 0)
- {
- ret = -EDEADLK;
- goto errout;
- }
-
- /* This is a request to set up the poll. Find an available
- * slot for the poll structure reference
- */
-
- for (i = 0; i < CONFIG_MAX11802_NPOLLWAITERS; i++)
- {
- /* Find an available slot */
-
- if (!priv->fds[i])
- {
- /* Bind the poll structure and this slot */
-
- priv->fds[i] = fds;
- fds->priv = &priv->fds[i];
- break;
- }
- }
-
- if (i >= CONFIG_MAX11802_NPOLLWAITERS)
- {
- fds->priv = NULL;
- ret = -EBUSY;
- goto errout;
- }
-
- /* Should we immediately notify on any of the requested events? */
-
- if (priv->penchange)
- {
- max11802_notify(priv);
- }
- }
- else if (fds->priv)
- {
- /* This is a request to tear down the poll. */
-
- struct pollfd **slot = (struct pollfd **)fds->priv;
- DEBUGASSERT(slot != NULL);
-
- /* Remove all memory of the poll setup */
-
- *slot = NULL;
- fds->priv = NULL;
- }
-
-errout:
- sem_post(&priv->devsem);
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: max11802_register
- *
- * Description:
- * Configure the MAX11802 to use the provided SPI device instance. This
- * will register the driver as /dev/inputN where N is the minor device
- * number
- *
- * Input Parameters:
- * dev - An SPI driver instance
- * config - Persistent board configuration data
- * minor - The input device minor number
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-int max11802_register(FAR struct spi_dev_s *spi,
- FAR struct max11802_config_s *config, int minor)
-{
- FAR struct max11802_dev_s *priv;
- char devname[DEV_NAMELEN];
-#ifdef CONFIG_MAX11802_MULTIPLE
- irqstate_t flags;
-#endif
- int ret;
-
- ivdbg("spi: %p minor: %d\n", spi, minor);
-
- /* Debug-only sanity checks */
-
- DEBUGASSERT(spi != NULL && config != NULL && minor >= 0 && minor < 100);
-
- /* Create and initialize a MAX11802 device driver instance */
-
-#ifndef CONFIG_MAX11802_MULTIPLE
- priv = &g_max11802;
-#else
- priv = (FAR struct max11802_dev_s *)kmalloc(sizeof(struct max11802_dev_s));
- if (!priv)
- {
- idbg("kmalloc(%d) failed\n", sizeof(struct max11802_dev_s));
- return -ENOMEM;
- }
-#endif
-
- /* Initialize the MAX11802 device driver instance */
-
- memset(priv, 0, sizeof(struct max11802_dev_s));
- priv->spi = spi; /* Save the SPI device handle */
- priv->config = config; /* Save the board configuration */
- priv->wdog = wd_create(); /* Create a watchdog timer */
- priv->threshx = INVALID_THRESHOLD; /* Initialize thresholding logic */
- priv->threshy = INVALID_THRESHOLD; /* Initialize thresholding logic */
-
- sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */
- sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */
-
- /* Make sure that interrupts are disabled */
-
- config->clear(config);
- config->enable(config, false);
-
- /* Attach the interrupt handler */
-
- ret = config->attach(config, max11802_interrupt);
- if (ret < 0)
- {
- idbg("Failed to attach interrupt\n");
- goto errout_with_priv;
- }
-
- idbg("Mode: %d Bits: 8 Frequency: %d\n",
- CONFIG_MAX11802_SPIMODE, CONFIG_MAX11802_FREQUENCY);
-
- /* Lock the SPI bus so that we have exclusive access */
-
- max11802_lock(spi);
-
- /* Configure the SPI interface */
-
- max11802_configspi(spi);
-
- /* Configure MAX11802 registers */
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, true);
- (void)SPI_SEND(priv->spi, MAX11802_CMD_MODE_WR);
- (void)SPI_SEND(priv->spi, MAX11802_MODE);
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, false);
-
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, true);
- (void)SPI_SEND(priv->spi, MAX11802_CMD_AVG_WR);
- (void)SPI_SEND(priv->spi, MAX11802_AVG);
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, false);
-
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, true);
- (void)SPI_SEND(priv->spi, MAX11802_CMD_TIMING_WR);
- (void)SPI_SEND(priv->spi, MAX11802_TIMING);
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, false);
-
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, true);
- (void)SPI_SEND(priv->spi, MAX11802_CMD_DELAY_WR);
- (void)SPI_SEND(priv->spi, MAX11802_DELAY);
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, false);
-
- /* Test that the device access was successful. */
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, true);
- (void)SPI_SEND(priv->spi, MAX11802_CMD_MODE_RD);
- ret = SPI_SEND(priv->spi, 0);
- SPI_SELECT(priv->spi, SPIDEV_TOUCHSCREEN, false);
-
- /* Unlock the bus */
- max11802_unlock(spi);
-
- if (ret != MAX11802_MODE)
- {
- idbg("max11802 mode readback failed: %02x\n", ret);
- goto errout_with_priv;
- }
-
- /* Register the device as an input device */
-
- (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor);
- ivdbg("Registering %s\n", devname);
-
- ret = register_driver(devname, &max11802_fops, 0666, priv);
- if (ret < 0)
- {
- idbg("register_driver() failed: %d\n", ret);
- goto errout_with_priv;
- }
-
- /* If multiple MAX11802 devices are supported, then we will need to add
- * this new instance to a list of device instances so that it can be
- * found by the interrupt handler based on the recieved IRQ number.
- */
-
-#ifdef CONFIG_MAX11802_MULTIPLE
- priv->flink = g_max11802list;
- g_max11802list = priv;
- irqrestore(flags);
-#endif
-
- /* Schedule work to perform the initial sampling and to set the data
- * availability conditions.
- */
-
- ret = work_queue(HPWORK, &priv->work, max11802_worker, priv, 0);
- if (ret != 0)
- {
- idbg("Failed to queue work: %d\n", ret);
- goto errout_with_priv;
- }
-
- /* And return success (?) */
-
- return OK;
-
-errout_with_priv:
- sem_destroy(&priv->devsem);
-#ifdef CONFIG_MAX11802_MULTIPLE
- kfree(priv);
-#endif
- return ret;
-}
diff --git a/nuttx/drivers/input/max11802.h b/nuttx/drivers/input/max11802.h
deleted file mode 100644
index b6beec045..000000000
--- a/nuttx/drivers/input/max11802.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/********************************************************************************************
- * drivers/input/max11802.h
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Authors: Gregory Nutt <gnutt@nuttx.org>
- * Petteri Aimonen <jpa@nx.mail.kapsi.fi>
- *
- * References:
- * "Low-Power, Ultra-Small Resistive Touch-Screen Controllers
- * with I2C/SPI Interface" Maxim IC, Rev 3, 10/2010
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ********************************************************************************************/
-
-#ifndef __DRIVERS_INPUT_MAX11802_H
-#define __DRIVERS_INPUT_MAX11802_H
-
-/********************************************************************************************
- * Included Files
- ********************************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdint.h>
-#include <semaphore.h>
-#include <poll.h>
-#include <wdog.h>
-#include <nuttx/wqueue.h>
-
-#include <nuttx/spi.h>
-#include <nuttx/clock.h>
-#include <nuttx/input/max11802.h>
-
-/********************************************************************************************
- * Pre-Processor Definitions
- ********************************************************************************************/
-/* Configuration ****************************************************************************/
-
-/* MAX11802 Interfaces *********************************************************************/
-
-/* LSB of register addresses specifies read (1) or write (0). */
-#define MAX11802_CMD_XPOSITION ((0x52 << 1) | 1)
-#define MAX11802_CMD_YPOSITION ((0x54 << 1) | 1)
-#define MAX11802_CMD_MEASUREXY (0x70 << 1)
-#define MAX11802_CMD_MODE_WR (0x0B << 1)
-#define MAX11802_CMD_MODE_RD ((0x0B << 1) | 1)
-#define MAX11802_CMD_AVG_WR (0x03 << 1)
-#define MAX11802_CMD_TIMING_WR (0x05 << 1)
-#define MAX11802_CMD_DELAY_WR (0x06 << 1)
-
-/* Register values to set */
-#define MAX11802_MODE 0x0E
-#define MAX11802_AVG 0x55
-#define MAX11802_TIMING 0x77
-#define MAX11802_DELAY 0x55
-
-/* Driver support **************************************************************************/
-/* This format is used to construct the /dev/input[n] device driver path. It
- * defined here so that it will be used consistently in all places.
- */
-
-#define DEV_FORMAT "/dev/input%d"
-#define DEV_NAMELEN 16
-
-/* Poll the pen position while the pen is down at this rate (50MS): */
-
-#define MAX11802_WDOG_DELAY ((50 + (MSEC_PER_TICK-1))/ MSEC_PER_TICK)
-
-/********************************************************************************************
- * Public Types
- ********************************************************************************************/
-
-/* This describes the state of one contact */
-
-enum max11802_contact_3
-{
- CONTACT_NONE = 0, /* No contact */
- CONTACT_DOWN, /* First contact */
- CONTACT_MOVE, /* Same contact, possibly different position */
- CONTACT_UP, /* Contact lost */
-};
-
-/* This structure describes the results of one MAX11802 sample */
-
-struct max11802_sample_s
-{
- uint8_t id; /* Sampled touch point ID */
- uint8_t contact; /* Contact state (see enum ads7843e_contact_e) */
- bool valid; /* True: x,y contain valid, sampled data */
- uint16_t x; /* Measured X position */
- uint16_t y; /* Measured Y position */
-};
-
-/* This structure describes the state of one MAX11802 driver instance */
-
-struct max11802_dev_s
-{
-#ifdef CONFIG_ADS7843E_MULTIPLE
- FAR struct ads7843e_dev_s *flink; /* Supports a singly linked list of drivers */
-#endif
- uint8_t nwaiters; /* Number of threads waiting for MAX11802 data */
- uint8_t id; /* Current touch point ID */
- volatile bool penchange; /* An unreported event is buffered */
- uint16_t threshx; /* Thresholding X value */
- uint16_t threshy; /* Thresholding Y value */
- sem_t devsem; /* Manages exclusive access to this structure */
- sem_t waitsem; /* Used to wait for the availability of data */
-
- FAR struct max11802_config_s *config; /* Board configuration data */
- FAR struct spi_dev_s *spi; /* Saved SPI driver instance */
- struct work_s work; /* Supports the interrupt handling "bottom half" */
- struct max11802_sample_s sample; /* Last sampled touch point data */
- WDOG_ID wdog; /* Poll the position while the pen is down */
-
- /* The following is a list if poll structures of threads waiting for
- * driver events. The 'struct pollfd' reference for each open is also
- * retained in the f_priv field of the 'struct file'.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- struct pollfd *fds[CONFIG_ADS7843E_NPOLLWAITERS];
-#endif
-};
-
-/********************************************************************************************
- * Public Function Prototypes
- ********************************************************************************************/
-
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DRIVERS_INPUT_ADS7843E_H */
diff --git a/nuttx/drivers/input/stmpe811.h b/nuttx/drivers/input/stmpe811.h
deleted file mode 100644
index f6d646527..000000000
--- a/nuttx/drivers/input/stmpe811.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/********************************************************************************************
- * drivers/input/stmpe811.h
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
- * GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ********************************************************************************************/
-
-#ifndef __DRIVERS_INPUT_STMPE811_H
-#define __DRIVERS_INPUT_STMPE811_H
-
-/********************************************************************************************
- * Included Files
- ********************************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <wdog.h>
-#include <semaphore.h>
-
-#include <nuttx/clock.h>
-#include <nuttx/wqueue.h>
-#include <nuttx/input/stmpe811.h>
-
-#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811)
-
-/********************************************************************************************
- * Pre-Processor Definitions
- ********************************************************************************************/
-/* Configuration ****************************************************************************/
-/* Reference counting is partially implemented, but not needed in the current design.
- */
-
-#undef CONFIG_STMPE811_REFCNT
-
-/* No support for the SPI interface yet */
-
-#ifdef CONFIG_STMPE811_SPI
-# error "Only the STMPE811 I2C interface is supported by this driver"
-#endif
-
-/* Driver support ***************************************************************************/
-/* This format is used to construct the /dev/input[n] device driver path. It defined here
- * so that it will be used consistently in all places.
- */
-
-#define DEV_FORMAT "/dev/input%d"
-#define DEV_NAMELEN 16
-
-/* STMPE811 Resources ************************************************************************/
-#ifndef CONFIG_STMPE811_TSC_DISABLE
-# define STMPE811_ADC_NPINS 4 /* Only pins 0-3 can be used for ADC */
-# define STMPE811_GPIO_NPINS 4 /* Only pins 0-3 can be used as GPIOs */
-#else
-# define STMPE811_ADC_NPINS 8 /* All pins can be used for ADC */
-# define STMPE811_GPIO_NPINS 8 /* All pins can be used as GPIOs */
-#endif
-
-/* Driver flags */
-
-#define STMPE811_FLAGS_TSC_INITIALIZED (1 << 0) /* 1: The TSC block has been initialized */
-#define STMPE811_FLAGS_GPIO_INITIALIZED (1 << 1) /* 1: The GIO block has been initialized */
-#define STMPE811_FLAGS_ADC_INITIALIZED (1 << 2) /* 1: The ADC block has been initialized */
-#define STMPE811_FLAGS_TS_INITIALIZED (1 << 3) /* 1: The TS block has been initialized */
-
-/* Timeout to detect missing pen up events */
-
-#define STMPE811_PENUP_TICKS ((100 + (MSEC_PER_TICK-1)) / MSEC_PER_TICK)
-
-/********************************************************************************************
- * Public Types
- ********************************************************************************************/
-/* This describes the state of one contact */
-
-enum stmpe811_contact_3
-{
- CONTACT_NONE = 0, /* No contact */
- CONTACT_DOWN, /* First contact */
- CONTACT_MOVE, /* Same contact, possibly different position */
- CONTACT_UP, /* Contact lost */
-};
-
-/* This structure describes the results of one STMPE811 sample */
-
-struct stmpe811_sample_s
-{
- uint8_t id; /* Sampled touch point ID */
- uint8_t contact; /* Contact state (see enum stmpe811_contact_e) */
- bool valid; /* True: x,y,z contain valid, sampled data */
- uint16_t x; /* Measured X position */
- uint16_t y; /* Measured Y position */
- uint8_t z; /* Measured Z index */
-};
-
-/* This structure represents the state of the STMPE811 driver */
-
-struct stmpe811_dev_s
-{
-#ifdef CONFIG_STMPE811_MULTIPLE
- FAR struct stmpe811_dev_s *flink; /* Supports a singly linked list of drivers */
-#endif
-
- /* Common fields */
-
- FAR struct stmpe811_config_s *config; /* Board configuration data */
- sem_t exclsem; /* Manages exclusive access to this structure */
-#ifdef CONFIG_STMPE811_SPI
- FAR struct spi_dev_s *spi; /* Saved SPI driver instance */
-#else
- FAR struct i2c_dev_s *i2c; /* Saved I2C driver instance */
-#endif
-
- uint8_t inuse; /* STMPE811 pins in use */
- uint8_t flags; /* See STMPE811_FLAGS_* definitions */
- struct work_s work; /* Supports the interrupt handling "bottom half" */
-
- /* Fields that may be disabled to save size if touchscreen support is not used. */
-
-#ifndef CONFIG_STMPE811_TSC_DISABLE
-#ifdef CONFIG_STMPE811_REFCNT
- uint8_t crefs; /* Number of times the device has been opened */
-#endif
- uint8_t nwaiters; /* Number of threads waiting for STMPE811 data */
- uint8_t id; /* Current touch point ID */
- uint8_t minor; /* Touchscreen minor device number */
- volatile bool penchange; /* An unreported event is buffered */
-
- uint16_t threshx; /* Thresholded X value */
- uint16_t threshy; /* Thresholded Y value */
- sem_t waitsem; /* Used to wait for the availability of data */
-
- struct work_s timeout; /* Supports tiemeout work */
- WDOG_ID wdog; /* Timeout to detect missing pen down events */
- struct stmpe811_sample_s sample; /* Last sampled touch point data */
-
- /* The following is a list if poll structures of threads waiting for
- * driver events. The 'struct pollfd' reference for each open is also
- * retained in the f_priv field of the 'struct file'.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- struct pollfd *fds[CONFIG_STMPE811_NPOLLWAITERS];
-#endif
-#endif
-
- /* Fields that may be disabled to save size of GPIO support is not used */
-
-#if !defined(CONFIG_STMPE811_GPIO_DISABLE) && !defined(CONFIG_STMPE811_GPIOINT_DISABLE)
- stmpe811_handler_t handlers[STMPE811_GPIO_NPINS]; /* GPIO "interrupt handlers" */
-#endif
-};
-
-/********************************************************************************************
- * Public Function Prototypes
- ********************************************************************************************/
-
-/********************************************************************************************
- * Name: stmpe811_getreg8
- *
- * Description:
- * Read from an 8-bit STMPE811 register
- *
- ********************************************************************************************/
-
-uint8_t stmpe811_getreg8(FAR struct stmpe811_dev_s *priv, uint8_t regaddr);
-
-/********************************************************************************************
- * Name: stmpe811_putreg8
- *
- * Description:
- * Write a value to an 8-bit STMPE811 register
- *
- ********************************************************************************************/
-
-void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv, uint8_t regaddr, uint8_t regval);
-
-/********************************************************************************************
- * Name: stmpe811_getreg16
- *
- * Description:
- * Read 16-bits of data from an STMPE-11 register
- *
- ********************************************************************************************/
-
-uint16_t stmpe811_getreg16(FAR struct stmpe811_dev_s *priv, uint8_t regaddr);
-
-/********************************************************************************************
- * Name: stmpe811_tscint
- *
- * Description:
- * Handle touchscreen interrupt events (this function actually executes in the context of
- * the worker thread).
- *
- ********************************************************************************************/
-
-#ifndef CONFIG_STMPE811_TSC_DISABLE
-void stmpe811_tscworker(FAR struct stmpe811_dev_s *priv, uint8_t intsta) weak_function;
-#endif
-
-/********************************************************************************************
- * Name: stmpe811_gpioworker
- *
- * Description:
- * Handle GPIO interrupt events (this function actually executes in the context of the
- * worker thread).
- *
- ********************************************************************************************/
-
-#if !defined(CONFIG_STMPE811_GPIO_DISABLE) && !defined(CONFIG_STMPE811_GPIOINT_DISABLE)
-void stmpe811_gpioworker(FAR struct stmpe811_dev_s *priv) weak_function;
-#endif
-
-#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 */
-#endif /* __DRIVERS_INPUT_STMPE811_H */
diff --git a/nuttx/drivers/input/stmpe811_adc.c b/nuttx/drivers/input/stmpe811_adc.c
deleted file mode 100644
index 1ffe987e6..000000000
--- a/nuttx/drivers/input/stmpe811_adc.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/****************************************************************************
- * drivers/input/stmpe811_adc.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
- * GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
- *
- * 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 <nuttx/config.h>
-
-#include <unistd.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/input/stmpe811.h>
-
-#include "stmpe811.h"
-
-#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811) && !defined(CONFIG_STMPE811_ADC_DISABLE)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: stmpe811_adcinitialize
- *
- * Description:
- * Configure for ADC mode operation. Set overall ADC ADC timing that
- * applies to all pins.
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-int stmpe811_adcinitialize(STMPE811_HANDLE handle)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
- uint8_t regval;
- int ret;
-
- DEBUGASSERT(handle);
-
- /* Get exclusive access to the device structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- int errval = errno;
- idbg("sem_wait failed: %d\n", errval);
- return -errval;
- }
-
- /* Enable Clocking for ADC */
-
- regval = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
- regval &= ~SYS_CTRL2_ADC_OFF;
- stmpe811_putreg8(priv, STMPE811_SYS_CTRL2, regval);
-
- /* Select Sample Time, bit number and ADC Reference */
-
- stmpe811_putreg8(priv, STMPE811_ADC_CTRL1, priv->config->ctrl1);
-
- /* Wait for 20 ms */
-
- up_mdelay(20);
-
- /* Select the ADC clock speed */
-
- stmpe811_putreg8(priv, STMPE811_ADC_CTRL2, priv->config->ctrl2);
-
- /* Mark ADC initialized */
-
- priv->flags |= STMPE811_FLAGS_ADC_INITIALIZED;
- sem_post(&priv->exclsem);
- return OK;
-}
-
-/****************************************************************************
- * Name: stmpe811_adcconfig
- *
- * Description:
- * Configure a pin for ADC input.
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- * pin - The ADC pin number
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-int stmpe811_adcconfig(STMPE811_HANDLE handle, int pin)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
- uint8_t pinmask = GPIO_PIN(pin);
- uint8_t regval;
- int ret;
-
- DEBUGASSERT(handle && (unsigned)pin < STMPE811_ADC_NPINS);
-
- /* Get exclusive access to the device structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- int errval = errno;
- idbg("sem_wait failed: %d\n", errval);
- return -errval;
- }
-
- /* Make sure that the pin is not already in use */
-
- if ((priv->inuse & pinmask) != 0)
- {
- idbg("PIN%d is already in-use\n", pin);
- sem_post(&priv->exclsem);
- return -EBUSY;
- }
-
- /* Clear the alternate function bit for the pin, making it an ADC input
- * (or perhaps an an external reference, depending on the state of the
- * ADC_CTRL1_REF_SEL bit).
- */
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_AF);
- regval &= ~pinmask;
- stmpe811_putreg8(priv, STMPE811_GPIO_AF, regval);
-
- /* Mark the pin as 'in use' */
-
- priv->inuse |= pinmask;
- sem_post(&priv->exclsem);
- return OK;
-}
-
-/****************************************************************************
- * Name: stmpe811_adcread
- *
- * Description:
- * Read the converted analog input value from the select pin.
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- * pin - The ADC pin number
- *
- * Returned Value:
- * The converted value (there is no error reporting mechanism).
- *
- ****************************************************************************/
-
-uint16_t stmpe811_adcread(STMPE811_HANDLE handle, int pin)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
- uint8_t pinmask = GPIO_PIN(pin);
- uint8_t regval;
- int i;
- int ret;
-
- DEBUGASSERT(handle && (unsigned)pin < 8);
-
- /* Get exclusive access to the device structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- int errval = errno;
- idbg("sem_wait failed: %d\n", errval);
- return -errval;
- }
-
- /* Request AD conversion by setting the bit corresponding the pin in the
- * ADC CAPT register.
- */
-
- stmpe811_putreg8(priv, STMPE811_ADC_CAPT, pinmask);
-
- /* Wait for the conversion to complete. The ADC CAPT register reads '1'
- * if conversion is completed. Reads '0' if conversion is in progress.
- * Try three times before giving up.
- */
-
- for (i = 0; i < 3; i++)
- {
- /* The worst case ADC conversion time is (nominally) 56.4 uS. The
- * following usleep() looks nice but in reality, the usleep()
- * does not have that kind of precision (it will probably end up
- * waiting 10 MS).
- */
-
- usleep(57);
-
- /* Check if the conversion is complete */
-
- regval = stmpe811_getreg8(priv, STMPE811_ADC_CAPT);
- if ((regval & pinmask) != 0)
- {
- break;
- }
- }
-
- /* At the completion of the conversion, return whatever we read from
- * from the channel register associated with the pin.
- */
-
- return stmpe811_getreg16(priv, STMPE811_ADC_DATACH(pin));
-}
-
-#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 && !CONFIG_STMPE811_ADC_DISABLE */
-
diff --git a/nuttx/drivers/input/stmpe811_base.c b/nuttx/drivers/input/stmpe811_base.c
deleted file mode 100644
index f37c24622..000000000
--- a/nuttx/drivers/input/stmpe811_base.c
+++ /dev/null
@@ -1,546 +0,0 @@
-/****************************************************************************
- * drivers/input/stmpe811_base.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
- * GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
- *
- * 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 <nuttx/config.h>
-
-#include <unistd.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/input/stmpe811.h>
-
-#include "stmpe811.h"
-
-#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* If only a single STMPE811 device is supported, then the driver state
- * structure may as well be pre-allocated.
- */
-
-#ifndef CONFIG_STMPE811_MULTIPLE
-static struct stmpe811_dev_s g_stmpe811;
-
-/* Otherwise, we will need to maintain allocated driver instances in a list */
-
-#else
-static struct stmpe811_dev_s *g_stmpe811list;
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: stmpe811_worker
- *
- * Description:
- * This is the "bottom half" of the STMPE811 interrupt handler
- *
- ****************************************************************************/
-
-static void stmpe811_worker(FAR void *arg)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)arg;
- uint8_t regval;
-
- DEBUGASSERT(priv && priv->config);
-
- /* Get the global interrupt status */
-
- regval = stmpe811_getreg8(priv, STMPE811_INT_STA);
-
- /* Check for a touchscreen interrupt */
-
-#ifndef CONFIG_STMPE811_TSC_DISABLE
- if ((regval & (INT_TOUCH_DET|INT_FIFO_TH|INT_FIFO_OFLOW)) != 0)
- {
- /* Dispatch the touchscreen interrupt if it was brought into the link */
-
-#ifdef CONFIG_HAVE_WEAKFUNCTIONS
- if (stmpe811_tscworker)
-#endif
- {
- stmpe811_tscworker(priv, regval);
- }
-
- stmpe811_putreg8(priv, STMPE811_INT_STA, (INT_TOUCH_DET|INT_FIFO_TH|INT_FIFO_OFLOW));
- regval &= ~(INT_TOUCH_DET|INT_FIFO_TH|INT_FIFO_OFLOW);
- }
-#endif
-
-#if !defined(CONFIG_STMPE811_GPIO_DISABLE) && !defined(CONFIG_STMPE811_GPIOINT_DISABLE)
- if ((regval & INT_GPIO) != 0)
- {
- /* Dispatch the GPIO interrupt if it was brought into the link */
-
-#ifdef CONFIG_HAVE_WEAKFUNCTIONS
- if (stmpe811_gpioworker)
-#endif
- {
- stmpe811_gpioworker(priv);
- }
-
- stmpe811_putreg8(priv, STMPE811_INT_STA, INT_GPIO);
- regval &= ~INT_GPIO;
- }
-#endif
-
- /* Clear any other residual, unhandled pending interrupt */
-
- if (regval != 0)
- {
- stmpe811_putreg8(priv, STMPE811_INT_STA, regval);
- }
-
- /* Re-enable the STMPE811 GPIO interrupt */
-
- priv->config->enable(priv->config, true);
-}
-
-/****************************************************************************
- * Name: stmpe811_interrupt
- *
- * Description:
- * The STMPE811 interrupt handler
- *
- ****************************************************************************/
-
-static int stmpe811_interrupt(int irq, FAR void *context)
-{
- FAR struct stmpe811_dev_s *priv;
- FAR struct stmpe811_config_s *config;
- int ret;
-
- /* Which STMPE811 device caused the interrupt? */
-
-#ifndef CONFIG_STMPE811_MULTIPLE
- priv = &g_stmpe811;
-#else
- for (priv = g_stmpe811list;
- priv && priv->config->irq != irq;
- priv = priv->flink);
-
- ASSERT(priv != NULL);
-#endif
-
- /* Get a pointer the callbacks for convenience (and so the code is not so
- * ugly).
- */
-
- config = priv->config;
- DEBUGASSERT(config != NULL);
-
- /* Disable further interrupts */
-
- config->enable(config, false);
-
- /* Check if interrupt work is already queue. If it is already busy, then
- * we already have interrupt processing in the pipeline and we need to do
- * nothing more.
- */
-
- if (work_available(&priv->work))
- {
- /* Yes.. Transfer processing to the worker thread. Since STMPE811
- * interrupts are disabled while the work is pending, no special
- * action should be required to protect the work queue.
- */
-
- ret = work_queue(HPWORK, &priv->work, stmpe811_worker, priv, 0);
- if (ret != 0)
- {
- illdbg("Failed to queue work: %d\n", ret);
- }
- }
-
- /* Clear any pending interrupts and return success */
-
- config->clear(config);
- return OK;
-}
-
-/****************************************************************************
- * Name: stmpe811_checkid
- *
- * Description:
- * Read and verify the STMPE811 chip ID
- *
- ****************************************************************************/
-
-static int stmpe811_checkid(FAR struct stmpe811_dev_s *priv)
-{
- uint16_t devid = 0;
-
- /* Read device ID */
-
- devid = stmpe811_getreg8(priv, STMPE811_CHIP_ID);
- devid = (uint32_t)(devid << 8);
- devid |= (uint32_t)stmpe811_getreg8(priv, STMPE811_CHIP_ID+1);
- ivdbg("devid: %04x\n", devid);
-
- if (devid != (uint16_t)CHIP_ID)
- {
- /* ID is not Correct */
-
- return -ENODEV;
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: stmpe811_reset
- *
- * Description:
- * Reset the STMPE811
- *
- ****************************************************************************/
-
-static void stmpe811_reset(FAR struct stmpe811_dev_s *priv)
-{
- /* Power Down the STMPE811 */
-
- stmpe811_putreg8(priv, STMPE811_SYS_CTRL1, SYS_CTRL1_SOFTRESET);
-
- /* Wait a bit */
-
- usleep(20*1000);
-
- /* Then power on again. All registers will be in their reset state. */
-
- stmpe811_putreg8(priv, STMPE811_SYS_CTRL1, 0);
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: stmpe811_instantiate
- *
- * Description:
- * Instantiate and configure the STMPE811 device driver to use the provided
- * I2C or SPIdevice instance.
- *
- * Input Parameters:
- * dev - An I2C or SPI driver instance
- * config - Persistant board configuration data
- *
- * Returned Value:
- * A non-zero handle is returned on success. This handle may then be used
- * to configure the STMPE811 driver as necessary. A NULL handle value is
- * returned on failure.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_STMPE811_SPI
-STMPE811_HANDLE stmpe811_instantiate(FAR struct spi_dev_s *dev,
- FAR struct stmpe811_config_s *config)
-#else
-STMPE811_HANDLE stmpe811_instantiate(FAR struct i2c_dev_s *dev,
- FAR struct stmpe811_config_s *config)
-#endif
-{
- FAR struct stmpe811_dev_s *priv;
- uint8_t regval;
- int ret;
-
- /* Allocate the device state structure */
-
-#ifdef CONFIG_STMPE811_MULTIPLE
- priv = (FAR struct stmpe811_dev_s *)kzalloc(sizeof(struct stmpe811_dev_s));
- if (!priv)
- {
- return NULL;
- }
-
- /* And save the device structure in the list of STMPE811 so that we can find it later */
-
- priv->flink = g_stmpe811list;
- g_stmpe811list = priv;
-#else
-
- /* Use the one-and-only STMPE811 driver instance */
-
- priv = &g_stmpe811;
-#endif
-
- /* Initialize the device state structure */
-
- sem_init(&priv->exclsem, 0, 1);
- priv->config = config;
-
-#ifdef CONFIG_STMPE811_SPI
- priv->spi = dev;
-#else
- priv->i2c = dev;
-
- /* Set the I2C address and frequency. REVISIT: This logic would be
- * insufficient if we share the I2C bus with any other devices that also
- * modify the address and frequency.
- */
-
- I2C_SETADDRESS(dev, config->address, 7);
- I2C_SETFREQUENCY(dev, config->frequency);
-#endif
-
- /* Read and verify the STMPE811 chip ID */
-
- ret = stmpe811_checkid(priv);
- if (ret < 0)
- {
-#ifdef CONFIG_STMPE811_MULTIPLE
- kfree(priv);
-#endif
- return NULL;
- }
-
- /* Generate STMPE811 Software reset */
-
- stmpe811_reset(priv);
-
- /* Configure the interrupt output pin to generate interrupts on high or low level. */
-
- regval = stmpe811_getreg8(priv, STMPE811_INT_CTRL);
-#ifdef CONFIG_STMPE811_ACTIVELOW
- regval &= ~INT_CTRL_INT_POLARITY; /* Pin polarity: Active low / falling edge */
-#else
- regval |= INT_CTRL_INT_POLARITY; /* Pin polarity: Active high / rising edge */
-#endif
-#ifdef CONFIG_STMPE811_EDGE
- regval |= INT_CTRL_INT_TYPE; /* Edge interrupt */
-#else
- regval &= ~INT_CTRL_INT_TYPE; /* Level interrupt */
-#endif
- stmpe811_putreg8(priv, STMPE811_INT_CTRL, regval);
-
- /* Attach the STMPE811 interrupt handler. */
-
- config->attach(config, stmpe811_interrupt);
-
- /* Clear any pending interrupts */
-
- stmpe811_putreg8(priv, STMPE811_INT_STA, INT_ALL);
- config->clear(config);
- config->enable(config, true);
-
- /* Enable global interrupts */
-
- regval = stmpe811_getreg8(priv, STMPE811_INT_CTRL);
- regval |= INT_CTRL_GLOBAL_INT;
- stmpe811_putreg8(priv, STMPE811_INT_CTRL, regval);
-
- /* Return our private data structure as an opaque handle */
-
- return (STMPE811_HANDLE)priv;
-}
-
-/****************************************************************************
- * Name: stmpe811_getreg8
- *
- * Description:
- * Read from an 8-bit STMPE811 register
- *
- ****************************************************************************/
-
-#ifdef CONFIG_STMPE811_I2C
-uint8_t stmpe811_getreg8(FAR struct stmpe811_dev_s *priv, uint8_t regaddr)
-{
- /* 8-bit data read sequence:
- *
- * Start - I2C_Write_Address - STMPE811_Reg_Address -
- * Repeated_Start - I2C_Read_Address - STMPE811_Read_Data - STOP
- */
-
- struct i2c_msg_s msg[2];
- uint8_t regval;
- int ret;
-
- /* Setup 8-bit STMPE811 address write message */
-
- msg[0].addr = priv->config->address; /* 7-bit address */
- msg[0].flags = 0; /* Write transaction, beginning with START */
- msg[0].buffer = &regaddr; /* Transfer from this address */
- msg[0].length = 1; /* Send one byte following the address
- * (no STOP) */
-
- /* Set up the 8-bit STMPE811 data read message */
-
- msg[1].addr = priv->config->address; /* 7-bit address */
- msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
- msg[1].buffer = &regval; /* Transfer to this address */
- msg[1].length = 1; /* Receive one byte following the address
- * (then STOP) */
-
- /* Perform the transfer */
-
- ret = I2C_TRANSFER(priv->i2c, msg, 2);
- if (ret < 0)
- {
- idbg("I2C_TRANSFER failed: %d\n", ret);
- return 0;
- }
-
-#ifdef CONFIG_STMPE811_REGDEBUG
- dbg("%02x->%02x\n", regaddr, regval);
-#endif
- return regval;
-}
-#endif
-
-/****************************************************************************
- * Name: stmpe811_putreg8
- *
- * Description:
- * Write a value to an 8-bit STMPE811 register
- *
- ****************************************************************************/
-
-#ifdef CONFIG_STMPE811_I2C
-void stmpe811_putreg8(FAR struct stmpe811_dev_s *priv,
- uint8_t regaddr, uint8_t regval)
-{
- /* 8-bit data read sequence:
- *
- * Start - I2C_Write_Address - STMPE811_Reg_Address - STMPE811_Write_Data - STOP
- */
-
- struct i2c_msg_s msg;
- uint8_t txbuffer[2];
- int ret;
-
-#ifdef CONFIG_STMPE811_REGDEBUG
- dbg("%02x<-%02x\n", regaddr, regval);
-#endif
-
- /* Setup to the data to be transferred. Two bytes: The STMPE811 register
- * address followed by one byte of data.
- */
-
- txbuffer[0] = regaddr;
- txbuffer[1] = regval;
-
- /* Setup 8-bit STMPE811 address write message */
-
- msg.addr = priv->config->address; /* 7-bit address */
- msg.flags = 0; /* Write transaction, beginning with START */
- msg.buffer = txbuffer; /* Transfer from this address */
- msg.length = 2; /* Send two byte following the address
- * (then STOP) */
-
- /* Perform the transfer */
-
- ret = I2C_TRANSFER(priv->i2c, &msg, 1);
- if (ret < 0)
- {
- idbg("I2C_TRANSFER failed: %d\n", ret);
- }
-}
-#endif
-
-/****************************************************************************
- * Name: stmpe811_getreg16
- *
- * Description:
- * Read 16-bits of data from an STMPE-11 register
- *
- ****************************************************************************/
-
-#ifdef CONFIG_STMPE811_I2C
-uint16_t stmpe811_getreg16(FAR struct stmpe811_dev_s *priv, uint8_t regaddr)
-{
- /* 16-bit data read sequence:
- *
- * Start - I2C_Write_Address - STMPE811_Reg_Address -
- * Repeated_Start - I2C_Read_Address - STMPE811_Read_Data_1 -
- * STMPE811_Read_Data_2 - STOP
- */
-
-
- struct i2c_msg_s msg[2];
- uint8_t rxbuffer[2];
- int ret;
-
- /* Setup 8-bit STMPE811 address write message */
-
- msg[0].addr = priv->config->address; /* 7-bit address */
- msg[0].flags = 0; /* Write transaction, beginning with START */
- msg[0].buffer = &regaddr; /* Transfer from this address */
- msg[0].length = 1; /* Send one byte following the address
- * (no STOP) */
-
- /* Set up the 8-bit STMPE811 data read message */
-
- msg[1].addr = priv->config->address; /* 7-bit address */
- msg[1].flags = I2C_M_READ; /* Read transaction, beginning with Re-START */
- msg[1].buffer = rxbuffer; /* Transfer to this address */
- msg[1].length = 2; /* Receive two bytes following the address
- * (then STOP) */
-
- /* Perform the transfer */
-
- ret = I2C_TRANSFER(priv->i2c, msg, 2);
- if (ret < 0)
- {
- idbg("I2C_TRANSFER failed: %d\n", ret);
- return 0;
- }
-
-#ifdef CONFIG_STMPE811_REGDEBUG
- dbg("%02x->%02x%02x\n", regaddr, rxbuffer[0], rxbuffer[1]);
-#endif
- return (uint16_t)rxbuffer[0] << 8 | (uint16_t)rxbuffer[1];
-}
-#endif
-
-#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 */
-
diff --git a/nuttx/drivers/input/stmpe811_gpio.c b/nuttx/drivers/input/stmpe811_gpio.c
deleted file mode 100644
index b545828d1..000000000
--- a/nuttx/drivers/input/stmpe811_gpio.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/****************************************************************************
- * drivers/input/stmpe811_gpio.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
- * GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
- *
- * 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 <nuttx/config.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/input/stmpe811.h>
-
-#include "stmpe811.h"
-
-#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811) && !defined(CONFIG_STMPE811_GPIO_DISABLE)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: stmpe811_gpioinit
- *
- * Description:
- * Initialize the GPIO interrupt subsystem
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-static void stmpe811_gpioinit(FAR struct stmpe811_dev_s *priv)
-{
- uint8_t regval;
-
- if ((priv->flags & STMPE811_FLAGS_GPIO_INITIALIZED) == 0)
- {
- /* Enable Clocking for GPIO */
-
- regval = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
- regval &= ~SYS_CTRL2_GPIO_OFF;
- stmpe811_putreg8(priv, STMPE811_SYS_CTRL2, regval);
-
- /* Disable all GPIO interrupts */
-
- stmpe811_putreg8(priv, STMPE811_GPIO_EN, 0);
-
- /* Enable global GPIO interrupts */
-
-#ifndef CONFIG_STMPE811_GPIOINT_DISABLE
- regval = stmpe811_getreg8(priv, STMPE811_INT_EN);
- regval |= INT_GPIO;
- stmpe811_putreg8(priv, STMPE811_INT_EN, regval);
-#endif
-
- priv->flags |= STMPE811_FLAGS_GPIO_INITIALIZED;
- }
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: stmpe811_gpioconfig
- *
- * Description:
- * Configure an STMPE811 GPIO pin
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- * pinconfig - Bit-encoded pin configuration
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-int stmpe811_gpioconfig(STMPE811_HANDLE handle, uint8_t pinconfig)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
- int pin = (pinconfig & STMPE811_GPIO_PIN_MASK) >> STMPE811_GPIO_PIN_SHIFT;
- uint8_t pinmask = (1 << pin);
- uint8_t regval;
- int ret;
-
- DEBUGASSERT(handle && (unsigned)pin < STMPE811_GPIO_NPINS);
-
- /* Get exclusive access to the device structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- int errval = errno;
- idbg("sem_wait failed: %d\n", errval);
- return -errval;
- }
-
- /* Make sure that the pin is not already in use */
-
- if ((priv->inuse & pinmask) != 0)
- {
- idbg("PIN%d is already in-use\n", pin);
- sem_post(&priv->exclsem);
- return -EBUSY;
- }
-
- /* Make sure that the GPIO block has been initialized */
-
- stmpe811_gpioinit(priv);
-
- /* Set the alternate function bit for the pin, making it a GPIO */
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_AF);
- regval |= pinmask;
- stmpe811_putreg8(priv, STMPE811_GPIO_AF, regval);
-
- /* Is the pin an input or an output? */
-
- if ((pinconfig & STMPE811_GPIO_DIR) == STMPE811_GPIO_OUTPUT)
- {
- /* The pin is an output */
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_DIR);
- regval &= ~pinmask;
- stmpe811_putreg8(priv, STMPE811_GPIO_DIR, regval);
-
- /* Set its initial output value */
-
- stmpe811_gpiowrite(handle, pinconfig,
- (pinconfig & STMPE811_GPIO_VALUE) != STMPE811_GPIO_ZERO);
- }
- else
- {
- /* It is an input */
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_DIR);
- regval |= pinmask;
- stmpe811_putreg8(priv, STMPE811_GPIO_DIR, regval);
-
- /* Set up the falling edge detection */
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_FE);
- if ((pinconfig & STMPE811_GPIO_FALLING) != 0)
- {
- regval |= pinmask;
- }
- else
- {
- regval &= pinmask;
- }
- stmpe811_putreg8(priv, STMPE811_GPIO_FE, regval);
-
- /* Set up the rising edge detection */
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_RE);
- if ((pinconfig & STMPE811_GPIO_FALLING) != 0)
- {
- regval |= pinmask;
- }
- else
- {
- regval &= pinmask;
- }
- stmpe811_putreg8(priv, STMPE811_GPIO_RE, regval);
-
- /* Disable interrupts for now */
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_EN);
- regval &= ~pinmask;
- stmpe811_putreg8(priv, STMPE811_GPIO_EN, regval);
- }
-
- /* Mark the pin as 'in use' */
-
- priv->inuse |= pinmask;
- sem_post(&priv->exclsem);
- return OK;
-}
-
-/****************************************************************************
- * Name: stmpe811_gpiowrite
- *
- * Description:
- * Set or clear the GPIO output
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- * pinconfig - Bit-encoded pin configuration
- * value = true: write logic '1'; false: write logic '0;
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-void stmpe811_gpiowrite(STMPE811_HANDLE handle, uint8_t pinconfig, bool value)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
- int pin = (pinconfig & STMPE811_GPIO_PIN_MASK) >> STMPE811_GPIO_PIN_SHIFT;
- int ret;
-
- DEBUGASSERT(handle && (unsigned)pin < STMPE811_GPIO_NPINS);
-
- /* Get exclusive access to the device structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- idbg("sem_wait failed: %d\n", errno);
- return;
- }
-
- /* Are we setting or clearing outputs? */
-
- if (value)
- {
- /* Set the output valu(s)e by writing to the SET register */
-
- stmpe811_putreg8(priv, STMPE811_GPIO_SETPIN, (1 << pin));
- }
- else
- {
- /* Clear the output value(s) by writing to the CLR register */
-
- stmpe811_putreg8(priv, STMPE811_GPIO_CLRPIN, (1 << pin));
- }
-
- sem_post(&priv->exclsem);
-}
-
-/****************************************************************************
- * Name: stmpe811_gpioread
- *
- * Description:
- * Set or clear the GPIO output
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- * pinconfig - Bit-encoded pin configuration
- * value - The location to return the state of the GPIO pin
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-int stmpe811_gpioread(STMPE811_HANDLE handle, uint8_t pinconfig, bool *value)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
- int pin = (pinconfig & STMPE811_GPIO_PIN_MASK) >> STMPE811_GPIO_PIN_SHIFT;
- uint8_t regval;
- int ret;
-
- DEBUGASSERT(handle && (unsigned)pin < STMPE811_GPIO_NPINS);
-
- /* Get exclusive access to the device structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- int errval = errno;
- idbg("sem_wait failed: %d\n", errval);
- return -errval;
- }
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_MPSTA);
- *value = ((regval & GPIO_PIN(pin)) != 0);
- sem_post(&priv->exclsem);
- return OK;
-}
-
-/***********************************************************************************
- * Name: stmpe811_gpioattach
- *
- * Description:
- * Attach to a GPIO interrupt input pin and enable interrupts on the pin. Using
- * the value NULL for the handler address will disable interrupts from the pin and
- * detach the handler.
- *
- * NOTE: Callbacks do not occur from an interrupt handler but rather from the
- * context of the worker thread.
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- * pinconfig - Bit-encoded pin configuration
- * handler - The handler that will be called when the interrupt occurs.
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is returned
- * to indicate the nature of the failure.
- *
- ************************************************************************************/
-
-#ifndef CONFIG_STMPE811_GPIOINT_DISABLE
-int stmpe811_gpioattach(STMPE811_HANDLE handle, uint8_t pinconfig,
- stmpe811_handler_t handler)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
- int pin = (pinconfig & STMPE811_GPIO_PIN_MASK) >> STMPE811_GPIO_PIN_SHIFT;
- uint8_t regval;
- int ret;
-
- DEBUGASSERT(handle && (unsigned)pin < STMPE811_GPIO_NPINS);
-
- /* Get exclusive access to the device structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- int errval = errno;
- idbg("sem_wait failed: %d\n", errval);
- return -errval;
- }
-
- /* Make sure that the GPIO interrupt system has been gpioinitialized */
-
- stmpe811_gpioinit(priv);
-
- /* Set/clear the handler */
-
- priv->handlers[pin] = handler;
-
- /* If an handler has provided, then we are enabling interrupts */
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_EN);
- if (handler)
- {
- /* Enable interrupts for this GPIO */
-
- regval &= ~GPIO_PIN(pin);
- }
- else
- {
- /* Disable interrupts for this GPIO */
-
- regval &= ~GPIO_PIN(pin);
- }
- stmpe811_putreg8(priv, STMPE811_GPIO_EN, regval);
-
- sem_post(&priv->exclsem);
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Name: stmpe811_gpioworker
- *
- * Description:
- * Handle GPIO interrupt events (this function actually executes in the
- * context of the worker thread).
- *
- ****************************************************************************/
-
-#ifndef CONFIG_STMPE811_GPIOINT_DISABLE
-void stmpe811_gpioworker(FAR struct stmpe811_dev_s *priv)
-{
- uint8_t regval;
- uint8_t pinmask;
- int pin;
-
- /* Get the set of pending GPIO interrupts */
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_INTSTA);
-
- /* Look at each pin */
-
- for (pin = 0; pin < STMPE811_GPIO_NPINS; pin++)
- {
- pinmask = GPIO_INT(pin);
- if ((regval & pinmask) != 0)
- {
- /* Check if we have a handler for this interrupt (there should
- * be one)
- */
-
- if (priv->handlers[pin])
- {
- /* Interrupt is pending... dispatch the interrupt to the
- * callback
- */
-
- priv->handlers[pin](pin);
- }
- else
- {
- illdbg("No handler for PIN%d, GPIO_INTSTA: %02x\n", pin, regval);
- }
-
- /* Clear the pending GPIO interrupt by writing a '1' to the
- * pin position in the status register.
- */
-
- stmpe811_putreg8(priv, STMPE811_GPIO_INTSTA, pinmask);
- }
- }
-}
-#endif
-
-#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 && !CONFIG_STMPE811_GPIO_DISABLE */
-
diff --git a/nuttx/drivers/input/stmpe811_temp.c b/nuttx/drivers/input/stmpe811_temp.c
deleted file mode 100644
index 0fefd2069..000000000
--- a/nuttx/drivers/input/stmpe811_temp.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/****************************************************************************
- * drivers/input/stmpe811_temp.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
- * GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
- *
- * 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 <nuttx/config.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/input/stmpe811.h>
-
-#include "stmpe811.h"
-
-#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811) && !defined(CONFIG_STMPE811_TEMP_DISABLE)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: stmpe811_tempinitialize
- *
- * Description:
- * Configure the temperature sensor.
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-int stmpe811_tempinitialize(STMPE811_HANDLE handle)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
- uint8_t regval;
-
- /* Enable clocking for ADC and the temperature sensor */
-
- regval = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
- regval &= ~(SYS_CTRL2_TS_OFF | SYS_CTRL2_ADC_OFF);
- stmpe811_putreg8(priv, STMPE811_SYS_CTRL2, regval);
-
- /* Enable the temperature sensor */
-
- stmpe811_putreg8(priv, STMPE811_TEMP_CTRL, TEMP_CTRL_ENABLE);
-
- /* Aquire data enable */
-
- stmpe811_putreg8(priv, STMPE811_TEMP_CTRL, (TEMP_CTRL_ACQ|TEMP_CTRL_ENABLE));
-
- return OK;
-}
-
-/****************************************************************************
- * Name: stmpe811_tempread
- *
- * Description:
- * Configure the temperature sensor.
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-uint16_t stmpe811_tempread(STMPE811_HANDLE handle)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
- uint32_t temp = 0;
- uint8_t temp1;
- uint8_t temp2;
-
- /* Acquire data enable */
-
- stmpe811_putreg8(priv, STMPE811_TEMP_CTRL, (TEMP_CTRL_ACQ|TEMP_CTRL_ENABLE));
-
- /* Read the temperature */
-
- temp1 = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
- temp2 = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2+1);
-
- /* Scale the temperature (where Vio is assumed to be .33) */
-
- temp = ((uint32_t)(temp1 & 3) << 8) | temp2;
- temp = (uint32_t)((33 * temp * 100) / 751);
- temp = (uint32_t)((temp + 5) / 10);
-
- return (uint16_t)temp;
-}
-
-/****************************************************************************
- * Name: stmpe811_tempinterrupt
- *
- * Description:
- * Configure the temperature sensor to sample the temperature periodically.
- * Set the temperature threshold to generate an interrupt and notify
- * to the client using the provide callback function pointer.
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_instantiate
- * threshold - The threshold temperature value
- * direction - True: Generate an interrupt if the temperate exceeds the
- * threshold value; False: Generate an interrupt if the
- * temperature falls below the threshold value.
- * callback - The client callback function that will be called when
- * the termperature crosses the threshold.
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-/* Not implemented */
-
-#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 && !CONFIG_STMPE811_TEMP_DISABLE */
-
diff --git a/nuttx/drivers/input/stmpe811_tsc.c b/nuttx/drivers/input/stmpe811_tsc.c
deleted file mode 100644
index c7f8b473b..000000000
--- a/nuttx/drivers/input/stmpe811_tsc.c
+++ /dev/null
@@ -1,1144 +0,0 @@
-/****************************************************************************
- * drivers/input/stmpe811_tsc.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "STMPE811 S-Touch® advanced resistive touchscreen controller with 8-bit
- * GPIO expander," Doc ID 14489 Rev 6, CD00186725, STMicroelectronics"
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <semaphore.h>
-
-#include <poll.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/arch.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/i2c.h>
-#include <nuttx/wqueue.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/input/touchscreen.h>
-#include <nuttx/input/stmpe811.h>
-
-#include "stmpe811.h"
-
-#if defined(CONFIG_INPUT) && defined(CONFIG_INPUT_STMPE811) && !defined(CONFIG_STMPE811_TSC_DISABLE)
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#define Direction_IN 0x00
-#define Direction_OUT 0x01
-
-#define Polarity_Low 0x00
-#define Polarity_High 0x04
-#define Type_Level 0x00
-#define Type_Edge 0x02
-
-#define IO_IT_0 0x01
-#define IO_IT_1 0x02
-#define IO_IT_2 0x04
-#define IO_IT_3 0x08
-#define IO_IT_4 0x10
-#define IO_IT_5 0x20
-#define IO_IT_6 0x40
-#define IO_IT_7 0x80
-#define ALL_IT 0xFF
-#define IOE_JOY_IT (uint8_t)(IO_IT_3 | IO_IT_4 | IO_IT_5 | IO_IT_6 | IO_IT_7)
-#define IOE_TS_IT (uint8_t)(IO_IT_0 | IO_IT_1 | IO_IT_2)
-#define IOE_INMEMS_IT (uint8_t)(IO_IT_2 | IO_IT_3)
-
-#define EDGE_FALLING 0x01
-#define EDGE_RISING 0x02
-
-#define TIMEOUT_MAX 0x3000 /*<! The value of the maximal timeout for I2C waiting loops */
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-/* Internal logic */
-
-static void stmpe811_notify(FAR struct stmpe811_dev_s *priv);
-static int stmpe811_sample(FAR struct stmpe811_dev_s *priv,
- FAR struct stmpe811_sample_s *sample);
-static inline int stmpe811_waitsample(FAR struct stmpe811_dev_s *priv,
- FAR struct stmpe811_sample_s *sample);
-
-/* Character driver methods */
-
-static int stmpe811_open(FAR struct file *filep);
-static int stmpe811_close(FAR struct file *filep);
-static ssize_t stmpe811_read(FAR struct file *filep, FAR char *buffer,
- size_t len);
-static int stmpe811_ioctl(FAR struct file *filep, int cmd,
- unsigned long arg);
-#ifndef CONFIG_DISABLE_POLL
-static int stmpe811_poll(FAR struct file *filep, struct pollfd *fds,
- bool setup);
-#endif
-
-/* Initialization logic */
-
-static inline void stmpe811_tscinitialize(FAR struct stmpe811_dev_s *priv);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* This the the vtable that supports the character driver interface */
-
-static const struct file_operations g_stmpe811fops =
-{
- stmpe811_open, /* open */
- stmpe811_close, /* close */
- stmpe811_read, /* read */
- 0, /* write */
- 0, /* seek */
- stmpe811_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , stmpe811_poll /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-/****************************************************************************
- * Name: stmpe811_notify
- *
- * Description:
- * Notify any threads waiting on touchscreen data that data is now
- * available for reading.
- *
- ****************************************************************************/
-
-static void stmpe811_notify(FAR struct stmpe811_dev_s *priv)
-{
-#ifndef CONFIG_DISABLE_POLL
- int i;
-#endif
-
- /* If there are threads waiting for read data, then signal one of them
- * that the read data is available.
- */
-
- if (priv->nwaiters > 0)
- {
- /* After posting this semaphore, we need to exit because the STMPE811
- * is no longer available.
- */
-
- sem_post(&priv->waitsem);
- }
-
- /* If there are threads waiting on poll() for STMPE811 data to become available,
- * then wake them up now. NOTE: we wake up all waiting threads because we
- * do not know that they are going to do. If they all try to read the data,
- * then some make end up blocking after all.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- for (i = 0; i < CONFIG_STMPE811_NPOLLWAITERS; i++)
- {
- struct pollfd *fds = priv->fds[i];
- if (fds)
- {
- fds->revents |= POLLIN;
- ivdbg("Report events: %02x\n", fds->revents);
- sem_post(fds->sem);
- }
- }
-#endif
-}
-
-/****************************************************************************
- * Name: stmpe811_sample
- *
- * Description:
- * Check if touchscreen sample data is available now and, if so, return
- * the sample data. This is part of the stmpe811_read logic.
- *
- * Assumption:
- * Pre-emption is disable to prevent the worker thread from running.
- * Otherwise, sampled data may continue to change.
- *
- ****************************************************************************/
-
-static int stmpe811_sample(FAR struct stmpe811_dev_s *priv,
- FAR struct stmpe811_sample_s *sample)
-{
- int ret = -EAGAIN;
-
- /* Is there new STMPE811 sample data available? */
-
- if (priv->penchange)
- {
- /* Yes.. the state has changed in some way. Return a copy of the
- * sampled data.
- */
-
- memcpy(sample, &priv->sample, sizeof(struct stmpe811_sample_s));
-
- /* Now manage state transitions */
-
- if (sample->contact == CONTACT_UP)
- {
- /* The sampling logic has detected pen-up in some condition other
- * than CONTACT_NONE. Set the next state to CONTACT_NONE: Further
- * pen-down reports will be ignored. Increment the ID so that
- * next contact ID will be unique
- */
-
- priv->sample.contact = CONTACT_NONE;
- priv->sample.valid = false;
- priv->id++;
- }
- else if (sample->contact == CONTACT_DOWN)
- {
- /* The sampling logic has detected pen-up in some condition other
- * than CONTACT_MOVE. Set the next state to CONTACT_MOVE: Further
- * samples collected while the pen is down will reported as movement
- * events.
- */
-
- priv->sample.contact = CONTACT_MOVE;
- }
-
- priv->penchange = false;
- ret = OK;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: stmpe811_waitsample
- *
- * Description:
- * Wait for a sample to become available (this is really part of the
- * stmpe811_read logic).
- *
- ****************************************************************************/
-
-static inline int stmpe811_waitsample(FAR struct stmpe811_dev_s *priv,
- FAR struct stmpe811_sample_s *sample)
-{
- int ret;
-
- /* Disable pre-emption to prevent the worker thread from running
- * asynchronously.
- */
-
- sched_lock();
-
- /* Now release the semaphore that manages mutually exclusive access to
- * the device structure. This may cause other tasks to become ready to
- * run, but they cannot run yet because pre-emption is disabled.
- */
-
- sem_post(&priv->exclsem);
-
- /* Try to get the a sample... if we cannot, then wait on the semaphore
- * that is posted when new sample data is availble.
- */
-
- while (stmpe811_sample(priv, sample) < 0)
- {
- /* Wait for a change in the STMPE811 state */
-
- priv->nwaiters++;
- ret = sem_wait(&priv->waitsem);
- priv->nwaiters--;
-
- /* When we are re-awakened, pre-emption will again be disabled */
-
- if (ret < 0)
- {
-#ifdef CONFIG_DEBUG
- // Sample the errno (debug output could change it)
-
- int errval = errno;
-
- /* If we are awakened by a signal, then we need to return
- * the failure now.
- */
-
- idbg("ERROR: sem_wait failed: %d\n", errval);
- DEBUGASSERT(errval == EINTR);
-#endif
- ret = -EINTR;
- goto errout;
- }
- }
-
- /* Re-acquire the the semaphore that manages mutually exclusive access to
- * the device structure. We may have to wait here. But we have our sample.
- * Interrupts and pre-emption will be re-enabled while we wait.
- */
-
- ret = sem_wait(&priv->exclsem);
-
-errout:
- /* Restore pre-emption. We might get suspended here but that is okay
- * because we already have our sample. Note: this means that if there
- * were two threads reading from the STMPE811 for some reason, the data
- * might be read out of order.
- */
-
- sched_unlock();
- return ret;
-}
-
-/****************************************************************************
- * Name: stmpe811_open
- *
- * Description:
- * Standard character driver open method.
- *
- ****************************************************************************/
-
-static int stmpe811_open(FAR struct file *filep)
-{
-#ifdef CONFIG_STMPE811_REFCNT
- FAR struct inode *inode;
- FAR struct stmpe811_dev_s *priv;
- uint8_t tmp;
- int ret;
-
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct stmpe811_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Increment the reference count */
-
- tmp = priv->crefs + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- goto errout_with_sem;
- }
-
- /* When the reference increments to 1, this is the first open event
- * on the driver.. and an opportunity to do any one-time initialization.
- */
-
- /* Save the new open count on success */
-
- priv->crefs = tmp;
-
-errout_with_sem:
- sem_post(&priv->exclsem);
- return ret;
-#else
- return OK;
-#endif
-}
-
-/****************************************************************************
- * Name: stmpe811_close
- *
- * Description:
- * Standard character driver close method.
- *
- ****************************************************************************/
-
-static int stmpe811_close(FAR struct file *filep)
-{
-#ifdef CONFIG_STMPE811_REFCNT
- FAR struct inode *inode;
- FAR struct stmpe811_dev_s *priv;
- int ret;
-
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct stmpe811_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Decrement the reference count unless it would decrement a negative
- * value. When the count decrements to zero, there are no further
- * open references to the driver.
- */
-
- if (priv->crefs >= 1)
- {
- priv->crefs--;
- }
-
- sem_post(&priv->exclsem);
-#endif
- return OK;
-}
-
-/****************************************************************************
- * Name: stmpe811_read
- *
- * Description:
- * Standard character driver read method.
- *
- ****************************************************************************/
-
-static ssize_t stmpe811_read(FAR struct file *filep, FAR char *buffer, size_t len)
-{
- FAR struct inode *inode;
- FAR struct stmpe811_dev_s *priv;
- FAR struct touch_sample_s *report;
- struct stmpe811_sample_s sample;
- int ret;
-
- ivdbg("len=%d\n", len);
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct stmpe811_dev_s *)inode->i_private;
-
- /* Verify that the caller has provided a buffer large enough to receive
- * the touch data.
- */
-
- if (len < SIZEOF_TOUCH_SAMPLE_S(1))
- {
- /* We could provide logic to break up a touch report into segments and
- * handle smaller reads... but why?
- */
-
- return -ENOSYS;
- }
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Try to read sample data. */
-
- ret = stmpe811_sample(priv, &sample);
- if (ret < 0)
- {
- /* Sample data is not available now. We would ave to wait to get
- * receive sample data. If the user has specified the O_NONBLOCK
- * option, then just return an error.
- */
-
- if (filep->f_oflags & O_NONBLOCK)
- {
- ret = -EAGAIN;
- goto errout;
- }
-
- /* Wait for sample data */
-
- ret = stmpe811_waitsample(priv, &sample);
- if (ret < 0)
- {
- /* We might have been awakened by a signal */
-
- goto errout;
- }
- }
-
- /* In any event, we now have sampled STMPE811 data that we can report
- * to the caller.
- */
-
- report = (FAR struct touch_sample_s *)buffer;
- memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1));
- report->npoints = 1;
- report->point[0].id = sample.id;
- report->point[0].x = sample.x;
- report->point[0].y = sample.y;
- report->point[0].pressure = sample.z;
-
- /* Report the appropriate flags */
-
- if (sample.contact == CONTACT_UP)
- {
- /* Pen is now up. Is the positional data valid? This is important to
- * know because the release will be sent to the window based on its
- * last positional data.
- */
-
- if (sample.valid)
- {
- report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID |
- TOUCH_POS_VALID | TOUCH_PRESSURE_VALID;
- }
- else
- {
- report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID;
- }
- }
- else if (sample.contact == CONTACT_DOWN)
- {
- /* First contact */
-
- report->point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID |
- TOUCH_POS_VALID | TOUCH_PRESSURE_VALID;
- }
- else /* if (sample->contact == CONTACT_MOVE) */
- {
- /* Movement of the same contact */
-
- report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID |
- TOUCH_POS_VALID | TOUCH_PRESSURE_VALID;
- }
-
- ret = SIZEOF_TOUCH_SAMPLE_S(1);
-
-errout:
- sem_post(&priv->exclsem);
- return ret;
-}
-
-/****************************************************************************
- * Name: stmpe811_ioctl
- *
- * Description:
- * Standard character driver ioctl method.
- *
-****************************************************************************/
-
-static int stmpe811_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode;
- FAR struct stmpe811_dev_s *priv;
- int ret;
-
- ivdbg("cmd: %d arg: %ld\n", cmd, arg);
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct stmpe811_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Process the IOCTL by command */
-
- switch (cmd)
- {
- case TSIOC_SETFREQUENCY: /* arg: Pointer to uint32_t frequency value */
- {
- FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
- DEBUGASSERT(priv->config != NULL && ptr != NULL);
- priv->config->frequency = I2C_SETFREQUENCY(priv->i2c, *ptr);
- }
- break;
-
- case TSIOC_GETFREQUENCY: /* arg: Pointer to uint32_t frequency value */
- {
- FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
- DEBUGASSERT(priv->config != NULL && ptr != NULL);
- *ptr = priv->config->frequency;
- }
- break;
-
- default:
- ret = -ENOTTY;
- break;
- }
-
- sem_post(&priv->exclsem);
- return ret;
-}
-
-/****************************************************************************
- * Name: stmpe811_poll
- *
- * Description:
- * Standard character driver poll method.
- *
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static int stmpe811_poll(FAR struct file *filep, FAR struct pollfd *fds,
- bool setup)
-{
- FAR struct inode *inode;
- FAR struct stmpe811_dev_s *priv;
- int ret;
- int i;
-
- ivdbg("setup: %d\n", (int)setup);
- DEBUGASSERT(filep && fds);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct stmpe811_dev_s *)inode->i_private;
-
- /* Are we setting up the poll? Or tearing it down? */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- if (setup)
- {
- /* Ignore waits that do not include POLLIN */
-
- if ((fds->events & POLLIN) == 0)
- {
- idbg("ERROR: Missing POLLIN: revents: %08x\n", fds->revents);
- ret = -EDEADLK;
- goto errout;
- }
-
- /* This is a request to set up the poll. Find an available
- * slot for the poll structure reference
- */
-
- for (i = 0; i < CONFIG_STMPE811_NPOLLWAITERS; i++)
- {
- /* Find an available slot */
-
- if (!priv->fds[i])
- {
- /* Bind the poll structure and this slot */
-
- priv->fds[i] = fds;
- fds->priv = &priv->fds[i];
- break;
- }
- }
-
- if (i >= CONFIG_STMPE811_NPOLLWAITERS)
- {
- idbg("ERROR: No availabled slot found: %d\n", i);
- fds->priv = NULL;
- ret = -EBUSY;
- goto errout;
- }
-
- /* Should we immediately notify on any of the requested events? */
-
- if (priv->penchange)
- {
- stmpe811_notify(priv);
- }
- }
- else if (fds->priv)
- {
- /* This is a request to tear down the poll. */
-
- struct pollfd **slot = (struct pollfd **)fds->priv;
- DEBUGASSERT(slot != NULL);
-
- /* Remove all memory of the poll setup */
-
- *slot = NULL;
- fds->priv = NULL;
- }
-
-errout:
- sem_post(&priv->exclsem);
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Name: stmpe811_timeoutworker
- *
- * Description:
- * A timer has expired without receiving a pen up event. Check again.
- *
- ****************************************************************************/
-
-static void stmpe811_timeoutworker(FAR void *arg)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)arg;
-
- DEBUGASSERT(priv);
-
- /* Treat the timeout just like an interrupt occurred */
-
- stmpe811_tscworker(priv, stmpe811_getreg8(priv, STMPE811_INT_STA));
-}
-
-/****************************************************************************
- * Name: stmpe811_timeout
- *
- * Description:
- * A timer has expired without receiving a pen up event. Schedule work
- * to check again.
- *
- ****************************************************************************/
-
-static void stmpe811_timeout(int argc, uint32_t arg1, ...)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)((uintptr_t)arg1);
- int ret;
-
- /* Are we still stuck in the pen down state? */
-
- if (priv->sample.contact == CONTACT_MOVE ||
- priv->sample.contact == CONTACT_MOVE)
- {
- /* Yes... is the worker thread available? If not, then apparently
- * we have work already pending?
- */
-
- if (work_available(&priv->timeout))
- {
- /* Yes.. Transfer processing to the worker thread. Since STMPE811
- * interrupts are disabled while the work is pending, no special
- * action should be required to protect the work queue.
- */
-
- ret = work_queue(HPWORK, &priv->timeout, stmpe811_timeoutworker, priv, 0);
- if (ret != 0)
- {
- illdbg("Failed to queue work: %d\n", ret);
- }
- }
- }
-}
-
-/****************************************************************************
- * Name: stmpe811_tscinitialize
- *
- * Description:
- * Initialize the touchscreen controller. This is really a part of the
- * stmpe811_register logic,
- *
- ****************************************************************************/
-
-static inline void stmpe811_tscinitialize(FAR struct stmpe811_dev_s *priv)
-{
- uint8_t regval;
-
- ivdbg("Initializing touchscreen controller\n");
-
- /* Enable TSC and ADC functions */
-
- regval = stmpe811_getreg8(priv, STMPE811_SYS_CTRL2);
- regval &= ~(SYS_CTRL2_TSC_OFF | SYS_CTRL2_ADC_OFF);
- stmpe811_putreg8(priv, STMPE811_SYS_CTRL2, regval);
-
- /* Enable the TSC global interrupts */
-
- regval = stmpe811_getreg8(priv, STMPE811_INT_EN);
- regval |= (uint32_t)(INT_TOUCH_DET | INT_FIFO_TH | INT_FIFO_OFLOW);
- stmpe811_putreg8(priv, STMPE811_INT_EN, regval);
-
- /* Select Sample Time, bit number and ADC Reference */
-
- stmpe811_putreg8(priv, STMPE811_ADC_CTRL1, priv->config->ctrl1);
-
- /* Wait for 20 ms */
-
- up_mdelay(20);
-
- /* Select the ADC clock speed */
-
- stmpe811_putreg8(priv, STMPE811_ADC_CTRL2, priv->config->ctrl2);
-
- /* Select TSC pins in non-GPIO mode (AF=0) */
-
- regval = stmpe811_getreg8(priv, STMPE811_GPIO_AF);
- regval &= ~(uint8_t)TSC_PIN_SET;
- stmpe811_putreg8(priv, STMPE811_GPIO_AF, regval);
-
- /* Select 2 nF filter capacitor */
-
- stmpe811_putreg8(priv, STMPE811_TSC_CFG,
- (TSC_CFG_AVE_CTRL_4SAMPLES | TSC_CFG_TOUCH_DELAY_500US | TSC_CFG_SETTLING_500US));
-
- /* Select single point reading */
-
- stmpe811_putreg8(priv, STMPE811_FIFO_TH, 1);
-
- /* Reset and clear the FIFO. */
-
- stmpe811_putreg8(priv, STMPE811_FIFO_STA, FIFO_STA_FIFO_RESET);
- stmpe811_putreg8(priv, STMPE811_FIFO_STA, 0);
-
- /* set the data format for Z value: 7 fractional part and 1 whole part */
-
- stmpe811_putreg8(priv, STMPE811_TSC_FRACTIONZ, 0x01);
-
- /* Set the driving capability of the device for TSC pins: 50mA */
-
- stmpe811_putreg8(priv, STMPE811_TSC_IDRIVE, TSC_IDRIVE_50MA);
-
- /* Enable the TSC. Use no tracking index, touch-screen controller
- * operation mode (XYZ).
- */
-
- stmpe811_putreg8(priv, STMPE811_TSC_CTRL, TSC_CTRL_EN);
-
- /* Clear all the status pending bits */
-
- stmpe811_putreg8(priv, STMPE811_INT_STA, INT_ALL);
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: stmpe811_register
- *
- * Description:
- * Enable TSC functionality. GPIO4-7 must be available. This function
- * will register the touchsceen driver as /dev/inputN where N is the minor
- * device number
- *
- * Input Parameters:
- * handle - The handle previously returned by stmpe811_register
- * minor - The input device minor number
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-int stmpe811_register(STMPE811_HANDLE handle, int minor)
-{
- FAR struct stmpe811_dev_s *priv = (FAR struct stmpe811_dev_s *)handle;
- char devname[DEV_NAMELEN];
- int ret;
-
- ivdbg("handle=%p minor=%d\n", handle, minor);
- DEBUGASSERT(priv);
-
- /* Get exclusive access to the device structure */
-
- ret = sem_wait(&priv->exclsem);
- if (ret < 0)
- {
- int errval = errno;
- idbg("ERROR: sem_wait failed: %d\n", errval);
- return -errval;
- }
-
- /* Make sure that the pins (4-7) need by the TSC are not already in use */
-
- if ((priv->inuse & TSC_PIN_SET) != 0)
- {
- idbg("ERROR: TSC pins is already in-use: %02x\n", priv->inuse);
- sem_post(&priv->exclsem);
- return -EBUSY;
- }
-
- /* Initialize the TS structure fields to their default values */
-
- priv->minor = minor;
- priv->penchange = false;
- priv->threshx = 0;
- priv->threshy = 0;
-
- /* Create a timer for catching missed pen up conditions */
-
- priv->wdog = wd_create();
- if (!priv->wdog)
- {
- idbg("ERROR: Failed to create a watchdog\n", errno);
- sem_post(&priv->exclsem);
- return -ENOSPC;
- }
-
- /* Register the character driver */
-
- snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor);
- ret = register_driver(devname, &g_stmpe811fops, 0666, priv);
- if (ret < 0)
- {
- idbg("ERROR: Failed to register driver %s: %d\n", devname, ret);
- sem_post(&priv->exclsem);
- return ret;
- }
-
- /* Initialize the touchscreen controller */
-
- stmpe811_tscinitialize(priv);
-
- /* Inidicate that the touchscreen controller was successfully initialized */
-
- priv->inuse |= TSC_PIN_SET; /* Pins 4-7 are now in-use */
- priv->flags |= STMPE811_FLAGS_TSC_INITIALIZED; /* TSC function is initialized */
- sem_post(&priv->exclsem);
- return ret;
-}
-
-/****************************************************************************
- * Name: stmpe811_tscworker
- *
- * Description:
- * This function is called to handle a TSC interrupt. It is not really
- * an interrupt handle because it is called from the STMPE811 "bottom half"
- * logic that runs on the worker thread.
- *
- ****************************************************************************/
-
-void stmpe811_tscworker(FAR struct stmpe811_dev_s *priv, uint8_t intsta)
-{
- FAR struct stmpe811_config_s *config; /* Convenience pointer */
- bool pendown; /* true: pend is down */
- uint16_t xdiff; /* X difference used in thresholding */
- uint16_t ydiff; /* Y difference used in thresholding */
- uint16_t x; /* X position */
- uint16_t y; /* Y position */
-
- ASSERT(priv != NULL);
-
- /* Cancel the missing pen up timer */
-
- (void)wd_cancel(priv->wdog);
-
- /* Get a pointer the callbacks for convenience (and so the code is not so
- * ugly).
- */
-
- config = priv->config;
- DEBUGASSERT(config != NULL);
-
- /* Check for pen up or down from the TSC_STA ibit n the STMPE811_TSC_CTRL register. */
-
- pendown = (stmpe811_getreg8(priv, STMPE811_TSC_CTRL) & TSC_CTRL_TSC_STA) != 0;
-
- /* Handle the change from pen down to pen up */
-
- if (!pendown)
- {
- /* The pen is up.. reset thresholding variables. FIFOs will read zero if
- * there is no data available (hence the choice of (0,0))
- */
-
- priv->threshx = 0;
- priv->threshy = 0;
-
- /* Ignore the interrupt if the pen was already up (CONTACT_NONE == pen up and
- * already reported; CONTACT_UP == pen up, but not reported)
- */
-
- if (priv->sample.contact == CONTACT_NONE ||
- priv->sample.contact == CONTACT_UP)
- {
- goto ignored;
- }
-
- /* A pen-down to up transition has been detected. CONTACT_UP indicates the
- * initial loss of contzt. The state will be changed to CONTACT_NONE
- * after the loss of contact is sampled.
- */
-
- priv->sample.contact = CONTACT_UP;
- }
-
- /* The pen is down... check for data in the FIFO */
-
- else if ((intsta & (INT_FIFO_TH|INT_FIFO_OFLOW)) != 0)
- {
- /* Read the next x and y positions from the FIFO. */
-
-#ifdef CONFIG_STMPE811_SWAPXY
- x = stmpe811_getreg16(priv, STMPE811_TSC_DATAX);
- y = stmpe811_getreg16(priv, STMPE811_TSC_DATAY);
-#else
- x = stmpe811_getreg16(priv, STMPE811_TSC_DATAY);
- y = stmpe811_getreg16(priv, STMPE811_TSC_DATAX);
-#endif
-
- /* If we have not yet processed the last pen up event, then we
- * cannot handle this pen down event. We will have to discard it. That
- * should be okay because there will be another FIFO event right behind
- * this one. Other kinds of data overruns are not harmful.
- *
- * Hmm.. a better design might be to disable FIFO interrupts when we
- * detect pen up. Then re-enable them when CONTACT_UP is reported.
- * That would save processing interrupts just to discard the data.
- */
-
- if (priv->sample.contact == CONTACT_UP)
- {
- /* We have not closed the loop on the last touch ... don't report
- * anything.
- */
-
- goto ignored;
- }
-
- /* Perform a thresholding operation so that the results will be more stable.
- * If the difference from the last sample is small, then ignore the event.
- * REVISIT: Should a large change in pressure also generate a event?
- */
-
- xdiff = x > priv->threshx ? (x - priv->threshx) : (priv->threshx - x);
- ydiff = y > priv->threshy ? (y - priv->threshy) : (priv->threshy - y);
-
- if (xdiff < CONFIG_STMPE811_THRESHX && ydiff < CONFIG_STMPE811_THRESHY)
- {
- /* Little or no change in either direction ... don't report anything. */
-
- goto ignored;
- }
-
- /* When we see a big difference, snap to the new x/y thresholds */
-
- priv->threshx = x;
- priv->threshy = y;
-
- /* Update the x/y position in the sample data */
-
- priv->sample.x = priv->threshx;
- priv->sample.y = priv->threshy;
-
- /* Update the Z pressure index */
-
- priv->sample.z = stmpe811_getreg8(priv, STMPE811_TSC_DATAZ);
- priv->sample.valid = true;
-
- /* If this is the first (acknowledged) pen down report, then report
- * this as the first contact. If contact == CONTACT_DOWN, it will be
- * set to set to CONTACT_MOVE after the contact is first sampled.
- */
-
- if (priv->sample.contact != CONTACT_MOVE)
- {
- /* First contact */
-
- priv->sample.contact = CONTACT_DOWN;
- }
- }
-
- /* Pen down, but no data in FIFO */
-
- else
- {
- /* Ignore the interrupt... wait until there is data in the FIFO */
-
- goto ignored;
- }
-
- /* We get here if (1) we just went from a pen down to a pen up state OR (2)
- * We just get a measurement from the FIFO in a pen down state. Indicate
- * the availability of new sample data for this ID.
- */
-
- priv->sample.id = priv->id;
- priv->penchange = true;
-
- /* Notify any waiters that new STMPE811 data is available */
-
- stmpe811_notify(priv);
-
- /* If we think that the pend is still down, the start/re-start the pen up
- * timer.
- */
-
-ignored:
- if (priv->sample.contact == CONTACT_MOVE ||
- priv->sample.contact == CONTACT_MOVE)
- {
- (void)wd_start(priv->wdog, STMPE811_PENUP_TICKS, stmpe811_timeout,
- 1, (uint32_t)((uintptr_t)priv));
- }
-
- /* Reset and clear all data in the FIFO */
-
- stmpe811_putreg8(priv, STMPE811_FIFO_STA, FIFO_STA_FIFO_RESET);
- stmpe811_putreg8(priv, STMPE811_FIFO_STA, 0);
-}
-
-#endif /* CONFIG_INPUT && CONFIG_INPUT_STMPE811 && !CONFIG_STMPE811_TSC_DISABLE */
-
diff --git a/nuttx/drivers/input/tsc2007.c b/nuttx/drivers/input/tsc2007.c
deleted file mode 100644
index 163118b95..000000000
--- a/nuttx/drivers/input/tsc2007.c
+++ /dev/null
@@ -1,1336 +0,0 @@
-/****************************************************************************
- * drivers/input/tsc2007.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "1.2V to 3.6V, 12-Bit, Nanopower, 4-Wire Micro TOUCH SCREEN CONTROLLER
- * with I2C Interface," SBAS405A March 2007, Revised, March 2009, Texas
- * Instruments Incorporated
- *
- * 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.
- *
- ****************************************************************************/
-
-/* The TSC2007 is an analog interface circuit for a human interface touch
- * screen device. All peripheral functions are controlled through the command
- * byte and onboard state machines.
- */
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <semaphore.h>
-#include <poll.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/arch.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/i2c.h>
-#include <nuttx/wqueue.h>
-
-#include <nuttx/input/touchscreen.h>
-#include <nuttx/input/tsc2007.h>
-
-#include "tsc2007.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Configuration ************************************************************/
-/* Reference counting is partially implemented, but not needed in the
- * current design.
- */
-
-#undef CONFIG_TSC2007_REFCNT
-
-/* I don't think that it is necessary to activate the converters before
- * making meaurements. However, I will keep this functionality enabled
- * until I have a change to prove that that activation is unnecessary.
- */
-
-#undef CONFIG_TSC2007_ACTIVATE
-#define CONFIG_TSC2007_ACTIVATE 1
-
-/* Driver support ***********************************************************/
-/* This format is used to construct the /dev/input[n] device driver path. It
- * defined here so that it will be used consistently in all places.
- */
-
-#define DEV_FORMAT "/dev/input%d"
-#define DEV_NAMELEN 16
-
-/* Commands *****************************************************************/
-
-#define TSC2007_SETUP (TSC2007_CMD_FUNC_SETUP)
-#ifdef CONFIG_TSC2007_8BIT
-# define TSC2007_ACTIVATE_Y (TSC2007_CMD_8BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_YON)
-# define TSC2007_MEASURE_Y (TSC2007_CMD_8BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_YPOS)
-# define TSC2007_ACTIVATE_X (TSC2007_CMD_8BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_XON)
-# define TSC2007_MEASURE_X (TSC2007_CMD_8BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_XPOS)
-# define TSC2007_ACTIVATE_Z (TSC2007_CMD_8BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_YXON)
-# define TSC2007_MEASURE_Z1 (TSC2007_CMD_8BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_Z1POS)
-# define TSC2007_MEASURE_Z2 (TSC2007_CMD_8BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_Z2POS)
-# define TSC2007_ENABLE_PENIRQ (TSC2007_CMD_8BIT | TSC2007_CMD_PWRDN_IRQEN)
-#else
-# define TSC2007_ACTIVATE_Y (TSC2007_CMD_12BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_YON)
-# define TSC2007_MEASURE_Y (TSC2007_CMD_12BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_YPOS)
-# define TSC2007_ACTIVATE_X (TSC2007_CMD_12BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_XON)
-# define TSC2007_MEASURE_X (TSC2007_CMD_12BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_XPOS)
-# define TSC2007_ACTIVATE_Z (TSC2007_CMD_12BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_YXON)
-# define TSC2007_MEASURE_Z1 (TSC2007_CMD_12BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_Z1POS)
-# define TSC2007_MEASURE_Z2 (TSC2007_CMD_12BIT | TSC2007_CMD_ADCON_IRQDIS | TSC2007_CMD_FUNC_Z2POS)
-# define TSC2007_ENABLE_PENIRQ (TSC2007_CMD_12BIT | TSC2007_CMD_PWRDN_IRQEN)
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This describes the state of one contact */
-
-enum tsc2007_contact_3
-{
- CONTACT_NONE = 0, /* No contact */
- CONTACT_DOWN, /* First contact */
- CONTACT_MOVE, /* Same contact, possibly different position */
- CONTACT_UP, /* Contact lost */
-};
-
-/* This structure describes the results of one TSC2007 sample */
-
-struct tsc2007_sample_s
-{
- uint8_t id; /* Sampled touch point ID */
- uint8_t contact; /* Contact state (see enum tsc2007_contact_e) */
- bool valid; /* True: x,y,pressure contain valid, sampled data */
- uint16_t x; /* Measured X position */
- uint16_t y; /* Measured Y position */
- uint16_t pressure; /* Calculated pressure */
-};
-
-/* This structure describes the state of one TSC2007 driver instance */
-
-struct tsc2007_dev_s
-{
-#ifdef CONFIG_TSC2007_MULTIPLE
- FAR struct tsc2007_dev_s *flink; /* Supports a singly linked list of drivers */
-#endif
-#ifdef CONFIG_TSC2007_REFCNT
- uint8_t crefs; /* Number of times the device has been opened */
-#endif
- uint8_t nwaiters; /* Number of threads waiting for TSC2007 data */
- uint8_t id; /* Current touch point ID */
- volatile bool penchange; /* An unreported event is buffered */
- sem_t devsem; /* Manages exclusive access to this structure */
- sem_t waitsem; /* Used to wait for the availability of data */
-
- FAR struct tsc2007_config_s *config; /* Board configuration data */
- FAR struct i2c_dev_s *i2c; /* Saved I2C driver instance */
- struct work_s work; /* Supports the interrupt handling "bottom half" */
- struct tsc2007_sample_s sample; /* Last sampled touch point data */
-
- /* The following is a list if poll structures of threads waiting for
- * driver events. The 'struct pollfd' reference for each open is also
- * retained in the f_priv field of the 'struct file'.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- struct pollfd *fds[CONFIG_TSC2007_NPOLLWAITERS];
-#endif
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static void tsc2007_notify(FAR struct tsc2007_dev_s *priv);
-static int tsc2007_sample(FAR struct tsc2007_dev_s *priv,
- FAR struct tsc2007_sample_s *sample);
-static int tsc2007_waitsample(FAR struct tsc2007_dev_s *priv,
- FAR struct tsc2007_sample_s *sample);
-#ifdef CONFIG_TSC2007_ACTIVATE
-static int tsc2007_activate(FAR struct tsc2007_dev_s *priv, uint8_t cmd);
-#endif
-static int tsc2007_transfer(FAR struct tsc2007_dev_s *priv, uint8_t cmd);
-static void tsc2007_worker(FAR void *arg);
-static int tsc2007_interrupt(int irq, FAR void *context);
-
-/* Character driver methods */
-
-static int tsc2007_open(FAR struct file *filep);
-static int tsc2007_close(FAR struct file *filep);
-static ssize_t tsc2007_read(FAR struct file *filep, FAR char *buffer, size_t len);
-static int tsc2007_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-#ifndef CONFIG_DISABLE_POLL
-static int tsc2007_poll(FAR struct file *filep, struct pollfd *fds, bool setup);
-#endif
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* This the the vtable that supports the character driver interface */
-
-static const struct file_operations tsc2007_fops =
-{
- tsc2007_open, /* open */
- tsc2007_close, /* close */
- tsc2007_read, /* read */
- 0, /* write */
- 0, /* seek */
- tsc2007_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , tsc2007_poll /* poll */
-#endif
-};
-
-/* If only a single TSC2007 device is supported, then the driver state
- * structure may as well be pre-allocated.
- */
-
-#ifndef CONFIG_TSC2007_MULTIPLE
-static struct tsc2007_dev_s g_tsc2007;
-
-/* Otherwise, we will need to maintain allocated driver instances in a list */
-
-#else
-static struct tsc2007_dev_s *g_tsc2007list;
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: tsc2007_notify
- ****************************************************************************/
-
-static void tsc2007_notify(FAR struct tsc2007_dev_s *priv)
-{
-#ifndef CONFIG_DISABLE_POLL
- int i;
-#endif
-
- /* If there are threads waiting for read data, then signal one of them
- * that the read data is available.
- */
-
- if (priv->nwaiters > 0)
- {
- /* After posting this semaphore, we need to exit because the TSC2007
- * is no longer available.
- */
-
- sem_post(&priv->waitsem);
- }
-
- /* If there are threads waiting on poll() for TSC2007 data to become available,
- * then wake them up now. NOTE: we wake up all waiting threads because we
- * do not know that they are going to do. If they all try to read the data,
- * then some make end up blocking after all.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- for (i = 0; i < CONFIG_TSC2007_NPOLLWAITERS; i++)
- {
- struct pollfd *fds = priv->fds[i];
- if (fds)
- {
- fds->revents |= POLLIN;
- ivdbg("Report events: %02x\n", fds->revents);
- sem_post(fds->sem);
- }
- }
-#endif
-}
-
-/****************************************************************************
- * Name: tsc2007_sample
- ****************************************************************************/
-
-static int tsc2007_sample(FAR struct tsc2007_dev_s *priv,
- FAR struct tsc2007_sample_s *sample)
-{
- irqstate_t flags;
- int ret = -EAGAIN;
-
- /* Interrupts me be disabled when this is called to (1) prevent posting
- * of semphores from interrupt handlers, and (2) to prevent sampled data
- * from changing until it has been reported.
- */
-
- flags = irqsave();
-
- /* Is there new TSC2007 sample data available? */
-
- if (priv->penchange)
- {
- /* Yes.. the state has changed in some way. Return a copy of the
- * sampled data.
- */
-
- memcpy(sample, &priv->sample, sizeof(struct tsc2007_sample_s ));
-
- /* Now manage state transitions */
-
- if (sample->contact == CONTACT_UP)
- {
- /* Next.. no contact. Increment the ID so that next contact ID
- * will be unique. X/Y positions are no longer valid.
- */
-
- priv->sample.contact = CONTACT_NONE;
- priv->sample.valid = false;
- priv->id++;
- }
- else if (sample->contact == CONTACT_DOWN)
- {
- /* First report -- next report will be a movement */
-
- priv->sample.contact = CONTACT_MOVE;
- }
-
- priv->penchange = false;
- ret = OK;
- }
-
- irqrestore(flags);
- return ret;
-}
-
-/****************************************************************************
- * Name: tsc2007_waitsample
- ****************************************************************************/
-
-static int tsc2007_waitsample(FAR struct tsc2007_dev_s *priv,
- FAR struct tsc2007_sample_s *sample)
-{
- irqstate_t flags;
- int ret;
-
- /* Interrupts me be disabled when this is called to (1) prevent posting
- * of semphores from interrupt handlers, and (2) to prevent sampled data
- * from changing until it has been reported.
- *
- * In addition, we will also disable pre-emption to prevent other threads
- * from getting control while we muck with the semaphores.
- */
-
- sched_lock();
- flags = irqsave();
-
- /* Now release the semaphore that manages mutually exclusive access to
- * the device structure. This may cause other tasks to become ready to
- * run, but they cannot run yet because pre-emption is disabled.
- */
-
- sem_post(&priv->devsem);
-
- /* Try to get the a sample... if we cannot, then wait on the semaphore
- * that is posted when new sample data is availble.
- */
-
- while (tsc2007_sample(priv, sample) < 0)
- {
- /* Wait for a change in the TSC2007 state */
-
- priv->nwaiters++;
- ret = sem_wait(&priv->waitsem);
- priv->nwaiters--;
-
- if (ret < 0)
- {
- /* If we are awakened by a signal, then we need to return
- * the failure now.
- */
-
- DEBUGASSERT(errno == EINTR);
- ret = -EINTR;
- goto errout;
- }
- }
-
- /* Re-acquire the the semaphore that manages mutually exclusive access to
- * the device structure. We may have to wait here. But we have our sample.
- * Interrupts and pre-emption will be re-enabled while we wait.
- */
-
- ret = sem_wait(&priv->devsem);
-
-errout:
- /* Then re-enable interrupts. We might get interrupt here and there
- * could be a new sample. But no new threads will run because we still
- * have pre-emption disabled.
- */
-
- irqrestore(flags);
-
- /* Restore pre-emption. We might get suspended here but that is okay
- * because we already have our sample. Note: this means that if there
- * were two threads reading from the TSC2007 for some reason, the data
- * might be read out of order.
- */
-
- sched_unlock();
- return ret;
-}
-
-/****************************************************************************
- * Name: tsc2007_activate
- ****************************************************************************/
-
-#ifdef CONFIG_TSC2007_ACTIVATE
-static int tsc2007_activate(FAR struct tsc2007_dev_s *priv, uint8_t cmd)
-{
- struct i2c_msg_s msg;
- uint8_t data;
- int ret;
-
- /* Send the setup command (with no ACK) followed by the A/D converter
- * activation command (ACKed).
- */
-
- data = TSC2007_SETUP;
-
- msg.addr = priv->config->address; /* 7-bit address */
- msg.flags = 0; /* Write transaction, beginning with START */
- msg.buffer = &data; /* Transfer from this address */
- msg.length = 1; /* Send one byte following the address */
-
- /* Ignore errors from the setup command (because it is not ACKed) */
-
- (void)I2C_TRANSFER(priv->i2c, &msg, 1);
-
- /* Now activate the A/D converter */
-
- data = cmd;
-
- msg.addr = priv->config->address; /* 7-bit address */
- msg.flags = 0; /* Write transaction, beginning with START */
- msg.buffer = &data; /* Transfer from this address */
- msg.length = 1; /* Send one byte following the address */
-
- ret = I2C_TRANSFER(priv->i2c, &msg, 1);
- if (ret < 0)
- {
- idbg("I2C_TRANSFER failed: %d\n", ret);
- }
- return ret;
-}
-#else
-# define tsc2007_activate(p,c)
-#endif
-
-/****************************************************************************
- * Name: tsc2007_transfer
- ****************************************************************************/
-
-static int tsc2007_transfer(FAR struct tsc2007_dev_s *priv, uint8_t cmd)
-{
- struct i2c_msg_s msg;
- uint8_t data12[2];
- int ret;
-
- /* "A conversion/write cycle begins when the master issues the address
- * byte containing the slave address of the TSC2007, with the eighth bit
- * equal to a 0 (R/W = 0)... Once the eighth bit has been received...
- * the TSC2007 issues an acknowledge.
- *
- * "When the master receives the acknowledge bit from the TSC2007, the
- * master writes the command byte to the slave... After the command byte
- * is received by the slave, the slave issues another acknowledge bit.
- * The master then ends the write cycle by issuing a repeated START or a
- * STOP condition...
- */
-
- msg.addr = priv->config->address; /* 7-bit address */
- msg.flags = 0; /* Write transaction, beginning with START */
- msg.buffer = &cmd; /* Transfer from this address */
- msg.length = 1; /* Send one byte following the address */
-
- ret = I2C_TRANSFER(priv->i2c, &msg, 1);
- if (ret < 0)
- {
- idbg("I2C_TRANSFER failed: %d\n", ret);
- return ret;
- }
-
- /* "The input multiplexer channel for the A/D converter is selected when
- * bits C3 through C0 are clocked in. If the selected channel is an X-,Y-,
- * or Z-position measurement, the appropriate drivers turn on once the
- * acquisition period begins.
- *
- * "... the input sample acquisition period starts on the falling edge of
- * SCL when the C0 bit of the command byte has been latched, and ends
- * when a STOP or repeated START condition has been issued. A/D conversion
- * starts immediately after the acquisition period...
- *
- * "For best performance, the I2C bus should remain in an idle state while
- * an A/D conversion is taking place. ... The master should wait for at
- * least 10ms before attempting to read data from the TSC2007...
- */
-
- usleep(10*1000);
-
- /* "Data access begins with the master issuing a START condition followed
- * by the address byte ... with R/W = 1.
- *
- * "When the eighth bit has been received and the address matches, the
- * slave issues an acknowledge. The first byte of serial data then follows
- * (D11-D4, MSB first).
- *
- * "After the first byte has been sent by the slave, it releases the SDA line
- * for the master to issue an acknowledge. The slave responds with the
- * second byte of serial data upon receiving the acknowledge from the master
- * (D3-D0, followed by four 0 bits). The second byte is followed by a NOT
- * acknowledge bit (ACK = 1) from the master to indicate that the last
- * data byte has been received...
- */
-
- msg.addr = priv->config->address; /* 7-bit address */
- msg.flags = I2C_M_READ; /* Read transaction, beginning with START */
- msg.buffer = data12; /* Transfer to this address */
- msg.length = 2; /* Read two bytes following the address */
-
- ret = I2C_TRANSFER(priv->i2c, &msg, 1);
- if (ret < 0)
- {
- idbg("I2C_TRANSFER failed: %d\n", ret);
- return ret;
- }
-
- /* Get the MS 8 bits from the first byte and the remaining LS 4 bits from
- * the second byte. The valid range of data is then from 0 to 4095 with
- * the LSB unit corresponding to Vref/4096.
- */
-
- ret = (unsigned int)data12[0] << 4 | (unsigned int)data12[1] >> 4;
- ivdbg("data: 0x%04x\n", ret);
- return ret;
-}
-
-/****************************************************************************
- * Name: tsc2007_worker
- ****************************************************************************/
-
-static void tsc2007_worker(FAR void *arg)
-{
- FAR struct tsc2007_dev_s *priv = (FAR struct tsc2007_dev_s *)arg;
- FAR struct tsc2007_config_s *config; /* Convenience pointer */
- bool pendown; /* true: pend is down */
- uint16_t x; /* X position */
- uint16_t y; /* Y position */
- uint16_t z1; /* Z1 position */
- uint16_t z2; /* Z2 position */
- uint32_t pressure; /* Measured pressure */
-
- ASSERT(priv != NULL);
-
- /* Get a pointer the callbacks for convenience (and so the code is not so
- * ugly).
- */
-
- config = priv->config;
- DEBUGASSERT(config != NULL);
-
- /* Check for pen up or down by reading the PENIRQ GPIO. */
-
- pendown = config->pendown(config);
-
- /* Handle the change from pen down to pen up */
-
- if (!pendown)
- {
- /* Ignore the interrupt if the pen was already down (CONTACT_NONE == pen up and
- * already reported. CONTACT_UP == pen up, but not reported)
- */
-
- if (priv->sample.contact == CONTACT_NONE)
- {
- goto errout;
- }
- }
-
- /* It is a pen down event. If the last loss-of-contact event has not been
- * processed yet, then we have to ignore the pen down event (or else it will
- * look like a drag event)
- */
-
- else if (priv->sample.contact == CONTACT_UP)
- {
- goto errout;
- }
- else
- {
- /* Handle all pen down events. First, sample X, Y, Z1, and Z2 values.
- *
- * "A resistive touch screen operates by applying a voltage across a
- * resistor network and measuring the change in resistance at a given
- * point on the matrix where the screen is touched by an input (stylus,
- * pen, or finger). The change in the resistance ratio marks the location
- * on the touch screen.
- *
- * "The 4-wire touch screen panel works by applying a voltage across the
- * vertical or horizontal resistive network. The A/D converter converts
- * the voltage measured at the point where the panel is touched. A measurement
- * of the Y position of the pointing device is made by connecting the X+
- * input to a data converter chip, turning on the Y+ and Y– drivers, and
- * digitizing the voltage seen at the X+ input ..."
- *
- * "... it is recommended that whenever the host writes to the TSC2007, the
- * master processor masks the interrupt associated to PENIRQ. This masking
- * prevents false triggering of interrupts when the PENIRQ line is disabled
- * in the cases previously listed."
- */
-
- (void)tsc2007_activate(priv, TSC2007_ACTIVATE_X);
- y = tsc2007_transfer(priv, TSC2007_MEASURE_Y);
-
-
- /* "Voltage is then applied to the other axis, and the A/D converter
- * converts the voltage representing the X position on the screen. This
- * process provides the X and Y coordinates to the associated processor."
- */
-
- (void)tsc2007_activate(priv, TSC2007_ACTIVATE_Y);
- x = tsc2007_transfer(priv, TSC2007_MEASURE_X);
-
- /* "... To determine pen or finger touch, the pressure of the touch must be
- * determined. ... There are several different ways of performing this
- * measurement. The TSC2007 supports two methods. The first method requires
- * knowing the X-plate resistance, the measurement of the X-position, and two
- * additional cross panel measurements (Z2 and Z1) of the touch screen."
- *
- * Rtouch = Rxplate * (X / 4096)* (Z2/Z1 - 1)
- *
- * "The second method requires knowing both the X-plate and Y-plate
- * resistance, measurement of X-position and Y-position, and Z1 ..."
- *
- * Rtouch = Rxplate * (X / 4096) * (4096/Z1 - 1) - Ryplate * (1 - Y/4096)
- *
- * Read Z1 and Z2 values.
- */
-
- (void)tsc2007_activate(priv, TSC2007_ACTIVATE_Z);
- z1 = tsc2007_transfer(priv, TSC2007_MEASURE_Z1);
- (void)tsc2007_activate(priv, TSC2007_ACTIVATE_Z);
- z2 = tsc2007_transfer(priv, TSC2007_MEASURE_Z2);
-
- /* Power down ADC and enable PENIRQ */
-
- (void)tsc2007_transfer(priv, TSC2007_ENABLE_PENIRQ);
-
- /* Now calculate the pressure using the first method, reduced to:
- *
- * Rtouch = X * Rxplate *(Z2 - Z1) * / Z1 / 4096
- */
-
- if (z1 == 0)
- {
- idbg("Z1 zero\n");
- pressure = 0;
- }
- else
- {
- pressure = (x * config->rxplate * (z2 - z1)) / z1;
- pressure = (pressure + 2048) >> 12;
-
- ivdbg("Position: (%d,%4d) pressure: %u z1/2: (%d,%d)\n",
- x, y, pressure, z1, z2);
-
- /* Ignore out of range caculcations */
-
- if (pressure > 0x0fff)
- {
- idbg("Dropped out-of-range pressure: %d\n", pressure);
- pressure = 0;
- }
- }
-
- /* Save the measurements */
-
- priv->sample.x = x;
- priv->sample.y = y;
- priv->sample.pressure = pressure;
- priv->sample.valid = true;
- }
-
- /* Note the availability of new measurements */
-
- if (pendown)
- {
- /* If this is the first (acknowledged) pend down report, then report
- * this as the first contact. If contact == CONTACT_DOWN, it will be
- * set to set to CONTACT_MOVE after the contact is first sampled.
- */
-
- if (priv->sample.contact != CONTACT_MOVE)
- {
- /* First contact */
-
- priv->sample.contact = CONTACT_DOWN;
- }
- }
- else /* if (priv->sample.contact != CONTACT_NONE) */
- {
- /* The pen is up. NOTE: We know from a previous test, that this is a
- * loss of contact condition. This will be changed to CONTACT_NONE
- * after the loss of contact is sampled.
- */
-
- priv->sample.contact = CONTACT_UP;
- }
-
- /* Indicate the availability of new sample data for this ID */
-
- priv->sample.id = priv->id;
- priv->penchange = true;
-
- /* Notify any waiters that nes TSC2007 data is available */
-
- tsc2007_notify(priv);
-
- /* Exit, re-enabling TSC2007 interrupts */
-
-errout:
- config->enable(config, true);
-}
-
-/****************************************************************************
- * Name: tsc2007_interrupt
- ****************************************************************************/
-
-static int tsc2007_interrupt(int irq, FAR void *context)
-{
- FAR struct tsc2007_dev_s *priv;
- FAR struct tsc2007_config_s *config;
- int ret;
-
- /* Which TSC2007 device caused the interrupt? */
-
-#ifndef CONFIG_TSC2007_MULTIPLE
- priv = &g_tsc2007;
-#else
- for (priv = g_tsc2007list;
- priv && priv->configs->irq != irq;
- priv = priv->flink);
-
- ASSERT(priv != NULL);
-#endif
-
- /* Get a pointer the callbacks for convenience (and so the code is not so
- * ugly).
- */
-
- config = priv->config;
- DEBUGASSERT(config != NULL);
-
- /* Disable further interrupts */
-
- config->enable(config, false);
-
- /* Transfer processing to the worker thread. Since TSC2007 interrupts are
- * disabled while the work is pending, no special action should be required
- * to protected the work queue.
- */
-
- DEBUGASSERT(priv->work.worker == NULL);
- ret = work_queue(HPWORK, &priv->work, tsc2007_worker, priv, 0);
- if (ret != 0)
- {
- illdbg("Failed to queue work: %d\n", ret);
- }
-
- /* Clear any pending interrupts and return success */
-
- config->clear(config);
- return OK;
-}
-
-/****************************************************************************
- * Name: tsc2007_open
- ****************************************************************************/
-
-static int tsc2007_open(FAR struct file *filep)
-{
-#ifdef CONFIG_TSC2007_REFCNT
- FAR struct inode *inode;
- FAR struct tsc2007_dev_s *priv;
- uint8_t tmp;
- int ret;
-
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct tsc2007_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Increment the reference count */
-
- tmp = priv->crefs + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- goto errout_with_sem;
- }
-
- /* When the reference increments to 1, this is the first open event
- * on the driver.. and an opportunity to do any one-time initialization.
- */
-
- /* Save the new open count on success */
-
- priv->crefs = tmp;
-
-errout_with_sem:
- sem_post(&priv->devsem);
- return ret;
-#else
- return OK;
-#endif
-}
-
-/****************************************************************************
- * Name: tsc2007_close
- ****************************************************************************/
-
-static int tsc2007_close(FAR struct file *filep)
-{
-#ifdef CONFIG_TSC2007_REFCNT
- FAR struct inode *inode;
- FAR struct tsc2007_dev_s *priv;
- int ret;
-
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct tsc2007_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Decrement the reference count unless it would decrement a negative
- * value. When the count decrements to zero, there are no further
- * open references to the driver.
- */
-
- if (priv->crefs >= 1)
- {
- priv->crefs--;
- }
-
- sem_post(&priv->devsem);
-#endif
- return OK;
-}
-
-/****************************************************************************
- * Name: tsc2007_read
- ****************************************************************************/
-
-static ssize_t tsc2007_read(FAR struct file *filep, FAR char *buffer, size_t len)
-{
- FAR struct inode *inode;
- FAR struct tsc2007_dev_s *priv;
- FAR struct touch_sample_s *report;
- struct tsc2007_sample_s sample;
- int ret;
-
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct tsc2007_dev_s *)inode->i_private;
-
- /* Verify that the caller has provided a buffer large enough to receive
- * the touch data.
- */
-
- if (len < SIZEOF_TOUCH_SAMPLE_S(1))
- {
- /* We could provide logic to break up a touch report into segments and
- * handle smaller reads... but why?
- */
-
- return -ENOSYS;
- }
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Try to read sample data. */
-
- ret = tsc2007_sample(priv, &sample);
- if (ret < 0)
- {
- /* Sample data is not available now. We would ave to wait to get
- * receive sample data. If the user has specified the O_NONBLOCK
- * option, then just return an error.
- */
-
- if (filep->f_oflags & O_NONBLOCK)
- {
- ret = -EAGAIN;
- goto errout;
- }
-
- /* Wait for sample data */
-
- ret = tsc2007_waitsample(priv, &sample);
- if (ret < 0)
- {
- /* We might have been awakened by a signal */
-
- goto errout;
- }
- }
-
- /* In any event, we now have sampled TSC2007 data that we can report
- * to the caller.
- */
-
- report = (FAR struct touch_sample_s *)buffer;
- memset(report, 0, SIZEOF_TOUCH_SAMPLE_S(1));
- report->npoints = 1;
- report->point[0].id = priv->id;
- report->point[0].x = sample.x;
- report->point[0].y = sample.y;
- report->point[0].pressure = sample.pressure;
-
- /* Report the appropriate flags */
-
- if (sample.contact == CONTACT_UP)
- {
- /* Pen is now up. Is the positional data valid? This is important to
- * know because the release will be sent to the window based on its
- * last positional data.
- */
-
- if (sample.valid)
- {
- report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID |
- TOUCH_POS_VALID | TOUCH_PRESSURE_VALID;
- }
- else
- {
- report->point[0].flags = TOUCH_UP | TOUCH_ID_VALID;
- }
- }
- else
- {
- if (sample.contact == CONTACT_DOWN)
- {
- /* First contact */
-
- report->point[0].flags = TOUCH_DOWN | TOUCH_ID_VALID | TOUCH_POS_VALID;
- }
- else /* if (sample->contact == CONTACT_MOVE) */
- {
- /* Movement of the same contact */
-
- report->point[0].flags = TOUCH_MOVE | TOUCH_ID_VALID | TOUCH_POS_VALID;
- }
-
- /* A pressure measurement of zero means that pressure is not available */
-
- if (report->point[0].pressure != 0)
- {
- report->point[0].flags |= TOUCH_PRESSURE_VALID;
- }
- }
-
- ret = SIZEOF_TOUCH_SAMPLE_S(1);
-
-errout:
- sem_post(&priv->devsem);
- return ret;
-}
-
-/****************************************************************************
- * Name:tsc2007_ioctl
- ****************************************************************************/
-
-static int tsc2007_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode;
- FAR struct tsc2007_dev_s *priv;
- int ret;
-
- ivdbg("cmd: %d arg: %ld\n", cmd, arg);
- DEBUGASSERT(filep);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct tsc2007_dev_s *)inode->i_private;
-
- /* Get exclusive access to the driver data structure */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- /* Process the IOCTL by command */
-
- switch (cmd)
- {
- case TSIOC_SETCALIB: /* arg: Pointer to int calibration value */
- {
- FAR int *ptr = (FAR int *)((uintptr_t)arg);
- DEBUGASSERT(priv->config != NULL && ptr != NULL);
- priv->config->rxplate = *ptr;
- }
- break;
-
- case TSIOC_GETCALIB: /* arg: Pointer to int calibration value */
- {
- FAR int *ptr = (FAR int *)((uintptr_t)arg);
- DEBUGASSERT(priv->config != NULL && ptr != NULL);
- *ptr = priv->config->rxplate;
- }
- break;
-
- case TSIOC_SETFREQUENCY: /* arg: Pointer to uint32_t frequency value */
- {
- FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
- DEBUGASSERT(priv->config != NULL && ptr != NULL);
- priv->config->frequency = I2C_SETFREQUENCY(priv->i2c, *ptr);
- }
- break;
-
- case TSIOC_GETFREQUENCY: /* arg: Pointer to uint32_t frequency value */
- {
- FAR uint32_t *ptr = (FAR uint32_t *)((uintptr_t)arg);
- DEBUGASSERT(priv->config != NULL && ptr != NULL);
- *ptr = priv->config->frequency;
- }
- break;
-
- default:
- ret = -ENOTTY;
- break;
- }
-
- sem_post(&priv->devsem);
- return ret;
-}
-
-/****************************************************************************
- * Name: tsc2007_poll
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static int tsc2007_poll(FAR struct file *filep, FAR struct pollfd *fds,
- bool setup)
-{
- FAR struct inode *inode;
- FAR struct tsc2007_dev_s *priv;
- int ret;
- int i;
-
- ivdbg("setup: %d\n", (int)setup);
- DEBUGASSERT(filep && fds);
- inode = filep->f_inode;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct tsc2007_dev_s *)inode->i_private;
-
- /* Are we setting up the poll? Or tearing it down? */
-
- ret = sem_wait(&priv->devsem);
- if (ret < 0)
- {
- /* This should only happen if the wait was canceled by an signal */
-
- DEBUGASSERT(errno == EINTR);
- return -EINTR;
- }
-
- if (setup)
- {
- /* Ignore waits that do not include POLLIN */
-
- if ((fds->events & POLLIN) == 0)
- {
- idbg("Missing POLLIN: revents: %08x\n", fds->revents);
- ret = -EDEADLK;
- goto errout;
- }
-
- /* This is a request to set up the poll. Find an available
- * slot for the poll structure reference
- */
-
- for (i = 0; i < CONFIG_TSC2007_NPOLLWAITERS; i++)
- {
- /* Find an available slot */
-
- if (!priv->fds[i])
- {
- /* Bind the poll structure and this slot */
-
- priv->fds[i] = fds;
- fds->priv = &priv->fds[i];
- break;
- }
- }
-
- if (i >= CONFIG_TSC2007_NPOLLWAITERS)
- {
- idbg("No availabled slot found: %d\n", i);
- fds->priv = NULL;
- ret = -EBUSY;
- goto errout;
- }
-
- /* Should we immediately notify on any of the requested events? */
-
- if (priv->penchange)
- {
- tsc2007_notify(priv);
- }
- }
- else if (fds->priv)
- {
- /* This is a request to tear down the poll. */
-
- struct pollfd **slot = (struct pollfd **)fds->priv;
- DEBUGASSERT(slot != NULL);
-
- /* Remove all memory of the poll setup */
-
- *slot = NULL;
- fds->priv = NULL;
- }
-
-errout:
- sem_post(&priv->devsem);
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: tsc2007_register
- *
- * Description:
- * Configure the TSC2007 to use the provided I2C device instance. This
- * will register the driver as /dev/inputN where N is the minor device
- * number
- *
- * Input Parameters:
- * dev - An I2C driver instance
- * config - Persistant board configuration data
- * minor - The input device minor number
- *
- * Returned Value:
- * Zero is returned on success. Otherwise, a negated errno value is
- * returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-int tsc2007_register(FAR struct i2c_dev_s *dev,
- FAR struct tsc2007_config_s *config, int minor)
-{
- FAR struct tsc2007_dev_s *priv;
- char devname[DEV_NAMELEN];
-#ifdef CONFIG_TSC2007_MULTIPLE
- irqstate_t flags;
-#endif
- int ret;
-
- ivdbg("dev: %p minor: %d\n", dev, minor);
-
- /* Debug-only sanity checks */
-
- DEBUGASSERT(dev != NULL && config != NULL && minor >= 0 && minor < 100);
- DEBUGASSERT((config->address & 0xfc) == 0x48);
- DEBUGASSERT(config->attach != NULL && config->enable != NULL &&
- config->clear != NULL && config->pendown != NULL);
-
- /* Create and initialize a TSC2007 device driver instance */
-
-#ifndef CONFIG_TSC2007_MULTIPLE
- priv = &g_tsc2007;
-#else
- priv = (FAR struct tsc2007_dev_s *)kmalloc(sizeof(struct tsc2007_dev_s));
- if (!priv)
- {
- idbg("kmalloc(%d) failed\n", sizeof(struct tsc2007_dev_s));
- return -ENOMEM;
- }
-#endif
-
- /* Initialize the TSC2007 device driver instance */
-
- memset(priv, 0, sizeof(struct tsc2007_dev_s));
- priv->i2c = dev; /* Save the I2C device handle */
- priv->config = config; /* Save the board configuration */
- sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */
- sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */
-
- /* Set the I2C frequency (saving the actual frequency) */
-
- config->frequency = I2C_SETFREQUENCY(dev, config->frequency);
-
- /* Set the I2C address and address size */
-
- ret = I2C_SETADDRESS(dev, config->address, 7);
- if (ret < 0)
- {
- idbg("I2C_SETADDRESS failed: %d\n", ret);
- goto errout_with_priv;
- }
-
- /* Make sure that interrupts are disabled */
-
- config->clear(config);
- config->enable(config, false);
-
- /* Attach the interrupt handler */
-
- ret = config->attach(config, tsc2007_interrupt);
- if (ret < 0)
- {
- idbg("Failed to attach interrupt\n");
- goto errout_with_priv;
- }
-
- /* Power down the ADC and enable PENIRQ. This is the normal state while
- * waiting for a touch event.
- */
-
- ret = tsc2007_transfer(priv, TSC2007_ENABLE_PENIRQ);
- if (ret < 0)
- {
- idbg("tsc2007_transfer failed: %d\n", ret);
- goto errout_with_priv;
- }
-
- /* Register the device as an input device */
-
- (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, minor);
- ivdbg("Registering %s\n", devname);
-
- ret = register_driver(devname, &tsc2007_fops, 0666, priv);
- if (ret < 0)
- {
- idbg("register_driver() failed: %d\n", ret);
- goto errout_with_priv;
- }
-
- /* If multiple TSC2007 devices are supported, then we will need to add
- * this new instance to a list of device instances so that it can be
- * found by the interrupt handler based on the recieved IRQ number.
- */
-
-#ifdef CONFIG_TSC2007_MULTIPLE
- flags = irqsave();
- priv->flink = g_tsc2007list;
- g_tsc2007list = priv;
- irqrestore(flags);
-#endif
-
- /* Schedule work to perform the initial sampling and to set the data
- * availability conditions.
- */
-
- ret = work_queue(HPWORK, &priv->work, tsc2007_worker, priv, 0);
- if (ret != 0)
- {
- idbg("Failed to queue work: %d\n", ret);
- goto errout_with_priv;
- }
-
- /* And return success (?) */
-
- return OK;
-
-errout_with_priv:
- sem_destroy(&priv->devsem);
-#ifdef CONFIG_TSC2007_MULTIPLE
- kfree(priv);
-#endif
- return ret;
-}
diff --git a/nuttx/drivers/input/tsc2007.h b/nuttx/drivers/input/tsc2007.h
deleted file mode 100644
index 76d5962bf..000000000
--- a/nuttx/drivers/input/tsc2007.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/********************************************************************************************
- * drivers/input/tsc2007.h
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "1.2V to 3.6V, 12-Bit, Nanopower, 4-Wire Micro TOUCH SCREEN CONTROLLER
- * with I2C Interface," SBAS405A March 2007, Revised, March 2009, Texas
- * Instruments Incorporated
- *
- * 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.
- *
- ********************************************************************************************/
-
-/* The TSC2007 is an analog interface circuit for a human interface touch screen device.
- * All peripheral functions are controlled through the command byte and onboard state
- * machines.
- */
-
-#ifndef __DRIVERS_INPUT_TSC2007_H
-#define __DRIVERS_INPUT_TSC2007_H
-
-/********************************************************************************************
- * Included Files
- ********************************************************************************************/
-
-/********************************************************************************************
- * Pre-Processor Definitions
- ********************************************************************************************/
-
-/* TSC2007 Address */
-
-#define TSC2007_ADDRESS_MASK (0xf8) /* Bits 3-7: Invariant part of TSC2007 address */
-#define TSC2007_ADDRESS (0x90) /* Bits 3-7: Always set at '10010' */
-#define TSC2007_A1 (1 << 2) /* Bit 2: A1 */
-#define TSC2007_A0 (1 << 1) /* Bit 1: A1 */
-#define TSC2007_READ (1 << 0) /* Bit0=1: Selects read operation */
-#define TSC2007_WRITE (0) /* Bit0=0: Selects write operation */
-
-/* TSC2007 Command Byte */
-
-#define TSC2007_CMD_FUNC_SHIFT (4) /* Bits 4-7: Converter function select bits */
-#define TSC2007_CMD_FUNC_MASK (15 << TSC2007_CMD_FUNC_SHIFT)
-# define TSC2007_CMD_FUNC_TEMP0 (0 << TSC2007_CMD_FUNC_SHIFT) /* Measure TEMP0 */
-# define TSC2007_CMD_FUNC_AUX (2 << TSC2007_CMD_FUNC_SHIFT) /* Measure AUX */
-# define TSC2007_CMD_FUNC_TEMP1 (4 << TSC2007_CMD_FUNC_SHIFT) /* Measure TEMP1 */
-# define TSC2007_CMD_FUNC_XON (8 << TSC2007_CMD_FUNC_SHIFT) /* Activate X-drivers */
-# define TSC2007_CMD_FUNC_YON (9 << TSC2007_CMD_FUNC_SHIFT) /* Activate Y-drivers */
-# define TSC2007_CMD_FUNC_YXON (10 << TSC2007_CMD_FUNC_SHIFT) /* Activate Y+, X-drivers */
-# define TSC2007_CMD_FUNC_SETUP (11 << TSC2007_CMD_FUNC_SHIFT) /* Setup command */
-# define TSC2007_CMD_FUNC_XPOS (12 << TSC2007_CMD_FUNC_SHIFT) /* Measure X position */
-# define TSC2007_CMD_FUNC_YPOS (13 << TSC2007_CMD_FUNC_SHIFT) /* Measure Y position */
-# define TSC2007_CMD_FUNC_Z1POS (14 << TSC2007_CMD_FUNC_SHIFT) /* Measure Z1 position */
-# define TSC2007_CMD_FUNC_Z2POS (15 << TSC2007_CMD_FUNC_SHIFT) /* Measure Z2 positionn */
-#define TSC2007_CMD_PWRDN_SHIFT (2) /* Bits 2-3: Power-down bits */
-#define TSC2007_CMD_PWRDN_MASK (3 << TSC2007_CMD_PWRDN_SHIFT)
-# define TSC2007_CMD_PWRDN_IRQEN (0 << TSC2007_CMD_PWRDN_SHIFT) /* 00: Power down between cycles; PENIRQ enabled */
-# define TSC2007_CMD_ADCON_IRQDIS (1 << TSC2007_CMD_PWRDN_SHIFT) /* 01: A/D converter on; PENIRQ disabled */
-# define TSC2007_CMD_ADCOFF_IRQEN (2 << TSC2007_CMD_PWRDN_SHIFT) /* 10: A/D converter off; PENIRQ enabled. */
- /* 11: A/D converter on; PENIRQ disabled. */
-#define TSC2007_CMD_12BIT (0) /* Bit 1: 0=12-bit */
-#define TSC2007_CMD_8BIT (1 << 1) /* Bit 1: 1=8-bit */
- /* Bit 0: Don't care */
-
-/* TSC2007 Setup Command */
-
-#define TSC2007_SETUP_CMD TSC2007_CMD_FUNC_SETUP /* Bits 4-7: Setup command */
- /* Bits 2-3: Must be zero */
-#define TSC2007_CMD_USEMAV (0) /* Bit 1: 0: Use the onboard MAV filter (default) */
-#define TSC2007_CMD_BYPASSMAV (1 << 1) /* Bit 1: 1: Bypass the onboard MAV filter */
-#define TSC2007_CMD_PU_50KOHM (0) /* Bit 0: 0: RIRQ = 50kOhm (default). */
-#define TSC2007_CMD_PU_90KOHM (1 << 1) /* Bit 0: 1: 1: RIRQ = 90kOhm */
-
-/********************************************************************************************
- * Public Types
- ********************************************************************************************/
-
-/********************************************************************************************
- * Public Function Prototypes
- ********************************************************************************************/
-
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DRIVERS_INPUT_TSC2007_H */
diff --git a/nuttx/drivers/lcd/Kconfig b/nuttx/drivers/lcd/Kconfig
deleted file mode 100644
index 2d20003ac..000000000
--- a/nuttx/drivers/lcd/Kconfig
+++ /dev/null
@@ -1,330 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-config LCD_NOGETRUN
- bool "Write-only LCD"
- default n
- ---help---
- Many LCD hardware interfaces provide only minimal graphics capability. In
- particulary, many simple LCD interfaces are write only. That is we, can
- write graphics data to the LCD device memory, but we cannot read it back.
- If the LCD hardware does not support reading the graphics memory, then
- this option should be defined so that the NX layer can taking alternative
- measures when the LCD is not readable. For example, if the LCD is not
- readable, then NX will not attempt to support transparency.
-
- See also NX_WRITEONLY in the graphics support menu.
-
-config LCD_MAXCONTRAST
- int "LCD maximum contrast"
- default 63 if NOKIA6100_S1D15G10
- default 127 if NOKIA6100_PCF8833
- default 255 if LCD_P14201
- default 63
- ---help---
- must be 63 with the Epson controller and 127 with
- the Phillips controller.
-
-config LCD_MAXPOWER
- int "LCD maximum power"
- default 1
- ---help---
- Maximum value of backlight setting. The backlight
- control is managed outside of the 6100 driver so this value has no
- meaning to the driver. Board-specific logic may place restrictions on
- this value.
-
-config LCD_P14201
- bool "Rit P1402 series display"
- default n
- ---help---
- p14201.c. Driver for RiT P14201 series display with SD1329 IC
- controller. This OLED is used with older versions of the
- TI/Luminary LM3S8962 Evaluation Kit.
-
-if LCD_P14201
-config P14201_NINTERFACES
- int "Number of physical P14201 devices"
- default 1
- range 1,1
- ---help---
- Specifies the number of physical P14201
- devices that will be supported.
-
-config P14201_SPIMODE
- int "SPI mode"
- default 2
- range 0,3
- ---help---
- Controls the SPI mode
-
-config P14201_FREQUENCY
- int "SPI frequency"
- default 1000000
- ---help---
- Define to use a different bus frequency,FIXME DEFAULT VALUE OK?
-
-config P14201_FRAMEBUFFER
- bool "Enable P14201 GDDRAM cache"
- default y
- ---help---
- If defined, accesses will be performed
- using an in-memory copy of the OLEDs GDDRAM. This cost of this
- buffer is 128 * 96 / 2 = 6Kb. If this is defined, then the driver
- will be fully functional. If not, then it will have the following
- limitations:
-
- Reading graphics memory cannot be supported, and
-
- All pixel writes must be aligned to byte boundaries.
- The latter limitation effectively reduces the 128x96 disply to 64x96.
-endif
-
-config LCD_NOKIA6100
- bool "Nokia 6100 display support"
- default n
- ---help---
- nokia6100.c. Supports the Nokia 6100 display with either the Philips
- PCF883 or the Epson S1D15G10 display controller. This LCD is used
- with the Olimex LPC1766-STK (but has not been fully integrated).
-if LCD_NOKIA6100
-config NOKIA6100_NINTERFACES
- int "Number of physical NOKIA6100 devices"
- default 1
- range 1,1
- ---help---
- Specifies the number of physical Nokia
- 6100 devices that will be supported.
-
-choice NOKIA6100_CONTROLLER
- prompt "Controller Setup"
- default NOKIA6100_S1D15G10
-config NOKIA6100_S1D15G10
- bool "S1D15G10 controller"
- ---help---
- Selects the Epson S1D15G10 display controller
-
-config NOKIA6100_PCF8833
- bool "PCF8833 controller"
- ---help---
- Selects the Phillips PCF8833 display controller
-endchoice
-
-config NOKIA6100_SPIMODE
- int "SPI mode"
- default 0
- range 0,3
- ---help---
- Controls the SPI mode
-
-config NOKIA6100_FREQUENCY
- int "SPI frequency"
- default 1000000
- ---help---
- Define to use a different bus frequency
-
-config NOKIA6100_BLINIT
- bool "Back light initial"
- default n
- ---help---
- Initial backlight setting
- The following may need to be tuned for your hardware:
-
-config NOKIA6100_BPP
- int "Display bits per pixel"
- default 8
- ---help---
- Device supports 8, 12, and 16 bits per pixel.
-
-config NOKIA6100_INVERT
- int "Display inversion"
- default 1
- range 0,1
- ---help---
- Display inversion, 0 or 1, Default: 1
-
-config NOKIA6100_MY
- int "Display row direction"
- default 0
- range 0,1
- ---help---
- Display row direction, 0 or 1, Default: 0
-
-config NOKIA6100_MX
- int "Display column direction"
- default 1
- range 0,1
- ---help---
- Display column direction, 0 or 1, Default: 1
-
-config NOKIA6100_V
- int "Display address direction"
- default 0
- range 0,1
- ---help---
- Display address direction, 0 or 1, Default: 0
-
-config NOKIA6100_ML
- int "Display scan direction"
- default 0
- range 0,1
- ---help---
- Display scan direction, 0 or 1, Default: 0
-
-config NOKIA6100_RGBORD
- int "Display RGB order"
- default 0
- range 0,1
- ---help---
- Display RGB order, 0 or 1, Default: 0
- Required LCD driver settings:
-endif
-
-config LCD_UG9664HSWAG01
- bool "UG-9664HSWAG01 OLED Display Module"
- default n
- ---help---
- OLED Display Module, UG-9664HSWAG01, Univision Technology Inc. Used
- with the LPCXpresso and Embedded Artists base board.
-
- Required LCD driver settings:
- LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted.
- LCD_MAXPOWER should be 1: 0=off, 1=on
-
- Required SPI driver settings:
- SPI_CMDDATA - Include support for cmd/data selection.
-
-if LCD_UG9664HSWAG01
-
-config UG9664HSWAG01_SPIMODE
- int "UG-9664HSWAG01 SPI Mode"
- default 0
- ---help---
- Controls the SPI mode
-
-config UG9664HSWAG01_FREQUENCY
- int "UG-9664HSWAG01 SPI Frequency"
- default 3500000
- ---help---
- Define to use a different bus frequency
-
-config UG9664HSWAG01_NINTERFACES
- int "Number of UG-9664HSWAG01 Devices"
- default 1
- ---help---
- Specifies the number of physical UG-9664HSWAG01 devices that will be
- supported. NOTE: At present, this must be undefined or defined to be 1.
-
-config UG9664HSWAG01_POWER
- bool "Power control"
- default n
- ---help---
- If the hardware supports a controllable OLED a power supply, this
- configuration should be defined. In this case the system must
- provide an interface ug_power().
-
-endif
-
-config LCD_UG2864AMBAG01
- bool "UG-2864AMBAG01 OLED Display Module"
- default n
- ---help---
- OLED Display Module, UG-2864AMBAG01, Univision Technology Inc.
-
- Required LCD driver settings:
- LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted.
- LCD_MAXPOWER should be 1: 0=off, 1=on
-
- Required SPI driver settings:
- SPI_CMDDATA - Include support for cmd/data selection.
-
-if LCD_UG2864AMBAG01
-
- config UG2864AMBAG01_SPIMODE
- int "UG-2864AMBAG01 SPI Mode"
- default 3
- ---help---
- Controls the SPI mode
-
-config UG2864AMBAG01_FREQUENCY
- int "UG-2864AMBAG01 SPI Frequency"
- default 3500000
- ---help---
- Define to use a different bus frequency
-
-config UG2864AMBAG01_NINTERFACES
- int "Number of UG-2864AMBAG01 Devices"
- default 1
- ---help---
- Specifies the number of physical UG-9664HSWAG01 devices that will be
- supported. NOTE: At present, this must be undefined or defined to be 1.
-
-endif
-
-config LCD_SSD1289
- bool "LCD Based on SSD1289 Controller"
- default n
- ---help---
- Enables generic support for any LCD based on the Solomon Systech,
- Ltd, SSD1289 Controller. Use of this driver will usually require so
- detailed customization of the LCD initialization code as necessary
- for the specific LCD driven by the SSD1289 controller.
-
-if LCD_SSD1289
-
-choice
- prompt "SSD1289 Initialization Profile"
- default SSD1289_PROFILE1
-
-config SSD1289_PROFILE1
- bool "Profile 1"
-
-config SSD1289_PROFILE2
- bool "Profile 2"
-
-config SSD1289_PROFILE3
- bool "Profile 3"
-
-endchoice
-endif
-
-choice
- prompt "LCD Orientation"
- default LCD_LANDSCAPE
- depends on LCD
- ---help---
- Some LCD drivers may support displays in different orientations.
- If the LCD driver supports this capability, than these are configuration
- options to select that display orientation.
-
-config LCD_LANDSCAPE
- bool "Landscape orientation"
- ---help---
- Define for "landscape" orientation support. Landscape mode refers one
- of two orientations where the the display is wider than it is tall
- (LCD_RLANDSCAPE is the other). This is the default orientation.
-
-config LCD_PORTRAIT
- bool "Portrait orientation"
- ---help---
- Define for "portrait" orientation support. Portrait mode refers one
- of two orientations where the the display is taller than it is wide
- (LCD_RPORTAIT is the other).
-
-config LCD_RPORTRAIT
- bool "Reverse portrait display"
- ---help---
- Define for "reverse portrait" orientation support. Reverse portrait mode
- refers one of two orientations where the the display is taller than it is
- wide (LCD_PORTAIT is the other).
-
-config LCD_RLANDSCAPE
- bool "Reverse landscape orientation"
- ---help---
- Define for "reverse landscape" orientation support. Reverse landscape mode
- refers one of two orientations where the the display is wider than it is
- tall (LCD_LANDSCAPE is the other).
-
-endchoice
diff --git a/nuttx/drivers/lcd/Make.defs b/nuttx/drivers/lcd/Make.defs
deleted file mode 100644
index 067f76f4e..000000000
--- a/nuttx/drivers/lcd/Make.defs
+++ /dev/null
@@ -1,76 +0,0 @@
-############################################################################
-# drivers/lcd/Make.defs
-#
-# Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-# Don't build anything if there is no NX support for LCD drivers
-
-ifeq ($(CONFIG_NX_LCDDRIVER),y)
-
-# Include LCD drivers
-
-ifeq ($(CONFIG_LCD_P14201),y)
- CSRCS += p14201.c
-endif
-
-ifeq ($(CONFIG_LCD_NOKIA6100),y)
- CSRCS += nokia6100.c
-endif
-
-ifeq ($(CONFIG_LCD_UG2864AMBAG01),y)
- CSRCS += ug-2864ambag01.c
-endif
-
-ifeq ($(CONFIG_LCD_UG2864HSWEG01),y)
- CSRCS += ug-2864hsweg01.c
-endif
-
-ifeq ($(CONFIG_LCD_UG9664HSWAG01),y)
- CSRCS += ug-9664hswag01.c
-endif
-
-ifeq ($(CONFIG_LCD_SSD1289),y)
- CSRCS += ssd1289.c
-endif
-
-ifeq ($(CONFIG_LCD_MIO283QT2),y)
- CSRCS += mio283qt2.c
-endif
-
-# Include LCD driver build support
-
-DEPPATH += --dep-path lcd
-VPATH += :lcd
-CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)lcd}
-endif
-
diff --git a/nuttx/drivers/lcd/README.txt b/nuttx/drivers/lcd/README.txt
deleted file mode 100644
index 0472043e6..000000000
--- a/nuttx/drivers/lcd/README.txt
+++ /dev/null
@@ -1,189 +0,0 @@
-nuttx/drivers/lcd README
-========================
-
-This is the README.txt file for the drivers/lcd/ directory.
-
-Contents
-========
-
- - LCD Header files
- include/nuttx/lcd/lcd.h
- struct lcd_dev_s
- - Binding LCD Drivers
- - Examples: /drivers/lcd/
- - Examples: configs/
- - graphics/
-
-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 privided in
- include/nuttx/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.
-
- 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:
-
- 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:
-
- 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.
-
- 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.
-
- int (*setpower)(struct lcd_dev_s *dev, int power);
-
- - Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST) */
-
- int (*getcontrast)(struct lcd_dev_s *dev);
-
- - Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST)
-
- int (*setcontrast)(struct lcd_dev_s *dev, unsigned int contrast);
-
-Binding LCD Drivers
-===================
-
- LCD drivers are not normally directly accessed by user code, but are
- usually bound to another, higher level device driver. In general, the
- binding sequence is:
-
- 1. Get an instance of struct lcd_dev_s from the hardware-specific LCD
- device driver, and
- 2. Provide that instance to the initialization method of the higher
- level device driver.
-
-Examples: /drivers/lcd/
-=======================
-
-Re-usable LCD drivers reside in the drivers/lcd directory:
-
- 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.
-
- nokia6100.c. Supports the Nokia 6100 display with either the Philips
- PCF883 or the Epson S1D15G10 display controller. This LCD is used
- with the Olimex LPC1766-STK (but has not been fully integrated).
-
- p14201.c. Driver for RiT P14201 series display with SD1329 IC
- controller. This OLED is used with older versions of the
- TI/Luminary LM3S8962 Evaluation Kit.
-
- 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 proably ahve to customize for any particular LCD
- hardware. (see also configs/hymini-stm32v/src/ssd1289.c below).
-
- ug-9664hswag01.c. OLED Display Module, UG-9664HSWAG01", Univision
- Technology Inc. Used with the LPC Xpresso and Embedded Artists
- base board.
-
-Examples: configs/
-==================
-
-There are additional LCD drivers in the configs/<board>/src directory
-that support additional LCDs. LCD drivers in the configuration directory
-if they support some differ LCD interface (such as a parallel interface)
-that makes then less re-usable:
-
- SSD1783 Drivers:
-
- configs/compal_e99/src/ssd1783.c
-
- SSD1289 Drivers:
-
- configs/hymini-stm32v/src/ssd1289.c. See also drivers/lcd/ssd1298.c
- above.
- configs/stm32f4discovery/src/up_ssd1289.c. This examples is the
- bottom half for the SSD1289 driver at drivers/lcd/ssd1289.c
- configs/hymini-stm32v/src/ssd1289.c. See also drivers/lcd/ssd1298.c
- above.
- configs/shenzhou/src/up_ssd1289.c
-
- kwikstik-k40:
-
- configs/kwikstik-k40/src/up_lcd.c. Don't waste your time. This is
- just a stub.
-
- Nokia LCD Drivers:
-
- configs/olimex-lpc1766stk/src/up_lcd.c. This examples is the
- bottom half for the driver at drivers/lcd/nokia6100.c.
- This was never completedly debugged ... there are probably issues
- with that nasty 9-bit SPI interfaces.
-
- HX8346:
-
- configs/sam3u-ek/src/up_lcd.c. The SAM3U-EK developement board features
- a TFT/Transmissive color LCD module with touch-screen, FTM280C12D,
- with integrated driver IC HX8346.
-
- HX8347:
-
- configs/pic32mx7mmb/src/up_mio283qt2.c. This driver is for the MI0283QT-2
- LCD from Multi-Inno Technology Co., Ltd. This LCD is based on the Himax
- HX8347-D LCD controller.
-
- ILI93xx and Similar:
-
- configs/stm3210e-eval/src/up_lcd.c. This driver supports the following
- LCDs:
-
- 1. Ampire AM-240320LTNQW00H
- 2. Orise Tech SPFD5408B
- 3. RenesasSP R61580
-
- configs/stm3220g-eval/src/up_lcd.c and configs/stm3240g-eval/src/up_lcd.c.
- AM-240320L8TNQW00H (LCD_ILI9320 or LCD_ILI9321) and
- AM-240320D5TOQW01H (LCD_ILI9325)
- configs/shenzhou/src/up_ili93xx.c. Another ILI93xx driver.
-
- OLEDs:
-
- configs/stm32f4discovery/src/up_ug2864ambag01.c
- configs/stm32f4discovery/src/up_ug2864hsweg01.c
- configs/zp214xpa/src/up_ug2864ambag01.c
-
- Alphnumeric LCD Displays:
-
- configs/skp16c26/src/up_lcd.c. Untested alphanumeric LCD driver.
- configs/pcblogic-pic32/src/up_lcd1602.c
-
-graphics/
-=========
-
- See also the usage of the LCD driver in the graphics/ directory.
-
diff --git a/nuttx/drivers/lcd/mio283qt2.c b/nuttx/drivers/lcd/mio283qt2.c
deleted file mode 100644
index 4c8835eef..000000000
--- a/nuttx/drivers/lcd/mio283qt2.c
+++ /dev/null
@@ -1,1014 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/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.
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Authors: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * 1) LCD Module Specification, Model : MI0283QT-2, Multi-Inno Technology Co.,
- * Ltd., Revision 1.0
- * 2) Data Sheet: HX8347-D(T), 240RGB x 320 dot, 262K color, with internal GRAM, TFT
- * Mobile Single Chip Driver Version 02 March, Doc No. HX8347-D(T)-DS, Himax
- * Technologies, Inc., 2009,
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/spi.h>
-#include <nuttx/lcd/lcd.h>
-#include <nuttx/lcd/mio283qt2.h>
-
-#ifdef CONFIG_LCD_MIO283QT2
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-/* Configuration **********************************************************************/
-
-/* Check contrast selection */
-
-#if !defined(CONFIG_LCD_MAXCONTRAST)
-# define CONFIG_LCD_MAXCONTRAST 1
-#endif
-
-/* Check power setting */
-
-#if !defined(CONFIG_LCD_MAXPOWER) || CONFIG_LCD_MAXPOWER < 1
-# define CONFIG_LCD_MAXPOWER 1
-#endif
-
-#if CONFIG_LCD_MAXPOWER > 255
-# error "CONFIG_LCD_MAXPOWER must be less than 256 to fit in uint8_t"
-#endif
-
-/* Check orientation */
-
-#if defined(CONFIG_LCD_PORTRAIT)
-# if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) || defined(CONFIG_LCD_RPORTRAIT)
-# error "Cannot define both portrait and any other orientations"
-# endif
-#elif defined(CONFIG_LCD_RPORTRAIT)
-# if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-# error "Cannot define both rportrait and any other orientations"
-# endif
-#elif defined(CONFIG_LCD_LANDSCAPE)
-# ifdef CONFIG_LCD_RLANDSCAPE
-# error "Cannot define both landscape and any other orientations"
-# endif
-#elif !defined(CONFIG_LCD_RLANDSCAPE)
-# define CONFIG_LCD_LANDSCAPE 1
-#endif
-
-/* Define CONFIG_DEBUG_LCD to enable detailed LCD debug output. Verbose debug must
- * also be enabled.
- */
-
-#ifndef CONFIG_DEBUG
-# undef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_DEBUG_GRAPHICS
-# undef CONFIG_DEBUG_LCD
-#endif
-
-#ifndef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_DEBUG_LCD
-#endif
-
-/* Display/Color Properties ***********************************************************/
-/* Display Resolution */
-
-#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-# define MIO283QT2_XRES 320
-# define MIO283QT2_YRES 240
-#else
-# define MIO283QT2_XRES 240
-# define MIO283QT2_YRES 320
-#endif
-
-/* Color depth and format */
-
-#define MIO283QT2_BPP 16
-#define MIO283QT2_COLORFMT FB_FMT_RGB16_565
-
-/* Hardware LCD/LCD controller definitions ********************************************/
-/* In this driver, I chose to use all literal constants for register address and
- * values. Some recent experiences have shown me that during LCD bringup, it is more
- * important to know the binary values rather than nice, people friendly names. Sad,
- * but true.
- */
-
-#define HIMAX_ID 0x0047
-
-/* LCD Profiles ***********************************************************************/
-/* Many details of the controller initialization must, unfortunately, vary from LCD to
- * LCD. I have looked at the spec and at three different drivers for LCDs that have
- * MIO283QT2 controllers. I have tried to summarize these differences as "LCD profiles"
- *
- * Most of the differences between LCDs are nothing more than a few minor bit
- * settings. The most significant difference betwen LCD drivers in is the
- * manner in which the LCD is powered up and in how the power controls are set.
- * My suggestion is that if you have working LCD initialization code, you should
- * simply replace the code in mio283qt2_hwinitialize with your working code.
- */
-
-#if defined (CONFIG_MIO283QT2_PROFILE2)
-# undef MIO283QT2_USE_SIMPLE_INIT
-
- /* PWRCTRL1: AP=smalll-to-medium, DC=Flinex24, BT=+5/-4, DCT=Flinex24 */
-
-# define PWRCTRL1_SETTING \
- (MIO283QT2_PWRCTRL1_AP_SMMED | MIO283QT2_PWRCTRL1_DC_FLINEx24 | \
- MIO283QT2_PWRCTRL1_BT_p5m4 | MIO283QT2_PWRCTRL1_DCT_FLINEx24)
-
- /* PWRCTRL2: 5.1v */
-
-# define PWRCTRL2_SETTING MIO283QT2_PWRCTRL2_VRC_5p1V
-
- /* PWRCTRL3: x 2.165
- * NOTE: Many drivers have bit 8 set which is not defined in the MIO283QT2 spec.
- */
-
-# define PWRCTRL3_SETTING MIO283QT2_PWRCTRL3_VRH_x2p165
-
- /* PWRCTRL4: VDV=9 + VCOMG */
-
-# define PWRCTRL4_SETTING (MIO283QT2_PWRCTRL4_VDV(9) | MIO283QT2_PWRCTRL4_VCOMG)
-
- /* PWRCTRL5: VCM=56 + NOTP */
-
-# define PWRCTRL5_SETTING (MIO283QT2_PWRCTRL5_VCM(56) | MIO283QT2_PWRCTRL5_NOTP)
-
-#elif defined (CONFIG_MIO283QT2_PROFILE3)
-# undef MIO283QT2_USE_SIMPLE_INIT
-
- /* PWRCTRL1: AP=smalll-to-medium, DC=Flinex24, BT=+5/-4, DCT=Flinex24 */
-
-# define PWRCTRL1_SETTING \
- (MIO283QT2_PWRCTRL1_AP_SMMED | MIO283QT2_PWRCTRL1_DC_FLINEx24 | \
- MIO283QT2_PWRCTRL1_BT_p5m4 | MIO283QT2_PWRCTRL1_DCT_FLINEx24)
-
- /* PWRCTRL2: 5.1v */
-
-# define PWRCTRL2_SETTING MIO283QT2_PWRCTRL2_VRC_5p1V
-
- /* PWRCTRL3: x 2.165
- * NOTE: Many drivers have bit 8 set which is not defined in the MIO283QT2 spec.
- */
-
-# define PWRCTRL3_SETTING MIO283QT2_PWRCTRL3_VRH_x2p165
-
- /* PWRCTRL4: VDV=9 + VCOMG */
-
-# define PWRCTRL4_SETTING (MIO283QT2_PWRCTRL4_VDV(9) | MIO283QT2_PWRCTRL4_VCOMG)
-
- /* PWRCTRL5: VCM=56 + NOTP */
-
-# define PWRCTRL5_SETTING (MIO283QT2_PWRCTRL5_VCM(56) | MIO283QT2_PWRCTRL5_NOTP)
-
-#else /* if defined (CONFIG_MIO283QT2_PROFILE1) */
-# undef MIO283QT2_USE_SIMPLE_INIT
-# define MIO283QT2_USE_SIMPLE_INIT 1
-
- /* PWRCTRL1: AP=medium-to-large, DC=Fosc/4, BT=+5/-4, DCT=Fosc/4 */
-
-# define PWRCTRL1_SETTING \
- (MIO283QT2_PWRCTRL1_AP_MEDLG | MIO283QT2_PWRCTRL1_DC_FOSd4 | \
- MIO283QT2_PWRCTRL1_BT_p5m4 | MIO283QT2_PWRCTRL1_DCT_FOSd4)
-
- /* PWRCTRL2: 5.3v */
-
-# define PWRCTRL2_SETTING MIO283QT2_PWRCTRL2_VRC_5p3V
-
- /* PWRCTRL3: x 2.570
- * NOTE: Many drivers have bit 8 set which is not defined in the MIO283QT2 spec.
- */
-
-# define PWRCTRL3_SETTING MIO283QT2_PWRCTRL3_VRH_x2p570
-
- /* PWRCTRL4: VDV=12 + VCOMG */
-
-# define PWRCTRL4_SETTING (MIO283QT2_PWRCTRL4_VDV(12) | MIO283QT2_PWRCTRL4_VCOMG)
-
- /* PWRCTRL5: VCM=60 + NOTP */
-
-# define PWRCTRL5_SETTING (MIO283QT2_PWRCTRL5_VCM(60) | MIO283QT2_PWRCTRL5_NOTP)
-
-#endif
-
-/* Debug ******************************************************************************/
-
-#ifdef CONFIG_DEBUG_LCD
-# define lcddbg dbg
-# define lcdvdbg vdbg
-#else
-# define lcddbg(x...)
-# define lcdvdbg(x...)
-#endif
-
-/**************************************************************************************
- * Private Type Definition
- **************************************************************************************/
-
-/* This structure describes the state of this driver */
-
-struct mio283qt2_dev_s
-{
- /* Publically visible device structure */
-
- struct lcd_dev_s dev;
-
- /* Private LCD-specific information follows */
-
- FAR struct mio283qt2_lcd_s *lcd; /* The contained platform-specific, LCD interface */
- uint8_t power; /* Current power setting */
-
- /* This is working memory allocated by the LCD driver for each LCD device
- * and for each color plane. This memory will hold one raster line of data.
- * The size of the allocated run buffer must therefore be at least
- * (bpp * xres / 8). Actual alignment of the buffer must conform to the
- * bitwidth of the underlying pixel type.
- *
- * If there are multiple planes, they may share the same working buffer
- * because different planes will not be operate on concurrently. However,
- * if there are multiple LCD devices, they must each have unique run buffers.
- */
-
- uint16_t runbuffer[MIO283QT2_XRES];
-};
-
-/**************************************************************************************
- * Private Function Protototypes
- **************************************************************************************/
-/* Low Level LCD access */
-
-static void mio283qt2_putreg(FAR struct mio283qt2_lcd_s *lcd, uint8_t regaddr,
- uint16_t regval);
-#ifndef CONFIG_LCD_NOGETRUN
-static uint16_t mio283qt2_readreg(FAR struct mio283qt2_lcd_s *lcd, uint8_t regaddr);
-#endif
-static inline void mio283qt2_gramwrite(FAR struct mio283qt2_lcd_s *lcd,
- uint16_t rgbcolor);
-#ifndef CONFIG_LCD_NOGETRUN
-static inline void mio283qt2_readsetup(FAR struct mio283qt2_lcd_s *lcd,
- FAR uint16_t *accum);
-static inline uint16_t mio283qt2_gramread(FAR struct mio283qt2_lcd_s *lcd,
- FAR uint16_t *accum);
-#endif
-static void mio283qt2_setarea(FAR struct mio283qt2_lcd_s *lcd,
- uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
-
-/* LCD Data Transfer Methods */
-
-static int mio283qt2_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels);
-static int mio283qt2_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels);
-
-/* LCD Configuration */
-
-static int mio283qt2_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo);
-static int mio283qt2_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo);
-
-/* LCD RGB Mapping */
-
-#ifdef CONFIG_FB_CMAP
-# error "RGB color mapping not supported by this driver"
-#endif
-
-/* Cursor Controls */
-
-#ifdef CONFIG_FB_HWCURSOR
-# error "Cursor control not supported by this driver"
-#endif
-
-/* LCD Specific Controls */
-
-static int mio283qt2_getpower(FAR struct lcd_dev_s *dev);
-static int mio283qt2_setpower(FAR struct lcd_dev_s *dev, int power);
-static int mio283qt2_getcontrast(FAR struct lcd_dev_s *dev);
-static int mio283qt2_setcontrast(FAR struct lcd_dev_s *dev, unsigned int contrast);
-
-/* Initialization */
-
-static inline int mio283qt2_hwinitialize(FAR struct mio283qt2_dev_s *priv);
-
-/**************************************************************************************
- * Private Data
- **************************************************************************************/
-
-/* This driver can support only a signal MIO283QT2 device. This is due to an
- * unfortunate decision made whent he getrun and putrun methods were designed. The
- * following is the single MIO283QT2 driver state instance:
- */
-
-static struct mio283qt2_dev_s g_lcddev;
-
-/**************************************************************************************
- * Private Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: mio283qt2_putreg(lcd,
- *
- * Description:
- * Write to an LCD register
- *
- **************************************************************************************/
-
-static void mio283qt2_putreg(FAR struct mio283qt2_lcd_s *lcd,
- uint8_t regaddr, uint16_t regval)
-{
- /* Set the index register to the register address and write the register contents */
-
- lcd->index(lcd, regaddr);
- lcd->write(lcd, regval);
-}
-
-/**************************************************************************************
- * Name: mio283qt2_readreg
- *
- * Description:
- * Read from an LCD register
- *
- **************************************************************************************/
-
-#ifndef CONFIG_LCD_NOGETRUN
-static uint16_t mio283qt2_readreg(FAR struct mio283qt2_lcd_s *lcd, uint8_t regaddr)
-{
- /* Set the index register to the register address and read the register contents. */
-
- lcd->index(lcd, regaddr);
- return lcd->read(lcd);
-}
-#endif
-
-/**************************************************************************************
- * Name: mio283qt2_gramselect
- *
- * Description:
- * Setup to read or write multiple pixels to the GRAM memory
- *
- **************************************************************************************/
-
-static inline void mio283qt2_gramselect(FAR struct mio283qt2_lcd_s *lcd)
-{
- lcd->index(lcd, 0x22);
-}
-
-/**************************************************************************************
- * Name: mio283qt2_gramwrite
- *
- * Description:
- * Setup to read or write multiple pixels to the GRAM memory
- *
- **************************************************************************************/
-
-static inline void mio283qt2_gramwrite(FAR struct mio283qt2_lcd_s *lcd, uint16_t data)
-{
- lcd->write(lcd, data);
-}
-
-/**************************************************************************************
- * Name: mio283qt2_readsetup
- *
- * Description:
- * Prime the operation by reading one pixel from the GRAM memory if necessary for
- * this LCD type. When reading 16-bit gram data, there may be some shifts in the
- * returned data:
- *
- * - ILI932x: Discard first dummy read; no shift in the return data
- *
- **************************************************************************************/
-
-#ifndef CONFIG_LCD_NOGETRUN
-static inline void mio283qt2_readsetup(FAR struct mio283qt2_lcd_s *lcd,
- FAR uint16_t *accum)
-{
-#if 0 /* Probably not necessary... untested */
- /* Read-ahead one pixel */
-
- *accum = lcd->read(lcd);
-#endif
-}
-#endif
-
-/**************************************************************************************
- * Name: mio283qt2_gramread
- *
- * Description:
- * Read one correctly aligned pixel from the GRAM memory. Possibly shifting the
- * data and possibly swapping red and green components.
- *
- * - ILI932x: Unknown -- assuming colors are in the color order
- *
- **************************************************************************************/
-
-#ifndef CONFIG_LCD_NOGETRUN
-static inline uint16_t mio283qt2_gramread(FAR struct mio283qt2_lcd_s *lcd,
- FAR uint16_t *accum)
-{
- /* Read the value (GRAM register already selected) */
-
- return lcd->read(lcd);
-}
-#endif
-
-/**************************************************************************************
- * Name: mio283qt2_setarea
- *
- * Description:
- * Set the cursor position. In landscape mode, the "column" is actually the physical
- * Y position and the "row" is the physical X position.
- *
- **************************************************************************************/
-
-static void mio283qt2_setarea(FAR struct mio283qt2_lcd_s *lcd,
- uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
-{
- mio283qt2_putreg(lcd, 0x03, (x0 & 0x00ff)); /* set x0 */
- mio283qt2_putreg(lcd, 0x02, (x0 >> 8)); /* set x0 */
- mio283qt2_putreg(lcd, 0x05, (x1 & 0x00ff)); /* set x1 */
- mio283qt2_putreg(lcd, 0x04, (x1 >> 8)); /* set x1 */
- mio283qt2_putreg(lcd, 0x07, (y0 & 0x00ff)); /* set y0 */
- mio283qt2_putreg(lcd, 0x06, (y0 >> 8)); /* set y0 */
- mio283qt2_putreg(lcd, 0x09, (y1 & 0x00ff)); /* set y1 */
- mio283qt2_putreg(lcd, 0x08, (y1 >> 8)); /* set y1 */
-}
-
-/**************************************************************************************
- * Name: mio283qt2_dumprun
- *
- * Description:
- * Dump the contexts of the run buffer:
- *
- * run - The buffer in containing the run read to be dumped
- * npixels - The number of pixels to dump
- *
- **************************************************************************************/
-
-#if 0 /* Sometimes useful */
-static void mio283qt2_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npixels)
-{
- int i, j;
-
- syslog("\n%s:\n", msg);
- for (i = 0; i < npixels; i += 16)
- {
- up_putc(' ');
- syslog(" ");
- for (j = 0; j < 16; j++)
- {
- syslog(" %04x", *run++);
- }
- up_putc('\n');
- }
-}
-#endif
-
-/**************************************************************************************
- * Name: mio283qt2_putrun
- *
- * Description:
- * This method can be used to write a partial raster line to the LCD:
- *
- * row - Starting row to write to (range: 0 <= row < yres)
- * col - Starting column to write to (range: 0 <= col <= xres-npixels)
- * buffer - The buffer containing the run to be written to the LCD
- * npixels - The number of pixels to write to the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-static int mio283qt2_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels)
-{
- FAR struct mio283qt2_dev_s *priv = &g_lcddev;
- FAR struct mio283qt2_lcd_s *lcd = priv->lcd;
- FAR const uint16_t *src = (FAR const uint16_t*)buffer;
- int i;
-
- /* Buffer must be provided and aligned to a 16-bit address boundary */
-
- lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
-
- /* Select the LCD */
-
- lcd->select(lcd);
-
- /* Write the run to GRAM. */
-
- mio283qt2_setarea(lcd, col, row, col + npixels - 1, row);
- mio283qt2_gramselect(lcd);
-
- for (i = 0; i < npixels; i++)
- {
- mio283qt2_gramwrite(lcd, *src);
- src++;
- }
-
- /* De-select the LCD */
-
- lcd->deselect(lcd);
- return OK;
-}
-
-/**************************************************************************************
- * Name: mio283qt2_getrun
- *
- * Description:
- * This method can be used to read a partial raster line from the LCD:
- *
- * row - Starting row to read from (range: 0 <= row < yres)
- * col - Starting column to read read (range: 0 <= col <= xres-npixels)
- * buffer - The buffer in which to return the run read from the LCD
- * npixels - The number of pixels to read from the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-static int mio283qt2_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels)
-{
-#ifndef CONFIG_LCD_NOGETRUN
- FAR struct mio283qt2_dev_s *priv = &g_lcddev;
- FAR struct mio283qt2_lcd_s *lcd = priv->lcd;
- FAR uint16_t *dest = (FAR uint16_t*)buffer;
- uint16_t accum;
- int i;
-
- /* Buffer must be provided and aligned to a 16-bit address boundary */
-
- lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
-
- /* Select the LCD */
-
- lcd->select(lcd);
-
- /* Read the run from GRAM. */
-
- /* Select the LCD */
-
- lcd->select(lcd);
-
- /* Red the run fram GRAM. */
-
- mio283qt2_setarea(lcd, col, row, col + npixels - 1, row);
- mio283qt2_gramselect(lcd);
-
- /* Prime the pump for unaligned read data */
-
- mio283qt2_readsetup(lcd, &accum);
-
- for (i = 0; i < npixels; i++)
- {
- *dest++ = mio283qt2_gramread(lcd, &accum);
- }
-
- /* De-select the LCD */
-
- lcd->deselect(lcd);
- return OK;
-#else
- return -ENOSYS;
-#endif
-}
-
-/**************************************************************************************
- * Name: mio283qt2_getvideoinfo
- *
- * Description:
- * Get information about the LCD video controller configuration.
- *
- **************************************************************************************/
-
-static int mio283qt2_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo)
-{
- DEBUGASSERT(dev && vinfo);
- lcdvdbg("fmt: %d xres: %d yres: %d nplanes: 1\n",
- MIO283QT2_COLORFMT, MIO283QT2_XRES, MIO283QT2_XRES);
-
- vinfo->fmt = MIO283QT2_COLORFMT; /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
- vinfo->xres = MIO283QT2_XRES; /* Horizontal resolution in pixel columns */
- vinfo->yres = MIO283QT2_YRES; /* Vertical resolution in pixel rows */
- vinfo->nplanes = 1; /* Number of color planes supported */
- return OK;
-}
-
-/**************************************************************************************
- * Name: mio283qt2_getplaneinfo
- *
- * Description:
- * Get information about the configuration of each LCD color plane.
- *
- **************************************************************************************/
-
-static int mio283qt2_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo)
-{
- FAR struct mio283qt2_dev_s *priv = (FAR struct mio283qt2_dev_s *)dev;
-
- DEBUGASSERT(dev && pinfo && planeno == 0);
- lcdvdbg("planeno: %d bpp: %d\n", planeno, MIO283QT2_BPP);
-
- pinfo->putrun = mio283qt2_putrun; /* Put a run into LCD memory */
- pinfo->getrun = mio283qt2_getrun; /* Get a run from LCD memory */
- pinfo->buffer = (uint8_t*)priv->runbuffer; /* Run scratch buffer */
- pinfo->bpp = MIO283QT2_BPP; /* Bits-per-pixel */
- return OK;
-}
-
-/**************************************************************************************
- * Name: mio283qt2_getpower
- *
- * Description:
- * 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.
- *
- **************************************************************************************/
-
-static int mio283qt2_getpower(FAR struct lcd_dev_s *dev)
-{
- lcdvdbg("power: %d\n", 0);
- return g_lcddev.power;
-}
-
-/**************************************************************************************
- * Name: mio283qt2_poweroff
- *
- * Description:
- * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On
- * backlit LCDs, this setting may correspond to the backlight setting.
- *
- **************************************************************************************/
-
-static int mio283qt2_poweroff(FAR struct mio283qt2_lcd_s *lcd)
-{
- /* Set the backlight off */
-
- lcd->backlight(lcd, 0);
-
- /* Turn the display off */
-
- mio283qt2_putreg(lcd, 0x28, 0x0000); /* GON=0, DTE=0, D=0 */
-
- /* Remember the power off state */
-
- g_lcddev.power = 0;
- return OK;
-}
-
-/**************************************************************************************
- * Name: mio283qt2_setpower
- *
- * Description:
- * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On
- * backlit LCDs, this setting may correspond to the backlight setting.
- *
- **************************************************************************************/
-
-static int mio283qt2_setpower(FAR struct lcd_dev_s *dev, int power)
-{
- FAR struct mio283qt2_dev_s *priv = (FAR struct mio283qt2_dev_s *)dev;
- FAR struct mio283qt2_lcd_s *lcd = priv->lcd;
-
- lcdvdbg("power: %d\n", power);
- DEBUGASSERT((unsigned)power <= CONFIG_LCD_MAXPOWER);
-
- /* Set new power level */
-
- if (power > 0)
- {
- /* Set the backlight level */
-
- lcd->backlight(lcd, power);
-
- /* Then turn the display on:
- * D=ON(3) CM=0 DTE=1 GON=1 SPT=0 VLE=0 PT=0
- */
-
- /* Display on */
-
- mio283qt2_putreg(lcd, 0x28, 0x0038); /* GON=1, DTE=1, D=2 */
- up_mdelay(40);
- mio283qt2_putreg(lcd, 0x28, 0x003c); /* GON=1, DTE=1, D=3 */
-
- g_lcddev.power = power;
- }
- else
- {
- /* Turn the display off */
-
- mio283qt2_poweroff(lcd);
- }
-
- return OK;
-}
-
-/**************************************************************************************
- * Name: mio283qt2_getcontrast
- *
- * Description:
- * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int mio283qt2_getcontrast(FAR struct lcd_dev_s *dev)
-{
- lcdvdbg("Not implemented\n");
- return -ENOSYS;
-}
-
-/**************************************************************************************
- * Name: mio283qt2_setcontrast
- *
- * Description:
- * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int mio283qt2_setcontrast(FAR struct lcd_dev_s *dev, unsigned int contrast)
-{
- lcdvdbg("contrast: %d\n", contrast);
- return -ENOSYS;
-}
-
-/**************************************************************************************
- * Name: mio283qt2_hwinitialize
- *
- * Description:
- * Initialize the LCD hardware.
- *
- **************************************************************************************/
-
-static inline int mio283qt2_hwinitialize(FAR struct mio283qt2_dev_s *priv)
-{
- FAR struct mio283qt2_lcd_s *lcd = priv->lcd;
-#ifndef CONFIG_LCD_NOGETRUN
- uint16_t id;
-#endif
-
- /* Select the LCD */
-
- lcd->select(lcd);
-
- /* Read the HIMAX ID registger (0x00) */
-
-#ifndef CONFIG_LCD_NOGETRUN
- id = mio283qt2_readreg(lcd, 0x00);
- lcddbg("LCD ID: %04x\n", id);
-
- /* Check if the ID is for the MIO283QT2 */
-
- if (id == HIMAX_ID)
-#endif
- {
- /* Driving ability */
-
- mio283qt2_putreg(lcd, 0xea, 0x0000); /* PTBA[15:8] */
- mio283qt2_putreg(lcd, 0xeb, 0x0020); /* PTBA[7:0] */
- mio283qt2_putreg(lcd, 0xec, 0x000c); /* STBA[15:8] */
- mio283qt2_putreg(lcd, 0xed, 0x00c4); /* STBA[7:0] */
- mio283qt2_putreg(lcd, 0xe8, 0x0040); /* OPON[7:0] */
- mio283qt2_putreg(lcd, 0xe9, 0x0038); /* OPON1[7:0] */
- mio283qt2_putreg(lcd, 0xf1, 0x0001); /* OTPS1B */
- mio283qt2_putreg(lcd, 0xf2, 0x0010); /* GEN */
- mio283qt2_putreg(lcd, 0x27, 0x00a3);
-
- /* Power voltage */
-
- mio283qt2_putreg(lcd, 0x1b, 0x001b); /* VRH = 4.65 */
- mio283qt2_putreg(lcd, 0x1a, 0x0001); /* BT */
- mio283qt2_putreg(lcd, 0x24, 0x002f); /* VMH */
- mio283qt2_putreg(lcd, 0x25, 0x0057); /* VML */
-
- /* Vcom offset */
-
- mio283qt2_putreg(lcd, 0x23, 0x008d); /* For flicker adjust */
-
- /* Power on */
-
- mio283qt2_putreg(lcd, 0x18, 0x0036);
- mio283qt2_putreg(lcd, 0x19, 0x0001); /* Start oscillator */
- mio283qt2_putreg(lcd, 0x01, 0x0000); /* Wakeup */
- mio283qt2_putreg(lcd, 0x1f, 0x0088);
- up_mdelay(5);
- mio283qt2_putreg(lcd, 0x1f, 0x0080);
- up_mdelay(5);
- mio283qt2_putreg(lcd, 0x1f, 0x0090);
- up_mdelay(5);
- mio283qt2_putreg(lcd, 0x1f, 0x00d0);
- up_mdelay(5);
-
- /* Gamma 2.8 setting */
-
- mio283qt2_putreg(lcd, 0x40, 0x0000);
- mio283qt2_putreg(lcd, 0x41, 0x0000);
- mio283qt2_putreg(lcd, 0x42, 0x0001);
- mio283qt2_putreg(lcd, 0x43, 0x0013);
- mio283qt2_putreg(lcd, 0x44, 0x0010);
- mio283qt2_putreg(lcd, 0x45, 0x0026);
- mio283qt2_putreg(lcd, 0x46, 0x0008);
- mio283qt2_putreg(lcd, 0x47, 0x0051);
- mio283qt2_putreg(lcd, 0x48, 0x0002);
- mio283qt2_putreg(lcd, 0x49, 0x0012);
- mio283qt2_putreg(lcd, 0x4a, 0x0018);
- mio283qt2_putreg(lcd, 0x4b, 0x0019);
- mio283qt2_putreg(lcd, 0x4c, 0x0014);
-
- mio283qt2_putreg(lcd, 0x50, 0x0019);
- mio283qt2_putreg(lcd, 0x51, 0x002f);
- mio283qt2_putreg(lcd, 0x52, 0x002c);
- mio283qt2_putreg(lcd, 0x53, 0x003e);
- mio283qt2_putreg(lcd, 0x54, 0x003f);
- mio283qt2_putreg(lcd, 0x55, 0x003f);
- mio283qt2_putreg(lcd, 0x56, 0x002e);
- mio283qt2_putreg(lcd, 0x57, 0x0077);
- mio283qt2_putreg(lcd, 0x58, 0x000b);
- mio283qt2_putreg(lcd, 0x59, 0x0006);
- mio283qt2_putreg(lcd, 0x5a, 0x0007);
- mio283qt2_putreg(lcd, 0x5b, 0x000d);
- mio283qt2_putreg(lcd, 0x5c, 0x001d);
- mio283qt2_putreg(lcd, 0x5d, 0x00cc);
-
- /* 4K Color Selection */
-
- mio283qt2_putreg(lcd, 0x17, 0x0003);
- mio283qt2_putreg(lcd, 0x17, 0x0005); /* 0x0005=65k, 0x0006=262k */
-
- /* Panel characteristics */
-
- mio283qt2_putreg(lcd, 0x36, 0x0000);
-
- /* Display Setting */
-
- mio283qt2_putreg(lcd, 0x01, 0x0000); /* IDMON=0, INVON=0, NORON=0, PTLON=0 */
-
-#if defined(CONFIG_LCD_LANDSCAPE)
- mio283qt2_putreg(lcd, 0x16, 0x00a8); /* MY=1, MX=0, MV=1, ML=0, BGR=1 */
-#elif defined(CONFIG_LCD_PORTRAIT)
- mio283qt2_putreg(lcd, 0x16, 0x0008); /* MY=0, MX=0, MV=0, ML=0, BGR=1 */
-#elif defined(CONFIG_LCD_RLANDSCAPE)
- mio283qt2_putreg(lcd, 0x16, 0x0068); /* MY=0, MX=1, MV=1, ML=0, BGR=1 */
-#elif defined(CONFIG_LCD_RPORTRAIT)
- mio283qt2_putreg(lcd, 0x16, 0x00c8); /* MY=1, MX=0, MV=1, ML=0, BGR=1 */
-#endif
-
- /* Window setting */
-
- mio283qt2_setarea(lcd, 0, 0, (MIO283QT2_XRES-1), (MIO283QT2_YRES-1));
- return OK;
- }
-#ifndef CONFIG_LCD_NOGETRUN
- else
- {
- lcddbg("Unsupported LCD type\n");
- return -ENODEV;
- }
-#endif
-
- /* De-select the LCD */
-
- lcd->deselect(lcd);
-}
-
- /*************************************************************************************
- * Public Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: mio283qt2_lcdinitialize
- *
- * Description:
- * Initialize the LCD video hardware. The initial state of the LCD is fully
- * initialized, display memory cleared, and the LCD ready to use, but with the power
- * setting at 0 (full off).
- *
- **************************************************************************************/
-
-FAR struct lcd_dev_s *mio283qt2_lcdinitialize(FAR struct mio283qt2_lcd_s *lcd)
-{
- int ret;
-
- lcdvdbg("Initializing\n");
-
- /* If we ccould support multiple MIO283QT2 devices, this is where we would allocate
- * a new driver data structure... but we can't. Why not? Because of a bad should
- * the form of the getrun() and putrun methods.
- */
-
- FAR struct mio283qt2_dev_s *priv = &g_lcddev;
-
- /* Initialize the driver data structure */
-
- priv->dev.getvideoinfo = mio283qt2_getvideoinfo;
- priv->dev.getplaneinfo = mio283qt2_getplaneinfo;
- priv->dev.getpower = mio283qt2_getpower;
- priv->dev.setpower = mio283qt2_setpower;
- priv->dev.getcontrast = mio283qt2_getcontrast;
- priv->dev.setcontrast = mio283qt2_setcontrast;
- priv->lcd = lcd;
-
- /* Configure and enable LCD */
-
- ret = mio283qt2_hwinitialize(priv);
- if (ret == OK)
- {
- /* Clear the display (setting it to the color 0=black) */
-
- mio283qt2_clear(&priv->dev, 0);
-
- /* Turn the display off */
-
- mio283qt2_poweroff(lcd);
- return &g_lcddev.dev;
- }
-
- return NULL;
-}
-
-/**************************************************************************************
- * Name: mio283qt2_clear
- *
- * Description:
- * This is a non-standard LCD interface just for the stm3240g-EVAL board. Because
- * of the various rotations, clearing the display in the normal way by writing a
- * sequences of runs that covers the entire display can be very slow. Here the
- * display is cleared by simply setting all GRAM memory to the specified color.
- *
- **************************************************************************************/
-
-void mio283qt2_clear(FAR struct lcd_dev_s *dev, uint16_t color)
-{
- FAR struct mio283qt2_dev_s *priv = (FAR struct mio283qt2_dev_s *)dev;
- FAR struct mio283qt2_lcd_s *lcd = priv->lcd;
- uint32_t i;
-
- /* Select the LCD and set the drawring area */
-
- lcd->select(lcd);
- mio283qt2_setarea(lcd, 0, 0, (MIO283QT2_XRES-1), (MIO283QT2_YRES-1));
-
- /* Prepare to write GRAM data */
-
- mio283qt2_gramselect(lcd);
-
- /* Copy color into all of GRAM. Orientation does not matter in this case. */
-
- for (i = 0; i < MIO283QT2_XRES * MIO283QT2_YRES; i++)
- {
- mio283qt2_gramwrite(lcd, color);
- }
-
- /* De-select the LCD */
-
- lcd->deselect(lcd);
-}
-
-#endif /* CONFIG_LCD_MIO283QT2 */
diff --git a/nuttx/drivers/lcd/nokia6100.c b/nuttx/drivers/lcd/nokia6100.c
deleted file mode 100644
index 7354b8a91..000000000
--- a/nuttx/drivers/lcd/nokia6100.c
+++ /dev/null
@@ -1,1230 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/nokia6100.c
- * Nokia 6100 LCD Display Driver
- *
- * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * "Nokia 6100 LCD Display Driver," Revision 1, James P. Lynch ("Nokia 6100 LCD
- * Display Driver.pdf")
- * "S1D15G0D08B000," Seiko Epson Corportation, 2002.
- * "Data Sheet, PCF8833 STN RGB 132x132x3 driver," Phillips, 2003 Feb 14.
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/spi.h>
-#include <nuttx/lcd/lcd.h>
-#include <nuttx/lcd/nokia6100.h>
-
-#ifdef CONFIG_NOKIA6100_PCF8833
-# include "pcf8833.h"
-#endif
-#ifdef CONFIG_NOKIA6100_S1D15G10
-# include "s1d15g10.h"
-#endif
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-
-/* Configuration **********************************************************************/
-/* Verify that all configuration requirements have been met */
-
-/* Nokia 6100 Configuration Settings:
- *
- * CONFIG_NOKIA6100_SPIMODE - Controls the SPI mode
- * CONFIG_NOKIA6100_FREQUENCY - Define to use a different bus frequency
- * CONFIG_NOKIA6100_NINTERFACES - Specifies the number of physical Nokia 6100 devices that
- * will be supported.
- * CONFIG_NOKIA6100_BPP - Device supports 8, 12, and 16 bits per pixel.
- * CONFIG_NOKIA6100_S1D15G10 - Selects the Epson S1D15G10 display controller
- * CONFIG_NOKIA6100_PCF8833 - Selects the Phillips PCF8833 display controller
- * CONFIG_NOKIA6100_BLINIT - Initial backlight setting
- *
- * The following may need to be tuned for your hardware:
- * CONFIG_NOKIA6100_INVERT - Display inversion, 0 or 1, Default: 1
- * CONFIG_NOKIA6100_MY - Display row direction, 0 or 1, Default: 0
- * CONFIG_NOKIA6100_MX - Display column direction, 0 or 1, Default: 1
- * CONFIG_NOKIA6100_V - Display address direction, 0 or 1, Default: 0
- * CONFIG_NOKIA6100_ML - Display scan direction, 0 or 1, Default: 0
- * CONFIG_NOKIA6100_RGBORD - Display RGB order, 0 or 1, Default: 0
- *
- * Required LCD driver settings:
- * CONFIG_LCD_NOKIA6100 - Enable Nokia 6100 support
- * CONFIG_LCD_MAXCONTRAST - must be 63 with the Epson controller and 127 with
- * the Phillips controller.
- * CONFIG_LCD_MAXPOWER - Maximum value of backlight setting. The backlight control is
- * managed outside of the 6100 driver so this value has no meaning to the driver.
- */
-
-/* Mode 0,0 should be use. However, somtimes you need to tinker with these things. */
-
-#ifndef CONFIG_NOKIA6100_SPIMODE
-# define CONFIG_NOKIA6100_SPIMODE SPIDEV_MODE0
-#endif
-
-/* Default frequency: 1Mhz */
-
-#ifndef CONFIG_NOKIA6100_FREQUENCY
-# define CONFIG_NOKIA6100_FREQUENCY 1000000
-#endif
-
-/* CONFIG_NOKIA6100_NINTERFACES determines the number of physical interfaces
- * that will be supported.
- */
-
-#ifndef CONFIG_NOKIA6100_NINTERFACES
-# define CONFIG_NOKIA6100_NINTERFACES 1
-#endif
-
-#if CONFIG_NOKIA6100_NINTERFACES != 1
-# error "This implementation supports only a single LCD device"
-#endif
-
-/* Only support for 8 and 12 BPP currently implemented */
-
-#if !defined(CONFIG_NOKIA6100_BPP)
-# warning "Assuming 8BPP"
-# define CONFIG_NOKIA6100_BPP 8
-#endif
-
-#if CONFIG_NOKIA6100_BPP != 8 && CONFIG_NOKIA6100_BPP != 12
-# if CONFIG_NOKIA6100_BPP == 16
-# error "Support for 16BPP no yet implemented"
-# else
-# error "LCD supports only 8, 12, and 16BPP"
-# endif
-#endif
-
-#if CONFIG_NOKIA6100_BPP == 8
-# ifdef CONFIG_NX_DISABLE_8BPP
-# warning "8-bit pixel support needed"
-# endif
-#elif CONFIG_NOKIA6100_BPP == 12
-# if defined(CONFIG_NX_DISABLE_12BPP) || !defined(CONFIG_NX_PACKEDMSFIRST)
-# warning "12-bit, big-endian pixel support needed"
-# endif
-#elif CONFIG_NOKIA6100_BPP == 16
-# ifdef CONFIG_NX_DISABLE_16BPP
-# warning "16-bit pixel support needed"
-# endif
-#endif
-
-/* Exactly one LCD controller must be selected. "The Olimex boards have both display
- * controllers possible; if the LCD has a GE-12 sticker on it, it’s a Philips PCF8833.
- * If it has a GE-8 sticker, it’s an Epson controller."
- */
-
-#if defined(CONFIG_NOKIA6100_S1D15G10) && defined(CONFIG_NOKIA6100_PCF8833)
-# error "Both CONFIG_NOKIA6100_S1D15G10 and CONFIG_NOKIA6100_PCF8833 are defined"
-#endif
-
-#if !defined(CONFIG_NOKIA6100_S1D15G10) && !defined(CONFIG_NOKIA6100_PCF8833)
-# error "One of CONFIG_NOKIA6100_S1D15G10 or CONFIG_NOKIA6100_PCF8833 must be defined"
-#endif
-
-/* Delay geometry defaults */
-
-#ifndef CONFIG_NOKIA6100_INVERT
-# define CONFIG_NOKIA6100_INVERT 1
-#endif
-
-#ifndef CONFIG_NOKIA6100_MY
-# define CONFIG_NOKIA6100_MY 0
-#endif
-
-#ifndef CONFIG_NOKIA6100_MX
-# define CONFIG_NOKIA6100_MX 1
-#endif
-
-#ifndef CONFIG_NOKIA6100_V
-# define CONFIG_NOKIA6100_V 0
-#endif
-
-#ifndef CONFIG_NOKIA6100_ML
-# define CONFIG_NOKIA6100_ML 0
-#endif
-
-#ifndef CONFIG_NOKIA6100_RGBORD
-# define CONFIG_NOKIA6100_RGBORD 0
-#endif
-
-/* Check contrast selection */
-
-#ifdef CONFIG_NOKIA6100_S1D15G10
-
-# if !defined(CONFIG_LCD_MAXCONTRAST)
-# define CONFIG_LCD_MAXCONTRAST 63
-# endif
-# if CONFIG_LCD_MAXCONTRAST != 63
-# error "CONFIG_LCD_MAXCONTRAST must be 63 with the Epson LCD controller"
-# endif
-# define NOKIA_DEFAULT_CONTRAST 32
-
-#else /* CONFIG_NOKIA6100_PCF8833 */
-
-# if !defined(CONFIG_LCD_MAXCONTRAST)
-# define CONFIG_LCD_MAXCONTRAST 127
-# endif
-# if CONFIG_LCD_MAXCONTRAST != 127
-# error "CONFIG_LCD_MAXCONTRAST must be 127 with the Phillips LCD controller"
-# endif
-# define NOKIA_DEFAULT_CONTRAST 48
-
-#endif
-
-/* Check initial backlight setting */
-
-#ifndef CONFIG_NOKIA6100_BLINIT
-# define CONFIG_NOKIA6100_BLINIT (NOKIA_DEFAULT_CONTRAST/3)
-#endif
-
-/* Word width must be 9 bits */
-
-#if defined(CONFIG_NOKIA6100_WORDWIDTH) && CONFIG_NOKIA6100_WORDWIDTH != 9
-# error "CONFIG_NOKIA6100_WORDWIDTH must be 9"
-#endif
-#ifndef CONFIG_NOKIA6100_WORDWIDTH
-# define CONFIG_NOKIA6100_WORDWIDTH 9
-#endif
-
-/* If bit 9 is set, the byte is data; clear for commands */
-
-#define NOKIA_LCD_DATA (1 << 8)
-
-/* Define CONFIG_LCD_REGDEBUG to enable register-level debug output.
- * (Verbose debug must also be enabled)
- */
-
-#ifndef CONFIG_DEBUG
-# undef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_DEBUG_GRAPHICS
-#endif
-
-#ifndef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_LCD_REGDEBUG
-#endif
-
-/* Controller independent definitions *************************************************/
-
-#ifdef CONFIG_NOKIA6100_PCF8833
-# define LCD_NOP PCF8833_NOP
-# define LCD_RAMWR PCF8833_RAMWR
-# define LCD_PASET PCF8833_PASET
-# define LCD_CASET PCF8833_CASET
-#endif
-#ifdef CONFIG_NOKIA6100_S1D15G10
-# define LCD_NOP S1D15G10_NOP
-# define LCD_RAMWR S1D15G10_RAMWR
-# define LCD_PASET S1D15G10_PASET
-# define LCD_CASET S1D15G10_CASET
-#endif
-
-/* Color Properties *******************************************************************/
-
-/* Display Resolution */
-
-#define NOKIA_XRES 132
-#define NOKIA_YRES 132
-
-/* Color depth and format */
-
-#if CONFIG_NOKIA6100_BPP == 8
-# define NOKIA_BPP 8
-# define NOKIA_COLORFMT FB_FMT_RGB8_332
-# define NOKIA_STRIDE NOKIA_XRES
-# define NOKIA_PIX2BYTES(p) (p)
-#elif CONFIG_NOKIA6100_BPP == 12
-# define NOKIA_BPP 12
-# define NOKIA_COLORFMT FB_FMT_RGB12_444
-# define NOKIA_STRIDE ((3*NOKIA_XRES+1)/2)
-# define NOKIA_PIX2BYTES(p) ((3*(p)+1)/2)
-#elif CONFIG_NOKIA6100_BPP == 16
-# define NOKIA_BPP 16
-# define NOKIA_COLORFMT FB_FMT_RGB16_565
-# define NOKIA_STRIDE (2*NOKIA_XRES)
-# define NOKIA_PIX2BYTES(p) (2*(p))
-#endif
-
-/* Handle any potential strange behavior at edges */
-
-#if 0 /* REVISIT */
-#define NOKIA_PGBIAS 2 /* May not be necessary */
-#define NOKIA_COLBIAS 0
-#define NOKIA_XBIAS 2 /* May not be necessary, if so need to subtract from XRES */
-#define NOKIA_YBIAS 0
-#else
-#define NOKIA_PGBIAS 0
-#define NOKIA_COLBIAS 0
-#define NOKIA_XBIAS 0
-#define NOKIA_YBIAS 0
-#endif
-
-#define NOKIA_ENDPAGE 131
-#define NOKIA_ENDCOL 131
-
-/* Debug ******************************************************************************/
-
-#ifdef CONFIG_LCD_REGDEBUG
-# define lcddbg(format, arg...) llvdbg(format, ##arg)
-#else
-# define lcddbg(x...)
-#endif
-
-/**************************************************************************************
- * Private Type Definition
- **************************************************************************************/
-
-/* This structure describes the state of this driver */
-
-struct nokia_dev_s
-{
- /* Publically visible device structure */
-
- struct lcd_dev_s dev;
-
- /* Private LCD-specific information follows */
-
- FAR struct spi_dev_s *spi; /* Contained SPI driver instance */
- uint8_t contrast; /* Current contrast setting */
- uint8_t power; /* Current power (backlight) setting */
-};
-
-/**************************************************************************************
- * Private Function Protototypes
- **************************************************************************************/
-
-/* SPI support */
-
-static inline void nokia_configspi(FAR struct spi_dev_s *spi);
-#ifdef CONFIG_SPI_OWNBUS
-static inline void nokia_select(FAR struct spi_dev_s *spi);
-static inline void nokia_deselect(FAR struct spi_dev_s *spi);
-#else
-static void nokia_select(FAR struct spi_dev_s *spi);
-static void nokia_deselect(FAR struct spi_dev_s *spi);
-#endif
-static void nokia_sndcmd(FAR struct spi_dev_s *spi, const uint8_t cmd);
-static void nokia_cmdarray(FAR struct spi_dev_s *spi, int len, const uint8_t *cmddata);
-static void nokia_clrram(FAR struct spi_dev_s *spi);
-
-/* LCD Data Transfer Methods */
-
-static int nokia_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels);
-static int nokia_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels);
-
-/* LCD Configuration */
-
-static int nokia_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo);
-static int nokia_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo);
-
-/* LCD RGB Mapping */
-
-#ifdef CONFIG_FB_CMAP
-# error "RGB color mapping not supported by this driver"
-#endif
-
-/* Cursor Controls */
-
-#ifdef CONFIG_FB_HWCURSOR
-# error "Cursor control not supported by this driver"
-#endif
-
-/* LCD Specific Controls */
-
-static int nokia_getpower(struct lcd_dev_s *dev);
-static int nokia_setpower(struct lcd_dev_s *dev, int power);
-static int nokia_getcontrast(struct lcd_dev_s *dev);
-static int nokia_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
-
-/* Initialization */
-
-static int nokia_initialize(struct nokia_dev_s *priv);
-
-/**************************************************************************************
- * Private Data
- **************************************************************************************/
-
-/* This is working memory allocated by the LCD driver for each LCD device
- * and for each color plane. This memory will hold one raster line of data.
- * The size of the allocated run buffer must therefore be at least
- * (bpp * xres / 8). Actual alignment of the buffer must conform to the
- * bitwidth of the underlying pixel type.
- *
- * If there are multiple planes, they may share the same working buffer
- * because different planes will not be operate on concurrently. However,
- * if there are multiple LCD devices, they must each have unique run buffers.
- */
-
-#if CONFIG_NOKIA6100_BPP == 8
-static uint8_t g_runbuffer[NOKIA_XRES];
-#elif CONFIG_NOKIA6100_BPP == 12
-static uint8_t g_runbuffer[(3*NOKIA_XRES+1)/2];
-#else /* CONFIG_NOKIA6100_BPP == 16 */
-static uint16_t g_runbuffer[NOKIA_XRES];
-#endif
-
-/* g_rowbuf is another buffer, but used internally by the Nokia 6100 driver in order
- * expand the pixel data into 9-bit data needed by the LCD. There are some
- * customizations that would eliminate the need for this extra buffer and for the
- * extra expansion/copy, but those customizations would require a special, non-standard
- * SPI driver that could expand 8- to 9-bit data on the fly.
- */
-
-static uint16_t g_rowbuf[NOKIA_STRIDE+1];
-
-/* Device Driver Data Structures ******************************************************/
-
-/* This structure describes the overall LCD video controller */
-
-static const struct fb_videoinfo_s g_videoinfo =
-{
- .fmt = NOKIA_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
- .xres = NOKIA_XRES, /* Horizontal resolution in pixel columns */
- .yres = NOKIA_YRES, /* Vertical resolution in pixel rows */
- .nplanes = 1, /* Number of color planes supported */
-};
-
-/* This is the standard, NuttX Plane information object */
-
-static const struct lcd_planeinfo_s g_planeinfo =
-{
- .putrun = nokia_putrun, /* Put a run into LCD memory */
- .getrun = nokia_getrun, /* Get a run from LCD memory */
- .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */
- .bpp = NOKIA_BPP, /* Bits-per-pixel */
-};
-
-/* This is the standard, NuttX LCD driver object */
-
-static struct nokia_dev_s g_lcddev =
-{
- .dev =
- {
- /* LCD Configuration */
-
- .getvideoinfo = nokia_getvideoinfo,
- .getplaneinfo = nokia_getplaneinfo,
-
- /* LCD RGB Mapping -- Not supported */
- /* Cursor Controls -- Not supported */
-
- /* LCD Specific Controls */
-
- .getpower = nokia_getpower,
- .setpower = nokia_setpower,
- .getcontrast = nokia_getcontrast,
- .setcontrast = nokia_setcontrast,
- },
-};
-
-/* LCD Command Strings ****************************************************************/
-
-#ifdef CONFIG_NOKIA6100_S1D15G10
-/* Display control:
- * P1: Specifies the CL dividing ratio, F1 and F2 drive-pattern switching period.
- * P2: Specifies the duty of the module on block basis
- * P3: Specify number of lines to be inversely highlighted on LCD panel
- * P4: 0: Dispersion P40= 1: Non-dispersion
- */
-
-#if 1 // CONFIG_NOKIA6100_BPP == 12
-static const uint8_t g_disctl[] =
-{
- S1D15G10_DISCTL, /* Display control */
- DISCTL_CLDIV_2|DISCTL_PERIOD_8, /* P1: Divide clock by 2; switching period = 8 */
-//DISCTL_CLDIV_NONE|DISCTL_PERIOD_8, /* P1: No clock division; switching period = 8 */
- 32, /* P2: nlines/4 - 1 = 132/4 - 1 = 32 */
- 0, /* P3: No inversely highlighted lines */
- 0 /* P4: No disperion */
-};
-#else /* CONFIG_NOKIA6100_BPP == 8 */
-static const uint8_t g_disctl[] =
-{
- S1D15G10_DISCTL, /* Display control */
- DISCTL_CLDIV_2|DISCTL_PERIOD_FLD, /* P1: Divide clock by 2; switching period = field */
- 32, /* P2: nlines/4 - 1 = 132/4 - 1 = 32 */
- 0, /* P3: No inversely highlighted lines */
- 0 /* P4: No disperion */
-};
-#endif
-
-/* Common scan direction:
- * P1: Cpecify the common output scan direction.
- */
-
-static const uint8_t g_comscn[] =
-{
- S1D15G10_COMSCN, /* Common scan direction */
- 1 /* 0x01 = Scan 1->68, 132<-69 */
-};
-
-/* Power control:
- * P1: Turn on or off the liquid crystal driving power circuit, booster/step-down
- * circuits and voltage follower circuit.
- */
-
-static const uint8_t g_pwrctr[] =
-{
- S1D15G10_PWRCTR, /* Power control */
- PWCTR_REFVOLTAGE|PWCTR_REGULATOR|PWCTR_BOOSTER2|PWCTR_BOOSTER1
-};
-
-/* Data control:
- * P1: Specify the normal or inverse display of the page address and also to specify
- * the page address scanning direction
- * P2: RGB sequence
- * P3: Grayscale setup
- */
-
-static const uint8_t g_datctl[] =
-{
- S1D15G10_DATCTL, /* Data control */
- 0
-#if CONFIG_NOKIA6100_MY != 0 /* Display row direction */
- |DATCTL_PGADDR_INV /* Page address inverted */
-#endif
-#if CONFIG_NOKIA6100_MX != 0 /* Display column direction */
- |DATCTL_COLADDR_REV /* Column address reversed */
-#endif
-#if CONFIG_NOKIA6100_V != 0 /* Display address direction */
- |DATCTL_ADDR_PGDIR /* Address scan in page direction */
-#endif
- ,
-#if CONFIG_NOKIA6100_RGBORD != 0
- DATCTL_BGR, /* RGB->BGR */
-#else
- 0, /* RGB->RGB */
-#endif
-#if CONFIG_NOKIA6100_BPP == 8
- DATCTL_8GRAY /* Selects 8-bit color */
-#elif CONFIG_NOKIA6100_BPP == 12
- DATCTL_16GRAY_A /* Selects 16-bit color, Type A */
-#else
-# error "16-bit mode not yet implemented"
-#endif
-};
-
-/* Voltage control (contrast setting):
- * P1: Volume value
- * P2: Resistance ratio
- * (May need to be tuned for individual displays)
- */
-
-static const uint8_t g_volctr[] =
-{
- S1D15G10_VOLCTR, /* Volume control */
- NOKIA_DEFAULT_CONTRAST, /* Volume value */
- 2 /* Resistance ratio */
-};
-
-/* 256-color position set (RGBSET8) */
-
-#if CONFIG_NOKIA6100_BPP == 8
-static const uint8_t g_rgbset8[] =
-{
- S1D15G10_RGBSET8, /* 256-color position set */
- 0, 2, 4, 6, 9, 11, 13, 15, /* Red tones */
- 0, 2, 4, 6, 9, 11, 13, 15, /* Green tones */
- 0, 5, 10, 15 /* Blue tones */
-};
-#endif
-
-/* Page address set (PASET) */
-
-static const uint8_t g_paset[] =
-{
- S1D15G10_PASET, /* Page start address set */
- NOKIA_PGBIAS,
- 131
-};
-
-/* Column address set (CASET) */
-
-static const uint8_t g_caset[] =
-{
- S1D15G10_CASET, /* Column start address set */
- NOKIA_COLBIAS,
- 131
-};
-#endif /* CONFIG_NOKIA6100_S1D15G10 */
-
-#ifdef CONFIG_NOKIA6100_PCF8833
-
-/* Color interface pixel format (COLMOD) */
-
-#if CONFIG_NOKIA6100_BPP == 12
-static const uint8_t g_colmod[] =
-{
- PCF8833_COLMOD, /* Color interface pixel format */
- PCF8833_FMT_12BPS /* 12 bits-per-pixel */
-};
-#else /* CONFIG_NOKIA6100_BPP == 8 */
-static const uint8_t g_colmod[] =
-{
- PCF8833_COLMOD, /* Color interface pixel format */
- PCF8833_FMT_8BPS /* 8 bits-per-pixel */
-};
-#endif
-
-/* Memory data access control(MADCTL) */
-
-static const uint8_t g_madctl[] =
-{
- PCF8833_MADCTL, /* Memory data access control*/
- 0
-#ifdef CONFIG_NOKIA6100_RGBORD != 0
- |MADCTL_RGB /* RGB->BGR */
-#endif
-#ifdef CONFIG_NOKIA6100_MY != 0 /* Display row direction */
- |MADCTL_MY /* Mirror Y */
-#endif
-#ifdef CONFIG_NOKIA6100_MX != 0 /* Display column direction */
- |MADCTL_MX /* Mirror X */
-#endif
-#ifdef CONFIG_NOKIA6100_V != 0 /* Display address direction */
- |MADCTL_V /* ertical RAM write; in Y direction */
-#endif
-#ifdef CONFIG_NOKIA6100_ML != 0 /* Display scan direction */
- |MADCTL_LAO /* Line address order bottom to top */
-#endif
-};
-
-/* Set contrast (SETCON) */
-
-static const uint8_t g_setcon[] =
-{
- PCF8833_SETCON, /* Set contrast */
- NOKIA_DEFAULT_CONTRAST
-};
-
-#endif /* CONFIG_NOKIA6100_PCF8833 */
-
-/**************************************************************************************
- * Private Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Function: nokia_configspi
- *
- * Description:
- * Configure the SPI for use with the Nokia 6100
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-static inline void nokia_configspi(FAR struct spi_dev_s *spi)
-{
- lcddbg("Mode: %d Bits: %d Frequency: %d\n",
- CONFIG_NOKIA6100_SPIMODE, CONFIG_NOKIA6100_WORDWIDTH, CONFIG_NOKIA6100_FREQUENCY);
-
- /* Configure SPI for the Nokia 6100. But only if we own the SPI bus. Otherwise, don't
- * bother because it might change.
- */
-
-#ifdef CONFIG_SPI_OWNBUS
- SPI_SETMODE(spi, CONFIG_NOKIA6100_SPIMODE);
- SPI_SETBITS(spi, CONFIG_NOKIA6100_WORDWIDTH);
- SPI_SETFREQUENCY(spi, CONFIG_NOKIA6100_FREQUENCY)
-#endif
-}
-
-/**************************************************************************************
- * Function: nokia_select
- *
- * Description:
- * Select the SPI, locking and re-configuring if necessary
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void nokia_select(FAR struct spi_dev_s *spi)
-{
- /* We own the SPI bus, so just select the chip */
-
- lcddbg("SELECTED\n");
- SPI_SELECT(spi, SPIDEV_DISPLAY, true);
-}
-#else
-static void nokia_select(FAR struct spi_dev_s *spi)
-{
- /* Select Nokia 6100 chip (locking the SPI bus in case there are multiple
- * devices competing for the SPI bus
- */
-
- lcddbg("SELECTED\n");
- SPI_LOCK(spi, true);
- SPI_SELECT(spi, SPIDEV_DISPLAY, true);
-
- /* Now make sure that the SPI bus is configured for the Nokia 6100 (it
- * might have gotten configured for a different device while unlocked)
- */
-
- SPI_SETMODE(spi, CONFIG_NOKIA6100_SPIMODE);
- SPI_SETBITS(spi, CONFIG_NOKIA6100_WORDWIDTH);
- SPI_SETFREQUENCY(spi, CONFIG_NOKIA6100_FREQUENCY);
-}
-#endif
-
-/**************************************************************************************
- * Function: nokia_deselect
- *
- * Description:
- * De-select the SPI
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void nokia_deselect(FAR struct spi_dev_s *spi)
-{
- /* We own the SPI bus, so just de-select the chip */
-
- lcddbg("DE-SELECTED\n");
- SPI_SELECT(spi, SPIDEV_DISPLAY, false);
-}
-#else
-static void nokia_deselect(FAR struct spi_dev_s *spi)
-{
- /* De-select Nokia 6100 chip and relinquish the SPI bus. */
-
- lcddbg("DE-SELECTED\n");
- SPI_SELECT(spi, SPIDEV_DISPLAY, false);
- SPI_LOCK(spi, false);
-}
-#endif
-
-/**************************************************************************************
- * Name: nokia_sndcmd
- *
- * Description:
- * Send a 1-byte command.
- *
- **************************************************************************************/
-
-static void nokia_sndcmd(FAR struct spi_dev_s *spi, const uint8_t cmd)
-{
- /* Select the LCD */
-
- lcddbg("cmd: %02x\n", cmd);
- nokia_select(spi);
-
- /* Send the command. Bit 8 == 0 denotes a command */
-
- (void)SPI_SEND(spi, (uint16_t)cmd);
-
- /* De-select the LCD */
-
- nokia_deselect(spi);
-}
-
-/**************************************************************************************
- * Name: nokia_cmddata
- *
- * Description:
- * Send a 1-byte command followed by datlen data bytes.
- *
- **************************************************************************************/
-
-static void nokia_cmddata(FAR struct spi_dev_s *spi, uint8_t cmd, int datlen,
- const uint8_t *data)
-{
- uint16_t *rowbuf = g_rowbuf;
- int i;
-
- lcddbg("cmd: %02x datlen: %d\n", cmd, datlen);
- DEBUGASSERT(datlen <= NOKIA_STRIDE);
-
- /* Copy the command into the line buffer. Bit 8 == 0 denotes a command. */
-
- *rowbuf++ = cmd;
-
- /* Copy any data after the command into the line buffer */
-
- for (i = 0; i < datlen; i++)
- {
- /* Bit 8 == 1 denotes data */
-
- *rowbuf++ = (uint16_t)*data++ | NOKIA_LCD_DATA;
- }
-
- /* Select the LCD */
-
- nokia_select(spi);
-
- /* Send the line buffer. */
-
- (void)SPI_SNDBLOCK(spi, g_rowbuf, datlen+1);
-
- /* De-select the LCD */
-
- nokia_deselect(spi);
-}
-
-/**************************************************************************************
- * Name: nokia_ramwr
- *
- * Description:
- * Send a RAMWR command followed by datlen data bytes.
- *
- **************************************************************************************/
-
-static void nokia_ramwr(FAR struct spi_dev_s *spi, int datlen, const uint8_t *data)
-{
- nokia_cmddata(spi, LCD_RAMWR, datlen, data);
-}
-
-/**************************************************************************************
- * Name: nokia_cmdarray
- *
- * Description:
- * Send a RAMWR command followed by len-1 data bytes.
- *
- **************************************************************************************/
-
-static void nokia_cmdarray(FAR struct spi_dev_s *spi, int len, const uint8_t *cmddata)
-{
-#ifdef CONFIG_LCD_REGDEBUG
- int i;
-
- for (i = 0; i < len; i++)
- {
- lcddbg("cmddata[%d]: %02x\n", i, cmddata[i]);
- }
-#endif
- nokia_cmddata(spi, cmddata[0], len-1, &cmddata[1]);
-}
-
-/**************************************************************************************
- * Name: nokia_clrram
- *
- * Description:
- * Send a 1-byte command followed by len-1 data bytes.
- *
- **************************************************************************************/
-
-static void nokia_clrram(FAR struct spi_dev_s *spi)
-{
- uint16_t *rowbuf = g_rowbuf;
- int i;
-
- /* Set all zero data in the line buffer */
-
- for (i = 0; i < NOKIA_STRIDE; i++)
- {
- /* Bit 8 == 1 denotes data */
-
- *rowbuf++ = NOKIA_LCD_DATA;
- }
-
- /* Select the LCD and send the RAMWR command */
-
- nokia_select(spi);
- SPI_SEND(spi, LCD_RAMWR);
-
- /* Send the line buffer, once for each row. */
-
- for (i = 0; i < NOKIA_YRES; i++)
- {
- (void)SPI_SNDBLOCK(spi, g_rowbuf, NOKIA_STRIDE);
- }
-
- /* De-select the LCD */
-
- nokia_deselect(spi);
-}
-
-/**************************************************************************************
- * Name: nokia_putrun
- *
- * Description:
- * This method can be used to write a partial raster line to the LCD:
- *
- * row - Starting row to write to (range: 0 <= row < yres)
- * col - Starting column to write to (range: 0 <= col <= xres-npixels)
- * buffer - The buffer containing the run to be written to the LCD
- * npixels - The number of pixels to write to the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-static int nokia_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels)
-{
- struct nokia_dev_s *priv = &g_lcddev;
- FAR struct spi_dev_s *spi = priv->spi;
- uint16_t cmd[3];
-
- gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
-
-#if NOKIA_XBIAS > 0
- col += NOKIA_XBIAS;
-#endif
-#if NOKIA_YBIAS > 0
- row += NOKIA_YBIAS;
-#endif
- DEBUGASSERT(buffer && col >=0 && (col + npixels) <= NOKIA_XRES && row >= 0 && row < NOKIA_YRES);
-
- /* Set up to write the run. */
-
- nokia_select(spi);
- cmd[0] = LCD_PASET;
- cmd[1] = col | NOKIA_LCD_DATA;
- cmd[2] = NOKIA_ENDPAGE | NOKIA_LCD_DATA;
- (void)SPI_SNDBLOCK(spi, cmd, 3);
- nokia_deselect(spi);
-
- /* De-select the LCD */
-
- nokia_select(spi);
- cmd[0] = LCD_CASET;
- cmd[1] = row | NOKIA_LCD_DATA;
- cmd[2] = NOKIA_ENDCOL | NOKIA_LCD_DATA;
- (void)SPI_SNDBLOCK(spi, cmd, 3);
- nokia_deselect(spi);
-
- /* Then send the run */
-
- nokia_ramwr(spi, NOKIA_PIX2BYTES(npixels), buffer);
- return OK;
-}
-
-/**************************************************************************************
- * Name: nokia_getrun
- *
- * Description:
- * This method can be used to read a partial raster line from the LCD:
- *
- * row - Starting row to read from (range: 0 <= row < yres)
- * col - Starting column to read read (range: 0 <= col <= xres-npixels)
- * buffer - The buffer in which to return the run read from the LCD
- * npixels - The number of pixels to read from the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-static int nokia_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels)
-{
- gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
-
- /* At present, this is a write-only LCD driver */
-
-#warning "Not implemented"
- return -ENOSYS;
-}
-
-/**************************************************************************************
- * Name: nokia_getvideoinfo
- *
- * Description:
- * Get information about the LCD video controller configuration.
- *
- **************************************************************************************/
-
-static int nokia_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo)
-{
- DEBUGASSERT(dev && vinfo);
- gvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n",
- g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes);
- memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: nokia_getplaneinfo
- *
- * Description:
- * Get information about the configuration of each LCD color plane.
- *
- **************************************************************************************/
-
-static int nokia_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo)
-{
- DEBUGASSERT(dev && pinfo && planeno == 0);
- gvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp);
- memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: nokia_getpower
- *
- * Description:
- * 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.
- *
- **************************************************************************************/
-
-static int nokia_getpower(struct lcd_dev_s *dev)
-{
- struct nokia_dev_s *priv = (struct nokia_dev_s *)dev;
- gvdbg("power: %d\n", priv->power);
- return priv->power;
-}
-
-/**************************************************************************************
- * Name: nokia_setpower
- *
- * Description:
- * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On
- * backlit LCDs, this setting may correspond to the backlight setting.
- *
- **************************************************************************************/
-
-static int nokia_setpower(struct lcd_dev_s *dev, int power)
-{
- struct nokia_dev_s *priv = (struct nokia_dev_s *)dev;
- int ret;
-
- gvdbg("power: %d\n", power);
- DEBUGASSERT(power <= CONFIG_LCD_MAXPOWER);
-
- /* Set new power level. The backlight power is controlled outside of the LCD
- * assembly and must be managmed by board-specific logic.
- */
-
- ret = nokia_backlight(power);
- if (ret == OK)
- {
- priv->power = power;
- }
- return ret;
-}
-
-/**************************************************************************************
- * Name: nokia_getcontrast
- *
- * Description:
- * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int nokia_getcontrast(struct lcd_dev_s *dev)
-{
- struct nokia_dev_s *priv = (struct nokia_dev_s *)dev;
- gvdbg("contrast: %d\n", priv->contrast);
- return priv->contrast;
-}
-
-/**************************************************************************************
- * Name: nokia_setcontrast
- *
- * Description:
- * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int nokia_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
-{
- struct nokia_dev_s *priv = (struct nokia_dev_s *)dev;
-
- if (contrast < CONFIG_LCD_MAXCONTRAST)
- {
-#ifdef CONFIG_NOKIA6100_S1D15G10
- while (priv->contrast < contrast)
- {
- nokia_sndcmd(priv->spi, S1D15G10_VOLUP);
- priv->contrast++;
- }
- while (priv->contrast > contrast)
- {
- nokia_sndcmd(priv->spi, S1D15G10_VOLDOWN);
- priv->contrast--;
- }
-#else /* CONFIG_NOKIA6100_PCF8833 */
- uint8_t cmd[2];
-
- cmd[0] = PCF8833_SETCON;
- cmd[1] = priv->contrast;
- nokia_sndarry(priv->spi, 2, cmd);
- priv->contrast = contrast;
-#endif
- }
-
- gvdbg("contrast: %d\n", contrast);
- return -ENOSYS;
-}
-
-/**************************************************************************************
- * Name: nokia_initialize
- *
- * Description:
- * Initialize the LCD controller.
- *
- **************************************************************************************/
-
-#ifdef CONFIG_NOKIA6100_S1D15G10
-static int nokia_initialize(struct nokia_dev_s *priv)
-{
- struct spi_dev_s *spi = priv->spi;
-
- /* Configure the display */
-
- nokia_cmdarray(spi, sizeof(g_disctl), g_disctl); /* Display control */
- nokia_cmdarray(spi, sizeof(g_comscn), g_comscn); /* Common scan direction */
- nokia_sndcmd(spi, S1D15G10_OSCON); /* Internal oscilator ON */
- nokia_sndcmd(spi, S1D15G10_SLPOUT); /* Sleep out */
- nokia_cmdarray(spi, sizeof(g_volctr), g_volctr); /* Volume control (contrast) */
- nokia_cmdarray(spi, sizeof(g_pwrctr), g_pwrctr); /* Turn on voltage regulators */
- up_mdelay(100);
-#ifdef CONFIG_NOKIA6100_INVERT
- nokia_sndcmd(spi, S1D15G10_DISINV); /* Invert display */
-#else
- nokia_sndcmd(spi, S1D15G10_DISNOR); /* Normal display */
-#endif
- nokia_cmdarray(spi, sizeof(g_datctl), g_datctl); /* Data control */
-#if CONFIG_NOKIA6100_BPP == 8
- nokia_cmdarray(spi, sizeof(g_rgbset8), g_rgbset8); /* Set up color lookup table */
- nokia_sndcmd(spi, S1D15G10_NOP);
-#endif
- nokia_cmdarray(spi, sizeof(g_paset), g_paset); /* Page address set */
- nokia_cmdarray(spi, sizeof(g_paset), g_caset); /* Column address set */
- nokia_clrram(spi);
- nokia_sndcmd(spi, S1D15G10_DISON); /* Display on */
- return OK;
-}
-#endif
-
-#ifdef CONFIG_NOKIA6100_PCF8833
-static int nokia_initialize(struct nokia_dev_s *priv)
-{
- struct struct spi_dev_s *spi = priv->spi;
-
- nokia_sndcmd(spi, PCF8833_SLEEPOUT); /* Exit sleep mode */
- nokia_sndcmd(spi, PCF8833_BSTRON); /* Turn on voltage booster */
-#ifdef CONFIG_NOKIA6100_INVERT
- nokia_sndcmd(spi, PCF8833_INVON); /* Invert display */
-#else
- nokia_sndcmd(spi, PCF8833_INVOFF); /* Don't invert display */
-#endif
- nokia_cmdarray(spi, sizeof(g_madctl), g_madctl); /* Memory data access control */
- nokia_cmdarray(spi, sizeof(g_colmod), g_colmod); /* Color interface pixel format */
- nokia_cmdarray(spi, sizeof(g_setcon), g_setcon); /* Set contrast */
- nokia_sndcmd(spi, PCF8833_NOP); /* No operation */
- nokia_clrram(spi);
- nokia_sndcmd(spi, PCF8833_DISPON); /* Display on */
- return OK;
-}
-#endif /* CONFIG_NOKIA6100_PCF8833 */
-
-/**************************************************************************************
- * Public Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: nokia_lcdinitialize
- *
- * Description:
- * Initialize the NOKIA6100 video hardware. The initial state of the LCD is fully
- * initialized, display memory cleared, and the LCD ready to use, but with the power
- * setting at 0 (full off == sleep mode).
- *
- * Input Parameters:
- *
- * spi - A reference to the SPI driver instance.
- * devno - A value in the range of 0 throuh CONFIG_NOKIA6100_NINTERFACES-1. This
- * allows support for multiple LCD devices.
- *
- * Returned Value:
- *
- * On success, this function returns a reference to the LCD object for the specified
- * LCD. NULL is returned on any failure.
- *
- **************************************************************************************/
-
-FAR struct lcd_dev_s *nokia_lcdinitialize(FAR struct spi_dev_s *spi, unsigned int devno)
-{
- struct nokia_dev_s *priv = &g_lcddev;
-
- gvdbg("Initializing\n");
- DEBUGASSERT(devno == 0);
-
- /* Initialize the driver data structure */
-
- priv->spi = spi; /* Save the SPI instance */
- priv->contrast = NOKIA_DEFAULT_CONTRAST; /* Initial contrast setting */
-
- /* Configure and enable the LCD controller */
-
- nokia_configspi(spi);
- if (nokia_initialize(priv) == OK)
- {
- /* Turn on the backlight */
-
- nokia_backlight(CONFIG_NOKIA6100_BLINIT);
- return &priv->dev;
- }
- return NULL;
-}
diff --git a/nuttx/drivers/lcd/p14201.c b/nuttx/drivers/lcd/p14201.c
deleted file mode 100644
index 934d251ca..000000000
--- a/nuttx/drivers/lcd/p14201.c
+++ /dev/null
@@ -1,1246 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/p14201.c
- * Driver for RiT P14201 series display (wih sd1329 IC controller)
- *
- * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/spi.h>
-#include <nuttx/lcd/lcd.h>
-#include <nuttx/lcd/p14201.h>
-
-#include <arch/irq.h>
-
-#include "sd1329.h"
-
-#ifdef CONFIG_LCD_P14201
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-
-/* Configuration **********************************************************************/
-
-/* P14201 Configuration Settings:
- *
- * CONFIG_P14201_SPIMODE - Controls the SPI mode
- * CONFIG_P14201_FREQUENCY - Define to use a different bus frequency
- * CONFIG_P14201_NINTERFACES - Specifies the number of physical P14201 devices that
- * will be supported.
- * CONFIG_P14201_FRAMEBUFFER - If defined, accesses will be performed using an in-memory
- * copy of the OLEDs GDDRAM. This cost of this buffer is 128 * 96 / 2 = 6Kb. If this
- * is defined, then the driver will be fully functional. If not, then it will have the
- * following limitations:
- *
- * - Reading graphics memory cannot be supported, and
- * - All pixel writes must be aligned to byte boundaries.
- *
- * The latter limitation effectively reduces the 128x96 disply to 64x96.
- *
- * Required LCD driver settings:
- * CONFIG_LCD_P14201 - Enable P14201 support
- * CONFIG_LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted.
- * CONFIG_LCD_MAXPOWER must be 1
- *
- * Required SPI driver settings:
- * CONFIG_SPI_CMDDATA - Include support for cmd/data selection.
- */
-
-#ifndef CONFIG_SPI_CMDDATA
-# error "CONFIG_SPI_CMDDATA must be defined in your NuttX configuration"
-#endif
-
-/* The P14201 spec says that is supports SPI mode 0,0 only. However,
- * somtimes you need to tinker with these things.
- */
-
-#ifndef CONFIG_P14201_SPIMODE
-# define CONFIG_P14201_SPIMODE SPIDEV_MODE2
-#endif
-
-/* CONFIG_P14201_NINTERFACES determines the number of physical interfaces
- * that will be supported.
- */
-
-#ifndef CONFIG_P14201_NINTERFACES
-# define CONFIG_P14201_NINTERFACES 1
-#endif
-
-#if CONFIG_P14201_NINTERFACES != 1
-# error "This implementation supports only a single OLED device"
-#endif
-
-/* Check contrast selection */
-
-#if !defined(CONFIG_LCD_MAXCONTRAST)
-# define CONFIG_LCD_MAXCONTRAST 255
-#endif
-
-#if CONFIG_LCD_MAXCONTRAST <= 0|| CONFIG_LCD_MAXCONTRAST > 255
-# error "CONFIG_LCD_MAXCONTRAST exceeds supported maximum"
-#endif
-
-/* Check power setting */
-
-#if !defined(CONFIG_LCD_MAXPOWER)
-# define CONFIG_LCD_MAXPOWER 1
-#endif
-
-#if CONFIG_LCD_MAXPOWER != 1
-# warning "CONFIG_LCD_MAXPOWER exceeds supported maximum"
-# undef CONFIG_LCD_MAXPOWER
-# define CONFIG_LCD_MAXPOWER 1
-#endif
-
-/* Color is 4bpp greyscale with leftmost column contained in bits 7:4 */
-
-#if defined(CONFIG_NX_DISABLE_4BPP) || !defined(CONFIG_NX_PACKEDMSFIRST)
-# warning "4-bit, big-endian pixel support needed"
-#endif
-
-/* Define the CONFIG_LCD_RITDEBUG to enable detailed debug output (stuff you would
- * never want to see unless you are debugging this file).
- *
- * Verbose debug must also be enabled
- */
-
-#ifndef CONFIG_DEBUG
-# undef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_DEBUG_GRAPHICS
-#endif
-
-#ifndef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_LCD_RITDEBUG
-#endif
-
-/* Color Properties *******************************************************************/
-
-/* Display Resolution */
-
-#define RIT_XRES 128
-#define RIT_YRES 96
-
-/* Color depth and format */
-
-#define RIT_BPP 4
-#define RIT_COLORFMT FB_FMT_Y4
-
-/* Default contrast */
-
-#define RIT_CONTRAST ((23 * (CONFIG_LCD_MAXCONTRAST+1) / 32) - 1)
-
-/* Helper Macros **********************************************************************/
-
-#define rit_sndcmd(p,b,l) rit_sndbytes(p,b,l,true);
-#define rit_snddata(p,b,l) rit_sndbytes(p,b,l,false);
-
-/* Debug ******************************************************************************/
-
-#ifdef CONFIG_LCD_RITDEBUG
-# define ritdbg(format, arg...) vdbg(format, ##arg)
-#else
-# define ritdbg(x...)
-#endif
-
-/**************************************************************************************
- * Private Type Definition
- **************************************************************************************/
-
-/* This structure describes the state of this driver */
-
-struct rit_dev_s
-{
- struct lcd_dev_s dev; /* Publically visible device structure */
- FAR struct spi_dev_s *spi; /* Cached SPI device reference */
- uint8_t contrast; /* Current contrast setting */
- bool on; /* true: display is on */
-};
-
-/**************************************************************************************
- * Private Function Protototypes
- **************************************************************************************/
-
-/* Low-level SPI helpers */
-
-static inline void rit_configspi(FAR struct spi_dev_s *spi);
-#ifdef CONFIG_SPI_OWNBUS
-static inline void rit_select(FAR struct spi_dev_s *spi);
-static inline void rit_deselect(FAR struct spi_dev_s *spi);
-#else
-static void rit_select(FAR struct spi_dev_s *spi);
-static void rit_deselect(FAR struct spi_dev_s *spi);
-#endif
-static void rit_sndbytes(FAR struct rit_dev_s *priv, FAR const uint8_t *buffer,
- size_t buflen, bool cmd);
-static void rit_sndcmds(FAR struct rit_dev_s *priv, FAR const uint8_t *table);
-
-/* LCD Data Transfer Methods */
-
-static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels);
-static int rit_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels);
-
-/* LCD Configuration */
-
-static int rit_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo);
-static int rit_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo);
-
-/* LCD RGB Mapping */
-
-#ifdef CONFIG_FB_CMAP
-# error "RGB color mapping not supported by this driver"
-#endif
-
-/* Cursor Controls */
-
-#ifdef CONFIG_FB_HWCURSOR
-# error "Cursor control not supported by this driver"
-#endif
-
-/* LCD Specific Controls */
-
-static int rit_getpower(struct lcd_dev_s *dev);
-static int rit_setpower(struct lcd_dev_s *dev, int power);
-static int rit_getcontrast(struct lcd_dev_s *dev);
-static int rit_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
-
-/**************************************************************************************
- * Private Data
- **************************************************************************************/
-
-/* This is working memory allocated by the LCD driver for each LCD device
- * and for each color plane. This memory will hold one raster line of data.
- * The size of the allocated run buffer must therefore be at least
- * (bpp * xres / 8). Actual alignment of the buffer must conform to the
- * bitwidth of the underlying pixel type.
- *
- * If there are multiple planes, they may share the same working buffer
- * because different planes will not be operate on concurrently. However,
- * if there are multiple LCD devices, they must each have unique run buffers.
- */
-
-static uint8_t g_runbuffer[RIT_XRES / 2];
-
-/* CONFIG_P14201_FRAMEBUFFER - If defined, accesses will be performed using an in-memory
- * copy of the OLEDs GDDRAM. This cost of this buffer is 128 * 64 / 2 = 4Kb. If this
- * is defined, then the driver will be full functional. If not, then:
- *
- * - Reading graphics memory cannot be supported, and
- * - All pixel writes must be aligned to byte boundaries.
- */
-
-#ifdef CONFIG_P14201_FRAMEBUFFER
-static uint8_t g_framebuffer[RIT_YRES * RIT_XRES / 2];
-#endif
-
-/* This structure describes the overall LCD video controller */
-
-static const struct fb_videoinfo_s g_videoinfo =
-{
- .fmt = RIT_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
- .xres = RIT_XRES, /* Horizontal resolution in pixel columns */
- .yres = RIT_YRES, /* Vertical resolution in pixel rows */
- .nplanes = 1, /* Number of color planes supported */
-};
-
-/* This is the standard, NuttX Plane information object */
-
-static const struct lcd_planeinfo_s g_planeinfo =
-{
- .putrun = rit_putrun, /* Put a run into LCD memory */
- .getrun = rit_getrun, /* Get a run from LCD memory */
- .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */
- .bpp = RIT_BPP, /* Bits-per-pixel */
-};
-
-/* This is the OLED driver instance (only a single device is supported for now) */
-
-static struct rit_dev_s g_oleddev =
-{
- .dev =
- {
- /* LCD Configuration */
-
- .getvideoinfo = rit_getvideoinfo,
- .getplaneinfo = rit_getplaneinfo,
-
- /* LCD RGB Mapping -- Not supported */
- /* Cursor Controls -- Not supported */
-
- /* LCD Specific Controls */
-
- .getpower = rit_getpower,
- .setpower = rit_setpower,
- .getcontrast = rit_getcontrast,
- .setcontrast = rit_setcontrast,
- },
-};
-
-/* A table of magic initialization commands. This initialization sequence is
- * derived from RiT Application Note for the P14201 (with a few tweaked values
- * as discovered in some Luminary code examples).
- */
-
-static const uint8_t g_initcmds[] =
-{
- 3, SSD1329_CMD_LOCK, /* Set lock command */
- SSD1329_LOCK_OFF, /* Disable locking */
- SSD1329_NOOP,
- 2, SSD1329_SLEEP_ON, /* Matrix display OFF */
- SSD1329_NOOP,
- 3, SSD1329_ICON_ALL, /* Set all ICONs to OFF */
- SSD1329_ICON_OFF, /* OFF selection */
- SSD1329_NOOP,
- 3, SSD1329_MUX_RATIO, /* Set MUX ratio */
- 95, /* 96 MUX */
- SSD1329_NOOP,
- 3, SSD1329_SET_CONTRAST, /* Set contrast */
- RIT_CONTRAST, /* Default contrast */
- SSD1329_NOOP,
- 3, SSD1329_PRECHRG2_SPEED, /* Set second pre-charge speed */
- (31 << 1) | SSD1329_PRECHRG2_DBL, /* Pre-charge speed == 32, doubled */
- SSD1329_NOOP,
- 3, SSD1329_GDDRAM_REMAP, /* Set GDDRAM re-map */
- (SSD1329_COM_SPLIT| /* Enable COM slip even/odd */
- SSD1329_COM_REMAP| /* Enable COM re-map */
- SSD1329_NIBBLE_REMAP), /* Enable nibble re-map */
- SSD1329_NOOP,
- 3, SSD1329_VERT_START, /* Set Display Start Line */
- 0, /* Line = 0 */
- SSD1329_NOOP,
- 3, SSD1329_VERT_OFFSET, /* Set Display Offset */
- 0, /* Offset = 0 */
- SSD1329_NOOP,
- 2, SSD1329_DISP_NORMAL, /* Display mode normal */
- SSD1329_NOOP,
- 3, SSD1329_PHASE_LENGTH, /* Set Phase Length */
- 1 | /* Phase 1 period = 1 DCLK */
- (1 << 4), /* Phase 2 period = 1 DCLK */
- SSD1329_NOOP,
- 3, SSD1329_FRAME_FREQ,
- 35, /* 35 DCLK's per row */
- SSD1329_NOOP,
- 3, SSD1329_DCLK_DIV, /* Set Front Clock Divider / Oscillator Frequency */
- 2 | /* Divide ration = 3 */
- (14 << 4), /* Oscillator Frequency, FOSC, setting */
- SSD1329_NOOP,
- 17, SSD1329_GSCALE_LOOKUP, /* Look Up Table for Gray Scale Pulse width */
- 1, 2, 3, 4, 5, /* Value for GS1-5 level Pulse width */
- 6, 8, 10, 12, 14, /* Value for GS6-10 level Pulse width */
- 16, 19, 22, 26, 30, /* Value for GS11-15 level Pulse width */
- SSD1329_NOOP,
- 3, SSD1329_PRECHRG2_PERIOD, /* Set Second Pre-charge Period */
- 1, /* 1 DCLK */
- SSD1329_NOOP,
- 3, SSD1329_PRECHRG1_VOLT, /* Set First Precharge voltage, VP */
- 0x3f, /* 1.00 x Vcc */
- SSD1329_NOOP,
- 0 /* Zero length command terminates table */
-};
-
-/* Turn the maxtrix display on (sleep mode off) */
-
-static const uint8_t g_sleepoff[] =
-{
- SSD1329_SLEEP_OFF, /* Matrix display ON */
- SSD1329_NOOP,
-};
-
-/* Turn the maxtrix display off (sleep mode on) */
-
-static const uint8_t g_sleepon[] =
-{
- SSD1329_SLEEP_ON, /* Matrix display OFF */
- SSD1329_NOOP,
-};
-
-/* Set horizontal increment mode */
-
-static const uint8_t g_horzinc[] =
-{
- SSD1329_GDDRAM_REMAP,
- (SSD1329_COM_SPLIT|SSD1329_COM_REMAP|SSD1329_NIBBLE_REMAP),
-};
-
-/* The following set a window that covers the entire display */
-
-static const uint8_t g_setallcol[] =
-{
- SSD1329_SET_COLADDR,
- 0,
- (RIT_XRES/2)-1
-};
-
-static const uint8_t g_setallrow[] =
-{
- SSD1329_SET_ROWADDR,
- 0,
- RIT_YRES-1
-};
-
-/**************************************************************************************
- * Private Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: rit_configspi
- *
- * Description:
- * Configure the SPI for use with the P14201
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-static inline void rit_configspi(FAR struct spi_dev_s *spi)
-{
-#ifdef CONFIG_P14201_FREQUENCY
- ritdbg("Mode: %d Bits: 8 Frequency: %d\n",
- CONFIG_P14201_SPIMODE, CONFIG_P14201_FREQUENCY);
-#else
- ritdbg("Mode: %d Bits: 8\n", CONFIG_P14201_SPIMODE);
-#endif
-
- /* Configure SPI for the P14201. But only if we own the SPI bus. Otherwise, don't
- * bother because it might change.
- */
-
-#ifdef CONFIG_SPI_OWNBUS
- SPI_SETMODE(spi, CONFIG_P14201_SPIMODE);
- SPI_SETBITS(spi, 8);
-#ifdef CONFIG_P14201_FREQUENCY
- SPI_SETFREQUENCY(spi, CONFIG_P14201_FREQUENCY)
-#endif
-#endif
-}
-
-/**************************************************************************************
- * Name: rit_select
- *
- * Description:
- * Select the SPI, locking and re-configuring if necessary
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void rit_select(FAR struct spi_dev_s *spi)
-{
- /* We own the SPI bus, so just select the chip */
-
- SPI_SELECT(spi, SPIDEV_DISPLAY, true);
-}
-#else
-static void rit_select(FAR struct spi_dev_s *spi)
-{
- /* Select P14201 chip (locking the SPI bus in case there are multiple
- * devices competing for the SPI bus
- */
-
- SPI_LOCK(spi, true);
- SPI_SELECT(spi, SPIDEV_DISPLAY, true);
-
- /* Now make sure that the SPI bus is configured for the P14201 (it
- * might have gotten configured for a different device while unlocked)
- */
-
- SPI_SETMODE(spi, CONFIG_P14201_SPIMODE);
- SPI_SETBITS(spi, 8);
-#ifdef CONFIG_P14201_FREQUENCY
- SPI_SETFREQUENCY(spi, CONFIG_P14201_FREQUENCY);
-#endif
-}
-#endif
-
-/**************************************************************************************
- * Name: rit_deselect
- *
- * Description:
- * De-select the SPI
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void rit_deselect(FAR struct spi_dev_s *spi)
-{
- /* We own the SPI bus, so just de-select the chip */
-
- SPI_SELECT(spi, SPIDEV_DISPLAY, false);
-}
-#else
-static void rit_deselect(FAR struct spi_dev_s *spi)
-{
- /* De-select P14201 chip and relinquish the SPI bus. */
-
- SPI_SELECT(spi, SPIDEV_DISPLAY, false);
- SPI_LOCK(spi, false);
-}
-#endif
-
-/**************************************************************************************
- * Name: rit_sndbytes
- *
- * Description:
- * Send a sequence of command or data bytes to the SSD1329 controller.
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- * buffer - A reference to memory containing the command bytes to be sent.
- * buflen - The number of command bytes in buffer to be sent
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * The caller as selected the OLED device.
- *
- **************************************************************************************/
-
-static void rit_sndbytes(FAR struct rit_dev_s *priv, FAR const uint8_t *buffer,
- size_t buflen, bool cmd)
-{
- FAR struct spi_dev_s *spi = priv->spi;
- uint8_t tmp;
-
- ritdbg("buflen: %d cmd: %s [%02x %02x %02x]\n",
- buflen, cmd ? "YES" : "NO", buffer[0], buffer[1], buffer[2] );
- DEBUGASSERT(spi);
-
- /* Clear/set the D/Cn bit to enable command or data mode */
-
- (void)SPI_CMDDATA(spi, SPIDEV_DISPLAY, cmd);
-
- /* Loop until the entire command/data block is transferred */
-
- while (buflen-- > 0)
- {
- /* Write the next byte to the controller */
-
- tmp = *buffer++;
- (void)SPI_SEND(spi, tmp);
- }
-}
-
-/**************************************************************************************
- * Name: rit_sndcmd
- *
- * Description:
- * Send multiple commands from a table of commands.
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- * table - A reference to table containing all of the commands to be sent.
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-static void rit_sndcmds(FAR struct rit_dev_s *priv, FAR const uint8_t *table)
-{
- int cmdlen;
-
- /* Table terminates with a zero length command */
-
- while ((cmdlen = *table++) != 0)
- {
- ritdbg("command: %02x cmdlen: %d\n", *table, cmdlen);
- rit_sndcmd(priv, table, cmdlen);
- table += cmdlen;
- }
-}
-
-/**************************************************************************************
- * Name: rit_clear
- *
- * Description:
- * This method can be used to clear the entire display.
- *
- * Input Parameters:
- * priv - Reference to private driver structure
- *
- * Assumptions:
- * Caller has selected the OLED section.
- *
- **************************************************************************************/
-
-#ifdef CONFIG_P14201_FRAMEBUFFER
-static inline void rit_clear(FAR struct rit_dev_s *priv)
-{
- FAR uint8_t *ptr = g_framebuffer;
- unsigned int row;
-
- ritdbg("Clear display\n");
-
- /* Initialize the framebuffer */
-
- memset(g_framebuffer, (RIT_Y4_BLACK << 4) | RIT_Y4_BLACK, RIT_YRES * RIT_XRES / 2);
-
- /* Set a window to fill the entire display */
-
- rit_sndcmd(priv, g_setallcol, sizeof(g_setallcol));
- rit_sndcmd(priv, g_setallrow, sizeof(g_setallrow));
- rit_sndcmd(priv, g_horzinc, sizeof(g_horzinc));
-
- /* Display each row */
-
- for(row = 0; row < RIT_YRES; row++)
- {
- /* Display a horizontal run */
-
- rit_snddata(priv, ptr, RIT_XRES / 2);
- ptr += RIT_XRES / 2;
- }
-}
-#else
-static inline void rit_clear(FAR struct rit_dev_s *priv)
-{
- unsigned int row;
-
- ritdbg("Clear display\n");
-
- /* Create a black row */
-
- memset(g_runbuffer, (RIT_Y4_BLACK << 4) | RIT_Y4_BLACK, RIT_XRES / 2);
-
- /* Set a window to fill the entire display */
-
- rit_sndcmd(priv, g_setallcol, sizeof(g_setallcol));
- rit_sndcmd(priv, g_setallrow, sizeof(g_setallrow));
- rit_sndcmd(priv, g_horzinc, sizeof(g_horzinc));
-
- /* Display each row */
-
- for(row = 0; row < RIT_YRES; row++)
- {
- /* Display a horizontal run */
-
- rit_snddata(priv, g_runbuffer, RIT_XRES / 2);
- }
-}
-#endif
-
-/**************************************************************************************
- * Name: rit_putrun
- *
- * Description:
- * This method can be used to write a partial raster line to the LCD.
- *
- * Input Parameters:
- * row - Starting row to write to (range: 0 <= row < yres)
- * col - Starting column to write to (range: 0 <= col <= xres-npixels)
- * buffer - The buffer containing the run to be written to the LCD
- * npixels - The number of pixels to write to the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-#ifdef CONFIG_P14201_FRAMEBUFFER
-static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels)
-{
- FAR struct rit_dev_s *priv = (FAR struct rit_dev_s *)&g_oleddev;
- uint8_t cmd[3];
- uint8_t *run;
- int start;
- int end;
- int aend;
- int i;
-
- ritdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer);
-
- /* Toss out the special case of the empty run now */
-
- if (npixels < 1)
- {
- return OK;
- }
-
- /* Get the beginning of the line containing run in the framebuffer */
-
- run = g_framebuffer + row * RIT_XRES / 2;
-
- /* Get the starting and ending byte offsets containing the run.
- * the run starts at &run[start] and continues through run[end-1].
- * However, the first and final pixels at these locations may
- * not be byte aligned.
- */
-
- start = col >> 1;
- aend = (col + npixels) >> 1;
- end = (col + npixels + 1) >> 1;
- ritdbg("start: %d aend: %d end: %d\n", start, aend, end);
-
- /* Copy the run into the framebuffer, handling nibble alignment.
- *
- * CASE 1: First pixel X position is byte aligned
- *
- * example col=6 npixels = 8 example col=6 npixels=7
- *
- * Run: |AB|AB|AB|AB| |AB|AB|AB|AB|
- * GDDRAM row:
- * Byte | 0| 1| 2| 3| 4| 5| 6| | 0| 1| 2| 3| 4| 5| 6|
- * Pixel: |--|--|--|AB|AB|AB|AB| |--|--|--|AB|AB|AB|A-|
- *
- * start = 3 start = 3
- * aend = 6 aend = 6
- * end = 6 end = 7
- *
- */
-
- if ((col & 1) == 0)
- {
- /* Check for the special case of only 1 pixel being blitted */
-
- if (npixels > 1)
- {
- /* Beginning of buffer is properly aligned, from start to aend */
-
- memcpy(&run[start], buffer, aend - start);
- }
-
- /* An even number of byte-aligned pixel pairs have been written (where
- * zero counts as an even number). If npixels was was odd (including
- * npixels == 1), then handle the final, byte aligned pixel.
- */
-
- if (aend != end)
- {
- /* The leftmost column is contained in source bits 7:4 and in
- * destination bits 7:4
- */
-
- run[aend] = (run[aend] & 0x0f) | (buffer[aend - start] & 0xf0);
- }
- }
-
- /* CASE 2: First pixel X position is byte aligned
- *
- * example col=7 npixels = 8 example col=7 npixels=7
- *
- * Run: |AB|AB|AB|AB| |AB|AB|AB|AB|
- * GDDRAM row:
- * Byte | 0| 1| 2| 3| 4| 5| 6| 7| | 0| 1| 2| 3| 4| 5| 6|
- * Pixel: |--|--|--|-A|BA|BA|BA|B-| |--|--|--|-A|BA|BA|BA|
- *
- * start = 3 start = 3
- * aend = 7 aend = 7
- * end = 8 end = 7
- */
-
- else
- {
- uint8_t curr = buffer[0];
- uint8_t last;
-
- /* Handle the initial unaligned pixel. Source bits 7:4 into
- * destination bits 3:0. In the special case of npixel == 1,
- * this finished the job.
- */
-
- run[start] = (run[start] & 0xf0) | (curr >> 4);
-
- /* Now construct the rest of the bytes in the run (possibly special
- * casing the final, partial byte below).
- */
-
- for (i = start + 1; i < aend; i++)
- {
- /* bits 3:0 from previous byte to run bits 7:4;
- * bits 7:4 of current byte to run bits 3:0
- */
-
- last = curr;
- curr = buffer[i-start];
- run[i] = (last << 4) | (curr >> 4);
- }
-
- /* An odd number of unaligned pixel have been written (where npixels
- * may have been as small as one). If npixels was was even, then handle
- * the final, unaligned pixel.
- */
-
- if (aend != end)
- {
- /* The leftmost column is contained in source bits 3:0 and in
- * destination bits 7:4
- */
-
- run[aend] = (run[aend] & 0x0f) | (curr << 4);
- }
- }
-
- /* Select the SD1329 controller */
-
- rit_select(priv->spi);
-
- /* Setup a window that describes a run starting at the specified column
- * and row, and ending at the column + npixels on the same row.
- */
-
- cmd[0] = SSD1329_SET_COLADDR;
- cmd[1] = start;
- cmd[2] = end - 1;
- rit_sndcmd(priv, cmd, 3);
-
- cmd[0] = SSD1329_SET_ROWADDR;
- cmd[1] = row;
- cmd[2] = row;
- rit_sndcmd(priv, cmd, 3);
-
- /* Write the run to GDDRAM. */
-
- rit_sndcmd(priv, g_horzinc, sizeof(g_horzinc));
- rit_snddata(priv, &run[start], end - start);
-
- /* De-select the SD1329 controller */
-
- rit_deselect(priv->spi);
- return OK;
-}
-#else
-static int rit_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels)
-{
- FAR struct rit_dev_s *priv = (FAR struct rit_dev_s *)&g_oleddev;
- uint8_t cmd[3];
-
- ritdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer);
-
- if (npixels > 0)
- {
- /* Check that the X and Y coordinates are within range */
-
- DEBUGASSERT(col < RIT_XRES && (col + npixels) <= RIT_XRES && row < RIT_YRES);
-
- /* Check that the X coordinates are aligned to 8-bit boundaries
- * (this needs to get fixed somehow)
- */
-
- DEBUGASSERT((col & 1) == 0 && (npixels & 1) == 0);
-
- /* Select the SD1329 controller */
-
- rit_select(priv->spi);
-
- /* Setup a window that describes a run starting at the specified column
- * and row, and ending at the column + npixels on the same row.
- */
-
- cmd[0] = SSD1329_SET_COLADDR;
- cmd[1] = col >> 1;
- cmd[2] = ((col + npixels) >> 1) - 1;
- rit_sndcmd(priv, cmd, 3);
-
- cmd[0] = SSD1329_SET_ROWADDR;
- cmd[1] = row;
- cmd[2] = row;
- rit_sndcmd(priv, cmd, 3);
-
- /* Write the run to GDDRAM. */
-
- rit_sndcmd(priv, g_horzinc, sizeof(g_horzinc));
- rit_snddata(priv, buffer, npixels >> 1);
-
- /* De-select the SD1329 controller */
-
- rit_deselect(priv->spi);
- }
-
- return OK;
-}
-#endif
-
-/**************************************************************************************
- * Name: rit_getrun
- *
- * Description:
- * This method can be used to read a partial raster line from the LCD:
- *
- * row - Starting row to read from (range: 0 <= row < yres)
- * col - Starting column to read read (range: 0 <= col <= xres-npixels)
- * buffer - The buffer in which to return the run read from the LCD
- * npixels - The number of pixels to read from the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-#ifdef CONFIG_P14201_FRAMEBUFFER
-static int rit_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels)
-{
- uint8_t *run;
- int start;
- int end;
- int aend;
- int i;
-
- ritdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer);
-
- /* Can't read from OLED GDDRAM in SPI mode, but we can read from the framebuffer */
- /* Toss out the special case of the empty run now */
-
- if (npixels < 1)
- {
- return OK;
- }
-
- /* Get the beginning of the line containing run in the framebuffer */
-
- run = g_framebuffer + row * RIT_XRES / 2;
-
- /* Get the starting and ending byte offsets containing the run.
- * the run starts at &run[start] and continues through run[end-1].
- * However, the first and final pixels at these locations may
- * not be byte aligned (see examples in putrun()).
- */
-
- start = col >> 1;
- aend = (col + npixels) >> 1;
- end = (col + npixels + 1) >> 1;
-
- /* Copy the run into the framebuffer, handling nibble alignment */
-
- if ((col & 1) == 0)
- {
- /* Check for the special case of only 1 pixels being copied */
-
- if (npixels > 1)
- {
- /* Beginning of buffer is properly aligned, from start to aend */
-
- memcpy(buffer, &run[start], aend - start + 1);
- }
-
- /* Handle any final pixel (including the special case where npixels == 1). */
-
- if (aend != end)
- {
- /* The leftmost column is contained in source bits 7:4 and in
- * destination bits 7:4
- */
-
- buffer[aend - start] = run[aend] & 0xf0;
- }
- }
- else
- {
- uint8_t curr = run[start];
- uint8_t last;
-
- /* Now construct the rest of the bytes in the run (possibly special
- * casing the final, partial byte below).
- */
-
- for (i = start + 1; i < aend; i++)
- {
- /* bits 3:0 from previous byte to run bits 7:4;
- * bits 7:4 of current byte to run bits 3:0
- */
-
- last = curr;
- curr = run[i];
- *buffer++ = (last << 4) | (curr >> 4);
- }
-
- /* Handle any final pixel (including the special case where npixels == 1). */
-
- if (aend != end)
- {
- /* The leftmost column is contained in source bits 3:0 and in
- * destination bits 7:4
- */
-
- *buffer = (curr << 4);
- }
- }
-
- return OK;
-}
-#else
-static int rit_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels)
-{
- /* Can't read from OLED GDDRAM in SPI mode */
-
- return -ENOSYS;
-}
-#endif
-
-/**************************************************************************************
- * Name: rit_getvideoinfo
- *
- * Description:
- * Get information about the LCD video controller configuration.
- *
- **************************************************************************************/
-
-static int rit_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo)
-{
- DEBUGASSERT(dev && vinfo);
- gvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n",
- g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes);
- memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: rit_getplaneinfo
- *
- * Description:
- * Get information about the configuration of each LCD color plane.
- *
- **************************************************************************************/
-
-static int rit_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo)
-{
- DEBUGASSERT(pinfo && planeno == 0);
- gvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp);
- memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: rit_getpower
- *
- * Description:
- * 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.
- *
- **************************************************************************************/
-
-static int rit_getpower(FAR struct lcd_dev_s *dev)
-{
- FAR struct rit_dev_s *priv = (FAR struct rit_dev_s *)dev;
- DEBUGASSERT(priv);
-
- gvdbg("power: %s\n", priv->on ? "ON" : "OFF");
- return priv->on ? CONFIG_LCD_MAXPOWER : 0;
-}
-
-/**************************************************************************************
- * Name: rit_setpower
- *
- * Description:
- * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On
- * backlit LCDs, this setting may correspond to the backlight setting.
- *
- **************************************************************************************/
-
-static int rit_setpower(struct lcd_dev_s *dev, int power)
-{
- struct rit_dev_s *priv = (struct rit_dev_s *)dev;
- DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER && priv->spi);
-
- gvdbg("power: %d\n", power);
-
- /* Select the SD1329 controller */
-
- rit_select(priv->spi);
-
- /* Only two power settings -- 0: sleep on, 1: sleep off */
-
- if (power > 0)
- {
- /* Re-initialize the SSD1329 controller */
-
- rit_sndcmds(priv, g_initcmds);
-
- /* Take the display out of sleep mode */
-
- rit_sndcmd(priv, g_sleepoff, sizeof(g_sleepoff));
- priv->on = true;
- }
- else
- {
- /* Put the display into sleep mode */
-
- rit_sndcmd(priv, g_sleepon, sizeof(g_sleepon));
- priv->on = false;
- }
-
- /* De-select the SD1329 controller */
-
- rit_deselect(priv->spi);
- return OK;
-}
-
-/**************************************************************************************
- * Name: rit_getcontrast
- *
- * Description:
- * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int rit_getcontrast(struct lcd_dev_s *dev)
-{
- struct rit_dev_s *priv = (struct rit_dev_s *)dev;
-
- gvdbg("contrast: %d\n", priv->contrast);
- return priv->contrast;
-}
-
-/**************************************************************************************
- * Name: rit_setcontrast
- *
- * Description:
- * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int rit_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
-{
- struct rit_dev_s *priv = (struct rit_dev_s *)dev;
- uint8_t cmd[3];
-
- gvdbg("contrast: %d\n", contrast);
- DEBUGASSERT(contrast <= CONFIG_LCD_MAXCONTRAST);
-
- /* Select the SD1329 controller */
-
- rit_select(priv->spi);
-
- /* Set new contrast */
-
- cmd[0] = SSD1329_SET_CONTRAST;
- cmd[1] = contrast;
- cmd[2] = SSD1329_NOOP;
- rit_sndcmd(priv, cmd, 3);
-
- /* De-select the SD1329 controller */
-
- rit_deselect(priv->spi);
- priv->contrast = contrast;
- return OK;
-}
-
-/**************************************************************************************
- * Public Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: rit_initialize
- *
- * Description:
- * Initialize the P14201 video hardware. The initial state of the OLED is fully
- * initialized, display memory cleared, and the OLED ready to use, but with the power
- * setting at 0 (full off == sleep mode).
- *
- * Input Parameters:
- * spi - A reference to the SPI driver instance.
- * devno - A value in the range of 0 throuh CONFIG_P14201_NINTERFACES-1. This allows
- * support for multiple OLED devices.
- *
- * Returned Value:
- * On success, this function returns a reference to the LCD object for the specified
- * OLED. NULL is returned on any failure.
- *
- **************************************************************************************/
-
-FAR struct lcd_dev_s *rit_initialize(FAR struct spi_dev_s *spi, unsigned int devno)
-{
- FAR struct rit_dev_s *priv = (FAR struct rit_dev_s *)&g_oleddev;
- DEBUGASSERT(devno == 0 && spi);
-
- gvdbg("Initializing devno: %d\n", devno);
-
- /* Driver state data */
-
- priv->spi = spi;
- priv->contrast = RIT_CONTRAST;
- priv->on = false;
-
- /* Select the SD1329 controller */
-
- rit_configspi(spi);
- rit_select(spi);
-
- /* Clear the display */
-
- rit_clear(priv);
-
- /* Configure (but don't enable) the OLED */
-
- rit_sndcmds(priv, g_initcmds);
-
- /* De-select the SD1329 controller */
-
- rit_deselect(spi);
- return &priv->dev;
-}
-#endif /* CONFIG_LCD_P14201 */
diff --git a/nuttx/drivers/lcd/pcf8833.h b/nuttx/drivers/lcd/pcf8833.h
deleted file mode 100644
index 36dc65ac3..000000000
--- a/nuttx/drivers/lcd/pcf8833.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/pcf8833.h
- * Definitions for the Phillips PCF8833 LCD controller
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References: "Data Sheet, PCF8833 STN RGB 132x132x3 driver," Phillips, 2003 Feb 14.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************/
-
-#ifndef __DRIVERS_LCD_PCF8833_H
-#define __DRIVERS_LCD_PCF8833_H
-
-/**************************************************************************************
- * Included Files
- **************************************************************************************/
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-/* Pixel format codes */
-
-#define PCF8833_FMT_8BPS (2)
-#define PCF8833_FMT_12BPS (3)
-#define PCF8833_FMT_16BPS (5)
-
-/* LCD Commands */
-
-#define PCF8833_NOP 0x00 /* No operation; Data: none */
-#define PCF8833_SWRESET 0x01 /* Software reset ; Data: none */
-#define PCF8833_BSTROFF 0x02 /* Booster voltage off; Data: none */
-#define PCF8833_BSTRON 0x03 /* Booster voltage on; Data: none */
-#define PCF8833_RDDIDIF 0x04 /* Read display identification; Data: none */
-#define PCF8833_RDDST 0x09 /* Read display status; Data: none */
-#define PCF8833_SLEEPIN 0x10 /* Sleep_IN; Data: none */
-#define PCF8833_SLEEPOUT 0x11 /* Sleep_OUT; Data: none */
-#define PCF8833_PTLON 0x12 /* Partial mode on; Data: none */
-#define PCF8833_NORON 0x13 /* Normal Display mode on; Data: none */
-#define PCF8833_INVOFF 0x20 /* Display inversion off; Data: none */
-#define PCF8833_INVON 0x21 /* Display inversion on; Data: none */
-#define PCF8833_DALO 0x22 /* All pixel off; Data: none */
-#define PCF8833_DAL 0x23 /* All pixel on; Data: none */
-#define PCF8833_SETCON 0x25 /* Set contrast; Data: (1) contrast */
-#define PCF8833_DISPOFF 0x28 /* Display off; Data: none */
-#define PCF8833_DISPON 0x29 /* Display on; Data: none */
-#define PCF8833_CASET 0x2a /* Column address set; Data: (1) X start (2) X end */
-#define PCF8833_PASET 0x2b /* Page address set Data: (1) Y start (2) Y end */
-#define PCF8833_RAMWR 0x2c /* Memory write; Data: (1) write data */
-#define PCF8833_RGBSET 0x2d /* Colour set; Data: (1-8) red tones, (9-16) green tones, (17-20) blue tones */
-#define PCF8833_PTLAR 0x30 /* Partial area; Data: (1) start address (2) end address */
-#define PCF8833_VSCRDEF 0x33 /* Vertical scroll definition; Data: (1) top fixed, (2) scrol area, (3) bottom fixed */
-#define PCF8833_TEOFF 0x34 /* Tearing line off; Data: none */
-#define PCF8833_TEON 0x35 /* Tearing line on; Data: (1) don't care */
-#define PCF8833_MADCTL 0x36 /* Memory data access control; Data: (1) access control settings */
-#define PCF8833_SEP 0x37 /* Set Scroll Entry Point; Data: (1) scroll entry point */
-#define PCF8833_IDMOFF 0x38 /* Idle mode off; Data: none */
-#define PCF8833_IDMON 0x39 /* Idle mode on; Data: none */
-#define PCF8833_COLMOD 0x3a /* Interface pixel format; Data: (1) color interface format */
-#define PCF8833_SETVOP 0xb0 /* Set VOP; Data: (1) VOP5-8 (2) VOP0-4 */
-#define PCF8833_BRS 0xb4 /* Bottom Row Swap; Data: none */
-#define PCF8833_TRS 0xb6 /* Top Row Swap; Data: none */
-#define PCF8833_FINV 0xb9 /* Super Frame INVersion; Data: none */
-#define PCF8833_DOR 0xba /* Data ORder; Data: none */
-#define PCF8833_TCDFE 0xbd /* Enable/disable DF temp comp; Data: none */
-#define PCF8833_TCVOPE 0xbf /* Enable or disable VOP temp comp; Data: none */
-#define PCF8833_EC 0xc0 /* Internal or external oscillator; Data: none */
-#define PCF8833_SETMUL 0xc2 /* Set multiplication factor; Data: (1) Multiplication factor */
-#define PCF8833_TCVOPAB 0xc3 /* Set TCVOP slopes A and B; Data: (1) SLB and SLA */
-#define PCF8833_TCVOPCD 0xc4 /* Set TCVOP slopes C and D; Data: (1) SLD and SLC */
-#define PCF8833_TCDF 0xc5 /* Set divider frequency; Data: Divider factor in region (1) A (2) B (3) C (4) D */
-#define PCF8833_DF8COLOR 0xc6 /* Set divider frequency 8-colour mode; Data: (1) DF80-6 */
-#define PCF8833_SETBS 0xc7 /* Set bias system; Data: (1) Bias systems */
-#define PCF8833_RDTEMP 0xc8 /* Temperature read back; Data: none */
-#define PCF8833_NLI 0xc9 /* N-Line Inversion; Data: (1) NLI time slots invervsion */
-#define PCF8833_RDID1 0xda /* Read ID1; Data: none */
-#define PCF8833_RDID2 0xdb /* Read ID2; Data: none */
-#define PCF8833_RDID3 0xdc /* Read ID3; Data: none */
-#define PCF8833_SFD 0xef /* Select factory defaults; Data: none */
-#define PCF8833_ECM 0xf0 /* Enter Calibration mode; Data: (1) Calibration control settings */
-#define PCF8833_OTPSHTIN 0xf1 /* Shift data in OTP shift registers; Data: Any number of bytes */
-
-/* Memory data access control (MADCTL) bit definitions */
-
-#define MADCTL_RGB (1 << 3) /* Bit 3: BGR */
-#define MADCTL_LAO (1 << 4) /* Bit 4: Line address order bottom to top */
-#define MADCTL_V (1 << 5) /* Bit 5: Vertical RAM write; in Y direction */
-#define MADCTL_MX (1 << 6) /* Bit 6: Mirror X */
-#define MADCTL_MY (1 << 7) /* Bit 7: Mirror Y */
-
-/* PCF8833 status register bit definitions */
-/* CMD format: RDDST command followed by four status bytes: */
-/* Byte 1: D31 d30 D29 D28 D27 D26 --- --- */
-
-#define PCF8833_ST_RGB (1 << 2) /* Bit 2: D26 - RGB/BGR order */
-#define PCF8833_ST_LINEADDR (1 << 3) /* Bit 3: D27 - Line address order */
-#define PCF8833_ST_ADDRMODE (1 << 4) /* Bit 4: D28 - Vertical/horizontal addressing mode */
-#define PCF8833_ST_XADDR (1 << 5) /* Bit 5: D29 - X address order */
-#define PCF8833_ST_YADDR (1 << 6) /* Bit 6: D30 - Y address order */
-#define PCF8833_ST_BOOSTER (1 << 7) /* Bit 7: D31 - Booster voltage status */
-
-/* Byte 2: --- D22 D21 D20 D19 D18 D17 D16 */
-
-#define PCF8833_ST_NORMAL (1 << 0) /* Bit 0: D16 - Normal display mode */
-#define PCF8833_ST_SLEEPIN (1 << 1) /* Bit 1: D17 - Sleep in selected */
-#define PCF8833_ST_PARTIAL (1 << 2) /* Bit 2: D18 - Partial mode on */
-#define PCF8833_ST_IDLE (1 << 3) /* Bit 3: D19 - Idle mode selected */
-#define PCF8833_ST_PIXELFMT_SHIFT (4) /* Bits 4-6: D20-D22 - Interface pixel format */
-#define PCF8833_ST_PIXELFMT_MASK (7 << PCF8833_ST_PIXELFMT_SHIFT)
-# define PCF8833_ST_PIXELFMT_8BPS (PCF8833_FMT_8BPS << PCF8833_ST_PIXELFMT_SHIFT)
-# define PCF8833_ST_PIXELFMT_12BPS (PCF8833_FMT_12BPS << PCF8833_ST_PIXELFMT_SHIFT)
-# define PCF8833_ST_PIXELFMT_16BPS (PCF8833_FMT_16BPS << PCF8833_ST_PIXELFMT_SHIFT)
-
-/* Byte 3: D15 -- D13 D12 D11 D10 D9 --- */
-
-#define PCF8833_ST_TEARING (1 << 1) /* Bit 1: D9 - Tearing effect on */
-#define PCF8833_ST_DISPLAYON (1 << 2) /* Bit 2: D10 - Display on */
-#define PCF8833_ST_PIXELSOFF (1 << 3) /* Bit 3: D11 - All pixels off */
-#define PCF8833_ST_PIXELSON (1 << 4) /* Bit 4: D12 - All pixels on */
-#define PCF8833_ST_INV (1 << 5) /* Bit 5: D13 - Display inversion */
-#define PCF8833_ST_VSCROLL (1 << 7) /* Bit 6: D15 - Vertical scroll mode */
-
-/* Byte 4: All zero */
-
-#endif /* __DRIVERS_LCD_PCF8833_H */ \ No newline at end of file
diff --git a/nuttx/drivers/lcd/s1d15g10.h b/nuttx/drivers/lcd/s1d15g10.h
deleted file mode 100644
index 9b5f7738f..000000000
--- a/nuttx/drivers/lcd/s1d15g10.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/s1d15g10.h
- * Definitions for the Epson S1D15G0 LCD controller
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References: S1D15G0D08B000, Seiko Epson Corportation, 2002.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************/
-
-#ifndef __DRIVERS_LCD_S1D15G10_H
-#define __DRIVERS_LCD_S1D15G10_H
-
-/**************************************************************************************
- * Included Files
- **************************************************************************************/
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-
-/* Epson S1D15G10 Command Set */
-
-#define S1D15G10_DISON 0xaf /* Display on; Data: none */
-#define S1D15G10_DISOFF 0xae /* Display off; Data: none */
-#define S1D15G10_DISNOR 0xa6 /* Normal display; Data: none */
-#define S1D15G10_DISINV 0xa7 /* Inverse display; Data: none */
-#define S1D15G10_COMSCN 0xbb /* Common scan direction; Data: (1) common scan direction */
-#define S1D15G10_DISCTL 0xca /* Display control; Data: Data: (1) CL div, F1/2 pat, (2) duty, (3) FR inverse (4) dispersion */
-#define S1D15G10_SLPIN 0x95 /* Sleep in; Data: none */
-#define S1D15G10_SLPOUT 0x94 /* Sleep out; Data: none */
-#define S1D15G10_PASET 0x75 /* Page address set; Data: (1) start page, (2) end page */
-#define S1D15G10_CASET 0x15 /* Column address set; Data: (1) start addr, (2) end addr */
-#define S1D15G10_DATCTL 0xbc /* Data scan direction, etc.; Data: (1) inverse, scan dir (2) RGB, (3) gray-scale */
-#define S1D15G10_RGBSET8 0xce /* 256-color position set; Data: (1-8) red tones, (9-16) green tones, (17-20) blue tones */
-#define S1D15G10_RAMWR 0x5c /* Writing to memory; Data: (1) write data */
-#define S1D15G10_RAMRD 0x5d /* Reading from memory; Data: (1) read data */
-#define S1D15G10_PTLIN 0xa8 /* Partial display in; Data: (1) start addr, (2) end addr */
-#define S1D15G10_PTLOUT 0xa9 /* Partial display out; Data: none */
-#define S1D15G10_RMWIN 0xe0 /* Read and modify write; Data: none */
-#define S1D15G10_RMWOUT 0xee /* End; Data: none */
-#define S1D15G10_ASCSET 0xaa /* Area scroll set; Data: (1) top addr, (2) bottom addr, (3) Num blocks, (4) scroll mode */
-#define S1D15G10_SCSTART 0xab /* Scroll start set; Data: (1) start block addr */
-#define S1D15G10_OSCON 0xd1 /* Internal oscillation on; Data: none */
-#define S1D15G10_OSCOFF 0xd2 /* Internal oscillation off; Data: none */
-#define S1D15G10_PWRCTR 0x20 /* Power control; Data: (1) LCD drive power */
-#define S1D15G10_VOLCTR 0x81 /* Electronic volume control; Data: (1) volume value, (2) resistance ratio */
-#define S1D15G10_VOLUP 0xd6 /* Increment electronic control by 1; Data: none */
-#define S1D15G10_VOLDOWN 0xd7 /* Decrement electronic control by 1; Data: none */
-#define S1D15G10_TMPGRD 0x82 /* Temperature gradient set; Data: (1-14) temperature gradient */
-#define S1D15G10_EPCTIN 0xcd /* Control EEPROM; Data: (1) read/write */
-#define S1D15G10_EPCOUT 0xcc /* Cancel EEPROM control; Data: none */
-#define S1D15G10_EPMWR 0xfc /* Write into EEPROM; Data: none */
-#define S1D15G10_EPMRD 0xfd /* Read from EEPROM; Data: none */
-#define S1D15G10_EPSRRD1 0x7c /* Read register 1; Data: none */
-#define S1D15G10_EPSRRD2 0x7d /* Read regiser 2; Data: none */
-#define S1D15G10_NOP 0x25 /* NOP intruction (0x45?); Data: none */
-#define S1D15G10_STREAD 0x20 /* Status read; Data: none */
-
-/* Display control (DISCTL) bit definitions */
-
-#define DISCTL_PERIOD_SHIFT (0) /* P1: Bits 0-1, F1 and F2 drive-pattern switching period */
-#define DISCTL_PERIOD_MASK (3 << DISCTL_PERIOD_SHIFT)
-# define DISCTL_PERIOD_8 (0 << DISCTL_PERIOD_SHIFT)
-# define DISCTL_PERIOD_4 (1 << DISCTL_PERIOD_SHIFT)
-# define DISCTL_PERIOD_16 (2 << DISCTL_PERIOD_SHIFT)
-# define DISCTL_PERIOD_FLD (3 << DISCTL_PERIOD_SHIFT)
-#define DISCTL_CLDIV_SHIFT (2) /* P1: Bits 2-4, Clock divider */
-#define DISCTL_CLDIV_MASK (7 << DISCTL_CLDIV_SHIFT)
-# define DISCTL_CLDIV_2 (0 << DISCTL_CLDIV_SHIFT)
-# define DISCTL_CLDIV_4 (1 << DISCTL_CLDIV_SHIFT)
-# define DISCTL_CLDIV_8 (2 << DISCTL_CLDIV_SHIFT)
-# define DISCTL_CLDIV_NONE (3 << DISCTL_CLDIV_SHIFT)
-
-/* Power control (PWRCTR) bit definitions */
-
-#define PWCTR_REFVOLTAGE (1 << 0) /* P1: Bit 0, Turn on reference voltage generation circuit. */
-#define PWCTR_REGULATOR (1 << 1) /* P1: Bit 1, Turn on voltage regulator and circuit voltage follower. */
-#define PWCTR_BOOSTER2 (1 << 2) /* P1: Bit 2, Turn on secondary booster/step-down circuit. */
-#define PWCTR_BOOSTER1 (1 << 3) /* P1: Bit 3, Turn on primary booster circuit. */
-#define PWCTR_EXTR (1 << 4) /* P1: Bit 4, Use external resistance to adjust voltage. */
-
-/* Data control (DATCTL) bit definitions */
-
-#define DATCTL_PGADDR_INV (1 << 0) /* P1: Bit 0, Inverse display of the page address. */
-#define DATCTL_COLADDR_REV (1 << 1) /* P1: Bit 1, Reverse turn of column address. */
-#define DATCTL_ADDR_PGDIR (1 << 2) /* P1: Bit 2, Address-scan direction in page (vs column) direction. */
-
-#define DATCTL_BGR (1 << 0) /* P2: Bit0, RGB->BGR */
-
-#define DATCTL_8GRAY (1) /* P3: Bits 0-2 = 001, 8 gray-scale */
-#define DATCTL_16GRAY_A (2) /* P3: Bits 0-2 = 010, 16 gray-scale display type A */
-#define DATCTL_16GRAY_B (4) /* P3: Bits 0-2 = 100, 16 gray-scale display type B */
-
-/* Status register bit definions (after reset or NOP) */
-
-#define S1D15G10_SR_PARTIAL (1 << 0) /* Bit 0: Partial display */
-#define S1D15G10_SR_NORMAL (1 << 1) /* Bit 1: Normal (vs. inverse) display */
-#define S1D15G10_SR_EEPROM (1 << 2) /* Bit 2: EEPROM access */
-#define S1D15G10_SR_DISPON (1 << 3) /* Bit 3: Display on */
-#define S1D15G10_SR_COLSCAN (1 << 4) /* Bit 4: Column (vs. page) scan direction */
-#define S1D15G10_SR_RMW (1 << 5) /* Bit 5: Read modify write */
-#define S1D15G10_SR_SCROLL (3 << 6) /* Bits 6-7: Area scroll mode */
-
-/* Status register bit definions (after EPSRRD1) */
-
-#define S1D15G10_SR_VOLUME 0x3f /* Bits 0-5: Electronic volume control values */
-
-/* Status register bit definions (after EPSRRD2) */
-
-#define S1D15G10_SR_RRATIO 0x07 /* Bits 0-2: Built-in resistance ratio */
-
-#endif /* __DRIVERS_LCD_S1D15G10_H */ \ No newline at end of file
diff --git a/nuttx/drivers/lcd/sd1329.h b/nuttx/drivers/lcd/sd1329.h
deleted file mode 100644
index 5d2ad4948..000000000
--- a/nuttx/drivers/lcd/sd1329.h
+++ /dev/null
@@ -1,527 +0,0 @@
-/****************************************************************************
- * drivers/lcd/sd1329.h
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_LCD_SD1329_H
-#define __DRIVERS_LCD_SD1329_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <stdint.h>
-
-/****************************************************************************
- * Pre-Processor Definitions
- ****************************************************************************/
-
-/* SD1329 Commands **********************************************************/
-/* Set column Address.
- *
- * This triple byte command specifies column start address and end address of
- * the display data RAM. This command also sets the column address pointer to
- * column start address. This pointer is used to define the current read/write
- * column address in graphic display data RAM. If horizontal address increment
- * mode is enabled by command 0xa0, after finishing read/write one column data,
- * it is incremented automatically to the next column address. Whenever the
- * column address pointer finishes accessing the end column address, it is
- * reset back to start column address and the row address is incremented to the
- * next row.
- *
- * Byte 1: 0x15
- * Byte 2: A[5:0]: Start Address, range: 0x00-0x3f
- * Byte 3: B[5:0]: End Address, range: 0x00-0x3f
- */
-
-#define SSD1329_SET_COLADDR 0x15
-
-/* Set Row Address.
- *
- * This triple byte command specifies row start address and end address of the
- * display data RAM. This command also sets the row address pointer to row
- * start address. This pointer is used to define the current read/write row
- * address in graphic display data RAM. If vertical address increment mode is
- * enabled by command 0xa0, after finishing read/write one row data, it is
- * incremented automatically to the next row address. Whenever the row address
- * pointer finishes accessing the end row address, it is reset back to start
- * row address.
- *
- * Byte 1: 0x75
- * Byte 2: A[6:0]: Start Address, range: 0x00-0x7f
- * Byte 3: B[6:0]: End Address, range: 0x00-0x7f
- */
-
-#define SSD1329_SET_ROWADDR 0x75
-
-/* Set Contract Current
- *
- * This double byte command is to set Contrast Setting of the display. The
- * chip has 256 contrast steps from 0x00 to 0xff. The segment output current
- * increases linearly with the increase of contrast step.
- *
- * Byte 1: 0x81
- * Byte 2: A[7:0]: Contrast Value, range: 0-255
- */
-
-#define SSD1329_SET_CONTRAST 0x81
-
-/* Set Second Pre-Charge Speed
- *
- * This command is used to set the speed of second pre-charge in phase 3.
- * This speed can be doubled to achieve faster pre-charging through setting
- * 0x82 A[0].
- *
- * Byte 1: 0x82
- * Byte 2: A[7:1]: Second Pre-charge Speed
- * A[0] = 1, Enable doubling the Second Pre-charge speed
- */
-
-#define SSD1329_PRECHRG2_SPEED 0x82
-# define SSD1329_PRECHRG2_DBL 0x01
-
-/* Set Master Icon Control
- *
- * This double command is used to set the ON / OFF conditions of internal
- * charge pump, icon circuits and overall icon status.
- *
- * Byte 1: 0x90
- * Byte 2: Icon control (OR of bits 0-1,4-5)
- */
-
-#define SSD1329_ICON_CONTROL 0x90
-# define SSD1329_ICON_NORMAL 0x00 /* A[1:0]1=00: Icon RESET to normal display */
-# define SSD1329_ICON_ALLON 0x01 /* A[1:0]1=01: Icon All ON */
-# define SSD1329_ICON_ALLOFF 0x02 /* A[1:0]=10: Icon All OFF */
-# define SSD1329_ICON_DISABLE 0x00 /* A[4]=0: Disable Icon display */
-# define SSD1329_ICON_ENABLE 0x10 /* A[4]=1: Enable Icon display */
-# define SSD1329_VICON_DISABLE 0x00 /* A[5]=0: Disable VICON charge pump circuit */
-# define SSD1329_VICON_ENABLE 0x20 /* A[5]=1: Enable VICON charge pump circuit */
-
-/* Set Icon Current Range
- *
- * This double byte command is used to set one fix current range for all icons
- * between the range of 0uA and 127.5uA. The uniformity improves as the icon
- * current range increases.
- *
- * Byte 1: 0x91
- * Byte 2: A[7:0]: Max icon current:
- * 00 = 0.0 uA
- * 01 = 0.5 uA
- * ...
- * ff = 127.5 uA
- */
-
-#define SSD1329_ICON_CURRRNG 0x91
-
-/* Set Individual Icon Current
- *
- * This multiple byte command is used to fine tune the current for each of the
- * 64 icons. Command 0x92 followed by 64 single byte data. These 64 byte data
- * have to be entered in order to make this command function. Below is the
- * formula for calculating the icon current.
- *
- * Icon Current = Single byte value / 127 x Maximum icon current set with command 0x91
- *
- * Byte 1: 0x92
- * Byte 2-65: An[6:0]: icon current for ICSn, range: 0x00-0x7f
- * Icon Current of ICSn = An[6:0]/127) x max icon current
- */
-
-#define SSD1329_ICON_CURRENT 0x92
-
-/* Set Individual Icon ON / OFF Register
- *
- * This double byte command is used to select one of the 64 icons and choose the
- * ON, OFF or blinking condition of the selected icon.
- *
- * Byte 1: 0x93
- * Byte 2: A[5:0]: Select one of the 64 icons from ICS0 ~ ICS63
- * A[7:6]: OFF/ON/BLINK
- */
-
-#define SSD1329_ICON_SELECT 0x93
-# define SSD1329_ICON_OFF 0x00
-# define SSD1329_ICON_ON 0x40
-# define SSD1329_ICON_BLINK 0xc0
-
-/* Set Icon ON / OFF Registers
- *
- * This double byte command is used to set the ON / OFF status of all 64 icons.
- *
- * Byte 1: 0x94
- * Byte 2: A[7:6]: OFF/ON/BLINK (Same as 0x93)
- */
-
-#define SSD1329_ICON_ALL 0x94
-
-/* Set Icon Blinking Cycle
- *
- * This double byte command is used to set icon oscillator frequency and
- * blinking cycle selected with above command 0x93.
- *
- * Byte 1: 0x95
- * Byte 2:
- * - A[2:0]:Icon Blinking cycle
- * - A[5:4]:Icon oscillation frequency
- */
-
-#define SSD1329_ICON_BLINKING 0x95
-# define SSD1329_ICON_BLINK_0p25S 0x00 /* 0.25 sec */
-# define SSD1329_ICON_BLINK_0p50S 0x01 /* 0.50 sec */
-# define SSD1329_ICON_BLINK_0p75S 0x02 /* 0.75 sec */
-# define SSD1329_ICON_BLINK_0p100S 0x03 /* 1.00 sec */
-# define SSD1329_ICON_BLINK_0p125S 0x04 /* 1.25 sec */
-# define SSD1329_ICON_BLINK_0p150S 0x05 /* 1.50 sec */
-# define SSD1329_ICON_BLINK_0p175S 0x06 /* 1.75 sec */
-# define SSD1329_ICON_BLINK_0p200S 0x07 /* 2.00 sec */
-# define SSD1329_ICON_BLINK_61KHZ 0x00 /* 61 KHz */
-# define SSD1329_ICON_BLINK_64KHZ 0x10 /* 64 KHz */
-# define SSD1329_ICON_BLINK_68KHZ 0x20 /* 68 KHz */
-# define SSD1329_ICON_BLINK_73KHZ 0x30 /* 73 KHz */
-
-/* Set Icon Duty
- *
- * This double byte command is used to set the icon frame frequency and icon AC
- * drive duty ratio.
- *
- * Byte 1: 0x96
- * Byte 2:
- * - A[2:0]: AC Drive
- * - A[7:4]: con frame frequency
- */
-
-#define SSD1329_ICON_ACDRIVE 0x96
-# define SSD1329_ICON_DUTY_DC 0x00
-# define SSD1329_ICON_DUTY_63_64 0x01
-# define SSD1329_ICON_DUTY_62_64 0x02
-# define SSD1329_ICON_DUTY_61_64 0x03
-# define SSD1329_ICON_DUTY_60_64 0x04
-# define SSD1329_ICON_DUTY_59_64 0x05
-# define SSD1329_ICON_DUTY_58_64 0x06
-# define SSD1329_ICON_DUTY_57_64 0x07
-
-/* Set Re-map
- *
- * This double command has multiple configurations and each bit setting is
- * described as follows:
- *
- * Column Address Remapping (A[0])
- * This bit is made for increase the flexibility layout of segment signals in
- * OLED module with segment arranged from left to right (when A[0] is set to 0)
- * or from right to left (when A[0] is set to 1).
- *
- * Nibble Remapping (A[1])
- * When A[1] is set to 1, the two nibbles of the data bus for RAM access are
- * re-mapped, such that (D7, D6, D5, D4, D3, D2, D1, D0) acts like (D3, D2, D1,
- * D0, D7, D6, D5, D4) If this feature works together with Column Address
- * Re-map, it would produce an effect of flipping the outputs from SEG0-127 to
- * SEG127-SEG0.
- *
- * Address increment mode (A[2])
- * When A[2] is set to 0, the driver is set as horizontal address incremen
- * mode. After the display RAM is read/written, the column address pointer is
- * increased automatically by 1. If the column address pointer reaches column
- * end address, the column address pointer is reset to column start address and
- * row address pointer is increased by 1.
- *
- * When A[2] is set to 1, the driver is set to vertical address increment mode.
- * After the display RAM is read/written, the row address pointer is increased
- * automatically by 1. If the row address pointer reaches the row end address,
- * the row address pointer is reset to row start address and column address
- * pointer is increased by 1.
- *
- * COM Remapping (A[4])
- * This bit defines the scanning direction of the common for flexible layout
- * of common signals in OLED module either from up to down (when A[4] is set to
- * 0) or from bottom to up (when A[4] is set to 1).
- *
- * Splitting of Odd / Even COM Signals (A[6])
- * This bit is made to match the COM layout connection on the panel. When A[6]
- * is set to 0, no splitting odd / even of the COM signal is performed. When
- * A[6] is set to 1, splitting odd / even of the COM signal is performed,
- * output pin assignment sequence is shown as below (for 128MUX ratio):
- *
- * Byte 1: 0xa0
- * Byte 2: A[7:0]
- */
-
-#define SSD1329_GDDRAM_REMAP 0xa0
-# define SSD1329_COLADDR_REMAP 0x01 /* A[0]: Enable column re-map */
-# define SSD1329_NIBBLE_REMAP 0x02 /* A[1]: Enable nibble re-map */
-# define SSD1329_VADDR_INCR 0x04 /* A[1]: Enable vertical address increment */
-# define SSD1329_COM_REMAP 0x10 /* A[4]: Enable COM re-map */
-# define SSD1329_COM_SPLIT 0x40 /* A[6]: Enable COM slip even/odd */
-
-/* Set Display Start Line
- *
- * This double byte command is to set Display Start Line register for
- * determining the starting address of display RAM to be displayed by selecting
- * a value from 0 to 127.
- *
- * Byte 1: 0xa1
- * Byte 2: A[6:0]: Vertical scroll by setting the starting address of
- * display RAM from 0-127
- */
-
-#define SSD1329_VERT_START 0xa1
-
-/* Set Display Offset
- *
- * This double byte command specifies the mapping of display start line (it is
- * assumed that COM0 is the display start line, display start line register
- * equals to 0) to one of COM0-COM127.
- *
- * Byte 1: 0xa2
- * Byte 2: A[6:0]: Set vertical offset by COM from 0-127
- */
-
-#define SSD1329_VERT_OFFSET 0xa2
-
-/* Set Display Mode - Normal, all on, all off, inverse
- *
- * These are single byte commands and are used to set display status to Normal
- * Display, Entire Display ON, Entire Display OFF or Inverse Display.
- *
- * Normal Display (0xa4)
- * Reset the “Entire Display ON, Entire Display OFF or Inverse Display” effects
- * and turn the data to ON at the corresponding gray level.
- *
- * Set Entire Display ON (0xa5)
- * Force the entire display to be at gray scale level GS15, regardless of the
- * contents of the display data RAM.
- *
- * Set Entire Display OFF (0xa6)
- * Force the entire display to be at gray scale level GS0, regardless of the
- * contents of the display data RAM.
- *
- * Inverse Display (0xa7)
- * The gray scale level of display data are swapped such that “GS0” <-> “GS15”,
- * “GS1” <-> “GS14”, etc.
- *
- * Byte 1: Display mode command
- */
-
-#define SSD1329_DISP_NORMAL 0xa4
-#define SSD1329_DISP_OFF 0xa5
-#define SSD1329_DISP_ON 0xa6
-#define SSD1329_DISP_INVERT 0xa7
-
-/* Set MUX Ratio
- *
- * This double byte command sets multiplex ratio (MUX ratio) from 16MUX to
- * 128MUX. In POR, multiplex ratio is 128MUX.
- *
- * Byte 1: 0xa8
- * Byte 2: A[6:0] 15-127 representing 16-128 MUX
- */
-
-#define SSD1329_MUX_RATIO 0xa8
-
-/* Set Sleep mode ON / OFF
- *
- * These single byte commands are used to turn the matrix display on the OLED
- * panel display either ON or OFF. When the sleep mode is set to ON (0xae), the
- * display is OFF, the segment and common output are in high impedance state
- * and circuits will be turned OFF. When the sleep mode is set to OFF (0xaf),
- * the display is ON.
- *
- * Byte 1: sleep mode command
- */
-
-#define SSD1329_SLEEP_ON 0xae
-#define SSD1329_SLEEP_OFF 0xaf
-
-/* Set Phase Length
- *
- * In the second byte of this double command, lower nibble and higher nibble is
- * defined separately. The lower nibble adjusts the phase length of Reset (phase
- * 1). The higher nibble is used to select the phase length of first pre-charge
- * phase (phase 2). The phase length is ranged from 1 to 16 DCLK's. RESET for
- * A[3:0] is set to 3 which means 4 DCLK’s selected for Reset phase. POR for
- * A[7:4] is set to 5 which means 6 DCLK’s is selected for first pre-charge
- * phase. Please refer to Table 9-1 for detail breakdown levels of each step.
- *
- * Byte 1: 0xb1
- * Byte 2: A[3:0]: Phase 1 period of 1~16 DCLK’s
- * A[7:4]: Phase 2 period of 1~16 DCLK’s
- */
-
-#define SSD1329_PHASE_LENGTH 0xb1
-
-/* Set Frame Frequency
- *
- * This double byte command is used to set the number of DCLK’s per row between
- * the range of 0x14 and 0x7f. Then the Frame frequency of the matrix display
- * is equal to DCLK frequency / A[6:0].
- *
- * Byte 1: 0xb2
- * Byte 2: A[6:0]:Total number of DCLK’s per row. Ranging from
- * 0x14 to 0x4e DCLK’s. frame Frequency = DCLK freq /A[6:0].
- */
-
-#define SSD1329_FRAME_FREQ 0xb2
-
-/* Set Front Clock Divider / Oscillator Frequency
- *
- * This double command is used to set the frequency of the internal display
- * clocks, DCLK's. It is defined by dividing the oscillator frequency by the
- * divide ratio (Value from 1 to 16). Frame frequency is determined by divide
- * ratio, number of display clocks per row, MUX ratio and oscillator frequency.
- * The lower nibble of the second byte is used to select the oscillator
- * frequency. Please refer to Table 9-1 for detail breakdown levels of each
- * step.
- *
- * Byte 1: 0xb3
- * Byte 2: A[3:0]: Define divide ratio (D) of display clock (DCLK)
- * Divide ratio=A[3:0]+1
- * A[7:4] : Set the Oscillator Frequency, FOSC. Range:0-15
- */
-
-#define SSD1329_DCLK_DIV 0xb3
-
-/* Set Default Gray Scale Table
- *
- * This single byte command is used to set the gray scale table to initial
- * default setting.
- *
- * Byte 1: 0xb7
- */
-
-#define SSD1329_GSCALE_TABLE 0xb7
-
-/* Look Up Table for Gray Scale Pulse width
- *
- * This command is used to set each individual gray scale level for the display.
- * Except gray scale level GS0 that has no pre-charge and current drive, each
- * gray scale level is programmed in the length of current drive stage pulse
- * width with unit of DCLK. The longer the length of the pulse width, the
- * brighter the OLED pixel when it’s turned ON.
- *
- * The setting of gray scale table entry can perform gamma correction on OLED
- * panel display. Normally, it is desired that the brightness response of the
- * panel is linearly proportional to the image data value in display data RAM.
- * However, the OLED panel is somehow responded in non-linear way. Appropriate
- * gray scale table setting like example below can compensate this effect.
- *
- * Byte 1: 0xb8
- * Bytes 2-16: An[5:0], value for GSn level Pulse width
- */
-
-#define SSD1329_GSCALE_LOOKUP 0xb8
-
-/* Set Second Pre-charge Period
- *
- * This double byte command is used to set the phase 3 second pre-charge period.
- * The period of phase 3 can be programmed by command 0xbb and it is ranged from
- * 0 to 15 DCLK's.
- *
- * Byte 1: 0xbb
- * Byte 2: 0-15 DCLKs
- */
-
-#define SSD1329_PRECHRG2_PERIOD 0xbb
-
-/* Set First Precharge voltage, VP
- *
- * This double byte command is used to set phase 2 first pre-charge voltage
- * level. It can be programmed to set the first pre-charge voltage reference to
- * VCC or VCOMH.
- *
- * Byte 1: 0xbc
- * Byte 2: A[5] == 0, Pre-charge voltage is (0.30 + A[4:0]) * Vcc
- * A{5] == 1, 1.00 x VCC or connect to VCOMH if VCC > VCOMH
- */
-
-#define SSD1329_PRECHRG1_VOLT 0xbc
-
-/* Set VCOMH
- *
- * This double byte command sets the high voltage level of common pins, VCOMH.
- * The level of VCOMH is programmed with reference to VCC.
- *
- * Byte 1: 0xbe
- * Byte 2: (0.51 + A[5:0]) * Vcc
- */
-
-#define SSD1329_COM_HIGH 0xbe
-
-/* NOOP
- *
- * This is a no operation command.
- *
- * Byte 1: 0xe3
- */
-
-#define SSD1329_NOOP 0xe3
-
-/* Set Command Lock
- *
- * This command is used to lock the MCU from accepting any command.
- *
- * Byte 1: 0xfd
- * Byte 2: 0x12 | A[2]
- * A[2] == 1, Enable locking the MCU from entering command
- */
-
-#define SSD1329_CMD_LOCK 0xfd
-# define SSD1329_LOCK_ON 0x13
-# define SSD1329_LOCK_OFF 0x12
-
-/* SD1329 Status ************************************************************/
-
-#define SDD1329_STATUS_ON 0x00 /* D[6]=0: indicates the display is ON */
-#define SDD1329_STATUS_OFF 0x40 /* D[6]=1: indicates the display is OFF */
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-#endif /* __DRIVERS_LCD_SD1329_H */
diff --git a/nuttx/drivers/lcd/skeleton.c b/nuttx/drivers/lcd/skeleton.c
deleted file mode 100644
index 83aa92018..000000000
--- a/nuttx/drivers/lcd/skeleton.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/skeleton.c
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/spi.h>
-#include <nuttx/lcd/lcd.h>
-
-#include "up_arch.h"
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-
-/* Configuration **********************************************************************/
-/* Verify that all configuration requirements have been met */
-
-/* Debug ******************************************************************************/
-/* Define the following to enable register-level debug output */
-
-#undef CONFIG_LCD_SKELDEBUG
-
-/* Verbose debug must also be enabled */
-
-#ifndef CONFIG_DEBUG
-# undef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_DEBUG_GRAPHICS
-#endif
-
-#ifndef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_LCD_SKELDEBUG
-#endif
-
-/* Color Properties *******************************************************************/
-
-/* Display Resolution */
-
-#define SKEL_XRES 320
-#define SKEL_YRES 240
-
-/* Color depth and format */
-
-#define SKEL_BPP 16
-#define SKEL_COLORFMT FB_FMT_RGB16_565
-
-/* Debug ******************************************************************************/
-
-#ifdef CONFIG_LCD_SKELDEBUG
-# define skeldbg(format, arg...) vdbg(format, ##arg)
-#else
-# define skeldbg(x...)
-#endif
-
-/**************************************************************************************
- * Private Type Definition
- **************************************************************************************/
-
-/* This structure describes the state of this driver */
-
-struct skel_dev_s
-{
- /* Publically visible device structure */
-
- struct lcd_dev_s dev;
-
- /* Private LCD-specific information follows */
-};
-
-/**************************************************************************************
- * Private Function Protototypes
- **************************************************************************************/
-
-/* LCD Data Transfer Methods */
-
-static int skel_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels);
-static int skel_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels);
-
-/* LCD Configuration */
-
-static int skel_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo);
-static int skel_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo);
-
-/* LCD RGB Mapping */
-
-#ifdef CONFIG_FB_CMAP
-# error "RGB color mapping not supported by this driver"
-#endif
-
-/* Cursor Controls */
-
-#ifdef CONFIG_FB_HWCURSOR
-# error "Cursor control not supported by this driver"
-#endif
-
-/* LCD Specific Controls */
-
-static int skel_getpower(struct lcd_dev_s *dev);
-static int skel_setpower(struct lcd_dev_s *dev, int power);
-static int skel_getcontrast(struct lcd_dev_s *dev);
-static int skel_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
-
-/**************************************************************************************
- * Private Data
- **************************************************************************************/
-
-/* This is working memory allocated by the LCD driver for each LCD device
- * and for each color plane. This memory will hold one raster line of data.
- * The size of the allocated run buffer must therefore be at least
- * (bpp * xres / 8). Actual alignment of the buffer must conform to the
- * bitwidth of the underlying pixel type.
- *
- * If there are multiple planes, they may share the same working buffer
- * because different planes will not be operate on concurrently. However,
- * if there are multiple LCD devices, they must each have unique run buffers.
- */
-
-static uint16_t g_runbuffer[SKEL_XRES];
-
-/* This structure describes the overall LCD video controller */
-
-static const struct fb_videoinfo_s g_videoinfo =
-{
- .fmt = SKEL_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
- .xres = SKEL_XRES, /* Horizontal resolution in pixel columns */
- .yres = SKEL_YRES, /* Vertical resolution in pixel rows */
- .nplanes = 1, /* Number of color planes supported */
-};
-
-/* This is the standard, NuttX Plane information object */
-
-static const struct lcd_planeinfo_s g_planeinfo =
-{
- .putrun = skel_putrun, /* Put a run into LCD memory */
- .getrun = skel_getrun, /* Get a run from LCD memory */
- .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */
- .bpp = SKEL_BPP, /* Bits-per-pixel */
-};
-
-/* This is the standard, NuttX LCD driver object */
-
-static struct skel_dev_s g_lcddev =
-{
- .dev =
- {
- /* LCD Configuration */
-
- .getvideoinfo = skel_getvideoinfo,
- .getplaneinfo = skel_getplaneinfo,
-
- /* LCD RGB Mapping -- Not supported */
- /* Cursor Controls -- Not supported */
-
- /* LCD Specific Controls */
-
- .getpower = skel_getpower,
- .setpower = skel_setpower,
- .getcontrast = skel_getcontrast,
- .setcontrast = skel_setcontrast,
- },
-};
-
-/**************************************************************************************
- * Private Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: skel_putrun
- *
- * Description:
- * This method can be used to write a partial raster line to the LCD:
- *
- * row - Starting row to write to (range: 0 <= row < yres)
- * col - Starting column to write to (range: 0 <= col <= xres-npixels)
- * buffer - The buffer containing the run to be written to the LCD
- * npixels - The number of pixels to write to the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-static int skel_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels)
-{
- /* Buffer must be provided and aligned to a 16-bit address boundary */
-
- gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
-
- /* Set up to write the run. */
-
- /* Write the run to GRAM. */
-#warning "Missing logic"
- return OK;
-}
-
-/**************************************************************************************
- * Name: skel_getrun
- *
- * Description:
- * This method can be used to read a partial raster line from the LCD:
- *
- * row - Starting row to read from (range: 0 <= row < yres)
- * col - Starting column to read read (range: 0 <= col <= xres-npixels)
- * buffer - The buffer in which to return the run read from the LCD
- * npixels - The number of pixels to read from the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-static int skel_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels)
-{
- /* Buffer must be provided and aligned to a 16-bit address boundary */
-
- gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
-
-#warning "Missing logic"
- return -ENOSYS;
-}
-
-/**************************************************************************************
- * Name: skel_getvideoinfo
- *
- * Description:
- * Get information about the LCD video controller configuration.
- *
- **************************************************************************************/
-
-static int skel_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo)
-{
- DEBUGASSERT(dev && vinfo);
- gvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n",
- g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes);
- memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: skel_getplaneinfo
- *
- * Description:
- * Get information about the configuration of each LCD color plane.
- *
- **************************************************************************************/
-
-static int skel_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo)
-{
- DEBUGASSERT(dev && pinfo && planeno == 0);
- gvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp);
- memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: skel_getpower
- *
- * Description:
- * 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.
- *
- **************************************************************************************/
-
-static int skel_getpower(struct lcd_dev_s *dev)
-{
- struct skel_dev_s *priv = (struct skel_dev_s *)dev;
- gvdbg("power: %d\n", 0);
-#warning "Missing logic"
- return 0;
-}
-
-/**************************************************************************************
- * Name: skel_setpower
- *
- * Description:
- * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On
- * backlit LCDs, this setting may correspond to the backlight setting.
- *
- **************************************************************************************/
-
-static int skel_setpower(struct lcd_dev_s *dev, int power)
-{
- struct skel_dev_s *priv = (struct skel_dev_s *)dev;
-
- gvdbg("power: %d\n", power);
- DEBUGASSERT(power <= CONFIG_LCD_MAXPOWER);
-
- /* Set new power level */
-#warning "Missing logic"
-
- return OK;
-}
-
-/**************************************************************************************
- * Name: skel_getcontrast
- *
- * Description:
- * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int skel_getcontrast(struct lcd_dev_s *dev)
-{
- gvdbg("Not implemented\n");
-#warning "Missing logic"
- return -ENOSYS;
-}
-
-/**************************************************************************************
- * Name: skel_setcontrast
- *
- * Description:
- * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int skel_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
-{
- gvdbg("contrast: %d\n", contrast);
-#warning "Missing logic"
- return -ENOSYS;
-}
-
-/**************************************************************************************
- * Public Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: up_oledinitialize
- *
- * Description:
- * Initialize the LCD video hardware. The initial state of the LCD is fully
- * initialized, display memory cleared, and the LCD ready to use, but with the power
- * setting at 0 (full off).
- *
- **************************************************************************************/
-
-FAR struct lcd_dev_s *up_oledinitialize(FAR struct spi_dev_s *spi)
-{
- gvdbg("Initializing\n");
-
- /* Configure GPIO pins */
-#warning "Missing logic"
-
- /* Enable clocking */
-#warning "Missing logic"
-
- /* Configure and enable LCD */
- #warning "Missing logic"
-
- return &g_lcddev.dev;
-}
diff --git a/nuttx/drivers/lcd/ssd1289.c b/nuttx/drivers/lcd/ssd1289.c
deleted file mode 100644
index d78688be5..000000000
--- a/nuttx/drivers/lcd/ssd1289.c
+++ /dev/null
@@ -1,1380 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/ssd1289.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 proably ahve to
- * customize for any particular LCD hardware.
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Authors: Gregory Nutt <gnutt@nuttx.org>
- *
- * References: SSD1289, Rev 1.3, Apr 2007, Solomon Systech Limited
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/spi.h>
-#include <nuttx/lcd/lcd.h>
-#include <nuttx/lcd/ssd1289.h>
-
-#include "ssd1289.h"
-
-#ifdef CONFIG_LCD_SSD1289
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-/* Configuration **********************************************************************/
-
-/* Check contrast selection */
-
-#if !defined(CONFIG_LCD_MAXCONTRAST)
-# define CONFIG_LCD_MAXCONTRAST 1
-#endif
-
-/* Check power setting */
-
-#if !defined(CONFIG_LCD_MAXPOWER) || CONFIG_LCD_MAXPOWER < 1
-# define CONFIG_LCD_MAXPOWER 1
-#endif
-
-#if CONFIG_LCD_MAXPOWER > 255
-# error "CONFIG_LCD_MAXPOWER must be less than 256 to fit in uint8_t"
-#endif
-
-/* Check orientation */
-
-#if defined(CONFIG_LCD_PORTRAIT)
-# if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE) || defined(CONFIG_LCD_RPORTRAIT)
-# error "Cannot define both portrait and any other orientations"
-# endif
-#elif defined(CONFIG_LCD_RPORTRAIT)
-# if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-# error "Cannot define both rportrait and any other orientations"
-# endif
-#elif defined(CONFIG_LCD_LANDSCAPE)
-# ifdef CONFIG_LCD_RLANDSCAPE
-# error "Cannot define both landscape and any other orientations"
-# endif
-#elif !defined(CONFIG_LCD_RLANDSCAPE)
-# define CONFIG_LCD_LANDSCAPE 1
-#endif
-
-/* Define CONFIG_DEBUG_LCD to enable detailed LCD debug output. Verbose debug must
- * also be enabled.
- */
-
-#ifndef CONFIG_DEBUG
-# undef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_DEBUG_GRAPHICS
-# undef CONFIG_DEBUG_LCD
-#endif
-
-#ifndef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_DEBUG_LCD
-#endif
-
-/* Display/Color Properties ***********************************************************/
-/* Display Resolution */
-
-#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-# define SSD1289_XRES 320
-# define SSD1289_YRES 240
-#else
-# define SSD1289_XRES 240
-# define SSD1289_YRES 320
-#endif
-
-/* Color depth and format */
-
-#define SSD1289_BPP 16
-#define SSD1289_COLORFMT FB_FMT_RGB16_565
-
-/* LCD Profiles ***********************************************************************/
-/* Many details of the controller initialization must, unfortunately, vary from LCD to
- * LCD. I have looked at the spec and at three different drivers for LCDs that have
- * SSD1289 controllers. I have tried to summarize these differences as "LCD profiles"
- *
- * Most of the differences between LCDs are nothing more than a few minor bit
- * settings. The most significant difference betwen LCD drivers in is the
- * manner in which the LCD is powered up and in how the power controls are set.
- * My suggestion is that if you have working LCD initialization code, you should
- * simply replace the code in ssd1289_hwinitialize with your working code.
- */
-
-#if defined (CONFIG_SSD1289_PROFILE2)
-# undef SSD1289_USE_SIMPLE_INIT
-
- /* PWRCTRL1: AP=smalll-to-medium, DC=Flinex24, BT=+5/-4, DCT=Flinex24 */
-
-# define PWRCTRL1_SETTING \
- (SSD1289_PWRCTRL1_AP_SMMED | SSD1289_PWRCTRL1_DC_FLINEx24 | \
- SSD1289_PWRCTRL1_BT_p5m4 | SSD1289_PWRCTRL1_DCT_FLINEx24)
-
- /* PWRCTRL2: 5.1v */
-
-# define PWRCTRL2_SETTING SSD1289_PWRCTRL2_VRC_5p1V
-
- /* PWRCTRL3: x 2.165
- * NOTE: Many drivers have bit 8 set which is not defined in the SSD1289 spec.
- */
-
-# define PWRCTRL3_SETTING SSD1289_PWRCTRL3_VRH_x2p165
-
- /* PWRCTRL4: VDV=9 + VCOMG */
-
-# define PWRCTRL4_SETTING (SSD1289_PWRCTRL4_VDV(9) | SSD1289_PWRCTRL4_VCOMG)
-
- /* PWRCTRL5: VCM=56 + NOTP */
-
-# define PWRCTRL5_SETTING (SSD1289_PWRCTRL5_VCM(56) | SSD1289_PWRCTRL5_NOTP)
-
-#elif defined (CONFIG_SSD1289_PROFILE3)
-# undef SSD1289_USE_SIMPLE_INIT
-
- /* PWRCTRL1: AP=smalll-to-medium, DC=Flinex24, BT=+5/-4, DCT=Flinex24 */
-
-# define PWRCTRL1_SETTING \
- (SSD1289_PWRCTRL1_AP_SMMED | SSD1289_PWRCTRL1_DC_FLINEx24 | \
- SSD1289_PWRCTRL1_BT_p5m4 | SSD1289_PWRCTRL1_DCT_FLINEx24)
-
- /* PWRCTRL2: 5.1v */
-
-# define PWRCTRL2_SETTING SSD1289_PWRCTRL2_VRC_5p1V
-
- /* PWRCTRL3: x 2.165
- * NOTE: Many drivers have bit 8 set which is not defined in the SSD1289 spec.
- */
-
-# define PWRCTRL3_SETTING SSD1289_PWRCTRL3_VRH_x2p165
-
- /* PWRCTRL4: VDV=9 + VCOMG */
-
-# define PWRCTRL4_SETTING (SSD1289_PWRCTRL4_VDV(9) | SSD1289_PWRCTRL4_VCOMG)
-
- /* PWRCTRL5: VCM=56 + NOTP */
-
-# define PWRCTRL5_SETTING (SSD1289_PWRCTRL5_VCM(56) | SSD1289_PWRCTRL5_NOTP)
-
-#else /* if defined (CONFIG_SSD1289_PROFILE1) */
-# undef SSD1289_USE_SIMPLE_INIT
-# define SSD1289_USE_SIMPLE_INIT 1
-
- /* PWRCTRL1: AP=medium-to-large, DC=Fosc/4, BT=+5/-4, DCT=Fosc/4 */
-
-# define PWRCTRL1_SETTING \
- (SSD1289_PWRCTRL1_AP_MEDLG | SSD1289_PWRCTRL1_DC_FOSd4 | \
- SSD1289_PWRCTRL1_BT_p5m4 | SSD1289_PWRCTRL1_DCT_FOSd4)
-
- /* PWRCTRL2: 5.3v */
-
-# define PWRCTRL2_SETTING SSD1289_PWRCTRL2_VRC_5p3V
-
- /* PWRCTRL3: x 2.570
- * NOTE: Many drivers have bit 8 set which is not defined in the SSD1289 spec.
- */
-
-# define PWRCTRL3_SETTING SSD1289_PWRCTRL3_VRH_x2p570
-
- /* PWRCTRL4: VDV=12 + VCOMG */
-
-# define PWRCTRL4_SETTING (SSD1289_PWRCTRL4_VDV(12) | SSD1289_PWRCTRL4_VCOMG)
-
- /* PWRCTRL5: VCM=60 + NOTP */
-
-# define PWRCTRL5_SETTING (SSD1289_PWRCTRL5_VCM(60) | SSD1289_PWRCTRL5_NOTP)
-
-#endif
-
-/* Debug ******************************************************************************/
-
-#ifdef CONFIG_DEBUG_LCD
-# define lcddbg dbg
-# define lcdvdbg vdbg
-#else
-# define lcddbg(x...)
-# define lcdvdbg(x...)
-#endif
-
-/**************************************************************************************
- * Private Type Definition
- **************************************************************************************/
-
-/* This structure describes the state of this driver */
-
-struct ssd1289_dev_s
-{
- /* Publically visible device structure */
-
- struct lcd_dev_s dev;
-
- /* Private LCD-specific information follows */
-
- FAR struct ssd1289_lcd_s *lcd; /* The contained platform-specific, LCD interface */
- uint8_t power; /* Current power setting */
-
- /* These fields simplify and reduce debug output */
-
-#ifdef CONFIG_DEBUG_LCD
- bool put; /* Last raster operation was a putrun */
- fb_coord_t firstrow; /* First row of the run */
- fb_coord_t lastrow; /* Last row of the run */
- fb_coord_t col; /* Column of the run */
- size_t npixels; /* Length of the run */
-#endif
-
- /* This is working memory allocated by the LCD driver for each LCD device
- * and for each color plane. This memory will hold one raster line of data.
- * The size of the allocated run buffer must therefore be at least
- * (bpp * xres / 8). Actual alignment of the buffer must conform to the
- * bitwidth of the underlying pixel type.
- *
- * If there are multiple planes, they may share the same working buffer
- * because different planes will not be operate on concurrently. However,
- * if there are multiple LCD devices, they must each have unique run buffers.
- */
-
- uint16_t runbuffer[SSD1289_XRES];
-};
-
-/**************************************************************************************
- * Private Function Protototypes
- **************************************************************************************/
-/* Low Level LCD access */
-
-static void ssd1289_putreg(FAR struct ssd1289_lcd_s *lcd, uint8_t regaddr,
- uint16_t regval);
-#ifndef CONFIG_LCD_NOGETRUN
-static uint16_t ssd1289_readreg(FAR struct ssd1289_lcd_s *lcd, uint8_t regaddr);
-#endif
-static inline void ssd1289_gramwrite(FAR struct ssd1289_lcd_s *lcd, uint16_t rgbcolor);
-#ifndef CONFIG_LCD_NOGETRUN
-static inline void ssd1289_readsetup(FAR struct ssd1289_lcd_s *lcd, FAR uint16_t *accum);
-static inline uint16_t ssd1289_gramread(FAR struct ssd1289_lcd_s *lcd, FAR uint16_t *accum);
-#endif
-static void ssd1289_setcursor(FAR struct ssd1289_lcd_s *lcd, uint16_t column,
- uint16_t row);
-
-/* LCD Data Transfer Methods */
-
-#if 0 /* Sometimes useful */
-static void ssd1289_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npixels);
-#else
-# define ssd1289_dumprun(m,r,n)
-#endif
-
-#ifdef CONFIG_DEBUG_LCD
-static void ssd1289_showrun(FAR struct ssd1289_dev_s *priv, fb_coord_t row,
- fb_coord_t col, size_t npixels, bool put);
-#else
-# define ssd1289_showrun(p,r,c,n,b)
-#endif
-
-static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels);
-static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels);
-
-/* LCD Configuration */
-
-static int ssd1289_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo);
-static int ssd1289_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo);
-
-/* LCD RGB Mapping */
-
-#ifdef CONFIG_FB_CMAP
-# error "RGB color mapping not supported by this driver"
-#endif
-
-/* Cursor Controls */
-
-#ifdef CONFIG_FB_HWCURSOR
-# error "Cursor control not supported by this driver"
-#endif
-
-/* LCD Specific Controls */
-
-static int ssd1289_getpower(FAR struct lcd_dev_s *dev);
-static int ssd1289_setpower(FAR struct lcd_dev_s *dev, int power);
-static int ssd1289_getcontrast(FAR struct lcd_dev_s *dev);
-static int ssd1289_setcontrast(FAR struct lcd_dev_s *dev, unsigned int contrast);
-
-/* Initialization */
-
-static inline int ssd1289_hwinitialize(FAR struct ssd1289_dev_s *priv);
-
-/**************************************************************************************
- * Private Data
- **************************************************************************************/
-
-/* This driver can support only a signal SSD1289 device. This is due to an
- * unfortunate decision made whent he getrun and putrun methods were designed. The
- * following is the single SSD1289 driver state instance:
- */
-
-static struct ssd1289_dev_s g_lcddev;
-
-/**************************************************************************************
- * Private Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: ssd1289_putreg(lcd,
- *
- * Description:
- * Write to an LCD register
- *
- **************************************************************************************/
-
-static void ssd1289_putreg(FAR struct ssd1289_lcd_s *lcd, uint8_t regaddr, uint16_t regval)
-{
- /* Set the index register to the register address and write the register contents */
-
- lcd->index(lcd, regaddr);
- lcd->write(lcd, regval);
-}
-
-/**************************************************************************************
- * Name: ssd1289_readreg
- *
- * Description:
- * Read from an LCD register
- *
- **************************************************************************************/
-
-#ifndef CONFIG_LCD_NOGETRUN
-static uint16_t ssd1289_readreg(FAR struct ssd1289_lcd_s *lcd, uint8_t regaddr)
-{
- /* Set the index register to the register address and read the register contents */
-
- lcd->index(lcd, regaddr);
- return lcd->read(lcd);
-}
-#endif
-
-/**************************************************************************************
- * Name: ssd1289_gramselect
- *
- * Description:
- * Setup to read or write multiple pixels to the GRAM memory
- *
- **************************************************************************************/
-
-static inline void ssd1289_gramselect(FAR struct ssd1289_lcd_s *lcd)
-{
- lcd->index(lcd, SSD1289_DATA);
-}
-
-/**************************************************************************************
- * Name: ssd1289_gramwrite
- *
- * Description:
- * Setup to read or write multiple pixels to the GRAM memory
- *
- **************************************************************************************/
-
-static inline void ssd1289_gramwrite(FAR struct ssd1289_lcd_s *lcd, uint16_t data)
-{
- lcd->write(lcd, data);
-}
-
-/**************************************************************************************
- * Name: ssd1289_readsetup
- *
- * Description:
- * Prime the operation by reading one pixel from the GRAM memory if necessary for
- * this LCD type. When reading 16-bit gram data, there may be some shifts in the
- * returned data:
- *
- * - ILI932x: Discard first dummy read; no shift in the return data
- *
- **************************************************************************************/
-
-#ifndef CONFIG_LCD_NOGETRUN
-static inline void ssd1289_readsetup(FAR struct ssd1289_lcd_s *lcd, FAR uint16_t *accum)
-{
- /* Read-ahead one pixel */
-
- *accum = lcd->read(lcd);
-}
-#endif
-
-/**************************************************************************************
- * Name: ssd1289_gramread
- *
- * Description:
- * Read one correctly aligned pixel from the GRAM memory. Possibly shifting the
- * data and possibly swapping red and green components.
- *
- * - ILI932x: Unknown -- assuming colors are in the color order
- *
- **************************************************************************************/
-
-#ifndef CONFIG_LCD_NOGETRUN
-static inline uint16_t ssd1289_gramread(FAR struct ssd1289_lcd_s *lcd, FAR uint16_t *accum)
-{
- /* Read the value (GRAM register already selected) */
-
- return lcd->read(lcd);
-}
-#endif
-
-/**************************************************************************************
- * Name: ssd1289_setcursor
- *
- * Description:
- * Set the cursor position. In landscape mode, the "column" is actually the physical
- * Y position and the "row" is the physical X position.
- *
- **************************************************************************************/
-
-static void ssd1289_setcursor(FAR struct ssd1289_lcd_s *lcd, uint16_t column, uint16_t row)
-{
-#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT)
- ssd1289_putreg(lcd, SSD1289_XADDR, column); /* 0-239 */
- ssd1289_putreg(lcd, SSD1289_YADDR, row); /* 0-319 */
-#elif defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
- ssd1289_putreg(lcd, SSD1289_XADDR, row); /* 0-239 */
- ssd1289_putreg(lcd, SSD1289_YADDR, column); /* 0-319 */
-#endif
-}
-
-/**************************************************************************************
- * Name: ssd1289_dumprun
- *
- * Description:
- * Dump the contexts of the run buffer:
- *
- * run - The buffer in containing the run read to be dumped
- * npixels - The number of pixels to dump
- *
- **************************************************************************************/
-
-#if 0 /* Sometimes useful */
-static void ssd1289_dumprun(FAR const char *msg, FAR uint16_t *run, size_t npixels)
-{
- int i, j;
-
- syslog("\n%s:\n", msg);
- for (i = 0; i < npixels; i += 16)
- {
- up_putc(' ');
- syslog(" ");
- for (j = 0; j < 16; j++)
- {
- syslog(" %04x", *run++);
- }
- up_putc('\n');
- }
-}
-#endif
-
-/**************************************************************************************
- * Name: ssd1289_showrun
- *
- * Description:
- * When LCD debug is enabled, try to reduce then amount of ouptut data generated by
- * ssd1289_putrun and ssd1289_getrun
- *
- **************************************************************************************/
-
-#ifdef CONFIG_DEBUG_LCD
-static void ssd1289_showrun(FAR struct ssd1289_dev_s *priv, fb_coord_t row,
- fb_coord_t col, size_t npixels, bool put)
-{
- fb_coord_t nextrow = priv->lastrow + 1;
-
- /* Has anything changed (other than the row is the next row in the sequence)? */
-
- if (put == priv->put && row == nextrow && col == priv->col &&
- npixels == priv->npixels)
- {
- /* No, just update the last row */
-
- priv->lastrow = nextrow;
- }
- else
- {
- /* Yes... then this is the end of the preceding sequence. Output the last run
- * (if there were more than one run in the sequence).
- */
-
- if (priv->firstrow != priv->lastrow)
- {
- lcddbg("...\n");
- lcddbg("%s row: %d col: %d npixels: %d\n",
- priv->put ? "PUT" : "GET",
- priv->lastrow, priv->col, priv->npixels);
- }
-
- /* And we are starting a new sequence. Output the first run of the
- * new sequence
- */
-
- lcddbg("%s row: %d col: %d npixels: %d\n",
- put ? "PUT" : "GET", row, col, npixels);
-
- /* And save information about the run so that we can detect continuations
- * of the sequence.
- */
-
- priv->put = put;
- priv->firstrow = row;
- priv->lastrow = row;
- priv->col = col;
- priv->npixels = npixels;
- }
-}
-#endif
-
-/**************************************************************************************
- * Name: ssd1289_putrun
- *
- * Description:
- * This method can be used to write a partial raster line to the LCD:
- *
- * row - Starting row to write to (range: 0 <= row < yres)
- * col - Starting column to write to (range: 0 <= col <= xres-npixels)
- * buffer - The buffer containing the run to be written to the LCD
- * npixels - The number of pixels to write to the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-static int ssd1289_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels)
-{
- FAR struct ssd1289_dev_s *priv = &g_lcddev;
- FAR struct ssd1289_lcd_s *lcd = priv->lcd;
- FAR const uint16_t *src = (FAR const uint16_t*)buffer;
- int i;
-
- /* Buffer must be provided and aligned to a 16-bit address boundary */
-
- ssd1289_showrun(priv, row, col, npixels, true);
- DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
-
- /* Select the LCD */
-
- lcd->select(lcd);
-
- /* Write the run to GRAM. */
-
-#ifdef CONFIG_LCD_LANDSCAPE
- /* Convert coordinates -- Here the edge away from the row of buttons on
- * the STM3240G-EVAL is used as the top.
- */
-
- /* Write the GRAM data, manually incrementing X */
-
- for (i = 0; i < npixels; i++)
- {
- /* Write the next pixel to this position */
-
- ssd1289_setcursor(lcd, col, row);
- ssd1289_gramselect(lcd);
- ssd1289_gramwrite(lcd, *src);
-
- /* Increment to the next column */
-
- src++;
- col++;
- }
-#elif defined(CONFIG_LCD_RLANDSCAPE)
- /* Convert coordinates -- Here the edge next to the row of buttons on
- * the STM3240G-EVAL is used as the top.
- */
-
- col = (SSD1289_XRES-1) - col;
- row = (SSD1289_YRES-1) - row;
-
- /* Set the cursor position */
-
- ssd1289_setcursor(lcd, col, row);
-
- /* Then write the GRAM data, auto-decrementing X */
-
- ssd1289_gramselect(lcd);
- for (i = 0; i < npixels; i++)
- {
- /* Write the next pixel to this position (auto-decrements to the next column) */
-
- ssd1289_gramwrite(lcd, *src);
- src++;
- }
-#elif defined(CONFIG_LCD_PORTRAIT)
- /* Convert coordinates. In this configuration, the top of the display is to the left
- * of the buttons (if the board is held so that the buttons are at the botton of the
- * board).
- */
-
- col = (SSD1289_XRES-1) - col;
-
- /* Then write the GRAM data, manually incrementing Y (which is col) */
-
- for (i = 0; i < npixels; i++)
- {
- /* Write the next pixel to this position */
-
- ssd1289_setcursor(lcd, row, col);
- ssd1289_gramselect(lcd);
- ssd1289_gramwrite(lcd, *src);
-
- /* Increment to the next column */
-
- src++;
- col--;
- }
-#else /* CONFIG_LCD_RPORTRAIT */
- /* Convert coordinates. In this configuration, the top of the display is to the right
- * of the buttons (if the board is held so that the buttons are at the botton of the
- * board).
- */
-
- row = (SSD1289_YRES-1) - row;
-
- /* Then write the GRAM data, manually incrementing Y (which is col) */
-
- for (i = 0; i < npixels; i++)
- {
- /* Write the next pixel to this position */
-
- ssd1289_setcursor(lcd, row, col);
- ssd1289_gramselect(lcd);
- ssd1289_gramwrite(lcd, *src);
-
- /* Decrement to the next column */
-
- src++;
- col++;
- }
-#endif
-
- /* De-select the LCD */
-
- lcd->deselect(lcd);
- return OK;
-}
-
-/**************************************************************************************
- * Name: ssd1289_getrun
- *
- * Description:
- * This method can be used to read a partial raster line from the LCD:
- *
- * row - Starting row to read from (range: 0 <= row < yres)
- * col - Starting column to read read (range: 0 <= col <= xres-npixels)
- * buffer - The buffer in which to return the run read from the LCD
- * npixels - The number of pixels to read from the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-static int ssd1289_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels)
-{
-#ifndef CONFIG_LCD_NOGETRUN
- FAR struct ssd1289_dev_s *priv = &g_lcddev;
- FAR struct ssd1289_lcd_s *lcd = priv->lcd;
- FAR uint16_t *dest = (FAR uint16_t*)buffer;
- uint16_t accum;
- int i;
-
- /* Buffer must be provided and aligned to a 16-bit address boundary */
-
- ssd1289_showrun(priv, row, col, npixels, false);
- DEBUGASSERT(buffer && ((uintptr_t)buffer & 1) == 0);
-
- /* Select the LCD */
-
- lcd->select(lcd);
-
- /* Read the run from GRAM. */
-
-#ifdef CONFIG_LCD_LANDSCAPE
- /* Convert coordinates -- Here the edge away from the row of buttons on
- * the STM3240G-EVAL is used as the top.
- */
-
- for (i = 0; i < npixels; i++)
- {
- /* Read the next pixel from this position */
-
- ssd1289_setcursor(lcd, row, col);
- ssd1289_gramselect(lcd);
- ssd1289_readsetup(lcd, &accum);
- *dest++ = ssd1289_gramread(lcd, &accum);
-
- /* Increment to the next column */
-
- col++;
- }
-#elif defined(CONFIG_LCD_RLANDSCAPE)
- /* Convert coordinates -- Here the edge next to the row of buttons on
- * the STM3240G-EVAL is used as the top.
- */
-
- col = (SSD1289_XRES-1) - col;
- row = (SSD1289_YRES-1) - row;
-
- /* Set the cursor position */
-
- ssd1289_setcursor(lcd, col, row);
-
- /* Then read the GRAM data, auto-decrementing Y */
-
- ssd1289_gramselect(lcd);
-
- /* Prime the pump for unaligned read data */
-
- ssd1289_readsetup(lcd, &accum);
-
- for (i = 0; i < npixels; i++)
- {
- /* Read the next pixel from this position (autoincrements to the next row) */
-
- *dest++ = ssd1289_gramread(lcd, &accum);
- }
-#elif defined(CONFIG_LCD_PORTRAIT)
- /* Convert coordinates. In this configuration, the top of the display is to the left
- * of the buttons (if the board is held so that the buttons are at the botton of the
- * board).
- */
-
- col = (SSD1289_XRES-1) - col;
-
- /* Then read the GRAM data, manually incrementing Y (which is col) */
-
- for (i = 0; i < npixels; i++)
- {
- /* Read the next pixel from this position */
-
- ssd1289_setcursor(lcd, row, col);
- ssd1289_gramselect(lcd);
- ssd1289_readsetup(lcd, &accum);
- *dest++ = ssd1289_gramread(lcd, &accum);
-
- /* Increment to the next column */
-
- col--;
- }
-#else /* CONFIG_LCD_RPORTRAIT */
- /* Convert coordinates. In this configuration, the top of the display is to the right
- * of the buttons (if the board is held so that the buttons are at the botton of the
- * board).
- */
-
- row = (SSD1289_YRES-1) - row;
-
- /* Then write the GRAM data, manually incrementing Y (which is col) */
-
- for (i = 0; i < npixels; i++)
- {
- /* Write the next pixel to this position */
-
- ssd1289_setcursor(lcd, row, col);
- ssd1289_gramselect(lcd);
- ssd1289_readsetup(lcd, &accum);
- *dest++ = ssd1289_gramread(lcd, &accum);
-
- /* Decrement to the next column */
-
- col++;
- }
-#endif
-
- /* De-select the LCD */
-
- lcd->deselect(lcd);
- return OK;
-#else
- return -ENOSYS;
-#endif
-}
-
-/**************************************************************************************
- * Name: ssd1289_getvideoinfo
- *
- * Description:
- * Get information about the LCD video controller configuration.
- *
- **************************************************************************************/
-
-static int ssd1289_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo)
-{
- DEBUGASSERT(dev && vinfo);
- lcdvdbg("fmt: %d xres: %d yres: %d nplanes: 1\n",
- SSD1289_COLORFMT, SSD1289_XRES, SSD1289_YRES);
-
- vinfo->fmt = SSD1289_COLORFMT; /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
- vinfo->xres = SSD1289_XRES; /* Horizontal resolution in pixel columns */
- vinfo->yres = SSD1289_YRES; /* Vertical resolution in pixel rows */
- vinfo->nplanes = 1; /* Number of color planes supported */
- return OK;
-}
-
-/**************************************************************************************
- * Name: ssd1289_getplaneinfo
- *
- * Description:
- * Get information about the configuration of each LCD color plane.
- *
- **************************************************************************************/
-
-static int ssd1289_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo)
-{
- FAR struct ssd1289_dev_s *priv = (FAR struct ssd1289_dev_s *)dev;
-
- DEBUGASSERT(dev && pinfo && planeno == 0);
- lcdvdbg("planeno: %d bpp: %d\n", planeno, SSD1289_BPP);
-
- pinfo->putrun = ssd1289_putrun; /* Put a run into LCD memory */
- pinfo->getrun = ssd1289_getrun; /* Get a run from LCD memory */
- pinfo->buffer = (uint8_t*)priv->runbuffer; /* Run scratch buffer */
- pinfo->bpp = SSD1289_BPP; /* Bits-per-pixel */
- return OK;
-}
-
-/**************************************************************************************
- * Name: ssd1289_getpower
- *
- * Description:
- * 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.
- *
- **************************************************************************************/
-
-static int ssd1289_getpower(FAR struct lcd_dev_s *dev)
-{
- lcdvdbg("power: %d\n", 0);
- return g_lcddev.power;
-}
-
-/**************************************************************************************
- * Name: ssd1289_poweroff
- *
- * Description:
- * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On
- * backlit LCDs, this setting may correspond to the backlight setting.
- *
- **************************************************************************************/
-
-static int ssd1289_poweroff(FAR struct ssd1289_lcd_s *lcd)
-{
- /* Set the backlight off */
-
- lcd->backlight(lcd, 0);
-
- /* Turn the display off */
-
- ssd1289_putreg(lcd, SSD1289_DSPCTRL, 0);
-
- /* Remember the power off state */
-
- g_lcddev.power = 0;
- return OK;
-}
-
-/**************************************************************************************
- * Name: ssd1289_setpower
- *
- * Description:
- * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On
- * backlit LCDs, this setting may correspond to the backlight setting.
- *
- **************************************************************************************/
-
-static int ssd1289_setpower(FAR struct lcd_dev_s *dev, int power)
-{
- FAR struct ssd1289_dev_s *priv = (FAR struct ssd1289_dev_s *)dev;
- FAR struct ssd1289_lcd_s *lcd = priv->lcd;
-
- lcdvdbg("power: %d\n", power);
- DEBUGASSERT((unsigned)power <= CONFIG_LCD_MAXPOWER);
-
- /* Set new power level */
-
- if (power > 0)
- {
- /* Set the backlight level */
-
- lcd->backlight(lcd, power);
-
- /* Then turn the display on:
- * D=ON(3) CM=0 DTE=1 GON=1 SPT=0 VLE=0 PT=0
- */
-
- ssd1289_putreg(lcd, SSD1289_DSPCTRL,
- (SSD1289_DSPCTRL_ON | SSD1289_DSPCTRL_GON |
- SSD1289_DSPCTRL_DTE | SSD1289_DSPCTRL_VLE(0)));
-
- g_lcddev.power = power;
- }
- else
- {
- /* Turn the display off */
-
- ssd1289_poweroff(lcd);
- }
-
- return OK;
-}
-
-/**************************************************************************************
- * Name: ssd1289_getcontrast
- *
- * Description:
- * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int ssd1289_getcontrast(FAR struct lcd_dev_s *dev)
-{
- lcdvdbg("Not implemented\n");
- return -ENOSYS;
-}
-
-/**************************************************************************************
- * Name: ssd1289_setcontrast
- *
- * Description:
- * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int ssd1289_setcontrast(FAR struct lcd_dev_s *dev, unsigned int contrast)
-{
- lcdvdbg("contrast: %d\n", contrast);
- return -ENOSYS;
-}
-
-/**************************************************************************************
- * Name: ssd1289_hwinitialize
- *
- * Description:
- * Initialize the LCD hardware.
- *
- **************************************************************************************/
-
-static inline int ssd1289_hwinitialize(FAR struct ssd1289_dev_s *priv)
-{
- FAR struct ssd1289_lcd_s *lcd = priv->lcd;
-#ifndef CONFIG_LCD_NOGETRUN
- uint16_t id;
-#endif
- int ret;
-
- /* Select the LCD */
-
- lcd->select(lcd);
-
- /* Read the device ID. Skip verification of the device ID is the LCD is
- * write-only. What choice do we have?
- */
-
-#ifndef CONFIG_LCD_NOGETRUN
- id = ssd1289_readreg(lcd, SSD1289_DEVCODE);
- if (id != 0)
- {
- lcddbg("LCD ID: %04x\n", id);
- }
-
- /* If we could not get the ID, then let's just assume that this is an SSD1289.
- * Perhaps we have some early register access issues. This seems to happen.
- * But then perhaps we should not even bother to read the device ID at all?
- */
-
- else
- {
- lcddbg("No LCD ID, assuming SSD1289\n");
- id = SSD1289_DEVCODE_VALUE;
- }
-
- /* Check if the ID is for the SSD1289 */
-
- if (id == SSD1289_DEVCODE_VALUE)
-#endif
- {
- /* LCD controller configuration. Many details of the controller initialization
- * must, unfortunately, vary from LCD to LCD. I have looked at the spec and at
- * three different drivers for LCDs that have SSD1289 controllers. I have tried
- * to summarize these differences as profiles (defined above). Some other
- * alternatives are noted below.
- *
- * Most of the differences between LCDs are nothing more than a few minor bit
- * settings. The most significant difference betwen LCD drivers in is the
- * manner in which the LCD is powered up and in how the power controls are set.
- * My suggestion is that if you have working LCD initialization code, you should
- * simply replace the following guesses with your working code.
- */
-
- /* Most drivers just enable the oscillator */
-
-#ifdef SSD1289_USE_SIMPLE_INIT
- ssd1289_putreg(lcd, SSD1289_OSCSTART, SSD1289_OSCSTART_OSCEN);
-#else
- /* But one goes through a more complex start-up sequence. Something like the
- * following:
- *
- * First, put the display in INTERNAL operation:
- * D=INTERNAL(1) CM=0 DTE=0 GON=1 SPT=0 VLE=0 PT=0
- */
-
- ssd1289_putreg(lcd, SSD1289_DSPCTRL,
- (SSD1289_DSPCTRL_INTERNAL | SSD1289_DSPCTRL_GON |
- SSD1289_DSPCTRL_VLE(0)));
-
- /* Then enable the oscillator */
-
- ssd1289_putreg(lcd, SSD1289_OSCSTART, SSD1289_OSCSTART_OSCEN);
-
- /* Turn the display on:
- * D=ON(3) CM=0 DTE=0 GON=1 SPT=0 VLE=0 PT=0
- */
-
- ssd1289_putreg(lcd, SSD1289_DSPCTRL,
- (SSD1289_DSPCTRL_ON | SSD1289_DSPCTRL_GON |
- SSD1289_DSPCTRL_VLE(0)));
-
- /* Take the LCD out of sleep mode */
-
- ssd1289_putreg(lcd, SSD1289_SLEEP, 0);
- up_mdelay(30);
-
- /* Turn the display on:
- * D=INTERNAL(1) CM=0 DTE=1 GON=1 SPT=0 VLE=0 PT=0
- */
-
- ssd1289_putreg(lcd, SSD1289_DSPCTRL,
- (SSD1289_DSPCTRL_ON | SSD1289_DSPCTRL_DTE |
- SSD1289_DSPCTRL_GON | SSD1289_DSPCTRL_VLE(0)));
-#endif
-
- /* Set up power control registers. There is a lot of variability
- * from LCD-to-LCD in how the power registers are configured.
- */
-
- ssd1289_putreg(lcd, SSD1289_PWRCTRL1, PWRCTRL1_SETTING);
- ssd1289_putreg(lcd, SSD1289_PWRCTRL2, PWRCTRL2_SETTING);
-
- /* One driver adds a delay here.. I doubt that this is really necessary. */
- /* up_mdelay(15); */
-
- ssd1289_putreg(lcd, SSD1289_PWRCTRL3, PWRCTRL3_SETTING);
- ssd1289_putreg(lcd, SSD1289_PWRCTRL4, PWRCTRL4_SETTING);
- ssd1289_putreg(lcd, SSD1289_PWRCTRL5, PWRCTRL5_SETTING);
-
- /* One driver does an odd setting of the the driver output control.
- * No idea why.
- */
-#if 0
- ssd1289_putreg(lcd, SSD1289_OUTCTRL,
- (SSD1289_OUTCTRL_MUX(12) | SSD1289_OUTCTRL_TB |
- SSD1289_OUTCTRL_BGR | SSD1289_OUTCTRL_CAD));
-
- /* The same driver does another small delay here */
-
- up_mdelay(15);
-#endif
-
- /* After this point, the drivers differ only in some varying register
- * bit settings.
- */
-
- /* Set the driver output control.
- * PORTRAIT MODES:
- * MUX=319, TB=1, SM=0, BGR=1, CAD=0, REV=1, RL=0
- * LANDSCAPE MODES:
- * MUX=319, TB=0, SM=0, BGR=1, CAD=0, REV=1, RL=0
- */
-
-#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT)
- ssd1289_putreg(lcd, SSD1289_OUTCTRL,
- (SSD1289_OUTCTRL_MUX(319) | SSD1289_OUTCTRL_TB |
- SSD1289_OUTCTRL_BGR | SSD1289_OUTCTRL_REV);
-#else
- ssd1289_putreg(lcd, SSD1289_OUTCTRL,
- (SSD1289_OUTCTRL_MUX(319) | SSD1289_OUTCTRL_BGR |
- SSD1289_OUTCTRL_REV));
-#endif
-
- /* Set the LCD driving AC waveform
- * NW=0, WSMD=0, EOR=1, BC=1, ENWD=0, FLD=0
- */
-
- ssd1289_putreg(lcd, SSD1289_ACCTRL,
- (SSD1289_ACCTRL_EOR | SSD1289_ACCTRL_BC));
-
- /* Take the LCD out of sleep mode (isn't this redundant in the non-
- * simple case?)
- */
-
- ssd1289_putreg(lcd, SSD1289_SLEEP, 0);
-
- /* Set entry mode */
-
-#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT)
- /* LG=0, AM=0, ID=3, TY=2, DMODE=0, WMODE=0, OEDEF=0, TRANS=0, DRM=3
- * Alternative TY=2 (But TY only applies in 262K color mode anyway)
- */
-
- ssd1289_putreg(lcd, SSD1289_ENTRY,
- (SSD1289_ENTRY_ID_HINCVINC | SSD1289_ENTRY_TY_C |
- SSD1289_ENTRY_DMODE_RAM | SSD1289_ENTRY_DFM_65K));
-#else
- /* LG=0, AM=1, ID=3, TY=2, DMODE=0, WMODE=0, OEDEF=0, TRANS=0, DRM=3 */
- /* Alternative TY=2 (But TY only applies in 262K color mode anyway) */
-
- ssd1289_putreg(lcd, SSD1289_ENTRY,
- (SSD1289_ENTRY_AM | SSD1289_ENTRY_ID_HINCVINC |
- SSD1289_ENTRY_TY_C | SSD1289_ENTRY_DMODE_RAM |
- SSD1289_ENTRY_DFM_65K));
-#endif
-
- /* Clear compare registers */
-
- ssd1289_putreg(lcd, SSD1289_CMP1, 0);
- ssd1289_putreg(lcd, SSD1289_CMP2, 0);
-
- /* One driver puts a huge, 100 millisecond delay here */
- /* up_mdelay(100); */
-
- /* Set Horizontal and vertical porch.
- * Horizontal porch: 239 pixels per line, delay=28
- * Vertical porch: VBP=3, XFP=0
- */
-
- ssd1289_putreg(lcd, SSD1289_HPORCH,
- (28 << SSD1289_HPORCH_HBP_SHIFT) | (239 << SSD1289_HPORCH_XL_SHIFT));
- ssd1289_putreg(lcd, SSD1289_VPORCH,
- (3 << SSD1289_VPORCH_VBP_SHIFT) | (0 << SSD1289_VPORCH_XFP_SHIFT));
-
- /* Set display control.
- * D=ON(3), CM=0 (not 8-color), DTE=1, GON=1, SPT=0, VLE=1 PT=0
- */
-
- ssd1289_putreg(lcd, SSD1289_DSPCTRL,
- (SSD1289_DSPCTRL_ON | SSD1289_DSPCTRL_DTE |
- SSD1289_DSPCTRL_GON | SSD1289_DSPCTRL_VLE(1)));
-
- /* Frame cycle control. Alternative: SSD1289_FCYCCTRL_DIV8 */
-
- ssd1289_putreg(lcd, SSD1289_FCYCCTRL, 0);
-
- /* Gate scan start position = 0 */
-
- ssd1289_putreg(lcd, SSD1289_GSTART, 0);
-
- /* Clear vertical scrolling */
-
- ssd1289_putreg(lcd, SSD1289_VSCROLL1, 0);
- ssd1289_putreg(lcd, SSD1289_VSCROLL2, 0);
-
- /* Setup window 1 (0-319) */
-
- ssd1289_putreg(lcd, SSD1289_W1START, 0);
- ssd1289_putreg(lcd, SSD1289_W1END, 319);
-
- /* Disable window 2 (0-0) */
-
- ssd1289_putreg(lcd, SSD1289_W2START, 0);
- ssd1289_putreg(lcd, SSD1289_W2END, 0);
-
- /* Horizontal start and end (0-239) */
-
- ssd1289_putreg(lcd, SSD1289_HADDR,
- (0 << SSD1289_HADDR_HSA_SHIFT) | (239 << SSD1289_HADDR_HEA_SHIFT));
-
- /* Vertical start and end (0-319) */
-
- ssd1289_putreg(lcd, SSD1289_VSTART, 0);
- ssd1289_putreg(lcd, SSD1289_VEND, 319);
-
- /* Gamma controls */
-
- ssd1289_putreg(lcd, SSD1289_GAMMA1, 0x0707);
- ssd1289_putreg(lcd, SSD1289_GAMMA2, 0x0204); /* Alternative: 0x0704 */
- ssd1289_putreg(lcd, SSD1289_GAMMA3, 0x0204);
- ssd1289_putreg(lcd, SSD1289_GAMMA4, 0x0502);
- ssd1289_putreg(lcd, SSD1289_GAMMA5, 0x0507);
- ssd1289_putreg(lcd, SSD1289_GAMMA6, 0x0204);
- ssd1289_putreg(lcd, SSD1289_GAMMA7, 0x0204);
- ssd1289_putreg(lcd, SSD1289_GAMMA8, 0x0502);
- ssd1289_putreg(lcd, SSD1289_GAMMA9, 0x0302);
- ssd1289_putreg(lcd, SSD1289_GAMMA10, 0x0302); /* Alternative: 0x1f00 */
-
- /* Clear write mask */
-
- ssd1289_putreg(lcd, SSD1289_WRMASK1, 0);
- ssd1289_putreg(lcd, SSD1289_WRMASK2, 0);
-
- /* Set frame frequency = 65Hz (This should not be necessary since this
- * is the default POR value)
- */
-
- ssd1289_putreg(lcd, SSD1289_FFREQ, SSD1289_FFREQ_OSC_FF65);
-
- /* Set the cursor at the home position and set the index register to
- * the gram data register (I can't imagine these are necessary).
- */
-
- ssd1289_setcursor(lcd, 0, 0);
- ssd1289_gramselect(lcd);
-
- /* One driver has a 50 msec delay here */
- /* up_mdelay(50); */
-
- ret = OK;
- }
-#ifndef CONFIG_LCD_NOGETRUN
- else
- {
- lcddbg("Unsupported LCD type\n");
- ret = -ENODEV;
- }
-#endif
-
- /* De-select the LCD */
-
- lcd->deselect(lcd);
- return ret;
-}
-
- /*************************************************************************************
- * Public Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: ssd1289_lcdinitialize
- *
- * Description:
- * Initialize the LCD video hardware. The initial state of the LCD is fully
- * initialized, display memory cleared, and the LCD ready to use, but with the power
- * setting at 0 (full off).
- *
- **************************************************************************************/
-
-FAR struct lcd_dev_s *ssd1289_lcdinitialize(FAR struct ssd1289_lcd_s *lcd)
-{
- int ret;
-
- lcdvdbg("Initializing\n");
-
- /* If we ccould support multiple SSD1289 devices, this is where we would allocate
- * a new driver data structure... but we can't. Why not? Because of a bad should
- * the form of the getrun() and putrun methods.
- */
-
- FAR struct ssd1289_dev_s *priv = &g_lcddev;
-
- /* Initialize the driver data structure */
-
- priv->dev.getvideoinfo = ssd1289_getvideoinfo;
- priv->dev.getplaneinfo = ssd1289_getplaneinfo;
- priv->dev.getpower = ssd1289_getpower;
- priv->dev.setpower = ssd1289_setpower;
- priv->dev.getcontrast = ssd1289_getcontrast;
- priv->dev.setcontrast = ssd1289_setcontrast;
- priv->lcd = lcd;
-
- /* Configure and enable LCD */
-
- ret = ssd1289_hwinitialize(priv);
- if (ret == OK)
- {
- /* Clear the display (setting it to the color 0=black) */
-
- ssd1289_clear(&priv->dev, 0);
-
- /* Turn the display off */
-
- ssd1289_poweroff(lcd);
- return &g_lcddev.dev;
- }
-
- return NULL;
-}
-
-/**************************************************************************************
- * Name: ssd1289_clear
- *
- * Description:
- * This is a non-standard LCD interface just for the stm3240g-EVAL board. Because
- * of the various rotations, clearing the display in the normal way by writing a
- * sequences of runs that covers the entire display can be very slow. Here the
- * display is cleared by simply setting all GRAM memory to the specified color.
- *
- **************************************************************************************/
-
-void ssd1289_clear(FAR struct lcd_dev_s *dev, uint16_t color)
-{
- FAR struct ssd1289_dev_s *priv = (FAR struct ssd1289_dev_s *)dev;
- FAR struct ssd1289_lcd_s *lcd = priv->lcd;
- uint32_t i;
-
- /* Select the LCD and home the cursor position */
-
- lcd->select(lcd);
- ssd1289_setcursor(lcd, 0, 0);
-
- /* Prepare to write GRAM data */
-
- ssd1289_gramselect(lcd);
-
- /* Copy color into all of GRAM. Orientation does not matter in this case. */
-
- for (i = 0; i < SSD1289_XRES * SSD1289_YRES; i++)
- {
- ssd1289_gramwrite(lcd, color);
- }
-
- /* De-select the LCD */
-
- lcd->deselect(lcd);
-}
-
-#endif /* CONFIG_LCD_SSD1289 */
diff --git a/nuttx/drivers/lcd/ssd1289.h b/nuttx/drivers/lcd/ssd1289.h
deleted file mode 100644
index 6d5d1c3cb..000000000
--- a/nuttx/drivers/lcd/ssd1289.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/ssd1289.h
- * Definitions for the Solomon Systech SSD1289 LCD controller
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References: SSD1289, Rev 1.3, Apr 2007, Solomon Systech Limited
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************/
-
-#ifndef __DRIVERS_LCD_SSD1289_H
-#define __DRIVERS_LCD_SSD1289_H
-
-/**************************************************************************************
- * Included Files
- **************************************************************************************/
-
-#include <nuttx/config.h>
-
-#ifdef CONFIG_LCD_SSD1289
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-
-/* SSD1289 Register Addresses (All with DC=1) */
-
-#define SSD1289_OSCSTART 0x00 /* Oscillation Start (write) */
-#define SSD1289_DEVCODE 0x00 /* Oscillation Start (read) */
-#define SSD1289_OUTCTRL 0x01 /* Driver output control */
-#define SSD1289_ACCTRL 0x02 /* LCD drive AC control */
-#define SSD1289_PWRCTRL1 0x03 /* Power control 1 */
-#define SSD1289_CMP1 0x05 /* Compare register 1 */
-#define SSD1289_CMP2 0x06 /* Compare register 2 */
-#define SSD1289_DSPCTRL 0x07 /* Display control */
-#define SSD1289_FCYCCTRL 0x0b /* Frame cycle control */
-#define SSD1289_PWRCTRL2 0x0c /* Power control 2 */
-#define SSD1289_PWRCTRL3 0x0d /* Power control 3 */
-#define SSD1289_PWRCTRL4 0x0e /* Power control 4 */
-#define SSD1289_GSTART 0x0f /* Gate scan start position */
-#define SSD1289_SLEEP 0x10 /* Sleep mode */
-#define SSD1289_ENTRY 0x11 /* Entry mode */
-#define SSD1289_OPT3 0x12 /* Optimize Access Speed 3 */
-#define SSD1289_GIFCTRL 0x15 /* Generic Interface Control */
-#define SSD1289_HPORCH 0x16 /* Horizontal Porch */
-#define SSD1289_VPORCH 0x17 /* Vertical Porch */
-#define SSD1289_PWRCTRL5 0x1e /* Power control 5 */
-#define SSD1289_DATA 0x22 /* RAM data/write data */
-#define SSD1289_WRMASK1 0x23 /* RAM write data mask 1 */
-#define SSD1289_WRMASK2 0x24 /* RAM write data mask 2 */
-#define SSD1289_FFREQ 0x25 /* Frame Frequency */
-#define SSD1289_VCOMOTP1 0x28 /* VCOM OTP */
-#define SSD1289_OPT1 0x28 /* Optimize Access Speed 1 */
-#define SSD1289_VCOMOTP2 0x29 /* VCOM OTP */
-#define SSD1289_OPT2 0x2f /* Optimize Access Speed 2 */
-#define SSD1289_GAMMA1 0x30 /* Gamma control 1 */
-#define SSD1289_GAMMA2 0x31 /* Gamma control 2 */
-#define SSD1289_GAMMA3 0x32 /* Gamma control 3 */
-#define SSD1289_GAMMA4 0x33 /* Gamma control 4 */
-#define SSD1289_GAMMA5 0x34 /* Gamma control 5 */
-#define SSD1289_GAMMA6 0x35 /* Gamma control 6 */
-#define SSD1289_GAMMA7 0x36 /* Gamma control 7 */
-#define SSD1289_GAMMA8 0x37 /* Gamma control 8 */
-#define SSD1289_GAMMA9 0x3a /* Gamma control 9 */
-#define SSD1289_GAMMA10 0x3b /* Gamma control 10 */
-#define SSD1289_VSCROLL1 0x41 /* Vertical scroll control 1 */
-#define SSD1289_VSCROLL2 0x42 /* Vertical scroll control 2 */
-#define SSD1289_HADDR 0x44 /* Horizontal RAM address position */
-#define SSD1289_VSTART 0x45 /* Vertical RAM address start position */
-#define SSD1289_VEND 0x46 /* Vertical RAM address end position */
-#define SSD1289_W1START 0x48 /* First window start */
-#define SSD1289_W1END 0x49 /* First window end */
-#define SSD1289_W2START 0x4a /* Second window start */
-#define SSD1289_W2END 0x4b /* Second window end */
-#define SSD1289_XADDR 0x4e /* Set GDDRAM X address counter */
-#define SSD1289_YADDR 0x4f /* Set GDDRAM Y address counter */
-
-/* SSD1289 Register Bit definitions */
-
-/* Index register (DC=0) */
-
-#define SSD1289_INDEX_MASK 0xff
-
-/* Device code (read) */
-
-#define SSD1289_DEVCODE_VALUE 0x8989
-
-/* Oscillation Start (write) */
-
-#define SSD1289_OSCSTART_OSCEN (1 << 0) /* Enable oscillator */
-
-/* Driver output control */
-
-#define SSD1289_OUTCTRL_MUX_SHIFT (0) /* Number of lines for the LCD driver */
-#define SSD1289_OUTCTRL_MUX_MASK (0x1ff << SSD1289_OUTCTRL_MUX_SHIFT)
-# define SSD1289_OUTCTRL_MUX(n) ((n) << SSD1289_OUTCTRL_MUX_SHIFT)
-#define SSD1289_OUTCTRL_TB (1 << 9) /* Selects the output shift direction of the gate driver */
-#define SSD1289_OUTCTRL_SM (1 << 10) /* Scanning order of gate driver */
-#define SSD1289_OUTCTRL_BGR (1 << 11) /* Order from RGB to BGR in 18-bit GDDRAM data */
-#define SSD1289_OUTCTRL_CAD (1 << 12) /* Retention capacitor configuration of the TFT panel */
-#define SSD1289_OUTCTRL_REV (1 << 13) /* Reversed display */
-#define SSD1289_OUTCTRL_RL (1 << 14) /* RL pin state */
-
-/* LCD drive AC control */
-
-#define SSD1289_ACCTRL_NW_SHIFT (0) /* Number of lines to alternate in N-line inversion */
-#define SSD1289_ACCTRL_NW_MASK (0xff << SSD1289_ACCTRL_NW_SHIFT)
-#define SSD1289_ACCTRL_WSMD (1 << 8) /* Waveform of WSYNC output */
-#define SSD1289_ACCTRL_EOR (1 << 9) /* EOR signals */
-#define SSD1289_ACCTRL_BC (1 << 10) /* Select the liquid crystal drive waveform */
-#define SSD1289_ACCTRL_ENWS (1 << 11) /* Enables WSYNC output pin */
-#define SSD1289_ACCTRL_FLD (1 << 12) /* Set display in interlace drive mode */
-
-/* Power control 1 */
-
-#define SSD1289_PWRCTRL1_AP_SHIFT (1) /* Current from internal operational amplifier */
-#define SSD1289_PWRCTRL1_AP_MASK (7 << SSD1289_PWRCTRL1_AP_SHIFT)
-# define SSD1289_PWRCTRL1_AP_LEAST (0 << SSD1289_PWRCTRL1_AP_SHIFT)
-# define SSD1289_PWRCTRL1_AP_SMALL (1 << SSD1289_PWRCTRL1_AP_SHIFT)
-# define SSD1289_PWRCTRL1_AP_SMMED (2 << SSD1289_PWRCTRL1_AP_SHIFT)
-# define SSD1289_PWRCTRL1_AP_MEDIUM (3 << SSD1289_PWRCTRL1_AP_SHIFT)
-# define SSD1289_PWRCTRL1_AP_MEDLG (4 << SSD1289_PWRCTRL1_AP_SHIFT)
-# define SSD1289_PWRCTRL1_AP_LARGE (5 << SSD1289_PWRCTRL1_AP_SHIFT)
-# define SSD1289_PWRCTRL1_AP_LGMX (6 << SSD1289_PWRCTRL1_AP_SHIFT)
-# define SSD1289_PWRCTRL1_AP_MAX (7 << SSD1289_PWRCTRL1_AP_SHIFT)
-#define SSD1289_PWRCTRL1_DC_SHIFT (4) /* Set the step-up cycle of the step-up circuit for 262k-color mode */
-#define SSD1289_PWRCTRL1_DC_MASK (15 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FLINEx24 (0 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FLINEx16 (1 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FLINEx12 (2 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FLINEx8 (3 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FLINEx6 (4 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FLINEx5 (5 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FLINEx4 (6 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FLINEx3 (7 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FLINEx2 (8 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FLINEx1 (9 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FOSd4 (10 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FOSd6 (11 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FOSd8 (12 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FOSd10 (13 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FOSd12 (14 << SSD1289_PWRCTRL1_DC_SHIFT)
-# define SSD1289_PWRCTRL1_DC_FOSd16 (15 << SSD1289_PWRCTRL1_DC_SHIFT)
-#define SSD1289_PWRCTRL1_BT_SHIFT (9) /* Control the step-up factor of the step-up circuit */
-#define SSD1289_PWRCTRL1_BT_MASK (7 << SSD1289_PWRCTRL1_BT_SHIFT)
-# define SSD1289_PWRCTRL1_BT_p6m5 (0 << SSD1289_PWRCTRL1_BT_SHIFT)
-# define SSD1289_PWRCTRL1_BT_p6m4 (1 << SSD1289_PWRCTRL1_BT_SHIFT)
-# define SSD1289_PWRCTRL1_BT_p6m6 (2 << SSD1289_PWRCTRL1_BT_SHIFT)
-# define SSD1289_PWRCTRL1_BT_p5m5 (3 << SSD1289_PWRCTRL1_BT_SHIFT)
-# define SSD1289_PWRCTRL1_BT_p5m4 (4 << SSD1289_PWRCTRL1_BT_SHIFT)
-# define SSD1289_PWRCTRL1_BT_p5m3 (5 << SSD1289_PWRCTRL1_BT_SHIFT)
-# define SSD1289_PWRCTRL1_BT_p4m4 (6 << SSD1289_PWRCTRL1_BT_SHIFT)
-# define SSD1289_PWRCTRL1_BT_p4m3 (7 << SSD1289_PWRCTRL1_BT_SHIFT)
-#define SSD1289_PWRCTRL1_DCT_SHIFT (12) /* Step-up cycle of the step-up circuit for 8-color mode */
-#define SSD1289_PWRCTRL1_DCT_MASK (15 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FLINEx24 (0 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FLINEx16 (1 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FLINEx12 (2 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FLINEx8 (3 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FLINEx6 (4 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FLINEx5 (5 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FLINEx4 (6 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FLINEx3 (7 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FLINEx2 (8 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FLINEx1 (9 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FOSd4 (10 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FOSd6 (11 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FOSd8 (12 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FOSd10 (13 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FOSd12 (14 << SSD1289_PWRCTRL1_DCT_SHIFT)
-# define SSD1289_PWRCTRL1_DCT_FOSd16 (15 << SSD1289_PWRCTRL1_DCT_SHIFT)
-
-/* Compare register 1 and 2 */
-
-#define SSD1289_CMP1_CPG_SHIFT (2)
-#define SSD1289_CMP1_CPG_MASK (0x3f << SSD1289_CMP1_CPG_SHIFT)
-#define SSD1289_CMP1_CPR_SHIFT (10)
-#define SSD1289_CMP1_CPR_MASK (0x3f << SSD1289_CMP1_CPR_SHIFT)
-
-#define SSD1289_CMP2_CPB_SHIFT (2)
-#define SSD1289_CMP2_CPB_MASK (0x3f << SSD1289_CMP2_CPB_SHIFT)
-
-/* Display control */
-
-#define SSD1289_DSPCTRL_D_SHIFT (0) /* Display control */
-#define SSD1289_DSPCTRL_D_MASK (3 << SSD1289_DSPCTRL_D_SHIFT)
-# define SSD1289_DSPCTRL_OFF (0 << SSD1289_DSPCTRL_D_SHIFT)
-# define SSD1289_DSPCTRL_INTERNAL (1 << SSD1289_DSPCTRL_D_SHIFT)
-# define SSD1289_DSPCTRL_ON (3 << SSD1289_DSPCTRL_D_SHIFT)
-#define SSD1289_DSPCTRL_CM (1 << 3) /* 8-color mode setting */
-#define SSD1289_DSPCTRL_DTE (1 << 4) /* Selected gate level */
-#define SSD1289_DSPCTRL_GON (1 << 5) /* Gate off level */
-#define SSD1289_DSPCTRL_SPT (1 << 8) /* 2-division LCD drive */
-#define SSD1289_DSPCTRL_VLE_SHIFT (9) /* Vertical scroll control */
-#define SSD1289_DSPCTRL_VLE_MASK (3 << SSD1289_DSPCTRL_VLE_SHIFT)
-# define SSD1289_DSPCTRL_VLE(n) ((n) << SSD1289_DSPCTRL_VLE_SHIFT)
-#define SSD1289_DSPCTRL_PT_SHIFT (11) /* Normalize the source outputs */
-#define SSD1289_DSPCTRL_PT_MASK (3 << SSD1289_DSPCTRL_PT_SHIFT)
-# define SSD1289_DSPCTRL_PT(n) ((n) << SSD1289_DSPCTRL_PT_SHIFT)
-
-/* Frame cycle control */
-
-#define SSD1289_FCYCCTRL_RTN_SHIFT (0) /* Number of clocks in each line */
-#define SSD1289_FCYCCTRL_RTN_MASK (3 << SSD1289_FCYCCTRL_RTN_SHIFT)
-# define SSD1289_FCYCCTRL_RTN(n) (((n)-16) << SSD1289_FCYCCTRL_RTN_SHIFT)
-#define SSD1289_FCYCCTRL_SRTN (1 << 4) /* When SRTN =1, RTN3-0 value will be count */
-#define SSD1289_FCYCCTRL_SDIV (1 << 5) /* When SDIV = 1, DIV1-0 value will be count */
-#define SSD1289_FCYCCTRL_DIV_SHIFT (6) /* Set the division ratio of clocks */
-#define SSD1289_FCYCCTRL_DIV_MASK (3 << SSD1289_FCYCCTRL_DIV_SHIFT)
-# define SSD1289_FCYCCTRL_DIV1 (0 << SSD1289_FCYCCTRL_DIV_SHIFT)
-# define SSD1289_FCYCCTRL_DIV2 (1 << SSD1289_FCYCCTRL_DIV_SHIFT)
-# define SSD1289_FCYCCTRL_DIV4 (2 << SSD1289_FCYCCTRL_DIV_SHIFT)
-# define SSD1289_FCYCCTRL_DIV8 (3 << SSD1289_FCYCCTRL_DIV_SHIFT)
-#define SSD1289_FCYCCTRL_EQ_SHIFT (8) /* Sets the equalizing period */
-#define SSD1289_FCYCCTRL_EQ_MASK (3 << SSD1289_FCYCCTRL_EQ_SHIFT)
-# define SSD1289_FCYCCTRL_EQ(n) (((n)-1) << SSD1289_FCYCCTRL_EQ_SHIFT) /* n = 2-8 clocks */
-#define SSD1289_FCYCCTRL_SDT_SHIFT (12) /* Set delay amount from the gate output */
-#define SSD1289_FCYCCTRL_SDT_MASK (3 << SSD1289_FCYCCTRL_SDT_SHIFT)
-# define SSD1289_FCYCCTRL_SDT(n) ((n) << SSD1289_FCYCCTRL_SDT_SHIFT) /* n = 1-3 clocks */
-#define SSD1289_FCYCCTRL_NO_SHIFT (14) /* Sets amount of non-overlap of the gate output */
-#define SSD1289_FCYCCTRL_NO_MASK (3 << SSD1289_FCYCCTRL_NO_SHIFT)
-# define SSD1289_FCYCCTRL_NO(n) ((n) << SSD1289_FCYCCTRL_NO_SHIFT) /* n = 1-3 clocks */
-
-/* Power control 2 */
-
-#define SSD1289_PWRCTRL2_VRC_SHIFT (0) /* Adjust VCIX2 output voltage */
-#define SSD1289_PWRCTRL2_VRC_MASK (7 << SSD1289_PWRCTRL2_VRC_SHIFT)
-# define SSD1289_PWRCTRL2_VRC_5p1V (0 << SSD1289_PWRCTRL2_VRC_SHIFT)
-# define SSD1289_PWRCTRL2_VRC_5p2V (1 << SSD1289_PWRCTRL2_VRC_SHIFT)
-# define SSD1289_PWRCTRL2_VRC_5p3V (2 << SSD1289_PWRCTRL2_VRC_SHIFT)
-# define SSD1289_PWRCTRL2_VRC_5p4V (3 << SSD1289_PWRCTRL2_VRC_SHIFT)
-# define SSD1289_PWRCTRL2_VRC_5p5V (4 << SSD1289_PWRCTRL2_VRC_SHIFT)
-# define SSD1289_PWRCTRL2_VRC_5p6V (5 << SSD1289_PWRCTRL2_VRC_SHIFT)
-# define SSD1289_PWRCTRL2_VRC_5p7V (6 << SSD1289_PWRCTRL2_VRC_SHIFT)
-# define SSD1289_PWRCTRL2_VRC_5p8V (7 << SSD1289_PWRCTRL2_VRC_SHIFT)
-
-/* Power control 3 */
-
-#define SSD1289_PWRCTRL3_VRH_SHIFT (0) /* Set amplitude magnification of VLCD63 */
-#define SSD1289_PWRCTRL3_VRH_MASK (15 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x1p540 (0 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x1p620 (1 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x1p700 (2 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x1p780 (3 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x1p850 (4 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x1p930 (5 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x2p020 (6 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x2p090 (7 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x2p165 (8 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x2p245 (9 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x2p335 (10 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x2p400 (11 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x2p500 (12 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x2p570 (13 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x2p645 (14 << SSD1289_PWRCTRL3_VRH_SHIFT)
-# define SSD1289_PWRCTRL3_VRH_x2p725 (15 << SSD1289_PWRCTRL3_VRH_SHIFT)
-
-/* Power control 4 */
-
-#define SSD1289_PWRCTRL4_VDV_SHIFT (8) /* Set amplitude magnification of VLCD63 */
-#define SSD1289_PWRCTRL4_VDV_MASK (32 << SSD1289_PWRCTRL4_VDV_SHIFT)
-# define SSD1289_PWRCTRL4_VDV(n) ((n) << SSD1289_PWRCTRL4_VDV_SHIFT)
-#define SSD1289_PWRCTRL4_VCOMG (1 << 13) /* VcomL variable */
-
-/* Gate scan start position */
-
-#define SSD1289_GSTART_MASK 0x1ff
-
-/* Sleep mode */
-
-#define SSD1289_SLEEP_ON (1 << 0)
-
-/* Entry mode */
-
-#define SSD1289_ENTRY_LG_SHIFT (0) /* Write after comparing */
-#define SSD1289_ENTRY_LG_MASK (7 << SSD1289_ENTRY_LG_SHIFT)
-#define SSD1289_ENTRY_AM (1 << 3) /* Address counter direction */
-#define SSD1289_ENTRY_ID_SHIFT (4) /* Address increment mode */
-#define SSD1289_ENTRY_ID_MASK (3 << SSD1289_ENTRY_ID_SHIFT)
-# define SSD1289_ENTRY_ID_HDECVDEC (0 << SSD1289_ENTRY_ID_SHIFT)
-# define SSD1289_ENTRY_ID_HINCVDEC (1 << SSD1289_ENTRY_ID_SHIFT)
-# define SSD1289_ENTRY_ID_HDECVINC (2 << SSD1289_ENTRY_ID_SHIFT)
-# define SSD1289_ENTRY_ID_HINCVINC (3 << SSD1289_ENTRY_ID_SHIFT)
-#define SSD1289_ENTRY_TY_SHIFT (6) /* RAM data write method */
-#define SSD1289_ENTRY_TY_MASK (3 << SSD1289_ENTRY_TY_SHIFT)
-# define SSD1289_ENTRY_TY_A (0 << SSD1289_ENTRY_TY_SHIFT)
-# define SSD1289_ENTRY_TY_B (1 << SSD1289_ENTRY_TY_SHIFT)
-# define SSD1289_ENTRY_TY_C (2 << SSD1289_ENTRY_TY_SHIFT)
-#define SSD1289_ENTRY_DMODE_SHIFT (8) /* Data display mode */
-#define SSD1289_ENTRY_DMODE_MASK (3 << SSD1289_ENTRY_DMODE_SHIFT)
-# define SSD1289_ENTRY_DMODE_RAM (0 << SSD1289_ENTRY_DMODE_SHIFT)
-# define SSD1289_ENTRY_DMODE_GENERIC (1 << SSD1289_ENTRY_DMODE_SHIFT)
-# define SSD1289_ENTRY_DMODE_RAMGEN (2 << SSD1289_ENTRY_DMODE_SHIFT)
-# define SSD1289_ENTRY_DMODE_GENRAM (3 << SSD1289_ENTRY_DMODE_SHIFT)
-#define SSD1289_ENTRY_WMODE (1 << 10) /* Select source of data in RAM */
-#define SSD1289_ENTRY_OEDEF (1 << 11) /* Define display window */
-#define SSD1289_ENTRY_TRANS (1 << 12) /* Transparent display */
-#define SSD1289_ENTRY_DFM_SHIFT (13) /* Color display mode */
-#define SSD1289_ENTRY_DFM_MASK (3 << SSD1289_ENTRY_DFM_SHIFT)
-# define SSD1289_ENTRY_DFM_262K (2 << SSD1289_ENTRY_DFM_SHIFT)
-# define SSD1289_ENTRY_DFM_65K (3 << SSD1289_ENTRY_DFM_SHIFT)
-#define SSD1289_ENTRY_VSMODE (1 << 15) /* Frame frequency depends on VSYNC */
-
-/* Generic Interface Control */
-
-#define SSD1289_GIFCTRL_INVVS (1 << 0) /* Sets the signal polarity of DOTCLK pin */
-#define SSD1289_GIFCTRL_INVHS (1 << 1) /* Sets the signal polarity of DEN pin */
-#define SSD1289_GIFCTRL_NVDEN (1 << 2) /* Sets the signal polarity of HSYNC pin */
-#define SSD1289_GIFCTRL_INVDOT (1 << 3) /* Sets the signal polarity of VSYNC pin */
-
-/* Horizontal Porch */
-
-#define SSD1289_HPORCH_HBP_SHIFT (0) /* Set delay from falling edge of HSYNC signal to data */
-#define SSD1289_HPORCH_HBP_MASK (0xff << SSD1289_HPORCH_HBP_SHIFT)
-#define SSD1289_HPORCH_XL_SHIFT (8) /* number of valid pixel per line */
-#define SSD1289_HPORCH_XL_MASK (0xff << SSD1289_HPORCH_XL_SHIFT)
-
-/* Vertical Porch */
-
-#define SSD1289_VPORCH_VBP_SHIFT (0) /* Set delay from falling edge of VSYNC signal to line */
-#define SSD1289_VPORCH_VBP_MASK (0xff << SSD1289_VPORCH_VBP_SHIFT)
-#define SSD1289_VPORCH_XFP_SHIFT (8) /* Delay from last line to falling edge of VSYNC of next frame */
-#define SSD1289_VPORCH_XFP_MASK (0xff << SSD1289_VPORCH_XFP_SHIFT)
-#define SSD1289_VPORCH_
-
-/* Power control 5 */
-
-#define SSD1289_PWRCTRL5_VCM_SHIFT (0) /* Set the VcomH voltage */
-#define SSD1289_PWRCTRL5_VCM_MASK (0x3f << SSD1289_PWRCTRL5_VCM_SHIFT)
-# define SSD1289_PWRCTRL5_VCM(n) ((n) << SSD1289_PWRCTRL5_VCM_SHIFT)
-#define SSD1289_PWRCTRL5_NOTP (1 << 7) /* 1=VCM valid */
-
-/* RAM write data mask 1 */
-
-#define SSD1289_WRMASK1_WMG_SHIFT (2)
-#define SSD1289_WRMASK1_WMG_MASK (0x3f << SSD1289_WRMASK1_WMG_SHIFT)
-#define SSD1289_WRMASK1_WMR_SHIFT (10)
-#define SSD1289_WRMASK1_WMR_MASK (0x3f << SSD1289_WRMASK1_WMR_SHIFT)
-
-#define SSD1289_WRMASK2_WMB_SHIFT (2)
-#define SSD1289_WRMASK2_WMB_MASK (0x3f << SSD1289_WRMASK2_WMB_SHIFT)
-
-/* Frame Frequency */
-
-#define SSD1289_FFREQ_OSC_SHIFT (12) /* Set the frame frequency */
-#define SSD1289_FFREQ_OSC_MASK (15 << SSD1289_FFREQ_OSC_SHIFT)
-# define SSD1289_FFREQ_OSC_FF50 (0 << SSD1289_FFREQ_OSC_SHIFT)
-# define SSD1289_FFREQ_OSC_FF55 (2 << SSD1289_FFREQ_OSC_SHIFT)
-# define SSD1289_FFREQ_OSC_FF60 (5 << SSD1289_FFREQ_OSC_SHIFT)
-# define SSD1289_FFREQ_OSC_FF65 (8 << SSD1289_FFREQ_OSC_SHIFT)
-# define SSD1289_FFREQ_OSC_FF70 (10 << SSD1289_FFREQ_OSC_SHIFT)
-# define SSD1289_FFREQ_OSC_FF75 (12 << SSD1289_FFREQ_OSC_SHIFT)
-# define SSD1289_FFREQ_OSC_FF80 (14 << SSD1289_FFREQ_OSC_SHIFT)
-
-/* VCOM OTP */
-
-#define SSD1289_VCOMOTP1_ACTIVATE 0x0006
-#define SSD1289_VCOMOTP1_FIRE 0x000a
-#define SSD1289_VCOMOTP2_ACTIVATE 0x80c0
-
-/* Optimize Access Speed 1, 2, 3 (omitted) */
-
-/* Gamma control 1-10. Magic values. I won't try to represent the fields. */
-
-/* Vertical scroll control 1 and 2 */
-
-#define SSD1289_VSCROLL_MASK 0x1ff /* Scroll length */
-
-/* Horizontal RAM address position */
-
-#define SSD1289_HADDR_HSA_SHIFT (0) /* Window horizontal start address */
-#define SSD1289_HADDR_HSA_MASK (0xff << SSD1289_HADDR_HSA_SHIFT)
-#define SSD1289_HADDR_HEA_SHIFT (8) /* Window horizontal end address */
-#define SSD1289_HADDR_HEA_MASK (0xff << SSD1289_HADDR_HEA_SHIFT)
-
-/* Vertical RAM address start/end position */
-
-#define SSD1289_VSTART_MASK 0x1ff /* Window Vertical start address */
-#define SSD1289_VEND_MASK 0x1ff /* Window Vertical end address */
-
-/* First window start/end */
-
-#define SSD1289_W1START_MASK 0x1ff /* Start line for first screen */
-#define SSD1289_W1END_MASK 0x1ff /* End line for first screen */
-
-/* Second window start/end */
-
-#define SSD1289_W2START_MASK 0x1ff /* Start line for second screen */
-#define SSD1289_W2END_MASK 0x1ff /* End line for second screen */
-
-/* Set GDDRAM X/Y address counter */
-
-#define SSD1289_XADDR_MASK 0xff /* GDDRAM X address in the address counter */
-#define SSD1289_YADDR_MASK 0x1ff /* GDDRAM Y address in the address counter */
-
-#endif /* CONFIG_LCD_SSD1289 */
-#endif /* __DRIVERS_LCD_SSD1289_H */
diff --git a/nuttx/drivers/lcd/ssd1305.h b/nuttx/drivers/lcd/ssd1305.h
deleted file mode 100644
index 34678fa80..000000000
--- a/nuttx/drivers/lcd/ssd1305.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/ssd1305.h
- * Definitions for the Solomon Systech SSD1305 132x64 Dot Matrix OLED/PLED
- * Segment/Common Driver with C
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References: SSD1305.pdf, "Solomon Systech SSD1305 132x64 Dot Matrix OLED/PLED
- * Segment/Common Driver with Controller," Solomon Systech Limited,
- * http://www.solomon-systech.com, May, 2008.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- **************************************************************************************/
-
-#ifndef __DRIVERS_LCD_SSD1305_H
-#define __DRIVERS_LCD_SSD1305_H
-
-/**************************************************************************************
- * Included Files
- **************************************************************************************/
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-/* General Definitions ******************************************************/
-
-#define SSD1305_COLORA 0
-#define SSD1305_COLORB 1
-#define SSD1305_COLORC 2
-#define SSD1305_COLORD 3
-
-/* Fundamental Commands *****************************************************/
-#define SSD1305_SETCOLL 0x00 /* 0x00-0x0f: Set lower column address */
-# define SSD1305_COLL_MASK 0x0f
-#define SSD1305_SETCOLH 0x10 /* 0x10-0x1f: Set higher column address */
-# define SSD1305_COLH_MASK 0x0f
-#define SSD1305_ADDRMODE 0x20 /* 0x20: Set memory address mode */
-# define SSD1305_ADDRMODE_HOR 0x00 /* Data 1: Set horizontal address mode */
-# define SSD1305_ADDRMODE_VIRT 0x01 /* Data 1: Set virtal address mode */
-# define SSD1305_ADDRMODE_PAGE 0x02 /* Data 1: Set page address mode */
-#define SSD1305_SETCOLADDR 0x21 /* 0x21: Set column address */
- /* Data 1: Column start address: 0-131 */
- /* Data 2: Column end address: 0-131 */
-#define SSD1305_SETPAGEADDR 0x22 /* 0x22: Set page address */
- /* Data 1: Page start address: 0x00-0x7d */
- /* Data 2: Page end address: 0x00-0x7d */
-#define SSD1305_SETSTARTLINE 0x40 /* 0x40-7f: Set display start line */
-# define SSD1305_STARTLINE_MASK 0x3f
-
-#define SSD1305_SETCONTRAST 0x81 /* 0x81: Set contrast control */
- /* Data 1: Set 1 of 256 contrast steps */
-#define SSD1305_SETBRIGHTNESS 0x82 /* 0x82: Set brightness */
- /* Data 1: Set 1 of 256 contrast steps */
-#define SSD1305_SETLUT 0x91 /* 0x01: Set lookup table */
- /* Data 1: Pulse width: 31-63 */
- /* Data 2: Color A: 31-63 */
- /* Data 3: Color B: 31-63 */
- /* Data 4: Color C: 31-63 */
-#define SSD1305_SETBANKCOLOR1 0x92 /* 0x92: Set bank 1-16 color */
-# define SSD1305_SETBANK1(c) (c) /* Data 1, Bits 0-1: Bank 1 color */
-# define SSD1305_SETBANK2(c) (c << 2) /* Data 1, Bits 2-3: Bank 2 color */
-# define SSD1305_SETBANK3(c) (c << 4) /* Data 1, Bits 4-5: Bank 3 color */
-# define SSD1305_SETBANK4(c) (c << 6) /* Data 1, Bits 6-7: Bank 4 color */
-# define SSD1305_SETBANK5(c) (c) /* Data 2, Bits 0-1: Bank 5 color */
-# define SSD1305_SETBANK6(c) (c << 2) /* Data 2, Bits 2-3: Bank 6 color */
-# define SSD1305_SETBANK7(c) (c << 4) /* Data 2, Bits 4-5: Bank 7 color */
-# define SSD1305_SETBANK8(c) (c << 6) /* Data 2, Bits 6-7: Bank 8 color */
-# define SSD1305_SETBANK9(c) (c) /* Data 3, Bits 0-1: Bank 9 color */
-# define SSD1305_SETBANK10(c) (c << 2) /* Data 3, Bits 2-3: Bank 10 color */
-# define SSD1305_SETBANK11(c) (c << 4) /* Data 3, Bits 4-5: Bank 11 color */
-# define SSD1305_SETBANK12(c) (c << 6) /* Data 3, Bits 6-7: Bank 12 color */
-# define SSD1305_SETBANK13(c) (c) /* Data 4, Bits 0-1: Bank 13 color */
-# define SSD1305_SETBANK14(c) (c << 2) /* Data 4, Bits 2-3: Bank 14 color */
-# define SSD1305_SETBANK15(c) (c << 4) /* Data 4, Bits 4-5: Bank 15 color */
-# define SSD1305_SETBANK16(c) (c << 6) /* Data 4, Bits 6-7: Bank 16 color */
-#define SSD1305_SETBANKCOLOR2 0x93 /* 0x93: Set bank 17-32 color */
-# define SSD1305_SETBANK17(c) (c) /* Data 1, Bits 0-1: Bank 17 color */
-# define SSD1305_SETBANK18(c) (c << 2) /* Data 1, Bits 2-3: Bank 18 color */
-# define SSD1305_SETBANK19(c) (c << 4) /* Data 1, Bits 4-5: Bank 19 color */
-# define SSD1305_SETBANK20(c) (c << 6) /* Data 1, Bits 6-7: Bank 20 color */
-# define SSD1305_SETBANK21(c) (c) /* Data 2, Bits 0-1: Bank 21 color */
-# define SSD1305_SETBANK22(c) (c << 2) /* Data 2, Bits 2-3: Bank 22 color */
-# define SSD1305_SETBANK23(c) (c << 4) /* Data 2, Bits 4-5: Bank 23 color */
-# define SSD1305_SETBANK24(c) (c << 6) /* Data 2, Bits 6-7: Bank 24 color */
-# define SSD1305_SETBANK25(c) (c) /* Data 3, Bits 0-1: Bank 25 color */
-# define SSD1305_SETBANK26(c) (c << 2) /* Data 3, Bits 2-3: Bank 26 color */
-# define SSD1305_SETBANK27(c) (c << 4) /* Data 3, Bits 4-5: Bank 27 color */
-# define SSD1305_SETBANK28(c) (c << 6) /* Data 3, Bits 6-7: Bank 28 color */
-# define SSD1305_SETBANK29(c) (c) /* Data 4, Bits 0-1: Bank 29 color */
-# define SSD1305_SETBANK30(c) (c << 2) /* Data 4, Bits 2-3: Bank 30 color */
-# define SSD1305_SETBANK31(c) (c << 4) /* Data 4, Bits 4-5: Bank 31 color */
-# define SSD1305_SETBANK32(c) (c << 6) /* Data 4, Bits 6-7: Bank 32 color */
-#define SSD1305_MAPCOL0 0xa0 /* 0xa0: Column address 0 is mapped to SEG0 */
-#define SSD1305_MAPCOL131 0xa1 /* 0xa1: Column address 131 is mapped to SEG0 */
-#define SSD1305_DISPRAM 0xa4 /* 0xa4: Resume to RAM content display */
-#define SSD1305_DISPENTIRE 0xa5 /* 0xa5: Entire display ON */
-#define SSD1305_DISPNORMAL 0xa6 /* 0xa6: Normal display */
-#define SSD1305_DISPINVERTED 0xa7 /* 0xa7: Inverse display */
-
-#define SSD1305_SETMUX 0xa8 /* 0xa8: Set Multiplex Ratio*/
- /* Data 1: MUX ratio -1: 15-63 */
-#define SSD1305_DIMMODE 0xab /* 0xab: Dim mode setting */
- /* Data 1: Reserverd, must be zero */
- /* Data 2: Contrast for bank1: 0-255 */
- /* Data 3: Brightness for color bank: 0-255 */
-#define SSD1305_MSTRCONFIG 0xad /* 0xad: Master configuration */
-# define SSD1305_MSTRCONFIG_EXTVCC 0x8e /* Data 1: Select external Vcc */
-#define SSD1305_DISPONDIM 0xac /* 0xac: Display ON in dim mode */
-#define SSD1305_DISPOFF 0xae /* 0xae: Display OFF (sleep mode) */
-#define SSD1305_DISPON 0xaf /* 0xaf: Display ON in normal mode */
-#define SSD1305_SETPAGESTART 0xb0 /* 0xb0-b7: Set page start address */
-# define SSD1305_PAGESTART_MASK 0x07
-#define SSD1305_SETCOMNORMAL 0xc0 /* 0xc0: Set COM output, normal mode */
-#define SSD1305_SETCOMREMAPPED 0xc8 /* 0xc8: Set COM output, remapped mode */
-
-#define SSD1305_SETOFFSET 0xd3 /* 0xd3: Set display offset */
- /* Data 1: Vertical shift by COM: 0-63 */
-#define SSD1305_SETDCLK 0xd5 /* 0xd5: Set display clock divide ratio/oscillator */
-# define SSD1305_DCLKDIV_SHIFT (0) /* Data 1, Bits 0-3: DCLK divide ratio/frequency*/
-# define SSD1305_DCLKDIV_MASK 0x0f
-# define SSD1305_DCLKFREQ_SHIFT (4) /* Data 1, Bits 4-7: DCLK divide oscillator frequency */
-# define SSD1305_DCLKFREQ_MASK 0xf0
-#define SSD1305_SETCOLORMODE 0xd8 /* 0xd: Set area color and low power display modes */
-# define SSD1305_COLORMODE_MONO 0x00 /* Data 1, Bits 4-5: 00=monochrome */
-# define SSD1305_COLORMODE_COLOR 0x30 /* Data 1, Bits 4-5: 11=area color enable */
-# define SSD1305_POWERMODE_NORMAL 0x00 /* Data 1, Bits 0,2: 00=normal power mode */
-# define SSD1305_POWERMODE_LOW 0x05 /* Data 1, Bits 0,2: 11=low power display mode */
-#define SSD1305_SETPRECHARGE 0xd9 /* 0xd9: Set pre-charge period */
-# define SSD1305_PHASE1_SHIFT (0) /* Data 1, Bits 0-3: Phase 1 period of up to 15 DCLK clocks */
-# define SSD1305_PHASE1_MASK 0x0f
-# define SSD1305_PHASE2_SHIFT (4) /* Data 1, Bits 4-7: Phase 2 period of up to 15 DCLK clocks */
-# define SSD1305_PHASE2_MASK 0xf0
-#define SSD1305_SETCOMCONFIG 0xda /* 0xda: Set COM configuration */
-# define SSD1305_COMCONFIG_SEQ 0x02 /* Data 1, Bit 4: 0=Sequential COM pin configuration */
-# define SSD1305_COMCONFIG_ALT 0x12 /* Data 1, Bit 4: 1=Alternative COM pin configuration */
-# define SSD1305_COMCONFIG_NOREMAP 0x02 /* Data 1, Bit 5: 0=Disable COM Left/Right remap */
-# define SSD1305_COMCONFIG_REMAP 0x22 /* Data 1, Bit 5: 1=Enable COM Left/Right remap */
-#define SSD1305_SETVCOMHDESEL 0xdb /* 0xdb: Set VCOMH delselect level */
-# define SSD1305_VCOMH_x4p3 0x00 /* Data 1: ~0.43 x Vcc */
-# define SSD1305_VCOMH_x7p7 0x34 /* Data 1: ~0.77 x Vcc */
-# define SSD1305_VCOMH_x8p3 0x3c /* Data 1: ~0.83 x Vcc */
-#define SSD1305_ENTER_RMWMODE 0xe0 /* 0xe0: Enter the Read Modify Write mode */
-#define SSD1305_NOP 0xe3 /* 0xe3: NOP Command for no operation */
-#define SSD1305_EXIT_RMWMODE 0xee /* 0xee: Leave the Read Modify Write mode */
-
-/* Graphic Acceleration Commands ********************************************/
-
-#define SSD1305_HSCROLL_RIGHT 0x26 /* 0x26: Right horizontal scroll */
-#define SSD1305_HSCROLL_LEFT 0x27 /* 0x27: Left horizontal scroll */
- /* Data 1, Bits 0-2: Column scroll offset: 0-4 */
- /* Data 2, Bits 0-2: Start page address: 0-7 */
-#define SSD1305_HSCROLL_FRAMES6 0x00 /* Data 3, Bits 0-2: Timer interval, 000=6 frames */
-#define SSD1305_HSCROLL_FRAMES32 0x01 /* Data 3, Bits 0-2: Timer interval, 001=32 frames */
-#define SSD1305_HSCROLL_FRAMES64 0x02 /* Data 3, Bits 0-2: Timer interval, 010=64 frames */
-#define SSD1305_HSCROLL_FRAMES128 0x03 /* Data 3, Bits 0-2: Timer interval, 011=128 frames */
-#define SSD1305_HSCROLL_FRAMES3 0x04 /* Data 3, Bits 0-2: Timer interval, 100=3 frames */
-#define SSD1305_HSCROLL_FRAMES4 0x05 /* Data 3, Bits 0-2: Timer interval, 101=4 frames */
-#define SSD1305_HSCROLL_FRAMES2 0x06 /* Data 3, Bits 0-2: Timer interval, 110=2 frames */
- /* Data 4, Bits 0-2: End page address: 0-7 */
-
-#define SSD1305_VSCROLL_RIGHT 0x29 /* 0x26: Vertical and right horizontal scroll */
-#define SSD1305_VSCROLL_LEFT 0x2a /* 0x27: Vertical and left horizontal scroll */
- /* Data 1, Bits 0-2: Column scroll offset: 0-4 */
- /* Data 2, Bits 0-2: Start page address: 0-7 */
-#define SSD1305_VSCROLL_FRAMES6 0x00 /* Data 3, Bits 0-2: Timer interval, 000=6 frames */
-#define SSD1305_VSCROLL_FRAMES32 0x01 /* Data 3, Bits 0-2: Timer interval, 001=32 frames */
-#define SSD1305_VSCROLL_FRAMES64 0x02 /* Data 3, Bits 0-2: Timer interval, 010=64 frames */
-#define SSD1305_VSCROLL_FRAMES128 0x03 /* Data 3, Bits 0-2: Timer interval, 011=128 frames */
-#define SSD1305_VSCROLL_FRAMES3 0x04 /* Data 3, Bits 0-2: Timer interval, 100=3 frames */
-#define SSD1305_VSCROLL_FRAMES4 0x05 /* Data 3, Bits 0-2: Timer interval, 101=4 frames */
-#define SSD1305_VSCROLL_FRAMES2 0x06 /* Data 3, Bits 0-2: Timer interval, 110=2 frames */
- /* Data 4, Bits 0-2: End page address: 0-7 */
- /* Data 5, Bits 0-5: Vertical scrolling offset: 0-63 */
-#define SSD1305_SCROLL_STOP 0x2e /* 0x2e: Deactivate scroll */
-#define SSD1305_SCROLL_START 0x2f /* 0x2f: Activate scroll */
-#define SSD1305_VSCROLL_AREA 0xa3 /* 0xa3: Set vertical scroll area */
- /* Data 1: Number of rows in the top fixed area */
- /* Data 1: Number of rows in the scroll area */
-
-/* Status register bit definitions ******************************************/
-
-#define SSD1305_STATUS_DISPOFF (1 << 6) /* Bit 6: 1=Display off */
-
-#endif /* __DRIVERS_LCD_SSD1305_H */
diff --git a/nuttx/drivers/lcd/ug-2864ambag01.c b/nuttx/drivers/lcd/ug-2864ambag01.c
deleted file mode 100644
index 6b3d6d5a8..000000000
--- a/nuttx/drivers/lcd/ug-2864ambag01.c
+++ /dev/null
@@ -1,1161 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/ug-2864ambag01.c
- * Driver for Univision UG-2864AMBAG01 OLED display (wih SH1101A controller) in SPI
- * mode
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * 1. Product Specification (Preliminary), Part Name: OEL Display Module, Part ID:
- * UG-2864AMBAG01, Doc No: SASI-9015-A, Univision Technology Inc.
- * 2. SH1101A, 132 X 64 Dot Matrix OLED/PLED, Preliminary Segment/Common Driver with
- * Controller, Sino Wealth
- *
- * 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.
- *
- **************************************************************************************/
-/**************************************************************************************
- * Device memory organization:
- *
- * +----------------------------+
- * | Column |
- * --------+----+---+---+---+-...-+-----+
- * Page | 0 | 1 | 2 | 3 | ... | 131 |
- * --------+----+---+---+---+-...-+-----+
- * Page 0 | D0 | X | | | | |
- * | D1 | X | | | | |
- * | D2 | X | | | | |
- * | D3 | X | | | | |
- * | D4 | X | | | | |
- * | D5 | X | | | | |
- * | D6 | X | | | | |
- * | D7 | X | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 1 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 2 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 3 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 4 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 5 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 6 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 7 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- *
- * -----------------------------------+---------------------------------------
- * Landscape Display: | Reverse Landscape Display:
- * --------+-----------------------+ | --------+---------------------------+
- * | Column | | | Column |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 0 | 0 | 1 | 2 | | 131 | | Page 7 | 131 | 130 | 129 | | 0 |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 1 | V | | Page 6 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 2 | V | | Page 5 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 3 | V | | Page 4 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 4 | V | | Page 3 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 5 | V | | Page 2 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 6 | V | | Page 1 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 7 | V | | Page 0 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * -----------------------------------+---------------------------------------
- *
- * -----------------------------------+---------------------------------------
- * Portrait Display: | Reverse Portrait Display:
- * -----------+---------------------+ | -----------+---------------------+
- * | Page | | | Page |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * Column 0 | 0 | 1 | 2 | | 7 | | Column 131 | 7 | 6 | 5 | | 0 |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * Column 1 | > > > > > | | Column 130 | |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * Column 2 | | | Column 129 | |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * ... | | | ... | |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * Column 131 | | | Column 0 | < < < < < |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * -----------------------------------+----------------------------------------
- **************************************************************************************/
-
-/**************************************************************************************
- * Included Files
- **************************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/spi.h>
-#include <nuttx/lcd/lcd.h>
-#include <nuttx/lcd/ug-2864ambag01.h>
-
-#include <arch/irq.h>
-
-#ifdef CONFIG_LCD_UG2864AMBAG01
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-/* Configuration **********************************************************************/
-/* Limitations of the current configuration that I hope to fix someday */
-
-#if CONFIG_UG2864AMBAG01_NINTERFACES != 1
-# warning "This implementation supports only a single OLED device"
-# undef CONFIG_UG2864AMBAG01_NINTERFACES
-# define CONFIG_UG2864AMBAG01_NINTERFACES 1
-#endif
-
-#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT)
-# warning "No support yet for portrait modes"
-# define CONFIG_LCD_LANDSCAPE 1
-# undef CONFIG_LCD_PORTRAIT
-# undef CONFIG_LCD_RLANDSCAPE
-# undef CONFIG_LCD_RPORTRAIT
-#elif defined(CONFIG_LCD_RLANDSCAPE)
-# warning "Reverse landscape mode is untested and, hence, probably buggy"
-#endif
-
-/* SH1101A Commands *******************************************************************/
-
-#define SH1101A_SETCOLL(ad) (0x00 | ((ad) & 0x0f)) /* Set Lower Column Address: (00h - 0fh) */
-#define SH1101A_SETCOLH(ad) (0x10 | ((ad) & 0x0f)) /* Set Higher Column Address: (10h - 1fh) */
-#define SH1101A_STARTLINE(ln) (0x40 | ((ln) & 0x3f)) /* Set Display Start Line: (40h - 7fh) */
-#define SH1101A_CONTRAST_MODE (0x81) /* Set Contrast Control Register: (Double Bytes Command) */
-# define SH1101A_CONTRAST(c) (c)
-#define SH1101A_SEGREMAP(m) (0xa0 | ((m) & 0x01)) /* Set Segment Re-map: (a0h - a1h) */
-# define SH1101A_REMAPRIGHT SH1101A_SEGREMAP(0) /* Right rotation */
-# define SH1101A_REMAPPLEFT SH1101A_SEGREMAP(1) /* Left rotation */
-#define SH1101A_EDISPOFFON(s) (0xa4 | ((s) & 0x01)) /* Set Entire Display OFF/ON: (a4h - a5h) */
-# define SH1101A_EDISPOFF SH1101A_EDISPOFFON(0) /* Display off */
-# define SH1101A_EDISPON SH1101A_EDISPOFFON(1) /* Display on */
-#define SH1101A_NORMREV(s) (0xa6 | ((s) & 0x01)) /* Set Normal/Reverse Display: (a6h -a7h) */
-# define SH1101A_NORMAL SH1101A_NORMREV(0) /* Normal display */
-# define SH1101A_REVERSE SH1101A_NORMREV(1) /* Reverse display */
-#define SH1101A_MRATIO_MODE (0xa8) /* Set Multiplex Ration: (Double Bytes Command) */
-# define SH1101A_MRATIO(d) ((d) & 0x3f)
-#define SH1101A_DCDC_MODE (0xad) /* Set DC-DC OFF/ON: (Double Bytes Command) */
-# define SH1101A_DCDC_OFF (0x8a)
- # define SH1101A_DCDC_ON (0x8b)
-#define SH1101A_DISPOFFON(s) (0xae | ((s) & 0x01)) /* Display OFF/ON: (aeh - afh) */
-# define SH1101A_DISPOFF SH1101A_DISPOFFON(0) /* Display off */
-# define SH1101A_DISPON SH1101A_DISPOFFON(1) /* Display on */
-#define SH1101A_PAGEADDR(a) (0xb0 | ((a) & 0x0f)) /* Set Page Address: (b0h - b7h) */
-#define SH1101A_SCANDIR(d) (0xc0 | ((d) & 0x08)) /* Set Common Output Scan Direction: (c0h - c8h) */
-# define SH1101A_SCANFROMCOM0 SH1101A_SCANDIR(0x00) /* Scan from COM[0] to COM[n-1]*/
-# define SH1101A_SCANTOCOM0 SH1101A_SCANDIR(0x08) /* Scan from COM[n-1] to COM[0] */
-#define SH1101A_DISPOFFS_MODE (0xd3) /* Set Display Offset: (Double Bytes Command) */
-# define SH1101A_DISPOFFS(o) ((o) & 0x3f)
-#define SH1101A_CLKDIV_SET (0xd5) /* Set Display Clock Divide Ratio/Oscillator Frequency: (Double Bytes Command) */
-# define SH1101A_CLKDIV(f,d) ((((f) & 0x0f) << 4) | ((d) & 0x0f))
-#define SH1101A_CHRGPER_SET (0xd9) /* Set Dis-charge/Pre-charge Period: (Double Bytes Command) */
-# define SH1101A_CHRGPER(d,p) ((((d) & 0x0f) << 4) | ((p) & 0x0f))
-#define SH1101A_CMNPAD_CONFIG (0xda) /* Set Common pads hardware configuration: (Double Bytes Command) */
- #define SH1101A_CMNPAD(c) ((0x02) | ((c) & 0x10))
-#define SH1101A_VCOM_SET (0xdb) /* Set VCOM Deselect Level: (Double Bytes Command) */
-# define SH1101A_VCOM(v) (v)
-#define SH1101A_RMWSTART (0xe0) /* Read-Modify-Write: (e0h) */
-#define SH1101A_NOP (0xe3) /* NOP: (e3h) */
-#define SH1101A_END (0xee) /* End: (eeh) */
-
-#define SH1101A_WRDATA(d) (d) /* Write Display Data */
-#define SH1101A_STATUS_BUSY (0x80) /* Read Status */
-#define SH1101A_STATUS_ONOFF (0x40)
-#define SH1101A_RDDATA(d) (d) /* Read Display Data */
-
-/* Color Properties *******************************************************************/
-/* Display Resolution
- *
- * The SH1101A display controller can handle a resolution of 132x64. The UG-2864AMBAG01
- * on the base board is 128x64.
- */
-
-#define UG2864AMBAG01_DEV_XRES 128 /* Only 128 of 131 columns used */
-#define UG2864AMBAG01_DEV_YRES 64 /* 8 pages each 8 rows */
-#define UG2864AMBAG01_DEV_XOFFSET 2 /* Offset to logical column 0 */
-#define UG2864AMBAG01_DEV_PAGES 8 /* 8 pages */
-
-#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-# define UG2864AMBAG01_XRES UG2864AMBAG01_DEV_XRES
-# define UG2864AMBAG01_YRES UG2864AMBAG01_DEV_YRES
-#else
-# define UG2864AMBAG01_XRES UG2864AMBAG01_DEV_YRES
-# define UG2864AMBAG01_YRES UG2864AMBAG01_DEV_XRES
-#endif
-
-/* Color depth and format */
-
-#define UG2864AMBAG01_BPP 1
-#define UG2864AMBAG01_COLORFMT FB_FMT_Y1
-
-/* Bytes per logical row and actual device row */
-
-#define UG2864AMBAG01_XSTRIDE (UG2864AMBAG01_XRES >> 3)
-#define UG2864AMBAG01_YSTRIDE (UG2864AMBAG01_YRES >> 3)
-
-/* Default contrast */
-
-#define UG2864AMBAG01_CONTRAST (128)
-
-/* The size of the shadow frame buffer or one row buffer.
- *
- * Frame buffer size: 128 columns x 64 rows / 8 bits-per-pixel
- * Row size: 128 columns x 8 rows-per-page / 8 bits-per-pixel
- */
-
-#define UG2864AMBAG01_FBSIZE (UG2864AMBAG01_XSTRIDE * UG2864AMBAG01_YRES)
-#define UG2864AMBAG01_ROWSIZE (UG2864AMBAG01_XSTRIDE)
-
-/* Bit helpers */
-
-#define LS_BIT (1 << 0)
-#define MS_BIT (1 << 7)
-
-/* Debug ******************************************************************************/
-
-#ifdef CONFIG_DEBUG_LCD
-# define lcddbg(format, arg...) dbg(format, ##arg)
-# define lcdvdbg(format, arg...) vdbg(format, ##arg)
-#else
-# define lcddbg(x...)
-# define lcdvdbg(x...)
-#endif
-
-/**************************************************************************************
- * Private Type Definition
- **************************************************************************************/
-
-/* This structure describes the state of this driver */
-
-struct ug2864ambag01_dev_s
-{
- struct lcd_dev_s dev; /* Publically visible device structure */
-
- /* Private LCD-specific information follows */
-
- FAR struct spi_dev_s *spi; /* Cached SPI device reference */
- uint8_t contrast; /* Current contrast setting */
- bool on; /* true: display is on */
-
-
- /* The SH1101A does not support reading from the display memory in SPI mode.
- * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep
- * a shadow copy of the framebuffer memory. At 128x64, this amounts to 1KB.
- */
-
- uint8_t fb[UG2864AMBAG01_FBSIZE];
-};
-
-/**************************************************************************************
- * Private Function Protototypes
- **************************************************************************************/
-
-/* Low-level SPI helpers */
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void ug2864ambag01_configspi(FAR struct spi_dev_s *spi);
-# define ug2864ambag01_lock(spi)
-# define ug2864ambag01_unlock(spi)
-#else
-# define ug2864ambag01_configspi(spi)
-static void ug2864ambag01_lock(FAR struct spi_dev_s *spi);
-static void ug2864ambag01_unlock(FAR struct spi_dev_s *spi);
-#endif
-
-/* LCD Data Transfer Methods */
-
-static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col,
- FAR const uint8_t *buffer, size_t npixels);
-static int ug2864ambag01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels);
-
-/* LCD Configuration */
-
-static int ug2864ambag01_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo);
-static int ug2864ambag01_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo);
-
-/* LCD RGB Mapping */
-
-#ifdef CONFIG_FB_CMAP
-# error "RGB color mapping not supported by this driver"
-#endif
-
-/* Cursor Controls */
-
-#ifdef CONFIG_FB_HWCURSOR
-# error "Cursor control not supported by this driver"
-#endif
-
-/* LCD Specific Controls */
-
-static int ug2864ambag01_getpower(struct lcd_dev_s *dev);
-static int ug2864ambag01_setpower(struct lcd_dev_s *dev, int power);
-static int ug2864ambag01_getcontrast(struct lcd_dev_s *dev);
-static int ug2864ambag01_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
-
-/**************************************************************************************
- * Private Data
- **************************************************************************************/
-
-/* This is working memory allocated by the LCD driver for each LCD device
- * and for each color plane. This memory will hold one raster line of data.
- * The size of the allocated run buffer must therefore be at least
- * (bpp * xres / 8). Actual alignment of the buffer must conform to the
- * bitwidth of the underlying pixel type.
- *
- * If there are multiple planes, they may share the same working buffer
- * because different planes will not be operate on concurrently. However,
- * if there are multiple LCD devices, they must each have unique run buffers.
- */
-
-static uint8_t g_runbuffer[UG2864AMBAG01_ROWSIZE];
-
-/* This structure describes the overall LCD video controller */
-
-static const struct fb_videoinfo_s g_videoinfo =
-{
- .fmt = UG2864AMBAG01_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
- .xres = UG2864AMBAG01_XRES, /* Horizontal resolution in pixel columns */
- .yres = UG2864AMBAG01_YRES, /* Vertical resolution in pixel rows */
- .nplanes = 1, /* Number of color planes supported */
-};
-
-/* This is the standard, NuttX Plane information object */
-
-static const struct lcd_planeinfo_s g_planeinfo =
-{
- .putrun = ug2864ambag01_putrun, /* Put a run into LCD memory */
- .getrun = ug2864ambag01_getrun, /* Get a run from LCD memory */
- .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */
- .bpp = UG2864AMBAG01_BPP, /* Bits-per-pixel */
-};
-
-/* This is the OLED driver instance (only a single device is supported for now) */
-
-static struct ug2864ambag01_dev_s g_oleddev =
-{
- .dev =
- {
- /* LCD Configuration */
-
- .getvideoinfo = ug2864ambag01_getvideoinfo,
- .getplaneinfo = ug2864ambag01_getplaneinfo,
-
- /* LCD RGB Mapping -- Not supported */
- /* Cursor Controls -- Not supported */
-
- /* LCD Specific Controls */
-
- .getpower = ug2864ambag01_getpower,
- .setpower = ug2864ambag01_setpower,
- .getcontrast = ug2864ambag01_getcontrast,
- .setcontrast = ug2864ambag01_setcontrast,
- },
-};
-
-/**************************************************************************************
- * Private Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: ug2864ambag01_configspi
- *
- * Description:
- * Configure the SPI for use with the UG-2864AMBAG01
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void ug2864ambag01_configspi(FAR struct spi_dev_s *spi)
-{
- lcdvdbg("Mode: %d Bits: 8 Frequency: %d\n",
- CONFIG_UG2864AMBAG01_SPIMODE, CONFIG_UG2864AMBAG01_FREQUENCY);
-
- /* Configure SPI for the UG-2864AMBAG01. But only if we own the SPI bus. Otherwise,
- * don't bother because it might change.
- */
-
- SPI_SETMODE(spi, CONFIG_UG2864AMBAG01_SPIMODE);
- SPI_SETBITS(spi, 8);
- SPI_SETFREQUENCY(spi, CONFIG_UG2864AMBAG01_FREQUENCY);
-}
-#endif
-
-/**************************************************************************************
- * Name: ug2864ambag01_lock
- *
- * Description:
- * Select the SPI, locking and re-configuring if necessary
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static inline void ug2864ambag01_lock(FAR struct spi_dev_s *spi)
-{
- /* Lock the SPI bus if there are multiple devices competing for the SPI bus. */
-
- SPI_LOCK(spi, true);
-
- /* Now make sure that the SPI bus is configured for the UG-2864AMBAG01 (it
- * might have gotten configured for a different device while unlocked)
- */
-
- SPI_SETMODE(spi, CONFIG_UG2864AMBAG01_SPIMODE);
- SPI_SETBITS(spi, 8);
- SPI_SETFREQUENCY(spi, CONFIG_UG2864AMBAG01_FREQUENCY);
-}
-#endif
-
-/**************************************************************************************
- * Name: ug2864ambag01_unlock
- *
- * Description:
- * De-select the SPI
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static inline void ug2864ambag01_unlock(FAR struct spi_dev_s *spi)
-{
- /* De-select UG-2864AMBAG01 chip and relinquish the SPI bus. */
-
- SPI_LOCK(spi, false);
-}
-#endif
-
-/**************************************************************************************
- * Name: ug2864ambag01_putrun
- *
- * Description:
- * This method can be used to write a partial raster line to the LCD.
- *
- * Input Parameters:
- * row - Starting row to write to (range: 0 <= row < yres)
- * col - Starting column to write to (range: 0 <= col <= xres-npixels)
- * buffer - The buffer containing the run to be written to the LCD
- * npixels - The number of pixels to write to the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-static int ug2864ambag01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels)
-{
- /* Because of this line of code, we will only be able to support a single UG device */
-
- FAR struct ug2864ambag01_dev_s *priv = (FAR struct ug2864ambag01_dev_s *)&g_oleddev;
- FAR uint8_t *fbptr;
- FAR uint8_t *ptr;
- uint8_t devcol;
- uint8_t fbmask;
- uint8_t page;
- uint8_t usrmask;
- int pixlen;
- uint8_t i;
-
- lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer);
-
- /* Clip the run to the display */
-
- pixlen = npixels;
- if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG2864AMBAG01_XRES)
- {
- pixlen = (int)UG2864AMBAG01_XRES - (int)col;
- }
-
- /* Verify that some portion of the run remains on the display */
-
- if (pixlen <= 0 || row > UG2864AMBAG01_YRES)
- {
- return OK;
- }
-
- /* Perform coordinate conversion for reverse landscape mode */
-
-#ifdef CONFIG_LCD_RLANDSCAPE
- row = (UG2864AMBAG01_YRES-1) - row;
- col = (UG2864AMBAG01_XRES-1) - col;
-#endif
-
- /* Get the page number. The range of 64 lines is divided up into eight
- * pages of 8 lines each.
- */
-
- page = row >> 3;
-
- /* Update the shadow frame buffer memory. First determine the pixel
- * position in the frame buffer memory. Pixels are organized like
- * this:
- *
- * --------+---+---+---+---+-...-+-----+
- * Segment | 0 | 1 | 2 | 3 | ... | 131 |
- * --------+---+---+---+---+-...-+-----+
- * D0 | | X | | | | |
- * D1 | | X | | | | |
- * D2 | | X | | | | |
- * D3 | | X | | | | |
- * D4 | | X | | | | |
- * D5 | | X | | | | |
- * D6 | | X | | | | |
- * D7 | | X | | | | |
- * --------+---+---+---+---+-...-+-----+
- *
- * So, in order to draw a white, horizontal line, at row 45. we
- * would have to modify all of the bytes in page 45/8 = 5. We
- * would have to set bit 45%8 = 5 in every byte in the page.
- */
-
- fbmask = 1 << (row & 7);
- fbptr = &priv->fb[page * UG2864AMBAG01_XRES + col];
-#ifdef CONFIG_LCD_RLANDSCAPE
- ptr = fbptr + pixlen - 1;
-#else
- ptr = fbptr;
-#endif
-#ifdef CONFIG_NX_PACKEDMSFIRST
- usrmask = MS_BIT;
-#else
- usrmask = LS_BIT;
-#endif
-
- for (i = 0; i < pixlen; i++)
- {
- /* Set or clear the corresponding bit */
-
-#ifdef CONFIG_LCD_RLANDSCAPE
- if ((*buffer & usrmask) != 0)
- {
- *ptr-- |= fbmask;
- }
- else
- {
- *ptr-- &= ~fbmask;
- }
-#else
- if ((*buffer & usrmask) != 0)
- {
- *ptr++ |= fbmask;
- }
- else
- {
- *ptr++ &= ~fbmask;
- }
-#endif
-
- /* Inc/Decrement to the next source pixel */
-
-#ifdef CONFIG_NX_PACKEDMSFIRST
- if (usrmask == LS_BIT)
- {
- buffer++;
- usrmask = MS_BIT;
- }
- else
- {
- usrmask >>= 1;
- }
-#else
- if (usrmask == MS_BIT)
- {
- buffer++;
- usrmask = LS_BIT;
- }
- else
- {
- usrmask <<= 1;
- }
-#endif
- }
-
- /* Offset the column position to account for smaller horizontal
- * display range.
- */
-
- devcol = col + UG2864AMBAG01_DEV_XOFFSET;
-
- /* Lock and select device */
-
- ug2864ambag01_lock(priv->spi);
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Select command transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Set the starting position for the run */
- /* Set the column address to the XOFFSET value */
-
- SPI_SEND(priv->spi, SH1101A_SETCOLL(devcol & 0x0f));
- SPI_SEND(priv->spi, SH1101A_SETCOLH(devcol >> 4));
-
- /* Set the page address */
-
- SPI_SEND(priv->spi, SH1101A_PAGEADDR(page));
-
- /* Select data transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false);
-
- /* Then transfer all of the data */
-
- (void)SPI_SNDBLOCK(priv->spi, fbptr, pixlen);
-
- /* De-select and unlock the device */
-
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false);
- ug2864ambag01_unlock(priv->spi);
- return OK;
-}
-#else
-# error "Configuration not implemented"
-#endif
-
-/**************************************************************************************
- * Name: ug2864ambag01_getrun
- *
- * Description:
- * This method can be used to read a partial raster line from the LCD:
- *
- * Description:
- * This method can be used to write a partial raster line to the LCD.
- *
- * row - Starting row to read from (range: 0 <= row < yres)
- * col - Starting column to read read (range: 0 <= col <= xres-npixels)
- * buffer - The buffer in which to return the run read from the LCD
- * npixels - The number of pixels to read from the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-static int ug2864ambag01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels)
-{
- /* Because of this line of code, we will only be able to support a single UG device */
-
- FAR struct ug2864ambag01_dev_s *priv = &g_oleddev;
- FAR uint8_t *fbptr;
- uint8_t page;
- uint8_t fbmask;
- uint8_t usrmask;
- int pixlen;
- uint8_t i;
-
- lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer);
-
- /* Clip the run to the display */
-
- pixlen = npixels;
- if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG2864AMBAG01_XRES)
- {
- pixlen = (int)UG2864AMBAG01_XRES - (int)col;
- }
-
- /* Verify that some portion of the run is actually the display */
-
- if (pixlen <= 0 || row > UG2864AMBAG01_YRES)
- {
- return -EINVAL;
- }
-
- /* Perform coordinate conversion for reverse landscape mode */
-
-#ifdef CONFIG_LCD_RLANDSCAPE
- row = (UG2864AMBAG01_YRES-1) - row;
- col = (UG2864AMBAG01_XRES-1) - col;
-#endif
-
- /* Then transfer the display data from the shadow frame buffer memory */
- /* Get the page number. The range of 64 lines is divided up into eight
- * pages of 8 lines each.
- */
-
- page = row >> 3;
-
- /* Update the shadow frame buffer memory. First determine the pixel
- * position in the frame buffer memory. Pixels are organized like
- * this:
- *
- * --------+---+---+---+---+-...-+-----+
- * Segment | 0 | 1 | 2 | 3 | ... | 131 |
- * --------+---+---+---+---+-...-+-----+
- * D0 | | X | | | | |
- * D1 | | X | | | | |
- * D2 | | X | | | | |
- * D3 | | X | | | | |
- * D4 | | X | | | | |
- * D5 | | X | | | | |
- * D6 | | X | | | | |
- * D7 | | X | | | | |
- * --------+---+---+---+---+-...-+-----+
- *
- * So, in order to draw a white, horizontal line, at row 45. we
- * would have to modify all of the bytes in page 45/8 = 5. We
- * would have to set bit 45%8 = 5 in every byte in the page.
- */
-
- fbmask = 1 << (row & 7);
-#ifdef CONFIG_LCD_RLANDSCAPE
- fbptr = &priv->fb[page * (UG2864AMBAG01_XRES-1) + col + pixlen];
-#else
- fbptr = &priv->fb[page * UG2864AMBAG01_XRES + col];
-#endif
-#ifdef CONFIG_NX_PACKEDMSFIRST
- usrmask = MS_BIT;
-#else
- usrmask = LS_BIT;
-#endif
-
- *buffer = 0;
- for (i = 0; i < pixlen; i++)
- {
- /* Set or clear the corresponding bit */
-
-#ifdef CONFIG_LCD_RLANDSCAPE
- uint8_t byte = *fbptr--;
-#else
- uint8_t byte = *fbptr++;
-#endif
- if ((byte & fbmask) != 0)
- {
- *buffer |= usrmask;
- }
-
- /* Inc/Decrement to the next destination pixel. Hmmmm. It looks like
- * this logic could write past the end of the user buffer. Revisit
- * this!
- */
-
-#ifdef CONFIG_NX_PACKEDMSFIRST
- if (usrmask == LS_BIT)
- {
- buffer++;
- *buffer = 0;
- usrmask = MS_BIT;
- }
- else
- {
- usrmask >>= 1;
- }
-#else
- if (usrmask == MS_BIT)
- {
- buffer++;
- *buffer = 0;
- usrmask = LS_BIT;
- }
- else
- {
- usrmask <<= 1;
- }
-#endif
- }
-
- return OK;
-}
-#else
-# error "Configuration not implemented"
-#endif
-
-/**************************************************************************************
- * Name: ug2864ambag01_getvideoinfo
- *
- * Description:
- * Get information about the LCD video controller configuration.
- *
- **************************************************************************************/
-
-static int ug2864ambag01_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo)
-{
- DEBUGASSERT(dev && vinfo);
- lcdvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n",
- g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes);
- memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug2864ambag01_getplaneinfo
- *
- * Description:
- * Get information about the configuration of each LCD color plane.
- *
- **************************************************************************************/
-
-static int ug2864ambag01_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo)
-{
- DEBUGASSERT(pinfo && planeno == 0);
- lcdvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp);
- memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug2864ambag01_getpower
- *
- * Description:
- * 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.
- *
- **************************************************************************************/
-
-static int ug2864ambag01_getpower(FAR struct lcd_dev_s *dev)
-{
- FAR struct ug2864ambag01_dev_s *priv = (FAR struct ug2864ambag01_dev_s *)dev;
- DEBUGASSERT(priv);
-
- lcdvdbg("power: %s\n", priv->on ? "ON" : "OFF");
- return priv->on ? CONFIG_LCD_MAXPOWER : 0;
-}
-
-/**************************************************************************************
- * Name: ug2864ambag01_setpower
- *
- * Description:
- * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On
- * backlit LCDs, this setting may correspond to the backlight setting.
- *
- **************************************************************************************/
-
-static int ug2864ambag01_setpower(struct lcd_dev_s *dev, int power)
-{
- struct ug2864ambag01_dev_s *priv = (struct ug2864ambag01_dev_s *)dev;
- DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER && priv->spi);
-
- lcdvdbg("power: %d [%d]\n", power, priv->on ? CONFIG_LCD_MAXPOWER : 0);
-
- /* Lock and select device */
-
- ug2864ambag01_lock(priv->spi);
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true);
-
- if (power <= 0)
- {
- /* Turn the display off */
-
- (void)SPI_SEND(priv->spi, SH1101A_DISPOFF);
- priv->on = false;
- }
- else
- {
- /* Turn the display on */
-
- (void)SPI_SEND(priv->spi, SH1101A_DISPON); /* Display on, dim mode */
- priv->on = true;
- }
-
- /* De-select and unlock the device */
-
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false);
- ug2864ambag01_unlock(priv->spi);
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug2864ambag01_getcontrast
- *
- * Description:
- * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int ug2864ambag01_getcontrast(struct lcd_dev_s *dev)
-{
- struct ug2864ambag01_dev_s *priv = (struct ug2864ambag01_dev_s *)dev;
- DEBUGASSERT(priv);
-
- lcdvdbg("contrast: %d\n", priv->contrast);
- return priv->contrast;
-}
-
-/**************************************************************************************
- * Name: ug2864ambag01_setcontrast
- *
- * Description:
- * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int ug2864ambag01_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
-{
- struct ug2864ambag01_dev_s *priv = (struct ug2864ambag01_dev_s *)dev;
- unsigned int scaled;
-
- lcdvdbg("contrast: %d\n", contrast);
- DEBUGASSERT(priv);
-
- /* Verify the contrast value */
-
-#ifdef CONFIG_DEBUG
- if (contrast > CONFIG_LCD_MAXCONTRAST)
- {
- return -EINVAL;
- }
-#endif
-
- /* Scale contrast: newcontrast = 255 * contrast / CONFIG_LCD_MAXCONTRAST
- * Where contrast is in the range {1,255}
- */
-
-#if CONFIG_LCD_MAXCONTRAST != 255
- scaled = ((contrast << 8) - 1) / CONFIG_LCD_MAXCONTRAST;
-#else
- scaled = contrast;
-#endif
-
- /* Lock and select device */
-
- ug2864ambag01_lock(priv->spi);
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Select command transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Set the contrast */
-
- (void)SPI_SEND(priv->spi, SH1101A_CONTRAST_MODE); /* Set contrast control register */
- (void)SPI_SEND(priv->spi, SH1101A_CONTRAST(scaled)); /* Data 1: Set 1 of 256 contrast steps */
- priv->contrast = contrast;
-
- /* De-select and unlock the device */
-
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false);
- ug2864ambag01_unlock(priv->spi);
- return OK;
-}
-
-/**************************************************************************************
- * Public Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: ug2864ambag01_initialize
- *
- * Description:
- * Initialize the UG-2864AMBAG01 video hardware. The initial state of the
- * OLED is fully initialized, display memory cleared, and the OLED ready
- * to use, but with the power setting at 0 (full off == sleep mode).
- *
- * Input Parameters:
- *
- * spi - A reference to the SPI driver instance.
- * devno - A value in the range of 0 through CONFIG_UG2864AMBAG01_NINTERFACES-1.
- * This allows support for multiple OLED devices.
- *
- * Returned Value:
- *
- * On success, this function returns a reference to the LCD object for
- * the specified OLED. NULL is returned on any failure.
- *
- **************************************************************************************/
-
-FAR struct lcd_dev_s *ug2864ambag01_initialize(FAR struct spi_dev_s *spi, unsigned int devno)
-{
- FAR struct ug2864ambag01_dev_s *priv = &g_oleddev;
-
- lcdvdbg("Initializing\n");
- DEBUGASSERT(spi && devno == 0);
-
- /* Save the reference to the SPI device */
-
- priv->spi = spi;
-
- /* Configure the SPI */
-
- ug2864ambag01_configspi(spi);
-
- /* Lock and select device */
-
- ug2864ambag01_lock(priv->spi);
- SPI_SELECT(spi, SPIDEV_DISPLAY, true);
-
- /* Select command transfer */
-
- SPI_CMDDATA(spi, SPIDEV_DISPLAY, true);
-
- /* Configure the device */
-
- SPI_SEND(spi, SH1101A_DISPOFF); /* Display off */
- SPI_SEND(spi, SH1101A_SETCOLL(0)); /* Set lower column address */
- SPI_SEND(spi, SH1101A_SETCOLH(0)); /* Set higher column address */
- SPI_SEND(spi, SH1101A_STARTLINE(0)); /* Set display start line */
- SPI_SEND(spi, SH1101A_PAGEADDR(0)); /* Set page address */
- SPI_SEND(spi, SH1101A_CONTRAST_MODE); /* Contrast control */
- SPI_SEND(spi ,UG2864AMBAG01_CONTRAST); /* Default contrast */
- SPI_SEND(spi, SH1101A_REMAPPLEFT); /* Set segment remap left */
- SPI_SEND(spi, SH1101A_EDISPOFF); /* Normal display */
- SPI_SEND(spi, SH1101A_NORMAL); /* Normal (un-reversed) display mode */
- SPI_SEND(spi, SH1101A_MRATIO_MODE); /* Multiplex ratio */
- SPI_SEND(spi, SH1101A_MRATIO(0x3f)); /* Duty = 1/64 */
- SPI_SEND(spi, SH1101A_SCANTOCOM0); /* Com scan direction: Scan from COM[n-1] to COM[0] */
- SPI_SEND(spi, SH1101A_DISPOFFS_MODE); /* Set display offset */
- SPI_SEND(spi, SH1101A_DISPOFFS(0));
- SPI_SEND(spi, SH1101A_CLKDIV_SET); /* Set clock divider */
- SPI_SEND(spi, SH1101A_CLKDIV(0,0));
- SPI_SEND(spi, SH1101A_CMNPAD_CONFIG); /* Set common pads */
- SPI_SEND(spi, SH1101A_CMNPAD(0x10));
- SPI_SEND(spi, SH1101A_VCOM_SET);
- SPI_SEND(spi, SH1101A_VCOM(0x40));
- SPI_SEND(spi, SH1101A_DCDC_MODE); /* DC/DC control mode: on */
- SPI_SEND(spi, SH1101A_DCDC_ON);
- SPI_SEND(spi, SH1101A_DISPON); /* display ON */
-
- /* De-select and unlock the device */
-
- SPI_SELECT(spi, SPIDEV_DISPLAY, false);
- ug2864ambag01_unlock(priv->spi);
-
- /* Clear the display */
-
- up_mdelay(100);
- ug2864ambag01_fill(&priv->dev, UG_Y1_BLACK);
- return &priv->dev;
-}
-
-/**************************************************************************************
- * Name: ug2864ambag01_fill
- *
- * Description:
- * This non-standard method can be used to clear the entire display by writing one
- * color to the display. This is much faster than writing a series of runs.
- *
- * Input Parameters:
- * priv - Reference to private driver structure
- *
- * Assumptions:
- * Caller has selected the OLED section.
- *
- **************************************************************************************/
-
-void ug2864ambag01_fill(FAR struct lcd_dev_s *dev, uint8_t color)
-{
- FAR struct ug2864ambag01_dev_s *priv = &g_oleddev;
- unsigned int page;
-
- /* Make an 8-bit version of the selected color */
-
- if (color & 1)
- {
- color = 0xff;
- }
- else
- {
- color = 0;
- }
-
- /* Initialize the framebuffer */
-
- memset(priv->fb, color, UG2864AMBAG01_FBSIZE);
-
- /* Lock and select device */
-
- ug2864ambag01_lock(priv->spi);
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Visit each page */
-
- for (page = 0; page < UG2864AMBAG01_DEV_PAGES; page++)
- {
- /* Select command transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Set the column address to the XOFFSET value */
-
- SPI_SEND(priv->spi, SH1101A_SETCOLL(UG2864AMBAG01_DEV_XOFFSET));
- SPI_SEND(priv->spi, SH1101A_SETCOLH(0));
-
- /* Set the page address */
-
- SPI_SEND(priv->spi, SH1101A_PAGEADDR(page));
-
- /* Select data transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false);
-
- /* Transfer one page of the selected color */
-
- (void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * UG2864AMBAG01_XRES],
- UG2864AMBAG01_XRES);
- }
-
- /* De-select and unlock the device */
-
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false);
- ug2864ambag01_unlock(priv->spi);
-}
-
-#endif /* CONFIG_LCD_UG2864AMBAG01 */
diff --git a/nuttx/drivers/lcd/ug-2864hsweg01.c b/nuttx/drivers/lcd/ug-2864hsweg01.c
deleted file mode 100644
index 02a59b104..000000000
--- a/nuttx/drivers/lcd/ug-2864hsweg01.c
+++ /dev/null
@@ -1,1218 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/ug-2864hsweg01.c
- * Driver for Univision UG-2864HSWEG01 OLED display (wih SSD1306 controller) in SPI
- * mode
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * 1. Product Specification (Preliminary), Part Name: OEL Display Module, Part ID:
- * UG-2864HSWEG01, Doc No: SAS1-9046-B, Univision Technology Inc.
- * 2. SSD1306, 128 X 64 Dot Matrix OLED/PLED, Preliminary Segment/Common Driver with
- * Controller, Solomon Systech
- *
- * 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.
- *
- **************************************************************************************/
-/**************************************************************************************
- * Device memory organization:
- *
- * +----------------------------+
- * | Column |
- * --------+----+---+---+---+-...-+-----+
- * Page | 0 | 1 | 2 | 3 | ... | 127 |
- * --------+----+---+---+---+-...-+-----+
- * Page 0 | D0 | X | | | | |
- * | D1 | X | | | | |
- * | D2 | X | | | | |
- * | D3 | X | | | | |
- * | D4 | X | | | | |
- * | D5 | X | | | | |
- * | D6 | X | | | | |
- * | D7 | X | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 1 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 2 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 3 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 4 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 5 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 6 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- * Page 7 | | | | | | |
- * --------+----+---+---+---+-...-+-----+
- *
- * -----------------------------------+---------------------------------------
- * Landscape Display: | Reverse Landscape Display:
- * --------+-----------------------+ | --------+---------------------------+
- * | Column | | | Column |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 0 | 0 | 1 | 2 | | 127 | | Page 7 | 127 | 126 | 125 | | 0 |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 1 | V | | Page 6 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 2 | V | | Page 5 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 3 | V | | Page 4 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 4 | V | | Page 3 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 5 | V | | Page 2 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 6 | V | | Page 1 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * Page 7 | V | | Page 0 | ^ |
- * --------+---+---+---+-...-+-----+ | --------+-----+-----+-----+-...-+---+
- * -----------------------------------+---------------------------------------
- *
- * -----------------------------------+---------------------------------------
- * Portrait Display: | Reverse Portrait Display:
- * -----------+---------------------+ | -----------+---------------------+
- * | Page | | | Page |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * Column 0 | 0 | 1 | 2 | | 7 | | Column 127 | 7 | 6 | 5 | | 0 |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * Column 1 | > > > > > | | Column 126 | |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * Column 2 | | | Column 125 | |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * ... | | | ... | |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * Column 127 | | | Column 0 | < < < < < |
- * -----------+---+---+---+-...-+---+ | -----------+---+---+---+-...-+---+
- * -----------------------------------+----------------------------------------
- **************************************************************************************/
-
-/**************************************************************************************
- * Included Files
- **************************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/spi.h>
-#include <nuttx/lcd/lcd.h>
-#include <nuttx/lcd/ug-2864hsweg01.h>
-
-#include <arch/irq.h>
-
-#ifdef CONFIG_LCD_UG2864HSWEG01
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-/* Configuration **********************************************************************/
-/* Limitations of the current configuration that I hope to fix someday */
-
-#if CONFIG_UG2864HSWEG01_NINTERFACES != 1
-# warning "This implementation supports only a single OLED device"
-# undef CONFIG_UG2864HSWEG01_NINTERFACES
-# define CONFIG_UG2864HSWEG01_NINTERFACES 1
-#endif
-
-#if defined(CONFIG_LCD_PORTRAIT) || defined(CONFIG_LCD_RPORTRAIT)
-# warning "No support yet for portrait modes"
-# define CONFIG_LCD_LANDSCAPE 1
-# undef CONFIG_LCD_PORTRAIT
-# undef CONFIG_LCD_RLANDSCAPE
-# undef CONFIG_LCD_RPORTRAIT
-#elif defined(CONFIG_LCD_RLANDSCAPE)
-# warning "Reverse landscape mode is untested and, hence, probably buggy"
-#endif
-
-/* SSD1306 Commands *******************************************************************/
-
-#define SSD1306_SETCOLL(ad) (0x00 | ((ad) & 0x0f)) /* Set Lower Column Address: (00h - 0fh) */
-#define SSD1306_SETCOLH(ad) (0x10 | ((ad) & 0x0f)) /* Set Higher Column Address: (10h - 1fh) */
-#define SSD1306_STARTLINE(ln) (0x40 | ((ln) & 0x3f)) /* Set Display Start Line: (40h - 7fh) */
-#define SSD1306_CONTRAST_MODE (0x81) /* Set Contrast Control Register: (Double Bytes Command) */
-# define SSD1306_CONTRAST(c) (c)
-#define SSD1306_SEGREMAP(m) (0xa0 | ((m) & 0x01)) /* Set Segment Re-map: (a0h - a1h) */
-# define SSD1306_REMAPRIGHT SSD1306_SEGREMAP(0) /* Right rotation */
-# define SSD1306_REMAPPLEFT SSD1306_SEGREMAP(1) /* Left rotation */
-#define SSD1306_EDISPOFFON(s) (0xa4 | ((s) & 0x01)) /* Set Entire Display OFF/ON: (a4h - a5h) */
-# define SSD1306_EDISPOFF SSD1306_EDISPOFFON(0) /* Display off */
-# define SSD1306_EDISPON SSD1306_EDISPOFFON(1) /* Display on */
-#define SSD1306_NORMREV(s) (0xa6 | ((s) & 0x01)) /* Set Normal/Reverse Display: (a6h -a7h) */
-# define SSD1306_NORMAL SSD1306_NORMREV(0) /* Normal display */
-# define SSD1306_REVERSE SSD1306_NORMREV(1) /* Reverse display */
-#define SSD1306_MRATIO_MODE (0xa8) /* Set Multiplex Ration: (Double Bytes Command) */
-# define SSD1306_MRATIO(d) ((d) & 0x3f)
-#define SSD1306_DCDC_MODE (0xad) /* Set DC-DC OFF/ON: (Double Bytes Command) */
-# define SSD1306_DCDC_OFF (0x8a)
-# define SSD1306_DCDC_ON (0x8b)
-
-#define SSD1306_DISPOFFON(s) (0xae | ((s) & 0x01)) /* Display OFF/ON: (aeh - afh) */
-# define SSD1306_DISPOFF SSD1306_DISPOFFON(0) /* Display off */
-# define SSD1306_DISPON SSD1306_DISPOFFON(1) /* Display on */
-#define SSD1306_PAGEADDR(a) (0xb0 | ((a) & 0x0f)) /* Set Page Address: (b0h - b7h) */
-#define SSD1306_SCANDIR(d) (0xc0 | ((d) & 0x08)) /* Set Common Output Scan Direction: (c0h - c8h) */
-# define SSD1306_SCANFROMCOM0 SSD1306_SCANDIR(0x00) /* Scan from COM[0] to COM[n-1]*/
-# define SSD1306_SCANTOCOM0 SSD1306_SCANDIR(0x08) /* Scan from COM[n-1] to COM[0] */
-#define SSD1306_DISPOFFS_MODE (0xd3) /* Set Display Offset: (Double Bytes Command) */
-# define SSD1306_DISPOFFS(o) ((o) & 0x3f)
-#define SSD1306_CLKDIV_SET (0xd5) /* Set Display Clock Divide Ratio/Oscillator Frequency: (Double Bytes Command) */
-# define SSD1306_CLKDIV(f,d) ((((f) & 0x0f) << 4) | ((d) & 0x0f))
-#define SSD1306_CHRGPER_SET (0xd9) /* Set Dis-charge/Pre-charge Period: (Double Bytes Command) */
-# define SSD1306_CHRGPER(d,p) ((((d) & 0x0f) << 4) | ((p) & 0x0f))
-#define SSD1306_CMNPAD_CONFIG (0xda) /* Set Common pads hardware configuration: (Double Bytes Command) */
-# define SSD1306_CMNPAD(c) ((0x02) | ((c) & 0x10))
-#define SSD1306_VCOM_SET (0xdb) /* Set VCOM Deselect Level: (Double Bytes Command) */
-# define SSD1306_VCOM(v) (v)
-
-#define SSD1306_CHRPUMP_SET (0x8d) /* Charge Pump Setting */
-# define SSD1306_CHRPUMP_ON (0x14)
-# define SSD1306_CHRPUMP_OFF (0x10)
-
-#define SSD1306_RMWSTART (0xe0) /* Read-Modify-Write: (e0h) */
-#define SSD1306_NOP (0xe3) /* NOP: (e3h) */
-#define SSD1306_END (0xee) /* End: (eeh) */
-
-#define SSD1306_WRDATA(d) (d) /* Write Display Data */
-#define SSD1306_STATUS_BUSY (0x80) /* Read Status */
-#define SSD1306_STATUS_ONOFF (0x40)
-#define SSD1306_RDDATA(d) (d) /* Read Display Data */
-
-/* Color Properties *******************************************************************/
-/* Display Resolution
- *
- * The SSD1306 display controller can handle a resolution of 132x64. The UG-2864HSWEG01
- * on the base board is 128x64.
- */
-
-#define UG2864HSWEG01_DEV_XRES 128 /* Only 128 of 131 columns used */
-#define UG2864HSWEG01_DEV_YRES 64 /* 8 pages each 8 rows */
-#define UG2864HSWEG01_DEV_XOFFSET 2 /* Offset to logical column 0 */
-#define UG2864HSWEG01_DEV_PAGES 8 /* 8 pages */
-
-#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-# define UG2864HSWEG01_XRES UG2864HSWEG01_DEV_XRES
-# define UG2864HSWEG01_YRES UG2864HSWEG01_DEV_YRES
-#else
-# define UG2864HSWEG01_XRES UG2864HSWEG01_DEV_YRES
-# define UG2864HSWEG01_YRES UG2864HSWEG01_DEV_XRES
-#endif
-
-/* Color depth and format */
-
-#define UG2864HSWEG01_BPP 1
-#define UG2864HSWEG01_COLORFMT FB_FMT_Y1
-
-/* Bytes per logical row and actual device row */
-
-#define UG2864HSWEG01_XSTRIDE (UG2864HSWEG01_XRES >> 3)
-#define UG2864HSWEG01_YSTRIDE (UG2864HSWEG01_YRES >> 3)
-
-/* Default contrast */
-
-#define UG2864HSWEG01_CONTRAST (128)
-
-/* The size of the shadow frame buffer or one row buffer.
- *
- * Frame buffer size: 128 columns x 64 rows / 8 bits-per-pixel
- * Row size: 128 columns x 8 rows-per-page / 8 bits-per-pixel
- */
-
-#define UG2864HSWEG01_FBSIZE (UG2864HSWEG01_XSTRIDE * UG2864HSWEG01_YRES)
-#define UG2864HSWEG01_ROWSIZE (UG2864HSWEG01_XSTRIDE)
-
-/* Bit helpers */
-
-#define LS_BIT (1 << 0)
-#define MS_BIT (1 << 7)
-
-/* Debug ******************************************************************************/
-
-#ifdef CONFIG_DEBUG_LCD
-# define lcddbg(format, arg...) dbg(format, ##arg)
-# define lcdvdbg(format, arg...) vdbg(format, ##arg)
-#else
-# define lcddbg(x...)
-# define lcdvdbg(x...)
-#endif
-
-/**************************************************************************************
- * Private Type Definition
- **************************************************************************************/
-
-/* This structure describes the state of this driver */
-
-struct ug2864hsweg01_dev_s
-{
- struct lcd_dev_s dev; /* Publically visible device structure */
-
- /* Private LCD-specific information follows */
-
- FAR struct spi_dev_s *spi; /* Cached SPI device reference */
- uint8_t contrast; /* Current contrast setting */
- bool on; /* true: display is on */
-
-
- /* The SSD1306 does not support reading from the display memory in SPI mode.
- * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep
- * a shadow copy of the framebuffer memory. At 128x64, this amounts to 1KB.
- */
-
- uint8_t fb[UG2864HSWEG01_FBSIZE];
-};
-
-/**************************************************************************************
- * Private Function Protototypes
- **************************************************************************************/
-
-/* Low-level SPI helpers */
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void ug2864hsweg01_configspi(FAR struct spi_dev_s *spi);
-# define ug2864hsweg01_lock(spi)
-# define ug2864hsweg01_unlock(spi)
-#else
-# define ug2864hsweg01_configspi(spi)
-static void ug2864hsweg01_lock(FAR struct spi_dev_s *spi);
-static void ug2864hsweg01_unlock(FAR struct spi_dev_s *spi);
-#endif
-
-/* LCD Data Transfer Methods */
-
-static int ug2864hsweg01_putrun(fb_coord_t row, fb_coord_t col,
- FAR const uint8_t *buffer, size_t npixels);
-static int ug2864hsweg01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels);
-
-/* LCD Configuration */
-
-static int ug2864hsweg01_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo);
-static int ug2864hsweg01_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo);
-
-/* LCD RGB Mapping */
-
-#ifdef CONFIG_FB_CMAP
-# error "RGB color mapping not supported by this driver"
-#endif
-
-/* Cursor Controls */
-
-#ifdef CONFIG_FB_HWCURSOR
-# error "Cursor control not supported by this driver"
-#endif
-
-/* LCD Specific Controls */
-
-static int ug2864hsweg01_getpower(struct lcd_dev_s *dev);
-static int ug2864hsweg01_setpower(struct lcd_dev_s *dev, int power);
-static int ug2864hsweg01_getcontrast(struct lcd_dev_s *dev);
-static int ug2864hsweg01_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
-
-/**************************************************************************************
- * Private Data
- **************************************************************************************/
-
-/* This is working memory allocated by the LCD driver for each LCD device
- * and for each color plane. This memory will hold one raster line of data.
- * The size of the allocated run buffer must therefore be at least
- * (bpp * xres / 8). Actual alignment of the buffer must conform to the
- * bitwidth of the underlying pixel type.
- *
- * If there are multiple planes, they may share the same working buffer
- * because different planes will not be operate on concurrently. However,
- * if there are multiple LCD devices, they must each have unique run buffers.
- */
-
-static uint8_t g_runbuffer[UG2864HSWEG01_ROWSIZE];
-
-/* This structure describes the overall LCD video controller */
-
-static const struct fb_videoinfo_s g_videoinfo =
-{
- .fmt = UG2864HSWEG01_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
- .xres = UG2864HSWEG01_XRES, /* Horizontal resolution in pixel columns */
- .yres = UG2864HSWEG01_YRES, /* Vertical resolution in pixel rows */
- .nplanes = 1, /* Number of color planes supported */
-};
-
-/* This is the standard, NuttX Plane information object */
-
-static const struct lcd_planeinfo_s g_planeinfo =
-{
- .putrun = ug2864hsweg01_putrun, /* Put a run into LCD memory */
- .getrun = ug2864hsweg01_getrun, /* Get a run from LCD memory */
- .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */
- .bpp = UG2864HSWEG01_BPP, /* Bits-per-pixel */
-};
-
-/* This is the OLED driver instance (only a single device is supported for now) */
-
-static struct ug2864hsweg01_dev_s g_oleddev =
-{
- .dev =
- {
- /* LCD Configuration */
-
- .getvideoinfo = ug2864hsweg01_getvideoinfo,
- .getplaneinfo = ug2864hsweg01_getplaneinfo,
-
- /* LCD RGB Mapping -- Not supported */
- /* Cursor Controls -- Not supported */
-
- /* LCD Specific Controls */
-
- .getpower = ug2864hsweg01_getpower,
- .setpower = ug2864hsweg01_setpower,
- .getcontrast = ug2864hsweg01_getcontrast,
- .setcontrast = ug2864hsweg01_setcontrast,
- },
-};
-
-/**************************************************************************************
- * Private Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: ug2864hsweg01_configspi
- *
- * Description:
- * Configure the SPI for use with the UG-2864HSWEG01
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void ug2864hsweg01_configspi(FAR struct spi_dev_s *spi)
-{
- lcdvdbg("Mode: %d Bits: 8 Frequency: %d\n",
- CONFIG_UG2864HSWEG01_SPIMODE, CONFIG_UG2864HSWEG01_FREQUENCY);
-
- /* Configure SPI for the UG-2864HSWEG01. But only if we own the SPI bus. Otherwise,
- * don't bother because it might change.
- */
-
- SPI_SETMODE(spi, CONFIG_UG2864HSWEG01_SPIMODE);
- SPI_SETBITS(spi, 8);
- SPI_SETFREQUENCY(spi, CONFIG_UG2864HSWEG01_FREQUENCY);
-}
-#endif
-
-/**************************************************************************************
- * Name: ug2864hsweg01_lock
- *
- * Description:
- * Select the SPI, locking and re-configuring if necessary
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static inline void ug2864hsweg01_lock(FAR struct spi_dev_s *spi)
-{
- /* Lock the SPI bus if there are multiple devices competing for the SPI bus. */
-
- SPI_LOCK(spi, true);
-
- /* Now make sure that the SPI bus is configured for the UG-2864HSWEG01 (it
- * might have gotten configured for a different device while unlocked)
- */
-
- SPI_SETMODE(spi, CONFIG_UG2864HSWEG01_SPIMODE);
- SPI_SETBITS(spi, 8);
- SPI_SETFREQUENCY(spi, CONFIG_UG2864HSWEG01_FREQUENCY);
-}
-#endif
-
-/**************************************************************************************
- * Name: ug2864hsweg01_unlock
- *
- * Description:
- * De-select the SPI
- *
- * Input Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static inline void ug2864hsweg01_unlock(FAR struct spi_dev_s *spi)
-{
- /* De-select UG-2864HSWEG01 chip and relinquish the SPI bus. */
-
- SPI_LOCK(spi, false);
-}
-#endif
-
-/**************************************************************************************
- * Name: ug2864hsweg01_putrun
- *
- * Description:
- * This method can be used to write a partial raster line to the LCD.
- *
- * Input Parameters:
- * row - Starting row to write to (range: 0 <= row < yres)
- * col - Starting column to write to (range: 0 <= col <= xres-npixels)
- * buffer - The buffer containing the run to be written to the LCD
- * npixels - The number of pixels to write to the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-static int ug2864hsweg01_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels)
-{
- /* Because of this line of code, we will only be able to support a single UG device */
-
- FAR struct ug2864hsweg01_dev_s *priv = (FAR struct ug2864hsweg01_dev_s *)&g_oleddev;
- FAR uint8_t *fbptr;
- FAR uint8_t *ptr;
- uint8_t devcol;
- uint8_t fbmask;
- uint8_t page;
- uint8_t usrmask;
- int pixlen;
- uint8_t i;
-
- lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer);
-
- /* Clip the run to the display */
-
- pixlen = npixels;
- if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG2864HSWEG01_XRES)
- {
- pixlen = (int)UG2864HSWEG01_XRES - (int)col;
- }
-
- /* Verify that some portion of the run remains on the display */
-
- if (pixlen <= 0 || row > UG2864HSWEG01_YRES)
- {
- return OK;
- }
-
- /* Perform coordinate conversion for reverse landscape mode */
-
-#ifdef CONFIG_LCD_RLANDSCAPE
- row = (UG2864HSWEG01_YRES-1) - row;
- col = (UG2864HSWEG01_XRES-1) - col;
-#endif
-
- /* Get the page number. The range of 64 lines is divided up into eight
- * pages of 8 lines each.
- */
-
- page = row >> 3;
-
- /* Update the shadow frame buffer memory. First determine the pixel
- * position in the frame buffer memory. Pixels are organized like
- * this:
- *
- * --------+---+---+---+---+-...-+-----+
- * Segment | 0 | 1 | 2 | 3 | ... | 131 |
- * --------+---+---+---+---+-...-+-----+
- * D0 | | X | | | | |
- * D1 | | X | | | | |
- * D2 | | X | | | | |
- * D3 | | X | | | | |
- * D4 | | X | | | | |
- * D5 | | X | | | | |
- * D6 | | X | | | | |
- * D7 | | X | | | | |
- * --------+---+---+---+---+-...-+-----+
- *
- * So, in order to draw a white, horizontal line, at row 45. we
- * would have to modify all of the bytes in page 45/8 = 5. We
- * would have to set bit 45%8 = 5 in every byte in the page.
- */
-
- fbmask = 1 << (row & 7);
- fbptr = &priv->fb[page * UG2864HSWEG01_XRES + col];
-#ifdef CONFIG_LCD_RLANDSCAPE
- ptr = fbptr + pixlen - 1;
-#else
- ptr = fbptr;
-#endif
-#ifdef CONFIG_NX_PACKEDMSFIRST
- usrmask = MS_BIT;
-#else
- usrmask = LS_BIT;
-#endif
-
- for (i = 0; i < pixlen; i++)
- {
- /* Set or clear the corresponding bit */
-
-#ifdef CONFIG_LCD_RLANDSCAPE
- if ((*buffer & usrmask) != 0)
- {
- *ptr-- |= fbmask;
- }
- else
- {
- *ptr-- &= ~fbmask;
- }
-#else
- if ((*buffer & usrmask) != 0)
- {
- *ptr++ |= fbmask;
- }
- else
- {
- *ptr++ &= ~fbmask;
- }
-#endif
-
- /* Inc/Decrement to the next source pixel */
-
-#ifdef CONFIG_NX_PACKEDMSFIRST
- if (usrmask == LS_BIT)
- {
- buffer++;
- usrmask = MS_BIT;
- }
- else
- {
- usrmask >>= 1;
- }
-#else
- if (usrmask == MS_BIT)
- {
- buffer++;
- usrmask = LS_BIT;
- }
- else
- {
- usrmask <<= 1;
- }
-#endif
- }
-
- /* Offset the column position to account for smaller horizontal
- * display range.
- */
-
- devcol = col + UG2864HSWEG01_DEV_XOFFSET;
-
- /* Lock and select device */
-
- ug2864hsweg01_lock(priv->spi);
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Select command transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Set the starting position for the run */
- /* Set the column address to the XOFFSET value */
-
- SPI_SEND(priv->spi, SSD1306_SETCOLL(devcol & 0x0f));
- SPI_SEND(priv->spi, SSD1306_SETCOLH(devcol >> 4));
-
- /* Set the page address */
-
- SPI_SEND(priv->spi, SSD1306_PAGEADDR(page));
-
- /* Select data transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false);
-
- /* Then transfer all of the data */
-
- (void)SPI_SNDBLOCK(priv->spi, fbptr, pixlen);
-
- /* De-select and unlock the device */
-
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false);
- ug2864hsweg01_unlock(priv->spi);
- return OK;
-}
-#else
-# error "Configuration not implemented"
-#endif
-
-/**************************************************************************************
- * Name: ug2864hsweg01_getrun
- *
- * Description:
- * This method can be used to read a partial raster line from the LCD:
- *
- * Description:
- * This method can be used to write a partial raster line to the LCD.
- *
- * row - Starting row to read from (range: 0 <= row < yres)
- * col - Starting column to read read (range: 0 <= col <= xres-npixels)
- * buffer - The buffer in which to return the run read from the LCD
- * npixels - The number of pixels to read from the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-#if defined(CONFIG_LCD_LANDSCAPE) || defined(CONFIG_LCD_RLANDSCAPE)
-static int ug2864hsweg01_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels)
-{
- /* Because of this line of code, we will only be able to support a single UG device */
-
- FAR struct ug2864hsweg01_dev_s *priv = &g_oleddev;
- FAR uint8_t *fbptr;
- uint8_t page;
- uint8_t fbmask;
- uint8_t usrmask;
- int pixlen;
- uint8_t i;
-
- lcdvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer);
-
- /* Clip the run to the display */
-
- pixlen = npixels;
- if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG2864HSWEG01_XRES)
- {
- pixlen = (int)UG2864HSWEG01_XRES - (int)col;
- }
-
- /* Verify that some portion of the run is actually the display */
-
- if (pixlen <= 0 || row > UG2864HSWEG01_YRES)
- {
- return -EINVAL;
- }
-
- /* Perform coordinate conversion for reverse landscape mode */
-
-#ifdef CONFIG_LCD_RLANDSCAPE
- row = (UG2864HSWEG01_YRES-1) - row;
- col = (UG2864HSWEG01_XRES-1) - col;
-#endif
-
- /* Then transfer the display data from the shadow frame buffer memory */
- /* Get the page number. The range of 64 lines is divided up into eight
- * pages of 8 lines each.
- */
-
- page = row >> 3;
-
- /* Update the shadow frame buffer memory. First determine the pixel
- * position in the frame buffer memory. Pixels are organized like
- * this:
- *
- * --------+---+---+---+---+-...-+-----+
- * Segment | 0 | 1 | 2 | 3 | ... | 131 |
- * --------+---+---+---+---+-...-+-----+
- * D0 | | X | | | | |
- * D1 | | X | | | | |
- * D2 | | X | | | | |
- * D3 | | X | | | | |
- * D4 | | X | | | | |
- * D5 | | X | | | | |
- * D6 | | X | | | | |
- * D7 | | X | | | | |
- * --------+---+---+---+---+-...-+-----+
- *
- * So, in order to draw a white, horizontal line, at row 45. we
- * would have to modify all of the bytes in page 45/8 = 5. We
- * would have to set bit 45%8 = 5 in every byte in the page.
- */
-
- fbmask = 1 << (row & 7);
-#ifdef CONFIG_LCD_RLANDSCAPE
- fbptr = &priv->fb[page * (UG2864HSWEG01_XRES-1) + col + pixlen];
-#else
- fbptr = &priv->fb[page * UG2864HSWEG01_XRES + col];
-#endif
-#ifdef CONFIG_NX_PACKEDMSFIRST
- usrmask = MS_BIT;
-#else
- usrmask = LS_BIT;
-#endif
-
- *buffer = 0;
- for (i = 0; i < pixlen; i++)
- {
- /* Set or clear the corresponding bit */
-
-#ifdef CONFIG_LCD_RLANDSCAPE
- uint8_t byte = *fbptr--;
-#else
- uint8_t byte = *fbptr++;
-#endif
- if ((byte & fbmask) != 0)
- {
- *buffer |= usrmask;
- }
-
- /* Inc/Decrement to the next destination pixel. Hmmmm. It looks like
- * this logic could write past the end of the user buffer. Revisit
- * this!
- */
-
-#ifdef CONFIG_NX_PACKEDMSFIRST
- if (usrmask == LS_BIT)
- {
- buffer++;
- *buffer = 0;
- usrmask = MS_BIT;
- }
- else
- {
- usrmask >>= 1;
- }
-#else
- if (usrmask == MS_BIT)
- {
- buffer++;
- *buffer = 0;
- usrmask = LS_BIT;
- }
- else
- {
- usrmask <<= 1;
- }
-#endif
- }
-
- return OK;
-}
-#else
-# error "Configuration not implemented"
-#endif
-
-/**************************************************************************************
- * Name: ug2864hsweg01_getvideoinfo
- *
- * Description:
- * Get information about the LCD video controller configuration.
- *
- **************************************************************************************/
-
-static int ug2864hsweg01_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo)
-{
- DEBUGASSERT(dev && vinfo);
- lcdvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n",
- g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes);
- memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug2864hsweg01_getplaneinfo
- *
- * Description:
- * Get information about the configuration of each LCD color plane.
- *
- **************************************************************************************/
-
-static int ug2864hsweg01_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo)
-{
- DEBUGASSERT(pinfo && planeno == 0);
- lcdvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp);
- memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug2864hsweg01_getpower
- *
- * Description:
- * 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.
- *
- **************************************************************************************/
-
-static int ug2864hsweg01_getpower(FAR struct lcd_dev_s *dev)
-{
- FAR struct ug2864hsweg01_dev_s *priv = (FAR struct ug2864hsweg01_dev_s *)dev;
- DEBUGASSERT(priv);
-
- lcdvdbg("power: %s\n", priv->on ? "ON" : "OFF");
- return priv->on ? CONFIG_LCD_MAXPOWER : 0;
-}
-
-/**************************************************************************************
- * Name: ug2864hsweg01_setpower
- *
- * Description:
- * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On
- * backlit LCDs, this setting may correspond to the backlight setting.
- *
- **************************************************************************************/
-
-static int ug2864hsweg01_setpower(struct lcd_dev_s *dev, int power)
-{
- struct ug2864hsweg01_dev_s *priv = (struct ug2864hsweg01_dev_s *)dev;
- DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER && priv->spi);
-
- lcdvdbg("power: %d [%d]\n", power, priv->on ? CONFIG_LCD_MAXPOWER : 0);
-
- /* Lock and select device */
-
- ug2864hsweg01_lock(priv->spi);
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true);
-
- if (power <= 0)
- {
- /* Turn the display off */
-
- (void)SPI_SEND(priv->spi, SSD1306_DISPOFF);
- priv->on = false;
- }
- else
- {
- /* Turn the display on */
-
- (void)SPI_SEND(priv->spi, SSD1306_DISPON); /* Display on, dim mode */
- priv->on = true;
- }
-
- /* De-select and unlock the device */
-
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false);
- ug2864hsweg01_unlock(priv->spi);
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug2864hsweg01_getcontrast
- *
- * Description:
- * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int ug2864hsweg01_getcontrast(struct lcd_dev_s *dev)
-{
- struct ug2864hsweg01_dev_s *priv = (struct ug2864hsweg01_dev_s *)dev;
- DEBUGASSERT(priv);
-
- lcdvdbg("contrast: %d\n", priv->contrast);
- return priv->contrast;
-}
-
-/**************************************************************************************
- * Name: ug2864hsweg01_setcontrast
- *
- * Description:
- * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int ug2864hsweg01_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
-{
- struct ug2864hsweg01_dev_s *priv = (struct ug2864hsweg01_dev_s *)dev;
- unsigned int scaled;
-
- lcdvdbg("contrast: %d\n", contrast);
- DEBUGASSERT(priv);
-
- /* Verify the contrast value */
-
-#ifdef CONFIG_DEBUG
- if (contrast > CONFIG_LCD_MAXCONTRAST)
- {
- return -EINVAL;
- }
-#endif
-
- /* Scale contrast: newcontrast = 255 * contrast / CONFIG_LCD_MAXCONTRAST
- * Where contrast is in the range {1,255}
- */
-
-#if CONFIG_LCD_MAXCONTRAST != 255
- scaled = ((contrast << 8) - 1) / CONFIG_LCD_MAXCONTRAST;
-#else
- scaled = contrast;
-#endif
-
- /* Lock and select device */
-
- ug2864hsweg01_lock(priv->spi);
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Select command transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Set the contrast */
-
- (void)SPI_SEND(priv->spi, SSD1306_CONTRAST_MODE); /* Set contrast control register */
- (void)SPI_SEND(priv->spi, SSD1306_CONTRAST(scaled)); /* Data 1: Set 1 of 256 contrast steps */
- priv->contrast = contrast;
-
- /* De-select and unlock the device */
-
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false);
- ug2864hsweg01_unlock(priv->spi);
- return OK;
-}
-
-/**************************************************************************************
- * Public Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: ug2864hsweg01_initialize
- *
- * Description:
- * Initialize the UG-2864HSWEG01 video hardware. The initial state of the
- * OLED is fully initialized, display memory cleared, and the OLED ready
- * to use, but with the power setting at 0 (full off == sleep mode).
- *
- * Input Parameters:
- *
- * spi - A reference to the SPI driver instance.
- * devno - A value in the range of 0 through CONFIG_UG2864HSWEG01_NINTERFACES-1.
- * This allows support for multiple OLED devices.
- *
- * Returned Value:
- *
- * On success, this function returns a reference to the LCD object for
- * the specified OLED. NULL is returned on any failure.
- *
- **************************************************************************************/
-
-FAR struct lcd_dev_s *ug2864hsweg01_initialize(FAR struct spi_dev_s *spi, unsigned int devno)
-{
- FAR struct ug2864hsweg01_dev_s *priv = &g_oleddev;
-
- lcdvdbg("Initializing\n");
- DEBUGASSERT(spi && devno == 0);
-
- /* Save the reference to the SPI device */
-
- priv->spi = spi;
-
- /* Configure the SPI */
-
- ug2864hsweg01_configspi(spi);
-
- /* Lock and select device */
-
- ug2864hsweg01_lock(priv->spi);
- SPI_SELECT(spi, SPIDEV_DISPLAY, true);
-
- /* Select command transfer */
-
- SPI_CMDDATA(spi, SPIDEV_DISPLAY, true);
-
- /* Configure OLED SPI or I/O, must be delayed 1-10ms */
-
- up_mdelay(5);
-
- /* Configure the device */
-
-//#define OLED_WriteCmd(v) SPI_SEND(spi,v)
-//
-// /* Module manufacturers to provide initialization code Ä£¿é³§¼ÒÌṩ³õʼ»¯´úÂë */
-//
-// OLED_WriteCmd(0xAE); /* ¹Ø±ÕOLEDÃæ°åÏÔʾ(ÐÝÃß) */
-// OLED_WriteCmd(0x00); /* ÉèÖÃÁеØÖ·µÍ4bit */
-// OLED_WriteCmd(0x10); /* ÉèÖÃÁеØÖ·¸ß4bit */
-// OLED_WriteCmd(0x40); /* ÉèÖÃÆðʼÐеØÖ·£¨µÍ5bit 0-63£©£¬ Ó²¼þÏà¹Ø*/
-//
-// OLED_WriteCmd(0x81); /* ÉèÖöԱȶÈÃüÁî(Ë«×Ö½ÚÃüÁ£¬µÚ1¸ö×Ö½ÚÊÇÃüÁµÚ2¸ö×Ö½ÚÊǶԱȶȲÎÊý0-255 */
-// OLED_WriteCmd(0xCF); /* ÉèÖöԱȶȲÎÊý */
-//
-// OLED_WriteCmd(0xA1); /* A0 £ºÁеØÖ·0Ó³Éäµ½SEG0; A1 £ºÁеØÖ·127Ó³Éäµ½SEG0 */
-// OLED_WriteCmd(0xA6); /* A6 : ÉèÖÃÕý³£ÏÔʾģʽ; A7 : ÉèÖÃΪ·´ÏÔģʽ */
-//
-// OLED_WriteCmd(0xA8); /* ÉèÖÃCOM·Êý */
-// OLED_WriteCmd(0x3F); /* 1 ->£¨63+1£©Â· */
-//
-// OLED_WriteCmd(0xD3); /* ÉèÖÃÏÔʾƫÒÆ£¨Ë«×Ö½ÚÃüÁ*/
-// OLED_WriteCmd(0x00); /* ÎÞÆ«ÒÆ */
-//
-// OLED_WriteCmd(0xD5); /* ÉèÖÃÏÔʾʱÖÓ·ÖƵϵÊý/Õñµ´ÆµÂÊ */
-// OLED_WriteCmd(0x80); /* ÉèÖ÷ÖƵϵÊý,¸ß4bitÊÇ·ÖƵϵÊý£¬µÍ4bitÊÇÕñµ´ÆµÂÊ */
-//
-// OLED_WriteCmd(0xD9); /* ÉèÖÃÔ¤³äµçÖÜÆÚ */
-// OLED_WriteCmd(0xF1); /* [3:0],PHASE 1; [7:4],PHASE 2; */
-//
-// OLED_WriteCmd(0xDA); /* ÉèÖÃCOM½ÅÓ²¼þ½ÓÏß·½Ê½ */
-// OLED_WriteCmd(0x12);
-//
-// OLED_WriteCmd(0xDB); /* ÉèÖà vcomh µçѹ±¶ÂÊ */
-// OLED_WriteCmd(0x40); /* [6:4] 000 = 0.65 x VCC; 0.77 x VCC (RESET); 0.83 x VCC */
-//
-// OLED_WriteCmd(0x8D); /* ÉèÖóäµç±Ã£¨ºÍϸöÃüÁî½áºÏʹÓã© */
-// OLED_WriteCmd(0x14); /* 0x14 ʹÄܳäµç±Ã£¬ 0x10 ÊÇ¹Ø±Õ */
-// OLED_WriteCmd(0xAF); /* ´ò¿ªOLEDÃæ°å */
-
- SPI_SEND(spi, SSD1306_DISPOFF); /* Display off 0xAE*/
- SPI_SEND(spi, SSD1306_SETCOLL(0)); /* Set lower column address 0x00 */
- SPI_SEND(spi, SSD1306_SETCOLH(0)); /* Set higher column address 0x10 */
- SPI_SEND(spi, SSD1306_STARTLINE(0)); /* Set display start line 0x40*/
- /* SPI_SEND(spi, SSD1306_PAGEADDR(0));*//* Set page address (Can ignore)*/
- SPI_SEND(spi, SSD1306_CONTRAST_MODE); /* Contrast control 0x81*/
- SPI_SEND(spi ,SSD1306_CONTRAST(UG2864HSWEG01_CONTRAST)); /* Default contrast 0xCF */
- SPI_SEND(spi, SSD1306_REMAPPLEFT); /* Set segment remap left 95 to 0 | 0xA1*/
- /* SPI_SEND(spi, SSD1306_EDISPOFF); */ /* Normal display :off 0xA4 (Can ignore)*/
- SPI_SEND(spi, SSD1306_NORMAL); /* Normal (un-reversed) display mode 0xA6 */
- SPI_SEND(spi, SSD1306_MRATIO_MODE); /* Multiplex ratio 0xA8*/
- SPI_SEND(spi, SSD1306_MRATIO(0x3f)); /* Duty = 1/64 */
- /* SPI_SEND(spi, SSD1306_SCANTOCOM0);*/ /* Com scan direction: Scan from COM[n-1] to COM[0] (Can ignore)*/
- SPI_SEND(spi, SSD1306_DISPOFFS_MODE); /* Set display offset 0xD3 */
- SPI_SEND(spi, SSD1306_DISPOFFS(0));
- SPI_SEND(spi, SSD1306_CLKDIV_SET); /* Set clock divider 0xD5*/
- SPI_SEND(spi, SSD1306_CLKDIV(8,0)); /* 0x80*/
-
- SPI_SEND(spi, SSD1306_CHRGPER_SET); /* ++Set pre-charge period 0xD9*/
- SPI_SEND(spi, SSD1306_CHRGPER(0x0f,1)); /* 0xf1 or 0x22£¨Enhanced mode?£© */
-
- SPI_SEND(spi, SSD1306_CMNPAD_CONFIG); /* Set common pads / set com pins hardware configuration 0xDA*/
- SPI_SEND(spi, SSD1306_CMNPAD(0x12)); /* 0x12 */
-
- SPI_SEND(spi, SSD1306_VCOM_SET); /* set vcomh 0xDB*/
- SPI_SEND(spi, SSD1306_VCOM(0x40));
-
- SPI_SEND(spi, SSD1306_CHRPUMP_SET); /* ++Set Charge Pump enable/disable 0x8D ssd1306*/
- SPI_SEND(spi, SSD1306_CHRPUMP_ON); /* 0x14 close 0x10 */
-
- /*SPI_SEND(spi, SSD1306_DCDC_MODE); */ /* DC/DC control mode: on (SSD1306 Not supported) */
- /*SPI_SEND(spi, SSD1306_DCDC_ON); */
-
- SPI_SEND(spi, SSD1306_DISPON); /* display ON 0xAF */
-
- /* De-select and unlock the device */
-
- SPI_SELECT(spi, SPIDEV_DISPLAY, false);
- ug2864hsweg01_unlock(priv->spi);
-
- /* Clear the display */
-
- up_mdelay(100);
- ug2864hsweg01_fill(&priv->dev, UG_Y1_BLACK);
- return &priv->dev;
-}
-
-/**************************************************************************************
- * Name: ug2864hsweg01_fill
- *
- * Description:
- * This non-standard method can be used to clear the entire display by writing one
- * color to the display. This is much faster than writing a series of runs.
- *
- * Input Parameters:
- * priv - Reference to private driver structure
- *
- * Assumptions:
- * Caller has selected the OLED section.
- *
- **************************************************************************************/
-
-void ug2864hsweg01_fill(FAR struct lcd_dev_s *dev, uint8_t color)
-{
- FAR struct ug2864hsweg01_dev_s *priv = &g_oleddev;
- unsigned int page;
-
- /* Make an 8-bit version of the selected color */
-
- if (color & 1)
- {
- color = 0xff;
- }
- else
- {
- color = 0;
- }
-
- /* Initialize the framebuffer */
-
- memset(priv->fb, color, UG2864HSWEG01_FBSIZE);
-
- /* Lock and select device */
-
- ug2864hsweg01_lock(priv->spi);
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Visit each page */
-
- for (page = 0; page < UG2864HSWEG01_DEV_PAGES; page++)
- {
- /* Select command transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Set the column address to the XOFFSET value */
-
- SPI_SEND(priv->spi, SSD1306_SETCOLL(UG2864HSWEG01_DEV_XOFFSET));
- SPI_SEND(priv->spi, SSD1306_SETCOLH(0));
-
- /* Set the page address */
-
- SPI_SEND(priv->spi, SSD1306_PAGEADDR(page));
-
- /* Select data transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false);
-
- /* Transfer one page of the selected color */
-
- (void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * UG2864HSWEG01_XRES],
- UG2864HSWEG01_XRES);
- }
-
- /* De-select and unlock the device */
-
- SPI_SELECT(priv->spi, SPIDEV_DISPLAY, false);
- ug2864hsweg01_unlock(priv->spi);
-}
-
-#endif /* CONFIG_LCD_UG2864HSWEG01 */
diff --git a/nuttx/drivers/lcd/ug-9664hswag01.c b/nuttx/drivers/lcd/ug-9664hswag01.c
deleted file mode 100644
index 6ef78fca6..000000000
--- a/nuttx/drivers/lcd/ug-9664hswag01.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-/**************************************************************************************
- * drivers/lcd/ug-9664hswag01.c
- * Driver for the Univision UG-9664HSWAG01 Display with the Solomon Systech SSD1305 LCD
- * controller.
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Reference: "Product Specification, OEL Display Module, UG-9664HSWAG01", Univision
- * Technology Inc., SAS1-6020-B, January 3, 2008.
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/spi.h>
-#include <nuttx/lcd/lcd.h>
-#include <nuttx/lcd/ug-9664hswag01.h>
-
-#include "ssd1305.h"
-
-/**************************************************************************************
- * Pre-processor Definitions
- **************************************************************************************/
-
-/* Configuration **********************************************************************/
-/* UG-9664HSWAG01 Configuration Settings:
- *
- * CONFIG_UG9664HSWAG01_SPIMODE - Controls the SPI mode
- * CONFIG_UG9664HSWAG01_FREQUENCY - Define to use a different bus frequency
- * CONFIG_UG9664HSWAG01_NINTERFACES - Specifies the number of physical
- * UG-9664HSWAG01 devices that will be supported. NOTE: At present, this
- * must be undefined or defined to be 1.
- * CONFIG_UG9664HSWAG01_POWER
- * If the hardware supports a controllable OLED a power supply, this
- * configuration shold be defined. (See ug_power() below).
- *
- * Required LCD driver settings:
- * CONFIG_LCD_UG9664HSWAG01 - Enable UG-9664HSWAG01 support
- * CONFIG_LCD_MAXCONTRAST should be 255, but any value >0 and <=255 will be accepted.
- * CONFIG_LCD_MAXPOWER should be 2: 0=off, 1=dim, 2=normal
- *
- * Required SPI driver settings:
- * CONFIG_SPI_CMDDATA - Include support for cmd/data selection.
- */
-
-/* Verify that all configuration requirements have been met */
-
-/* The UG-9664HSWAG01 spec says that is supports SPI mode 0,0 only. However, somtimes
- * you need to tinker with these things.
- */
-
-#ifndef CONFIG_UG9664HSWAG01_SPIMODE
-# define CONFIG_UG9664HSWAG01_SPIMODE SPIDEV_MODE0
-#endif
-
-/* SPI frequency */
-
-#ifndef CONFIG_UG9664HSWAG01_FREQUENCY
-# define CONFIG_UG9664HSWAG01_FREQUENCY 3500000
-#endif
-
-/* CONFIG_UG9664HSWAG01_NINTERFACES determines the number of physical interfaces
- * that will be supported.
- */
-
-#ifndef CONFIG_UG9664HSWAG01_NINTERFACES
-# define CONFIG_UG9664HSWAG01_NINTERFACES 1
-#endif
-
-#if CONFIG_UG9664HSWAG01_NINTERFACES != 1
-# warning "Only a single UG-9664HSWAG01 interface is supported"
-# undef CONFIG_UG9664HSWAG01_NINTERFACES
-# define CONFIG_UG9664HSWAG01_NINTERFACES 1
-#endif
-
-/* Verbose debug must also be enabled to use the extra OLED debug */
-
-#ifndef CONFIG_DEBUG
-# undef CONFIG_DEBUG_VERBOSE
-#endif
-
-#ifndef CONFIG_DEBUG_VERBOSE
-# undef CONFIG_DEBUG_LCD
-#endif
-
-/* Check contrast selection */
-
-#ifndef CONFIG_LCD_MAXCONTRAST
-# define CONFIG_LCD_MAXCONTRAST 255
-#endif
-
-#if CONFIG_LCD_MAXCONTRAST <= 0 || CONFIG_LCD_MAXCONTRAST > 255
-# error "CONFIG_LCD_MAXCONTRAST exceeds supported maximum"
-#endif
-
-#if CONFIG_LCD_MAXCONTRAST < 255
-# warning "Optimal setting of CONFIG_LCD_MAXCONTRAST is 255"
-#endif
-
-/* Check power setting */
-
-#if !defined(CONFIG_LCD_MAXPOWER)
-# define CONFIG_LCD_MAXPOWER 2
-#endif
-
-#if CONFIG_LCD_MAXPOWER != 2
-# warning "CONFIG_LCD_MAXPOWER should be 2"
-# undef CONFIG_LCD_MAXPOWER
-# define CONFIG_LCD_MAXPOWER 2
-#endif
-
-/* The OLED requires CMD/DATA SPI support */
-
-#ifndef CONFIG_SPI_CMDDATA
-# error "CONFIG_SPI_CMDDATA must be defined in your NuttX configuration"
-#endif
-
-/* Color is 1bpp monochrome with leftmost column contained in bits 0 */
-
-#ifdef CONFIG_NX_DISABLE_1BPP
-# warning "1 bit-per-pixel support needed"
-#endif
-
-/* Color Properties *******************************************************************/
-/* The SSD1305 display controller can handle a resolution of 132x64. The OLED
- * on the base board is 96x64.
- */
-
-#define UG_DEV_XRES 132
-#define UG_XOFFSET 18
-
-/* Display Resolution */
-
-#define UG_XRES 96
-#define UG_YRES 64
-
-/* Color depth and format */
-
-#define UG_BPP 1
-#define UG_COLORFMT FB_FMT_Y1
-
-/* Bytes per logical row and actual device row */
-
-#define UG_XSTRIDE (UG_XRES >> 3) /* Pixels arrange "horizontally for user" */
-#define UG_YSTRIDE (UG_YRES >> 3) /* But actual device arrangement is "vertical" */
-
-/* The size of the shadow frame buffer */
-
-#define UG_FBSIZE (UG_XRES * UG_YSTRIDE)
-
-/* Bit helpers */
-
-#define LS_BIT (1 << 0)
-#define MS_BIT (1 << 7)
-
-/* Debug ******************************************************************************/
-
-#ifdef CONFIG_DEBUG_LCD
-# define lcddbg(format, arg...) vdbg(format, ##arg)
-#else
-# define lcddbg(x...)
-#endif
-
-/**************************************************************************************
- * Private Type Definition
- **************************************************************************************/
-
-/* This structure describes the state of this driver */
-
-struct ug_dev_s
-{
- /* Publically visible device structure */
-
- struct lcd_dev_s dev;
-
- /* Private LCD-specific information follows */
-
- FAR struct spi_dev_s *spi;
- uint8_t contrast;
- uint8_t powered;
-
- /* The SSD1305 does not support reading from the display memory in SPI mode.
- * Since there is 1 BPP and access is byte-by-byte, it is necessary to keep
- * a shadow copy of the framebuffer memory.
- */
-
- uint8_t fb[UG_FBSIZE];
-};
-
-/**************************************************************************************
- * Private Function Protototypes
- **************************************************************************************/
-
-/* SPI helpers */
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void ug_select(FAR struct spi_dev_s *spi);
-static inline void ug_deselect(FAR struct spi_dev_s *spi);
-#else
-static void ug_select(FAR struct spi_dev_s *spi);
-static void ug_deselect(FAR struct spi_dev_s *spi);
-#endif
-
-/* LCD Data Transfer Methods */
-
-static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels);
-static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels);
-
-/* LCD Configuration */
-
-static int ug_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo);
-static int ug_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo);
-
-/* LCD RGB Mapping */
-
-#ifdef CONFIG_FB_CMAP
-# error "RGB color mapping not supported by this driver"
-#endif
-
-/* Cursor Controls */
-
-#ifdef CONFIG_FB_HWCURSOR
-# error "Cursor control not supported by this driver"
-#endif
-
-/* LCD Specific Controls */
-
-static int ug_getpower(struct lcd_dev_s *dev);
-static int ug_setpower(struct lcd_dev_s *dev, int power);
-static int ug_getcontrast(struct lcd_dev_s *dev);
-static int ug_setcontrast(struct lcd_dev_s *dev, unsigned int contrast);
-
-/* Initialization */
-
-static inline void up_clear(FAR struct ug_dev_s *priv);
-
-/**************************************************************************************
- * Private Data
- **************************************************************************************/
-
-/* This is working memory allocated by the LCD driver for each LCD device
- * and for each color plane. This memory will hold one raster line of data.
- * The size of the allocated run buffer must therefore be at least
- * (bpp * xres / 8). Actual alignment of the buffer must conform to the
- * bitwidth of the underlying pixel type.
- *
- * If there are multiple planes, they may share the same working buffer
- * because different planes will not be operate on concurrently. However,
- * if there are multiple LCD devices, they must each have unique run buffers.
- */
-
-static uint8_t g_runbuffer[UG_XSTRIDE+1];
-
-/* This structure describes the overall LCD video controller */
-
-static const struct fb_videoinfo_s g_videoinfo =
-{
- .fmt = UG_COLORFMT, /* Color format: RGB16-565: RRRR RGGG GGGB BBBB */
- .xres = UG_XRES, /* Horizontal resolution in pixel columns */
- .yres = UG_YRES, /* Vertical resolution in pixel rows */
- .nplanes = 1, /* Number of color planes supported */
-};
-
-/* This is the standard, NuttX Plane information object */
-
-static const struct lcd_planeinfo_s g_planeinfo =
-{
- .putrun = ug_putrun, /* Put a run into LCD memory */
- .getrun = ug_getrun, /* Get a run from LCD memory */
- .buffer = (uint8_t*)g_runbuffer, /* Run scratch buffer */
- .bpp = UG_BPP, /* Bits-per-pixel */
-};
-
-/* This is the standard, NuttX LCD driver object */
-
-static struct ug_dev_s g_ugdev =
-{
- .dev =
- {
- /* LCD Configuration */
-
- .getvideoinfo = ug_getvideoinfo,
- .getplaneinfo = ug_getplaneinfo,
-
- /* LCD RGB Mapping -- Not supported */
- /* Cursor Controls -- Not supported */
-
- /* LCD Specific Controls */
-
- .getpower = ug_getpower,
- .setpower = ug_setpower,
- .getcontrast = ug_getcontrast,
- .setcontrast = ug_setcontrast,
- },
-};
-
-/**************************************************************************************
- * Private Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: ug_powerstring
- *
- * Description:
- * Convert the power setting to a string.
- *
- **************************************************************************************/
-
-
-static inline FAR const char *ug_powerstring(uint8_t power)
-{
- if (power == UG_POWER_OFF)
- {
- return "OFF";
- }
- else if (power == UG_POWER_DIM)
- {
- return "DIM";
- }
- else if (power == UG_POWER_ON)
- {
- return "ON";
- }
- else
- {
- return "ERROR";
- }
-}
-
-/**************************************************************************************
- * Function: ug_select
- *
- * Description:
- * Select the SPI, locking and re-configuring if necessary
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void ug_select(FAR struct spi_dev_s *spi)
-{
- /* We own the SPI bus, so just select the chip */
-
- SPI_SELECT(spi, SPIDEV_DISPLAY, true);
-}
-#else
-static void ug_select(FAR struct spi_dev_s *spi)
-{
- /* Select UG-9664HSWAG01 chip (locking the SPI bus in case there are multiple
- * devices competing for the SPI bus
- */
-
- SPI_LOCK(spi, true);
- SPI_SELECT(spi, SPIDEV_DISPLAY, true);
-
- /* Now make sure that the SPI bus is configured for the UG-9664HSWAG01 (it
- * might have gotten configured for a different device while unlocked)
- */
-
- SPI_SETMODE(spi, CONFIG_UG9664HSWAG01_SPIMODE);
- SPI_SETBITS(spi, 8);
-#ifdef CONFIG_UG9664HSWAG01_FREQUENCY
- SPI_SETFREQUENCY(spi, CONFIG_UG9664HSWAG01_FREQUENCY);
-#endif
-}
-#endif
-
-/**************************************************************************************
- * Function: ug_deselect
- *
- * Description:
- * De-select the SPI
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- **************************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void ug_deselect(FAR struct spi_dev_s *spi)
-{
- /* We own the SPI bus, so just de-select the chip */
-
- SPI_SELECT(spi, SPIDEV_DISPLAY, false);
-}
-#else
-static void ug_deselect(FAR struct spi_dev_s *spi)
-{
- /* De-select UG-9664HSWAG01 chip and relinquish the SPI bus. */
-
- SPI_SELECT(spi, SPIDEV_DISPLAY, false);
- SPI_LOCK(spi, false);
-}
-#endif
-
-/**************************************************************************************
- * Name: ug_putrun
- *
- * Description:
- * This method can be used to write a partial raster line to the LCD:
- *
- * row - Starting row to write to (range: 0 <= row < yres)
- * col - Starting column to write to (range: 0 <= col <= xres-npixels)
- * buffer - The buffer containing the run to be written to the LCD
- * npixels - The number of pixels to write to the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-static int ug_putrun(fb_coord_t row, fb_coord_t col, FAR const uint8_t *buffer,
- size_t npixels)
-{
- /* Because of this line of code, we will only be able to support a single UG device */
-
- FAR struct ug_dev_s *priv = &g_ugdev;
- FAR uint8_t *fbptr;
- FAR uint8_t *ptr;
- uint8_t devcol;
- uint8_t fbmask;
- uint8_t page;
- uint8_t usrmask;
- uint8_t i;
- int pixlen;
-
- gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer);
-
- /* Clip the run to the display */
-
- pixlen = npixels;
- if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG_XRES)
- {
- pixlen = (int)UG_XRES - (int)col;
- }
-
- /* Verify that some portion of the run remains on the display */
-
- if (pixlen <= 0 || row > UG_YRES)
- {
- return OK;
- }
-
- /* Get the page number. The range of 64 lines is divided up into eight
- * pages of 8 lines each.
- */
-
- page = row >> 3;
-
- /* Update the shadow frame buffer memory. First determine the pixel
- * position in the frame buffer memory. Pixels are organized like
- * this:
- *
- * --------+---+---+---+---+-...-+-----+
- * Segment | 0 | 1 | 2 | 3 | ... | 131 |
- * --------+---+---+---+---+-...-+-----+
- * Bit 0 | | X | | | | |
- * Bit 1 | | X | | | | |
- * Bit 2 | | X | | | | |
- * Bit 3 | | X | | | | |
- * Bit 4 | | X | | | | |
- * Bit 5 | | X | | | | |
- * Bit 6 | | X | | | | |
- * Bit 7 | | X | | | | |
- * --------+---+---+---+---+-...-+-----+
- *
- * So, in order to draw a white, horizontal line, at row 45. we
- * would have to modify all of the bytes in page 45/8 = 5. We
- * would have to set bit 45%8 = 5 in every byte in the page.
- */
-
- fbmask = 1 << (row & 7);
- fbptr = &priv->fb[page * UG_XRES + col];
- ptr = fbptr;
-#ifdef CONFIG_NX_PACKEDMSFIRST
- usrmask = MS_BIT;
-#else
- usrmask = LS_BIT;
-#endif
-
- for (i = 0; i < pixlen; i++)
- {
- /* Set or clear the corresponding bit */
-
- if ((*buffer & usrmask) != 0)
- {
- *ptr++ |= fbmask;
- }
- else
- {
- *ptr++ &= ~fbmask;
- }
-
- /* Inc/Decrement to the next source pixel */
-
-#ifdef CONFIG_NX_PACKEDMSFIRST
- if (usrmask == LS_BIT)
- {
- buffer++;
- usrmask = MS_BIT;
- }
- else
- {
- usrmask >>= 1;
- }
-#else
- if (usrmask == MS_BIT)
- {
- buffer++;
- usrmask = LS_BIT;
- }
- else
- {
- usrmask <<= 1;
- }
-#endif
- }
-
- /* Offset the column position to account for smaller horizontal
- * display range.
- */
-
- devcol = col + UG_XOFFSET;
-
- /* Select and lock the device */
-
- ug_select(priv->spi);
-
- /* Select command transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Set the starting position for the run */
-
- (void)SPI_SEND(priv->spi, SSD1305_SETPAGESTART+page); /* Set the page start */
- (void)SPI_SEND(priv->spi, SSD1305_SETCOLL + (devcol & 0x0f)); /* Set the low column */
- (void)SPI_SEND(priv->spi, SSD1305_SETCOLH + (devcol >> 4)); /* Set the high column */
-
- /* Select data transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, false);
-
- /* Then transfer all of the data */
-
- (void)SPI_SNDBLOCK(priv->spi, fbptr, pixlen);
-
- /* Unlock and de-select the device */
-
- ug_deselect(priv->spi);
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug_getrun
- *
- * Description:
- * This method can be used to read a partial raster line from the LCD:
- *
- * row - Starting row to read from (range: 0 <= row < yres)
- * col - Starting column to read read (range: 0 <= col <= xres-npixels)
- * buffer - The buffer in which to return the run read from the LCD
- * npixels - The number of pixels to read from the LCD
- * (range: 0 < npixels <= xres-col)
- *
- **************************************************************************************/
-
-static int ug_getrun(fb_coord_t row, fb_coord_t col, FAR uint8_t *buffer,
- size_t npixels)
-{
- /* Because of this line of code, we will only be able to support a single UG device */
-
- FAR struct ug_dev_s *priv = &g_ugdev;
- FAR uint8_t *fbptr;
- uint8_t page;
- uint8_t fbmask;
- uint8_t usrmask;
- uint8_t i;
- int pixlen;
-
- gvdbg("row: %d col: %d npixels: %d\n", row, col, npixels);
- DEBUGASSERT(buffer);
-
- /* Clip the run to the display */
-
- pixlen = npixels;
- if ((unsigned int)col + (unsigned int)pixlen > (unsigned int)UG_XRES)
- {
- pixlen = (int)UG_XRES - (int)col;
- }
-
- /* Verify that some portion of the run is actually the display */
-
- if (pixlen <= 0 || row > UG_YRES)
- {
- return -EINVAL;
- }
-
- /* Then transfer the display data from the shadow frame buffer memory */
- /* Get the page number. The range of 64 lines is divided up into eight
- * pages of 8 lines each.
- */
-
- page = row >> 3;
-
- /* Update the shadow frame buffer memory. First determine the pixel
- * position in the frame buffer memory. Pixels are organized like
- * this:
- *
- * --------+---+---+---+---+-...-+-----+
- * Segment | 0 | 1 | 2 | 3 | ... | 131 |
- * --------+---+---+---+---+-...-+-----+
- * Bit 0 | | X | | | | |
- * Bit 1 | | X | | | | |
- * Bit 2 | | X | | | | |
- * Bit 3 | | X | | | | |
- * Bit 4 | | X | | | | |
- * Bit 5 | | X | | | | |
- * Bit 6 | | X | | | | |
- * Bit 7 | | X | | | | |
- * --------+---+---+---+---+-...-+-----+
- *
- * So, in order to draw a white, horizontal line, at row 45. we
- * would have to modify all of the bytes in page 45/8 = 5. We
- * would have to set bit 45%8 = 5 in every byte in the page.
- */
-
- fbmask = 1 << (row & 7);
- fbptr = &priv->fb[page * UG_XRES + col];
-#ifdef CONFIG_NX_PACKEDMSFIRST
- usrmask = MS_BIT;
-#else
- usrmask = LS_BIT;
-#endif
-
- *buffer = 0;
- for (i = 0; i < pixlen; i++)
- {
- /* Set or clear the corresponding bit */
-
- uint8_t byte = *fbptr++;
- if ((byte & fbmask) != 0)
- {
- *buffer |= usrmask;
- }
-
- /* Inc/Decrement to the next destination pixel. Hmmmm. It looks like
- * this logic could write past the end of the user buffer. Revisit
- * this!
- */
-
-#ifdef CONFIG_NX_PACKEDMSFIRST
- if (usrmask == LS_BIT)
- {
- buffer++;
- *buffer = 0;
- usrmask = MS_BIT;
- }
- else
- {
- usrmask >>= 1;
- }
-#else
- if (usrmask == MS_BIT)
- {
- buffer++;
- *buffer = 0;
- usrmask = LS_BIT;
- }
- else
- {
- usrmask <<= 1;
- }
-#endif
- }
-
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug_getvideoinfo
- *
- * Description:
- * Get information about the LCD video controller configuration.
- *
- **************************************************************************************/
-
-static int ug_getvideoinfo(FAR struct lcd_dev_s *dev,
- FAR struct fb_videoinfo_s *vinfo)
-{
- DEBUGASSERT(dev && vinfo);
- gvdbg("fmt: %d xres: %d yres: %d nplanes: %d\n",
- g_videoinfo.fmt, g_videoinfo.xres, g_videoinfo.yres, g_videoinfo.nplanes);
- memcpy(vinfo, &g_videoinfo, sizeof(struct fb_videoinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug_getplaneinfo
- *
- * Description:
- * Get information about the configuration of each LCD color plane.
- *
- **************************************************************************************/
-
-static int ug_getplaneinfo(FAR struct lcd_dev_s *dev, unsigned int planeno,
- FAR struct lcd_planeinfo_s *pinfo)
-{
- DEBUGASSERT(dev && pinfo && planeno == 0);
- gvdbg("planeno: %d bpp: %d\n", planeno, g_planeinfo.bpp);
- memcpy(pinfo, &g_planeinfo, sizeof(struct lcd_planeinfo_s));
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug_getpower
- *
- * Description:
- * 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.
- *
- **************************************************************************************/
-
-static int ug_getpower(struct lcd_dev_s *dev)
-{
- struct ug_dev_s *priv = (struct ug_dev_s *)dev;
- DEBUGASSERT(priv);
- gvdbg("powered: %s\n", ug_powerstring(priv->powered));
- return priv->powered;
-}
-
-/**************************************************************************************
- * Name: ug_setpower
- *
- * Description:
- * Enable/disable LCD panel power (0: full off - CONFIG_LCD_MAXPOWER: full on). On
- * backlit LCDs, this setting may correspond to the backlight setting.
- *
- **************************************************************************************/
-
-static int ug_setpower(struct lcd_dev_s *dev, int power)
-{
- struct ug_dev_s *priv = (struct ug_dev_s *)dev;
-
- DEBUGASSERT(priv && (unsigned)power <= CONFIG_LCD_MAXPOWER);
- gvdbg("power: %s powered: %s\n",
- ug_powerstring(power), ug_powerstring(priv->powered));
-
- /* Select and lock the device */
-
- ug_select(priv->spi);
- if (power <= UG_POWER_OFF)
- {
- /* Turn the display off */
-
- (void)SPI_SEND(priv->spi, SSD1305_DISPOFF); /* Display off */
-
- /* Remove power to the device */
-
- ug_power(0, false);
- priv->powered = UG_POWER_OFF;
- }
- else
- {
- /* Turn the display on, dim or normal */
-
- if (power == UG_POWER_DIM)
- {
- (void)SPI_SEND(priv->spi, SSD1305_DISPONDIM); /* Display on, dim mode */
- }
- else /* if (power > UG_POWER_DIM) */
- {
- (void)SPI_SEND(priv->spi, SSD1305_DISPON); /* Display on, normal mode */
- power = UG_POWER_ON;
- }
- (void)SPI_SEND(priv->spi, SSD1305_DISPRAM); /* Resume to RAM content display */
-
- /* Restore power to the device */
-
- ug_power(0, true);
- priv->powered = power;
- }
- ug_deselect(priv->spi);
-
- return OK;
-}
-
-/**************************************************************************************
- * Name: ug_getcontrast
- *
- * Description:
- * Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int ug_getcontrast(struct lcd_dev_s *dev)
-{
- struct ug_dev_s *priv = (struct ug_dev_s *)dev;
- DEBUGASSERT(priv);
- return (int)priv->contrast;
-}
-
-/**************************************************************************************
- * Name: ug_setcontrast
- *
- * Description:
- * Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST).
- *
- **************************************************************************************/
-
-static int ug_setcontrast(struct lcd_dev_s *dev, unsigned int contrast)
-{
- struct ug_dev_s *priv = (struct ug_dev_s *)dev;
-
- gvdbg("contrast: %d\n", contrast);
- DEBUGASSERT(priv);
-
- if (contrast > 255)
- {
- return -EINVAL;
- }
-
- /* Select and lock the device */
-
- ug_select(priv->spi);
-
- /* Select command transfer */
-
- SPI_CMDDATA(priv->spi, SPIDEV_DISPLAY, true);
-
- /* Set the contrast */
-
- (void)SPI_SEND(priv->spi, SSD1305_SETCONTRAST); /* Set contrast control register */
- (void)SPI_SEND(priv->spi, contrast); /* Data 1: Set 1 of 256 contrast steps */
- priv->contrast = contrast;
-
- /* Unlock and de-select the device */
-
- ug_deselect(priv->spi);
- return OK;
-}
-
-/**************************************************************************************
- * Name: up_clear
- *
- * Description:
- * Clear the display.
- *
- **************************************************************************************/
-
-static inline void up_clear(FAR struct ug_dev_s *priv)
-{
- FAR struct spi_dev_s *spi = priv->spi;
- int page;
- int i;
-
- /* Clear the framebuffer */
-
- memset(priv->fb, UG_Y1_BLACK, UG_FBSIZE);
-
- /* Select and lock the device */
-
- ug_select(priv->spi);
-
- /* Go through all 8 pages */
-
- for (page = 0, i = 0; i < 8; i++)
- {
- /* Select command transfer */
-
- SPI_CMDDATA(spi, SPIDEV_DISPLAY, true);
-
- /* Set the starting position for the run */
-
- (void)SPI_SEND(priv->spi, SSD1305_SETPAGESTART+i);
- (void)SPI_SEND(priv->spi, SSD1305_SETCOLL + (UG_XOFFSET & 0x0f));
- (void)SPI_SEND(priv->spi, SSD1305_SETCOLH + (UG_XOFFSET >> 4));
-
- /* Select data transfer */
-
- SPI_CMDDATA(spi, SPIDEV_DISPLAY, false);
-
- /* Then transfer all 96 columns of data */
-
- (void)SPI_SNDBLOCK(priv->spi, &priv->fb[page * UG_XRES], UG_XRES);
- }
-
- /* Unlock and de-select the device */
-
- ug_deselect(spi);
-}
-
-/**************************************************************************************
- * Public Functions
- **************************************************************************************/
-
-/**************************************************************************************
- * Name: ug_initialize
- *
- * Description:
- * Initialize the UG-9664HSWAG01 video hardware. The initial state of the
- * OLED is fully initialized, display memory cleared, and the OLED ready to
- * use, but with the power setting at 0 (full off == sleep mode).
- *
- * Input Parameters:
- *
- * spi - A reference to the SPI driver instance.
- * devno - A value in the range of 0 through CONFIG_UG9664HSWAG01_NINTERFACES-1.
- * This allows support for multiple OLED devices.
- *
- * Returned Value:
- *
- * On success, this function returns a reference to the LCD object for the specified
- * OLED. NULL is returned on any failure.
- *
- **************************************************************************************/
-
-FAR struct lcd_dev_s *ug_initialize(FAR struct spi_dev_s *spi, unsigned int devno)
-{
- /* Configure and enable LCD */
-
- FAR struct ug_dev_s *priv = &g_ugdev;
-
- gvdbg("Initializing\n");
- DEBUGASSERT(spi && devno == 0);
-
- /* Save the reference to the SPI device */
-
- priv->spi = spi;
-
- /* Select and lock the device */
-
- ug_select(spi);
-
- /* Make sure that the OLED off */
-
- ug_power(0, false);
-
- /* Select command transfer */
-
- SPI_CMDDATA(spi, SPIDEV_DISPLAY, true);
-
- /* Configure the device */
-
- (void)SPI_SEND(spi, SSD1305_SETCOLL + 2); /* Set low column address */
- (void)SPI_SEND(spi, SSD1305_SETCOLH + 2); /* Set high column address */
- (void)SPI_SEND(spi, SSD1305_SETSTARTLINE+0); /* Display start set */
- (void)SPI_SEND(spi, SSD1305_SCROLL_STOP); /* Stop horizontal scroll */
- (void)SPI_SEND(spi, SSD1305_SETCONTRAST); /* Set contrast control register */
- (void)SPI_SEND(spi, 0x32); /* Data 1: Set 1 of 256 contrast steps */
- (void)SPI_SEND(spi, SSD1305_SETBRIGHTNESS); /* Brightness for color bank */
- (void)SPI_SEND(spi, 0x80); /* Data 1: Set 1 of 256 contrast steps */
- (void)SPI_SEND(spi, SSD1305_MAPCOL131); /* Set segment re-map */
- (void)SPI_SEND(spi, SSD1305_DISPNORMAL); /* Set normal display */
-/*(void)SPI_SEND(spi, SSD1305_DISPINVERTED); Set inverse display */
- (void)SPI_SEND(spi, SSD1305_SETMUX); /* Set multiplex ratio */
- (void)SPI_SEND(spi, 0x3f); /* Data 1: MUX ratio -1: 15-63 */
- (void)SPI_SEND(spi, SSD1305_SETOFFSET); /* Set display offset */
- (void)SPI_SEND(spi, 0x40); /* Data 1: Vertical shift by COM: 0-63 */
- (void)SPI_SEND(spi, SSD1305_MSTRCONFIG); /* Set dc-dc on/off */
- (void)SPI_SEND(spi, SSD1305_MSTRCONFIG_EXTVCC); /* Data 1: Select external Vcc */
- (void)SPI_SEND(spi, SSD1305_SETCOMREMAPPED); /* Set com output scan direction */
- (void)SPI_SEND(spi, SSD1305_SETDCLK); /* Set display clock divide
- * ratio/oscillator/frequency */
- (void)SPI_SEND(spi, 15 << SSD1305_DCLKFREQ_SHIFT | 0 << SSD1305_DCLKDIV_SHIFT);
- (void)SPI_SEND(spi, SSD1305_SETCOLORMODE); /* Set area color mode on/off & low power
- * display mode */
- (void)SPI_SEND(spi, SSD1305_COLORMODE_MONO | SSD1305_POWERMODE_LOW);
- (void)SPI_SEND(spi, SSD1305_SETPRECHARGE); /* Set pre-charge period */
- (void)SPI_SEND(spi, 15 << SSD1305_PHASE2_SHIFT | 1 << SSD1305_PHASE1_SHIFT);
- (void)SPI_SEND(spi, SSD1305_SETCOMCONFIG); /* Set COM configuration */
- (void)SPI_SEND(spi, SSD1305_COMCONFIG_ALT); /* Data 1, Bit 4: 1=Alternative COM pin configuration */
- (void)SPI_SEND(spi, SSD1305_SETVCOMHDESEL); /* Set VCOMH deselect level */
- (void)SPI_SEND(spi, SSD1305_VCOMH_x7p7); /* Data 1: ~0.77 x Vcc */
- (void)SPI_SEND(spi, SSD1305_SETLUT); /* Set look up table for area color */
- (void)SPI_SEND(spi, 0x3f); /* Data 1: Pulse width: 31-63 */
- (void)SPI_SEND(spi, 0x3f); /* Data 2: Color A: 31-63 */
- (void)SPI_SEND(spi, 0x3f); /* Data 3: Color B: 31-63 */
- (void)SPI_SEND(spi, 0x3f); /* Data 4: Color C: 31-63 */
- (void)SPI_SEND(spi, SSD1305_DISPON); /* Display on, normal mode */
- (void)SPI_SEND(spi, SSD1305_DISPRAM); /* Resume to RAM content display */
-
- /* Let go of the SPI lock and de-select the device */
-
- ug_deselect(spi);
-
- /* Clear the framebuffer */
-
- up_mdelay(100);
- up_clear(priv);
- return &priv->dev;
-}
diff --git a/nuttx/drivers/loop.c b/nuttx/drivers/loop.c
deleted file mode 100644
index 4744ae0dd..000000000
--- a/nuttx/drivers/loop.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/****************************************************************************
- * drivers/loop.c
- *
- * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/mount.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <semaphore.h>
-#include <debug.h>
-#include <errno.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-#define loop_semgive(d) sem_post(&(d)->sem) /* To match loop_semtake */
-#define MAX_OPENCNT (255) /* Limit of uint8_t */
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct loop_struct_s
-{
- sem_t sem; /* For safe read-modify-write operations */
- uint32_t nsectors; /* Number of sectors on device */
- off_t offset; /* Offset (in bytes) to the first sector */
- uint16_t sectsize; /* The size of one sector */
- uint8_t opencnt; /* Count of open references to the loop device */
-#ifdef CONFIG_FS_WRITABLE
- bool writeenabled; /* true: can write to device */
-#endif
- int fd; /* Descriptor of char device/file */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static void loop_semtake(FAR struct loop_struct_s *dev);
-static int loop_open(FAR struct inode *inode);
-static int loop_close(FAR struct inode *inode);
-static ssize_t loop_read(FAR struct inode *inode, unsigned char *buffer,
- size_t start_sector, unsigned int nsectors);
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t loop_write(FAR struct inode *inode, const unsigned char *buffer,
- size_t start_sector, unsigned int nsectors);
-#endif
-static int loop_geometry(FAR struct inode *inode, struct geometry *geometry);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct block_operations g_bops =
-{
- loop_open, /* open */
- loop_close, /* close */
- loop_read, /* read */
-#ifdef CONFIG_FS_WRITABLE
- loop_write, /* write */
-#else
- NULL, /* write */
-#endif
- loop_geometry, /* geometry */
- NULL /* ioctl */
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: loop_semtake
- ****************************************************************************/
-
-static void loop_semtake(FAR struct loop_struct_s *dev)
-{
- /* Take the semaphore (perhaps waiting) */
-
- while (sem_wait(&dev->sem) != 0)
- {
- /* The only case that an error should occur here is if
- * the wait was awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-}
-
-/****************************************************************************
- * Name: loop_open
- *
- * Description: Open the block device
- *
- ****************************************************************************/
-
-static int loop_open(FAR struct inode *inode)
-{
- FAR struct loop_struct_s *dev;
- int ret = OK;
-
- DEBUGASSERT(inode && inode->i_private);
- dev = (FAR struct loop_struct_s *)inode->i_private;
-
- /* Make sure we have exclusive access to the state structure */
-
- loop_semtake(dev);
- if (dev->opencnt == MAX_OPENCNT)
- {
- return -EMFILE;
- }
- else
- {
- /* Increment the open count */
-
- dev->opencnt++;
- }
-
- loop_semgive(dev);
- return ret;
-}
-
-/****************************************************************************
- * Name: loop_close
- *
- * Description: close the block device
- *
- ****************************************************************************/
-
-static int loop_close(FAR struct inode *inode)
-{
- FAR struct loop_struct_s *dev;
- int ret = OK;
-
- DEBUGASSERT(inode && inode->i_private);
- dev = (FAR struct loop_struct_s *)inode->i_private;
-
- /* Make sure we have exclusive access to the state structure */
-
- loop_semtake(dev);
- if (dev->opencnt == 0)
- {
- return -EIO;
- }
- else
- {
- /* Decrement the open count */
-
- dev->opencnt--;
- }
-
- loop_semgive(dev);
- return ret;
-}
-
-/****************************************************************************
- * Name: loop_read
- *
- * Description: Read the specified numer of sectors
- *
- ****************************************************************************/
-
-static ssize_t loop_read(FAR struct inode *inode, unsigned char *buffer,
- size_t start_sector, unsigned int nsectors)
-{
- FAR struct loop_struct_s *dev;
- ssize_t nbytesread;
- off_t offset;
- int ret;
-
- DEBUGASSERT(inode && inode->i_private);
- dev = (FAR struct loop_struct_s *)inode->i_private;
-
- if (start_sector + nsectors > dev->nsectors)
- {
- dbg("Read past end of file\n");
- return -EIO;
- }
-
- /* Calculate the offset to read the sectors and seek to the position */
-
- offset = start_sector * dev->sectsize + dev->offset;
- ret = lseek(dev->fd, offset, SEEK_SET);
- if (ret == (off_t)-1)
- {
- dbg("Seek failed for offset=%d: %d\n", (int)offset, errno);
- return -EIO;
- }
-
- /* Then read the requested number of sectors from that position */
-
- do
- {
- nbytesread = read(dev->fd, buffer, nsectors * dev->sectsize);
- if (nbytesread < 0 && errno != EINTR)
- {
- dbg("Read failed: %d\n", errno);
- return -errno;
- }
- }
- while (nbytesread < 0);
-
- /* Return the number of sectors read */
-
- return nbytesread / dev->sectsize;
-}
-
-/****************************************************************************
- * Name: loop_write
- *
- * Description: Write the specified number of sectors
- *
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t loop_write(FAR struct inode *inode, const unsigned char *buffer,
- size_t start_sector, unsigned int nsectors)
-{
- FAR struct loop_struct_s *dev;
- ssize_t nbyteswritten;
- off_t offset;
- int ret;
-
- DEBUGASSERT(inode && inode->i_private);
- dev = (FAR struct loop_struct_s *)inode->i_private;
-
- /* Calculate the offset to write the sectors and seek to the position */
-
- offset = start_sector * dev->sectsize + dev->offset;
- ret = lseek(dev->fd, offset, SEEK_SET);
- if (ret == (off_t)-1)
- {
- dbg("Seek failed for offset=%d: %d\n", (int)offset, errno);
- }
-
- /* Then write the requested number of sectors to that position */
-
- do
- {
- nbyteswritten = write(dev->fd, buffer, nsectors * dev->sectsize);
- if (nbyteswritten < 0 && errno != EINTR)
- {
- dbg("Write failed: %d\n", errno);
- return -errno;
- }
- }
- while (nbyteswritten < 0);
-
- /* Return the number of sectors written */
-
- return nbyteswritten / dev->sectsize;
-}
-#endif
-
-/****************************************************************************
- * Name: loop_geometry
- *
- * Description: Return device geometry
- *
- ****************************************************************************/
-
-static int loop_geometry(FAR struct inode *inode, struct geometry *geometry)
-{
- FAR struct loop_struct_s *dev;
-
- DEBUGASSERT(inode);
- if (geometry)
- {
- dev = (FAR struct loop_struct_s *)inode->i_private;
- geometry->geo_available = true;
- geometry->geo_mediachanged = false;
-#ifdef CONFIG_FS_WRITABLE
- geometry->geo_writeenabled = dev->writeenabled;
-#else
- geometry->geo_writeenabled = false;
-#endif
- geometry->geo_nsectors = dev->nsectors;
- geometry->geo_sectorsize = dev->sectsize;
- return OK;
- }
-
- return -EINVAL;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: losetup
- *
- * Description:
- * Setup the loop device so that it exports the file referenced by 'filename'
- * as a block device.
- *
- ****************************************************************************/
-
-int losetup(const char *devname, const char *filename, uint16_t sectsize,
- off_t offset, bool readonly)
-{
- FAR struct loop_struct_s *dev;
- struct stat sb;
- int ret;
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (!devname || !filename || !sectsize)
- {
- return -EINVAL;
- }
-#endif
-
- /* Get the size of the file */
-
- ret = stat(filename, &sb);
- if (ret < 0)
- {
- dbg("Failed to stat %s: %d\n", filename, errno);
- return -errno;
- }
-
- /* Check if the file system is big enough for one block */
-
- if (sb.st_size - offset < sectsize)
- {
- dbg("File is too small for blocksize\n");
- return -ERANGE;
- }
-
- /* Allocate a loop device structure */
-
- dev = (FAR struct loop_struct_s *)kzalloc(sizeof(struct loop_struct_s));
- if (!dev)
- {
- return -ENOMEM;
- }
-
- /* Initialize the loop device structure. */
-
- sem_init(&dev->sem, 0, 1);
- dev->nsectors = (sb.st_size - offset) / sectsize;
- dev->sectsize = sectsize;
- dev->offset = offset;
-
- /* Open the file. */
-
-#ifdef CONFIG_FS_WRITABLE
- dev->writeenabled = false; /* Assume failure */
- dev->fd = -1;
-
- /* First try to open the device R/W access (unless we are asked
- * to open it readonly).
- */
-
- if (!readonly)
- {
- dev->fd = open(filename, O_RDWR);
- }
-
- if (dev->fd >= 0)
- {
- dev->writeenabled = true; /* Success */
- }
- else
-#endif
- {
- /* If that fails, then try to open the device read-only */
-
- dev->fd = open(filename, O_RDWR);
- if (dev->fd < 0)
- {
- dbg("Failed to open %s: %d\n", filename, errno);
- ret = -errno;
- goto errout_with_dev;
- }
- }
-
- /* Inode private data will be reference to the loop device structure */
-
- ret = register_blockdriver(devname, &g_bops, 0, dev);
- if (ret < 0)
- {
- fdbg("register_blockdriver failed: %d\n", -ret);
- goto errout_with_fd;
- }
-
- return OK;
-
-errout_with_fd:
- close(dev->fd);
-errout_with_dev:
- kfree(dev);
- return ret;
-}
-
-/****************************************************************************
- * Name: loteardown
- *
- * Description:
- * Undo the setup performed by losetup
- *
- ****************************************************************************/
-
-int loteardown(const char *devname)
-{
- FAR struct loop_struct_s *dev;
- FAR struct inode *inode;
- int ret;
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (!devname)
- {
- return -EINVAL;
- }
-#endif
-
- /* Open the block driver associated with devname so that we can get the inode
- * reference.
- */
-
- ret = open_blockdriver(devname, MS_RDONLY, &inode);
- if (ret < 0)
- {
- dbg("Failed to open %s: %d\n", devname, -ret);
- return ret;
- }
-
- /* Inode private data is a reference to the loop device stgructure */
-
- dev = (FAR struct loop_struct_s *)inode->i_private;
- close_blockdriver(inode);
-
- DEBUGASSERT(dev);
-
- /* Are there still open references to the device */
-
- if (dev->opencnt > 0)
- {
- return -EBUSY;
- }
-
- /* Otherwise, unregister the block device */
-
- ret = unregister_blockdriver(devname);
-
- /* Release the device structure */
-
- if (dev->fd >= 0)
- {
- (void)close(dev->fd);
- }
-
- kfree(dev);
- return ret;
-}
diff --git a/nuttx/drivers/mmcsd/Kconfig b/nuttx/drivers/mmcsd/Kconfig
deleted file mode 100644
index 2d9a04bbb..000000000
--- a/nuttx/drivers/mmcsd/Kconfig
+++ /dev/null
@@ -1,79 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-config MMCSD_NSLOTS
- int "Number of MMC/SD slots"
- default 1
- ---help---
- Number of MMC/SD slots supported by the
- driver. Default is one.
-
-config MMCSD_READONLY
- bool "Disable MMC/SD write access"
- default n
- ---help---
- Provide read-only access. Default is
- Read/Write
-
-config MMCSD_MULTIBLOCK_DISABLE
- bool "Disable MMC/SD multiblock transfer"
- default n
- ---help---
- Use only the single block transfer method.
- This setting is used to work around buggy SDIO drivers that cannot handle
- multiple block transfers.
-
-config MMCSD_MMCSUPPORT
- bool "MMC cards support"
- default y
- ---help---
- Enable support for MMC cards
-
-config MMCSD_HAVECARDDETECT
- bool "MMC/SD card detection"
- default y
- ---help---
- SDIO driver card detection is
- 100% accurate
-
-config MMCSD_SPI
- bool "MMC/SD SPI transfer support"
- default y
- depends on SPI
-
-config MMCSD_SPICLOCK
- int "MMC/SD maximum SPI clock"
- default 20000000
- depends on MMCSD_SPI
- ---help---
- Maximum SPI clock to drive MMC/SD card.
- Default is 20MHz.
-
-config MMCSD_SDIO
- bool "MMC/SD sdio transfer support"
- default n
-
-if MMCSD_SDIO
-config SDIO_DMA
- bool "SDIO dma support"
- default n
- ---help---
- SDIO driver supports DMA
-
-config SDIO_MUXBUS
- bool "SDIO bus share support"
- default n
- ---help---
- Set this SDIO interface if the SDIO interface
- or hardware resources are shared with other drivers.
-
-config SDIO_WIDTH_D1_ONLY
- bool "SDIO 1-bit transfer"
- default n
- ---help---
- Select 1-bit transfer mode. Default:
- 4-bit transfer mode.
-endif
-
diff --git a/nuttx/drivers/mmcsd/Make.defs b/nuttx/drivers/mmcsd/Make.defs
deleted file mode 100644
index 06e689c75..000000000
--- a/nuttx/drivers/mmcsd/Make.defs
+++ /dev/null
@@ -1,56 +0,0 @@
-############################################################################
-# drivers/mmcsd/Make.defs
-#
-# Copyright (C) 2008, 2011-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-ifeq ($(CONFIG_MMCSD),y)
-
-# Include MMC/SD drivers
-
-ifeq ($(CONFIG_MMCSD_SDIO),y)
-CSRCS += mmcsd_sdio.c
-endif
-
-ifeq ($(CONFIG_MMCSD_SPI),y)
-CSRCS += mmcsd_spi.c mmcsd_debug.c
-endif
-
-# Include MMC/SD driver build support
-
-DEPPATH += --dep-path mmcsd
-VPATH += :mmcsd
-CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)mmcsd}
-
-endif
-
-
diff --git a/nuttx/drivers/mmcsd/mmcsd_csd.h b/nuttx/drivers/mmcsd/mmcsd_csd.h
deleted file mode 100644
index d5343aa84..000000000
--- a/nuttx/drivers/mmcsd/mmcsd_csd.h
+++ /dev/null
@@ -1,424 +0,0 @@
-/****************************************************************************
- * drivers/mmcsd/mmcsd_csd.h
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_MMCSD_MMCSD_CSD_H
-#define __DRIVERS_MMCSD_MMCSD_CSD_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <stdint.h>
-
-/****************************************************************************
- * Pre-Processor Definitions
- ****************************************************************************/
-
-/* CSD **********************************************************************/
-
-/* The CSD is a 16 byte, / 128-bit packed structure. The following macros
- * can be used to extract each packed field from the CSD. Two types of
- * macros are supported, selected by CONFIG_MMCSD_BE16: (1) byte data (with
- * MS byte first), or (2) 16-bit big-endian data (with MS hword first).
- */
-
-#ifdef CONFIG_MMCSD_BE16
-
-/* CSD_STRUCTURE 126-127 */
-
-#define MMCSD_CSD_CSDSTRUCT(csd) (csd[0] >> 14)
-
-/* SPEC_VERS 122-125 = (word 0, bits 13:10) (MMC) Spec version */
-
-#define MMC_CSD_SPECVERS(csd) ((csd[0] >> 10) & 0x0f)
-
-/* Reserved 120-125 */
-
-/* TAAC 112-119 = Data read access-time-1
- * TIME_VALUE 3-6 = Time mantissa
- * TIME_UNIT 0-2 = Time exponent
- */
-
-#define MMCSD_CSD_TAAC_TIMEVALUE(csd) ((csd[0] >> 3) & 0x0f)
-#define MMCSD_CSD_TAAC_TIMEUNIT(csd) (csd[0] & 7)
-
-/* NSAC 111:104 = Data read access-time-2 in CLK cycle(NSAC*100) */
-
-#define MMCSD_CSD_NSAC(csd) (csd[1] >> 8)
-
-/* TRAN_SPEED 96-103 = Max. data transfer rate
- * TIME_VALUE 3-6 = Rate exponent
- * TRANSFER_RATE_UNIT 0-2 = Rate mantissa
- */
-
-#define MMCSD_CSD_TRANSPEED_TIMEVALUE(csd) ((csd[1] >> 3) & 0x0f)
-#define MMCSD_CSD_TRANSPEED_TRANSFERRATEUNIT(csd) (csd[1] & 7)
-
-/* CCC 84-95 = Card command classes */
-
-#define MMCSD_CSD_CCC(csd) ((csd[2] >> 4) & 0x0fff)
-
- /* READ_BL_LEN 80-83 = Max. read data block length */
-
-#define MMCSD_CSD_READBLLEN(csd) (csd[2] & 0x0f)
-
-/* READ_BL_PARTIAL 79-79 = Partial blocks for read allowed */
-
-#define MMCSD_CSD_READBLPARTIAL(csd) (csd[3] >> 15)
-
-/* WRITE_BLK_MISALIGN 78-78 = Write block misalignment */
-
-#define MMCSD_CSD_WRITEBLKMISALIN(csd) ((csd[3] >> 14) & 1)
-
-/* READ_BLK_MISALIGN 77:77 = Read block misalignment */
-
-#define MMCSD_CSD_READBLKMISALIN(csd) ((csd[3] >> 13) & 1)
-
-/* DSR_IMP 76-76 = DSR implemented */
-
-#define MMCSD_CSD_DSRIMP(csd) ((csd[3] >> 12) & 1)
-
-/* C_SIZE 62-73 Device size */
-
-#define MMCSD_CSD_CSIZE(csd) (((csd[3] & 0x03ff) << 2) | ((csd[4] >> 14) & 3))
-
-/* VDD_R_CURR_MIN 59-61 = Max. read current at Vcc min */
-
-#define MMCSD_CSD_VDDRCURRMIN(csd) ((csd[4] >> 11) & 7)
-
-/* VDD_R_CURR_MAX 56-58 = Max. read current at Vcc max */
-
-#define MMCSD_CSD_VDDRCURRMAX(csd) ((csd[4] >> 8) & 7)
-
-/* VDD_W_CURR_MIN 53-55 = Max. write current at Vcc min */
-
-#define MMCSD_CSD_VDDWCURRMIN(csd) ((csd[4] >> 5) & 7)
-
-/* VDD_W_CURR_MAX 50-52 = Max. write current at Vcc max */
-
-#define MMCSD_CSD_VDDWCURRMAX(csd) ((csd[4] >> 2) & 7)
-
-/* C_SIZE_MULT 47-49 Device size multiplier */
-
-#define MMCSD_CSD_CSIZEMULT(csd) (((csd[4] & 3) << 1) | (csd[5] >> 15))
-
-/* ER_BLK_EN 46-46 =Erase single block enable (SD) */
-
-#define SD_CSD_SDERBLKEN(csd) ((csd[5] >> 14) & 1)
-
-/* SECTOR_SIZE 39-45 = Erase sector size (SD) */
-
-#define SD_CSD_SECTORSIZE(csd) ((csd[5] >> 7) & 0x7f)
-
-/* SECTOR_SIZE 42-46 = Erase sector size (MMC) */
-
-#define MMC_CSD_SECTORSIZE(csd) ((csd[5] >> 10) & 0x1f)
-
-/* ER_GRP_SIZE 37-41 = Erase group size (MMC)*/
-
-#define MMC_CSD_ERGRPSIZE(csd) ((csd[5] >> 5) & 0x1f)
-
-/* WP_GRP_SIZE 32-38 = Write protect group size (SD) */
-
-#define SD_CSD_WPGRPSIZE(csd) (csd[5] & 0x7f)
-
-/* WP_GRP_SIZE 32-36 = Write protect group size (MMC) */
-
-#define MMC_CSD_WPGRPSIZE(csd) (csd[5] & 0x1f)
-
-/* WP_GRP_EN 31-31 = Write protect group enable */
-
-#define MMCSD_WPGRPEN(csd) (csd[6] >> 15)
-
-/* DFLT_ECC 29-30 = Manufacturer default ECC (MMC) */
-
-#define MMC_CSD_DFLTECC(csd) ((csd[6] >> 13) & 3)
-
-/* R2W_FACTOR 26-28 = Write speed factor */
-
-#define MMCSD_CSD_R2WFACTOR(csd) ((csd[6] >> 10) & 7)
-
-/* WRITE_BL_LEN 22-25 = Max. write data block length */
-
-#define MMCSD_CSD_WRITEBLLEN(csd) ((csd[6] >> 6) & 0x0f)
-
-/* WRITE_BL_PARTIAL 21-21 = Partial blocks for write allowed */
-
-#define MMCSD_CSD_WRITEBLPARTIAL(csd) ((csd[6] >> 5) & 1)
-
-/* Reserved 16-20 */
-
-/* FILE_FORMAT_GROUP 15-15 = File format group */
-
-#define MMCSD_CSD_FILEFORMATGRP(csd) (csd[7] >> 15)
-
-/* COPY 14-14 = Copy flag (OTP) */
-
-#define MMCSD_CSD_COPY(csd) ((csd[7] >> 14) & 1)
-
-/* PERM_WRITE_PROTECT 13-13 = Permanent write protection */
-
-#define MMCSD_CSD_PERMWRITEPROTECT(csd) ((csd[7] >> 13) & 1)
-
-/* TMP_WRITE_PROTECT 12-12 = Temporary write protection */
-
-#define MMCSD_CSD_TMPWRITEPROTECT(csd) ((csd[7] >> 12) & 1)
-
-/* FILE_FORMAT 10-11 = File format */
-
-#define MMCSD_CSD_FILEFORMAT(csd) ((csd[7] >> 10) & 3)
-
-/* ECC 8-9 = ECC (MMC) */
-
-#define MMC_CSD_ECC(csd) ((csd[7] >> 8) & 3)
-
-/* CRC 1-7 = CRC */
-
-#define MMCSD_CSD_CRC(csd) ((csd[7] >> 1) & 0x7f)
-
-/* Reserved 0-0 */
-
-#else /* CONFIG_MMCSD_BE16 */
-
-/* CSD_STRUCTURE 126-127 */
-
-#define MMCSD_CSD_CSDSTRUCT(csd) (csd[0] >> 6)
-
-/* SPEC_VERS 122-125 = (word 0, bits 13:10) (MMC) Spec version */
-
-#define MMC_CSD_SPECVERS(csd) ((csd[0] >> 2) & 0x0f)
-
-/* Reserved 120-155 */
-
-/* TAAC 112-119 = Data read access-time-1
- * TIME_VALUE 3-6 = Time mantissa
- * TIME_UNIT 0-2 = Time exponent
- */
-
-#define MMCSD_CSD_TAAC_TIMEVALUE(csd) ((csd[1] >> 3) & 0x0f)
-#define MMCSD_CSD_TAAC_TIMEUNIT(csd) (csd[1] & 7)
-
-#define SD20_CSD_TAC_TIMEVALUE(csd) (1)
-#define SD20_CSD_TAC_TIMEUNIT(csd) (6)
-
-/* NSAC 111:104 = Data read access-time-2 in CLK cycle(NSAC*100) */
-
-#define MMCSD_CSD_NSAC(csd) (csd[2])
-#define SD20_CSD_NSAC(csd) (0)
-
-/* TRAN_SPEED 96-103 = Max. data transfer rate
- * TIME_VALUE 3-6 = Rate exponent
- * TRANSFER_RATE_UNIT 0-2 = Rate mantissa
- */
-
-#define MMCSD_CSD_TRANSPEED_TIMEVALUE(csd) ((csd[3] >> 3) & 0x0f)
-#define MMCSD_CSD_TRANSPEED_TRANSFERRATEUNIT(csd) (csd[3] & 7)
-
-#define SD20_CSD_TRANSPEED_TIMEVALUE(csd) MMCSD_CSD_TRANSPEED_TIMEVALUE(csd)
-#define SD20_CSD_TRANSPEED_TRANSFERRATEUNIT(csd) MMCSD_CSD_TRANSPEED_TRANSFERRATEUNIT(csd)
-
-/* CCC 84-95 = Card command classes */
-
-#define MMCSD_CSD_CCC(csd) (((uint16_t)csd[4] << 4) | ((uint16_t)csd[5] >> 4))
-#define SD20_CSD_CCC(csd) MMCSD_CSD_CCC(csd)
-
- /* READ_BL_LEN 80-83 = Max. read data block length */
-
-#define MMCSD_CSD_READBLLEN(csd) (csd[5] & 0x0f)
-#define SD20_CSD_READBLLEN(csd) (9)
-
-/* READ_BL_PARTIAL 79-79 = Partial blocks for read allowed */
-
-#define MMCSD_CSD_READBLPARTIAL(csd) (csd[6] >> 7)
-#define SD20_CSD_READBLPARTIAL(csd) (0)
-
-/* WRITE_BLK_MISALIGN 78-78 = Write block misalignment */
-
-#define MMCSD_CSD_WRITEBLKMISALIGN(csd) ((csd[6] >> 6) & 1)
-#define SD20_CSD_WRITEBLKMISALIGN(csd) (0)
-
-/* READ_BLK_MISALIGN 77:77 = Read block misalignment */
-
-#define MMCSD_CSD_READBLKMISALIGN(csd) ((csd[6] >> 5) & 1)
-#define SD20_CSD_READBLKMISALIGN(csd) (0)
-
-/* DSR_IMP 76-76 = DSR implemented */
-
-#define MMCSD_CSD_DSRIMP(csd) ((csd[6] >> 4) & 1)
-#define SD20_CSD_DSRIMP(csd) MMCSD_CSD_DSRIMP(csd)
-
-/* C_SIZE 62-73 Device size */
-
-#define MMCSD_CSD_CSIZE(csd) (((csd[6] & 3) << 10) | (csd[7] << 2) | (csd[8] >> 6))
-#define SD20_CSD_CSIZE(csd) ((((uint32_t)csd[7] & 0x3f) << 16) | (csd[8] << 8) | csd[9])
-
-/* VDD_R_CURR_MIN 59-61 = Max. read current at Vcc min */
-
-#define MMCSD_CSD_VDDRCURRMIN(csd) ((csd[8] >> 3) & 7)
-#define SD20_CSD_VDDRCURRMIN(csd) (7)
-
-/* VDD_R_CURR_MAX 56-58 = Max. read current at Vcc max */
-
-#define MMCSD_CSD_VDDRCURRMAX(csd) (csd[8] & 7)
-#define SD20_CSD_VDDRCURRMAX(csd) (6)
-
-/* VDD_W_CURR_MIN 53-55 = Max. write current at Vcc min */
-
-#define MMCSD_CSD_VDDWCURRMIN(csd) ((csd[9] >> 5) & 7)
-#define SD20_CSD_VDDWCURRMIN(csd) (7)
-
-/* VDD_W_CURR_MAX 50-52 = Max. write current at Vcc max */
-
-#define MMCSD_CSD_VDDWCURRMAX(csd) ((csd[9] >> 2) & 7)
-#define SD20_CSD_VDDWCURRMAX(csd) (6)
-
-/* C_SIZE_MULT 47-49 Device size multiplier */
-
-#define MMCSD_CSD_CSIZEMULT(csd) (((csd[9] & 3) << 1) | (csd[10] >> 7))
-#define SD20_CSD_CSIZEMULT(csd) (10-2)
-
-/* ER_BLK_EN 46-46 = Erase single block enable (SD) */
-
-#define SD_CSD_SDERBLKEN(csd) ((csd[10] >> 6) & 1)
-#define SD20_CSD_SDERBLKEN(csd) (1)
-
-/* SECTOR_SIZE 39-45 = Erase sector size (SD) */
-
-#define SD_CSD_SECTORSIZE(csd) (((csd[10] & 0x3f) << 1) | (csd[11] >> 7))
-#define SD20_CSD_SECTORSIZE(csd) (0x7f)
-
-/* SECTOR_SIZE 42-46 = Erase sector size (MMC) */
-
-#define MMC_CSD_SECTORSIZE(csd) ((csd[10] >> 2) & 0x1f)
-
-/* ER_GRP_SIZE 37-41 = Erase group size (MMC)*/
-
-#define MMC_CSD_ERGRPSIZE(csd) (((csd[10] & 3) << 3) | (csd[11] > 5))
-
-/* WP_GRP_SIZE 32-38 = Write protect group size (SD) */
-
-#define SD_CSD_WPGRPSIZE(csd) (csd[11] & 0x7f)
-#define SD20_CSD_WPGRPSIZE(csd) (0)
-
-/* WP_GRP_SIZE 32-36 = Write protect group size (MMC) */
-
-#define MMC_CSD_WPGRPSIZE(csd) (csd[11] & 0x1f)
-
-/* WP_GRP_EN 31-31 = Write protect group enable */
-
-#define MMCSD_WPGRPEN(csd) (csd[12] >> 7)
-#define SD20_WPGRPEN(csd) (0)
-
-/* DFLT_ECC 29-30 = Manufacturer default ECC (MMC) */
-
-#define MMC_CSD_DFLTECC(csd) ((csd[12] >> 5) & 3)
-
-/* R2W_FACTOR 26-28 = Write speed factor */
-
-#define MMCSD_CSD_R2WFACTOR(csd) ((csd[12] >> 2) & 7)
-#define SD20_CSD_R2WFACTOR(csd) (2)
-
-/* WRITE_BL_LEN 22-25 = Max. write data block length */
-
-#define MMCSD_CSD_WRITEBLLEN(csd) (((csd[12] & 3) << 2) | (csd[13] >> 6))
-#define SD20_CSD_WRITEBLLEN(csd) (9)
-
-/* WRITE_BL_PARTIAL 21-21 = Partial blocks for write allowed */
-
-#define MMCSD_CSD_WRITEBLPARTIAL(csd) ((csd[13] >> 5) & 1)
-#define SD20_CSD_WRITEBLPARTIAL(csd) (0)
-
-/* Reserved 16-20 */
-
-/* FILE_FORMAT_GROUP 15-15 = File format group */
-
-#define MMCSD_CSD_FILEFORMATGRP(csd) (csd[14] >> 7)
-#define SD20_CSD_FILEFORMATGRP(csd) (0)
-
-/* COPY 14-14 = Copy flag (OTP) */
-
-#define MMCSD_CSD_COPY(csd) ((csd[14] >> 6) & 1)
-#define SD20_CSD_COPY(csd) MMCSD_CSD_COPY(csd)
-
-/* PERM_WRITE_PROTECT 13-13 = Permanent write protection */
-
-#define MMCSD_CSD_PERMWRITEPROTECT(csd) ((csd[14] >> 5) & 1)
-#define SD20_CSD_PERMWRITEPROTECT(csd) MMCSD_CSD_PERMWRITEPROTECT(csd)
-
-/* TMP_WRITE_PROTECT 12-12 = Temporary write protection */
-
-#define MMCSD_CSD_TMPWRITEPROTECT(csd) ((csd[14] >> 4) & 1)
-#define SD20_CSD_TMPWRITEPROTECT(csd) MMCSD_CSD_TMPWRITEPROTECT(csd)
-
-/* FILE_FORMAT 10-11 = File format */
-
-#define MMCSD_CSD_FILEFORMAT(csd) ((csd[14] >> 2) & 3)
-#define SD20_CSD_FILEFORMAT(csd) (0)
-
-/* ECC 8-9 = ECC (MMC) */
-
-#define MMC_CSD_ECC(csd) (csd[14] & 3)
-
-/* CRC 1-7 = CRC */
-
-#define MMCSD_CSD_CRC(csd) (csd[15] >> 1)
-#define SD20_CSD_CRC(csd) MMCSD_CSD_CRC(csd)
-
-/* Reserved 0-0 */
-
-#endif /* CONFIG_MMCSD_BE16 */
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-#endif /* __DRIVERS_MMCSD_MMCSD_CSD_H */
diff --git a/nuttx/drivers/mmcsd/mmcsd_debug.c b/nuttx/drivers/mmcsd/mmcsd_debug.c
deleted file mode 100644
index 8cb5b2a2a..000000000
--- a/nuttx/drivers/mmcsd/mmcsd_debug.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/****************************************************************************
- * drivers/mmcsd/mmcsd_debug.c
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include "mmcsd_csd.h"
-#include "mmcsd_internal.h"
-
-/****************************************************************************
- * Pre-Processor Definitions
- ****************************************************************************/
-
-/* This needs to match the logic in include/debug.h */
-
-#ifdef CONFIG_CPP_HAVE_VARARGS
-# define message(format, arg...) syslog(format, ##arg)
-#else
-# define message syslog
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: mmcsd_dmpcsd
- *
- * Description:
- * Dump the contents of the CSD
- *
- ****************************************************************************/
-
-#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
-void mmcsd_dmpcsd(FAR const uint8_t *csd, uint8_t cardtype)
-{
- bool mmc = (cardtype == MMCSD_CARDTYPE_MMC);
- bool sd2 = (MMCSD_CSD_CSDSTRUCT(csd) == 1);
-
- fvdbg("CSD\n");
- fvdbg(" CSD_STRUCTURE: 1.%d\n", MMCSD_CSD_CSDSTRUCT(csd));
- if (mmc)
- {
- fvdbg(" MMC SPEC_VERS: %d\n", MMC_CSD_SPECVERS(csd));
- }
- fvdbg(" TAAC:\n",
- sd2 ? SD20_CSD_TAC_TIMEVALUE(csd) : MMCSD_CSD_TAAC_TIMEVALUE(csd));
- fvdbg(" TIME_VALUE: 0x%02x\n",
- sd2 ? SD20_CSD_TAC_TIMEVALUE(csd) : MMCSD_CSD_TAAC_TIMEVALUE(csd));
- fvdbg(" TIME_UNIT: 0x%02x\n",
- sd2 ? SD20_CSD_TAC_TIMEUNIT(csd) : MMCSD_CSD_TAAC_TIMEUNIT(csd));
- fvdbg(" NSAC: 0x%02x\n",
- sd2 ? SD20_CSD_NSAC(csd) : MMCSD_CSD_NSAC(csd));
- fvdbg(" TRAN_SPEED:\n");
- fvdbg(" TIME_VALUE: 0x%02x\n",
- sd2 ? SD20_CSD_TRANSPEED_TIMEVALUE(csd) : MMCSD_CSD_TRANSPEED_TIMEVALUE(csd));
- fvdbg(" RATE_UNIT: 0x%02x\n",
- sd2 ? SD20_CSD_TRANSPEED_TRANSFERRATEUNIT(csd) : MMCSD_CSD_TRANSPEED_TRANSFERRATEUNIT(csd));
- fvdbg(" CCC: 0x%03x\n",
- sd2 ? SD20_CSD_CCC(csd) : MMCSD_CSD_CCC(csd));
- fvdbg(" READ_BL_LEN: %d\n",
- sd2 ? SD20_CSD_READBLLEN(csd) : MMCSD_CSD_READBLLEN(csd));
- fvdbg(" READ_BL_PARTIAL: %d\n",
- sd2 ? SD20_CSD_READBLPARTIAL(csd) : MMCSD_CSD_READBLPARTIAL(csd));
- fvdbg(" WRITE_BLK_MISALIGN: %d\n",
- sd2 ? SD20_CSD_WRITEBLKMISALIGN(csd) : MMCSD_CSD_WRITEBLKMISALIGN(csd));
- fvdbg(" READ_BLK_MISALIGN: %d\n",
- sd2 ? SD20_CSD_READBLKMISALIGN(csd) : MMCSD_CSD_READBLKMISALIGN(csd));
- fvdbg(" DSR_IMP: %d\n",
- sd2 ? SD20_CSD_DSRIMP(csd) : MMCSD_CSD_DSRIMP(csd));
- fvdbg(" C_SIZE: %d\n",
- sd2 ? SD20_CSD_CSIZE(csd) : MMCSD_CSD_CSIZE(csd));
- fvdbg(" VDD_R_CURR_MIN: %d\n",
- sd2 ? SD20_CSD_VDDRCURRMIN(csd) : MMCSD_CSD_VDDRCURRMIN(csd));
- fvdbg(" VDD_R_CURR_MAX: %d\n",
- sd2 ? SD20_CSD_VDDRCURRMAX(csd) : MMCSD_CSD_VDDRCURRMAX(csd));
- fvdbg(" VDD_W_CURR_MIN: %d\n",
- sd2 ? SD20_CSD_VDDWCURRMIN(csd) : MMCSD_CSD_VDDWCURRMIN(csd));
- fvdbg(" VDD_W_CURR_MAX: %d\n",
- sd2 ? SD20_CSD_VDDWCURRMAX(csd) : MMCSD_CSD_VDDWCURRMAX(csd));
- fvdbg(" C_SIZE_MULT: %d\n",
- sd2 ? SD20_CSD_CSIZEMULT(csd) : MMCSD_CSD_CSIZEMULT(csd));
- if (mmc)
- {
- fvdbg(" MMC SECTOR_SIZE: %d\n", MMC_CSD_SECTORSIZE(csd));
- fvdbg(" MMC ER_GRP_SIZE: %d\n", MMC_CSD_ERGRPSIZE(csd));
- fvdbg(" MMC WP_GRP_SIZE: %d\n", MMC_CSD_WPGRPSIZE(csd));
- fvdbg(" MMC DFLT_ECC: %d\n", MMC_CSD_DFLTECC(csd));
- }
- else
- {
- fvdbg(" SD ER_BLK_EN: %d\n",
- sd2 ? SD20_CSD_SDERBLKEN(csd) : SD_CSD_SDERBLKEN(csd));
- fvdbg(" SD SECTOR_SIZE: %d\n",
- sd2 ? SD20_CSD_SECTORSIZE(csd) : SD_CSD_SECTORSIZE(csd));
- fvdbg(" SD WP_GRP_SIZE: %d\n",
- sd2 ? SD_CSD_WPGRPSIZE(csd) : SD_CSD_WPGRPSIZE(csd));
- }
- fvdbg(" WP_GRP_EN: %d\n",
- sd2 ? SD20_WPGRPEN(csd) : MMCSD_WPGRPEN(csd));
- fvdbg(" R2W_FACTOR: %d\n",
- sd2 ? SD20_CSD_R2WFACTOR(csd) : MMCSD_CSD_R2WFACTOR(csd));
- fvdbg(" WRITE_BL_LEN: %d\n",
- sd2 ? SD20_CSD_WRITEBLLEN(csd) : MMCSD_CSD_WRITEBLLEN(csd));
- fvdbg(" WRITE_BL_PARTIAL: %d\n",
- sd2 ? SD20_CSD_WRITEBLPARTIAL(csd) : MMCSD_CSD_WRITEBLPARTIAL(csd));
- fvdbg(" FILE_FORMAT_GROUP: %d\n",
- sd2 ? SD20_CSD_FILEFORMATGRP(csd) : MMCSD_CSD_FILEFORMATGRP(csd));
- fvdbg(" COPY: %d\n",
- sd2 ? SD20_CSD_COPY(csd) : MMCSD_CSD_COPY(csd));
- fvdbg(" PERM_WRITE_PROTECT: %d\n",
- sd2 ? SD20_CSD_PERMWRITEPROTECT(csd) : MMCSD_CSD_PERMWRITEPROTECT(csd));
- fvdbg(" TMP_WRITE_PROTECT: %d\n",
- sd2 ?SD20_CSD_TMPWRITEPROTECT(csd) : MMCSD_CSD_TMPWRITEPROTECT(csd));
- fvdbg(" FILE_FORMAT: %d\n",
- sd2 ? SD20_CSD_FILEFORMAT(csd) : MMCSD_CSD_FILEFORMAT(csd));
- if (mmc)
- {
- fvdbg(" MMC ECC: %d\n",
- sd2 ? MMC_CSD_ECC(csd) : MMC_CSD_ECC(csd));
- }
- fvdbg(" CRC: %02x\n",
- sd2 ? SD20_CSD_CRC(csd) : MMCSD_CSD_CRC(csd));
-}
-#endif
diff --git a/nuttx/drivers/mmcsd/mmcsd_internal.h b/nuttx/drivers/mmcsd/mmcsd_internal.h
deleted file mode 100644
index ed669cdfa..000000000
--- a/nuttx/drivers/mmcsd/mmcsd_internal.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
- * drivers/mmcsd/mmcsd_internal.h
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_MMCSD_MMCSD_INTERNAL_H
-#define __DRIVERS_MMCSD_MMCSD_INTERNAL_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <stdint.h>
-#include <debug.h>
-
-/****************************************************************************
- * Pre-Processor Definitions
- ****************************************************************************/
-
-/* Enable excessive debug options */
-
-#undef CONFIG_MMCSD_DUMPALL /* MUST BE DEFINED MANUALLY */
-
-#if !defined(CONFIG_DEBUG_VERBOSE) || !defined(CONFIG_DEBUG_FS)
-# undef CONFIG_MMCSD_DUMPALL
-#endif
-
-/* Card type */
-
-#define MMCSD_CARDTYPE_UNKNOWN 0 /* Unknown card type */
-#define MMCSD_CARDTYPE_MMC 1 /* Bit 0: MMC card */
-#define MMCSD_CARDTYPE_SDV1 2 /* Bit 1: SD version 1.x */
-#define MMCSD_CARDTYPE_SDV2 4 /* Bit 2: SD version 2.x with byte addressing */
-#define MMCSD_CARDTYPE_BLOCK 8 /* Bit 3: SD version 2.x with block addressing */
-
-#define IS_MMC(t) (((t) & MMCSD_CARDTYPE_MMC) != 0)
-#define IS_SD(t) (((t) & (MMCSD_CARDTYPE_SDV1|MMCSD_CARDTYPE_SDV2)) != 0)
-#define IS_SDV1(t) (((t) & MMCSD_CARDTYPE_SDV1) != 0)
-#define IS_SDV2(t) (((t) & MMCSD_CARDTYPE_SDV2) != 0)
-#define IS_BLOCK(t) (((t) & MMCSD_CARDTYPE_BLOCK) != 0)
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-#ifdef CONFIG_MMCSD_DUMPALL
-# define mmcsd_dumpbuffer(m,b,l) fvdbgdumpbuffer(m,b,l)
-#else
-# define mmcsd_dumpbuffer(m,b,l)
-#endif
-
-#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
-EXTERN void mmcsd_dmpcsd(FAR const uint8_t *csd, uint8_t cardtype);
-#else
-# define mmcsd_dmpcsd(csd,cadtype)
-#endif
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-#endif /* __DRIVERS_MMCSD_MMCSD_INTERNAL_H */
diff --git a/nuttx/drivers/mmcsd/mmcsd_sdio.c b/nuttx/drivers/mmcsd/mmcsd_sdio.c
deleted file mode 100644
index 3caa61583..000000000
--- a/nuttx/drivers/mmcsd/mmcsd_sdio.c
+++ /dev/null
@@ -1,3186 +0,0 @@
-/****************************************************************************
- * drivers/mmcsd/mmcsd_sdio.c
- *
- * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#if defined (CONFIG_MMCSD) && defined (CONFIG_MMCSD_SDIO)
-
-#include <nuttx/compiler.h>
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <semaphore.h>
-#include <debug.h>
-#include <errno.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/clock.h>
-#include <nuttx/arch.h>
-#include <nuttx/rwbuffer.h>
-#include <nuttx/sdio.h>
-#include <nuttx/mmcsd.h>
-
-#include "mmcsd_internal.h"
-#include "mmcsd_sdio.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* The maximum number of references on the driver (because a uint8_t is used.
- * Use a larger type if more references are needed.
- */
-
-#define MAX_CREFS 0xff
-
-/* Timing (all in units of microseconds) */
-
-#define MMCSD_POWERUP_DELAY ((useconds_t)250) /* 74 clock cycles @ 400KHz = 185uS */
-#define MMCSD_IDLE_DELAY ((useconds_t)50000) /* Short delay to allow change to IDLE state */
-#define MMCSD_DSR_DELAY ((useconds_t)100000) /* Time to wait after setting DSR */
-#define MMCSD_CLK_DELAY ((useconds_t)500000) /* Delay after changing clock speeds */
-
-/* Data delays (all in units of milliseconds).
- *
- * For MMC & SD V1.x, these should be based on Nac = TAAC + NSAC; The maximum
- * value of TAAC is 80MS and the maximum value of NSAC is 25.5K clock cycle.
- * For SD V2.x, a fixed delay of 100MS is recommend which is pretty close to
- * the worst case SD V1.x Nac. Here we just use 100MS delay for all data
- * transfers.
- */
-
-#define MMCSD_SCR_DATADELAY (100) /* Wait up to 100MS to get SCR */
-#define MMCSD_BLOCK_DATADELAY (100) /* Wait up to 100MS to get one data block */
-
-#define IS_EMPTY(priv) (priv->type == MMCSD_CARDTYPE_UNKNOWN)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This structure is contains the unique state of the MMC/SD block driver */
-
-struct mmcsd_state_s
-{
- FAR struct sdio_dev_s *dev; /* The SDIO device bound to this instance */
- uint8_t crefs; /* Open references on the driver */
- sem_t sem; /* Assures mutually exclusive access to the slot */
-
- /* Status flags */
-
- uint8_t probed:1; /* true: mmcsd_probe() discovered a card */
- uint8_t widebus:1; /* true: Wide 4-bit bus selected */
- uint8_t mediachanged:1; /* true: Media changed since last check */
- uint8_t wrbusy:1; /* true: Last transfer was a write, card may be busy */
- uint8_t wrprotect:1; /* true: Card is write protected (from CSD) */
- uint8_t locked:1; /* true: Media is locked (from R1) */
- uint8_t dsrimp:1; /* true: card supports CMD4/DSR setting (from CSD) */
-#ifdef CONFIG_SDIO_DMA
- uint8_t dma:1; /* true: hardware supports DMA */
-#endif
-
- uint8_t mode:2; /* (See MMCSDMODE_* definitions) */
- uint8_t type:4; /* Card type (See MMCSD_CARDTYPE_* definitions) */
- uint8_t buswidth:4; /* Bus widthes supported (SD only) */
- uint16_t selblocklen; /* The currently selected block length */
- uint16_t rca; /* Relative Card Address (RCS) register */
-
- /* Memory card geometry (extracted from the CSD) */
-
- uint8_t blockshift; /* Log2 of blocksize */
- uint16_t blocksize; /* Read block length (== block size) */
- uint32_t nblocks; /* Number of blocks */
-
-#ifdef CONFIG_HAVE_LONG_LONG
- uint64_t capacity; /* Total capacity of volume */
-#else
- uint32_t capacity; /* Total capacity of volume (Limited to 4Gb) */
-#endif
- /* Read-ahead and write buffering support */
-
-#if defined(CONFIG_FS_WRITEBUFFER) || defined(CONFIG_FS_READAHEAD)
- struct rwbuffer_s rwbuffer;
-#endif
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Misc Helpers *************************************************************/
-
-static void mmcsd_takesem(FAR struct mmcsd_state_s *priv);
-
-#ifndef CONFIG_SDIO_MUXBUS
-# define mmcsd_givesem(p) sem_post(&priv->sem);
-#endif
-
-/* Command/response helpers *************************************************/
-
-static int mmcsd_sendcmdpoll(FAR struct mmcsd_state_s *priv,
- uint32_t cmd, uint32_t arg);
-static int mmcsd_recvR1(FAR struct mmcsd_state_s *priv, uint32_t cmd);
-static int mmcsd_recvR6(FAR struct mmcsd_state_s *priv, uint32_t cmd);
-static int mmcsd_getSCR(FAR struct mmcsd_state_s *priv, uint32_t scr[2]);
-
-static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv,
- uint32_t csd[4]);
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
-static void mmcsd_decodeCID(FAR struct mmcsd_state_s *priv,
- uint32_t cid[4]);
-#else
-# define mmcsd_decodeCID(priv,cid)
-#endif
-static void mmcsd_decodeSCR(FAR struct mmcsd_state_s *priv,
- uint32_t scr[2]);
-
-static int mmcsd_getR1(FAR struct mmcsd_state_s *priv, FAR uint32_t *r1);
-static int mmcsd_verifystate(FAR struct mmcsd_state_s *priv,
- uint32_t status);
-
-/* Transfer helpers *********************************************************/
-
-#ifdef CONFIG_FS_WRITABLE
-static bool mmcsd_wrprotected(FAR struct mmcsd_state_s *priv);
-#endif
-static int mmcsd_eventwait(FAR struct mmcsd_state_s *priv,
- sdio_eventset_t failevents, uint32_t timeout);
-static int mmcsd_transferready(FAR struct mmcsd_state_s *priv);
-#ifndef CONFIG_MMCSD_MULTIBLOCK_DISABLE
-static int mmcsd_stoptransmission(FAR struct mmcsd_state_s *priv);
-#endif
-static int mmcsd_setblocklen(FAR struct mmcsd_state_s *priv,
- uint32_t blocklen);
-static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv,
- FAR uint8_t *buffer, off_t startblock);
-#ifndef CONFIG_MMCSD_MULTIBLOCK_DISABLE
-static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv,
- FAR uint8_t *buffer, off_t startblock, size_t nblocks);
-#endif
-#ifdef CONFIG_FS_READAHEAD
-static ssize_t mmcsd_reload(FAR void *dev, FAR uint8_t *buffer,
- off_t startblock, size_t nblocks);
-#endif
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv,
- FAR const uint8_t *buffer, off_t startblock);
-#ifndef CONFIG_MMCSD_MULTIBLOCK_DISABLE
-static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
- FAR const uint8_t *buffer, off_t startblock, size_t nblocks);
-#endif
-#ifdef CONFIG_FS_WRITEBUFFER
-static ssize_t mmcsd_flush(FAR void *dev, FAR const uint8_t *buffer,
- off_t startblock, size_t nblocks);
-#endif
-#endif
-
-/* Block driver methods *****************************************************/
-
-static int mmcsd_open(FAR struct inode *inode);
-static int mmcsd_close(FAR struct inode *inode);
-static ssize_t mmcsd_read(FAR struct inode *inode, FAR unsigned char *buffer,
- size_t startsector, unsigned int nsectors);
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t mmcsd_write(FAR struct inode *inode,
- FAR const unsigned char *buffer, size_t startsector,
- unsigned int nsectors);
-#endif
-static int mmcsd_geometry(FAR struct inode *inode,
- FAR struct geometry *geometry);
-static int mmcsd_ioctl(FAR struct inode *inode, int cmd,
- unsigned long arg);
-
-/* Initialization/uninitialization/reset ************************************/
-
-static void mmcsd_mediachange(FAR void *arg);
-static int mmcsd_widebus(FAR struct mmcsd_state_s *priv);
-#ifdef CONFIG_MMCSD_MMCSUPPORT
-static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv);
-#endif
-static int mmcsd_sdinitialize(FAR struct mmcsd_state_s *priv);
-static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv);
-static int mmcsd_probe(FAR struct mmcsd_state_s *priv);
-static int mmcsd_removed(FAR struct mmcsd_state_s *priv);
-static int mmcsd_hwinitialize(FAR struct mmcsd_state_s *priv);
-static void mmcsd_hwuninitialize(FAR struct mmcsd_state_s *priv);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct block_operations g_bops =
-{
- mmcsd_open, /* open */
- mmcsd_close, /* close */
- mmcsd_read, /* read */
-#ifdef CONFIG_FS_WRITABLE
- mmcsd_write, /* write */
-#else
- NULL, /* write */
-#endif
- mmcsd_geometry, /* geometry */
- mmcsd_ioctl /* ioctl */
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Misc Helpers
- ****************************************************************************/
-
-static void mmcsd_takesem(FAR struct mmcsd_state_s *priv)
-{
- /* Take the semaphore, giving exclusive access to the driver (perhaps
- * waiting)
- */
-
- while (sem_wait(&priv->sem) != 0)
- {
- /* The only case that an error should occur here is if the wait was
- * awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-
- /* Lock the bus if mutually exclusive access to the SDIO bus is required
- * on this platform.
- */
-
-#ifdef CONFIG_SDIO_MUXBUS
- SDIO_LOCK(priv->dev, TRUE);
-#endif
-}
-
-#ifdef CONFIG_SDIO_MUXBUS
-static void mmcsd_givesem(FAR struct mmcsd_state_s *priv)
-{
- /* Release the SDIO bus lock, then the MMC/SD driver semaphore in the
- * opposite order that they were taken to assure that no deadlock
- * conditions will arise.
- */
-
- SDIO_LOCK(priv->dev, FALSE);
- sem_post(&priv->sem);
-}
-#endif
-
-/****************************************************************************
- * Command/Response Helpers
- ****************************************************************************/
-
-/****************************************************************************
- * Name: mmcsd_sendcmdpoll
- *
- * Description:
- * Send a command and poll-wait for the response.
- *
- ****************************************************************************/
-
-static int mmcsd_sendcmdpoll(FAR struct mmcsd_state_s *priv, uint32_t cmd,
- uint32_t arg)
-{
- int ret;
-
- /* Send the command */
-
- ret = SDIO_SENDCMD(priv->dev, cmd, arg);
- if (ret == OK)
- {
- /* Then poll-wait until the response is available */
-
- ret = SDIO_WAITRESPONSE(priv->dev, cmd);
- if (ret != OK)
- {
- fdbg("ERROR: Wait for response to cmd: %08x failed: %d\n", cmd, ret);
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_sendcmd4
- *
- * Description:
- * Set the Driver Stage Register (DSR) if (1) a CONFIG_MMCSD_DSR has been
- * provided and (2) the card supports a DSR register. If no DSR value
- * the card default value (0x0404) will be used.
- *
- ****************************************************************************/
-
-static inline int mmcsd_sendcmd4(FAR struct mmcsd_state_s *priv)
-{
- int ret = OK;
-
-#ifdef CONFIG_MMCSD_DSR
- /* The dsr_imp bit from the CSD will tell us if the card supports setting
- * the DSR via CMD4 or not.
- */
-
- if (priv->dsrimp != false)
- {
- /* CMD4 = SET_DSR will set the cards DSR register. The DSR and CMD4
- * support are optional. However, since this is a broadcast command
- * with no response (like CMD0), we will never know if the DSR was
- * set correctly or not
- */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD4, CONFIG_MMCSD_DSR << 16);
- up_udelay(MMCSD_DSR_DELAY);
-
- /* Send it again to have more confidence */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD4, CONFIG_MMCSD_DSR << 16);
- up_udelay(MMCSD_DSR_DELAY);
- }
-#endif
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_recvR1
- *
- * Description:
- * Receive R1 response and check for errors.
- *
- ****************************************************************************/
-
-static int mmcsd_recvR1(FAR struct mmcsd_state_s *priv, uint32_t cmd)
-{
- uint32_t r1;
- int ret;
-
- /* Get the R1 response from the hardware */
-
- ret = SDIO_RECVR1(priv->dev, cmd, &r1);
- if (ret == OK)
- {
- /* Check if R1 reports an error */
-
- if ((r1 & MMCSD_R1_ERRORMASK) != 0)
- {
- /* Card locked is considered an error. Save the card locked
- * indication for later use.
- */
-
- fvdbg("ERROR: R1=%08x\n", r1);
- priv->locked = ((r1 & MMCSD_R1_CARDISLOCKED) != 0);
- ret = -EIO;
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_recvR6
- *
- * Description:
- * Receive R6 response and check for errors. On success, priv->rca is set
- * to the received RCA
- *
- ****************************************************************************/
-
-static int mmcsd_recvR6(FAR struct mmcsd_state_s *priv, uint32_t cmd)
-{
- uint32_t r6 = 0;
- int ret;
-
- /* R6 Published RCA Response (48-bit, SD card only)
- * 47 0 Start bit
- * 46 0 Transmission bit (0=from card)
- * 45:40 bit5 - bit0 Command index (0-63)
- * 39:8 bit31 - bit0 32-bit Argument Field, consisting of:
- * [31:16] New published RCA of card
- * [15:0] Card status bits {23,22,19,12:0}
- * 7:1 bit6 - bit0 CRC7
- * 0 1 End bit
- *
- * Get the R1 response from the hardware
- */
-
- ret = SDIO_RECVR6(priv->dev, cmd, &r6);
- if (ret == OK)
- {
- /* Check if R6 reports an error */
-
- if ((r6 & MMCSD_R6_ERRORMASK) == 0)
- {
- /* No, save the RCA and return success */
-
- priv->rca = (uint16_t)(r6 >> 16);
- return OK;
- }
-
- /* Otherwise, return an I/O failure */
-
- ret = -EIO;
- }
-
- fdbg("ERROR: Failed to get RCA. R6=%08x: %d\n", r6, ret);
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_getSCR
- *
- * Description:
- * Obtain the SD card's Configuration Register (SCR)
- *
- * Returned Value:
- * OK on success; a negated ernno on failure.
- *
- ****************************************************************************/
-
-static int mmcsd_getSCR(FAR struct mmcsd_state_s *priv, uint32_t scr[2])
-{
- int ret;
-
- /* Set Block Size To 8 Bytes */
-
- ret = mmcsd_setblocklen(priv, 8);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
- return ret;
- }
-
- /* Send CMD55 APP_CMD with argument as card's RCA */
-
- mmcsd_sendcmdpoll(priv, SD_CMD55, (uint32_t)priv->rca << 16);
- ret = mmcsd_recvR1(priv, SD_CMD55);
- if (ret != OK)
- {
- fdbg("ERROR: RECVR1 for CMD55 failed: %d\n", ret);
- return ret;
- }
-
- /* Setup up to receive data with interrupt mode */
-
- SDIO_BLOCKSETUP(priv->dev, 8, 1);
- SDIO_RECVSETUP(priv->dev, (FAR uint8_t*)scr, 8);
-
- /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 to start data receipt */
-
- (void)SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR);
- mmcsd_sendcmdpoll(priv, SD_ACMD51, 0);
- ret = mmcsd_recvR1(priv, SD_ACMD51);
- if (ret != OK)
- {
- fdbg("ERROR: RECVR1 for ACMD51 failed: %d\n", ret);
- SDIO_CANCEL(priv->dev);
- return ret;
- }
-
- /* Wait for data to be transferred */
-
- ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, MMCSD_SCR_DATADELAY);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_eventwait for READ DATA failed: %d\n", ret);
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_decodeCSD
- *
- * Description:
- * Decode and extract necessary information from the CSD. If debug is
- * enabled, then decode and show the full contents of the CSD.
- *
- * Returned Value:
- * OK on success; a negated ernno on failure. On success, the following
- * values will be set in the driver state structure:
- *
- * priv->dsrimp true: card supports CMD4/DSR setting (from CSD)
- * priv->wrprotect true: card is write protected (from CSD)
- * priv->blocksize Read block length (== block size)
- * priv->nblocks Number of blocks
- * priv->capacity Total capacity of volume
- *
- ****************************************************************************/
-
-static void mmcsd_decodeCSD(FAR struct mmcsd_state_s *priv, uint32_t csd[4])
-{
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
- struct mmcsd_csd_s decoded;
-#endif
- unsigned int readbllen;
- bool permwriteprotect;
- bool tmpwriteprotect;
-
- /* Word 1: Bits 127-96:
- *
- * CSD_STRUCTURE 127:126 CSD structure
- * SPEC_VERS 125:122 (MMC) Spec version
- * TAAC 119:112 Data read access-time-1
- * TIME_VALUE 6:3 Time mantissa
- * TIME_UNIT 2:0 Time exponent
- * NSAC 111:104 Data read access-time-2 in CLK cycle(NSAC*100)
- * TRAN_SPEED 103:96 Max. data transfer rate
- * TIME_VALUE 6:3 Rate exponent
- * TRANSFER_RATE_UNIT 2:0 Rate mantissa
- */
-
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
- memset(&decoded, 0, sizeof(struct mmcsd_csd_s));
- decoded.csdstructure = csd[0] >> 30;
- decoded.mmcspecvers = (csd[0] >> 26) & 0x0f;
- decoded.taac.timevalue = (csd[0] >> 19) & 0x0f;
- decoded.taac.timeunit = (csd[0] >> 16) & 7;
- decoded.nsac = (csd[0] >> 8) & 0xff;
- decoded.transpeed.timevalue = (csd[0] >> 3) & 0x0f;
- decoded.transpeed.transferrateunit = csd[0] & 7;
-#endif
-
- /* Word 2: Bits 64:95
- * CCC 95:84 Card command classes
- * READ_BL_LEN 83:80 Max. read data block length
- * READ_BL_PARTIAL 79:79 Partial blocks for read allowed
- * WRITE_BLK_MISALIGN 78:78 Write block misalignment
- * READ_BLK_MISALIGN 77:77 Read block misalignment
- * DSR_IMP 76:76 DSR implemented
- * Byte addressed SD and MMC:
- * C_SIZE 73:62 Device size
- * Block addressed SD:
- * 75:70 (reserved)
- * C_SIZE 48:69 Device size
- */
-
- priv->dsrimp = (csd[1] >> 12) & 1;
- readbllen = (csd[1] >> 16) & 0x0f;
-
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
- decoded.ccc = (csd[1] >> 20) & 0x0fff;
- decoded.readbllen = (csd[1] >> 16) & 0x0f;
- decoded.readblpartial = (csd[1] >> 15) & 1;
- decoded.writeblkmisalign = (csd[1] >> 14) & 1;
- decoded.readblkmisalign = (csd[1] >> 13) & 1;
- decoded.dsrimp = priv->dsrimp;
-#endif
-
- /* Word 3: Bits 32-63
- *
- * Byte addressed SD:
- * C_SIZE 73:62 Device size
- * VDD_R_CURR_MIN 61:59 Max. read current at Vcc min
- * VDD_R_CURR_MAX 58:56 Max. read current at Vcc max
- * VDD_W_CURR_MIN 55:53 Max. write current at Vcc min
- * VDD_W_CURR_MAX 52:50 Max. write current at Vcc max
- * C_SIZE_MULT 49:47 Device size multiplier
- * SD_ER_BLK_EN 46:46 Erase single block enable (SD only)
- * SD_SECTOR_SIZE 45:39 Erase sector size
- * SD_WP_GRP_SIZE 38:32 Write protect group size
- * Block addressed SD:
- * 75:70 (reserved)
- * C_SIZE 48:69 Device size
- * 47:47 (reserved)
- * SD_ER_BLK_EN 46:46 Erase single block enable (SD only)
- * SD_SECTOR_SIZE 45:39 Erase sector size
- * SD_WP_GRP_SIZE 38:32 Write protect group size
- * MMC:
- * C_SIZE 73:62 Device size
- * VDD_R_CURR_MIN 61:59 Max. read current at Vcc min
- * VDD_R_CURR_MAX 58:56 Max. read current at Vcc max
- * VDD_W_CURR_MIN 55:53 Max. write current at Vcc min
- * VDD_W_CURR_MAX 52:50 Max. write current at Vcc max
- * C_SIZE_MULT 49:47 Device size multiplier
- * MMC_SECTOR_SIZE 46:42 Erase sector size
- * MMC_ER_GRP_SIZE 41:37 Erase group size (MMC)
- * MMC_WP_GRP_SIZE 36:32 Write protect group size
- */
-
- if (IS_BLOCK(priv->type))
- {
- /* Block addressed SD:
- *
- * C_SIZE: 69:64 from Word 2 and 63:48 from Word 3
- *
- * 512 = (1 << 9)
- * 1024 = (1 << 10)
- * 512*1024 = (1 << 19)
- */
-
- uint32_t csize = ((csd[1] & 0x3f) << 16) | (csd[2] >> 16);
-#ifdef CONFIG_HAVE_LONG_LONG
- priv->capacity = ((uint64_t)(csize + 1)) << 19;
-#else
- priv->capacity = (csize + 1) << 19;
-#endif
- priv->blockshift = 9;
- priv->blocksize = 1 << 9;
- priv->nblocks = priv->capacity >> 9;
-
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
- decoded.u.sdblock.csize = csize;
- decoded.u.sdblock.sderblen = (csd[2] >> 14) & 1;
- decoded.u.sdblock.sdsectorsize = (csd[2] >> 7) & 0x7f;
- decoded.u.sdblock.sdwpgrpsize = csd[2] & 0x7f;
-#endif
- }
- else
- {
- /* Byte addressed SD:
- *
- * C_SIZE: 73:64 from Word 2 and 63:62 from Word 3
- */
-
- uint16_t csize = ((csd[1] & 0x03ff) << 2) | ((csd[2] >> 30) & 3);
- uint8_t csizemult = (csd[2] >> 15) & 7;
-
- priv->nblocks = ((uint32_t)csize + 1) * (1 << (csizemult + 2));
- priv->blockshift = readbllen;
- priv->blocksize = (1 << readbllen);
- priv->capacity = (priv->nblocks << readbllen);
-
- /* Some devices, such as 2Gb devices, report blocksizes larger than 512 bytes
- * but still expect to be accessed with a 512 byte blocksize.
- *
- * NOTE: A minor optimization would be to eliminated priv->blocksize and
- * priv->blockshift: Those values will be 512 and 9 in all cases anyway.
- */
-
- if (priv->blocksize > 512)
- {
- priv->nblocks <<= (priv->blockshift - 9);
- priv->blocksize = 512;
- priv->blockshift = 9;
- }
-
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
- if (IS_SD(priv->type))
- {
- decoded.u.sdbyte.csize = csize;
- decoded.u.sdbyte.vddrcurrmin = (csd[2] >> 27) & 7;
- decoded.u.sdbyte.vddrcurrmax = (csd[2] >> 24) & 7;
- decoded.u.sdbyte.vddwcurrmin = (csd[2] >> 21) & 7;
- decoded.u.sdbyte.vddwcurrmax = (csd[2] >> 18) & 7;
- decoded.u.sdbyte.csizemult = csizemult;
- decoded.u.sdbyte.sderblen = (csd[2] >> 14) & 1;
- decoded.u.sdbyte.sdsectorsize = (csd[2] >> 7) & 0x7f;
- decoded.u.sdbyte.sdwpgrpsize = csd[2] & 0x7f;
- }
-#ifdef CONFIG_MMCSD_MMCSUPPORT
- else if (IS_MMC(priv->type))
- {
- decoded.u.mmc.csize = csize;
- decoded.u.mmc.vddrcurrmin = (csd[2] >> 27) & 7;
- decoded.u.mmc.vddrcurrmax = (csd[2] >> 24) & 7;
- decoded.u.mmc.vddwcurrmin = (csd[2] >> 21) & 7;
- decoded.u.mmc.vddwcurrmax = (csd[2] >> 18) & 7;
- decoded.u.mmc.csizemult = csizemult;
- decoded.u.mmc.er.mmc22.sectorsize = (csd[2] >> 10) & 0x1f;
- decoded.u.mmc.er.mmc22.ergrpsize = (csd[2] >> 5) & 0x1f;
- decoded.u.mmc.mmcwpgrpsize = csd[2] & 0x1f;
- }
-#endif
-#endif
- }
-
- /* Word 4: Bits 0-31
- * WP_GRP_EN 31:31 Write protect group enable
- * MMC DFLT_ECC 30:29 Manufacturer default ECC (MMC only)
- * R2W_FACTOR 28:26 Write speed factor
- * WRITE_BL_LEN 25:22 Max. write data block length
- * WRITE_BL_PARTIAL 21:21 Partial blocks for write allowed
- * FILE_FORMAT_GROUP 15:15 File format group
- * COPY 14:14 Copy flag (OTP)
- * PERM_WRITE_PROTECT 13:13 Permanent write protection
- * TMP_WRITE_PROTECT 12:12 Temporary write protection
- * FILE_FORMAT 10:11 File format
- * ECC 9:8 ECC (MMC only)
- * CRC 7:1 CRC
- * Not used 0:0
- */
-
- permwriteprotect = (csd[3] >> 13) & 1;
- tmpwriteprotect = (csd[3] >> 12) & 1;
- priv->wrprotect = (permwriteprotect || tmpwriteprotect);
-
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
- decoded.wpgrpen = csd[3] >> 31;
- decoded.mmcdfltecc = (csd[3] >> 29) & 3;
- decoded.r2wfactor = (csd[3] >> 26) & 7;
- decoded.writebllen = (csd[3] >> 22) & 0x0f;
- decoded.writeblpartial = (csd[3] >> 21) & 1;
- decoded.fileformatgrp = (csd[3] >> 15) & 1;
- decoded.copy = (csd[3] >> 14) & 1;
- decoded.permwriteprotect = permwriteprotect;
- decoded.tmpwriteprotect = tmpwriteprotect;
- decoded.fileformat = (csd[3] >> 10) & 3;
- decoded.mmcecc = (csd[3] >> 8) & 3;
- decoded.crc = (csd[3] >> 1) & 0x7f;
-
- fvdbg("CSD:\n");
- fvdbg(" CSD_STRUCTURE: %d SPEC_VERS: %d (MMC)\n",
- decoded.csdstructure, decoded.mmcspecvers);
- fvdbg(" TAAC {TIME_UNIT: %d TIME_VALUE: %d} NSAC: %d\n",
- decoded.taac.timeunit, decoded.taac.timevalue, decoded.nsac);
- fvdbg(" TRAN_SPEED {TRANSFER_RATE_UNIT: %d TIME_VALUE: %d}\n",
- decoded.transpeed.transferrateunit, decoded.transpeed.timevalue);
- fvdbg(" CCC: %d\n", decoded.ccc);
- fvdbg(" READ_BL_LEN: %d READ_BL_PARTIAL: %d\n",
- decoded.readbllen, decoded.readblpartial);
- fvdbg(" WRITE_BLK_MISALIGN: %d READ_BLK_MISALIGN: %d\n",
- decoded.writeblkmisalign, decoded.readblkmisalign);
- fvdbg(" DSR_IMP: %d\n",
- decoded.dsrimp);
-
- if (IS_BLOCK(priv->type))
- {
- fvdbg(" SD Block Addressing:\n");
- fvdbg(" C_SIZE: %d SD_ER_BLK_EN: %d\n",
- decoded.u.sdblock.csize, decoded.u.sdblock.sderblen);
- fvdbg(" SD_SECTOR_SIZE: %d SD_WP_GRP_SIZE: %d\n",
- decoded.u.sdblock.sdsectorsize, decoded.u.sdblock.sdwpgrpsize);
- }
- else if (IS_SD(priv->type))
- {
- fvdbg(" SD Byte Addressing:\n");
- fvdbg(" C_SIZE: %d C_SIZE_MULT: %d\n",
- decoded.u.sdbyte.csize, decoded.u.sdbyte.csizemult);
- fvdbg(" VDD_R_CURR_MIN: %d VDD_R_CURR_MAX: %d\n",
- decoded.u.sdbyte.vddrcurrmin, decoded.u.sdbyte.vddrcurrmax);
- fvdbg(" VDD_W_CURR_MIN: %d VDD_W_CURR_MAX: %d\n",
- decoded.u.sdbyte.vddwcurrmin, decoded.u.sdbyte.vddwcurrmax);
- fvdbg(" SD_ER_BLK_EN: %d SD_SECTOR_SIZE: %d (SD) SD_WP_GRP_SIZE: %d\n",
- decoded.u.sdbyte.sderblen, decoded.u.sdbyte.sdsectorsize, decoded.u.sdbyte.sdwpgrpsize);
- }
-#ifdef CONFIG_MMCSD_MMCSUPPORT
- else if (IS_MMC(priv->type))
- {
- fvdbg(" MMC:\n");
- fvdbg(" C_SIZE: %d C_SIZE_MULT: %d\n",
- decoded.u.mmc.csize, decoded.u.mmc.csizemult);
- fvdbg(" VDD_R_CURR_MIN: %d VDD_R_CURR_MAX: %d\n",
- decoded.u.mmc.vddrcurrmin, decoded.u.mmc.vddrcurrmax);
- fvdbg(" VDD_W_CURR_MIN: %d VDD_W_CURR_MAX: %d\n",
- decoded.u.mmc.vddwcurrmin, decoded.u.mmc.vddwcurrmax);
- fvdbg(" MMC_SECTOR_SIZE: %d MMC_ER_GRP_SIZE: %d MMC_WP_GRP_SIZE: %d\n",
- decoded.u.mmc.er.mmc22.sectorsize, decoded.u.mmc.er.mmc22.ergrpsize,
- decoded.u.mmc.mmcwpgrpsize);
- }
-#endif
-
- fvdbg(" WP_GRP_EN: %d MMC DFLT_ECC: %d (MMC) R2W_FACTOR: %d\n",
- decoded.wpgrpen, decoded.mmcdfltecc, decoded.r2wfactor);
- fvdbg(" WRITE_BL_LEN: %d WRITE_BL_PARTIAL: %d\n",
- decoded.writebllen, decoded.writeblpartial);
- fvdbg(" FILE_FORMAT_GROUP: %d COPY: %d\n",
- decoded.fileformatgrp, decoded.copy);
- fvdbg(" PERM_WRITE_PROTECT: %d TMP_WRITE_PROTECT: %d\n",
- decoded.permwriteprotect, decoded.tmpwriteprotect);
- fvdbg(" FILE_FORMAT: %d ECC: %d (MMC) CRC: %d\n",
- decoded.fileformat, decoded.mmcecc, decoded.crc);
-
- fvdbg("Capacity: %luKb, Block size: %db, nblocks: %d wrprotect: %d\n",
- (unsigned long)(priv->capacity / 1024), priv->blocksize,
- priv->nblocks, priv->wrprotect);
-#endif
-}
-
-/****************************************************************************
- * Name: mmcsd_decodeCID
- *
- * Description:
- * Show the contents of the Card Indentification Data (CID) (for debug
- * purposes only)
- *
- ****************************************************************************/
-
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
-static void mmcsd_decodeCID(FAR struct mmcsd_state_s *priv, uint32_t cid[4])
-{
- struct mmcsd_cid_s decoded;
-
- /* Word 1: Bits 127-96:
- * mid - 127-120 8-bit Manufacturer ID
- * oid - 119-104 16-bit OEM/Application ID (ascii)
- * pnm - 103-64 40-bit Product Name (ascii) + null terminator
- * pnm[0] 103:96
- */
-
- decoded.mid = cid[0] >> 24;
- decoded.oid = (cid[0] >> 16) & 0xffff;
- decoded.pnm[0] = cid[0] & 0xff;
-
- /* Word 2: Bits 64:95
- * pnm - 103-64 40-bit Product Name (ascii) + null terminator
- * pnm[1] 95:88
- * pnm[2] 87:80
- * pnm[3] 79:72
- * pnm[4] 71:64
- */
-
- decoded.pnm[1] = cid[1] >> 24;
- decoded.pnm[2] = (cid[1] >> 16) & 0xff;
- decoded.pnm[3] = (cid[1] >> 8) & 0xff;
- decoded.pnm[4] = cid[1] & 0xff;
- decoded.pnm[5] = '\0';
-
- /* Word 3: Bits 32-63
- * prv - 63-56 8-bit Product revision
- * psn - 55-24 32-bit Product serial number
- */
-
- decoded.prv = cid[2] >> 24;
- decoded.psn = cid[2] << 8;
-
- /* Word 4: Bits 0-31
- * psn - 55-24 32-bit Product serial number
- * 23-20 4-bit (reserved)
- * mdt - 19:8 12-bit Manufacturing date
- * crc - 7:1 7-bit CRC7
- */
-
- decoded.psn |= cid[3] >> 24;
- decoded.mdt = (cid[3] >> 8) & 0x0fff;
- decoded.crc = (cid[3] >> 1) & 0x7f;
-
- fvdbg("mid: %02x oid: %04x pnm: %s prv: %d psn: %d mdt: %02x crc: %02x\n",
- decoded.mid, decoded.oid, decoded.pnm, decoded.prv,
- decoded.psn, decoded.mdt, decoded.crc);
-}
-#endif
-
-/****************************************************************************
- * Name: mmcsd_decodeSCR
- *
- * Description:
- * Show the contents of the SD Configuration Register (SCR). The only
- * value retained is: priv->buswidth;
- *
- ****************************************************************************/
-
-static void mmcsd_decodeSCR(FAR struct mmcsd_state_s *priv, uint32_t scr[2])
-{
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
-struct mmcsd_scr_s decoded;
-#endif
-
- /* Word 1, bits 63:32
- * SCR_STRUCTURE 63:60 4-bit SCR structure version
- * SD_VERSION 59:56 4-bit SD memory spec. version
- * DATA_STATE_AFTER_ERASE 55:55 1-bit erase status
- * SD_SECURITY 54:52 3-bit SD security support level
- * SD_BUS_WIDTHS 51:48 4-bit bus width indicator
- * Reserved 47:32 16-bit SD reserved space
- */
-
-#ifdef CONFIG_ENDIAN_BIG /* Card transfers SCR in big-endian order */
- priv->buswidth = (scr[0] >> 16) & 15;
-#else
- priv->buswidth = (scr[0] >> 8) & 15;
-#endif
-
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
-#ifdef CONFIG_ENDIAN_BIG /* Card SCR is big-endian order / CPU also big-endian
- * 60 56 52 48 44 40 36 32
- * VVVV SSSS ESSS BBBB RRRR RRRR RRRR RRRR */
- decoded.scrversion = scr[0] >> 28;
- decoded.sdversion = (scr[0] >> 24) & 15;
- decoded.erasestate = (scr[0] >> 23) & 1;
- decoded.security = (scr[0] >> 20) & 7;
-#else /* Card SCR is big-endian order / CPU is little-endian
- * 36 32 44 40 52 48 60 56
- * RRRR RRRR RRRR RRRR ESSS BBBB VVVV SSSS */
- decoded.scrversion = (scr[0] >> 4) & 15;
- decoded.sdversion = scr[0] & 15;
- decoded.erasestate = (scr[0] >> 15) & 1;
- decoded.security = (scr[0] >> 12) & 7;
-#endif
- decoded.buswidth = priv->buswidth;
-#endif
-
- /* Word 1, bits 63:32
- * Reserved 31:0 32-bits reserved for manufacturing usage.
- */
-
-#if defined(CONFIG_DEBUG) && defined (CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_FS)
- decoded.mfgdata = scr[1]; /* Might be byte reversed! */
-
- fvdbg("SCR:\n");
- fvdbg(" SCR_STRUCTURE: %d SD_VERSION: %d\n",
- decoded.scrversion,decoded.sdversion);
- fvdbg(" DATA_STATE_AFTER_ERASE: %d SD_SECURITY: %d SD_BUS_WIDTHS: %x\n",
- decoded.erasestate, decoded.security, decoded.buswidth);
- fvdbg(" Manufacturing data: %08x\n",
- decoded.mfgdata);
-#endif
-}
-
-/****************************************************************************
- * Name: mmcsd_getR1
- *
- * Description:
- * Get the R1 status of the card using CMD13
- *
- ****************************************************************************/
-
-static int mmcsd_getR1(FAR struct mmcsd_state_s *priv, FAR uint32_t *r1)
-{
- uint32_t localR1;
- int ret;
-
- DEBUGASSERT(priv != NULL && r1 != NULL);
-
- /* Send CMD13, SEND_STATUS. The addressed card responds by sending its
- * R1 card status register.
- */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD13, (uint32_t)priv->rca << 16);
- ret = SDIO_RECVR1(priv->dev, MMCSD_CMD13, &localR1);
- if (ret == OK)
- {
- /* Check if R1 reports an error */
-
- if ((localR1 & MMCSD_R1_ERRORMASK) != 0)
- {
- /* Card locked is considered an error. Save the card locked
- * indication for later use.
- */
-
- priv->locked = ((localR1 & MMCSD_R1_CARDISLOCKED) != 0);
- ret = -EIO;
- }
- else
- {
- /* No errors, return R1 */
-
- *r1 = localR1;
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_verifystate
- *
- * Description:
- * Verify that the card is in STANDBY state
- *
- ****************************************************************************/
-
-static int mmcsd_verifystate(FAR struct mmcsd_state_s *priv, uint32_t state)
-{
- uint32_t r1;
- int ret;
-
- /* Get the current R1 status from the card */
-
- ret = mmcsd_getR1(priv, &r1);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_getR1 failed: %d\n", ret);
- return ret;
- }
-
- /* Now check if the card is in the expected state. */
-
- if (IS_STATE(r1, state))
- {
- /* Yes.. return Success */
-
- priv->wrbusy = false;
- return OK;
- }
- return -EINVAL;
-}
-
-/****************************************************************************
- * Transfer Helpers
- ****************************************************************************/
-
-/****************************************************************************
- * Name: mmcsd_wrprotected
- *
- * Description:
- * Return true if the the card is unlocked an not write protected. The
- *
- *
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITABLE
-static bool mmcsd_wrprotected(FAR struct mmcsd_state_s *priv)
-{
- /* Check if the card is locked (priv->locked) or write protected either (1)
- * via software as reported via the CSD and retained in priv->wrprotect or
- * (2) via the mechanical write protect on the card (which we get from the
- * SDIO driver via SDIO_WRPROTECTED)
- */
-
- return (priv->wrprotect || priv->locked || SDIO_WRPROTECTED(priv->dev));
-}
-#endif
-
-/****************************************************************************
- * Name: mmcsd_eventwait
- *
- * Description:
- * Wait for the specified events to occur. Check for wakeup on error events.
- *
- ****************************************************************************/
-
-static int mmcsd_eventwait(FAR struct mmcsd_state_s *priv,
- sdio_eventset_t failevents, uint32_t timeout)
-{
- sdio_eventset_t wkupevent;
-
- /* Wait for the set of events enabled by SDIO_EVENTENABLE. */
-
- wkupevent = SDIO_EVENTWAIT(priv->dev, timeout);
-
- /* SDIO_EVENTWAIT returns the event set containing the event(s) that ended
- * the wait. It should always be non-zero, but may contain failure as
- * well as success events. Check if it contains any failure events.
- */
-
- if ((wkupevent & failevents) != 0)
- {
- /* Yes.. the failure event is probably SDIOWAIT_TIMEOUT */
-
- fdbg("ERROR: Awakened with %02x\n", wkupevent);
- return wkupevent & SDIOWAIT_TIMEOUT ? -ETIMEDOUT : -EIO;
- }
-
- /* Since there are no failure events, we must have been awakened by one
- * (or more) success events.
- */
-
- return OK;
-}
-
-/****************************************************************************
- * Name: mmcsd_transferready
- *
- * Description:
- * Check if the MMC/SD card is ready for the next read or write transfer.
- * Ready means: (1) card still in the slot, and (2) if the last transfer
- * was a write transfer, the card is no longer busy from that transfer.
- *
- ****************************************************************************/
-
-static int mmcsd_transferready(FAR struct mmcsd_state_s *priv)
-{
- uint32_t starttime;
- uint32_t elapsed;
- uint32_t r1;
- int ret;
-
- /* First, check if the card has been removed. */
-
- if (!SDIO_PRESENT(priv->dev))
- {
- fdbg("ERROR: Card has been removed\n");
- return -ENODEV;
- }
-
- /* If the last data transfer was not a write, then we do not have to check
- * the card status.
- */
-
- else if (!priv->wrbusy)
- {
- return OK;
- }
-
- /* The card is still present and the last transfer was a write transfer.
- * Loop, querying the card state. Return when (1) the card is in the TRANSFER
- * state, (2) the card stays in the PROGRAMMING state too long, or (3) the
- * card is in any other state.
- *
- * The PROGRAMMING state occurs normally after a WRITE operation. During this
- * time, the card may be busy completing the WRITE and is not available for
- * other operations. The card will transition from the PROGRAMMING state to
- * the TRANSFER state when the card completes the WRITE operation.
- */
-
- starttime = clock_systimer();
- do
- {
- /* Get the current R1 status from the card */
-
- ret = mmcsd_getR1(priv, &r1);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_getR1 failed: %d\n", ret);
- return ret;
- }
-
- /* Now check if the card is in the expected transfer state. */
-
- if (IS_STATE(r1, MMCSD_R1_STATE_TRAN))
- {
- /* Yes.. return Success */
-
- priv->wrbusy = false;
- return OK;
- }
-
- /* Check for the programming state. This is not an error. It means
- * that the card is still busy from the last (write) transfer.
- */
-
- else if (!IS_STATE(r1, MMCSD_R1_STATE_PRG))
- {
- /* Any other state would be an error in this context. There is
- * a possibility that the card is not selected. In this case,
- * it could be in STANDBY or DISCONNECTED state and the fix
- * might b to send CMD7 to re-select the card. Consider this
- * if this error occurs.
- */
-
- fdbg("ERROR: Unexpected R1 state: %08x\n", r1);
- return -EINVAL;
- }
-
- /* We are still in the programming state. Calculate the elapsed
- * time... we can't stay in this loop forever!
- */
-
- elapsed = clock_systimer() - starttime;
- }
- while (elapsed < TICK_PER_SEC);
- return -ETIMEDOUT;
-}
-
-/****************************************************************************
- * Name: mmcsd_stoptransmission
- *
- * Description:
- * Send STOP_TRANSMISSION
- *
- ****************************************************************************/
-
-#ifndef CONFIG_MMCSD_MULTIBLOCK_DISABLE
-static int mmcsd_stoptransmission(FAR struct mmcsd_state_s *priv)
-{
- int ret;
-
- /* Send CMD12, STOP_TRANSMISSION, and verify good R1 return status */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD12, 0);
- ret = mmcsd_recvR1(priv, MMCSD_CMD12);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_recvR1 for CMD12 failed: %d\n", ret);
- }
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Name: mmcsd_setblocklen
- *
- * Description:
- * Read a single block of data.
- *
- ****************************************************************************/
-
-static int mmcsd_setblocklen(FAR struct mmcsd_state_s *priv, uint32_t blocklen)
-{
- int ret = OK;
-
- /* Is the block length already selected in the card? */
-
- if (priv->selblocklen != blocklen)
- {
- /* Send CMD16 = SET_BLOCKLEN. This command sets the block length (in
- * bytes) for all following block commands (read and write). Default
- * block length is specified in the CSD.
- */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD16, blocklen);
- ret = mmcsd_recvR1(priv, MMCSD_CMD16);
- if (ret == OK)
- {
- priv->selblocklen = blocklen;
- }
- else
- {
- fdbg("ERROR: mmcsd_recvR1 for CMD16 failed: %d\n", ret);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_readsingle
- *
- * Description:
- * Read a single block of data.
- *
- ****************************************************************************/
-
-static ssize_t mmcsd_readsingle(FAR struct mmcsd_state_s *priv,
- FAR uint8_t *buffer, off_t startblock)
-{
- off_t offset;
- int ret;
-
- fvdbg("startblock=%d\n", startblock);
- DEBUGASSERT(priv != NULL && buffer != NULL);
-
- /* Check if the card is locked */
-
- if (priv->locked)
- {
- fdbg("ERROR: Card is locked\n");
- return -EPERM;
- }
-
- /* Verify that the card is ready for the transfer. The card may still be
- * busy from the preceding write transfer. It would be simpler to check
- * for write busy at the end of each write, rather than at the beginning of
- * each read AND write, but putting the busy-wait at the beginning of the
- * transfer allows for more overlap and, hopefully, better performance
- */
-
- ret = mmcsd_transferready(priv);
- if (ret != OK)
- {
- fdbg("ERROR: Card not ready: %d\n", ret);
- return ret;
- }
-
- /* If this is a byte addressed SD card, then convert sector start sector
- * number to a byte offset
- */
-
- if (IS_BLOCK(priv->type))
- {
- offset = startblock;
- }
- else
- {
- offset = startblock << priv->blockshift;
- }
- fvdbg("offset=%d\n", offset);
-
- /* Select the block size for the card */
-
- ret = mmcsd_setblocklen(priv, priv->blocksize);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
- return ret;
- }
-
- /* Configure SDIO controller hardware for the read transfer */
-
- SDIO_BLOCKSETUP(priv->dev, priv->blocksize, 1);
- SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR);
-#ifdef CONFIG_SDIO_DMA
- if (priv->dma)
- {
- SDIO_DMARECVSETUP(priv->dev, buffer, priv->blocksize);
- }
- else
-#endif
- {
- SDIO_RECVSETUP(priv->dev, buffer, priv->blocksize);
- }
-
- /* Send CMD17, READ_SINGLE_BLOCK: Read a block of the size selected
- * by the mmcsd_setblocklen() and verify that good R1 status is
- * returned. The card state should change from Transfer to Sending-Data
- * state.
- */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD17, offset);
- ret = mmcsd_recvR1(priv, MMCSD_CMD17);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_recvR1 for CMD17 failed: %d\n", ret);
- SDIO_CANCEL(priv->dev);
- return ret;
- }
-
- /* Then wait for the data transfer to complete */
-
- ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, MMCSD_BLOCK_DATADELAY);
- if (ret != OK)
- {
- fdbg("ERROR: CMD17 transfer failed: %d\n", ret);
- return ret;
- }
-
- /* Return value: One sector read */
-
- return 1;
-}
-
-/****************************************************************************
- * Name: mmcsd_readmultiple
- *
- * Description:
- * Read multiple, contiguous blocks of data from the physical device.
- *
- ****************************************************************************/
-
-#ifndef CONFIG_MMCSD_MULTIBLOCK_DISABLE
-static ssize_t mmcsd_readmultiple(FAR struct mmcsd_state_s *priv,
- FAR uint8_t *buffer, off_t startblock,
- size_t nblocks)
-{
- size_t nbytes;
- off_t offset;
- int ret;
-
- fvdbg("startblock=%d nblocks=%d\n", startblock, nblocks);
- DEBUGASSERT(priv != NULL && buffer != NULL && nblocks > 1);
-
- /* Check if the card is locked */
-
- if (priv->locked)
- {
- fdbg("ERROR: Card is locked\n");
- return -EPERM;
- }
-
- /* Verify that the card is ready for the transfer. The card may still be
- * busy from the preceding write transfer. It would be simpler to check
- * for write busy at the end of each write, rather than at the beginning of
- * each read AND write, but putting the busy-wait at the beginning of the
- * transfer allows for more overlap and, hopefully, better performance
- */
-
- ret = mmcsd_transferready(priv);
- if (ret != OK)
- {
- fdbg("ERROR: Card not ready: %d\n", ret);
- return ret;
- }
-
- /* If this is a byte addressed SD card, then convert both the total transfer
- * size to bytes and the sector start sector number to a byte offset
- */
-
- nbytes = nblocks << priv->blockshift;
- if (IS_BLOCK(priv->type))
- {
- offset = startblock;
- }
- else
- {
- offset = startblock << priv->blockshift;
- }
- fvdbg("nbytes=%d byte offset=%d\n", nbytes, offset);
-
- /* Select the block size for the card */
-
- ret = mmcsd_setblocklen(priv, priv->blocksize);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
- return ret;
- }
-
- /* Configure SDIO controller hardware for the read transfer */
-
- SDIO_BLOCKSETUP(priv->dev, priv->blocksize, nblocks);
- SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR);
-#ifdef CONFIG_SDIO_DMA
- if (priv->dma)
- {
- SDIO_DMARECVSETUP(priv->dev, buffer, nbytes);
- }
- else
-#endif
- {
- SDIO_RECVSETUP(priv->dev, buffer, nbytes);
- }
-
- /* Send CMD18, READ_MULT_BLOCK: Read a block of the size selected by
- * the mmcsd_setblocklen() and verify that good R1 status is returned
- */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD18, offset);
- ret = mmcsd_recvR1(priv, MMCSD_CMD18);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_recvR1 for CMD18 failed: %d\n", ret);
- SDIO_CANCEL(priv->dev);
- return ret;
- }
-
- /* Wait for the transfer to complete */
-
- ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, nblocks * MMCSD_BLOCK_DATADELAY);
- if (ret != OK)
- {
- fdbg("ERROR: CMD18 transfer failed: %d\n", ret);
- return ret;
- }
-
- /* Send STOP_TRANSMISSION */
-
- ret = mmcsd_stoptransmission(priv);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_stoptransmission failed: %d\n", ret);
- }
-
- /* On success, return the number of blocks read */
-
- return nblocks;
-}
-#endif
-
-/****************************************************************************
- * Name: mmcsd_reload
- *
- * Description:
- * Reload the specified number of sectors from the physical device into the
- * read-ahead buffer.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_FS_READAHEAD
-static ssize_t mmcsd_reload(FAR void *dev, FAR uint8_t *buffer,
- off_t startblock, size_t nblocks)
-{
- FAR struct mmcsd_state_s *priv = (FAR struct mmcsd_state_s *)dev;
-#ifdef CONFIG_MMCSD_MULTIBLOCK_DISABLE
- size_t block;
- size_t endblock;
-#endif
- ssize_t ret;
-
- DEBUGASSERT(priv != NULL && buffer != NULL && nblocks > 0)
-
-#ifdef CONFIG_MMCSD_MULTIBLOCK_DISABLE
- /* Read each block using only the single block transfer method */
-
- endblock = startblock + nblocks - 1;
- for (block = startblock; block <= endblock; block++)
- {
- /* Read this block into the user buffer */
-
- ret = mmcsd_readsingle(priv, buffer, block);
- if (ret < 0)
- {
- break;
- }
-
- /* Increment the buffer pointer by the block size */
-
- buffer += priv->blocksize;
- }
-#else
- /* Use either the single- or muliple-block transfer method */
-
- if (nblocks == 1)
- {
- ret = mmcsd_readsingle(priv, buffer, startblock);
- }
- else
- {
- ret = mmcsd_readmultiple(priv, buffer, startblock, nblocks);
- }
-#endif
-
- /* On success, return the number of blocks read */
-
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Name: mmcsd_writesingle
- *
- * Description:
- * Write a single block of data to the physical device.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t mmcsd_writesingle(FAR struct mmcsd_state_s *priv,
- FAR const uint8_t *buffer, off_t startblock)
-{
- off_t offset;
- int ret;
-
- fvdbg("startblock=%d\n", startblock);
- DEBUGASSERT(priv != NULL && buffer != NULL);
-
- /* Check if the card is locked or write protected (either via software or
- * via the mechanical write protect on the card)
- */
-
- if (mmcsd_wrprotected(priv))
- {
- fdbg("ERROR: Card is locked or write protected\n");
- return -EPERM;
- }
-
- /* Verify that the card is ready for the transfer. The card may still be
- * busy from the preceding write transfer. It would be simpler to check
- * for write busy at the end of each write, rather than at the beginning of
- * each read AND write, but putting the busy-wait at the beginning of the
- * transfer allows for more overlap and, hopefully, better performance
- */
-
- ret = mmcsd_transferready(priv);
- if (ret != OK)
- {
- fdbg("ERROR: Card not ready: %d\n", ret);
- return ret;
- }
-
- /* If this is a byte addressed SD card, then convert sector start sector
- * number to a byte offset
- */
-
- if (IS_BLOCK(priv->type))
- {
- offset = startblock;
- }
- else
- {
- offset = startblock << priv->blockshift;
- }
- fvdbg("offset=%d\n", offset);
-
- /* Select the block size for the card */
-
- ret = mmcsd_setblocklen(priv, priv->blocksize);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
- return ret;
- }
-
- /* Send CMD24, WRITE_BLOCK, and verify that good R1 status is returned */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD24, offset);
- ret = mmcsd_recvR1(priv, MMCSD_CMD24);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_recvR1 for CMD24 failed: %d\n", ret);
- return ret;
- }
-
- /* Configure SDIO controller hardware for the write transfer */
-
- SDIO_BLOCKSETUP(priv->dev, priv->blocksize, 1);
- SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR);
-#ifdef CONFIG_SDIO_DMA
- if (priv->dma)
- {
- SDIO_DMASENDSETUP(priv->dev, buffer, priv->blocksize);
- }
- else
-#endif
- {
- SDIO_SENDSETUP(priv->dev, buffer, priv->blocksize);
- }
-
- /* Flag that a write transfer is pending that we will have to check for
- * write complete at the beginning of the next transfer.
- */
-
- priv->wrbusy = true;
-
- /* Wait for the transfer to complete */
-
- ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, MMCSD_BLOCK_DATADELAY);
- if (ret != OK)
- {
- fdbg("ERROR: CMD24 transfer failed: %d\n", ret);
- return ret;
- }
-
- /* On success, return the number of blocks written */
-
- return 1;
-}
-#endif
-
-/****************************************************************************
- * Name: mmcsd_writemultiple
- *
- * Description:
- * Write multiple, contiguous blocks of data to the physical device.
- *
- ****************************************************************************/
-
-#if defined(CONFIG_FS_WRITABLE) && !defined(CONFIG_MMCSD_MULTIBLOCK_DISABLE)
-static ssize_t mmcsd_writemultiple(FAR struct mmcsd_state_s *priv,
- FAR const uint8_t *buffer, off_t startblock,
- size_t nblocks)
-{
- off_t offset;
- size_t nbytes;
- int ret;
-
- fvdbg("startblockr=%d nblocks=%d\n", startblock, nblocks);
- DEBUGASSERT(priv != NULL && buffer != NULL && nblocks > 1);
-
- /* Check if the card is locked or write protected (either via software or
- * via the mechanical write protect on the card)
- */
-
- if (mmcsd_wrprotected(priv))
- {
- fdbg("ERROR: Card is locked or write protected\n");
- return -EPERM;
- }
-
- /* Verify that the card is ready for the transfer. The card may still be
- * busy from the preceding write transfer. It would be simpler to check
- * for write busy at the end of each write, rather than at the beginning of
- * each read AND write, but putting the busy-wait at the beginning of the
- * transfer allows for more overlap and, hopefully, better performance
- */
-
- ret = mmcsd_transferready(priv);
- if (ret != OK)
- {
- fdbg("ERROR: Card not ready: %d\n", ret);
- return ret;
- }
-
- /* If this is a byte addressed SD card, then convert both the total transfer
- * size to bytes and the sector start sector number to a byte offset
- */
-
- nbytes = nblocks << priv->blockshift;
- if (IS_BLOCK(priv->type))
- {
- offset = startblock;
- }
- else
- {
- offset = startblock << priv->blockshift;
- }
- fvdbg("nbytes=%d byte offset=%d\n", nbytes, offset);
-
- /* Select the block size for the card */
-
- ret = mmcsd_setblocklen(priv, priv->blocksize);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_setblocklen failed: %d\n", ret);
- return ret;
- }
-
- /* If this is an SD card, then send ACMD23 (SET_WR_BLK_COUNT) just before
- * sending CMD25 (WRITE_MULTIPLE_BLOCK). This sets the number of write
- * blocks to be pre-erased and might make the following multiple block write
- * command faster.
- */
-
- if (IS_SD(priv->type))
- {
- /* Send CMD55, APP_CMD, a verify that good R1 status is retured */
-
- mmcsd_sendcmdpoll(priv, SD_CMD55, 0);
- ret = mmcsd_recvR1(priv, SD_CMD55);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_recvR1 for CMD55 (ACMD23) failed: %d\n", ret);
- return ret;
- }
-
- /* Send CMD23, SET_WR_BLK_COUNT, and verify that good R1 status is returned */
-
- mmcsd_sendcmdpoll(priv, SD_ACMD23, 0);
- ret = mmcsd_recvR1(priv, SD_ACMD23);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_recvR1 for ACMD23 failed: %d\n", ret);
- return ret;
- }
- }
-
- /* Send CMD25, WRITE_MULTIPLE_BLOCK, and verify that good R1 status
- * is returned
- */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD25, offset);
- ret = mmcsd_recvR1(priv, MMCSD_CMD25);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_recvR1 for CMD24 failed: %d\n", ret);
- return ret;
- }
-
- /* Configure SDIO controller hardware for the write transfer */
-
- SDIO_BLOCKSETUP(priv->dev, priv->blocksize, nblocks);
- SDIO_WAITENABLE(priv->dev, SDIOWAIT_TRANSFERDONE|SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR);
-#ifdef CONFIG_SDIO_DMA
- if (priv->dma)
- {
- SDIO_DMASENDSETUP(priv->dev, buffer, nbytes);
- }
- else
-#endif
- {
- SDIO_SENDSETUP(priv->dev, buffer, nbytes);
- }
-
- /* Flag that a write transfer is pending that we will have to check for
- * write complete at the beginning of the next transfer.
- */
-
- priv->wrbusy = true;
-
- /* Wait for the transfer to complete */
-
- ret = mmcsd_eventwait(priv, SDIOWAIT_TIMEOUT|SDIOWAIT_ERROR, nblocks * MMCSD_BLOCK_DATADELAY);
- if (ret != OK)
- {
- fdbg("ERROR: CMD18 transfer failed: %d\n", ret);
- return ret;
- }
-
- /* Send STOP_TRANSMISSION */
-
- ret = mmcsd_stoptransmission(priv);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_stoptransmission failed: %d\n", ret);
- return ret;
- }
-
- /* On success, return the number of blocks read */
-
- return nblocks;
-}
-#endif
-
-/****************************************************************************
- * Name: mmcsd_flush
- *
- * Description:
- * Flush the specified number of sectors from the write buffer to the card.
- *
- ****************************************************************************/
-
-#if defined(CONFIG_FS_WRITABLE) && defined(CONFIG_FS_WRITEBUFFER)
-static ssize_t mmcsd_flush(FAR void *dev, FAR const uint8_t *buffer,
- off_t startblock, size_t nblocks)
-{
- FAR struct mmcsd_state_s *priv = (FAR struct mmcsd_state_s *)dev;
-#ifndef CONFIG_MMCSD_MULTIBLOCK_DISABLE
- size_t block;
- size_t endblock;
-#endif
- ssize_t ret;
-
- DEBUGASSERT(priv != NULL && buffer != NULL && nblocks > 0)
-
-#ifdef CONFIG_MMCSD_MULTIBLOCK_DISABLE
- /* Write each block using only the single block transfer method */
-
- endblock = startblock + nblocks - 1;
- for (block = startblock; block <= endblock; block++)
- {
- /* Write this block from the user buffer */
-
- ret = mmcsd_writesingle(priv, buffer, block);
- if (ret < 0)
- {
- break;
- }
-
- /* Increment the buffer pointer by the block size */
-
- buffer += priv->blocksize;
- }
-#else
- if (nblocks == 1)
- {
- ret = mmcsd_writesingle(priv, buffer, startblock);
- }
- else
- {
- ret = mmcsd_writemultiple(priv, buffer, startblock, nblocks);
- }
-#endif
-
- /* On success, return the number of blocks written */
-
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Block Driver Methods
- ****************************************************************************/
-/****************************************************************************
- * Name: mmcsd_open
- *
- * Description: Open the block device
- *
- ****************************************************************************/
-
-static int mmcsd_open(FAR struct inode *inode)
-{
- FAR struct mmcsd_state_s *priv;
-
- fvdbg("Entry\n");
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct mmcsd_state_s *)inode->i_private;
-
- /* Just increment the reference count on the driver */
-
- DEBUGASSERT(priv->crefs < MAX_CREFS);
- mmcsd_takesem(priv);
- priv->crefs++;
- mmcsd_givesem(priv);
- return OK;
-}
-
-/****************************************************************************
- * Name: mmcsd_close
- *
- * Description: close the block device
- *
- ****************************************************************************/
-
-static int mmcsd_close(FAR struct inode *inode)
-{
- FAR struct mmcsd_state_s *priv;
-
- fvdbg("Entry\n");
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct mmcsd_state_s *)inode->i_private;
-
- /* Decrement the reference count on the block driver */
-
- DEBUGASSERT(priv->crefs > 0);
- mmcsd_takesem(priv);
- priv->crefs--;
- mmcsd_givesem(priv);
- return OK;
-}
-
-/****************************************************************************
- * Name: mmcsd_read
- *
- * Description:
- * Read the specified numer of sectors from the read-ahead buffer or from
- * the physical device.
- *
- ****************************************************************************/
-
-static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
- size_t startsector, unsigned int nsectors)
-{
- FAR struct mmcsd_state_s *priv;
-#if !defined(CONFIG_FS_READAHEAD) && defined(CONFIG_MMCSD_MULTIBLOCK_DISABLE)
- size_t sector;
- size_t endsector;
-#endif
- ssize_t ret = 0;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct mmcsd_state_s *)inode->i_private;
- fvdbg("startsector: %d nsectors: %d sectorsize: %d\n",
- startsector, nsectors, priv->blocksize);
-
- if (nsectors > 0)
- {
- mmcsd_takesem(priv);
-
-#if defined(CONFIG_FS_READAHEAD)
- /* Get the data from the read-ahead buffer */
-
- ret = rwb_read(&priv->rwbuffer, startsector, nsectors, buffer);
-
-#elif defined(CONFIG_MMCSD_MULTIBLOCK_DISABLE)
- /* Read each block using only the single block transfer method */
-
- endsector = startsector + nsectors - 1;
- for (sector = startsector; sector <= endsector; sector++)
- {
- /* Read this sector into the user buffer */
-
- ret = mmcsd_readsingle(priv, buffer, sector);
- if (ret < 0)
- {
- break;
- }
-
- /* Increment the buffer pointer by the sector size */
-
- buffer += priv->blocksize;
- }
-#else
- /* Use either the single- or muliple-block transfer method */
-
- if (nsectors == 1)
- {
- ret = mmcsd_readsingle(priv, buffer, startsector);
- }
- else
- {
- ret = mmcsd_readmultiple(priv, buffer, startsector, nsectors);
- }
-#endif
- mmcsd_givesem(priv);
- }
-
- /* On success, return the number of blocks read */
-
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_write
- *
- * Description:
- * Write the specified number of sectors to the write buffer or to the
- * physical device.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t mmcsd_write(FAR struct inode *inode, FAR const unsigned char *buffer,
- size_t startsector, unsigned int nsectors)
-{
- FAR struct mmcsd_state_s *priv;
-#if !defined(CONFIG_FS_WRITEBUFFER) && defined(CONFIG_MMCSD_MULTIBLOCK_DISABLE)
- size_t sector;
- size_t endsector;
-#endif
- ssize_t ret = 0;
-
- fvdbg("sector: %d nsectors: %d sectorsize: %d\n");
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct mmcsd_state_s *)inode->i_private;
-
- mmcsd_takesem(priv);
-
-#if defined(CONFIG_FS_WRITEBUFFER)
- /* Write the data to the write buffer */
-
- ret = rwb_write(&priv->rwbuffer, startsector, nsectors, buffer);
-
-#elif defined(CONFIG_MMCSD_MULTIBLOCK_DISABLE)
- /* Write each block using only the single block transfer method */
-
- endsector = startsector + nsectors - 1;
- for (sector = startsector; sector <= endsector; sector++)
- {
- /* Write this block from the user buffer */
-
- ret = mmcsd_writesingle(priv, buffer, sector);
- if (ret < 0)
- {
- break;
- }
-
- /* Increment the buffer pointer by the block size */
-
- buffer += priv->blocksize;
- }
-#else
- /* Use either the single- or multiple-block transfer method */
-
- if (nsectors == 1)
- {
- ret = mmcsd_writesingle(priv, buffer, startsector);
- }
- else
- {
- ret = mmcsd_writemultiple(priv, buffer, startsector, nsectors);
- }
-#endif
- mmcsd_givesem(priv);
-
- /* On success, return the number of blocks written */
-
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Name: mmcsd_geometry
- *
- * Description: Return device geometry
- *
- ****************************************************************************/
-
-static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
-{
- FAR struct mmcsd_state_s *priv;
- int ret = -EINVAL;
-
- fvdbg("Entry\n");
- DEBUGASSERT(inode && inode->i_private);
-
- if (geometry)
- {
- /* Is there a (supported) card inserted in the slot? */
-
- priv = (FAR struct mmcsd_state_s *)inode->i_private;
- mmcsd_takesem(priv);
- if (IS_EMPTY(priv))
- {
- /* No.. return ENODEV */
-
- fvdbg("IS_EMPTY\n");
- ret = -ENODEV;
- }
- else
- {
- /* Yes.. return the geometry of the card */
-
- geometry->geo_available = true;
- geometry->geo_mediachanged = priv->mediachanged;
-#ifdef CONFIG_FS_WRITABLE
- geometry->geo_writeenabled = !mmcsd_wrprotected(priv);
-#else
- geometry->geo_writeenabled = false;
-#endif
- geometry->geo_nsectors = priv->nblocks;
- geometry->geo_sectorsize = priv->blocksize;
-
- fvdbg("available: true mediachanged: %s writeenabled: %s\n",
- geometry->geo_mediachanged ? "true" : "false",
- geometry->geo_writeenabled ? "true" : "false");
- fvdbg("nsectors: %ld sectorsize: %d\n",
- (long)geometry->geo_nsectors, geometry->geo_sectorsize);
-
- priv->mediachanged = false;
- ret = OK;
- }
- mmcsd_givesem(priv);
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_ioctl
- *
- * Description: Return device geometry
- *
- ****************************************************************************/
-
-static int mmcsd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
-{
- FAR struct mmcsd_state_s *priv;
- int ret;
-
- fvdbg("Entry\n");
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct mmcsd_state_s *)inode->i_private;
-
- /* Process the IOCTL by command */
-
- mmcsd_takesem(priv);
- switch (cmd)
- {
- case BIOC_PROBE: /* Check for media in the slot */
- {
- fvdbg("BIOC_PROBE\n");
-
- /* Probe the MMC/SD slot for media */
-
- ret = mmcsd_probe(priv);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_probe failed: %d\n", ret);
- }
- }
- break;
-
- case BIOC_EJECT: /* Media has been removed from the slot */
- {
- fvdbg("BIOC_EJECT\n");
-
- /* Process the removal of the card */
-
- ret = mmcsd_removed(priv);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_removed failed: %d\n", ret);
- }
-
- /* Enable logic to detect if a card is re-inserted */
-
- SDIO_CALLBACKENABLE(priv->dev, SDIOMEDIA_INSERTED);
- }
- break;
-
- default:
- ret = -ENOTTY;
- break;
- }
-
- mmcsd_givesem(priv);
- return ret;
-}
-
-/****************************************************************************
- * Initialization/uninitialization/reset
- ****************************************************************************/
-
-/****************************************************************************
- * Name: mmcsd_mediachange
- *
- * Description:
- * This is a callback function from the SDIO driver that indicates that
- * there has been a change in the slot... either a card has been inserted
- * or a card has been removed.
- *
- * Assumptions:
- * This callback is NOT supposd to run in the context of an interrupt
- * handler; it is probably running in the context of work thread.
- *
- ****************************************************************************/
-
-static void mmcsd_mediachange(FAR void *arg)
-{
- FAR struct mmcsd_state_s *priv = (FAR struct mmcsd_state_s *)arg;
-
- fvdbg("arg: %p\n", arg);
- DEBUGASSERT(priv);
-
- /* Is there a card present in the slot? */
-
- mmcsd_takesem(priv);
- if (SDIO_PRESENT(priv->dev))
- {
- /* No... process the card insertion. This could cause chaos if we think
- * that a card is already present and there are mounted filesystems!
- * NOTE that mmcsd_probe() will always re-enable callbacks appropriately.
- */
-
- (void)mmcsd_probe(priv);
- }
- else
- {
- /* No... process the card removal. This could have very bad implications
- * for any mounted file systems! NOTE that mmcsd_removed() does NOT
- * re-enable callbacks so we will need to do that here.
- */
-
- (void)mmcsd_removed(priv);
-
- /* Enable logic to detect if a card is re-inserted */
-
- SDIO_CALLBACKENABLE(priv->dev, SDIOMEDIA_INSERTED);
- }
- mmcsd_givesem(priv);
-}
-
-/****************************************************************************
- * Name: mmcsd_widebus
- *
- * Description:
- * An SD card has been inserted and its SCR has been obtained. Select wide
- * (4-bit) bus operation if the card supports it.
- *
- * Assumptions:
- * This function is called only once per card insertion as part of the SD
- * card initialization sequence. It is not necessary to reselect the card
- * there is not need to check if wide bus operation has already been
- * selected.
- *
- ****************************************************************************/
-
-static int mmcsd_widebus(FAR struct mmcsd_state_s *priv)
-{
-#ifndef CONFIG_SDIO_WIDTH_D1_ONLY
- int ret;
-
- /* Check if the SD card supports this feature (as reported in the SCR) */
-
- if ((priv->buswidth & MMCSD_SCR_BUSWIDTH_4BIT) != 0)
- {
- /* Disconnect any CD/DAT3 pull up using ACMD42. ACMD42 is optional and
- * need not be supported by all SD calls.
- *
- * First end CMD55 APP_CMD with argument as card's RCA.
- */
-
- mmcsd_sendcmdpoll(priv, SD_CMD55, (uint32_t)priv->rca << 16);
- ret = mmcsd_recvR1(priv, SD_CMD55);
- if (ret != OK)
- {
- fdbg("ERROR: RECVR1 for CMD55 of ACMD42: %d\n", ret);
- return ret;
- }
-
- /* Then send ACMD42 with the argument to disconnect the CD/DAT3
- * pullup
- */
-
- mmcsd_sendcmdpoll(priv, SD_ACMD42, MMCSD_ACMD42_CD_DISCONNECT);
- ret = mmcsd_recvR1(priv, SD_ACMD42);
- if (ret != OK)
- {
- fvdbg("WARNING: SD card does not support ACMD42: %d\n", ret);
- return ret;
- }
-
- /* Now send ACMD6 to select wide, 4-bit bus operation, beginning
- * with CMD55, APP_CMD:
- */
-
- mmcsd_sendcmdpoll(priv, SD_CMD55, (uint32_t)priv->rca << 16);
- ret = mmcsd_recvR1(priv, SD_CMD55);
- if (ret != OK)
- {
- fdbg("ERROR: RECVR1 for CMD55 of ACMD6: %d\n", ret);
- return ret;
- }
-
- /* Then send ACMD6 */
-
- mmcsd_sendcmdpoll(priv, SD_ACMD6, MMCSD_ACMD6_BUSWIDTH_4);
- ret = mmcsd_recvR1(priv, SD_ACMD6);
- if (ret != OK)
- {
- return ret;
- }
-
- /* Configure the SDIO peripheral */
-
- fvdbg("Wide bus operation selected\n");
- SDIO_WIDEBUS(priv->dev, true);
- priv->widebus = true;
-
- SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_4BIT);
- up_udelay(MMCSD_CLK_DELAY);
- return OK;
- }
-
- /* Wide bus operation not supported */
-
- fdbg("WARNING: Card does not support wide-bus operation\n");
- return -ENOSYS;
-
-#else /* CONFIG_SDIO_WIDTH_D1_ONLY */
-
- fvdbg("Wide-bus operation is disabled\n");
- return -ENOSYS;
-
-#endif /* CONFIG_SDIO_WIDTH_D1_ONLY */
-}
-
-/****************************************************************************
- * Name: mmcsd_mmcinitialize
- *
- * Description:
- * We believe that there is an MMC card in the slot. Attempt to initialize
- * and configure the MMC card. This is called only from mmcsd_probe().
- *
- ****************************************************************************/
-
-#ifdef CONFIG_MMCSD_MMCSUPPORT
-static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv)
-{
- uint32_t cid[4];
- uint32_t csd[4];
- int ret;
-
- /* At this point, slow, ID mode clocking has been supplied to the card
- * and CMD0 has been sent successfully. CMD1 succeeded and ACMD41 failed
- * so there is good evidence that we have an MMC card inserted into the
- * slot.
- *
- * Send CMD2, ALL_SEND_CID. This implementation supports only one MMC slot.
- * If mulitple cards were installed, each card would respond to CMD2 by
- * sending its CID (only one card completes the response at a time). The
- * driver should send CMD2 and assign an RCAs until no response to
- * ALL_SEND_CID is received. CMD2 causes transition to identification state/
- * card-identification mode */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD2, 0);
- ret = SDIO_RECVR2(priv->dev, MMCSD_CMD2, cid);
- if (ret != OK)
- {
- fdbg("ERROR: SDIO_RECVR2 for MMC CID failed: %d\n", ret);
- return ret;
- }
- mmcsd_decodeCID(priv, cid);
-
- /* Send CMD3, SET_RELATIVE_ADDR. This command is used to assign a logical
- * address to the card. For MMC, the host assigns the address. CMD3 causes
- * transition to standby state/data-transfer mode
- */
-
- priv->rca = 1; /* There is only one card */
- mmcsd_sendcmdpoll(priv, MMC_CMD3, priv->rca << 16);
- ret = mmcsd_recvR1(priv, MMC_CMD3);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_recvR1(CMD3) failed: %d\n", ret);
- return ret;
- }
-
- /* This should have caused a transition to standby state. However, this will
- * not be reflected in the present R1 status. R1/6 contains the state of the
- * card when the command was received, not when it completed execution.
- *
- * Verify that we are in standby state/data-transfer mode
- */
-
- ret = mmcsd_verifystate(priv, MMCSD_R1_STATE_STBY);
- if (ret != OK)
- {
- fdbg("ERROR: Failed to enter standby state\n");
- return ret;
- }
-
- /* Send CMD9, SEND_CSD in standby state/data-transfer mode to obtain the
- * Card Specific Data (CSD) register, e.g., block length, card storage
- * capacity, etc. (Stays in standy state/data-transfer mode)
- */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD9, priv->rca << 16);
- ret = SDIO_RECVR2(priv->dev, MMCSD_CMD9, csd);
- if (ret != OK)
- {
- fdbg("ERROR: Could not get SD CSD register: %d\n", ret);
- return ret;
- }
- mmcsd_decodeCSD(priv, csd);
-
- /* Set the Driver Stage Register (DSR) if (1) a CONFIG_MMCSD_DSR has been
- * provided and (2) the card supports a DSR register. If no DSR value
- * the card default value (0x0404) will be used.
- */
-
- (void)mmcsd_sendcmd4(priv);
-
- /* Select high speed MMC clocking (which may depend on the DSR setting) */
-
- SDIO_CLOCK(priv->dev, CLOCK_MMC_TRANSFER);
- up_udelay(MMCSD_CLK_DELAY);
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Name: mmcsd_sdinitialize
- *
- * Description:
- * We believe that there is an SD card in the slot. Attempt to initialize
- * and configure the SD card. This is called only from mmcsd_probe().
- *
- ****************************************************************************/
-
-static int mmcsd_sdinitialize(FAR struct mmcsd_state_s *priv)
-{
- uint32_t cid[4];
- uint32_t csd[4];
- uint32_t scr[2];
- int ret;
-
- /* At this point, clocking has been supplied to the card, both CMD0 and
- * ACMD41 (with OCR=0) have been sent successfully, the card is no longer
- * busy and (presumably) in the IDLE state so there is good evidence
- * that we have an SD card inserted into the slot.
- *
- * Send CMD2, ALL_SEND_CID. The SD CMD2 is similar to the MMC CMD2 except
- * that the buffer type used to transmit to response of the card (SD Memory
- * Card: Push-Pull, MMC: Open-Drain). This implementation supports only a
- * single SD card. If multiple cards were installed in the slot, each card
- * would respond to CMD2 by sending its CID (only one card completes the
- * response at a time). The driver should send CMD2 and obtain RCAs until
- * no response to ALL_SEND_CID is received.
- *
- * When an SD card receives the CMD2 command it should transition to the
- * identification state/card-identification mode
- */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD2, 0);
- ret = SDIO_RECVR2(priv->dev, MMCSD_CMD2, cid);
- if (ret != OK)
- {
- fdbg("ERROR: SDIO_RECVR2 for SD CID failed: %d\n", ret);
- return ret;
- }
- mmcsd_decodeCID(priv, cid);
-
- /* Send CMD3, SET_RELATIVE_ADDR. In both protocols, this command is used
- * to assign a logical address to the card. For MMC, the host assigns the
- * address; for SD, the memory card has this responsibility. CMD3 causes
- * transition to standby state/data-transfer mode
- *
- * Send CMD3 with argument 0, SD card publishes its RCA in the response.
- */
-
- mmcsd_sendcmdpoll(priv, SD_CMD3, 0);
- ret = mmcsd_recvR6(priv, SD_CMD3);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_recvR2 for SD RCA failed: %d\n", ret);
- return ret;
- }
- fvdbg("RCA: %04x\n", priv->rca);
-
- /* This should have caused a transition to standby state. However, this will
- * not be reflected in the present R1 status. R1/6 contains the state of
- * the card when the command was received, not when it completed execution.
- *
- * Verify that we are in standby state/data-transfer mode
- */
-
- ret = mmcsd_verifystate(priv, MMCSD_R1_STATE_STBY);
- if (ret != OK)
- {
- fdbg("ERROR: Failed to enter standby state\n");
- return ret;
- }
-
- /* Send CMD9, SEND_CSD, in standby state/data-transfer mode to obtain the
- * Card Specific Data (CSD) register. The argument is the RCA that we
- * just obtained from CMD3. The card stays in standy state/data-transfer
- * mode.
- */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD9, (uint32_t)priv->rca << 16);
- ret = SDIO_RECVR2(priv->dev, MMCSD_CMD9, csd);
- if (ret != OK)
- {
- fdbg("ERROR: Could not get SD CSD register(%d)\n", ret);
- return ret;
- }
- mmcsd_decodeCSD(priv, csd);
-
- /* Send CMD7 with the argument == RCA in order to select the card.
- * Since we are supporting only a single card, we just leave the
- * card selected all of the time.
- */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD7S, (uint32_t)priv->rca << 16);
- ret = mmcsd_recvR1(priv, MMCSD_CMD7S);
- if (ret != OK)
- {
- fdbg("ERROR: mmcsd_recvR1 for CMD7 failed: %d\n", ret);
- return ret;
- }
-
- /* Set the Driver Stage Register (DSR) if (1) a CONFIG_MMCSD_DSR has been
- * provided and (2) the card supports a DSR register. If no DSR value
- * the card default value (0x0404) will be used.
- */
-
- (void)mmcsd_sendcmd4(priv);
-
- /* Select high speed SD clocking (which may depend on the DSR setting) */
-
- SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_1BIT);
- up_udelay(MMCSD_CLK_DELAY);
-
- /* Get the SD card Configuration Register (SCR). We need this now because
- * that configuration register contains the indication whether or not
- * this card supports wide bus operation.
- */
-
- ret = mmcsd_getSCR(priv, scr);
- if (ret != OK)
- {
- fdbg("ERROR: Could not get SD SCR register(%d)\n", ret);
- return ret;
- }
- mmcsd_decodeSCR(priv, scr);
-
- /* Select width (4-bit) bus operation (if the card supports it) */
-
- ret = mmcsd_widebus(priv);
- if (ret != OK)
- {
- fdbg("WARN: Failed to set wide bus operation: %d\n", ret);
- }
-
- /* TODO: If widebus selected, then send CMD6 to see if the card supports
- * high speed mode. A new SDIO method will be needed to set high speed
- * mode.
- */
-
- return OK;
-}
-
-/****************************************************************************
- * Name: mmcsd_cardidentify
- *
- * Description:
- * We believe that there is media in the slot. Attempt to initialize and
- * configure the card. This is called only from mmcsd_probe().
- *
- ****************************************************************************/
-
-static int mmcsd_cardidentify(FAR struct mmcsd_state_s *priv)
-{
- uint32_t response;
- uint32_t start;
- uint32_t elapsed;
- uint32_t sdcapacity = MMCSD_ACMD41_STDCAPACITY;
- int ret;
-
- /* Assume failure to identify the card */
-
- priv->type = MMCSD_CARDTYPE_UNKNOWN;
-
- /* Check if there is a card present in the slot. This is normally a matter is
- * of GPIO sensing.
- */
-
- if (!SDIO_PRESENT(priv->dev))
- {
- fvdbg("No card present\n");
- return -ENODEV;
- }
-
- /* Set ID mode clocking (<400KHz) */
-
- SDIO_CLOCK(priv->dev, CLOCK_IDMODE);
-
- /* After power up at least 74 clock cycles are required prior to starting bus
- * communication
- */
-
- up_udelay(MMCSD_POWERUP_DELAY);
-
- /* Then send CMD0 (twice just to be sure) */
-
- mmcsd_sendcmdpoll(priv, MMCSD_CMD0, 0);
- mmcsd_sendcmdpoll(priv, MMCSD_CMD0, 0);
- up_udelay(MMCSD_IDLE_DELAY);
-
- /* Check for SDHC Version 2.x. Send CMD8 to verify SD card interface
- * operating condition. CMD 8 is reserved on SD version 1.0 and MMC.
- *
- * CMD8 Argument:
- * [31:12]: Reserved (shall be set to '0')
- * [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
- * [7:0]: Check Pattern (recommended 0xaa)
- * CMD8 Response: R7
- */
-
- ret = mmcsd_sendcmdpoll(priv, SD_CMD8, MMCSD_CMD8CHECKPATTERN|MMCSD_CMD8VOLTAGE_27);
- if (ret == OK)
- {
- /* CMD8 was sent successfully... Get the R7 response */
-
- ret = SDIO_RECVR7(priv->dev, SD_CMD8, &response);
- }
-
- /* Were both the command sent and response received correctly? */
-
- if (ret == OK)
- {
- /* CMD8 succeeded this is probably a SDHC card. Verify the operating
- * voltage and that the check pattern was correctly echoed
- */
-
- if (((response & MMCSD_R7VOLTAGE_MASK) == MMCSD_R7VOLTAGE_27) &&
- ((response & MMCSD_R7ECHO_MASK) == MMCSD_R7CHECKPATTERN))
- {
- fvdbg("SD V2.x card\n");
- priv->type = MMCSD_CARDTYPE_SDV2;
- sdcapacity = MMCSD_ACMD41_HIGHCAPACITY;
- }
- else
- {
- fdbg("ERROR: R7: %08x\n", response);
- return -EIO;
- }
- }
-
- /* At this point, type is either UNKNOWN or SDV2. Try sending
- * CMD55 and (maybe) ACMD41 for up to 1 second or until the card
- * exits the IDLE state. CMD55 is supported by SD V1.x and SD V2.x,
- * but not MMC
- */
-
- start = clock_systimer();
- elapsed = 0;
- do
- {
- /* We may have already determined that his card is an MMC card from
- * an earlier pass through through this loop. In that case, we should
- * skip the SD-specific commands.
- */
-
-#ifdef CONFIG_MMCSD_MMCSUPPORT
- if (priv->type != MMCSD_CARDTYPE_MMC)
-#endif
- {
- /* Send CMD55 with argument = 0 */
-
- mmcsd_sendcmdpoll(priv, SD_CMD55, 0);
- ret = mmcsd_recvR1(priv, SD_CMD55);
- if (ret != OK)
- {
- /* I am a little confused.. I think both SD and MMC cards support
- * CMD55 (but maybe only SD cards support CMD55). We'll make the
- * the MMC vs. SD decision based on CMD1 and ACMD41.
- */
-
- fdbg("ERROR: mmcsd_recvR1(CMD55) failed: %d\n", ret);
- }
- else
- {
- /* Send ACMD41 */
-
- mmcsd_sendcmdpoll(priv, SD_ACMD41, MMCSD_ACMD41_VOLTAGEWINDOW|sdcapacity);
- ret = SDIO_RECVR3(priv->dev, SD_ACMD41, &response);
- if (ret != OK)
- {
- /* If the error is a timeout, then it is probably an MMC card,
- * but we will make the decision based on CMD1 below
- */
-
- fdbg("ERROR: ACMD41 RECVR3: %d\n", ret);
- }
- else
- {
- /* ACMD41 succeeded. ACMD41 is supported by SD V1.x and SD V2.x,
- * but not MMC. If we did not previously determine that this is
- * an SD V2.x (via CMD8), then this must be SD V1.x
- */
-
- fvdbg("R3: %08x\n", response);
- if (priv->type == MMCSD_CARDTYPE_UNKNOWN)
- {
- fvdbg("SD V1.x card\n");
- priv->type = MMCSD_CARDTYPE_SDV1;
- }
-
- /* Check if the card is busy. Very confusing, BUSY is set LOW
- * if the card has not finished its initialization, so it really
- * means NOT busy.
- */
-
- if ((response & MMCSD_CARD_BUSY) != 0)
- {
- /* No.. We really should check the current state to see if
- * the SD card successfully made it to the IDLE state, but
- * at least for now, we will simply assume that that is the
- * case.
- *
- * Now, check if this is a SD V2.x card that supports block
- * addressing
- */
-
- if ((response & MMCSD_R3_HIGHCAPACITY) != 0)
- {
- fvdbg("SD V2.x card with block addressing\n");
- DEBUGASSERT(priv->type == MMCSD_CARDTYPE_SDV2);
- priv->type |= MMCSD_CARDTYPE_BLOCK;
- }
-
- /* And break out of the loop with an SD card identified */
-
- break;
- }
- }
- }
- }
-
- /* If we get here then either (1) CMD55 failed, (2) CMD41 failed, or (3)
- * and SD or MMC card has been identified, but it is not yet in the IDLE state.
- * If SD card has not been identified, then we might be looking at an
- * MMC card. We can send the CMD1 to find out for sure. CMD1 is supported
- * by MMC cards, but not by SD cards.
- */
-#ifdef CONFIG_MMCSD_MMCSUPPORT
- if (priv->type == MMCSD_CARDTYPE_UNKNOWN || priv->type == MMCSD_CARDTYPE_MMC)
- {
- /* Send the MMC CMD1 to specify the operating voltage. CMD1 causes
- * transition to ready state/ card-identification mode. NOTE: If the
- * card does not support this voltage range, it will go the inactive
- * state.
- *
- * NOTE: An MMC card will only respond once to CMD1 (unless it is busy).
- * This is part of the logic used to determine how many MMC cards are
- * connected (This implementation supports only a single MMC card). So
- * we cannot re-send CMD1 without first placing the card back into
- * stand-by state (if the card is busy, it will automatically
- * go back to the the standby state).
- */
-
- mmcsd_sendcmdpoll(priv, MMC_CMD1, MMCSD_VDD_33_34);
- ret = SDIO_RECVR3(priv->dev, MMC_CMD1, &response);
-
- /* Was the operating range set successfully */
-
- if (ret != OK)
- {
- fdbg("ERROR: CMD1 RECVR3: %d\n", ret);
- }
- else
- {
- /* CMD1 succeeded... this must be an MMC card */
-
- fdbg("CMD1 succeeded, assuming MMC card\n");
- priv->type = MMCSD_CARDTYPE_MMC;
-
- /* Check if the card is busy. Very confusing, BUSY is set LOW
- * if the card has not finished its initialization, so it really
- * means NOT busy.
- */
-
- if ((response & MMCSD_CARD_BUSY) != 0)
- {
- /* NO.. We really should check the current state to see if the
- * MMC successfully made it to the IDLE state, but at least for now,
- * we will simply assume that that is the case.
- *
- * Then break out of the look with an MMC card identified
- */
-
- break;
- }
- }
- }
-#endif
- /* Check the elapsed time. We won't keep trying this forever! */
-
- elapsed = clock_systimer() - start;
- }
- while( elapsed < TICK_PER_SEC ); /* On successful reception while 'breaks', see above. */
-
- /* We get here when the above loop completes, either (1) we could not
- * communicate properly with the card due to errors (and the loop times
- * out), or (3) it is an MMC or SD card that has successfully transitioned
- * to the IDLE state (well, at least, it provided its OCR saying that it
- * it is no longer busy).
- */
-
- if (elapsed >= TICK_PER_SEC || priv->type == MMCSD_CARDTYPE_UNKNOWN)
- {
- fdbg("ERROR: Failed to identify card\n");
- return -EIO;
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: mmcsd_probe
- *
- * Description:
- * Check for media inserted in a slot. Called (1) during initialization to
- * see if there was a card in the slot at power up, (2) when/if a media
- * insertion event occurs, or (3) if the BIOC_PROBE ioctl command is
- * received.
- *
- ****************************************************************************/
-
-static int mmcsd_probe(FAR struct mmcsd_state_s *priv)
-{
- int ret;
-
- fvdbg("type: %d probed: %d\n", priv->type, priv->probed);
-
- /* If we have reliable card detection events and if we have
- * already probed the card, then we don't need to do anything
- * else
- */
-
-#ifdef CONFIG_MMCSD_HAVECARDDETECT
- if (priv->probed && SDIO_PRESENT(priv->dev))
- {
- return OK;
- }
-#endif
-
- /* Otherwise, we are going to probe the card. There are lots of
- * possibilities here: We may think that there is a card in the slot,
- * or not. There may be a card in the slot, or not. If there is
- * card in the slot, perhaps it is a different card than we one we
- * think is there? The safest thing to do is to process the card
- * removal first and start from known place.
- */
-
- mmcsd_removed(priv);
-
- /* Now.. is there a card in the slot? */
-
- if (SDIO_PRESENT(priv->dev))
- {
- /* Yes.. probe it. First, what kind of card was inserted? */
-
- ret = mmcsd_cardidentify(priv);
- if (ret != OK)
- {
- fdbg("ERROR: Failed to initialize card: %d\n", ret);
-#ifdef CONFIG_MMCSD_HAVECARDDETECT
- SDIO_CALLBACKENABLE(priv->dev, SDIOMEDIA_INSERTED);
-#endif
- }
- else
- {
- /* Then initialize the driver according to the identified card type */
-
- switch (priv->type)
- {
- case MMCSD_CARDTYPE_SDV1: /* Bit 1: SD version 1.x */
- case MMCSD_CARDTYPE_SDV2: /* SD version 2.x with byte addressing */
- case MMCSD_CARDTYPE_SDV2|MMCSD_CARDTYPE_BLOCK: /* SD version 2.x with block addressing */
- ret = mmcsd_sdinitialize(priv);
- break;
-
- case MMCSD_CARDTYPE_MMC: /* MMC card */
-#ifdef CONFIG_MMCSD_MMCSUPPORT
- ret = mmcsd_mmcinitialize(priv);
- break;
-#endif
- case MMCSD_CARDTYPE_UNKNOWN: /* Unknown card type */
- default:
- fdbg("ERROR: Internal confusion: %d\n", priv->type);
- ret = -EPERM;
- break;
- };
-
- /* Was the card configured successfully? */
-
- if (ret == OK)
- {
- /* Yes... */
-
- fvdbg("Capacity: %lu Kbytes\n", (unsigned long)(priv->capacity / 1024));
- priv->mediachanged = true;
-
- /* Set up to receive asynchronous, media removal events */
-
- SDIO_CALLBACKENABLE(priv->dev, SDIOMEDIA_EJECTED);
- }
- }
-
- /* In any event, we have probed this card */
-
- priv->probed = true;
- }
- else
- {
- /* There is no card in the slot */
-
- fvdbg("No card\n");
-#ifdef CONFIG_MMCSD_HAVECARDDETECT
- SDIO_CALLBACKENABLE(priv->dev, SDIOMEDIA_INSERTED);
-#endif
- ret = -ENODEV;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_removed
- *
- * Description:
- * Disable support for media in the slot. Called (1) when/if a media
- * removal event occurs, or (2) if the BIOC_EJECT ioctl command is
- * received.
- *
- ****************************************************************************/
-
-static int mmcsd_removed(FAR struct mmcsd_state_s *priv)
-{
- fvdbg("type: %d present: %d\n", priv->type, SDIO_PRESENT(priv->dev));
-
- /* Forget the card geometry, pretend the slot is empty (it might not
- * be), and that the card has never been initialized.
- */
-
- priv->capacity = 0; /* Capacity=0 sometimes means no media */
- priv->blocksize = 0;
- priv->mediachanged = false;
- priv->type = MMCSD_CARDTYPE_UNKNOWN;
- priv->probed = false;
- priv->rca = 0;
- priv->selblocklen = 0;
-
- /* Go back to the default 1-bit data bus. */
-
- SDIO_WIDEBUS(priv->dev, false);
- priv->widebus = false;
-
- /* Disable clocking to the card */
-
- (void)SDIO_CLOCK(priv->dev, CLOCK_SDIO_DISABLED);
- return OK;
-}
-
-/****************************************************************************
- * Name: mmcsd_hwinitialize
- *
- * Description:
- * One-time hardware initialization. Called only from sdio_slotinitialize.
- *
- ****************************************************************************/
-
-static int mmcsd_hwinitialize(FAR struct mmcsd_state_s *priv)
-{
- int ret;
-
- mmcsd_takesem(priv);
-
-#ifdef CONFIG_SDIO_DMA
- /* Does this architecture support DMA with the MMC/SD device? */
-
- priv->dma = SDIO_DMASUPPORTED(priv->dev);
- fvdbg("DMA supported: %d\n", priv->dma);
-#endif
-
- /* Attach and prepare MMC/SD interrupts */
-
- if (SDIO_ATTACH(priv->dev))
- {
- fdbg("ERROR: Unable to attach MMC/SD interrupts\n");
- mmcsd_givesem(priv);
- return -EBUSY;
- }
- fvdbg("Attached MMC/SD interrupts\n");
-
- /* Register a callback so that we get informed if media is inserted or
- * removed from the slot (Initially all callbacks are disabled).
- */
-
- SDIO_REGISTERCALLBACK(priv->dev, mmcsd_mediachange, (FAR void *)priv);
-
- /* Is there a card in the slot now? For an MMC/SD card, there are three
- * possible card detect mechanisms:
- *
- * 1. Mechanical insertion that can be detected using the WP switch
- * that is closed when a card is inserted into then SD slot (SD
- * "hot insertion capable" card conector only)
- * 2. Electrical insertion that can be sensed using the pull-up resistor
- * on CD/DAT3 (both SD/MMC),
- * 3. Or by periodic attempts to initialize the card from software.
- *
- * The behavior of SDIO_PRESENT() is to use whatever information is available
- * on the particular platform. If no card insertion information is available
- * (polling only), then SDIO_PRESENT() will always return true and we will
- * try to initialize the card.
- */
-
- if (SDIO_PRESENT(priv->dev))
- {
- /* Yes... probe for a card in the slot */
-
- ret = mmcsd_probe(priv);
- if (ret != OK)
- {
- fvdbg("Slot not empty, but initialization failed: %d\n", ret);
-
- /* NOTE: The failure to initialize a card does not mean that
- * initialization has failed! A card could be installed in the slot
- * at a later time. ENODEV is return in this case,
- * sdio_slotinitialize will use this return value to set up the
- * card inserted callback event.
- */
-
- ret = -ENODEV;
- }
- }
- else
- {
- /* ENODEV is returned to indicate that no card is inserted in the slot.
- * sdio_slotinitialize will use this return value to set up the card
- * inserted callback event.
- */
-
- ret = -ENODEV;
- }
-
- /* OK is returned only if the slot initialized correctly AND the card in
- * the slot was successfully configured.
- */
-
- mmcsd_givesem(priv);
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_hwuninitialize
- *
- * Description:
- * Restore the MMC/SD slot to the uninitialized state. Called only from
- * sdio_slotinitialize on a failure to initialize.
- *
- ****************************************************************************/
-
-static void mmcsd_hwuninitialize(FAR struct mmcsd_state_s *priv)
-{
- if (priv)
- {
- mmcsd_removed(priv);
- SDIO_RESET(priv->dev);
- kfree(priv);
- }
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: mmcsd_slotinitialize
- *
- * Description:
- * Initialize one slot for operation using the MMC/SD interface
- *
- * Input Parameters:
- * minor - The MMC/SD minor device number. The MMC/SD device will be
- * registered as /dev/mmcsdN where N is the minor number
- * dev - And instance of an MMC/SD interface. The MMC/SD hardware should
- * be initialized and ready to use.
- *
- ****************************************************************************/
-
-int mmcsd_slotinitialize(int minor, FAR struct sdio_dev_s *dev)
-{
- FAR struct mmcsd_state_s *priv;
- char devname[16];
- int ret = -ENOMEM;
-
- fvdbg("minor: %d\n", minor);
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (minor < 0 || minor > 255 || !dev)
- {
- return -EINVAL;
- }
-#endif
-
- /* Allocate a MMC/SD state structure */
-
- priv = (FAR struct mmcsd_state_s *)kmalloc(sizeof(struct mmcsd_state_s));
- if (priv)
- {
- /* Initialize the MMC/SD state structure */
-
- memset(priv, 0, sizeof(struct mmcsd_state_s));
- sem_init(&priv->sem, 0, 1);
-
- /* Bind the MMCSD driver to the MMCSD state structure */
-
- priv->dev = dev;
-
- /* Initialize the hardware associated with the slot */
-
- ret = mmcsd_hwinitialize(priv);
-
- /* Was the slot initialized successfully? */
-
- if (ret != OK)
- {
- /* No... But the error ENODEV is returned if hardware initialization
- * succeeded but no card is inserted in the slot. In this case, the
- * no error occurred, but the driver is still not ready.
- */
-
- if (ret == -ENODEV)
- {
- /* No card in the slot (or if there is, we could not recognize
- * it).. Setup to receive the media inserted event
- */
-
- SDIO_CALLBACKENABLE(priv->dev, SDIOMEDIA_INSERTED);
-
- fdbg("MMC/SD slot is empty\n");
- }
- else
- {
- /* Some other non-recoverable bad thing happened */
-
- fdbg("ERROR: Failed to initialize MMC/SD slot: %d\n", ret);
- goto errout_with_alloc;
- }
- }
-
- /* Initialize buffering */
-
-#if defined(CONFIG_FS_WRITEBUFFER) || defined(CONFIG_FS_READAHEAD)
-
- ret = rwb_initialize(&priv->rwbuffer);
- if (ret < 0)
- {
- fdbg("ERROR: Buffer setup failed: %d\n", ret);
- goto errout_with_hwinit;
- }
-#endif
-
- /* Create a MMCSD device name */
-
- snprintf(devname, 16, "/dev/mmcsd%d", minor);
-
- /* Inode private data is a reference to the MMCSD state structure */
-
- ret = register_blockdriver(devname, &g_bops, 0, priv);
- if (ret < 0)
- {
- fdbg("ERROR: register_blockdriver failed: %d\n", ret);
- goto errout_with_buffers;
- }
- }
- return OK;
-
-errout_with_buffers:
-#if defined(CONFIG_FS_WRITEBUFFER) || defined(CONFIG_FS_READAHEAD)
- rwb_uninitialize(&priv->rwbuffer);
-errout_with_hwinit:
-#endif
- mmcsd_hwuninitialize(priv); /* This will free the private data structure */
- return ret;
-
-errout_with_alloc:
- kfree(priv);
- return ret;
-}
-
-#endif /* defined (CONFIG_MMCSD) && defined (CONFIG_MMCSD_SDIO) */
diff --git a/nuttx/drivers/mmcsd/mmcsd_sdio.h b/nuttx/drivers/mmcsd/mmcsd_sdio.h
deleted file mode 100644
index 9e3794e25..000000000
--- a/nuttx/drivers/mmcsd/mmcsd_sdio.h
+++ /dev/null
@@ -1,339 +0,0 @@
-/********************************************************************************************
- * drivers/mmcsd/mmcsd_sdio.h
- *
- * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ********************************************************************************************/
-
-#ifndef __DRIVERS_MMCSD_MMCSD_SDIO_H
-#define __DRIVERS_MMCSD_MMCSD_SDIO_H
-
-/********************************************************************************************
- * Included Files
- ********************************************************************************************/
-
-#include <nuttx/config.h>
-#include <stdint.h>
-
-/********************************************************************************************
- * Pre-Processor Definitions
- ********************************************************************************************/
-
-/* CMD8 Argument:
- * [31:12]: Reserved (shall be set to '0')
- * [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
- * [7:0]: Check Pattern (recommended 0xaa)
- * CMD8 Response: R7
- */
-
-#define MMCSD_CMD8VOLTAGE_SHIFT (8) /* Bits 8-11: Supply voltage */
-#define MMCSD_CMD8VOLTAGE_MASK ((uint32_t)0x0f << MMCSD_CMD8VOLTAGE_SHIFT)
-# define MMCSD_CMD8VOLTAGE_27 ((uint32_t)0x01 << MMCSD_CMD8VOLTAGE_SHIFT) /* 2.7-3.6V */
-#define MMCSD_CMD8ECHO_SHIFT (0) /* Bits 0-7: Check pattern */
-#define MMCSD_CMD8ECHO_MASK ((uint32_t)0xff << MMCSD_CMD8ECHO_SHIFT)
-# define MMCSD_CMD8CHECKPATTERN ((uint32_t)0xaa << MMCSD_CMD8ECHO_SHIFT)
-
-/* ACMD6 argument */
-
-#define MMCSD_ACMD6_BUSWIDTH_1 ((uint32_t)0) /* Bus width = 1-bit */
-#define MMCSD_ACMD6_BUSWIDTH_4 ((uint32_t)2) /* Bus width = 4-bit */
-
-/* ACMD41 argument */
-
-#define MMCSD_ACMD41_VOLTAGEWINDOW ((uint32_t)0x80100000)
-#define MMCSD_ACMD41_HIGHCAPACITY ((uint32_t)1 << 30)
-#define MMCSD_ACMD41_STDCAPACITY ((uint32_t)0)
-
-/* ACMD42 argument */
-
-#define MMCSD_ACMD42_CD_DISCONNECT ((uint32_t)0) /* Disconnect card detection logic */
-#define MMCSD_ACMD42_CD_CONNECT ((uint32_t)1) /* Connect card detection logic */
-
-/* R1 Card Status bit definitions */
-
-#define MMCSD_R1_OUTOFRANGE ((uint32_t)1 << 31) /* Bad argument */
-#define MMCSD_R1_ADDRESSERROR ((uint32_t)1 << 30) /* Bad address */
-#define MMCSD_R1_BLOCKLENERROR ((uint32_t)1 << 29) /* Bad block length */
-#define MMCSD_R1_ERASESEQERROR ((uint32_t)1 << 28) /* Erase cmd error */
-#define MMCSD_R1_ERASEPARAM ((uint32_t)1 << 27) /* Bad write blocks */
-#define MMCSD_R1_WPVIOLATION ((uint32_t)1 << 26) /* Erase access failure */
-#define MMCSD_R1_CARDISLOCKED ((uint32_t)1 << 25) /* Card is locked */
-#define MMCSD_R1_LOCKUNLOCKFAILED ((uint32_t)1 << 24) /* Password error */
-#define MMCSD_R1_COMCRCERROR ((uint32_t)1 << 23) /* CRC error */
-#define MMCSD_R1_ILLEGALCOMMAND ((uint32_t)1 << 22) /* Bad command */
-#define MMCSD_R1_CARDECCFAILED ((uint32_t)1 << 21) /* Failed to correct data */
-#define MMCSD_R1_CCERROR ((uint32_t)1 << 20) /* Card controller error */
-#define MMCSD_R1_ERROR ((uint32_t)1 << 19) /* General error */
-#define MMCSD_R1_UNDERRUN ((uint32_t)1 << 18) /* Underrun (MMC only) */
-#define MMCSD_R1_OVERRRUN ((uint32_t)1 << 17) /* Overrun (MMC only) */
-#define MMCSD_R1_CIDCSDOVERWRITE ((uint32_t)1 << 16) /* CID/CSD error */
-#define MMCSD_R1_WPERASESKIP ((uint32_t)1 << 15) /* Not all erased */
-#define MMCSD_R1_CARDECCDISABLED ((uint32_t)1 << 14) /* Internal ECC not used */
-#define MMCSD_R1_ERASERESET ((uint32_t)1 << 13) /* Reset sequence cleared */
-#define MMCSD_R1_STATE_SHIFT (9) /* Current card state */
-#define MMCSD_R1_STATE_MASK ((uint32_t)15 << MMCSD_R1_STATE_SHIFT)
- /* Card identification mode states */
-# define MMCSD_R1_STATE_IDLE ((uint32_t)0 << MMCSD_R1_STATE_SHIFT) /* 0=Idle state */
-# define MMCSD_R1_STATE_READY ((uint32_t)1 << MMCSD_R1_STATE_SHIFT) /* 1=Ready state */
-# define MMCSD_R1_STATE_IDENT ((uint32_t)2 << MMCSD_R1_STATE_SHIFT) /* 2=Identification state */
- /* Data transfer states */
-# define MMCSD_R1_STATE_STBY ((uint32_t)3 << MMCSD_R1_STATE_SHIFT) /* 3=Standby state */
-# define MMCSD_R1_STATE_TRAN ((uint32_t)4 << MMCSD_R1_STATE_SHIFT) /* 4=Transfer state */
-# define MMCSD_R1_STATE_DATA ((uint32_t)5 << MMCSD_R1_STATE_SHIFT) /* 5=Sending data state */
-# define MMCSD_R1_STATE_RCV ((uint32_t)6 << MMCSD_R1_STATE_SHIFT) /* 6=Receiving data state */
-# define MMCSD_R1_STATE_PRG ((uint32_t)7 << MMCSD_R1_STATE_SHIFT) /* 7=Programming state */
-# define MMCSD_R1_STATE_DIS ((uint32_t)8 << MMCSD_R1_STATE_SHIFT) /* 8=Disconnect state */
-#define MMCSD_R1_READYFORDATA ((uint32_t)1 << 8) /* Buffer empty */
-#define MMCSD_R1_APPCMD ((uint32_t)1 << 5) /* Next CMD is ACMD */
-#define MMCSD_R1_AKESEQERROR ((uint32_t)1 << 3) /* Authentication error */
-#define MMCSD_R1_ERRORMASK ((uint32_t)0xfdffe008) /* Error mask */
-
-#define IS_STATE(v,s) ((((uint32_t)v)&MMCSD_R1_STATE_MASK)==(s))
-
-/* R3 (OCR) */
-
-#define MMC_VDD_20_36 ((uint32_t)0x00ffff00) /* VDD voltage 2.0-3.6 */
-
-#define MMCSD_VDD_145_150 ((uint32_t)1 << 0) /* VDD voltage 1.45 - 1.50 */
-#define MMCSD_VDD_150_155 ((uint32_t)1 << 1) /* VDD voltage 1.50 - 1.55 */
-#define MMCSD_VDD_155_160 ((uint32_t)1 << 2) /* VDD voltage 1.55 - 1.60 */
-#define MMCSD_VDD_160_165 ((uint32_t)1 << 3) /* VDD voltage 1.60 - 1.65 */
-#define MMCSD_VDD_165_170 ((uint32_t)1 << 4) /* VDD voltage 1.65 - 1.70 */
-#define MMCSD_VDD_17_18 ((uint32_t)1 << 5) /* VDD voltage 1.7 - 1.8 */
-#define MMCSD_VDD_18_19 ((uint32_t)1 << 6) /* VDD voltage 1.8 - 1.9 */
-#define MMCSD_VDD_19_20 ((uint32_t)1 << 7) /* VDD voltage 1.9 - 2.0 */
-#define MMCSD_VDD_20_21 ((uint32_t)1 << 8) /* VDD voltage 2.0-2.1 */
-#define MMCSD_VDD_21_22 ((uint32_t)1 << 9) /* VDD voltage 2.1-2.2 */
-#define MMCSD_VDD_22_23 ((uint32_t)1 << 10) /* VDD voltage 2.2-2.3 */
-#define MMCSD_VDD_23_24 ((uint32_t)1 << 11) /* VDD voltage 2.3-2.4 */
-#define MMCSD_VDD_24_25 ((uint32_t)1 << 12) /* VDD voltage 2.4-2.5 */
-#define MMCSD_VDD_25_26 ((uint32_t)1 << 13) /* VDD voltage 2.5-2.6 */
-#define MMCSD_VDD_26_27 ((uint32_t)1 << 14) /* VDD voltage 2.6-2.7 */
-#define MMCSD_VDD_27_28 ((uint32_t)1 << 15) /* VDD voltage 2.7-2.8 */
-#define MMCSD_VDD_28_29 ((uint32_t)1 << 16) /* VDD voltage 2.8-2.9 */
-#define MMCSD_VDD_29_30 ((uint32_t)1 << 17) /* VDD voltage 2.9-3.0 */
-#define MMCSD_VDD_30_31 ((uint32_t)1 << 18) /* VDD voltage 3.0-3.1 */
-#define MMCSD_VDD_31_32 ((uint32_t)1 << 19) /* VDD voltage 3.1-3.2 */
-#define MMCSD_VDD_32_33 ((uint32_t)1 << 20) /* VDD voltage 3.2-3.3 */
-#define MMCSD_VDD_33_34 ((uint32_t)1 << 21) /* VDD voltage 3.3-3.4 */
-#define MMCSD_VDD_34_35 ((uint32_t)1 << 22) /* VDD voltage 3.4-3.5 */
-#define MMCSD_VDD_35_36 ((uint32_t)1 << 23) /* VDD voltage 3.5-3.6 */
-#define MMCSD_R3_HIGHCAPACITY ((uint32_t)1 << 30) /* true: Card supports block addressing */
-#define MMCSD_CARD_BUSY ((uint32_t)1 << 31) /* Card power-up busy bit */
-
-/* R6 Card Status bit definitions */
-
-#define MMCSD_R6_RCA_SHIFT (16) /* New published RCA */
-#define MMCSD_R6_RCA_MASK ((uint32_t)0xffff << MMCSD_R6_RCA_SHIFT)
-#define MMCSD_R6_COMCRCERROR ((uint32_t)1 << 15) /* CRC error */
-#define MMCSD_R6_ILLEGALCOMMAND ((uint32_t)1 << 14) /* Bad command */
-#define MMCSD_R6_ERROR ((uint32_t)1 << 13) /* General error */
-#define MMCSD_R6_STATE_SHIFT (9) /* Current card state */
-#define MMCSD_R6_STATE_MASK ((uint32_t)15 << MMCSD_R6_STATE_SHIFT)
- /* Card identification mode states */
-# define MMCSD_R6_STATE_IDLE ((uint32_t)0 << MMCSD_R6_STATE_SHIFT) /* 0=Idle state */
-# define MMCSD_R6_STATE_READY ((uint32_t)1 << MMCSD_R6_STATE_SHIFT) /* 1=Ready state */
-# define MMCSD_R6_STATE_IDENT ((uint32_t)2 << MMCSD_R6_STATE_SHIFT) /* 2=Identification state */
- /* Data transfer states */
-# define MMCSD_R6_STATE_STBY ((uint32_t)3 << MMCSD_R6_STATE_SHIFT) /* 3=Standby state */
-# define MMCSD_R6_STATE_TRAN ((uint32_t)4 << MMCSD_R6_STATE_SHIFT) /* 4=Transfer state */
-# define MMCSD_R6_STATE_DATA (5(uint32_t) << MMCSD_R6_STATE_SHIFT) /* 5=Sending data state */
-# define MMCSD_R6_STATE_RCV ((uint32_t)6 << MMCSD_R6_STATE_SHIFT) /* 6=Receiving data state */
-# define MMCSD_R6_STATE_PRG ((uint32_t)7 << MMCSD_R6_STATE_SHIFT) /* 7=Programming state */
-# define MMCSD_R6_STATE_DIS ((uint32_t) << MMCSD_R6_STATE_SHIFT) /* 8=Disconnect state */
-#define MMCSD_R6_ERRORMASK ((uint32_t)0x0000e000) /* Error mask */
-
-/* SD Configuration Register (SCR) encoding */
-
-#define MMCSD_SCR_BUSWIDTH_1BIT (1)
-#define MMCSD_SCR_BUSWIDTH_2BIT (2)
-#define MMCSD_SCR_BUSWIDTH_4BIT (4)
-#define MMCSD_SCR_BUSWIDTH_8BIT (8)
-
-/* Last 4 bytes of the 48-bit R7 response */
-
-#define MMCSD_R7VERSION_SHIFT (28) /* Bits 28-31: Command version number */
-#define MMCSD_R7VERSION_MASK ((uint32_t)0x0f << MMCSD_R7VERSION_SHIFT)
-#define MMCSD_R7VOLTAGE_SHIFT (8) /* Bits 8-11: Voltage accepted */
-#define MMCSD_R7VOLTAGE_MASK ((uint32_t)0x0f << MMCSD_R7VOLTAGE_SHIFT)
-# define MMCSD_R7VOLTAGE_27 ((uint32_t)0x01 << MMCSD_R7VOLTAGE_SHIFT) /* 2.7-3.6V */
-#define MMCSD_R7ECHO_SHIFT (0) /* Bits 0-7: Echoed check pattern */
-#define MMCSD_R7ECHO_MASK ((uint32_t)0xff << MMCSD_R7ECHO_SHIFT)
-# define MMCSD_R7CHECKPATTERN ((uint32_t)0xaa << MMCSD_R7ECHO_SHIFT)
-
-/********************************************************************************************
- * Public Types
- ********************************************************************************************/
-
-/* Decoded Card Identification (CID) register */
-
-struct mmcsd_cid_s
-{
- uint8_t mid; /* 127:120 8-bit Manufacturer ID */
- uint16_t oid; /* 119:104 16-bit OEM/Application ID (ascii) */
- uint8_t pnm[6]; /* 103:64 40-bit Product Name (ascii) + null terminator */
- uint8_t prv; /* 63:56 8-bit Product revision */
- uint32_t psn; /* 55:24 32-bit Product serial number */
- /* 23:20 4-bit (reserved) */
- uint16_t mdt; /* 19:8 12-bit Manufacturing date */
- uint8_t crc; /* 7:1 7-bit CRC7 */
- /* 0:0 1-bit (not used) */
-};
-
-/* Decoded Card Specific Data (CSD) register */
-
-struct mmcsd_csd_s
-{
- uint8_t csdstructure; /* 127:126 CSD structure */
- uint8_t mmcspecvers; /* 125:122 MMC Spec version (MMC only) */
-
- struct
- {
- uint8_t timeunit; /* 2:0 Time exponent */
- uint8_t timevalue; /* 6:3 Time mantissa */
- } taac; /* 119:112 Data read access-time-1 */
-
- uint8_t nsac; /* 111:104 Data read access-time-2 in CLK cycle(NSAC*100) */
-
- struct
- {
- uint8_t transferrateunit; /* 2:0 Rate exponent */
- uint8_t timevalue; /* 6:3 Rate mantissa */
- } transpeed; /* 103:96 Max. data transfer rate */
-
- uint16_t ccc; /* 95:84 Card command classes */
- uint8_t readbllen; /* 83:80 Max. read data block length */
- uint8_t readblpartial; /* 79:79 Partial blocks for read allowed */
- uint8_t writeblkmisalign; /* 78:78 Write block misalignment */
- uint8_t readblkmisalign; /* 77:77 Read block misalignment */
- uint8_t dsrimp; /* 76:76 DSR implemented */
-
- union
- {
-#ifdef CONFIG_MMCSD_MMCSUPPORT
- struct
- {
- uint16_t csize; /* 73:62 Device size */
- uint8_t vddrcurrmin; /* 61:59 Max. read current at Vdd min */
- uint8_t vddrcurrmax; /* 58:56 Max. read current at Vdd max */
- uint8_t vddwcurrmin; /* 55:53 Max. write current at Vdd min */
- uint8_t vddwcurrmax; /* 52:50 Max. write current at Vdd max */
- uint8_t csizemult; /* 49:47 Device size multiplier */
-
- union
- {
- struct /* MMC system specification version 3.1 */
- {
- uint8_t ergrpsize; /* 46:42 Erase group size (MMC 3.1) */
- uint8_t ergrpmult; /* 41:37 Erase group multiplier (MMC 3.1) */
- } mmc31;
- struct /* MMC system specification version 2.2 */
- {
- uint8_t sectorsize; /* 46:42 Erase sector size (MMC 2.2) */
- uint8_t ergrpsize; /* 41:37 Erase group size (MMC 2.2) */
- } mmc22;
- } er;
-
- uint8_t mmcwpgrpsize; /* 36:32 Write protect group size (MMC) */
- } mmc;
-#endif
- struct
- {
- uint16_t csize; /* 73:62 Device size */
- uint8_t vddrcurrmin; /* 61:59 Max. read current at Vdd min */
- uint8_t vddrcurrmax; /* 58:56 Max. read current at Vdd max */
- uint8_t vddwcurrmin; /* 55:53 Max. write current at Vdd min */
- uint8_t vddwcurrmax; /* 52:50 Max. write current at Vdd max */
- uint8_t csizemult; /* 49:47 Device size multiplier */
- uint8_t sderblen; /* 46:46 Erase single block enable (SD) */
- uint8_t sdsectorsize; /* 45:39 Erase sector size (SD) */
- uint8_t sdwpgrpsize; /* 38:32 Write protect group size (SD) */
- } sdbyte;
-
- struct
- {
- /* 73:70 (reserved) */
- uint32_t csize; /* 69:48 Device size */
- /* 47:47 (reserved) */
- uint8_t sderblen; /* 46:46 Erase single block enable (SD) */
- uint8_t sdsectorsize; /* 45:39 Erase sector size (SD) */
- uint8_t sdwpgrpsize; /* 38:32 Write protect group size (SD) */
- } sdblock;
- } u;
-
- uint8_t wpgrpen; /* 31:31 Write protect group enable */
- uint8_t mmcdfltecc; /* 30:29 Manufacturer default ECC (MMC) */
- uint8_t r2wfactor; /* 28:26 Write speed factor */
- uint8_t writebllen; /* 25:22 Max. write data block length */
- uint8_t writeblpartial; /* 21:21 Partial blocks for write allowed */
- uint8_t fileformatgrp; /* 15:15 File format group */
- uint8_t copy; /* 14:14 Copy flag (OTP) */
- uint8_t permwriteprotect; /* 13:13 Permanent write protection */
- uint8_t tmpwriteprotect; /* 12:12 Temporary write protection */
- uint8_t fileformat; /* 10:11 File format */
- uint8_t mmcecc; /* 9:8 ECC (MMC) */
- uint8_t crc; /* 7:1 CRC */
- /* 0:0 Not used */
-};
-
-struct mmcsd_scr_s
-{
- uint8_t scrversion; /* 63:60 Version of SCR structure */
- uint8_t sdversion; /* 59:56 SD memory card physical layer version */
- uint8_t erasestate; /* 55:55 Data state after erase (1 or 0) */
- uint8_t security; /* 54:52 SD security support */
- uint8_t buswidth; /* 51:48 DAT bus widthes supported */
- /* 47:32 SD reserved space */
- uint32_t mfgdata; /* 31:0 Reserved for manufacturing data */
-};
-
-/********************************************************************************************
- * Public Data
- ********************************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-/********************************************************************************************
- * Public Functions
- ********************************************************************************************/
-
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-#endif /* __DRIVERS_MMCSD_MMCSD_SDIO_H */
diff --git a/nuttx/drivers/mmcsd/mmcsd_spi.c b/nuttx/drivers/mmcsd/mmcsd_spi.c
deleted file mode 100644
index 3d4cf1dd1..000000000
--- a/nuttx/drivers/mmcsd/mmcsd_spi.c
+++ /dev/null
@@ -1,1889 +0,0 @@
-/****************************************************************************
- * drivers/mmcsd/mmcsd_spi.c
- *
- * Copyright (C) 2008-2010, 2011-2013 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#if defined (CONFIG_MMCSD) && defined (CONFIG_MMCSD_SPI)
-
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/clock.h>
-#include <nuttx/spi.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/mmcsd.h>
-
-#include "mmcsd_spi.h"
-#include "mmcsd_csd.h"
-#include "mmcsd_internal.h"
-
-/****************************************************************************
- * Pre-Processor Definitions
- ****************************************************************************/
-
-/* Configuration ************************************************************/
-
-#ifndef CONFIG_MMCSD_NSLOTS
-# ifdef CONFIG_CPP_HAVE_WARNING
-# warning "CONFIG_MMCSD_NSLOTS not defined"
-# endif
-# define CONFIG_MMCSD_NSLOTS 1
-#endif
-
-#define MMCSD_IDMODE_CLOCK (400000)
-
-#if defined(CONFIG_FS_WRITABLE) && !defined(CONFIG_MMCSD_READONLY)
-# define MMCSD_MODE 0666
-#else
-# define MMCSD_MODE 0444
-#endif
-
-#ifndef CONFIG_MMCSD_SPICLOCK
-# define CONFIG_MMCSD_SPICLOCK 20000000
-#endif
-
-#ifndef CONFIG_MMCSD_SECTOR512
-# define CONFIG_MMCSD_SECTOR512 /* Force 512 byte sectors on all cards */
-#endif
-
-/* Slot struct info *********************************************************/
-/* Slot status definitions */
-
-#define MMCSD_SLOTSTATUS_NOTREADY 0x01 /* Card not initialized */
-#define MMCSD_SLOTSTATUS_NODISK 0x02 /* No card in the slot */
-#define MMCSD_SLOTSTATUS_WRPROTECT 0x04 /* Card is write protected */
-#define MMCSD_SLOTSTATUS_MEDIACHGD 0x08 /* Media changed in slot */
-
-/* Values in the MMC/SD command table ***************************************/
-/* These define the value returned by the MMC/SD command */
-
-#define MMCSD_CMDRESP_R1 0
-#define MMCSD_CMDRESP_R1B 1
-#define MMCSD_CMDRESP_R2 2
-#define MMCSD_CMDRESP_R3 3
-#define MMCSD_CMDRESP_R7 4
-
-#ifdef CONFIG_MMCSD_SECTOR512
-# define SECTORSIZE(s) (512)
-#else
-# define SECTORSIZE(s) ((s)->sectorsize)
-#endif
-
-/* Time delays in units of the system clock. CLK_TCK is the number of clock
- * ticks per second.
- */
-
-#define MMCSD_DELAY_10MS (CLK_TCK/100 + 1)
-#define MMCSD_DELAY_50MS (CLK_TCK/20 + 1)
-#define MMCSD_DELAY_100MS (CLK_TCK/10 + 1)
-#define MMCSD_DELAY_250MS (CLK_TCK/4 + 1)
-#define MMCSD_DELAY_500MS (CLK_TCK/2 + 1)
-#define MMCSD_DELAY_1SEC (CLK_TCK + 1)
-#define MMCSD_DELAY_10SEC (10 * CLK_TCK + 1)
-
-#define ELAPSED_TIME(t) (clock_systimer()-(t))
-#define START_TIME (clock_systimer())
-
-/* SD read timeout: ~100msec, Write Time out ~250ms. Units of clock ticks */
-
-#define SD_READACCESS MMCSD_DELAY_100MS
-#define SD_WRITEACCESS MMCSD_DELAY_250MS
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This structure represents the state of one card slot */
-
-struct mmcsd_slot_s
-{
- FAR struct spi_dev_s *spi; /* SPI port bound to this slot */
- sem_t sem; /* Assures mutually exclusive accesss to card and SPI */
- uint8_t state; /* State of the slot (see MMCSD_SLOTSTATUS_* definitions) */
- uint8_t type; /* Disk type */
- uint8_t csd[16]; /* Copy of card CSD */
-#ifndef CONFIG_MMCSD_SECTOR512
- uint16_t sectorsize; /* Media block size (in bytes) */
-#endif
- uint32_t nsectors; /* Number of blocks on the media */
- uint32_t taccess; /* Card access time */
- uint32_t twrite; /* Card write time */
- uint32_t ocr; /* Last 4 bytes of OCR (R3) */
- uint32_t r7; /* Last 4 bytes of R7 */
-};
-
-struct mmcsd_cmdinfo_s
-{
- uint8_t cmd;
- uint8_t resp;
- uint8_t chksum;
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Misc *********************************************************************/
-
-static void mmcsd_semtake(sem_t *sem);
-
-/* Card SPI interface *******************************************************/
-
-static int mmcsd_waitready(FAR struct mmcsd_slot_s *slot);
-static uint32_t mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
- const struct mmcsd_cmdinfo_s *cmd, uint32_t arg);
-static void mmcsd_setblklen(FAR struct mmcsd_slot_s *slot,
- uint32_t length);
-static uint32_t mmcsd_nsac(FAR struct mmcsd_slot_s *slot, uint8_t *csd,
- uint32_t frequency);
-static uint32_t mmcsd_taac(FAR struct mmcsd_slot_s *slot, uint8_t *csd);
-static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, uint8_t *csd);
-static void mmcsd_checkwrprotect(FAR struct mmcsd_slot_s *slot,
- uint8_t *csd);
-static int mmcsd_getcardinfo(FAR struct mmcsd_slot_s *slot,
- uint8_t *buffer, const struct mmcsd_cmdinfo_s *cmd);
-
-#define mmcsd_getcsd(slot, csd) mmcsd_getcardinfo(slot, csd, &g_cmd9);
-#define mmcsd_getcid(slot, cid) mmcsd_getcardinfo(slot, cid, &g_cmd10);
-
-static int mmcsd_recvblock(FAR struct mmcsd_slot_s *slot,
- uint8_t *buffer, int nbytes);
-#if defined(CONFIG_FS_WRITABLE) && !defined(CONFIG_MMCSD_READONLY)
-static int mmcsd_xmitblock(FAR struct mmcsd_slot_s *slot,
- const uint8_t *buffer, int nbytes, uint8_t token);
-#endif
-
-/* Block driver interfaces **************************************************/
-
-static int mmcsd_open(FAR struct inode *inode);
-static int mmcsd_close(FAR struct inode *inode);
-static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
- size_t start_sector, unsigned int nsectors);
-#if defined(CONFIG_FS_WRITABLE) && !defined(CONFIG_MMCSD_READONLY)
-static ssize_t mmcsd_write(FAR struct inode *inode,
- const unsigned char *buffer, size_t start_sector,
- unsigned int nsectors);
-#endif
-static int mmcsd_geometry(FAR struct inode *inode,
- struct geometry *geometry);
-
-/* Initialization ***********************************************************/
-
-static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot);
-static void mmcsd_mediachanged(void *arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* Driver state *************************************************************/
-
-/* These are the lock driver methods supported by this file */
-
-static const struct block_operations g_bops =
-{
- mmcsd_open, /* open */
- mmcsd_close, /* close */
- mmcsd_read, /* read */
-#if defined(CONFIG_FS_WRITABLE) && !defined(CONFIG_MMCSD_READONLY)
- mmcsd_write, /* write */
-#else
- NULL, /* write */
-#endif
- mmcsd_geometry, /* geometry */
- NULL /* ioctl */
-};
-
-/* A slot structure allocated for each configured slot */
-
-static struct mmcsd_slot_s g_mmcsdslot[CONFIG_MMCSD_NSLOTS];
-
-/* Timing *******************************************************************/
-
-/* We will use the TRAN_SPEED from the CSD to determine the maximum SPI
- * clocking (TRAN_SPEED defines the maximum transfer rate per bit per data
- * line).
- *
- * The CSD TRAN_SPEED is provided as a 3 bit rate unit (RU) and a 4 bit time
- * value (TU). We need the transfer frequency which is: RU*TU bits/sec
- *
- * g_transpeedru holds RU/10 and g_transpeedtu holds TU*10 so that the
- * correct value is returned in the product
- */
-
-static const uint32_t g_transpeedru[8] =
-{
- 10000, /* 0: 10 Kbit/sec / 10 */
- 100000, /* 1: 1 Mbit/sec / 10 */
- 1000000, /* 2: 10 Mbit/sec / 10 */
- 10000000, /* 3: 100 Mbit/sec / 10*/
-
- 0, 0, 0, 0 /* 4-7: Reserved values */
-};
-
-static const uint32_t g_transpeedtu[16] =
-{
- 0, 10, 12, 13, /* 0-3: Reserved, 1.0, 1.1, 1.2, 1.3 */
- 15, 20, 25, 30, /* 4-7: 1.5, 2.0, 2.5, 3.0 */
- 35, 40, 45, 50, /* 8-11: 3.5, 4.0, 4.5, 5.0 */
- 55, 60, 70, 80, /* 12-15: 5.5, 6.0, 7.0, 8.0 */
-};
-
-/* The TAAC defines the asynchronous part of the data access time. The
- * read access time the sum of the TAAC and the NSAC. These define the
- * time from the end bit of the read command to start bit of the data block.
- *
- * The TAAC consists of a 3-bit time unit (TU) and a 4-bit time value (TV).
- * TAAC is in units of time; NSAC is in units of SPI clocks.
- * The access time we need is then given by:
- *
- * taccess = TU*TV + NSAC/spifrequency
- *
- * g_taactu holds TU in units of nanoseconds and microseconds (you have to use
- * the index to distiguish). g_taactv holds TV with 8-bits of fraction.
- */
-
-#define MAX_USTUNDX 2
-static const uint16_t g_taactu[8] =
-{
- /* Units of nanoseconds */
-
- 1, /* 0: 1 ns */
- 10, /* 1: 10 ns */
- 100, /* 2: 100 ns */
-
- /* Units of microseconds */
-
- 1, /* 3: 1 us 1,000 ns */
- 10, /* 4: 10 us 10,000 ns */
- 100, /* 5: 100 us 100,000 ns */
- 1000, /* 6: 1 ms 1,000,000 ns*/
- 10000, /* 7: 10 ms 10,000,000 ns */
-};
-
-static const uint16_t g_taactv[] =
-{
- 0x000, 0x100, 0x133, 0x14d, /* 0-3: Reserved, 1.0, 1.2, 1.3 */
- 0x180, 0x200, 0x280, 0x300, /* 4-7: 1.5, 2.0, 2.5, 3.0 */
- 0x380, 0x400, 0x480, 0x500, /* 8-11: 3.5, 4.0, 4.5, 5.0 */
- 0x580, 0x600, 0x700, 0x800 /* 12-15: 5.5, 6.0, 7.0, 8.0 */
-};
-
-/* Commands *****************************************************************/
-
-static const struct mmcsd_cmdinfo_s g_cmd0 = {CMD0, MMCSD_CMDRESP_R1, 0x95};
-static const struct mmcsd_cmdinfo_s g_cmd1 = {CMD1, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd8 = {CMD8, MMCSD_CMDRESP_R7, 0x87};
-static const struct mmcsd_cmdinfo_s g_cmd9 = {CMD9, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd10 = {CMD10, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd12 = {CMD12, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd16 = {CMD16, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd17 = {CMD17, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd18 = {CMD18, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd24 = {CMD24, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd25 = {CMD25, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd55 = {CMD55, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_cmd58 = {CMD58, MMCSD_CMDRESP_R3, 0xff};
-static const struct mmcsd_cmdinfo_s g_acmd23 = {ACMD23, MMCSD_CMDRESP_R1, 0xff};
-static const struct mmcsd_cmdinfo_s g_acmd41 = {ACMD41, MMCSD_CMDRESP_R1, 0xff};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: mmcsd_semtake
- ****************************************************************************/
-
-static void mmcsd_semtake(sem_t *sem)
-{
- while (sem_wait(sem) != 0)
- {
- /* The only case that an error should occur here is if the wait was
- * awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-}
-
-#define mmcsd_semgive(sem) sem_post(sem)
-
-/****************************************************************************
- * Name: mmcsd_waitready
- *
- * Description:
- * Wait until the card is no longer busy
- *
- * Assumptions:
- * MMC/SD card already selected
- *
- ****************************************************************************/
-
-static int mmcsd_waitready(FAR struct mmcsd_slot_s *slot)
-{
- FAR struct spi_dev_s *spi = slot->spi;
- uint8_t response;
- uint32_t start;
- uint32_t elapsed;
-
- /* Wait until the card is no longer busy (up to 500MS) */
-
- start = START_TIME;
- do
- {
- response = SPI_SEND(spi, 0xff);
- if (response == 0xff)
- {
- return OK;
- }
- elapsed = ELAPSED_TIME(start);
- }
- while (elapsed < MMCSD_DELAY_500MS);
-
- fdbg("Card still busy, last response: %02x\n", response);
- return -EBUSY;
-}
-
-/****************************************************************************
- * Name: mmcsd_sendcmd
- *
- * Description:
- * Send a command to MMC
- *
- * Assumptions:
- * MMC/SD card already selected
- *
- ****************************************************************************/
-
-static uint32_t mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
- const struct mmcsd_cmdinfo_s *cmd, uint32_t arg)
-{
- FAR struct spi_dev_s *spi = slot->spi;
- uint32_t result;
- uint8_t response = 0xff;
- int ret;
- int i;
-
- /* Wait until the card is not busy. Some SD cards will not enter the IDLE
- * state until CMD0 is sent for the first time, switching the card to SPI
- * mode. Having a pull-up resistor on MISO may avoid this problem, but
- * this check makes it work also without the pull-up.
- */
-
- ret = mmcsd_waitready(slot);
- if (ret != OK && cmd != &g_cmd0)
- {
- return ret;
- }
-
- /* Send command code */
-
- SPI_SEND(spi, cmd->cmd);
-
- /* Send command's arguments (should be zero if there are no arguements) */
-
- SPI_SEND(spi, (arg >> 24) & 0xff);
- SPI_SEND(spi, (arg >> 16) & 0xff);
- SPI_SEND(spi, (arg >> 8) & 0xff);
- SPI_SEND(spi, arg & 0xff);
-
- /* Send CRC if needed. The SPI interface is initialized in non-protected
- * mode. However, the reset command (CMD0) and CMD8 are received by the
- * card while it is still in SD mode and, therefore, must have a valid
- * CRC field.
- */
-
- SPI_SEND(spi, cmd->chksum);
-
- /* Skip stuff byte on CMD12 */
-
- if (cmd->cmd == CMD12)
- {
- SPI_SEND(spi, 0xff);
- }
-
- /* Get the response to the command. A valid response will have bit7=0.
- * Usually, the non-response is 0xff, but I have seen 0xc0 too.
- */
-
- for (i = 0; i < 9 && (response & 0x80) != 0; i++)
- {
- response = SPI_SEND(spi, 0xff);
- }
-
- if ((response & 0x80) != 0)
- {
- fdbg("Failed: i=%d response=%02x\n", i, response);
- return (uint32_t)-1;
- }
-
- /* Interpret the response according to the command */
-
- result = response;
- switch (cmd->resp)
- {
- /* The R1B response is two bytes long */
-
- case MMCSD_CMDRESP_R1B:
- {
- uint32_t busy = 0;
- uint32_t start;
- uint32_t elapsed;
-
- start = START_TIME;
- do
- {
- busy = SPI_SEND(spi, 0xff);
- elapsed = ELAPSED_TIME(start);
- }
- while (elapsed < slot->twrite && busy != 0xff);
-
- if (busy != 0xff)
- {
- fdbg("Failed: card still busy (%02x)\n", busy);
- return (uint32_t)-1;
- }
-
- fvdbg("CMD%d[%08x] R1B=%02x\n",
- cmd->cmd & 0x3f, arg, response);
- }
- break;
-
- /* The R1 response is a single byte */
-
- case MMCSD_CMDRESP_R1:
- {
- fvdbg("CMD%d[%08x] R1=%02x\n",
- cmd->cmd & 0x3f, arg, response);
- }
- break;
-
- /* The R2 response is two bytes long */
-
- case MMCSD_CMDRESP_R2:
- {
- result = ((uint32_t)(response & 0xff) << 8);
- result |= SPI_SEND(spi, 0xff) & 0xff;
-
- fvdbg("CMD%d[%08x] R2=%04x\n",
- cmd->cmd & 0x3f, arg, result);
- }
- break;
-
- /* The R3 response is 5 bytes long. The first byte is identical to R1. */
-
- case MMCSD_CMDRESP_R3:
- {
- slot->ocr = ((uint32_t)(SPI_SEND(spi, 0xff) & 0xff) << 24);
- slot->ocr |= ((uint32_t)(SPI_SEND(spi, 0xff) & 0xff) << 16);
- slot->ocr |= ((uint32_t)(SPI_SEND(spi, 0xff) & 0xff) << 8);
- slot->ocr |= SPI_SEND(spi, 0xff) & 0xff;
-
- fvdbg("CMD%d[%08x] R1=%02x OCR=%08x\n",
- cmd->cmd & 0x3f, arg, response, slot->ocr);
- }
- break;
-
- /* The R7 response is 5 bytes long. The first byte is identical to R1. */
-
- case MMCSD_CMDRESP_R7:
- default:
- {
- slot->r7 = ((uint32_t)(SPI_SEND(spi, 0xff) & 0xff) << 24);
- slot->r7 |= ((uint32_t)(SPI_SEND(spi, 0xff) & 0xff) << 16);
- slot->r7 |= ((uint32_t)(SPI_SEND(spi, 0xff) & 0xff) << 8);
- slot->r7 |= SPI_SEND(spi, 0xff) & 0xff;
-
- fvdbg("CMD%d[%08x] R1=%02x R7=%08x\n",
- cmd->cmd & 0x3f, arg, response, slot->r7);
- }
- break;
- }
-
- return result;
-}
-
-/****************************************************************************
- * Name: mmcsd_setblklen
- *
- * Description:
- * Set block length
- *
- * Assumptions:
- * MMC/SD card already selected
- *
- ****************************************************************************/
-
-static void mmcsd_setblklen(FAR struct mmcsd_slot_s *slot, uint32_t length)
-{
- uint32_t response;
-
- fvdbg("Set block length to %d\n", length);
- response = mmcsd_sendcmd(slot, &g_cmd16, length);
- if (response != MMCSD_SPIR1_OK)
- {
- fdbg("Failed to set block length: %02x\n", response);
- }
-}
-
-/****************************************************************************
- * Name: mmcsd_nsac
- *
- * Description: Convert the value of the NSAC to microseconds
- *
- ****************************************************************************/
-
-static uint32_t mmcsd_nsac(FAR struct mmcsd_slot_s *slot, uint8_t *csd,
- uint32_t frequency)
-{
- /* NSAC is 8-bits wide and is in units of 100 clock cycles. Therefore, the
- * maximum value is 25.5K clock cycles.
- */
-
- uint32_t nsac = MMCSD_CSD_NSAC(csd) * ((uint32_t)100*1000);
- uint32_t fhkz = (frequency + 500) / 1000;
- return (nsac + (fhkz >> 1)) / fhkz;
-}
-
-/****************************************************************************
- * Name: mmcsd_taac
- *
- * Description: Convert the value of the TAAC to microseconds
- *
- ****************************************************************************/
-
-static uint32_t mmcsd_taac(FAR struct mmcsd_slot_s *slot, uint8_t *csd)
-{
- int tundx;
-
- /*The TAAC consists of a 3-bit time unit (TU) and a 4-bit time value (TV).
- * TAAC is in units of time; NSAC is in units of SPI clocks.
- * The access time we need is then given by:
- *
- * taccess = TU*TV + NSAC/spifrequency
- *
- * g_taactu holds TU in units of nanoseconds and microseconds (you have to use
- * the index to distiguish. g_taactv holds TV with 8-bits of fraction.
- */
-
- tundx = MMCSD_CSD_TAAC_TIMEUNIT(csd);
- if (tundx <= MAX_USTUNDX)
- {
- /* The maximum value of the nanosecond TAAC is 800 ns. The rounded
- * answer in microseconds will be at most 1.
- */
-
- return 1;
- }
- else
- {
- /* Return the answer in microseconds */
-
- return (g_taactu[tundx]*g_taactv[MMCSD_CSD_TAAC_TIMEVALUE(csd)] + 0x80) >> 8;
- }
-}
-
-/****************************************************************************
- * Name: mmcsd_decodecsd
- *
- * Description:
- *
- ****************************************************************************/
-
-static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, uint8_t *csd)
-{
- FAR struct spi_dev_s *spi = slot->spi;
- uint32_t maxfrequency;
- uint32_t frequency;
- uint32_t readbllen;
- uint32_t csizemult;
- uint32_t csize;
-
- /* Calculate SPI max clock */
-
- maxfrequency =
- g_transpeedtu[MMCSD_CSD_TRANSPEED_TIMEVALUE(csd)] *
- g_transpeedru[MMCSD_CSD_TRANSPEED_TRANSFERRATEUNIT(csd)];
-
- /* Clip the max frequency to account for board limitations */
-
- frequency = maxfrequency;
- if (frequency > CONFIG_MMCSD_SPICLOCK)
- {
- frequency = CONFIG_MMCSD_SPICLOCK;
- }
-
- /* Set the actual SPI frequency as close as possible to that value */
-
- frequency = SPI_SETFREQUENCY(spi, frequency);
-
- /* Now determine the delay to access data */
-
- if (slot->type == MMCSD_CARDTYPE_MMC)
- {
- /* The TAAC consists of a 3-bit time unit (TU) and a 4-bit time value (TV).
- * TAAC is in units of time; NSAC is in units of SPI clocks.
- * The access time we need is then given by:
- *
- * taccess = TU*TV + NSAC/spifrequency
- *
- * Example: TAAC = 1.5 ms, NSAC = 0, r2wfactor = 4, CLK_TCK=100
- * taccessus = 1,500uS
- * taccess = (1,500 * 100) / 100,000) + 1 = 2 (ideal, 1.5)
- * twrite = (1,500 * 4 * 100) / 100,000) + 1 = 7 (ideal 6.0)
- *
- * First get the access time in microseconds
- */
-
- uint32_t taccessus = mmcsd_taac(slot, csd) + mmcsd_nsac(slot, csd, frequency);
-
- /* Then convert to system clock ticks. The maximum read access is 10 times
- * the tacc value: taccess = 10 * (taccessus / 1,000,000) * CLK_TCK, or
- */
-
- slot->taccess = (taccessus * CLK_TCK) / 100000 + 1;
-
- /* NOTE that we add one to taccess to assure that we wait at least this
- * time. The write access time is larger by the R2WFACTOR: */
-
- slot->taccess = (taccessus * MMCSD_CSD_R2WFACTOR(csd) * CLK_TCK) / 100000 + 1;
- }
- else
- {
- /* For SD, the average is still given by the TAAC+NSAC, but the
- * maximum are the constants 100 and 250MS
- */
-
- slot->taccess = SD_READACCESS;
- slot->twrite = SD_WRITEACCESS;
- }
-
- fvdbg("SPI Frequency\n");
- fvdbg(" Maximum: %d Hz\n", maxfrequency);
- fvdbg(" Actual: %d Hz\n", frequency);
- fvdbg("Read access time: %d ticks\n", slot->taccess);
- fvdbg("Write access time: %d ticks\n", slot->twrite);
-
- /* Get the physical geometry of the card: sector size and number of
- * sectors. The card's total capacity is computed from
- *
- * capacity = BLOCKNR * BLOCK_LEN
- * BLOCKNR = (C_SIZE+1)*MULT
- * MULT = 2**(C_SIZE_MULT+2) (C_SIZE_MULT < 8)
- * BLOCK_LEN = 2**READ_BL_LEN (READ_BL_LEN < 12)
- *
- * Or
- *
- * capacity = ((C_SIZE+1) << (READD_BL_LEN + C_SIZE_MULT + 2))
- *
- * In units of the sector size (1 << READ_BL_LEN), then simplifies to
- *
- * nsectors = ((C_SIZE+1) << (C_SIZE_MULT + 2))
- */
-
- if (MMCSD_CSD_CSDSTRUCT(csd) != 0)
- {
- /* SDC structure ver 2.xx */
- /* Note: On SD card WRITE_BL_LEN is always the same as READ_BL_LEN */
-
- readbllen = SD20_CSD_READBLLEN(csd);
- csizemult = SD20_CSD_CSIZEMULT(csd) + 2;
- csize = SD20_CSD_CSIZE(csd) + 1;
- }
- else
- {
- /* MMC or SD structure ver 1.xx */
- /* Note: On SD card WRITE_BL_LEN is always the same as READ_BL_LEN */
-
- readbllen = MMCSD_CSD_READBLLEN(csd);
- csizemult = MMCSD_CSD_CSIZEMULT(csd) + 2;
- csize = MMCSD_CSD_CSIZE(csd) + 1;
- }
-
- /* SDHC ver2.x cards have fixed block transfer size of 512 bytes. SDC
- * ver1.x cards with capacity less than 1Gb, will have sector size
- * 512 byes. SDC ver1.x cards with capacity of 2Gb will report readbllen
- * of 1024 but should use 512 bytes for block transfers. SDC ver1.x 4Gb
- * cards will report readbllen of 2048 bytes -- are they also 512 bytes?
- */
-
-#ifdef CONFIG_MMCSD_SECTOR512
- if (readbllen > 9)
- {
- csizemult += (readbllen - 9);
- }
- else
- {
- DEBUGASSERT(readbllen == 9);
- }
-#else
- if (IS_SDV2(slot->type))
- {
- if (readbllen > 9)
- {
- fdbg("Forcing 512 byte sector size\n");
- csizemult += (readbllen - 9);
- readbllen = 9;
- }
- }
-
- slot->sectorsize = 1 << readbllen;
-#endif
- slot->nsectors = csize << csizemult;
- fvdbg("Sector size: %d\n", SECTORSIZE(slot));
- fvdbg("Number of sectors: %d\n", slot->nsectors);
-}
-
-/****************************************************************************
- * Name: mmcsd_checkwrprotect
- *
- * Description:
- *
- ****************************************************************************/
-
-static void mmcsd_checkwrprotect(FAR struct mmcsd_slot_s *slot, uint8_t *csd)
-{
- FAR struct spi_dev_s *spi = slot->spi;
-
- /* Check if (1) the slot is reporting that reporting that write protection
- * is set, (2) the card reports permanent write protect, or (2) the card
- * reports temporary write protect.
- */
-
- if ((SPI_STATUS(spi, SPIDEV_MMCSD) & SPI_STATUS_WRPROTECTED) != 0 ||
- MMCSD_CSD_PERMWRITEPROTECT(csd) ||
- MMCSD_CSD_TMPWRITEPROTECT(csd))
- {
- slot->state |= MMCSD_SLOTSTATUS_WRPROTECT;
- }
- else
- {
- slot->state &= ~MMCSD_SLOTSTATUS_WRPROTECT;
- }
-}
-
-/****************************************************************************
- * Name: mmcsd_getcardinfo
- *
- * Description:
- * Read CSD or CID registers
- *
- * Assumptions:
- * MMC/SD card already selected
- *
- ****************************************************************************/
-
-static int mmcsd_getcardinfo(FAR struct mmcsd_slot_s *slot, uint8_t *buffer,
- const struct mmcsd_cmdinfo_s *cmd)
-{
- FAR struct spi_dev_s *spi = slot->spi;
- uint32_t result;
- uint8_t response;
- int i;
-
- SPI_SEND(spi, 0xff);
-
- /* Send the CMD9 or CMD10 */
-
- result = mmcsd_sendcmd(slot, cmd, 0);
- if (result != MMCSD_SPIR1_OK)
- {
- fdbg("CMD9/10 failed: R1=%02x\n", result);
- return -EIO;
- }
-
- /* Try up to 8 times to find the start of block (or until an error occurs) */
-
- for (i = 0; i < 8; i++)
- {
- response = SPI_SEND(spi, 0xff);
- fvdbg("%d. SPI send returned %02x\n", i, response);
-
- /* If a read operation fails and the card cannot provide the requested
- * data, it will send a data error token instead. The 4 least
- * significant bits are the same as those in the R2 response.
- */
-
- if (response != 0 && (response & MMCSD_SPIDET_UPPER) == 0)
- {
- fdbg("%d. Data transfer error: %02x\n", i, response);
- return -EIO;
- }
- else if (response == MMCSD_SPIDT_STARTBLKSNGL)
- {
- for (i = 0; i < 16; ++i)
- {
- *buffer++ = SPI_SEND(spi, 0xff);
- }
-
- /* CRC receive */
-
- SPI_SEND(spi, 0xff);
- SPI_SEND(spi, 0xff);
- return OK;
- }
- }
-
- fdbg("%d. Did not find start of block\n");
- return -EIO;
-}
-
-/****************************************************************************
- * Name: mmcsd_recvblock
- *
- * Description: Receive a data block from the card
- *
- ****************************************************************************/
-
-static int mmcsd_recvblock(FAR struct mmcsd_slot_s *slot, uint8_t *buffer, int nbytes)
-{
- FAR struct spi_dev_s *spi = slot->spi;
- uint32_t start;
- uint32_t elapsed;
- uint8_t token;
-
- /* Wait up to the maximum to receive a valid data token. taccess is the
- * time from when the command is sent until the first byte of data is
- * received */
-
- start = START_TIME;
- do
- {
- token = SPI_SEND(spi, 0xff);
- elapsed = ELAPSED_TIME(start);
- }
- while (token == 0xff && elapsed < slot->taccess);
-
- if (token == MMCSD_SPIDT_STARTBLKSNGL)
- {
- /* Receive the block */
-
- SPI_RECVBLOCK(spi, buffer, nbytes);
-
- /* Discard the CRC */
-
- SPI_SEND(spi, 0xff);
- SPI_SEND(spi, 0xff);
- return OK;
- }
-
- fdbg("Did not receive data token (%02x)\n", token);
- return ERROR;
-}
-
-/****************************************************************************
- * Name: mmcsd_xmitblock
- *
- * Description: Transmit a data block to the card
- *
- ****************************************************************************/
-
-#if defined(CONFIG_FS_WRITABLE) && !defined(CONFIG_MMCSD_READONLY)
-static int mmcsd_xmitblock(FAR struct mmcsd_slot_s *slot, const uint8_t *buffer,
- int nbytes, uint8_t token)
-{
- FAR struct spi_dev_s *spi = slot->spi;
- uint8_t response;
-
- /* Start the block transfer:
- * 1. 0xff (sync)
- * 2. 0xfe or 0xfc (start of block token)
- * 3. Followed by the block of data and 2 byte CRC
- */
-
- SPI_SEND(spi, 0xff); /* sync */
- SPI_SEND(spi, token); /* data token */
-
- /* Transmit the block to the MMC/SD card */
-
- (void)SPI_SNDBLOCK(spi, buffer, nbytes);
-
- /* Add the bogus CRC. By default, the SPI interface is initialized in
- * non-protected mode. However, we still have to send bogus CRC values
- */
-
- SPI_SEND(spi, 0xff);
- SPI_SEND(spi, 0xff);
-
- /* Now get the data response */
-
- response = SPI_SEND(spi, 0xff);
- if ((response & MMCSD_SPIDR_MASK) != MMCSD_SPIDR_ACCEPTED)
- {
- fdbg("Bad data response: %02x\n", response);
- return -EIO;
- }
- return OK;
-}
-#endif /* CONFIG_FS_WRITABLE && !CONFIG_MMCSD_READONLY */
-
-/****************************************************************************
- * Block Driver Operations
- ****************************************************************************/
-
-/****************************************************************************
- * Name: mmcsd_open
- *
- * Description: Open the block device
- *
- ****************************************************************************/
-
-static int mmcsd_open(FAR struct inode *inode)
-{
- FAR struct mmcsd_slot_s *slot;
- FAR struct spi_dev_s *spi;
- int ret;
-
- fvdbg("Entry\n");
-
-#ifdef CONFIG_DEBUG
- if (!inode || !inode->i_private)
- {
- fdbg("Internal confusion\n");
- return -EIO;
- }
-#endif
-
- /* Extract our private data from the inode structure */
-
- slot = (FAR struct mmcsd_slot_s *)inode->i_private;
- spi = slot->spi;
-
-#ifdef CONFIG_DEBUG
- if (!spi)
- {
- fdbg("Internal confusion\n");
- return -EIO;
- }
-#endif
-
- /* Verify that an MMC/SD card has been inserted */
-
- ret = -ENODEV;
- mmcsd_semtake(&slot->sem);
- if ((SPI_STATUS(spi, SPIDEV_MMCSD) & SPI_STATUS_PRESENT) != 0)
- {
- /* Yes.. a card is present. Has it been initialized? */
-
- if (slot->type == MMCSD_CARDTYPE_UNKNOWN)
- {
- /* Ininitialize for the media in the slot */
-
- ret = mmcsd_mediainitialize(slot);
- if (ret < 0)
- {
- fvdbg("Failed to initialize card\n");
- goto errout_with_sem;
- }
- }
-
- /* Make sure that the card is ready */
-
- SPI_SELECT(spi, SPIDEV_MMCSD, true);
- ret = mmcsd_waitready(slot);
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- }
-
-errout_with_sem:
- mmcsd_semgive(&slot->sem);
- return ret;
-}
-
-/****************************************************************************
- * Name: mmcsd_close
- *
- * Description: close the block device
- *
- ****************************************************************************/
-
-static int mmcsd_close(FAR struct inode *inode)
-{
- fvdbg("Entry\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: mmcsd_read
- *
- * Description: Read the specified numer of sectors
- *
- ****************************************************************************/
-
-static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
- size_t start_sector, unsigned int nsectors)
-{
- FAR struct mmcsd_slot_s *slot;
- FAR struct spi_dev_s *spi;
- size_t nbytes;
- off_t offset;
- uint8_t response;
- int i;
-
- fvdbg("start_sector=%d nsectors=%d\n", start_sector, nsectors);
-
-#ifdef CONFIG_DEBUG
- if (!buffer)
- {
- fdbg("Invalid parameters\n");
- return -EINVAL;
- }
-
- if (!inode || !inode->i_private)
- {
- fdbg("Internal confusion\n");
- return -EIO;
- }
-#endif
-
- /* Extract our private data from the inode structure */
-
- slot = (FAR struct mmcsd_slot_s *)inode->i_private;
- spi = slot->spi;
-
-#ifdef CONFIG_DEBUG
- if (!spi)
- {
- fdbg("Internal confusion\n");
- return -EIO;
- }
-#endif
-
- /* Verify that card is available */
-
- if (slot->state & MMCSD_SLOTSTATUS_NOTREADY)
- {
- fdbg("Slot not ready\n");
- return -ENODEV;
- }
-
- /* Do nothing on zero-length transfer */
-
- if (nsectors < 1)
- {
- return 0;
- }
-
- /* Convert sector and nsectors to nbytes and byte offset */
-
- nbytes = nsectors * SECTORSIZE(slot);
- if (IS_BLOCK(slot->type))
- {
- offset = start_sector;
- fvdbg("nbytes=%d sector offset=%d\n", nbytes, offset);
- }
- else
- {
- offset = start_sector * SECTORSIZE(slot);
- fvdbg("nbytes=%d byte offset=%d\n", nbytes, offset);
- }
-
- /* Select the slave */
-
- mmcsd_semtake(&slot->sem);
- SPI_SELECT(spi, SPIDEV_MMCSD, true);
-
- /* Single or multiple block read? */
-
- if (nsectors == 1)
- {
- /* Send CMD17: Reads a block of the size selected by the SET_BLOCKLEN
- * command and verify that good R1 status is returned
- */
-
- response = mmcsd_sendcmd(slot, &g_cmd17, offset);
- if (response != MMCSD_SPIR1_OK)
- {
- fdbg("CMD17 failed: R1=%02x\n", response);
- goto errout_with_eio;
- }
-
- /* Receive the block */
-
- if (mmcsd_recvblock(slot, buffer, SECTORSIZE(slot)) != 0)
- {
- fdbg("Failed: to receive the block\n");
- goto errout_with_eio;
- }
- }
- else
- {
- /* Send CMD18: Reads a block of the size selected by the SET_BLOCKLEN
- * command and verify that good R1 status is returned
- */
-
- response = mmcsd_sendcmd(slot, &g_cmd18, offset);
- if (response != MMCSD_SPIR1_OK)
- {
- fdbg("CMD118 failed: R1=%02x\n", response);
- goto errout_with_eio;
- }
-
- /* Receive each block */
-
- for (i = 0; i < nsectors; i++)
- {
- if (mmcsd_recvblock(slot, buffer, SECTORSIZE(slot)) != 0)
- {
- fdbg("Failed: to receive the block\n");
- goto errout_with_eio;
- }
- buffer += SECTORSIZE(slot);
- }
-
- /* Send CMD12: Stops transmission */
-
- response = mmcsd_sendcmd(slot, &g_cmd12, 0);
- }
-
- /* On success, return the number of sectors transfer */
-
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- SPI_SEND(spi, 0xff);
- mmcsd_semgive(&slot->sem);
-
- fvdbg("Read %d bytes:\n", nbytes);
- mmcsd_dumpbuffer("Read buffer", buffer, nbytes);
- return nsectors;
-
-errout_with_eio:
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- mmcsd_semgive(&slot->sem);
- return -EIO;
-}
-
-/****************************************************************************
- * Name: mmcsd_write
- *
- * Description:
- * Write the specified number of sectors
- *
- ****************************************************************************/
-
-#if defined(CONFIG_FS_WRITABLE) && !defined(CONFIG_MMCSD_READONLY)
-static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
- size_t start_sector, unsigned int nsectors)
-{
- FAR struct mmcsd_slot_s *slot;
- FAR struct spi_dev_s *spi;
- size_t nbytes;
- off_t offset;
- uint8_t response;
- int ret;
- int i;
-
- fvdbg("start_sector=%d nsectors=%d\n", start_sector, nsectors);
-
-#ifdef CONFIG_DEBUG
- if (!buffer)
- {
- fdbg("Invalid parameters\n");
- return -EINVAL;
- }
-
- if (!inode || !inode->i_private)
- {
- fdbg("Internal confusion\n");
- return -EIO;
- }
-#endif
-
- /* Extract our private data from the inode structure */
-
- slot = (FAR struct mmcsd_slot_s *)inode->i_private;
- spi = slot->spi;
-
-#ifdef CONFIG_DEBUG
- if (!spi)
- {
- fdbg("Internal confusion\n");
- return -EIO;
- }
-#endif
-
- /* Verify that card is available */
-
- if (slot->state & MMCSD_SLOTSTATUS_NOTREADY)
- {
- fdbg("Slot not ready\n");
- return -ENODEV;
- }
-
- /* Verify that the card is write enabled */
-
- if (slot->state & MMCSD_SLOTSTATUS_WRPROTECT)
- {
- fdbg("Not write enabled\n");
- return -EACCES;
- }
-
- /* Do nothing on zero-length transfer */
-
- if (nsectors < 1)
- {
- return 0;
- }
-
- /* Convert sector and nsectors to nbytes and byte offset */
-
- nbytes = nsectors * SECTORSIZE(slot);
- if (IS_BLOCK(slot->type))
- {
- offset = start_sector;
- fvdbg("nbytes=%d sector offset=%d\n", nbytes, offset);
- }
- else
- {
- offset = start_sector * SECTORSIZE(slot);
- fvdbg("nbytes=%d byte offset=%d\n", nbytes, offset);
- }
- mmcsd_dumpbuffer("Write buffer", buffer, nbytes);
-
- /* Select the slave */
-
- mmcsd_semtake(&slot->sem);
- SPI_SELECT(spi, SPIDEV_MMCSD, true);
-
- /* Single or multiple block transfer? */
-
- if (nsectors == 1)
- {
- /* Send CMD24 (WRITE_BLOCK) and verify that good R1 status is returned */
-
- response = mmcsd_sendcmd(slot, &g_cmd24, offset);
- if (response != MMCSD_SPIR1_OK)
- {
- fdbg("CMD24 failed: R1=%02x\n", response);
- goto errout_with_sem;
- }
-
- /* Then transfer the sector */
-
- if (mmcsd_xmitblock(slot, buffer, SECTORSIZE(slot), 0xfe) != 0)
- {
- fdbg("Block transfer failed\n");
- goto errout_with_sem;
- }
- }
- else
- {
- /* Set the number of blocks to be pre-erased (SD only) */
-
- if (IS_SD(slot->type))
- {
- response = mmcsd_sendcmd(slot, &g_acmd23, nsectors);
- if (response != MMCSD_SPIR1_OK)
- {
- fdbg("ACMD23 failed: R1=%02x\n", response);
- goto errout_with_sem;
- }
- }
-
- /* Send CMD25: Continuously write blocks of data until the
- * tranmission is stopped.
- */
-
- response = mmcsd_sendcmd(slot, &g_cmd25, offset);
- if (response != MMCSD_SPIR1_OK)
- {
- fdbg("CMD25 failed: R1=%02x\n", response);
- goto errout_with_sem;
- }
-
- /* Transmit each block */
-
- for (i = 0; i < nsectors; i++)
- {
- if (mmcsd_xmitblock(slot, buffer, SECTORSIZE(slot), 0xfc) != 0)
- {
- fdbg("Failed: to receive the block\n");
- goto errout_with_sem;
- }
- buffer += SECTORSIZE(slot);
- }
-
- /* Send the stop transmission token */
-
- SPI_SEND(spi, MMCSD_SPIDT_STOPTRANS);
- }
-
- /* Wait until the card is no longer busy */
-
- ret = mmcsd_waitready(slot);
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- SPI_SEND(spi, 0xff);
- mmcsd_semgive(&slot->sem);
-
- /* The success return value is the number of sectors written */
-
- return nsectors;
-
-errout_with_sem:
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- mmcsd_semgive(&slot->sem);
- return -EIO;
-}
-#endif
-
-/****************************************************************************
- * Name: mmcsd_geometry
- *
- * Description:
- * Return device geometry
- *
- ****************************************************************************/
-
-static int mmcsd_geometry(FAR struct inode *inode, struct geometry *geometry)
-{
- FAR struct mmcsd_slot_s *slot;
- FAR struct spi_dev_s *spi;
- uint8_t csd[16];
- int ret;
-
-#ifdef CONFIG_DEBUG
- if (!geometry)
- {
- fdbg("Invalid parameters\n");
- return -EINVAL;
- }
-
- if (!inode || !inode->i_private)
- {
- fdbg("Internal confusion\n");
- return -EIO;
- }
-#endif
-
- /* Extract our private data from the inode structure */
-
- slot = (FAR struct mmcsd_slot_s *)inode->i_private;
- spi = slot->spi;
-
-#ifdef CONFIG_DEBUG
- if (!spi)
- {
- fdbg("Internal confusion\n");
- return -EIO;
- }
-#endif
-
- /* Re-sample the CSD */
-
- mmcsd_semtake(&slot->sem);
- SPI_SELECT(spi, SPIDEV_MMCSD, true);
- ret = mmcsd_getcsd(slot, csd);
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
-
- if (ret < 0)
- {
- mmcsd_semgive(&slot->sem);
- fdbg("mmcsd_getcsd returned %d\n", ret);
- return ret;
- }
-
- /* Check for changes related to write protection */
-
- mmcsd_checkwrprotect(slot, csd);
-
- /* Then return the card geometry */
-
- geometry->geo_available =
- ((slot->state & (MMCSD_SLOTSTATUS_NOTREADY|MMCSD_SLOTSTATUS_NODISK)) == 0);
- geometry->geo_mediachanged =
- ((slot->state & MMCSD_SLOTSTATUS_MEDIACHGD) != 0);
-#if defined(CONFIG_FS_WRITABLE) && !defined(CONFIG_MMCSD_READONLY)
- geometry->geo_writeenabled =
- ((slot->state & MMCSD_SLOTSTATUS_WRPROTECT) == 0);
-#else
- geometry->geo_writeenabled = false;
-#endif
- geometry->geo_nsectors = slot->nsectors;
- geometry->geo_sectorsize = SECTORSIZE(slot);
-
- /* After reporting mediachanged, clear the indication so that it is not
- * reported again.
- */
-
- slot->state &= ~MMCSD_SLOTSTATUS_MEDIACHGD;
- mmcsd_semgive(&slot->sem);
-
- fvdbg("geo_available: %d\n", geometry->geo_available);
- fvdbg("geo_mediachanged: %d\n", geometry->geo_mediachanged);
- fvdbg("geo_writeenabled: %d\n", geometry->geo_writeenabled);
- fvdbg("geo_nsectors: %d\n", geometry->geo_nsectors);
- fvdbg("geo_sectorsize: %d\n", geometry->geo_sectorsize);
-
- return OK;
-}
-
-/****************************************************************************
- * Initialization
- ****************************************************************************/
-
-/****************************************************************************
- * Name: mmcsd_mediainitialize
- *
- * Description:
- * Detect media and initialize
- *
- ****************************************************************************/
-
-static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
-{
- FAR struct spi_dev_s *spi = slot->spi;
- uint8_t csd[16];
- uint32_t result = MMCSD_SPIR1_IDLESTATE;
- uint32_t start;
- uint32_t elapsed;
- int i, j;
-
- /* Assume that the card is not ready (we'll clear this on successful card
- * initialization.
- */
-
- slot->state |= MMCSD_SLOTSTATUS_NOTREADY;
-
- /* Check if there is a card present in the slot. This is normally a matter is
- * of GPIO sensing and does not really involve SPI, but by putting this
- * functionality in the SPI interface, we encapuslate the SPI MMC/SD
- * interface
- */
-
- if ((SPI_STATUS(spi, SPIDEV_MMCSD) & SPI_STATUS_PRESENT) == 0)
- {
- fdbg("No card present\n");
- slot->state |= MMCSD_SLOTSTATUS_NODISK;
- return -ENODEV;
- }
-
- /* Clock Freq. Identification Mode < 400kHz */
-
- SPI_SETFREQUENCY(spi, MMCSD_IDMODE_CLOCK);
-
- /* Set the maximum access time out */
-
- slot->taccess = SD_READACCESS;
-
- /* The SD card wakes up in SD mode. It will enter SPI mode if the chip select signal is
- * asserted (negative) during the reception of the reset command (CMD0) and the card is in
- * IDLE state.
- */
-
- for (i = 0; i < 2; i++)
- {
- /* After power up at least 74 clock cycles are required prior to
- * starting bus communication
- */
-
- for (j = 10; j; j--)
- {
- SPI_SEND(spi, 0xff);
- }
-
- /* Send CMD0 (GO_TO_IDLE) with CS asserted to put MMC/SD in
- * IDLE/SPI mode. Return from CMD0 is R1 which should now
- * show IDLE STATE
- */
-
- fvdbg("Send CMD0\n");
- SPI_SELECT(spi, SPIDEV_MMCSD, true);
- result = mmcsd_sendcmd(slot, &g_cmd0, 0);
- if (result == MMCSD_SPIR1_IDLESTATE)
- {
- /* Break out of the loop with card selected */
-
- fvdbg("Card is in IDLE state\n");
- break;
- }
-
- /* De-select card and try again */
-
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- }
-
- /* Verify that we exit the above loop with the card reporting IDLE state */
-
- if (result != MMCSD_SPIR1_IDLESTATE)
- {
- fdbg("Send CMD0 failed: R1=%02x\n", result);
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- return -EIO;
- }
-
- slot->type = MMCSD_CARDTYPE_UNKNOWN;
-
- /* Check for SDHC Version 2.x. CMD 8 is reserved on SD version 1.0 and MMC. */
-
- fvdbg("Send CMD8\n");
- result = mmcsd_sendcmd(slot, &g_cmd8, 0x1aa);
- if (result == MMCSD_SPIR1_IDLESTATE)
- {
- /* Verify the operating voltage and that the 0xaa was correctly echoed */
-
- if (((slot->r7 & MMCSD_SPIR7_VOLTAGE_MASK) == MMCSD_SPIR7_VOLTAGE_27) &&
- ((slot->r7 & MMCSD_SPIR7_ECHO_MASK) == 0xaa))
- {
- /* Try CMD55/ACMD41 for up to 1 second or until the card exits
- * the IDLE state
- */
-
- start = START_TIME;
- elapsed = 0;
- do
- {
- fvdbg("%d. Send CMD55/ACMD41\n", elapsed);
- result = mmcsd_sendcmd(slot, &g_cmd55, 0);
- if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
- {
- result = mmcsd_sendcmd(slot, &g_acmd41, (uint32_t)1 << 30);
- if (result == MMCSD_SPIR1_OK)
- {
- break;
- }
- }
- elapsed = ELAPSED_TIME(start);
- }
- while (elapsed < MMCSD_DELAY_1SEC);
-
- /* Check if ACMD41 was sent successfully */
-
- if (elapsed < MMCSD_DELAY_1SEC)
- {
- fvdbg("Send CMD58\n");
- SPI_SEND(spi, 0xff);
- result = mmcsd_sendcmd(slot, &g_cmd58, 0);
- if (result == MMCSD_SPIR1_OK)
- {
- fvdbg("OCR: %08x\n", slot->ocr);
- if ((slot->ocr & MMCSD_OCR_CCS) != 0)
- {
- fdbg("Identified SD ver2 card/with block access\n");
- slot->type = MMCSD_CARDTYPE_SDV2|MMCSD_CARDTYPE_BLOCK;
- }
- else
- {
- fdbg("Identified SD ver2 card\n");
- slot->type = MMCSD_CARDTYPE_SDV2;
- }
- }
- }
- }
- }
-
- /* Check for SDC version 1.x or MMC */
-
- else
- {
- /* Both the MMC card and the SD card support CMD55 */
-
- fvdbg("Send CMD55/ACMD41\n");
- result = mmcsd_sendcmd(slot, &g_cmd55, 0);
- if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
- {
- /* But ACMD41 is supported only on SD */
-
- result = mmcsd_sendcmd(slot, &g_acmd41, 0);
- if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
- {
- fdbg("Identified SD ver1 card\n");
- slot->type = MMCSD_CARDTYPE_SDV1;
- }
- }
-
- /* Make sure that we are out of the Idle state */
-
- start = START_TIME;
- elapsed = 0;
- do
- {
- if (IS_SD(slot->type))
- {
- fvdbg("%d. Send CMD55/ACMD41\n", elapsed);
- result = mmcsd_sendcmd(slot, &g_cmd55, 0);
- if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
- {
- result = mmcsd_sendcmd(slot, &g_acmd41, 0);
- if (result == MMCSD_SPIR1_OK)
- {
- break;
- }
- }
- }
- else
- {
- fvdbg("%d. Send CMD1\n", i);
- result = mmcsd_sendcmd(slot, &g_cmd1, 0);
- if (result == MMCSD_SPIR1_OK)
- {
- fdbg("%d. Identified MMC card\n", i);
- slot->type = MMCSD_CARDTYPE_MMC;
- break;
- }
- }
- elapsed = ELAPSED_TIME(start);
- }
- while (elapsed < MMCSD_DELAY_1SEC);
-
- if (elapsed >= MMCSD_DELAY_1SEC)
- {
- fdbg("Failed to exit IDLE state\n");
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- return -EIO;
- }
- }
-
- if (slot->type == MMCSD_CARDTYPE_UNKNOWN)
- {
- fdbg("Failed to identify card\n");
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- return -EIO;
- }
-
- /* Read CSD. CSD must always be valid */
-
- fvdbg("Get CSD\n");
- result = mmcsd_getcsd(slot, csd);
- if (result != OK)
- {
- fdbg("mmcsd_getcsd(CMD9) failed: %d\n", result);
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- return -EIO;
- }
- mmcsd_dmpcsd(csd, slot->type);
-
- /* CSD data and set block size */
-
- mmcsd_decodecsd(slot, csd);
- mmcsd_checkwrprotect(slot, csd);
-
- /* SDHC ver2.x cards have fixed block transfer size of 512 bytes. SDC
- * ver1.x cards with capacity less than 1Gb, will have sector size
- * 512 byes. SDC ver1.x cards with capacity of 2Gb will report readbllen
- * of 1024 but should use 512 bytes for block transfers. SDC ver1.x 4Gb
- * cards will report readbllen of 2048 bytes -- are they also 512 bytes?
- * I think that none of these high capacity cards support setting the
- * block length??
- */
-
-#ifdef CONFIG_MMCSD_SECTOR512
- /* Using 512 byte sectors, the maximum ver1.x capacity is 4096 x 512 blocks.
- * The saved slot->nsectors is converted to 512 byte blocks, so if slot->nsectors
- * exceeds 4096 x 512, then we must be dealing with a card with read_bl_len
- * of 1024 or 2048.
- */
-
- if (!IS_SDV2(slot->type) && slot->nsectors <= ((uint32_t)4096*12))
- {
- /* Don't set the block len on high capacity cards (ver1.x or ver2.x) */
-
- mmcsd_setblklen(slot, SECTORSIZE(slot));
- }
-#else
- if (!IS_SDV2(slot->type))
- {
- /* Don't set the block len on ver2.x cards */
-
- mmcsd_setblklen(slot, SECTORSIZE(slot));
- }
-#endif
-
- slot->state &= ~MMCSD_SLOTSTATUS_NOTREADY;
- SPI_SELECT(spi, SPIDEV_MMCSD, false);
- return OK;
-}
-
-/****************************************************************************
- * Name: mmcsd_mediachanged
- *
- * Description:
- * Handle initialization/media change events
- *
- ****************************************************************************/
-
-static void mmcsd_mediachanged(void *arg)
-{
- struct mmcsd_slot_s *slot = (struct mmcsd_slot_s*)arg;
- FAR struct spi_dev_s *spi;
- uint8_t oldstate;
- int ret;
-
-#ifdef CONFIG_DEBUG
- if (!slot || !slot->spi)
- {
- fdbg("Internal confusion\n");
- return;
- }
-#endif
- spi = slot->spi;
-
- /* Save the current slot state and reassess the new state */
-
- mmcsd_semtake(&slot->sem);
- oldstate = slot->state;
-
- /* Check if media was removed or inserted */
-
- slot->state &= ~(MMCSD_SLOTSTATUS_NODISK|MMCSD_SLOTSTATUS_NOTREADY|MMCSD_SLOTSTATUS_MEDIACHGD);
- if ((SPI_STATUS(spi, SPIDEV_MMCSD) & SPI_STATUS_PRESENT) == 0)
- {
- /* Media is not present */
-
- fdbg("No card present\n");
- slot->state |= (MMCSD_SLOTSTATUS_NODISK|MMCSD_SLOTSTATUS_NOTREADY);
-
- /* Was media removed? */
-
- if ((oldstate & MMCSD_SLOTSTATUS_NODISK) == 0)
- {
- slot->state |= MMCSD_SLOTSTATUS_MEDIACHGD;
- }
- }
-
- /* Media is present, was it just inserted? Or, if it was previously not ready,
- * then try re-initializing it
- */
-
- else if ((oldstate & (MMCSD_SLOTSTATUS_NODISK|MMCSD_SLOTSTATUS_NOTREADY)) != 0)
- {
- /* (Re-)ininitialize for the media in the slot */
-
- ret = mmcsd_mediainitialize(slot);
- if (ret == 0)
- {
- fvdbg("mmcsd_mediainitialize returned OK\n");
- slot->state |= MMCSD_SLOTSTATUS_MEDIACHGD;
- }
- }
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: mmcsd_spislotinitialize
- *
- * Description:
- * Initialize one slot for operation using the SPI MMC/SD interface
- *
- * Input Parameters:
- * minor - The MMC/SD minor device number. The MMC/SD device will be
- * registered as /dev/mmcsdN where N is the minor number
- * slotno - The slot number to use. This is only meaningful for architectures
- * that support multiple MMC/SD slots. This value must be in the range
- * {0, ..., CONFIG_MMCSD_NSLOTS}.
- * spi - And instance of an SPI interface obtained by called
- * up_spiinitialize() with the appropriate port number (see spi.h)
- *
- ****************************************************************************/
-
-int mmcsd_spislotinitialize(int minor, int slotno, FAR struct spi_dev_s *spi)
-{
- struct mmcsd_slot_s *slot;
- char devname[16];
- int ret;
-
-#ifdef CONFIG_DEBUG
- if ((unsigned)slotno >= CONFIG_MMCSD_NSLOTS || (unsigned)minor > 255 || !spi)
- {
- fdbg("Invalid arguments\n");
- return -EINVAL;
- }
-#endif
-
- /* Select the slot structure */
-
- slot = &g_mmcsdslot[slotno];
- memset(slot, 0, sizeof(struct mmcsd_slot_s));
- sem_init(&slot->sem, 0, 1);
-
-#ifdef CONFIG_DEBUG
- if (slot->spi)
- {
- fdbg("Already registered\n");
- return -EBUSY;
- }
-#endif
-
- /* Bind the SPI port to the slot */
-
- slot->spi = spi;
-
- /* Ininitialize for the media in the slot (if any) */
-
- ret = mmcsd_mediainitialize(slot);
- if (ret == 0)
- {
- fvdbg("mmcsd_mediainitialize returned OK\n");
- slot->state |= MMCSD_SLOTSTATUS_MEDIACHGD;
- }
-
- /* Create a MMC/SD device name */
-
- snprintf(devname, 16, "/dev/mmcsd%d", minor);
-
- /* Register the driver, even on a failure condition. A
- * card may be inserted later, for example.
- */
-
- ret = register_blockdriver(devname, &g_bops, MMCSD_MODE, slot);
- if (ret < 0)
- {
- fdbg("register_blockdriver failed: %d\n", -ret);
- slot->spi = NULL;
- return ret;
- }
-
- /* Register a media change callback to handler insertion and
- * removal of cards.
- */
-
- (void)SPI_REGISTERCALLBACK(spi, mmcsd_mediachanged, (void*)slot);
- return OK;
-}
-
-#endif /* defined (CONFIG_MMCSD) && defined (CONFIG_MMCSD_SPI) */
diff --git a/nuttx/drivers/mmcsd/mmcsd_spi.h b/nuttx/drivers/mmcsd/mmcsd_spi.h
deleted file mode 100644
index 8c6f9bae7..000000000
--- a/nuttx/drivers/mmcsd/mmcsd_spi.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/****************************************************************************
- * drivers/mmcsd/mmcsd_spi.h
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_MMCSD_MMCSD_SPI_H
-#define __DRIVERS_MMCSD_MMCSD_SPI_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-/****************************************************************************
- * Pre-Processor Definitions
- ****************************************************************************/
-
-/* SPI *******************************************************************/
-
-/* SPI Command Set */
-
-#define CMD0 0x40 /* GO_IDLE_STATE: Resets all cards to idle state */
-#define CMD1 0x41 /* SEND_OP_COND: Sends capacity support information */
-#define CMD6 0x46 /* SWITCH_FUNC: Checks switchable function */
-#define CMD8 0x48 /* SEND_IF_COND: Sends SD Memory Card interface condition */
-#define CMD9 0x49 /* SEND_CSD: Asks card to send its card specific data (CSD) */
-#define CMD10 0x4a /* SEND_CID: Asks card to send its card identification (CID) */
-#define CMD12 0x4c /* STOP_TRANSMISSION: Forces the card to stop transmission */
-#define CMD13 0x4d /* SEND_STATUS: Asks card to send its status register */
-#define CMD16 0x50 /* SET_BLOCKLEN: Sets a block length (in bytes) */
-#define CMD17 0x51 /* READ_SINGLE_BLOCK: Reads a block of the selected size */
-#define CMD18 0x52 /* READ_MULTIPLE_BLOCK: Continuously transfers blocks from card to host */
-#define CMD20 0x54 /* CMD_WRITEBLOCK: Write block to memory (MMC) */
-#define CMD24 0x58 /* WRITE_BLOCK: Writes a block of the selected size */
-#define CMD25 0x59 /* WRITE_MULTIPLE_BLOCK: Continuously writes blocks of data */
-#define CMD27 0x5b /* PROGRAM_CSD: Set programmable bits of the CSD */
-#define CMD28 0x5c /* SET_WRITE_PROT: Sets the write protection bit of group */
-#define CMD29 0x5d /* CLR_WRITE_PROT: Clears the write protection bit of group */
-#define CMD30 0x5e /* SEND_WRITE_PROT: Asks card to send state of write protection bits */
-#define CMD32 0x60 /* ERASE_WR_BLK_START_ADDR: Sets address of first block to erase */
-#define CMD33 0x61 /* ERASE_WR_BLK_END_ADDR: Sets address of last block to erase */
-#define CMD34 0x62 /* UNTAG_SECTOR: (MMC) */
-#define CMD35 0x63 /* TAG_ERASE_GROUP_START: (MMC) */
-#define CMD36 0x64 /* TAG_ERASE_GOUPR_END: (MMC) */
-#define CMD37 0x65 /* UNTAG_ERASE_GROUP: (MMC) */
-#define CMD38 0x66 /* ERASE: Erases all previously selected write blocks */
-#define CMD40 0x68 /* CRC_ON_OFF: (MMC) */
-#define CMD42 0x6a /* LOCK_UNLOCK: Used to Set/Reset the Password or lock/unlock card */
-#define CMD55 0x77 /* APP_CMD: Tells card that the next command is an application specific command */
-#define CMD56 0x78 /* GEN_CMD: Used transfer a block to or get block from card */
-#define CMD58 0x7a /* READ_OCR :Reads the OCR register of a card */
-#define CMD59 0x7b /* CRC_ON_OFF: Turns the CRC option on or off */
-#define ACMD13 0x4d /* SD_STATUS: Send the SD Status */
-#define ACMD22 0x56 /* SEND_NUM_WR_BLOCKS: Send number of the errorfree blocks */
-#define ACMD23 0x57 /* SET_WR_BLK_ERASE_COUNT: Set number blocks to erase before writing */
-#define ACMD41 0x69 /* SD_SEND_OP_COND: Sends host capacity support information */
-#define ACMD42 0x6a /* SET_CLR_CARD_DETECT: Connect/disconnect pull-up resistor on CS */
-#define ACMD51 0x73 /* SEND_SCR: Reads the SD Configuration Register (SCR) */
-
-/* SPI 8-bit R1 response */
-
-#define MMCSD_SPIR1_OK 0x00 /* No error bits set */
-#define MMCSD_SPIR1_IDLESTATE 0x01 /* Idle state */
-#define MMCSD_SPIR1_ERASERESET 0x02 /* Erase reset */
-#define MMCSD_SPIR1_ILLEGALCMD 0x04 /* Illegal command */
-#define MMCSD_SPIR1_CRCERROR 0x08 /* Com CRC error */
-#define MMCSD_SPIR1_ERASEERROR 0x10 /* Erase sequence error */
-#define MMCSD_SPIR1_ADDRERROR 0x20 /* Address error */
-#define MMCSD_SPIR1_PARAMERROR 0x40 /* Parameter error */
-
-/* SPI 8-bit R2 response */
-
-#define MMCSD_SPIR2_CARDLOCKED 0x0001 /* Card is locked */
-#define MMCSD_SPIR2_WPERASESKIP 0x0002 /* WP erase skip */
-#define MMCSD_SPIR2_LOCKFAIL 0x0002 /* Lock/unlock cmd failed */
-#define MMCSD_SPIR2_ERROR 0x0004 /* Error */
-#define MMCSD_SPIR2_CCERROR 0x0008 /* CC error */
-#define MMCSD_SPIR2_CARDECCFAIL 0x0010 /* Card ECC failed */
-#define MMCSD_SPIR2_WPVIOLATION 0x0020 /* WP violoation */
-#define MMCSD_SPIR2_ERASEPARAM 0x0040 /* Erase parameter */
-#define MMCSD_SPIR2_OUTOFRANGE 0x0080 /* Out of range */
-#define MMCSD_SPIR2_CSDOVERWRITE 0x0080 /* CSD overwrite */
-#define MMCSD_SPIR2_IDLESTATE 0x0100 /* In idle state */
-#define MMCSD_SPIR2_ERASERESET 0x0200 /* Erase reset */
-#define MMCSD_SPIR2_ILLEGALCMD 0x0400 /* Illegal command */
-#define MMCSD_SPIR2_CRCERROR 0x0800 /* Com CRC error */
-#define MMCSD_SPIR2_ERASEERROR 0x1000 /* Erase sequence error */
-#define MMCSD_SPIR2_ADDRERROR 0x2000 /* Address error */
-#define MMCSD_SPIR2_PARAMERROR 0x4000 /* Parameter error */
-
-/* Last 4 bytes of the 5 byte R7 response */
-
-#define MMCSD_SPIR7_VERSION_SHIFT (28) /* Bits 28-31: Command version number */
-#define MMCSD_SPIR7_VERSION_MASK ((uint32_t)0x0f << MMCSD_SPIR7_VERSION_SHIFT)
-#define MMCSD_SPIR7_VOLTAGE_SHIFT (8) /* Bits 8-11: Voltage accepted */
-#define MMCSD_SPIR7_VOLTAGE_MASK ((uint32_t)0x0f << MMCSD_SPIR7_VOLTAGE_SHIFT)
-#define MMCSD_SPIR7_VOLTAGE_27 ((uint32_t)0x01 << MMCSD_SPIR7_VOLTAGE_SHIFT) /* 2.7-3.6V */
-#define MMCSD_SPIR7_ECHO_SHIFT (0) /* Bits 0-7: Echoed check pattern */
-#define MMCSD_SPIR7_ECHO_MASK ((uint32_t)0xff << MMCSD_SPIR7_ECHO_SHIFT)
-
-/* Data Response */
-
-#define MMCSD_SPIDR_MASK 0x1f /* Mask for valid data response bits */
-#define MMCSD_SPIDR_ACCEPTED 0x05 /* Data accepted */
-#define MMCSD_SPIDR_CRCERROR 0x0b /* Data rejected due to CRC error */
-#define MMCSD_SPIDR_WRERROR 0x0d /* Data rejected due to write error */
-
-/* Data Tokens */
-
-#define MMCSD_SPIDT_STARTBLKSNGL 0xfe /* First byte of block, single block */
-#define MMCSD_SPIDT_STARTBLKMULTI 0xfc /* First byte of block, multi-block */
-#define MMCSD_SPIDT_STOPTRANS 0xfd /* Stop transmission */
-
-/* Data error token */
-
-#define MMCSD_SPIDET_UPPER 0xf0 /* The upper four bits are zero */
-#define MMCSD_SPIDET_ERROR 0x01 /* Error */
-#define MMCSD_SPIDET_CCERROR 0x02 /* CC error */
-#define MMCSD_SPIDET_CARDECCFAIL 0x04 /* Card ECC failed */
-#define MMCSD_SPIDET_OUTOFRANGE 0x08 /* Out of range */
-
-/* Operating Conditions register */
-
-#define MMCSD_OCR_V27 ((uint32_t)1 << 15) /* Bit 15: 2.7-2.8V */
-#define MMCSD_OCR_V28 ((uint32_t)1 << 16) /* Bit 16: 2.8-2.9V */
-#define MMCSD_OCR_V29 ((uint32_t)1 << 17) /* Bit 17: 2.9-3.0V */
-#define MMCSD_OCR_V30 ((uint32_t)1 << 18) /* Bit 18: 3.0-3.1V */
-#define MMCSD_OCR_V31 ((uint32_t)1 << 19) /* Bit 19: 3.1-3.2V */
-#define MMCSD_OCR_V32 ((uint32_t)1 << 20) /* Bit 20: 3.2-3.3V */
-#define MMCSD_OCR_V33 ((uint32_t)1 << 21) /* Bit 21: 3.3-3.4V */
-#define MMCSD_OCR_V34 ((uint32_t)1 << 22) /* Bit 22: 3.4-3.5V */
-#define MMCSD_OCR_V35 ((uint32_t)1 << 23) /* Bit 23: 3.5-3.6V */
-#define MMCSD_OCR_CCS ((uint32_t)1 << 30) /* Bit 30: Card capacity status */
-#define MMCSD_OCR_BUSY ((uint32_t)1 << 31) /* Bit 31: Card powered up status bit */
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-#endif /* __DRIVERS_MMCSD_MMCSD_SPI_H */
diff --git a/nuttx/drivers/mtd/Kconfig b/nuttx/drivers/mtd/Kconfig
deleted file mode 100644
index ae656c474..000000000
--- a/nuttx/drivers/mtd/Kconfig
+++ /dev/null
@@ -1,133 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-config MTD_AT24XX
- bool "I2C-based AT24XX eeprom"
- default n
- select I2C
-
-config AT24XX_SIZE
- int "at24xx size(kByte)"
- default 64
- depends on MTD_AT24XX
-
-config AT24XX_ADDR
- hex "at24xx i2c address"
- default 0x50
- depends on MTD_AT24XX
-
-config MTD_AT45DB
- bool "SPI-based AT45DB flash"
- default n
- select SPI
-
-config AT45DB_FREQUENCY
- int "at45db frequency"
- default 1000000
- depends on MTD_AT45DB
-
-config AT45DB_PREWAIT
- bool "enables higher performance write logic"
- default y
- depends on MTD_AT45DB
-
-config AT45DB_PWRSAVE
- bool "enables power save"
- default n
- depends on MTD_AT45DB
-
-config MTD_MP25P
- bool "SPI-based M25P FLASH"
- default n
- select SPI
-
-config MP25P_SPIMODE
- int "MP25P SPI mode"
- default 0
- depends on MTD_MP25P
-
-config MP25P_MANUFACTURER
- hex "MP25P manufacturers ID"
- default 0x20
- depends on MTD_MP25P
- ---help---
- Various manufacturers may have produced the parts. 0x20 is the manufacturer ID
- for the STMicro MP25x serial FLASH. If, for example, you are using the a Macronix
- International MX25 serial FLASH, the correct manufacturer ID would be 0xc2.
-
-config MTD_RAMTRON
- bool "SPI-based RAMTRON NVRAM Devices FM25V10"
- default n
- select SPI
- ---help---
- SPI-based RAMTRON NVRAM Devices FM25V10
-
-config MTD_RAM
- bool "Memory bus ram"
- default n
-
-config MTD_SST25
- bool "SPI-based SST25 FLASH"
- default n
- select SPI
-
-config SST25_SPIMODE
- int "SST25 SPI Mode"
- default 0
- depends on MTD_SST25
-
-config SST25_SPIFREQUENCY
- int "SST25 SPI Frequency"
- default 20000000
- depends on MTD_SST25
-
-config SST25_READONLY
- bool "SST25 Read-Only FLASH"
- default n
- depends on MTD_SST25
-
-config SST25_SECTOR512
- bool "Simulate 512 byte Erase Blocks"
- default n
- depends on MTD_SST25
-
-config SST25_SLOWWRITE
- bool
- default y
- depends on MTD_SST25
-
-config SST25_SLOWREAD
- bool
- default n
- depends on MTD_SST25
-
-config MTD_W25
- bool "SPI-based W25 FLASH"
- default n
- select SPI
-
-config W25_SPIMODE
- int "W25 SPI Mode"
- default 0
- depends on MTD_W25
-
-config W25_SPIFREQUENCY
- int "W25 SPI Frequency"
- default 20000000
- depends on MTD_W25
-
-config W25_READONLY
- bool "W25 Read-Only FLASH"
- default n
- depends on MTD_W25
-
-config W25_SECTOR512
- bool "Simulate 512 byte Erase Blocks"
- default n
- depends on MTD_W25
-
-config W25_SLOWREAD
- bool
- default n
- depends on MTD_W25
diff --git a/nuttx/drivers/mtd/Make.defs b/nuttx/drivers/mtd/Make.defs
deleted file mode 100644
index 3102f1447..000000000
--- a/nuttx/drivers/mtd/Make.defs
+++ /dev/null
@@ -1,65 +0,0 @@
-############################################################################
-# drivers/mtd/Make.defs
-# These driver supports various Memory Technology Devices (MTD) using the
-# NuttX MTD interface.
-#
-# Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-# Include MTD drivers
-
-ifeq ($(CONFIG_MTD),y)
-
-CSRCS += at45db.c flash_eraseall.c ftl.c m25px.c rammtd.c ramtron.c
-
-ifeq ($(CONFIG_MTD_AT24XX),y)
-CSRCS += at24xx.c
-endif
-
-ifeq ($(CONFIG_MTD_SST25),y)
-CSRCS += sst25.c
-endif
-
-ifeq ($(CONFIG_MTD_W25),y)
-CSRCS += w25.c
-endif
-
-ifeq ($(CONFIG_MTD_AT25),y)
-CSRCS += at25.c
-endif
-
-# Include MTD driver support
-
-DEPPATH += --dep-path mtd
-VPATH += :mtd
-
-endif
diff --git a/nuttx/drivers/mtd/at24xx.c b/nuttx/drivers/mtd/at24xx.c
deleted file mode 100644
index d157a9c47..000000000
--- a/nuttx/drivers/mtd/at24xx.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/************************************************************************************
- * drivers/mtd/at24xx.c
- * Driver for I2C-based at24cxx EEPROM(at24c32,at24c64,at24c128,at24c256)
- *
- * Copyright (C) 2011 Li Zhuoyi. All rights reserved.
- * Author: Li Zhuoyi <lzyy.cn@gmail.com>
- * History: 0.1 2011-08-20 initial version
- *
- * 2011-11-1 Added support for larger MTD block sizes: Hal Glenn <hglenn@2g-eng.com>
- *
- * Derived from drivers/mtd/m25px.c
- *
- * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/i2c.h>
-#include <nuttx/mtd.h>
-
-#ifdef CONFIG_MTD_AT24XX
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-/* As a minimum, the size of the AT24 part and its 7-bit I2C address are required. */
-
-#ifndef CONFIG_AT24XX_SIZE
-# warning "Assuming AT24 size 64"
-# define CONFIG_AT24XX_SIZE 64
-#endif
-#ifndef CONFIG_AT24XX_ADDR
-# warning "Assuming AT24 address of 0x50"
-# define CONFIG_AT24XX_ADDR 0x50
-#endif
-
-/* Get the part configuration based on the size configuration */
-
-#if CONFIG_AT24XX_SIZE == 32
-# define AT24XX_NPAGES 128
-# define AT24XX_PAGESIZE 32
-#elif CONFIG_AT24XX_SIZE == 48
-# define AT24XX_NPAGES 192
-# define AT24XX_PAGESIZE 32
-#elif CONFIG_AT24XX_SIZE == 64
-# define AT24XX_NPAGES 256
-# define AT24XX_PAGESIZE 32
-#elif CONFIG_AT24XX_SIZE == 128
-# define AT24XX_NPAGES 256
-# define AT24XX_PAGESIZE 64
-#elif CONFIG_AT24XX_SIZE == 256
-# define AT24XX_NPAGES 512
-# define AT24XX_PAGESIZE 64
-#endif
-
-/* For applications where a file system is used on the AT24, the tiny page sizes
- * will result in very inefficient FLASH usage. In such cases, it is better if
- * blocks are comprised of "clusters" of pages so that the file system block
- * size is, say, 256 or 512 bytes. In any event, the block size *must* be an
- * even multiple of the pages.
- */
-
-#ifndef CONFIG_AT24XX_MTD_BLOCKSIZE
-# warning "Assuming driver block size is the same as the FLASH page size"
-# define CONFIG_AT24XX_MTD_BLOCKSIZE AT24XX_PAGESIZE
-#endif
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-/* This type represents the state of the MTD device. The struct mtd_dev_s
- * must appear at the beginning of the definition so that you can freely
- * cast between pointers to struct mtd_dev_s and struct at24c_dev_s.
- */
-
-struct at24c_dev_s
-{
- struct mtd_dev_s mtd; /* MTD interface */
- FAR struct i2c_dev_s *dev; /* Saved I2C interface instance */
- uint8_t addr; /* I2C address */
- uint16_t pagesize; /* 32, 63 */
- uint16_t npages; /* 128, 256, 512, 1024 */
-};
-
-/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-
-/* MTD driver methods */
-
-static int at24c_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks);
-static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR uint8_t *buf);
-static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR const uint8_t *buf);
-static ssize_t at24c_read(FAR struct mtd_dev_s *dev, off_t offset,
- size_t nbytes,FAR uint8_t *buffer);
-static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
-
-/************************************************************************************
- * Private Data
- ************************************************************************************/
-
-/* At present, only a signal AT24 part is supported. In this case, a statically
- * allocated state structure may be used.
- */
-
-static struct at24c_dev_s g_at24c;
-
-/************************************************************************************
- * Private Functions
- ************************************************************************************/
-
-static int at24c_eraseall(FAR struct at24c_dev_s *priv)
-{
- int startblock = 0;
- uint8_t buf[AT24XX_PAGESIZE + 2];
-
- memset(&buf[2],0xff,priv->pagesize);
- I2C_SETADDRESS(priv->dev,priv->addr,7);
- I2C_SETFREQUENCY(priv->dev,100000);
-
- for (startblock = 0; startblock < priv->npages; startblock++)
- {
- uint16_t offset = startblock * priv->pagesize;
- buf[1] = offset & 0xff;
- buf[0] = (offset >> 8) & 0xff;
-
- while (I2C_WRITE(priv->dev, buf, 2) < 0)
- {
- usleep(1000);
- }
- I2C_WRITE(priv->dev, buf, priv->pagesize + 2);
- }
-
- return OK;
-}
-
-/************************************************************************************
- * Name: at24c_erase
- ************************************************************************************/
-
-static int at24c_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks)
-{
- /* EEprom need not erase */
-
- return (int)nblocks;
-}
-
-/************************************************************************************
- * Name: at24c_bread
- ************************************************************************************/
-
-static ssize_t at24c_bread(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR uint8_t *buffer)
-{
- FAR struct at24c_dev_s *priv = (FAR struct at24c_dev_s *)dev;
- size_t blocksleft;
-
-#if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE
- startblock *= (CONFIG_AT24XX_MTD_BLOCKSIZE / AT24XX_PAGESIZE);
- nblocks *= (CONFIG_AT24XX_MTD_BLOCKSIZE / AT24XX_PAGESIZE);
-#endif
- blocksleft = nblocks;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- if (startblock >= priv->npages)
- {
- return 0;
- }
-
- if (startblock + nblocks > priv->npages)
- {
- nblocks = priv->npages - startblock;
- }
-
- I2C_SETADDRESS(priv->dev,priv->addr,7);
- I2C_SETFREQUENCY(priv->dev,100000);
-
- while (blocksleft-- > 0)
- {
- uint16_t offset = startblock * priv->pagesize;
- uint8_t buf[2];
- buf[1] = offset & 0xff;
- buf[0] = (offset >> 8) & 0xff;
-
- while (I2C_WRITE(priv->dev, buf, 2) < 0)
- {
- fvdbg("wait\n");
- usleep(1000);
- }
-
- I2C_READ(priv->dev, buffer, priv->pagesize);
- startblock++;
- buffer += priv->pagesize;
- }
-
-#if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE
- return nblocks / (CONFIG_AT24XX_MTD_BLOCKSIZE / AT24XX_PAGESIZE);
-#else
- return nblocks;
-#endif
-}
-
-/************************************************************************************
- * Name: at24c_bwrite
- *
- * Operates on MTD block's and translates to FLASH pages
- *
- ************************************************************************************/
-
-static ssize_t at24c_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR const uint8_t *buffer)
-{
- FAR struct at24c_dev_s *priv = (FAR struct at24c_dev_s *)dev;
- size_t blocksleft;
- uint8_t buf[AT24XX_PAGESIZE+2];
-
-#if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE
- startblock *= (CONFIG_AT24XX_MTD_BLOCKSIZE / AT24XX_PAGESIZE);
- nblocks *= (CONFIG_AT24XX_MTD_BLOCKSIZE / AT24XX_PAGESIZE);
-#endif
- blocksleft = nblocks;
-
- if (startblock >= priv->npages)
- {
- return 0;
- }
-
- if (startblock + nblocks > priv->npages)
- {
- nblocks = priv->npages - startblock;
- }
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
- I2C_SETADDRESS(priv->dev, priv->addr, 7);
- I2C_SETFREQUENCY(priv->dev, 100000);
-
- while (blocksleft-- > 0)
- {
- uint16_t offset = startblock * priv->pagesize;
- while (I2C_WRITE(priv->dev, (uint8_t *)&offset, 2) < 0)
- {
- fvdbg("wait\n");
- usleep(1000);
- }
-
- buf[1] = offset & 0xff;
- buf[0] = (offset >> 8) & 0xff;
- memcpy(&buf[2], buffer, priv->pagesize);
-
- I2C_WRITE(priv->dev, buf, priv->pagesize + 2);
- startblock++;
- buffer += priv->pagesize;
- }
-
-#if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE
- return nblocks / (CONFIG_AT24XX_MTD_BLOCKSIZE / AT24XX_PAGESIZE);
-#else
- return nblocks;
-#endif
-}
-
-/************************************************************************************
- * Name: at24c_ioctl
- ************************************************************************************/
-
-static int at24c_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
-{
- FAR struct at24c_dev_s *priv = (FAR struct at24c_dev_s *)dev;
- int ret = -EINVAL; /* Assume good command with bad parameters */
-
- fvdbg("cmd: %d \n", cmd);
-
- switch (cmd)
- {
- case MTDIOC_GEOMETRY:
- {
- FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg);
- if (geo)
- {
- /* Populate the geometry structure with information need to know
- * the capacity and how to access the device.
- *
- * NOTE: that the device is treated as though it where just an array
- * of fixed size blocks. That is most likely not true, but the client
- * will expect the device logic to do whatever is necessary to make it
- * appear so.
- *
- * blocksize:
- * May be user defined. The block size for the at24XX devices may be
- * larger than the page size in order to better support file systems.
- * The read and write functions translate BLOCKS to pages for the
- * small flash devices
- * erasesize:
- * It has to be at least as big as the blocksize, bigger serves no
- * purpose.
- * neraseblocks
- * Note that the device size is in kilobits and must be scaled by
- * 1024 / 8
- */
-
-#if CONFIG_AT24XX_MTD_BLOCKSIZE > AT24XX_PAGESIZE
- geo->blocksize = CONFIG_AT24XX_MTD_BLOCKSIZE;
- geo->erasesize = CONFIG_AT24XX_MTD_BLOCKSIZE;
- geo->neraseblocks = (CONFIG_AT24XX_SIZE * 1024 / 8) / CONFIG_AT24XX_MTD_BLOCKSIZE;
-#else
- geo->blocksize = priv->pagesize;
- geo->erasesize = priv->pagesize;
- geo->neraseblocks = priv->npages;
-#endif
- ret = OK;
-
- fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n",
- geo->blocksize, geo->erasesize, geo->neraseblocks);
- }
- }
- break;
-
- case MTDIOC_BULKERASE:
- ret=at24c_eraseall(priv);
- break;
-
- case MTDIOC_XIPBASE:
- default:
- ret = -ENOTTY; /* Bad command */
- break;
- }
-
- return ret;
-}
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: at24c_initialize
- *
- * Description:
- * Create an initialize MTD device instance. MTD devices are not registered
- * in the file system, but are created as instances that can be bound to
- * other functions (such as a block or character driver front end).
- *
- ************************************************************************************/
-
-FAR struct mtd_dev_s *at24c_initialize(FAR struct i2c_dev_s *dev)
-{
- FAR struct at24c_dev_s *priv;
-
- fvdbg("dev: %p\n", dev);
-
- /* Allocate a state structure (we allocate the structure instead of using
- * a fixed, static allocation so that we can handle multiple FLASH devices.
- * The current implementation would handle only one FLASH part per I2C
- * device (only because of the SPIDEV_FLASH definition) and so would have
- * to be extended to handle multiple FLASH parts on the same I2C bus.
- */
-
- priv = &g_at24c;
- if (priv)
- {
- /* Initialize the allocated structure */
-
- priv->addr = CONFIG_AT24XX_ADDR;
- priv->pagesize = AT24XX_PAGESIZE;
- priv->npages = AT24XX_NPAGES;
-
- priv->mtd.erase = at24c_erase;
- priv->mtd.bread = at24c_bread;
- priv->mtd.bwrite = at24c_bwrite;
- priv->mtd.ioctl = at24c_ioctl;
- priv->dev = dev;
- }
-
- /* Return the implementation-specific state structure as the MTD device */
-
- fvdbg("Return %p\n", priv);
- return (FAR struct mtd_dev_s *)priv;
-}
-
-#endif
diff --git a/nuttx/drivers/mtd/at25.c b/nuttx/drivers/mtd/at25.c
deleted file mode 100644
index c58b16122..000000000
--- a/nuttx/drivers/mtd/at25.c
+++ /dev/null
@@ -1,710 +0,0 @@
-/************************************************************************************
- * drivers/mtd/at25.c
- * Driver for SPI-based AT25DF321 (32Mbit) flash.
- *
- * Copyright (C) 2009-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- * Petteri Aimonen <jpa@nx.mail.kapsi.fi>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/spi.h>
-#include <nuttx/mtd.h>
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-#ifndef CONFIG_AT25_SPIMODE
-# define CONFIG_AT25_SPIMODE SPIDEV_MODE0
-#endif
-
-/* AT25 Registers *******************************************************************/
-/* Indentification register values */
-
-#define AT25_MANUFACTURER 0x1F
-#define AT25_AT25DF321_TYPE 0x47 /* 32 M-bit */
-
-/* AT25DF321 capacity is 4,194,304 bytes:
- * (64 sectors) * (65,536 bytes per sector)
- * (16384 pages) * (256 bytes per page)
- */
-
-#define AT25_AT25DF321_SECTOR_SHIFT 12 /* Sector size 1 << 12 = 4096 */
-#define AT25_AT25DF321_NSECTORS 1024
-#define AT25_AT25DF321_PAGE_SHIFT 9 /* Page size 1 << 9 = 512 */
-#define AT25_AT25DF321_NPAGES 8192
-
-/* Instructions */
-/* Command Value N Description Addr Dummy Data */
-#define AT25_WREN 0x06 /* 1 Write Enable 0 0 0 */
-#define AT25_WRDI 0x04 /* 1 Write Disable 0 0 0 */
-#define AT25_RDID 0x9f /* 1 Read Identification 0 0 1-3 */
-#define AT25_RDSR 0x05 /* 1 Read Status Register 0 0 >=1 */
-#define AT25_WRSR 0x01 /* 1 Write Status Register 0 0 1 */
-#define AT25_READ 0x03 /* 1 Read Data Bytes 3 0 >=1 */
-#define AT25_FAST_READ 0x0b /* 1 Higher speed read 3 1 >=1 */
-#define AT25_PP 0x02 /* 1 Page Program 3 0 1-256 */
-#define AT25_SE 0x20 /* 1 Sector Erase 3 0 0 */
-#define AT25_BE 0xc7 /* 1 Bulk Erase 0 0 0 */
-#define AT25_DP 0xb9 /* 2 Deep power down 0 0 0 */
-#define AT25_RES 0xab /* 2 Read Electronic Signature 0 3 >=1 */
-
-/* Status register bit definitions */
-
-#define AT25_SR_WIP (1 << 0) /* Bit 0: Write in progress bit */
-#define AT25_SR_WEL (1 << 1) /* Bit 1: Write enable latch bit */
-#define AT25_SR_EPE (1 << 5) /* Bit 5: Erase/program error */
-#define AT25_SR_UNPROT 0x00 /* Global unprotect command */
-
-#define AT25_DUMMY 0xa5
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-/* This type represents the state of the MTD device. The struct mtd_dev_s
- * must appear at the beginning of the definition so that you can freely
- * cast between pointers to struct mtd_dev_s and struct at25_dev_s.
- */
-
-struct at25_dev_s
-{
- struct mtd_dev_s mtd; /* MTD interface */
- FAR struct spi_dev_s *dev; /* Saved SPI interface instance */
- uint8_t sectorshift; /* 16 or 18 */
- uint8_t pageshift; /* 8 */
- uint16_t nsectors; /* 128 or 64 */
- uint32_t npages; /* 32,768 or 65,536 */
-};
-
-/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-
-/* Helpers */
-
-static void at25_lock(FAR struct spi_dev_s *dev);
-static inline void at25_unlock(FAR struct spi_dev_s *dev);
-static inline int at25_readid(struct at25_dev_s *priv);
-static void at25_waitwritecomplete(struct at25_dev_s *priv);
-static void at25_writeenable(struct at25_dev_s *priv);
-static inline void at25_sectorerase(struct at25_dev_s *priv, off_t offset);
-static inline int at25_bulkerase(struct at25_dev_s *priv);
-static inline void at25_pagewrite(struct at25_dev_s *priv, FAR const uint8_t *buffer,
- off_t offset);
-
-/* MTD driver methods */
-
-static int at25_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks);
-static ssize_t at25_bread(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR uint8_t *buf);
-static ssize_t at25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR const uint8_t *buf);
-static ssize_t at25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer);
-static int at25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
-
-/************************************************************************************
- * Private Data
- ************************************************************************************/
-
-/************************************************************************************
- * Private Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: at25_lock
- ************************************************************************************/
-
-static void at25_lock(FAR struct spi_dev_s *dev)
-{
- /* On SPI busses where there are multiple devices, it will be necessary to
- * lock SPI to have exclusive access to the busses for a sequence of
- * transfers. The bus should be locked before the chip is selected.
- *
- * This is a blocking call and will not return until we have exclusiv access to
- * the SPI buss. We will retain that exclusive access until the bus is unlocked.
- */
-
- (void)SPI_LOCK(dev, true);
-
- /* After locking the SPI bus, the we also need call the setfrequency, setbits, and
- * setmode methods to make sure that the SPI is properly configured for the device.
- * If the SPI buss is being shared, then it may have been left in an incompatible
- * state.
- */
-
- SPI_SETMODE(dev, CONFIG_AT25_SPIMODE);
- SPI_SETBITS(dev, 8);
- (void)SPI_SETFREQUENCY(dev, 20000000);
-}
-
-/************************************************************************************
- * Name: at25_unlock
- ************************************************************************************/
-
-static inline void at25_unlock(FAR struct spi_dev_s *dev)
-{
- (void)SPI_LOCK(dev, false);
-}
-
-/************************************************************************************
- * Name: at25_readid
- ************************************************************************************/
-
-static inline int at25_readid(struct at25_dev_s *priv)
-{
- uint16_t manufacturer;
- uint16_t memory;
- uint16_t version;
-
- fvdbg("priv: %p\n", priv);
-
- /* Lock the SPI bus, configure the bus, and select this FLASH part. */
-
- at25_lock(priv->dev);
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send the "Read ID (RDID)" command and read the first three ID bytes */
-
- (void)SPI_SEND(priv->dev, AT25_RDID);
- manufacturer = SPI_SEND(priv->dev, AT25_DUMMY);
- memory = SPI_SEND(priv->dev, AT25_DUMMY);
-
- /* Deselect the FLASH and unlock the bus */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- at25_unlock(priv->dev);
-
- fvdbg("manufacturer: %02x memory: %02x\n",
- manufacturer, memory);
-
- /* Check for a valid manufacturer and memory type */
-
- if (manufacturer == AT25_MANUFACTURER && memory == AT25_AT25DF321_TYPE)
- {
- priv->sectorshift = AT25_AT25DF321_SECTOR_SHIFT;
- priv->nsectors = AT25_AT25DF321_NSECTORS;
- priv->pageshift = AT25_AT25DF321_PAGE_SHIFT;
- priv->npages = AT25_AT25DF321_NPAGES;
- return OK;
- }
-
- return -ENODEV;
-}
-
-/************************************************************************************
- * Name: at25_waitwritecomplete
- ************************************************************************************/
-
-static void at25_waitwritecomplete(struct at25_dev_s *priv)
-{
- uint8_t status;
-
- /* Are we the only device on the bus? */
-
-#ifdef CONFIG_SPI_OWNBUS
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read Status Register (RDSR)" command */
-
- (void)SPI_SEND(priv->dev, AT25_RDSR);
-
- /* Loop as long as the memory is busy with a write cycle */
-
- do
- {
- /* Send a dummy byte to generate the clock needed to shift out the status */
-
- status = SPI_SEND(priv->dev, AT25_DUMMY);
- }
- while ((status & AT25_SR_WIP) != 0);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-
-#else
-
- /* Loop as long as the memory is busy with a write cycle */
-
- do
- {
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read Status Register (RDSR)" command */
-
- (void)SPI_SEND(priv->dev, AT25_RDSR);
-
- /* Send a dummy byte to generate the clock needed to shift out the status */
-
- status = SPI_SEND(priv->dev, AT25_DUMMY);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-
- /* Given that writing could take up to few tens of milliseconds, and erasing
- * could take more. The following short delay in the "busy" case will allow
- * other peripherals to access the SPI bus.
- */
-
- if ((status & AT25_SR_WIP) != 0)
- {
- at25_unlock(priv->dev);
- usleep(10000);
- at25_lock(priv->dev);
- }
- }
- while ((status & AT25_SR_WIP) != 0);
-#endif
-
- if (status & AT25_SR_EPE)
- {
- fdbg("Write error, status: 0x%02x\n", status);
- }
-
- fvdbg("Complete, status: 0x%02x\n", status);
-}
-
-/************************************************************************************
- * Name: at25_writeenable
- ************************************************************************************/
-
-static void at25_writeenable(struct at25_dev_s *priv)
-{
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
- (void)SPI_SEND(priv->dev, AT25_WREN);
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Enabled\n");
-}
-
-/************************************************************************************
- * Name: at25_sectorerase
- ************************************************************************************/
-
-static inline void at25_sectorerase(struct at25_dev_s *priv, off_t sector)
-{
- off_t offset = sector << priv->sectorshift;
-
- fvdbg("sector: %08lx\n", (long)sector);
-
- /* Wait for any preceding write to complete. We could simplify things by
- * perform this wait at the end of each write operation (rather than at
- * the beginning of ALL operations), but have the wait first will slightly
- * improve performance.
- */
-
- at25_waitwritecomplete(priv);
-
- /* Send write enable instruction */
-
- at25_writeenable(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send the "Sector Erase (SE)" instruction */
-
- (void)SPI_SEND(priv->dev, AT25_SE);
-
- /* Send the sector offset high byte first. For all of the supported
- * parts, the sector number is completely contained in the first byte
- * and the values used in the following two bytes don't really matter.
- */
-
- (void)SPI_SEND(priv->dev, (offset >> 16) & 0xff);
- (void)SPI_SEND(priv->dev, (offset >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, offset & 0xff);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Erased\n");
-}
-
-/************************************************************************************
- * Name: at25_bulkerase
- ************************************************************************************/
-
-static inline int at25_bulkerase(struct at25_dev_s *priv)
-{
- fvdbg("priv: %p\n", priv);
-
- /* Wait for any preceding write to complete. We could simplify things by
- * perform this wait at the end of each write operation (rather than at
- * the beginning of ALL operations), but have the wait first will slightly
- * improve performance.
- */
-
- at25_waitwritecomplete(priv);
-
- /* Send write enable instruction */
-
- at25_writeenable(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send the "Bulk Erase (BE)" instruction */
-
- (void)SPI_SEND(priv->dev, AT25_BE);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Return: OK\n");
- return OK;
-}
-
-/************************************************************************************
- * Name: at25_pagewrite
- ************************************************************************************/
-
-static inline void at25_pagewrite(struct at25_dev_s *priv, FAR const uint8_t *buffer,
- off_t page)
-{
- off_t offset = page << 8;
-
- fvdbg("page: %08lx offset: %08lx\n", (long)page, (long)offset);
-
- /* Wait for any preceding write to complete. We could simplify things by
- * perform this wait at the end of each write operation (rather than at
- * the beginning of ALL operations), but have the wait first will slightly
- * improve performance.
- */
-
- at25_waitwritecomplete(priv);
-
- /* Enable the write access to the FLASH */
-
- at25_writeenable(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Page Program (PP)" command */
-
- (void)SPI_SEND(priv->dev, AT25_PP);
-
- /* Send the page offset high byte first. */
-
- (void)SPI_SEND(priv->dev, (offset >> 16) & 0xff);
- (void)SPI_SEND(priv->dev, (offset >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, offset & 0xff);
-
- /* Then write the specified number of bytes */
-
- SPI_SNDBLOCK(priv->dev, buffer, 256);
-
- /* Deselect the FLASH: Chip Select high */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Written\n");
-}
-
-/************************************************************************************
- * Name: at25_erase
- ************************************************************************************/
-
-static int at25_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks)
-{
- FAR struct at25_dev_s *priv = (FAR struct at25_dev_s *)dev;
- size_t blocksleft = nblocks;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Lock access to the SPI bus until we complete the erase */
-
- at25_lock(priv->dev);
- while (blocksleft-- > 0)
- {
- /* Erase each sector */
-
- at25_sectorerase(priv, startblock);
- startblock++;
- }
-
- at25_unlock(priv->dev);
- return (int)nblocks;
-}
-
-/************************************************************************************
- * Name: at25_bread
- ************************************************************************************/
-
-static ssize_t at25_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR uint8_t *buffer)
-{
- FAR struct at25_dev_s *priv = (FAR struct at25_dev_s *)dev;
- ssize_t nbytes;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* On this device, we can handle the block read just like the byte-oriented read */
-
- nbytes = at25_read(dev, startblock << priv->pageshift, nblocks << priv->pageshift, buffer);
- if (nbytes > 0)
- {
- return nbytes >> priv->pageshift;
- }
-
- return (int)nbytes;
-}
-
-/************************************************************************************
- * Name: at25_bwrite
- ************************************************************************************/
-
-static ssize_t at25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR const uint8_t *buffer)
-{
- FAR struct at25_dev_s *priv = (FAR struct at25_dev_s *)dev;
- size_t blocksleft = nblocks;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Lock the SPI bus and write each page to FLASH */
-
- at25_lock(priv->dev);
- while (blocksleft-- > 0)
- {
- at25_pagewrite(priv, buffer, startblock * 2);
- at25_pagewrite(priv, buffer + 256, startblock * 2 + 1);
- buffer += 1 << priv->pageshift;
- startblock++;
- }
-
- at25_unlock(priv->dev);
- return nblocks;
-}
-
-/************************************************************************************
- * Name: at25_read
- ************************************************************************************/
-
-static ssize_t at25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer)
-{
- FAR struct at25_dev_s *priv = (FAR struct at25_dev_s *)dev;
-
- fvdbg("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
-
- /* Wait for any preceding write to complete. We could simplify things by
- * perform this wait at the end of each write operation (rather than at
- * the beginning of ALL operations), but have the wait first will slightly
- * improve performance.
- */
-
- at25_waitwritecomplete(priv);
-
- /* Lock the SPI bus and select this FLASH part */
-
- at25_lock(priv->dev);
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read from Memory " instruction */
-
- (void)SPI_SEND(priv->dev, AT25_READ);
-
- /* Send the page offset high byte first. */
-
- (void)SPI_SEND(priv->dev, (offset >> 16) & 0xff);
- (void)SPI_SEND(priv->dev, (offset >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, offset & 0xff);
-
- /* Then read all of the requested bytes */
-
- SPI_RECVBLOCK(priv->dev, buffer, nbytes);
-
- /* Deselect the FLASH and unlock the SPI bus */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- at25_unlock(priv->dev);
-
- fvdbg("return nbytes: %d\n", (int)nbytes);
- return nbytes;
-}
-
-/************************************************************************************
- * Name: at25_ioctl
- ************************************************************************************/
-
-static int at25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
-{
- FAR struct at25_dev_s *priv = (FAR struct at25_dev_s *)dev;
- int ret = -EINVAL; /* Assume good command with bad parameters */
-
- fvdbg("cmd: %d \n", cmd);
-
- switch (cmd)
- {
- case MTDIOC_GEOMETRY:
- {
- FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg);
- if (geo)
- {
- /* Populate the geometry structure with information need to know
- * the capacity and how to access the device.
- *
- * NOTE: that the device is treated as though it where just an array
- * of fixed size blocks. That is most likely not true, but the client
- * will expect the device logic to do whatever is necessary to make it
- * appear so.
- */
-
- geo->blocksize = (1 << priv->pageshift);
- geo->erasesize = (1 << priv->sectorshift);
- geo->neraseblocks = priv->nsectors;
- ret = OK;
-
- fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n",
- geo->blocksize, geo->erasesize, geo->neraseblocks);
- }
- }
- break;
-
- case MTDIOC_BULKERASE:
- {
- /* Erase the entire device */
-
- at25_lock(priv->dev);
- ret = at25_bulkerase(priv);
- at25_unlock(priv->dev);
- }
- break;
-
- case MTDIOC_XIPBASE:
- default:
- ret = -ENOTTY; /* Bad command */
- break;
- }
-
- fvdbg("return %d\n", ret);
- return ret;
-}
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: at25_initialize
- *
- * Description:
- * Create an initialize MTD device instance. MTD devices are not registered
- * in the file system, but are created as instances that can be bound to
- * other functions (such as a block or character driver front end).
- *
- ************************************************************************************/
-
-FAR struct mtd_dev_s *at25_initialize(FAR struct spi_dev_s *dev)
-{
- FAR struct at25_dev_s *priv;
- int ret;
-
- fvdbg("dev: %p\n", dev);
-
- /* Allocate a state structure (we allocate the structure instead of using
- * a fixed, static allocation so that we can handle multiple FLASH devices.
- * The current implementation would handle only one FLASH part per SPI
- * device (only because of the SPIDEV_FLASH definition) and so would have
- * to be extended to handle multiple FLASH parts on the same SPI bus.
- */
-
- priv = (FAR struct at25_dev_s *)kmalloc(sizeof(struct at25_dev_s));
- if (priv)
- {
- /* Initialize the allocated structure */
-
- priv->mtd.erase = at25_erase;
- priv->mtd.bread = at25_bread;
- priv->mtd.bwrite = at25_bwrite;
- priv->mtd.read = at25_read;
- priv->mtd.ioctl = at25_ioctl;
- priv->dev = dev;
-
- /* Deselect the FLASH */
-
- SPI_SELECT(dev, SPIDEV_FLASH, false);
-
- /* Identify the FLASH chip and get its capacity */
-
- ret = at25_readid(priv);
- if (ret != OK)
- {
- /* Unrecognized! Discard all of that work we just did and return NULL */
-
- fdbg("Unrecognized\n");
- kfree(priv);
- priv = NULL;
- }
- else
- {
- /* Unprotect all sectors */
-
- at25_writeenable(priv);
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
- (void)SPI_SEND(priv->dev, AT25_WRSR);
- (void)SPI_SEND(priv->dev, AT25_SR_UNPROT);
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- }
- }
-
- /* Return the implementation-specific state structure as the MTD device */
-
- fvdbg("Return %p\n", priv);
- return (FAR struct mtd_dev_s *)priv;
-}
diff --git a/nuttx/drivers/mtd/at45db.c b/nuttx/drivers/mtd/at45db.c
deleted file mode 100644
index f3c0c72c1..000000000
--- a/nuttx/drivers/mtd/at45db.c
+++ /dev/null
@@ -1,899 +0,0 @@
-/************************************************************************************
- * drivers/mtd/at45db.c
- * Driver for SPI-based AT45DB161D (16Mbit)
- *
- * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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.
- *
- ************************************************************************************/
-
-/* Ordering Code Detail:
- *
- * AT 45DB 16 1 D – SS U
- * | | | | | | `- Device grade
- * | | | | | `- Package Option
- * | | | | `- Device revision
- * | | | `- Interface: 1=serial
- * | | `- Capacity: 16=16Mbit
- * | `- Product family
- * `- Atmel designator
- */
-
-/************************************************************************************
- * Included Files
- ************************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/arch.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/spi.h>
-#include <nuttx/mtd.h>
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-/* Configuration ********************************************************************/
-/* CONFIG_AT45DB_PREWAIT enables higher performance write logic: We leave the chip
- * busy after write and erase operations. This improves write and erase performance
- * because we do not have to wait as long between transactions (other processing can
- * occur while the chip is busy) but means that the chip must stay powered:
- */
-
-#if defined(CONFIG_AT45DB_PWRSAVE) && defined(CONFIG_AT45DB_PREWAIT)
-# error "Both CONFIG_AT45DB_PWRSAVE and CONFIG_AT45DB_PREWAIT are defined"
-#endif
-
-/* If the user has provided no frequency, use 1MHz */
-
-#ifndef CONFIG_AT45DB_FREQUENCY
-# define CONFIG_AT45DB_FREQUENCY 1000000
-#endif
-
-/* SPI Commands *********************************************************************/
-
-/* Read commands */
-
-#define AT45DB_RDMN 0xd2 /* Main Memory Page Read */
-#define AT45DB_RDARRY 0xe8 /* Continuous Array Read (Legacy Command) */
-#define AT45DB_RDARRAYLF 0x03 /* Continuous Array Read (Low Frequency) */
-#define AT45DB_RDARRAYHF 0x0b /* Continuous Array Read (High Frequency) */
-#define AT45DB_RDBF1LF 0xd1 /* Buffer 1 Read (Low Frequency) */
-#define AT45DB_RDBF2LF 0xd3 /* Buffer 2 Read (Low Frequency) */
-#define AT45DB_RDBF1 0xd4 /* Buffer 1 Read */
-#define AT45DB_RDBF2 0xd6 /* Buffer 2 Read */
-
-/* Program and Erase Commands */
-
-#define AT45DB_WRBF1 0x84 /* Buffer 1 Write */
-#define AT45DB_WRBF2 0x87 /* Buffer 2 Write */
-#define AT45DB_BF1TOMNE 0x83 /* Buffer 1 to Main Memory Page Program with Built-in Erase */
-#define AT45DB_BF2TOMNE 0x86 /* Buffer 2 to Main Memory Page Program with Built-in Erase */
-#define AT45DB_BF1TOMN 0x88 /* Buffer 1 to Main Memory Page Program without Built-in Erase */
-#define AT45DB_BF2TOMN 0x89 /* Buffer 2 to Main Memory Page Program without Built-in Erase */
-#define AT45DB_PGERASE 0x81 /* Page Erase */
-#define AT45DB_BLKERASE 0x50 /* Block Erase */
-#define AT45DB_SECTERASE 0x7c /* Sector Erase */
-#define AT45DB_CHIPERASE1 0xc7 /* Chip Erase - byte 1 */
-# define AT45DB_CHIPERASE2 0x94 /* Chip Erase - byte 2 */
-# define AT45DB_CHIPERASE3 0x80 /* Chip Erase - byte 3 */
-# define AT45DB_CHIPERASE4 0x9a /* Chip Erase - byte 4 */
-#define AT45DB_MNTHRUBF1 0x82 /* Main Memory Page Program Through Buffer 1 */
-#define AT45DB_MNTHRUBF2 0x85 /* Main Memory Page Program Through Buffer 2 */
-
-/* Protection and Security Commands */
-
-#define AT45DB_ENABPROT1 0x3d /* Enable Sector Protection - byte 1 */
-# define AT45DB_ENABPROT2 0x2a /* Enable Sector Protection - byte 2 */
-# define AT45DB_ENABPROT3 0x7f /* Enable Sector Protection - byte 3 */
-# define AT45DB_ENABPROT4 0xa9 /* Enable Sector Protection - byte 4 */
-#define AT45DB_DISABPROT1 0x3d /* Disable Sector Protection - byte 1 */
-# define AT45DB_DISABPROT2 0x2a /* Disable Sector Protection - byte 2 */
-# define AT45DB_DISABPROT3 0x7f /* Disable Sector Protection - byte 3 */
-# define AT45DB_DISABPROT4 0x9a /* Disable Sector Protection - byte 4 */
-#define AT45DB_ERASEPROT1 0x3d /* Erase Sector Protection Register - byte 1 */
-# define AT45DB_ERASEPROT2 0x2a /* Erase Sector Protection Register - byte 2 */
-# define AT45DB_ERASEPROT3 0x7f /* Erase Sector Protection Register - byte 3 */
-# define AT45DB_ERASEPROT4 0xcf /* Erase Sector Protection Register - byte 4 */
-#define AT45DB_PROGPROT1 0x3d /* Program Sector Protection Register - byte 1 */
-# define AT45DB_PROGPROT2 0x2a /* Program Sector Protection Register - byte 2 */
-# define AT45DB_PROGPROT3 0x7f /* Program Sector Protection Register - byte 3 */
-# define AT45DB_PROGPROT4 0xfc /* Program Sector Protection Register - byte 4 */
-#define AT45DB_RDPROT 0x32 /* Read Sector Protection Register */
-#define AT45DB_LOCKDOWN1 0x3d /* Sector Lockdown - byte 1 */
-# define AT45DB_LOCKDOWN2 0x2a /* Sector Lockdown - byte 2 */
-# define AT45DB_LOCKDOWN3 0x7f /* Sector Lockdown - byte 3 */
-# define AT45DB_LOCKDOWN4 0x30 /* Sector Lockdown - byte 4 */
-#define AT45DB_RDLOCKDOWN 0x35 /* Read Sector Lockdown Register */
-#define AT45DB_PROGSEC1 0x9b /* Program Security Register - byte 1 */
-# define AT45DB_PROGSEC2 0x00 /* Program Security Register - byte 2 */
-# define AT45DB_PROGSEC3 0x00 /* Program Security Register - byte 3 */
-# define AT45DB_PROGSEC4 0x00 /* Program Security Register - byte 4 */
-#define AT45DB_RDSEC 0x77 /* Read Security Register */
-
-/* Additional commands */
-
-#define AT45DB_MNTOBF1XFR 0x53 /* Main Memory Page to Buffer 1 Transfer */
-#define AT45DB_MNTOBF2XFR 0x55 /* Main Memory Page to Buffer 2 Transfer */
-#define AT45DB_MNBF1CMP 0x60 /* Main Memory Page to Buffer 1 Compare */
-#define AT45DB_MNBF2CMP 0x61 /* Main Memory Page to Buffer 2 Compare */
-#define AT45DB_AUTOWRBF1 0x58 /* Auto Page Rewrite through Buffer 1 */
-#define AT45DB_AUTOWRBF2 0x59 /* Auto Page Rewrite through Buffer 2 */
-#define AT45DB_PWRDOWN 0xb9 /* Deep Power-down */
-#define AT45DB_RESUME 0xab /* Resume from Deep Power-down */
-#define AT45DB_RDSR 0xd7 /* Status Register Read */
-#define AT45DB_RDDEVID 0x9f /* Manufacturer and Device ID Read */
-
-#define AT45DB_MANUFACTURER 0x1f /* Manufacturer ID: Atmel */
-#define AT45DB_DEVID1_CAPMSK 0x1f /* Bits 0-4: Capacity */
-#define AT45DB_DEVID1_1MBIT 0x02 /* xxx0 0010 = 1Mbit AT45DB011 */
-#define AT45DB_DEVID1_2MBIT 0x03 /* xxx0 0012 = 2Mbit AT45DB021 */
-#define AT45DB_DEVID1_4MBIT 0x04 /* xxx0 0100 = 4Mbit AT45DB041 */
-#define AT45DB_DEVID1_8MBIT 0x05 /* xxx0 0101 = 8Mbit AT45DB081 */
-#define AT45DB_DEVID1_16MBIT 0x06 /* xxx0 0110 = 16Mbit AT45DB161 */
-#define AT45DB_DEVID1_32MBIT 0x07 /* xxx0 0111 = 32Mbit AT45DB321 */
-#define AT45DB_DEVID1_64MBIT 0x08 /* xxx0 1000 = 32Mbit AT45DB641 */
-#define AT45DB_DEVID1_FAMMSK 0xe0 /* Bits 5-7: Family */
-#define AT45DB_DEVID1_DFLASH 0x20 /* 001x xxxx = Dataflash */
-#define AT45DB_DEVID1_AT26DF 0x40 /* 010x xxxx = AT26DFxxx series (Not supported) */
-#define AT45DB_DEVID2_VERMSK 0x1f /* Bits 0-4: MLC mask */
-#define AT45DB_DEVID2_MLCMSK 0xe0 /* Bits 5-7: MLC mask */
-
-/* Status register bit definitions */
-
-#define AT45DB_SR_RDY (1 << 7) /* Bit 7: RDY/ Not BUSY */
-#define AT45DB_SR_COMP (1 << 6) /* Bit 6: COMP */
-#define AT45DB_SR_PROTECT (1 << 1) /* Bit 1: PROTECT */
-#define AT45DB_SR_PGSIZE (1 << 0) /* Bit 0: PAGE_SIZE */
-
-/* 1 Block = 16 pages; 1 sector = 256 pages */
-
-#define PG_PER_BLOCK (16)
-#define PG_PER_SECTOR (256)
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-/* This type represents the state of the MTD device. The struct mtd_dev_s
- * must appear at the beginning of the definition so that you can freely
- * cast between pointers to struct mtd_dev_s and struct at45db_dev_s.
- */
-
-struct at45db_dev_s
-{
- struct mtd_dev_s mtd; /* MTD interface */
- FAR struct spi_dev_s *spi; /* Saved SPI interface instance */
- uint8_t pageshift; /* log2 of the page size (eg. 1 << 9 = 512) */
- uint32_t npages; /* Number of pages in the device */
-};
-
-/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-
-/* Lock and per-transaction configuration */
-
-static void at45db_lock(struct at45db_dev_s *priv);
-static inline void at45db_unlock(struct at45db_dev_s *priv);
-
-/* Power management */
-
-#ifdef CONFIG_AT45DB_PWRSAVE
-static void at45db_pwrdown(struct at45db_dev_s *priv);
-static void at45db_resume(struct at45db_dev_s *priv);
-#else
-# define at45db_pwrdown(priv)
-# define at45db_resume(priv)
-#endif
-
-/* Low-level AT45DB Helpers */
-
-static inline int at45db_rdid(struct at45db_dev_s *priv);
-static inline uint8_t at45db_rdsr(struct at45db_dev_s *priv);
-static uint8_t at45db_waitbusy(struct at45db_dev_s *priv);
-static inline void at45db_pgerase(struct at45db_dev_s *priv, off_t offset);
-static inline int at32db_chiperase(struct at45db_dev_s *priv);
-static inline void at45db_pgwrite(struct at45db_dev_s *priv, FAR const uint8_t *buffer,
- off_t offset);
-
-/* MTD driver methods */
-
-static int at45db_erase(FAR struct mtd_dev_s *mtd, off_t startblock, size_t nblocks);
-static ssize_t at45db_bread(FAR struct mtd_dev_s *mtd, off_t startblock,
- size_t nblocks, FAR uint8_t *buf);
-static ssize_t at45db_bwrite(FAR struct mtd_dev_s *mtd, off_t startblock,
- size_t nblocks, FAR const uint8_t *buf);
-static ssize_t at45db_read(FAR struct mtd_dev_s *mtd, off_t offset, size_t nbytes,
- FAR uint8_t *buffer);
-static int at45db_ioctl(FAR struct mtd_dev_s *mtd, int cmd, unsigned long arg);
-
-/************************************************************************************
- * Private Data
- ************************************************************************************/
-
-/* Chip erase sequence */
-
-#define CHIP_ERASE_SIZE 4
-static const uint8_t g_chiperase[CHIP_ERASE_SIZE] = {0xc7, 0x94, 0x80, 0x9a};
-
-/* Sequence to program the device to binary page sizes{256, 512, 1024} */
-
-#define BINPGSIZE_SIZE 4
-static const uint8_t g_binpgsize[BINPGSIZE_SIZE] = {0x3d, 0x2a, 0x80, 0xa6};
-
-/************************************************************************************
- * Private Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: at45db_lock
- ************************************************************************************/
-
-static void at45db_lock(struct at45db_dev_s *priv)
-{
- /* On SPI busses where there are multiple devices, it will be necessary to
- * lock SPI to have exclusive access to the busses for a sequence of
- * transfers. The bus should be locked before the chip is selected.
- *
- * This is a blocking call and will not return until we have exclusiv access to
- * the SPI buss. We will retain that exclusive access until the bus is unlocked.
- */
-
- (void)SPI_LOCK(priv->spi, true);
-
- /* After locking the SPI bus, the we also need call the setfrequency, setbits, and
- * setmode methods to make sure that the SPI is properly configured for the device.
- * If the SPI buss is being shared, then it may have been left in an incompatible
- * state.
- */
-
- SPI_SETMODE(priv->spi, SPIDEV_MODE0);
- SPI_SETBITS(priv->spi, 8);
- (void)SPI_SETFREQUENCY(priv->spi, CONFIG_AT45DB_FREQUENCY);
-}
-
-/************************************************************************************
- * Name: at45db_unlock
- ************************************************************************************/
-
-static inline void at45db_unlock(struct at45db_dev_s *priv)
-{
- (void)SPI_LOCK(priv->spi, false);
-}
-
-/************************************************************************************
- * Name: at45db_pwrdown
- ************************************************************************************/
-
-#ifdef CONFIG_AT45DB_PWRSAVE
-static void at45db_pwrdown(struct at45db_dev_s *priv)
-{
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
- SPI_SEND(priv->spi, AT45DB_PWRDOWN);
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-}
-#endif
-
-/************************************************************************************
- * Name: at45db_resume
- ************************************************************************************/
-
-#ifdef CONFIG_AT45DB_PWRSAVE
-static void at45db_resume(struct at45db_dev_s *priv)
-{
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
- SPI_SEND(priv->spi, AT45DB_RESUME);
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
- up_udelay(50);
-}
-#endif
-
-/************************************************************************************
- * Name: at45db_rdid
- ************************************************************************************/
-
-static inline int at45db_rdid(struct at45db_dev_s *priv)
-{
- uint8_t capacity;
- uint8_t devid[3];
-
- fvdbg("priv: %p\n", priv);
-
- /* Configure the bus, and select this FLASH part. (The caller should alread have
- * loced the bus for exclusive access)
- */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send the " Manufacturer and Device ID Read" command and read the next three
- * ID bytes from the FLASH.
- */
-
- (void)SPI_SEND(priv->spi, AT45DB_RDDEVID);
- SPI_RECVBLOCK(priv->spi, devid, 3);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-
- fvdbg("manufacturer: %02x devid1: %02x devid2: %02x\n",
- devid[0], devid[1], devid[2]);
-
- /* Check for a valid manufacturer and memory family */
-
- if (devid[0] == AT45DB_MANUFACTURER &&
- (devid[1] & AT45DB_DEVID1_FAMMSK) == AT45DB_DEVID1_DFLASH)
- {
- /* Okay.. is it a FLASH capacity that we understand? */
-
- capacity = devid[1] & AT45DB_DEVID1_CAPMSK;
- switch (capacity)
- {
- case AT45DB_DEVID1_1MBIT:
- /* Save the FLASH geometry for the 16Mbit AT45DB011 */
-
- priv->pageshift = 8; /* Page size = 256 bytes */
- priv->npages = 512; /* 512 pages */
- return OK;
-
- case AT45DB_DEVID1_2MBIT:
- /* Save the FLASH geometry for the 16Mbit AT45DB021 */
-
- priv->pageshift = 8; /* Page size = 256/264 bytes */
- priv->npages = 1024; /* 1024 pages */
- return OK;
-
- case AT45DB_DEVID1_4MBIT:
- /* Save the FLASH geometry for the 16Mbit AT45DB041 */
-
- priv->pageshift = 8; /* Page size = 256/264 bytes */
- priv->npages = 2048; /* 2048 pages */
- return OK;
-
- case AT45DB_DEVID1_8MBIT:
- /* Save the FLASH geometry for the 16Mbit AT45DB081 */
-
- priv->pageshift = 8; /* Page size = 256/264 bytes */
- priv->npages = 4096; /* 4096 pages */
- return OK;
-
- case AT45DB_DEVID1_16MBIT:
- /* Save the FLASH geometry for the 16Mbit AT45DB161 */
-
- priv->pageshift = 9; /* Page size = 512/528 bytes */
- priv->npages = 4096; /* 4096 pages */
- return OK;
-
- case AT45DB_DEVID1_32MBIT:
- /* Save the FLASH geometry for the 16Mbit AT45DB321 */
-
- priv->pageshift = 9; /* Page size = 512/528 bytes */
- priv->npages = 8192; /* 8192 pages */
- return OK;
-
- case AT45DB_DEVID1_64MBIT:
- /* Save the FLASH geometry for the 16Mbit AT45DB321 */
-
- priv->pageshift = 10; /* Page size = 1024/1056 bytes */
- priv->npages = 8192; /* 8192 pages */
- return OK;
-
- default:
- return -ENODEV;
- }
- }
-
- return -ENODEV;
-}
-
-/************************************************************************************
- * Name: at45db_rdsr
- ************************************************************************************/
-
-static inline uint8_t at45db_rdsr(struct at45db_dev_s *priv)
-{
- uint8_t retval;
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
- SPI_SEND(priv->spi, AT45DB_RDSR);
- retval = SPI_SEND(priv->spi, 0xff);
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
- return retval;
-}
-
-/************************************************************************************
- * Name: at45db_waitbusy
- ************************************************************************************/
-
-static uint8_t at45db_waitbusy(struct at45db_dev_s *priv)
-{
- uint8_t sr;
-
- /* Poll the device, waiting for it to report that it is ready */
-
- do
- {
- up_udelay(10);
- sr = (uint8_t)at45db_rdsr(priv);
- }
- while ((sr & AT45DB_SR_RDY) == 0);
- return sr;
-}
-
-/************************************************************************************
- * Name: at45db_pgerase
- ************************************************************************************/
-
-static inline void at45db_pgerase(struct at45db_dev_s *priv, off_t sector)
-{
- uint8_t erasecmd[4];
- off_t offset = sector << priv->pageshift;
-
- fvdbg("sector: %08lx\n", (long)sector);
-
- /* Higher performance write logic: We leave the chip busy after write and erase
- * operations. This improves write and erase performance because we do not have
- * to wait as long between transactions (other processing can occur while the chip
- * is busy) but means that the chip must stay powered and that we must check if
- * the chip is still busy on each entry point.
- */
-
-#ifdef CONFIG_AT45DB_PREWAIT
- at45db_waitbusy(priv);
-#endif
-
- /* "The Page Erase command can be used to individually erase any page in the main
- * memory array allowing the Buffer to Main Memory Page Program to be utilized at a
- * later time. ... To perform a page erase in the binary page size ..., the
- * opcode 81H must be loaded into the device, followed by three address bytes
- * ... When a low-to-high transition occurs on the CS pin, the part will erase the
- * selected page (the erased state is a logical 1). ... the status register and the
- * RDY/BUSY pin will indicate that the part is busy."
- */
-
- erasecmd[0] = AT45DB_PGERASE; /* Page erase command */
- erasecmd[1] = (offset >> 16) & 0xff; /* 24-bit offset MS bytes */
- erasecmd[2] = (offset >> 8) & 0xff; /* 24-bit offset middle bytes */
- erasecmd[3] = offset & 0xff; /* 24-bit offset LS bytes */
-
- /* Erase the page */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
- SPI_SNDBLOCK(priv->spi, erasecmd, 4);
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-
- /* Wait for any erase to complete if we are not trying to improve write
- * performance. (see comments above).
- */
-
-#ifndef CONFIG_AT45DB_PREWAIT
- at45db_waitbusy(priv);
-#endif
- fvdbg("Erased\n");
-}
-
-/************************************************************************************
- * Name: at32db_chiperase
- ************************************************************************************/
-
-static inline int at32db_chiperase(struct at45db_dev_s *priv)
-{
- fvdbg("priv: %p\n", priv);
-
- /* Higher performance write logic: We leave the chip busy after write and erase
- * operations. This improves write and erase performance because we do not have
- * to wait as long between transactions (other processing can occur while the chip
- * is busy) but means that the chip must stay powered and that we must check if
- * the chip is still busy on each entry point.
- */
-
-#ifdef CONFIG_AT45DB_PREWAIT
- at45db_waitbusy(priv);
-#endif
-
- /* "The entire main memory can be erased at one time by using the Chip Erase
- * command. To execute the Chip Erase command, a 4-byte command sequence C7H, 94H,
- * 80H and 9AH must be clocked into the device. ... After the last bit of the opcode
- * sequence has been clocked in, the CS pin can be deasserted to start the erase
- * process. ... the Status Register will indicate that the device is busy. The Chip
- * Erase command will not affect sectors that are protected or locked down...
- */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
- SPI_SNDBLOCK(priv->spi, g_chiperase, CHIP_ERASE_SIZE);
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-
- /* Wait for any erase to complete if we are not trying to improve write
- * performance. (see comments above).
- */
-
-#ifndef CONFIG_AT45DB_PREWAIT
- at45db_waitbusy(priv);
-#endif
- return OK;
-}
-
-/************************************************************************************
- * Name: at45db_pgwrite
- ************************************************************************************/
-
-static inline void at45db_pgwrite(struct at45db_dev_s *priv, FAR const uint8_t *buffer,
- off_t page)
-{
- uint8_t wrcmd [4];
- off_t offset = page << priv->pageshift;
-
- fvdbg("page: %08lx offset: %08lx\n", (long)page, (long)offset);
-
- /* We assume that sectors are not write protected */
-
- wrcmd[0] = AT45DB_MNTHRUBF1; /* To main memory through buffer 1 */
- wrcmd[1] = (offset >> 16) & 0xff; /* 24-bit address MS byte */
- wrcmd[2] = (offset >> 8) & 0xff; /* 24-bit address middle byte */
- wrcmd[3] = offset & 0xff; /* 24-bit address LS byte */
-
- /* Higher performance write logic: We leave the chip busy after write and erase
- * operations. This improves write and erase performance because we do not have
- * to wait as long between transactions (other processing can occur while the chip
- * is busy) but means that the chip must stay powered and that we must check if
- * the chip is still busy on each entry point.
- */
-
-#ifdef CONFIG_AT45DB_PREWAIT
- at45db_waitbusy(priv);
-#endif
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
- SPI_SNDBLOCK(priv->spi, wrcmd, 4);
- SPI_SNDBLOCK(priv->spi, buffer, 1 << priv->pageshift);
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-
- /* Wait for any erase to complete if we are not trying to improve write
- * performance. (see comments above).
- */
-
-#ifndef CONFIG_AT45DB_PREWAIT
- at45db_waitbusy(priv);
-#endif
- fvdbg("Written\n");
-}
-
-/************************************************************************************
- * Name: at45db_erase
- ************************************************************************************/
-
-static int at45db_erase(FAR struct mtd_dev_s *mtd, off_t startblock, size_t nblocks)
-{
- FAR struct at45db_dev_s *priv = (FAR struct at45db_dev_s *)mtd;
- size_t pgsleft = nblocks;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Take the lock so that we have exclusive access to the bus, then power up the
- * FLASH device.
- */
-
- at45db_lock(priv);
- at45db_resume(priv);
-
- /* Then erase each page */
-
- while (pgsleft-- > 0)
- {
- /* Erase each sector */
-
- at45db_pgerase(priv, startblock);
- startblock++;
- }
-
- at45db_pwrdown(priv);
- at45db_unlock(priv);
- return (int)nblocks;
-}
-
-/************************************************************************************
- * Name: at45db_bread
- ************************************************************************************/
-
-static ssize_t at45db_bread(FAR struct mtd_dev_s *mtd, off_t startblock, size_t nblocks,
- FAR uint8_t *buffer)
-{
- FAR struct at45db_dev_s *priv = (FAR struct at45db_dev_s *)mtd;
- ssize_t nbytes;
-
- /* On this device, we can handle the block read just like the byte-oriented read */
-
- nbytes = at45db_read(mtd, startblock << priv->pageshift, nblocks << priv->pageshift, buffer);
- if (nbytes > 0)
- {
- return nbytes >> priv->pageshift;
- }
- return nbytes;
-}
-
-/************************************************************************************
- * Name: at45db_bwrite
- ************************************************************************************/
-
-static ssize_t at45db_bwrite(FAR struct mtd_dev_s *mtd, off_t startblock, size_t nblocks,
- FAR const uint8_t *buffer)
-{
- FAR struct at45db_dev_s *priv = (FAR struct at45db_dev_s *)mtd;
- size_t pgsleft = nblocks;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Take the lock so that we have exclusive access to the bus, then power up the
- * FLASH device.
- */
-
- at45db_lock(priv);
- at45db_resume(priv);
-
- /* Write each page to FLASH */
-
- while (pgsleft-- > 0)
- {
- at45db_pgwrite(priv, buffer, startblock);
- startblock++;
- }
-
- at45db_pwrdown(priv);
- at45db_unlock(priv);
-
- return nblocks;
-}
-
-/************************************************************************************
- * Name: at45db_read
- ************************************************************************************/
-
-static ssize_t at45db_read(FAR struct mtd_dev_s *mtd, off_t offset, size_t nbytes,
- FAR uint8_t *buffer)
-{
- FAR struct at45db_dev_s *priv = (FAR struct at45db_dev_s *)mtd;
- uint8_t rdcmd [5];
-
- fvdbg("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
-
- /* Set up for the read */
-
- rdcmd[0] = AT45DB_RDARRAYHF; /* FAST_READ is safe at all supported SPI speeds. */
- rdcmd[1] = (offset >> 16) & 0xff; /* 24-bit address upper byte */
- rdcmd[2] = (offset >> 8) & 0xff; /* 24-bit address middle byte */
- rdcmd[3] = offset & 0xff; /* 24-bit address least significant byte */
- rdcmd[4] = 0; /* Dummy byte */
-
- /* Take the lock so that we have exclusive access to the bus, then power up the
- * FLASH device.
- */
-
- at45db_lock(priv);
- at45db_resume(priv);
-
- /* Higher performance write logic: We leave the chip busy after write and erase
- * operations. This improves write and erase performance because we do not have
- * to wait as long between transactions (other processing can occur while the chip
- * is busy) but means that the chip must stay powered and that we must check if
- * the chip is still busy on each entry point.
- */
-
-#ifdef CONFIG_AT45DB_PREWAIT
- at45db_waitbusy(priv);
-#endif
-
- /* Perform the read */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
- SPI_SNDBLOCK(priv->spi, rdcmd, 5);
- SPI_RECVBLOCK(priv->spi, buffer, nbytes);
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-
- at45db_pwrdown(priv);
- at45db_unlock(priv);
-
- fvdbg("return nbytes: %d\n", (int)nbytes);
- return nbytes;
-}
-
-/************************************************************************************
- * Name: at45db_ioctl
- ************************************************************************************/
-
-static int at45db_ioctl(FAR struct mtd_dev_s *mtd, int cmd, unsigned long arg)
-{
- FAR struct at45db_dev_s *priv = (FAR struct at45db_dev_s *)mtd;
- int ret = -EINVAL; /* Assume good command with bad parameters */
-
- fvdbg("cmd: %d \n", cmd);
-
- switch (cmd)
- {
- case MTDIOC_GEOMETRY:
- {
- FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg);
- if (geo)
- {
- /* Populate the geometry structure with information need to know
- * the capacity and how to access the device.
- *
- * NOTE: that the device is treated as though it where just an array
- * of fixed size blocks. That is most likely not true, but the client
- * will expect the device logic to do whatever is necessary to make it
- * appear so.
- */
-
- geo->blocksize = (1 << priv->pageshift);
- geo->erasesize = geo->blocksize;
- geo->neraseblocks = priv->npages;
- ret = OK;
-
- fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n",
- geo->blocksize, geo->erasesize, geo->neraseblocks);
- }
- }
- break;
-
- case MTDIOC_BULKERASE:
- {
- /* Take the lock so that we have exclusive access to the bus, then
- * power up the FLASH device.
- */
-
- at45db_lock(priv);
- at45db_resume(priv);
-
- /* Erase the entire device */
-
- ret = at32db_chiperase(priv);
- at45db_pwrdown(priv);
- at45db_unlock(priv);
- }
- break;
-
- case MTDIOC_XIPBASE:
- default:
- ret = -ENOTTY; /* Bad command */
- break;
- }
-
- fvdbg("return %d\n", ret);
- return ret;
-}
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: at45db_initialize
- *
- * Description:
- * Create an initialize MTD device instance. MTD devices are not registered
- * in the file system, but are created as instances that can be bound to
- * other functions (such as a block or character driver front end).
- *
- ************************************************************************************/
-
-FAR struct mtd_dev_s *at45db_initialize(FAR struct spi_dev_s *spi)
-{
- FAR struct at45db_dev_s *priv;
- uint8_t sr;
- int ret;
-
- fvdbg("spi: %p\n", spi);
-
- /* Allocate a state structure (we allocate the structure instead of using
- * a fixed, static allocation so that we can handle multiple FLASH devices.
- * The current implementation would handle only one FLASH part per SPI
- * device (only because of the SPIDEV_FLASH definition) and so would have
- * to be extended to handle multiple FLASH parts on the same SPI bus.
- */
-
- priv = (FAR struct at45db_dev_s *)kmalloc(sizeof(struct at45db_dev_s));
- if (priv)
- {
- /* Initialize the allocated structure */
-
- priv->mtd.erase = at45db_erase;
- priv->mtd.bread = at45db_bread;
- priv->mtd.bwrite = at45db_bwrite;
- priv->mtd.read = at45db_read;
- priv->mtd.ioctl = at45db_ioctl;
- priv->spi = spi;
-
- /* Deselect the FLASH */
-
- SPI_SELECT(spi, SPIDEV_FLASH, false);
-
- /* Lock and configure the SPI bus. */
-
- at45db_lock(priv);
- at45db_resume(priv);
-
- /* Identify the FLASH chip and get its capacity */
-
- ret = at45db_rdid(priv);
- if (ret != OK)
- {
- /* Unrecognized! Discard all of that work we just did and return NULL */
-
- fdbg("Unrecognized\n");
- goto errout;
- }
-
- /* Get the value of the status register (as soon as the device is ready) */
-
- sr = at45db_waitbusy(priv);
-
- /* Check if the device is configured as 256, 512 or 1024 bytes-per-page device */
-
- if ((sr & AT45DB_SR_PGSIZE) == 0)
- {
- /* No, re-program it for the binary page size. NOTE: A power cycle
- * is required after the device has be re-programmed.
- */
-
- fdbg("Reprogramming page size\n");
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
- SPI_SNDBLOCK(priv->spi, g_binpgsize, BINPGSIZE_SIZE);
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
- goto errout;
- }
-
- /* Release the lock and power down the device */
-
- at45db_pwrdown(priv);
- at45db_unlock(priv);
- }
-
- fvdbg("Return %p\n", priv);
- return (FAR struct mtd_dev_s *)priv;
-
-/* On any failure, we need free memory allocations and release the lock that
- * we hold on the SPI bus. On failures, assume that we cannot talk to the
- * device to do any more.
- */
-
-errout:
- at45db_unlock(priv);
- kfree(priv);
- return NULL;
-}
diff --git a/nuttx/drivers/mtd/flash_eraseall.c b/nuttx/drivers/mtd/flash_eraseall.c
deleted file mode 100644
index ce0cfe649..000000000
--- a/nuttx/drivers/mtd/flash_eraseall.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
- * drivers/mtd/flash_eraseall.c
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/mtd.h>
-
-/****************************************************************************
- * Private Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: flash_eraseall
- *
- * Description:
- * Call a block driver with the MDIOC_BULKERASE ioctl command. This will
- * cause the MTD driver to erase all of the flash.
- *
- ****************************************************************************/
-
-int flash_eraseall(FAR const char *driver)
-{
- FAR struct inode *inode;
- FAR const struct block_operations *ops;
- int ret;
-
- /* Open the block driver */
-
- ret = open_blockdriver(driver ,0, &inode);
- if (ret < 0)
- {
- fdbg("ERROR: Failed to open '%s': %d\n", driver, ret);
- return ret;
- }
-
- /* Get the block operations */
-
- ops = inode->u.i_bops;
-
- /* Invoke the block driver ioctl method */
-
- ret = -EPERM;
- if (ops->ioctl)
- {
- ret = ops->ioctl(inode, MTDIOC_BULKERASE, 0);
- if (ret < 0)
- {
- fdbg("ERROR: MTD ioctl(%04x) failed: %d\n", MTDIOC_BULKERASE, ret);
- }
- }
-
- /* Close the block driver */
-
- close_blockdriver(inode);
- return ret;
-}
diff --git a/nuttx/drivers/mtd/ftl.c b/nuttx/drivers/mtd/ftl.c
deleted file mode 100644
index 6cf8f0317..000000000
--- a/nuttx/drivers/mtd/ftl.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/****************************************************************************
- * drivers/mtd/ftl.c
- *
- * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <debug.h>
-#include <errno.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/mtd.h>
-#include <nuttx/rwbuffer.h>
-
-/****************************************************************************
- * Private Definitions
- ****************************************************************************/
-
-#if defined(CONFIG_FS_READAHEAD) || (defined(CONFIG_FS_WRITABLE) && defined(CONFIG_FS_WRITEBUFFER))
-# defined CONFIG_FTL_RWBUFFER 1
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct ftl_struct_s
-{
- FAR struct mtd_dev_s *mtd; /* Contained MTD interface */
- struct mtd_geometry_s geo; /* Device geometry */
-#ifdef CONFIG_FTL_RWBUFFER
- struct rwbuffer_s rwb; /* Read-ahead/write buffer support */
-#endif
- uint16_t blkper; /* R/W blocks per erase block */
-#ifdef CONFIG_FS_WRITABLE
- FAR uint8_t *eblock; /* One, in-memory erase block */
-#endif
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int ftl_open(FAR struct inode *inode);
-static int ftl_close(FAR struct inode *inode);
-static ssize_t ftl_reload(FAR void *priv, FAR uint8_t *buffer,
- off_t startblock, size_t nblocks);
-static ssize_t ftl_read(FAR struct inode *inode, unsigned char *buffer,
- size_t start_sector, unsigned int nsectors);
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer,
- off_t startblock, size_t nblocks);
-static ssize_t ftl_write(FAR struct inode *inode, const unsigned char *buffer,
- size_t start_sector, unsigned int nsectors);
-#endif
-static int ftl_geometry(FAR struct inode *inode, struct geometry *geometry);
-static int ftl_ioctl(FAR struct inode *inode, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct block_operations g_bops =
-{
- ftl_open, /* open */
- ftl_close, /* close */
- ftl_read, /* read */
-#ifdef CONFIG_FS_WRITABLE
- ftl_write, /* write */
-#else
- NULL, /* write */
-#endif
- ftl_geometry, /* geometry */
- ftl_ioctl /* ioctl */
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: ftl_open
- *
- * Description: Open the block device
- *
- ****************************************************************************/
-
-static int ftl_open(FAR struct inode *inode)
-{
- fvdbg("Entry\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: ftl_close
- *
- * Description: close the block device
- *
- ****************************************************************************/
-
-static int ftl_close(FAR struct inode *inode)
-{
- fvdbg("Entry\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: ftl_reload
- *
- * Description: Read the specified numer of sectors
- *
- ****************************************************************************/
-
-static ssize_t ftl_reload(FAR void *priv, FAR uint8_t *buffer,
- off_t startblock, size_t nblocks)
-{
- struct ftl_struct_s *dev = (struct ftl_struct_s *)priv;
- ssize_t nread;
-
- /* Read the full erase block into the buffer */
-
- nread = MTD_BREAD(dev->mtd, startblock, nblocks, buffer);
- if (nread != nblocks)
- {
- fdbg("Read %d blocks starting at block %d failed: %d\n",
- nblocks, startblock, nread);
- }
- return nread;
-}
-
-/****************************************************************************
- * Name: ftl_read
- *
- * Description: Read the specified numer of sectors
- *
- ****************************************************************************/
-
-static ssize_t ftl_read(FAR struct inode *inode, unsigned char *buffer,
- size_t start_sector, unsigned int nsectors)
-{
- struct ftl_struct_s *dev;
-
- fvdbg("sector: %d nsectors: %d\n", start_sector, nsectors);
-
- DEBUGASSERT(inode && inode->i_private);
- dev = (struct ftl_struct_s *)inode->i_private;
-#ifdef CONFIG_FS_READAHEAD
- return rwb_read(&dev->rwb, start_sector, nsectors, buffer);
-#else
- return ftl_reload(dev, buffer, start_sector, nsectors);
-#endif
-}
-
-/****************************************************************************
- * Name: ftl_flush
- *
- * Description: Write the specified number of sectors
- *
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer,
- off_t startblock, size_t nblocks)
-{
- struct ftl_struct_s *dev = (struct ftl_struct_s *)priv;
- off_t alignedblock;
- off_t mask;
- off_t rwblock;
- off_t eraseblock;
- off_t offset;
- size_t remaining;
- size_t nxfrd;
- int nbytes;
- int ret;
-
- /* Get the aligned block. Here is is assumed: (1) The number of R/W blocks
- * per erase block is a power of 2, and (2) the erase begins with that same
- * alignment.
- */
-
- mask = dev->blkper - 1;
- alignedblock = (startblock + mask) & ~mask;
-
- /* Handle partial erase blocks before the first unaligned block */
-
- remaining = nblocks;
- if (alignedblock > startblock)
- {
- /* Check if the write is shorter than to the end of the erase block */
-
- bool short_write = (remaining < (alignedblock - startblock));
-
- /* Read the full erase block into the buffer */
-
- rwblock = startblock & ~mask;
- nxfrd = MTD_BREAD(dev->mtd, rwblock, dev->blkper, dev->eblock);
- if (nxfrd != dev->blkper)
- {
- fdbg("Read erase block %d failed: %d\n", rwblock, nxfrd);
- return -EIO;
- }
-
- /* Then erase the erase block */
-
- eraseblock = rwblock / dev->blkper;
- ret = MTD_ERASE(dev->mtd, eraseblock, 1);
- if (ret < 0)
- {
- fdbg("Erase block=%d failed: %d\n", eraseblock, ret);
- return ret;
- }
-
- /* Copy the user data at the end of the buffered erase block */
-
- offset = (startblock & mask) * dev->geo.blocksize;
-
- if (short_write)
- {
- nbytes = remaining * dev->geo.blocksize;
- }
- else
- {
- nbytes = dev->geo.erasesize - offset;
- }
-
- fvdbg("Copy %d bytes into erase block=%d at offset=%d\n",
- nbytes, eraseblock, offset);
-
- memcpy(dev->eblock + offset, buffer, nbytes);
-
- /* And write the erase back to flash */
-
- nxfrd = MTD_BWRITE(dev->mtd, rwblock, dev->blkper, dev->eblock);
- if (nxfrd != dev->blkper)
- {
- fdbg("Write erase block %d failed: %d\n", rwblock, nxfrd);
- return -EIO;
- }
-
- /* Then update for amount written */
-
- if (short_write)
- {
- remaining = 0;
- }
- else
- {
- remaining -= dev->blkper - (startblock & mask);
- }
-
- buffer += nbytes;
- }
-
- /* How handle full erase pages in the middle */
-
- while (remaining >= dev->blkper)
- {
- /* Erase the erase block */
-
- eraseblock = alignedblock / dev->blkper;
- ret = MTD_ERASE(dev->mtd, eraseblock, 1);
- if (ret < 0)
- {
- fdbg("Erase block=%d failed: %d\n", eraseblock, ret);
- return ret;
- }
-
- /* Write a full erase back to flash */
-
- fvdbg("Write %d bytes into erase block=%d at offset=0\n",
- dev->geo.erasesize, alignedblock);
-
- nxfrd = MTD_BWRITE(dev->mtd, alignedblock, dev->blkper, buffer);
- if (nxfrd != dev->blkper)
- {
- fdbg("Write erase block %d failed: %d\n", alignedblock, nxfrd);
- return -EIO;
- }
-
- /* Then update for amount written */
-
- alignedblock += dev->blkper;
- remaining -= dev->blkper;
- buffer += dev->geo.erasesize;
- }
-
- /* Finally, handler any partial blocks after the last full erase block */
-
- if (remaining > 0)
- {
- /* Read the full erase block into the buffer */
-
- nxfrd = MTD_BREAD(dev->mtd, alignedblock, dev->blkper, dev->eblock);
- if (nxfrd != dev->blkper)
- {
- fdbg("Read erase block %d failed: %d\n", alignedblock, nxfrd);
- return -EIO;
- }
-
- /* Then erase the erase block */
-
- eraseblock = alignedblock / dev->blkper;
- ret = MTD_ERASE(dev->mtd, eraseblock, 1);
- if (ret < 0)
- {
- fdbg("Erase block=%d failed: %d\n", eraseblock, ret);
- return ret;
- }
-
- /* Copy the user data at the beginning the buffered erase block */
-
- nbytes = remaining * dev->geo.blocksize;
- fvdbg("Copy %d bytes into erase block=%d at offset=0\n",
- nbytes, alignedblock);
- memcpy(dev->eblock, buffer, nbytes);
-
- /* And write the erase back to flash */
-
- nxfrd = MTD_BWRITE(dev->mtd, alignedblock, dev->blkper, dev->eblock);
- if (nxfrd != dev->blkper)
- {
- fdbg("Write erase block %d failed: %d\n", alignedblock, nxfrd);
- return -EIO;
- }
- }
-
- return nblocks;
-}
-#endif
-
-/****************************************************************************
- * Name: ftl_write
- *
- * Description: Write (or buffer) the specified number of sectors
- *
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t ftl_write(FAR struct inode *inode, const unsigned char *buffer,
- size_t start_sector, unsigned int nsectors)
-{
- struct ftl_struct_s *dev;
-
- fvdbg("sector: %d nsectors: %d\n", start_sector, nsectors);
-
- DEBUGASSERT(inode && inode->i_private);
- dev = (struct ftl_struct_s *)inode->i_private;
-#ifdef CONFIG_FS_WRITEBUFFER
- return rwb_write(&dev->rwb, start_sector, nsectors, buffer);
-#else
- return ftl_flush(dev, buffer, start_sector, nsectors);
-#endif
-}
-#endif
-
-/****************************************************************************
- * Name: ftl_geometry
- *
- * Description: Return device geometry
- *
- ****************************************************************************/
-
-static int ftl_geometry(FAR struct inode *inode, struct geometry *geometry)
-{
- struct ftl_struct_s *dev;
-
- fvdbg("Entry\n");
-
- DEBUGASSERT(inode);
- if (geometry)
- {
- dev = (struct ftl_struct_s *)inode->i_private;
- geometry->geo_available = true;
- geometry->geo_mediachanged = false;
-#ifdef CONFIG_FS_WRITABLE
- geometry->geo_writeenabled = true;
-#else
- geometry->geo_writeenabled = false;
-#endif
- geometry->geo_nsectors = dev->geo.neraseblocks * dev->blkper;
- geometry->geo_sectorsize = dev->geo.blocksize;
-
- fvdbg("available: true mediachanged: false writeenabled: %s\n",
- geometry->geo_writeenabled ? "true" : "false");
- fvdbg("nsectors: %d sectorsize: %d\n",
- geometry->geo_nsectors, geometry->geo_sectorsize);
-
- return OK;
- }
- return -EINVAL;
-}
-
-/****************************************************************************
- * Name: ftl_ioctl
- *
- * Description: Return device geometry
- *
- ****************************************************************************/
-
-static int ftl_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
-{
- struct ftl_struct_s *dev ;
- int ret;
-
- fvdbg("Entry\n");
- DEBUGASSERT(inode && inode->i_private);
-
- /* Only one block driver ioctl command is supported by this driver (and
- * that command is just passed on to the MTD driver in a slightly
- * different form).
- */
-
- if (cmd == BIOC_XIPBASE)
- {
- /* The argument accompanying the BIOC_XIPBASE should be non-NULL. If
- * DEBUG is enabled, we will catch it here instead of in the MTD
- * driver.
- */
-
-#ifdef CONFIG_DEBUG
- if (arg == 0)
- {
- fdbg("ERROR: BIOC_XIPBASE argument is NULL\n");
- return -EINVAL;
- }
-#endif
-
- /* Just change the BIOC_XIPBASE command to the MTDIOC_XIPBASE command. */
-
- cmd = MTDIOC_XIPBASE;
- }
-
- /* No other block driver ioctl commmands are not recognized by this
- * driver. Other possible MTD driver ioctl commands are passed through
- * to the MTD driver (unchanged).
- */
-
- dev = (struct ftl_struct_s *)inode->i_private;
- ret = MTD_IOCTL(dev->mtd, cmd, arg);
- if (ret < 0)
- {
- fdbg("ERROR: MTD ioctl(%04x) failed: %d\n", cmd, ret);
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: ftl_initialize
- *
- * Description:
- * Initialize to provide a block driver wrapper around an MTD interface
- *
- * Input Parameters:
- * minor - The minor device number. The MTD block device will be
- * registered as as /dev/mtdblockN where N is the minor number.
- * mtd - The MTD device that supports the FLASH interface.
- *
- ****************************************************************************/
-
-int ftl_initialize(int minor, FAR struct mtd_dev_s *mtd)
-{
- struct ftl_struct_s *dev;
- char devname[16];
- int ret = -ENOMEM;
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (minor < 0 || minor > 255 || !mtd)
- {
- return -EINVAL;
- }
-#endif
-
- /* Allocate a FTL device structure */
-
- dev = (struct ftl_struct_s *)kmalloc(sizeof(struct ftl_struct_s));
- if (dev)
- {
- /* Initialize the FTL device structure */
-
- dev->mtd = mtd;
-
- /* Get the device geometry. (casting to uintptr_t first eliminates
- * complaints on some architectures where the sizeof long is different
- * from the size of a pointer).
- */
-
- ret = MTD_IOCTL(mtd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&dev->geo));
- if (ret < 0)
- {
- fdbg("MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", ret);
- kfree(dev);
- return ret;
- }
-
- /* Allocate one, in-memory erase block buffer */
-
-#ifdef CONFIG_FS_WRITABLE
- dev->eblock = (FAR uint8_t *)kmalloc(dev->geo.erasesize);
- if (!dev->eblock)
- {
- fdbg("Failed to allocate an erase block buffer\n");
- kfree(dev);
- return -ENOMEM;
- }
-#endif
-
- /* Get the number of R/W blocks per erase block */
-
- dev->blkper = dev->geo.erasesize / dev->geo.blocksize;
- DEBUGASSERT(dev->blkper * dev->geo.blocksize == dev->geo.erasesize);
-
- /* Configure read-ahead/write buffering */
-
-#ifdef CONFIG_FTL_RWBUFFER
- dev->rwb.blocksize = dev->geo.blocksize;
- dev->rwb.nblocks = dev->geo.neraseblocks * dev->blkper;
- dev->rwb.dev = (FAR void *)dev;
-
-#if defined(CONFIG_FS_WRITABLE) && defined(CONFIG_FS_WRITEBUFFER)
- dev->rwb.wrmaxblocks = dev->blkper;
- dev->rwb.wrflush = ftl_flush;
-#endif
-
-#ifdef CONFIG_FS_READAHEAD
- dev->rwb.rhmaxblocks = dev->blkper;
- dev->rwb.rhreload = ftl_reload;
-#endif
- ret = rwb_initialize(&dev->rwb);
- if (ret < 0)
- {
- fdbg("rwb_initialize failed: %d\n", ret);
- kfree(dev);
- return ret;
- }
-#endif
-
- /* Create a MTD block device name */
-
- snprintf(devname, 16, "/dev/mtdblock%d", minor);
-
- /* Inode private data is a reference to the FTL device structure */
-
- ret = register_blockdriver(devname, &g_bops, 0, dev);
- if (ret < 0)
- {
- fdbg("register_blockdriver failed: %d\n", -ret);
- kfree(dev);
- }
- }
- return ret;
-}
diff --git a/nuttx/drivers/mtd/m25px.c b/nuttx/drivers/mtd/m25px.c
deleted file mode 100644
index 4f96c5a3b..000000000
--- a/nuttx/drivers/mtd/m25px.c
+++ /dev/null
@@ -1,798 +0,0 @@
-/************************************************************************************
- * drivers/mtd/m25px.c
- * Driver for SPI-based M25P1 (128Kbit), M25P64 (32Mbit), M25P64 (64Mbit), and
- * M25P128 (128Mbit) FLASH (and compatible).
- *
- * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/spi.h>
-#include <nuttx/mtd.h>
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-/* Configuration ********************************************************************/
-/* Per the data sheet, MP25P10 parts can be driven with either SPI mode 0 (CPOL=0 and
- * CPHA=0) or mode 3 (CPOL=1 and CPHA=1). But I have heard that other devices can
- * operated in mode 0 or 1. So you may need to specify CONFIG_MP25P_SPIMODE to
- * select the best mode for your device. If CONFIG_MP25P_SPIMODE is not defined,
- * mode 0 will be used.
- */
-
-#ifndef CONFIG_MP25P_SPIMODE
-# define CONFIG_MP25P_SPIMODE SPIDEV_MODE0
-#endif
-
-/* Various manufacturers may have produced the parts. 0x20 is the manufacturer ID
- * for the STMicro MP25x serial FLASH. If, for example, you are using the a Macronix
- * International MX25 serial FLASH, the correct manufacturer ID would be 0xc2.
- */
-
-#ifndef CONFIG_MP25P_MANUFACTURER
-# define CONFIG_MP25P_MANUFACTURER 0x20
-#endif
-
-/* M25P Registers *******************************************************************/
-/* Indentification register values */
-
-#define M25P_MANUFACTURER CONFIG_MP25P_MANUFACTURER
-#define M25P_MEMORY_TYPE 0x20
-#define M25P_M25P1_CAPACITY 0x11 /* 1 M-bit */
-#define M25P_M25P32_CAPACITY 0x16 /* 32 M-bit */
-#define M25P_M25P64_CAPACITY 0x17 /* 64 M-bit */
-#define M25P_M25P128_CAPACITY 0x18 /* 128 M-bit */
-
-/* M25P1 capacity is 131,072 bytes:
- * (4 sectors) * (32,768 bytes per sector)
- * (512 pages) * (256 bytes per page)
- */
-
-#define M25P_M25P1_SECTOR_SHIFT 15 /* Sector size 1 << 15 = 65,536 */
-#define M25P_M25P1_NSECTORS 4
-#define M25P_M25P1_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */
-#define M25P_M25P1_NPAGES 512
-
-/* M25P32 capacity is 4,194,304 bytes:
- * (64 sectors) * (65,536 bytes per sector)
- * (16384 pages) * (256 bytes per page)
- */
-
-#define M25P_M25P32_SECTOR_SHIFT 16 /* Sector size 1 << 16 = 65,536 */
-#define M25P_M25P32_NSECTORS 64
-#define M25P_M25P32_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */
-#define M25P_M25P32_NPAGES 16384
-
-/* M25P64 capacity is 8,338,608 bytes:
- * (128 sectors) * (65,536 bytes per sector)
- * (32768 pages) * (256 bytes per page)
- */
-
-#define M25P_M25P64_SECTOR_SHIFT 16 /* Sector size 1 << 16 = 65,536 */
-#define M25P_M25P64_NSECTORS 128
-#define M25P_M25P64_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */
-#define M25P_M25P64_NPAGES 32768
-
-/* M25P128 capacity is 16,777,216 bytes:
- * (64 sectors) * (262,144 bytes per sector)
- * (65536 pages) * (256 bytes per page)
- */
-
-#define M25P_M25P128_SECTOR_SHIFT 18 /* Sector size 1 << 18 = 262,144 */
-#define M25P_M25P128_NSECTORS 64
-#define M25P_M25P128_PAGE_SHIFT 8 /* Page size 1 << 8 = 256 */
-#define M25P_M25P128_NPAGES 65536
-
-/* Instructions */
-/* Command Value N Description Addr Dummy Data */
-#define M25P_WREN 0x06 /* 1 Write Enable 0 0 0 */
-#define M25P_WRDI 0x04 /* 1 Write Disable 0 0 0 */
-#define M25P_RDID 0x9f /* 1 Read Identification 0 0 1-3 */
-#define M25P_RDSR 0x05 /* 1 Read Status Register 0 0 >=1 */
-#define M25P_WRSR 0x01 /* 1 Write Status Register 0 0 1 */
-#define M25P_READ 0x03 /* 1 Read Data Bytes 3 0 >=1 */
-#define M25P_FAST_READ 0x0b /* 1 Higher speed read 3 1 >=1 */
-#define M25P_PP 0x02 /* 1 Page Program 3 0 1-256 */
-#define M25P_SE 0xd8 /* 1 Sector Erase 3 0 0 */
-#define M25P_BE 0xc7 /* 1 Bulk Erase 0 0 0 */
-#define M25P_DP 0xb9 /* 2 Deep power down 0 0 0 */
-#define M25P_RES 0xab /* 2 Read Electronic Signature 0 3 >=1 */
-
-/* NOTE 1: All parts, NOTE 2: M25P632/M25P64 */
-
-/* Status register bit definitions */
-
-#define M25P_SR_WIP (1 << 0) /* Bit 0: Write in progress bit */
-#define M25P_SR_WEL (1 << 1) /* Bit 1: Write enable latch bit */
-#define M25P_SR_BP_SHIFT (2) /* Bits 2-4: Block protect bits */
-#define M25P_SR_BP_MASK (7 << M25P_SR_BP_SHIFT)
-# define M25P_SR_BP_NONE (0 << M25P_SR_BP_SHIFT) /* Unprotected */
-# define M25P_SR_BP_UPPER64th (1 << M25P_SR_BP_SHIFT) /* Upper 64th */
-# define M25P_SR_BP_UPPER32nd (2 << M25P_SR_BP_SHIFT) /* Upper 32nd */
-# define M25P_SR_BP_UPPER16th (3 << M25P_SR_BP_SHIFT) /* Upper 16th */
-# define M25P_SR_BP_UPPER8th (4 << M25P_SR_BP_SHIFT) /* Upper 8th */
-# define M25P_SR_BP_UPPERQTR (5 << M25P_SR_BP_SHIFT) /* Upper quarter */
-# define M25P_SR_BP_UPPERHALF (6 << M25P_SR_BP_SHIFT) /* Upper half */
-# define M25P_SR_BP_ALL (7 << M25P_SR_BP_SHIFT) /* All sectors */
- /* Bits 5-6: Unused, read zero */
-#define M25P_SR_SRWD (1 << 7) /* Bit 7: Status register write protect */
-
-#define M25P_DUMMY 0xa5
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-/* This type represents the state of the MTD device. The struct mtd_dev_s
- * must appear at the beginning of the definition so that you can freely
- * cast between pointers to struct mtd_dev_s and struct m25p_dev_s.
- */
-
-struct m25p_dev_s
-{
- struct mtd_dev_s mtd; /* MTD interface */
- FAR struct spi_dev_s *dev; /* Saved SPI interface instance */
- uint8_t sectorshift; /* 16 or 18 */
- uint8_t pageshift; /* 8 */
- uint16_t nsectors; /* 128 or 64 */
- uint32_t npages; /* 32,768 or 65,536 */
-};
-
-/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-
-/* Helpers */
-
-static void m25p_lock(FAR struct spi_dev_s *dev);
-static inline void m25p_unlock(FAR struct spi_dev_s *dev);
-static inline int m25p_readid(struct m25p_dev_s *priv);
-static void m25p_waitwritecomplete(struct m25p_dev_s *priv);
-static void m25p_writeenable(struct m25p_dev_s *priv);
-static inline void m25p_sectorerase(struct m25p_dev_s *priv, off_t offset);
-static inline int m25p_bulkerase(struct m25p_dev_s *priv);
-static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer,
- off_t offset);
-
-/* MTD driver methods */
-
-static int m25p_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks);
-static ssize_t m25p_bread(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR uint8_t *buf);
-static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR const uint8_t *buf);
-static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer);
-static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
-
-/************************************************************************************
- * Private Data
- ************************************************************************************/
-
-/************************************************************************************
- * Private Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: m25p_lock
- ************************************************************************************/
-
-static void m25p_lock(FAR struct spi_dev_s *dev)
-{
- /* On SPI busses where there are multiple devices, it will be necessary to
- * lock SPI to have exclusive access to the busses for a sequence of
- * transfers. The bus should be locked before the chip is selected.
- *
- * This is a blocking call and will not return until we have exclusiv access to
- * the SPI buss. We will retain that exclusive access until the bus is unlocked.
- */
-
- (void)SPI_LOCK(dev, true);
-
- /* After locking the SPI bus, the we also need call the setfrequency, setbits, and
- * setmode methods to make sure that the SPI is properly configured for the device.
- * If the SPI buss is being shared, then it may have been left in an incompatible
- * state.
- */
-
- SPI_SETMODE(dev, CONFIG_MP25P_SPIMODE);
- SPI_SETBITS(dev, 8);
- (void)SPI_SETFREQUENCY(dev, 20000000);
-}
-
-/************************************************************************************
- * Name: m25p_unlock
- ************************************************************************************/
-
-static inline void m25p_unlock(FAR struct spi_dev_s *dev)
-{
- (void)SPI_LOCK(dev, false);
-}
-
-/************************************************************************************
- * Name: m25p_readid
- ************************************************************************************/
-
-static inline int m25p_readid(struct m25p_dev_s *priv)
-{
- uint16_t manufacturer;
- uint16_t memory;
- uint16_t capacity;
-
- fvdbg("priv: %p\n", priv);
-
- /* Lock the SPI bus, configure the bus, and select this FLASH part. */
-
- m25p_lock(priv->dev);
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send the "Read ID (RDID)" command and read the first three ID bytes */
-
- (void)SPI_SEND(priv->dev, M25P_RDID);
- manufacturer = SPI_SEND(priv->dev, M25P_DUMMY);
- memory = SPI_SEND(priv->dev, M25P_DUMMY);
- capacity = SPI_SEND(priv->dev, M25P_DUMMY);
-
- /* Deselect the FLASH and unlock the bus */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- m25p_unlock(priv->dev);
-
- fvdbg("manufacturer: %02x memory: %02x capacity: %02x\n",
- manufacturer, memory, capacity);
-
- /* Check for a valid manufacturer and memory type */
-
- if (manufacturer == M25P_MANUFACTURER && memory == M25P_MEMORY_TYPE)
- {
- /* Okay.. is it a FLASH capacity that we understand? */
-
- if (capacity == M25P_M25P1_CAPACITY)
- {
- /* Save the FLASH geometry */
-
- priv->sectorshift = M25P_M25P1_SECTOR_SHIFT;
- priv->nsectors = M25P_M25P1_NSECTORS;
- priv->pageshift = M25P_M25P1_PAGE_SHIFT;
- priv->npages = M25P_M25P1_NPAGES;
- return OK;
- }
- else if (capacity == M25P_M25P32_CAPACITY)
- {
- /* Save the FLASH geometry */
-
- priv->sectorshift = M25P_M25P32_SECTOR_SHIFT;
- priv->nsectors = M25P_M25P32_NSECTORS;
- priv->pageshift = M25P_M25P32_PAGE_SHIFT;
- priv->npages = M25P_M25P32_NPAGES;
- return OK;
- }
- else if (capacity == M25P_M25P64_CAPACITY)
- {
- /* Save the FLASH geometry */
-
- priv->sectorshift = M25P_M25P64_SECTOR_SHIFT;
- priv->nsectors = M25P_M25P64_NSECTORS;
- priv->pageshift = M25P_M25P64_PAGE_SHIFT;
- priv->npages = M25P_M25P64_NPAGES;
- return OK;
- }
- else if (capacity == M25P_M25P128_CAPACITY)
- {
- /* Save the FLASH geometry */
-
- priv->sectorshift = M25P_M25P128_SECTOR_SHIFT;
- priv->nsectors = M25P_M25P128_NSECTORS;
- priv->pageshift = M25P_M25P128_PAGE_SHIFT;
- priv->npages = M25P_M25P128_NPAGES;
- return OK;
- }
- }
-
- return -ENODEV;
-}
-
-/************************************************************************************
- * Name: m25p_waitwritecomplete
- ************************************************************************************/
-
-static void m25p_waitwritecomplete(struct m25p_dev_s *priv)
-{
- uint8_t status;
-
- /* Are we the only device on the bus? */
-
-#ifdef CONFIG_SPI_OWNBUS
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read Status Register (RDSR)" command */
-
- (void)SPI_SEND(priv->dev, M25P_RDSR);
-
- /* Loop as long as the memory is busy with a write cycle */
-
- do
- {
- /* Send a dummy byte to generate the clock needed to shift out the status */
-
- status = SPI_SEND(priv->dev, M25P_DUMMY);
- }
- while ((status & M25P_SR_WIP) != 0);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-
-#else
-
- /* Loop as long as the memory is busy with a write cycle */
-
- do
- {
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read Status Register (RDSR)" command */
-
- (void)SPI_SEND(priv->dev, M25P_RDSR);
-
- /* Send a dummy byte to generate the clock needed to shift out the status */
-
- status = SPI_SEND(priv->dev, M25P_DUMMY);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-
- /* Given that writing could take up to few tens of milliseconds, and erasing
- * could take more. The following short delay in the "busy" case will allow
- * other peripherals to access the SPI bus.
- */
-
- if ((status & M25P_SR_WIP) != 0)
- {
- m25p_unlock(priv->dev);
- usleep(1000);
- m25p_lock(priv->dev);
- }
- }
- while ((status & M25P_SR_WIP) != 0);
-#endif
-
- fvdbg("Complete\n");
-}
-
-/************************************************************************************
- * Name: m25p_writeenable
- ************************************************************************************/
-
-static void m25p_writeenable(struct m25p_dev_s *priv)
-{
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Write Enable (WREN)" command */
-
- (void)SPI_SEND(priv->dev, M25P_WREN);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Enabled\n");
-}
-
-/************************************************************************************
- * Name: m25p_sectorerase
- ************************************************************************************/
-
-static inline void m25p_sectorerase(struct m25p_dev_s *priv, off_t sector)
-{
- off_t offset = sector << priv->sectorshift;
-
- fvdbg("sector: %08lx\n", (long)sector);
-
- /* Wait for any preceding write to complete. We could simplify things by
- * perform this wait at the end of each write operation (rather than at
- * the beginning of ALL operations), but have the wait first will slightly
- * improve performance.
- */
-
- m25p_waitwritecomplete(priv);
-
- /* Send write enable instruction */
-
- m25p_writeenable(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send the "Sector Erase (SE)" instruction */
-
- (void)SPI_SEND(priv->dev, M25P_SE);
-
- /* Send the sector offset high byte first. For all of the supported
- * parts, the sector number is completely contained in the first byte
- * and the values used in the following two bytes don't really matter.
- */
-
- (void)SPI_SEND(priv->dev, (offset >> 16) & 0xff);
- (void)SPI_SEND(priv->dev, (offset >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, offset & 0xff);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Erased\n");
-}
-
-/************************************************************************************
- * Name: m25p_bulkerase
- ************************************************************************************/
-
-static inline int m25p_bulkerase(struct m25p_dev_s *priv)
-{
- fvdbg("priv: %p\n", priv);
-
- /* Wait for any preceding write to complete. We could simplify things by
- * perform this wait at the end of each write operation (rather than at
- * the beginning of ALL operations), but have the wait first will slightly
- * improve performance.
- */
-
- m25p_waitwritecomplete(priv);
-
- /* Send write enable instruction */
-
- m25p_writeenable(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send the "Bulk Erase (BE)" instruction */
-
- (void)SPI_SEND(priv->dev, M25P_BE);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Return: OK\n");
- return OK;
-}
-
-/************************************************************************************
- * Name: m25p_pagewrite
- ************************************************************************************/
-
-static inline void m25p_pagewrite(struct m25p_dev_s *priv, FAR const uint8_t *buffer,
- off_t page)
-{
- off_t offset = page << priv->pageshift;
-
- fvdbg("page: %08lx offset: %08lx\n", (long)page, (long)offset);
-
- /* Wait for any preceding write to complete. We could simplify things by
- * perform this wait at the end of each write operation (rather than at
- * the beginning of ALL operations), but have the wait first will slightly
- * improve performance.
- */
-
- m25p_waitwritecomplete(priv);
-
- /* Enable the write access to the FLASH */
-
- m25p_writeenable(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Page Program (PP)" command */
-
- (void)SPI_SEND(priv->dev, M25P_PP);
-
- /* Send the page offset high byte first. */
-
- (void)SPI_SEND(priv->dev, (offset >> 16) & 0xff);
- (void)SPI_SEND(priv->dev, (offset >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, offset & 0xff);
-
- /* Then write the specified number of bytes */
-
- SPI_SNDBLOCK(priv->dev, buffer, 1 << priv->pageshift);
-
- /* Deselect the FLASH: Chip Select high */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Written\n");
-}
-
-/************************************************************************************
- * Name: m25p_erase
- ************************************************************************************/
-
-static int m25p_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks)
-{
- FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev;
- size_t blocksleft = nblocks;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Lock access to the SPI bus until we complete the erase */
-
- m25p_lock(priv->dev);
- while (blocksleft-- > 0)
- {
- /* Erase each sector */
-
- m25p_sectorerase(priv, startblock);
- startblock++;
- }
- m25p_unlock(priv->dev);
- return (int)nblocks;
-}
-
-/************************************************************************************
- * Name: m25p_bread
- ************************************************************************************/
-
-static ssize_t m25p_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR uint8_t *buffer)
-{
- FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev;
- ssize_t nbytes;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* On this device, we can handle the block read just like the byte-oriented read */
-
- nbytes = m25p_read(dev, startblock << priv->pageshift, nblocks << priv->pageshift, buffer);
- if (nbytes > 0)
- {
- return nbytes >> priv->pageshift;
- }
- return (int)nbytes;
-}
-
-/************************************************************************************
- * Name: m25p_bwrite
- ************************************************************************************/
-
-static ssize_t m25p_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR const uint8_t *buffer)
-{
- FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev;
- size_t blocksleft = nblocks;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Lock the SPI bus and write each page to FLASH */
-
- m25p_lock(priv->dev);
- while (blocksleft-- > 0)
- {
- m25p_pagewrite(priv, buffer, startblock);
- startblock++;
- }
- m25p_unlock(priv->dev);
-
- return nblocks;
-}
-
-/************************************************************************************
- * Name: m25p_read
- ************************************************************************************/
-
-static ssize_t m25p_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer)
-{
- FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev;
-
- fvdbg("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
-
- /* Wait for any preceding write to complete. We could simplify things by
- * perform this wait at the end of each write operation (rather than at
- * the beginning of ALL operations), but have the wait first will slightly
- * improve performance.
- */
-
- m25p_waitwritecomplete(priv);
-
- /* Lock the SPI bus and select this FLASH part */
-
- m25p_lock(priv->dev);
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read from Memory " instruction */
-
- (void)SPI_SEND(priv->dev, M25P_READ);
-
- /* Send the page offset high byte first. */
-
- (void)SPI_SEND(priv->dev, (offset >> 16) & 0xff);
- (void)SPI_SEND(priv->dev, (offset >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, offset & 0xff);
-
- /* Then read all of the requested bytes */
-
- SPI_RECVBLOCK(priv->dev, buffer, nbytes);
-
- /* Deselect the FLASH and unlock the SPI bus */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- m25p_unlock(priv->dev);
- fvdbg("return nbytes: %d\n", (int)nbytes);
- return nbytes;
-}
-
-/************************************************************************************
- * Name: m25p_ioctl
- ************************************************************************************/
-
-static int m25p_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
-{
- FAR struct m25p_dev_s *priv = (FAR struct m25p_dev_s *)dev;
- int ret = -EINVAL; /* Assume good command with bad parameters */
-
- fvdbg("cmd: %d \n", cmd);
-
- switch (cmd)
- {
- case MTDIOC_GEOMETRY:
- {
- FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg);
- if (geo)
- {
- /* Populate the geometry structure with information need to know
- * the capacity and how to access the device.
- *
- * NOTE: that the device is treated as though it where just an array
- * of fixed size blocks. That is most likely not true, but the client
- * will expect the device logic to do whatever is necessary to make it
- * appear so.
- */
-
- geo->blocksize = (1 << priv->pageshift);
- geo->erasesize = (1 << priv->sectorshift);
- geo->neraseblocks = priv->nsectors;
- ret = OK;
-
- fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n",
- geo->blocksize, geo->erasesize, geo->neraseblocks);
- }
- }
- break;
-
- case MTDIOC_BULKERASE:
- {
- /* Erase the entire device */
-
- m25p_lock(priv->dev);
- ret = m25p_bulkerase(priv);
- m25p_unlock(priv->dev);
- }
- break;
-
- case MTDIOC_XIPBASE:
- default:
- ret = -ENOTTY; /* Bad command */
- break;
- }
-
- fvdbg("return %d\n", ret);
- return ret;
-}
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: m25p_initialize
- *
- * Description:
- * Create an initialize MTD device instance. MTD devices are not registered
- * in the file system, but are created as instances that can be bound to
- * other functions (such as a block or character driver front end).
- *
- ************************************************************************************/
-
-FAR struct mtd_dev_s *m25p_initialize(FAR struct spi_dev_s *dev)
-{
- FAR struct m25p_dev_s *priv;
- int ret;
-
- fvdbg("dev: %p\n", dev);
-
- /* Allocate a state structure (we allocate the structure instead of using
- * a fixed, static allocation so that we can handle multiple FLASH devices.
- * The current implementation would handle only one FLASH part per SPI
- * device (only because of the SPIDEV_FLASH definition) and so would have
- * to be extended to handle multiple FLASH parts on the same SPI bus.
- */
-
- priv = (FAR struct m25p_dev_s *)kmalloc(sizeof(struct m25p_dev_s));
- if (priv)
- {
- /* Initialize the allocated structure */
-
- priv->mtd.erase = m25p_erase;
- priv->mtd.bread = m25p_bread;
- priv->mtd.bwrite = m25p_bwrite;
- priv->mtd.read = m25p_read;
- priv->mtd.ioctl = m25p_ioctl;
- priv->dev = dev;
-
- /* Deselect the FLASH */
-
- SPI_SELECT(dev, SPIDEV_FLASH, false);
-
- /* Identify the FLASH chip and get its capacity */
-
- ret = m25p_readid(priv);
- if (ret != OK)
- {
- /* Unrecognized! Discard all of that work we just did and return NULL */
-
- fdbg("Unrecognized\n");
- kfree(priv);
- priv = NULL;
- }
- }
-
- /* Return the implementation-specific state structure as the MTD device */
-
- fvdbg("Return %p\n", priv);
- return (FAR struct mtd_dev_s *)priv;
-}
diff --git a/nuttx/drivers/mtd/rammtd.c b/nuttx/drivers/mtd/rammtd.c
deleted file mode 100644
index 82a7191ea..000000000
--- a/nuttx/drivers/mtd/rammtd.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/****************************************************************************
- * drivers/mtd/rammtd.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/mtd.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Configuration ************************************************************/
-
-#ifndef CONFIG_RAMMTD_BLOCKSIZE
-# define CONFIG_RAMMTD_BLOCKSIZE 512
-#endif
-
-#ifndef CONFIG_RAMMTD_ERASESIZE
-# define CONFIG_RAMMTD_ERASESIZE 4096
-#endif
-
-#ifndef CONFIG_RAMMTD_ERASESTATE
-# define CONFIG_RAMMTD_ERASESTATE 0xff
-#endif
-
-#if CONFIG_RAMMTD_ERASESTATE != 0xff && CONFIG_RAMMTD_ERASESTATE != 0x00
-# error "Unsupported value for CONFIG_RAMMTD_ERASESTATE"
-#endif
-
-#if CONFIG_RAMMTD_BLOCKSIZE > CONFIG_RAMMTD_ERASESIZE
-# error "Must have CONFIG_RAMMTD_BLOCKSIZE <= CONFIG_RAMMTD_ERASESIZE"
-#endif
-
-#undef CONFIG_RAMMTD_BLKPER
-#define CONFIG_RAMMTD_BLKPER (CONFIG_RAMMTD_ERASESIZE/CONFIG_RAMMTD_BLOCKSIZE)
-
-#if CONFIG_RAMMTD_BLKPER*CONFIG_RAMMTD_BLOCKSIZE != CONFIG_RAMMTD_ERASESIZE
-# error "CONFIG_RAMMTD_ERASESIZE must be an even multiple of CONFIG_RAMMTD_BLOCKSIZE"
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This type represents the state of the MTD device. The struct mtd_dev_s
- * must appear at the beginning of the definition so that you can freely
- * cast between pointers to struct mtd_dev_s and struct ram_dev_s.
- */
-
-struct ram_dev_s
-{
- struct mtd_dev_s mtd; /* MTD device */
- FAR uint8_t *start; /* Start of RAM */
- size_t nblocks; /* Number of erase blocks */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-/* The RAM MTD driver may be useful just as it is, but another good use of
- * the RAM MTD driver is as a FLASH simulation -- to support testing of FLASH
- * based logic without having FLASH. CONFIG_RAMMTD_FLASHSIM will add some
- * extra logic to improve the level of FLASH simulation.
- */
-
-#define ram_read(dest, src, len) memcpy(dest, src, len)
-#ifdef CONFIG_RAMMTD_FLASHSIM
-static void *ram_write(FAR void *dest, FAR const void *src, size_t len);
-#else
-# define ram_write(dest, src, len) memcpy(dest, src, len)
-#endif
-
-/* MTD driver methods */
-
-static int ram_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks);
-static ssize_t ram_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR uint8_t *buf);
-static ssize_t ram_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR const uint8_t *buf);
-static int ram_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: ram_write
- ****************************************************************************/
-
-#ifdef CONFIG_RAMMTD_FLASHSIM
-static void *ram_write(FAR void *dest, FAR const void *src, size_t len)
-{
- FAR uint8_t *pout = (FAR uint8_t *)dest;
- FAR const uint8_t *pin = (FAR const uint8_t *)src;
-
- while (len-- > 0)
- {
- /* Get the source and destination values */
-
- uint8_t oldvalue = *pout;
- uint8_t srcvalue = *pin++;
- uint8_t newvalue;
-
- /* Get the new destination value, accounting for bits that cannot be
- * changes because they are not in the erased state.
- */
-
-#if CONFIG_RAMMTD_ERASESTATE == 0xff
- newvalue = oldvalue & srcvalue; /* We can only clear bits */
-#else /* CONFIG_RAMMTD_ERASESTATE == 0x00 */
- newvalue = oldvalue | srcvalue; /* We can only set bits */
-#endif
-
- /* Report any attempt to change the value of bits that are not in the
- * erased state.
- */
-
-#ifdef CONFIG_DEBUG
- if (newvalue != srcvalue)
- {
- dbg("ERROR: Bad write: source=%02x dest=%02x result=%02x\n",
- srcvalue, oldvalue, newvalue);
- }
-#endif
-
- /* Write the modified value to simulated FLASH */
-
- *pout++ = newvalue;
- }
-
- return dest;
-}
-#endif
-
-/****************************************************************************
- * Name: ram_erase
- ****************************************************************************/
-
-static int ram_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks)
-{
- FAR struct ram_dev_s *priv = (FAR struct ram_dev_s *)dev;
- off_t offset;
- size_t nbytes;
-
- DEBUGASSERT(dev);
-
- /* Don't let the erase exceed the size of the ram buffer */
-
- if (startblock >= priv->nblocks)
- {
- return 0;
- }
-
- if (startblock + nblocks > priv->nblocks)
- {
- nblocks = priv->nblocks - startblock;
- }
-
- /* Convert the erase block to a logical block and the number of blocks
- * in logical block numbers
- */
-
- startblock *= CONFIG_RAMMTD_BLKPER;
- nblocks *= CONFIG_RAMMTD_BLKPER;
-
- /* Get the offset corresponding to the first block and the size
- * corresponding to the number of blocks.
- */
-
- offset = startblock * CONFIG_RAMMTD_BLOCKSIZE;
- nbytes = nblocks * CONFIG_RAMMTD_BLOCKSIZE;
-
- /* Then erase the data in RAM */
-
- memset(&priv->start[offset], CONFIG_RAMMTD_ERASESTATE, nbytes);
- return OK;
-}
-
-/****************************************************************************
- * Name: ram_bread
- ****************************************************************************/
-
-static ssize_t ram_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR uint8_t *buf)
-{
- FAR struct ram_dev_s *priv = (FAR struct ram_dev_s *)dev;
- off_t offset;
- off_t maxblock;
- size_t nbytes;
-
- DEBUGASSERT(dev && buf);
-
- /* Don't let the read exceed the size of the ram buffer */
-
- maxblock = priv->nblocks * CONFIG_RAMMTD_BLKPER;
- if (startblock >= maxblock)
- {
- return 0;
- }
-
- if (startblock + nblocks > maxblock)
- {
- nblocks = maxblock - startblock;
- }
-
- /* Get the offset corresponding to the first block and the size
- * corresponding to the number of blocks.
- */
-
- offset = startblock * CONFIG_RAMMTD_BLOCKSIZE;
- nbytes = nblocks * CONFIG_RAMMTD_BLOCKSIZE;
-
- /* Then read the data frp, RAM */
-
- ram_read(buf, &priv->start[offset], nbytes);
- return nblocks;
-}
-
-/****************************************************************************
- * Name: ram_bwrite
- ****************************************************************************/
-
-static ssize_t ram_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR const uint8_t *buf)
-{
- FAR struct ram_dev_s *priv = (FAR struct ram_dev_s *)dev;
- off_t offset;
- off_t maxblock;
- size_t nbytes;
-
- DEBUGASSERT(dev && buf);
-
- /* Don't let the write exceed the size of the ram buffer */
-
- maxblock = priv->nblocks * CONFIG_RAMMTD_BLKPER;
- if (startblock >= maxblock)
- {
- return 0;
- }
-
- if (startblock + nblocks > maxblock)
- {
- nblocks = maxblock - startblock;
- }
-
- /* Get the offset corresponding to the first block and the size
- * corresponding to the number of blocks.
- */
-
- offset = startblock * CONFIG_RAMMTD_BLOCKSIZE;
- nbytes = nblocks * CONFIG_RAMMTD_BLOCKSIZE;
-
- /* Then write the data to RAM */
-
- ram_write(&priv->start[offset], buf, nbytes);
- return nblocks;
-}
-
-/****************************************************************************
- * Name: ram_ioctl
- ****************************************************************************/
-
-static int ram_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
-{
- FAR struct ram_dev_s *priv = (FAR struct ram_dev_s *)dev;
- int ret = -EINVAL; /* Assume good command with bad parameters */
-
- switch (cmd)
- {
- case MTDIOC_GEOMETRY:
- {
- FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg);
- if (geo)
- {
- /* Populate the geometry structure with information need to know
- * the capacity and how to access the device.
- */
-
- geo->blocksize = CONFIG_RAMMTD_BLOCKSIZE;
- geo->erasesize = CONFIG_RAMMTD_ERASESIZE;
- geo->neraseblocks = priv->nblocks;
- ret = OK;
- }
- }
- break;
-
- case MTDIOC_XIPBASE:
- {
- FAR void **ppv = (FAR void**)((uintptr_t)arg);
- if (ppv)
- {
- /* Return (void*) base address of device memory */
-
- *ppv = (FAR void*)priv->start;
- ret = OK;
- }
- }
- break;
-
- case MTDIOC_BULKERASE:
- {
- size_t size = priv->nblocks * CONFIG_RAMMTD_ERASESIZE;
-
- /* Erase the entire device */
-
- memset(priv->start, CONFIG_RAMMTD_ERASESTATE, size);
- ret = OK;
- }
- break;
-
- default:
- ret = -ENOTTY; /* Bad command */
- break;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: rammtd_initialize
- *
- * Description:
- * Create and initialize a RAM MTD device instance.
- *
- * Input Parameters:
- * start - Address of the beginning of the allocated RAM regions.
- * size - The size in bytes of the allocated RAM region.
- *
- ****************************************************************************/
-
-FAR struct mtd_dev_s *rammtd_initialize(FAR uint8_t *start, size_t size)
-{
- FAR struct ram_dev_s *priv;
- size_t nblocks;
-
- /* Create an instance of the RAM MTD device state structure */
-
- priv = (FAR struct ram_dev_s *)kmalloc(sizeof(struct ram_dev_s));
- if (!priv)
- {
- fdbg("Failed to allocate the RAM MTD state structure\n");
- return NULL;
- }
-
- /* Force the size to be an even number of the erase block size */
-
- nblocks = size / CONFIG_RAMMTD_ERASESIZE;
- if (nblocks <= 0)
- {
- fdbg("Need to provide at least one full erase block\n");
- return NULL;
- }
-
- /* Perform initialization as necessary */
-
- priv->mtd.erase = ram_erase;
- priv->mtd.bread = ram_bread;
- priv->mtd.bwrite = ram_bwrite;
- priv->mtd.ioctl = ram_ioctl;
- priv->mtd.erase = ram_erase;
-
- priv->start = start;
- priv->nblocks = nblocks;
- return &priv->mtd;
-}
diff --git a/nuttx/drivers/mtd/ramtron.c b/nuttx/drivers/mtd/ramtron.c
deleted file mode 100644
index 34273bccf..000000000
--- a/nuttx/drivers/mtd/ramtron.c
+++ /dev/null
@@ -1,686 +0,0 @@
-/************************************************************************************
- * drivers/mtd/ramtron.c
- * Driver for SPI-based RAMTRON NVRAM Devices FM25V10 and others (not tested)
- *
- * Copyright (C) 2011 Uros Platise. All rights reserved.
- * Copyright (C) 2009-2010, 2012 Gregory Nutt. All rights reserved.
- * Author: Uros Platise <uros.platise@isotel.eu>
- * Gregory Nutt <gnutt@nuttx.org>
- *
- * 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.
- *
- ************************************************************************************/
-
-/* OPTIONS:
- * - additional non-jedec standard device: FM25H20
- * must be enabled with the CONFIG_RAMTRON_FRAM_NON_JEDEC=y
- *
- * NOTE:
- * - frequency is fixed to desired max by RAMTRON_INIT_CLK_MAX
- * if new devices with different speed arrive, then SETFREQUENCY()
- * needs to handle freq changes and INIT_CLK_MAX must be reduced
- * to fit all devices. Note that STM32_SPI driver is prone to
- * too high freq. parameters and limit it within physical constraints.
- *
- * TODO:
- * - add support for sleep
- * - add support for faster read FSTRD command
- */
-
-/************************************************************************************
- * Included Files
- ************************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <debug.h>
-#include <assert.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/spi.h>
-#include <nuttx/mtd.h>
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-/* RAMTRON devices are flat!
- * For purpose of the VFAT file system we emulate the following configuration:
- */
-
-#define RAMTRON_EMULATE_SECTOR_SHIFT 9
-#define RAMTRON_EMULATE_PAGE_SHIFT 9
-
-/* RAMTRON Indentification register values */
-
-#define RAMTRON_MANUFACTURER 0x7F
-#define RAMTRON_MEMORY_TYPE 0xC2
-
-/* Instructions:
- * Command Value N Description Addr Dummy Data */
-#define RAMTRON_WREN 0x06 /* 1 Write Enable 0 0 0 */
-#define RAMTRON_WRDI 0x04 /* 1 Write Disable 0 0 0 */
-#define RAMTRON_RDSR 0x05 /* 1 Read Status Register 0 0 >=1 */
-#define RAMTRON_WRSR 0x01 /* 1 Write Status Register 0 0 1 */
-#define RAMTRON_READ 0x03 /* 1 Read Data Bytes A 0 >=1 */
-#define RAMTRON_FSTRD 0x0b /* 1 Higher speed read A 1 >=1 */
-#define RAMTRON_WRITE 0x02 /* 1 Write A 0 1-256 */
-#define RAMTRON_SLEEP 0xb9 // TODO:
-#define RAMTRON_RDID 0x9f /* 1 Read Identification 0 0 1-3 */
-#define RAMTRON_SN 0xc3 // TODO:
-
-
-/* Status register bit definitions */
-
-#define RAMTRON_SR_WIP (1 << 0) /* Bit 0: Write in progress bit */
-#define RAMTRON_SR_WEL (1 << 1) /* Bit 1: Write enable latch bit */
-#define RAMTRON_SR_BP_SHIFT (2) /* Bits 2-4: Block protect bits */
-#define RAMTRON_SR_BP_MASK (7 << RAMTRON_SR_BP_SHIFT)
-# define RAMTRON_SR_BP_NONE (0 << RAMTRON_SR_BP_SHIFT) /* Unprotected */
-# define RAMTRON_SR_BP_UPPER64th (1 << RAMTRON_SR_BP_SHIFT) /* Upper 64th */
-# define RAMTRON_SR_BP_UPPER32nd (2 << RAMTRON_SR_BP_SHIFT) /* Upper 32nd */
-# define RAMTRON_SR_BP_UPPER16th (3 << RAMTRON_SR_BP_SHIFT) /* Upper 16th */
-# define RAMTRON_SR_BP_UPPER8th (4 << RAMTRON_SR_BP_SHIFT) /* Upper 8th */
-# define RAMTRON_SR_BP_UPPERQTR (5 << RAMTRON_SR_BP_SHIFT) /* Upper quarter */
-# define RAMTRON_SR_BP_UPPERHALF (6 << RAMTRON_SR_BP_SHIFT) /* Upper half */
-# define RAMTRON_SR_BP_ALL (7 << RAMTRON_SR_BP_SHIFT) /* All sectors */
-#define RAMTRON_SR_SRWD (1 << 7) /* Bit 7: Status register write protect */
-
-#define RAMTRON_DUMMY 0xa5
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-struct ramtron_parts_s
-{
- const char *name;
- uint8_t id1;
- uint8_t id2;
- uint32_t size;
- uint8_t addr_len;
- uint32_t speed;
-};
-
-/* This type represents the state of the MTD device. The struct mtd_dev_s
- * must appear at the beginning of the definition so that you can freely
- * cast between pointers to struct mtd_dev_s and struct ramtron_dev_s.
- */
-
-struct ramtron_dev_s
-{
- struct mtd_dev_s mtd; /* MTD interface */
- FAR struct spi_dev_s *dev; /* Saved SPI interface instance */
- uint8_t sectorshift;
- uint8_t pageshift;
- uint16_t nsectors;
- uint32_t npages;
- const struct ramtron_parts_s *part; /* part instance */
-};
-
-/************************************************************************************
- * Supported Part Lists
- ************************************************************************************/
-
-/* Defines the initial speed compatible with all devices. In case of RAMTRON
- * the defined devices within the part list have all the same speed.
- */
-
-#define RAMTRON_INIT_CLK_MAX 40000000UL
-
-static struct ramtron_parts_s ramtron_parts[] =
-{
- {
- "FM25V02", /* name */
- 0x22, /* id1 */
- 0x00, /* id2 */
- 32L*1024L, /* size */
- 2, /* addr_len */
- 40000000 /* speed */
- },
- {
- "FM25VN02", /* name */
- 0x22, /* id1 */
- 0x01, /* id2 */
- 32L*1024L, /* size */
- 2, /* addr_len */
- 40000000 /* speed */
- },
- {
- "FM25V05", /* name */
- 0x23, /* id1 */
- 0x00, /* id2 */
- 64L*1024L, /* size */
- 2, /* addr_len */
- 40000000 /* speed */
- },
- {
- "FM25VN05", /* name */
- 0x23, /* id1 */
- 0x01, /* id2 */
- 64L*1024L, /* size */
- 2, /* addr_len */
- 40000000 /* speed */
- },
- {
- "FM25V10", /* name */
- 0x24, /* id1 */
- 0x00, /* id2 */
- 128L*1024L, /* size */
- 3, /* addr_len */
- 40000000 /* speed */
- },
- {
- "FM25VN10", /* name */
- 0x24, /* id1 */
- 0x01, /* id2 */
- 128L*1024L, /* size */
- 3, /* addr_len */
- 40000000 /* speed */
- },
-#ifdef CONFIG_RAMTRON_FRAM_NON_JEDEC
- {
- "FM25H20", /* name */
- 0xff, /* id1 */
- 0xff, /* id2 */
- 256L*1024L, /* size */
- 3, /* addr_len */
- 40000000 /* speed */
- },
- {
- NULL, /* name */
- 0, /* id1 */
- 0, /* id2 */
- 0, /* size */
- 0, /* addr_len */
- 0 /* speed */
- }
-#endif
-};
-
-
-/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-
-/* Helpers */
-
-static void ramtron_lock(FAR struct spi_dev_s *dev);
-static inline void ramtron_unlock(FAR struct spi_dev_s *dev);
-static inline int ramtron_readid(struct ramtron_dev_s *priv);
-static void ramtron_waitwritecomplete(struct ramtron_dev_s *priv);
-static void ramtron_writeenable(struct ramtron_dev_s *priv);
-static inline void ramtron_pagewrite(struct ramtron_dev_s *priv, FAR const uint8_t *buffer,
- off_t offset);
-
-/* MTD driver methods */
-
-static int ramtron_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks);
-static ssize_t ramtron_bread(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR uint8_t *buf);
-static ssize_t ramtron_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR const uint8_t *buf);
-static ssize_t ramtron_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer);
-static int ramtron_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
-
-/************************************************************************************
- * Private Data
- ************************************************************************************/
-
-/************************************************************************************
- * Private Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: ramtron_lock
- ************************************************************************************/
-
-static void ramtron_lock(FAR struct spi_dev_s *dev)
-{
- /* On SPI busses where there are multiple devices, it will be necessary to
- * lock SPI to have exclusive access to the busses for a sequence of
- * transfers. The bus should be locked before the chip is selected.
- *
- * This is a blocking call and will not return until we have exclusiv access to
- * the SPI buss. We will retain that exclusive access until the bus is unlocked.
- */
-
- (void)SPI_LOCK(dev, true);
-
- /* After locking the SPI bus, the we also need call the setfrequency, setbits, and
- * setmode methods to make sure that the SPI is properly configured for the device.
- * If the SPI buss is being shared, then it may have been left in an incompatible
- * state.
- */
-
- SPI_SETMODE(dev, SPIDEV_MODE3);
- SPI_SETBITS(dev, 8);
-
- (void)SPI_SETFREQUENCY(dev, RAMTRON_INIT_CLK_MAX);
-}
-
-/************************************************************************************
- * Name: ramtron_unlock
- ************************************************************************************/
-
-static inline void ramtron_unlock(FAR struct spi_dev_s *dev)
-{
- (void)SPI_LOCK(dev, false);
-}
-
-/************************************************************************************
- * Name: ramtron_readid
- ************************************************************************************/
-
-static inline int ramtron_readid(struct ramtron_dev_s *priv)
-{
- uint16_t manufacturer, memory, capacity, part;
- int i;
-
- fvdbg("priv: %p\n", priv);
-
- /* Lock the SPI bus, configure the bus, and select this FLASH part. */
-
- ramtron_lock(priv->dev);
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send the "Read ID (RDID)" command and read the first three ID bytes */
-
- (void)SPI_SEND(priv->dev, RAMTRON_RDID);
- for (i = 0; i < 6; i++)
- {
- manufacturer = SPI_SEND(priv->dev, RAMTRON_DUMMY);
- }
-
- memory = SPI_SEND(priv->dev, RAMTRON_DUMMY);
- capacity = SPI_SEND(priv->dev, RAMTRON_DUMMY); // fram.id1
- part = SPI_SEND(priv->dev, RAMTRON_DUMMY); // fram.id2
-
- /* Deselect the FLASH and unlock the bus */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- ramtron_unlock(priv->dev);
-
- /* Select part from the part list */
-
- for (priv->part = ramtron_parts;
- priv->part->name != NULL && !(priv->part->id1 == capacity && priv->part->id2 == part);
- priv->part++);
-
- if (priv->part->name)
- {
- fvdbg("RAMTRON %s of size %d bytes (mf:%02x mem:%02x cap:%02x part:%02x)\n",
- priv->part->name, priv->part->size, manufacturer, memory, capacity, part);
-
- priv->sectorshift = RAMTRON_EMULATE_SECTOR_SHIFT;
- priv->nsectors = priv->part->size / (1 << RAMTRON_EMULATE_SECTOR_SHIFT);
- priv->pageshift = RAMTRON_EMULATE_PAGE_SHIFT;
- priv->npages = priv->part->size / (1 << RAMTRON_EMULATE_PAGE_SHIFT);
- return OK;
- }
-
- fvdbg("RAMTRON device not found\n");
- return -ENODEV;
-}
-
-/************************************************************************************
- * Name: ramtron_waitwritecomplete
- ************************************************************************************/
-
-static void ramtron_waitwritecomplete(struct ramtron_dev_s *priv)
-{
- uint8_t status;
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read Status Register (RDSR)" command */
-
- (void)SPI_SEND(priv->dev, RAMTRON_RDSR);
-
- /* Loop as long as the memory is busy with a write cycle */
-
- do
- {
- /* Send a dummy byte to generate the clock needed to shift out the status */
-
- status = SPI_SEND(priv->dev, RAMTRON_DUMMY);
- }
- while ((status & RAMTRON_SR_WIP) != 0);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Complete\n");
-}
-
-/************************************************************************************
- * Name: ramtron_writeenable
- ************************************************************************************/
-
-static void ramtron_writeenable(struct ramtron_dev_s *priv)
-{
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Write Enable (WREN)" command */
-
- (void)SPI_SEND(priv->dev, RAMTRON_WREN);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Enabled\n");
-}
-
-/************************************************************************************
- * Name: ramtron_sendaddr
- ************************************************************************************/
-
-static inline void ramtron_sendaddr(const struct ramtron_dev_s *priv, uint32_t addr)
-{
- DEBUGASSERT(priv->part->addr_len == 3 || priv->part->addr_len == 2);
-
- if (priv->part->addr_len == 3)
- {
- (void)SPI_SEND(priv->dev, (addr >> 16) & 0xff);
- }
-
- (void)SPI_SEND(priv->dev, (addr >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, addr & 0xff);
-}
-
-/************************************************************************************
- * Name: ramtron_pagewrite
- ************************************************************************************/
-
-static inline void ramtron_pagewrite(struct ramtron_dev_s *priv, FAR const uint8_t *buffer,
- off_t page)
-{
- off_t offset = page << priv->pageshift;
-
- fvdbg("page: %08lx offset: %08lx\n", (long)page, (long)offset);
-
- /* Wait for any preceding write to complete. We could simplify things by
- * perform this wait at the end of each write operation (rather than at
- * the beginning of ALL operations), but have the wait first will slightly
- * improve performance.
- */
-
- ramtron_waitwritecomplete(priv);
-
- /* Enable the write access to the FLASH */
-
- ramtron_writeenable(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Page Program (PP)" command */
-
- (void)SPI_SEND(priv->dev, RAMTRON_WRITE);
-
- /* Send the page offset high byte first. */
-
- ramtron_sendaddr(priv, offset);
-
- /* Then write the specified number of bytes */
-
- SPI_SNDBLOCK(priv->dev, buffer, 1 << priv->pageshift);
-
- /* Deselect the FLASH: Chip Select high */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Written\n");
-}
-
-/************************************************************************************
- * Name: ramtron_erase
- ************************************************************************************/
-
-static int ramtron_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks)
-{
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
- fvdbg("On RAMTRON devices erasing makes no sense, returning as OK\n");
- return (int)nblocks;
-}
-
-/************************************************************************************
- * Name: ramtron_bread
- ************************************************************************************/
-
-static ssize_t ramtron_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR uint8_t *buffer)
-{
- FAR struct ramtron_dev_s *priv = (FAR struct ramtron_dev_s *)dev;
- ssize_t nbytes;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* On this device, we can handle the block read just like the byte-oriented read */
-
- nbytes = ramtron_read(dev, startblock << priv->pageshift, nblocks << priv->pageshift, buffer);
- if (nbytes > 0)
- {
- return nbytes >> priv->pageshift;
- }
-
- return (int)nbytes;
-}
-
-/************************************************************************************
- * Name: ramtron_bwrite
- ************************************************************************************/
-
-static ssize_t ramtron_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR const uint8_t *buffer)
-{
- FAR struct ramtron_dev_s *priv = (FAR struct ramtron_dev_s *)dev;
- size_t blocksleft = nblocks;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Lock the SPI bus and write each page to FLASH */
-
- ramtron_lock(priv->dev);
- while (blocksleft-- > 0)
- {
- ramtron_pagewrite(priv, buffer, startblock);
- startblock++;
- }
-
- ramtron_unlock(priv->dev);
- return nblocks;
-}
-
-/************************************************************************************
- * Name: ramtron_read
- ************************************************************************************/
-
-static ssize_t ramtron_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer)
-{
- FAR struct ramtron_dev_s *priv = (FAR struct ramtron_dev_s *)dev;
-
- fvdbg("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
-
- /* Wait for any preceding write to complete. We could simplify things by
- * perform this wait at the end of each write operation (rather than at
- * the beginning of ALL operations), but have the wait first will slightly
- * improve performance.
- */
-
- ramtron_waitwritecomplete(priv);
-
- /* Lock the SPI bus and select this FLASH part */
-
- ramtron_lock(priv->dev);
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read from Memory " instruction */
-
- (void)SPI_SEND(priv->dev, RAMTRON_READ);
-
- /* Send the page offset high byte first. */
-
- ramtron_sendaddr(priv, offset);
-
- /* Then read all of the requested bytes */
-
- SPI_RECVBLOCK(priv->dev, buffer, nbytes);
-
- /* Deselect the FLASH and unlock the SPI bus */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- ramtron_unlock(priv->dev);
- fvdbg("return nbytes: %d\n", (int)nbytes);
- return nbytes;
-}
-
-/************************************************************************************
- * Name: ramtron_ioctl
- ************************************************************************************/
-
-static int ramtron_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
-{
- FAR struct ramtron_dev_s *priv = (FAR struct ramtron_dev_s *)dev;
- int ret = -EINVAL; /* Assume good command with bad parameters */
-
- fvdbg("cmd: %d \n", cmd);
-
- switch (cmd)
- {
- case MTDIOC_GEOMETRY:
- {
- FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg);
- if (geo)
- {
- /* Populate the geometry structure with information need to know
- * the capacity and how to access the device.
- *
- * NOTE: that the device is treated as though it where just an array
- * of fixed size blocks. That is most likely not true, but the client
- * will expect the device logic to do whatever is necessary to make it
- * appear so.
- */
-
- geo->blocksize = (1 << priv->pageshift);
- geo->erasesize = (1 << priv->sectorshift);
- geo->neraseblocks = priv->nsectors;
- ret = OK;
-
- fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n",
- geo->blocksize, geo->erasesize, geo->neraseblocks);
- }
- }
- break;
-
- case MTDIOC_BULKERASE:
- fvdbg("BULDERASE: Makes no sense in ramtron. Let's confirm operation as OK\n");
- ret = OK;
- break;
-
- case MTDIOC_XIPBASE:
- default:
- ret = -ENOTTY; /* Bad command */
- break;
- }
-
- fvdbg("return %d\n", ret);
- return ret;
-}
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: ramtron_initialize
- *
- * Description:
- * Create an initialize MTD device instance. MTD devices are not registered
- * in the file system, but are created as instances that can be bound to
- * other functions (such as a block or character driver front end).
- *
- ************************************************************************************/
-
-FAR struct mtd_dev_s *ramtron_initialize(FAR struct spi_dev_s *dev)
-{
- FAR struct ramtron_dev_s *priv;
-
- fvdbg("dev: %p\n", dev);
-
- /* Allocate a state structure (we allocate the structure instead of using
- * a fixed, static allocation so that we can handle multiple FLASH devices.
- * The current implementation would handle only one FLASH part per SPI
- * device (only because of the SPIDEV_FLASH definition) and so would have
- * to be extended to handle multiple FLASH parts on the same SPI bus.
- */
-
- priv = (FAR struct ramtron_dev_s *)kmalloc(sizeof(struct ramtron_dev_s));
- if (priv)
- {
- /* Initialize the allocated structure */
-
- priv->mtd.erase = ramtron_erase;
- priv->mtd.bread = ramtron_bread;
- priv->mtd.bwrite = ramtron_bwrite;
- priv->mtd.read = ramtron_read;
- priv->mtd.ioctl = ramtron_ioctl;
- priv->dev = dev;
-
- /* Deselect the FLASH */
-
- SPI_SELECT(dev, SPIDEV_FLASH, false);
-
- /* Identify the FLASH chip and get its capacity */
-
- if (ramtron_readid(priv) != OK)
- {
- /* Unrecognized! Discard all of that work we just did and return NULL */
-
- kfree(priv);
- priv = NULL;
- }
- }
-
- /* Return the implementation-specific state structure as the MTD device */
-
- fvdbg("Return %p\n", priv);
- return (FAR struct mtd_dev_s *)priv;
-}
diff --git a/nuttx/drivers/mtd/skeleton.c b/nuttx/drivers/mtd/skeleton.c
deleted file mode 100644
index a2fb98238..000000000
--- a/nuttx/drivers/mtd/skeleton.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/****************************************************************************
- * drivers/mtd/skeleton.c
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <errno.h>
-
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/mtd.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This type represents the state of the MTD device. The struct mtd_dev_s
- * must appear at the beginning of the definition so that you can freely
- * cast between pointers to struct mtd_dev_s and struct skel_dev_s.
- */
-
-struct skel_dev_s
-{
- struct mtd_dev_s mtd;
-
- /* Other implementation specific data may follow here */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* MTD driver methods */
-
-static int skel_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks);
-static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR uint8_t *buf);
-static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR const uint8_t *buf);
-static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer);
-static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static struct skel_dev_s g_skeldev =
-{
- { skel_erase, skel_rbead, skel_bwrite, skel_read, skel_ioctl },
- /* Initialization of any other implemenation specific data goes here */
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: skel_erase
- ****************************************************************************/
-
-static int skel_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks)
-{
- FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
-
- /* The interface definition assumes that all erase blocks ar the same size.
- * If that is not true for this particular device, then transform the
- * start block and nblocks as necessary.
- */
-
- /* Erase the specified blocks and return status (OK or a negated errno) */
-
- return OK;
-}
-
-/****************************************************************************
- * Name: skel_bread
- ****************************************************************************/
-
-static ssize_t skel_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR uint8_t *buf)
-{
- FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
-
- /* The interface definition assumes that all read/write blocks ar the same size.
- * If that is not true for this particular device, then transform the
- * start block and nblocks as necessary.
- */
-
- /* Read the specified blocks into the provided user buffer and return status
- * (The positive, number of blocks actually read or a negated errno).
- */
-
- return 0;
-}
-
-/****************************************************************************
- * Name: skel_bwrite
- ****************************************************************************/
-
-static ssize_t skel_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR const uint8_t *buf)
-{
- FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
-
- /* The interface definition assumes that all read/write blocks ar the same size.
- * If that is not true for this particular device, then transform the
- * start block and nblocks as necessary.
- */
-
- /* Write the specified blocks from the provided user buffer and return status
- * (The positive, number of blocks actually written or a negated errno)
- */
-
- return 0;
-}
-
-/****************************************************************************
- * Name: skel_read
- ****************************************************************************/
-
-static ssize_t skel_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer)
-{
- FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
-
- /* Some devices may support byte oriented read (optional). Byte-oriented
- * writing is inherently block oriented on most MTD devices and is not supported.
- * It is recommended that low-level drivers not support read() if it requires
- * buffering -- let the higher level logic handle that. If the read method is
- * not implemented, just set the method pointer to NULL in the struct mtd_dev_s
- * instance.
- */
-
- /* The interface definition assumes that all read/write blocks ar the same size.
- * If that is not true for this particular device, then transform the
- * start block and nblocks as necessary.
- */
-
- /* Read the specified blocks into the provided user buffer and return status
- * (The positive, number of blocks actually read or a negated errno)
- */
-
- return 0;
-}
-
-/****************************************************************************
- * Name: skel_ioctl
- ****************************************************************************/
-
-static int skel_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
-{
- FAR struct skel_dev_s *priv = (FAR struct skel_dev_s *)dev;
- int ret = -EINVAL; /* Assume good command with bad parameters */
-
- switch (cmd)
- {
- case MTDIOC_GEOMETRY:
- {
- FAR struct mtd_geometry_s *geo = (FARstruct mtd_geometry_s *)arg;
- if (geo)
- {
- /* Populate the geometry structure with information need to know
- * the capacity and how to access the device.
- *
- * NOTE: that the device is treated as though it where just an array
- * of fixed size blocks. That is most likely not true, but the client
- * will expect the device logic to do whatever is necessary to make it
- * appear so.
- */
-
- geo->blocksize = 512; /* Size of one read/write block */
- geo->erasesize = 4096; /* Size of one erase block */
- geo->neraseblocks = 1024; /* Number of erase blocks */
- ret = OK;
- }
- }
- break;
-
- case MTDIOC_XIPBASE:
- {
- FAR void **ppv = (FAR void**)arg;
-
- if (ppv)
- {
- /* If media is directly acccesible, return (void*) base address
- * of device memory. NULL otherwise. It is acceptable to omit
- * this case altogether and simply return -ENOTTY.
- */
-
- *ppv = NULL;
- ret = OK;
- }
- }
- break;
-
- case MTDIOC_BULKERASE:
- {
- /* Erase the entire device */
-
- ret = OK;
- }
- break;
-
- default:
- ret = -ENOTTY; /* Bad command */
- break;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: skel_initialize
- *
- * Description:
- * Create and initialize an MTD device instance. MTD devices are not
- * registered in the file system, but are created as instances that can
- * be bound to other functions (such as a block or character driver front
- * end).
- *
- ****************************************************************************/
-
-void skel_initialize(void)
-{
- /* Perform initialization as necessary */
-
- /* Return the implementation-specific state structure as the MTD device */
-
- return (FAR struct mtd_dev_s *)&g_skeldev;
-}
diff --git a/nuttx/drivers/mtd/sst25.c b/nuttx/drivers/mtd/sst25.c
deleted file mode 100644
index 66d201add..000000000
--- a/nuttx/drivers/mtd/sst25.c
+++ /dev/null
@@ -1,1250 +0,0 @@
-/************************************************************************************
- * drivers/mtd/sst25.c
- * Driver for SPI-based SST25 FLASH.
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/spi.h>
-#include <nuttx/mtd.h>
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-/* Configuration ********************************************************************/
-/* Per the data sheet, the SST25 parts can be driven with either SPI mode 0 (CPOL=0
- * and CPHA=0) or mode 3 (CPOL=1 and CPHA=1). But I have heard that other devices
- * can operate in mode 0 or 1. So you may need to specify CONFIG_SST25_SPIMODE to
- * select the best mode for your device. If CONFIG_SST25_SPIMODE is not defined,
- * mode 0 will be used.
- */
-
-#ifndef CONFIG_SST25_SPIMODE
-# define CONFIG_SST25_SPIMODE SPIDEV_MODE0
-#endif
-
-/* SPI Frequency. May be up to 25MHz. */
-
-#ifndef CONFIG_SST25_SPIFREQUENCY
-# define CONFIG_SST25_SPIFREQUENCY 20000000
-#endif
-
-/* There is a bug in the current code when using the higher speed AAI write sequence.
- * The nature of the bug is that the WRDI instruction is not working. At the end
- * of the AAI sequence, the status register continues to report that the SST25 is
- * write enabled (WEL bit) and in AAI mode (AAI bit). This *must* be fixed in any
- * production code if you want to have proper write performance.
- */
-
-#warning "REVISIT"
-#undef CONFIG_SST25_SLOWWRITE
-#define CONFIG_SST25_SLOWWRITE 1
-
-/* SST25 Instructions ***************************************************************/
-/* Command Value Description Addr Data */
-/* Dummy */
-#define SST25_READ 0x03 /* Read data bytes 3 0 >=1 */
-#define SST25_FAST_READ 0x0b /* Higher speed read 3 1 >=1 */
-#define SST25_SE 0x20 /* 4Kb Sector erase 3 0 0 */
-#define SST25_BE32 0x52 /* 32Kbit block Erase 3 0 0 */
-#define SST25_BE64 0xd8 /* 64Kbit block Erase 3 0 0 */
-#define SST25_CE 0xc7 /* Chip erase 0 0 0 */
-#define SST25_CE_ALT 0x60 /* Chip erase (alternate) 0 0 0 */
-#define SST25_BP 0x02 /* Byte program 3 0 1 */
-#define SST25_AAI 0xad /* Auto address increment 3 0 >=2 */
-#define SST25_RDSR 0x05 /* Read status register 0 0 >=1 */
-#define SST25_EWSR 0x50 /* Write enable status 0 0 0 */
-#define SST25_WRSR 0x01 /* Write Status Register 0 0 1 */
-#define SST25_WREN 0x06 /* Write Enable 0 0 0 */
-#define SST25_WRDI 0x04 /* Write Disable 0 0 0 */
-#define SST25_RDID 0xab /* Read Identification 0 0 >=1 */
-#define SST25_RDID_ALT 0x90 /* Read Identification (alt) 0 0 >=1 */
-#define SST25_JEDEC_ID 0x9f /* JEDEC ID read 0 0 >=3 */
-#define SST25_EBSY 0x70 /* Enable SO RY/BY# status 0 0 0 */
-#define SST25_DBSY 0x80 /* Disable SO RY/BY# status 0 0 0 */
-
-/* SST25 Registers ******************************************************************/
-/* Read ID (RDID) register values */
-
-#define SST25_MANUFACTURER 0xbf /* SST manufacturer ID */
-#define SST25_VF032_DEVID 0x20 /* SSTVF032B device ID */
-
-/* JEDEC Read ID register values */
-
-#define SST25_JEDEC_MANUFACTURER 0xbf /* SST manufacturer ID */
-#define SST25_JEDEC_MEMORY_TYPE 0x25 /* SST25 memory type */
-#define SST25_JEDEC_MEMORY_CAPACITY 0x4a /* SST25VF032B memory capacity */
-
-/* Status register bit definitions */
-
-#define SST25_SR_BUSY (1 << 0) /* Bit 0: Write in progress */
-#define SST25_SR_WEL (1 << 1) /* Bit 1: Write enable latch bit */
-#define SST25_SR_BP_SHIFT (2) /* Bits 2-5: Block protect bits */
-#define SST25_SR_BP_MASK (15 << SST25_SR_BP_SHIFT)
-# define SST25_SR_BP_NONE (0 << SST25_SR_BP_SHIFT) /* Unprotected */
-# define SST25_SR_BP_UPPER64th (1 << SST25_SR_BP_SHIFT) /* Upper 64th */
-# define SST25_SR_BP_UPPER32nd (2 << SST25_SR_BP_SHIFT) /* Upper 32nd */
-# define SST25_SR_BP_UPPER16th (3 << SST25_SR_BP_SHIFT) /* Upper 16th */
-# define SST25_SR_BP_UPPER8th (4 << SST25_SR_BP_SHIFT) /* Upper 8th */
-# define SST25_SR_BP_UPPERQTR (5 << SST25_SR_BP_SHIFT) /* Upper quarter */
-# define SST25_SR_BP_UPPERHALF (6 << SST25_SR_BP_SHIFT) /* Upper half */
-# define SST25_SR_BP_ALL (7 << SST25_SR_BP_SHIFT) /* All sectors */
-#define SST25_SR_AAI (1 << 6) /* Bit 6: Auto Address increment programming */
-#define SST25_SR_SRWD (1 << 7) /* Bit 7: Status register write protect */
-
-#define SST25_DUMMY 0xa5
-
-/* Chip Geometries ******************************************************************/
-/* SST25VF512 capacity is 512Kbit (64Kbit x 8) = 64Kb (8Kb x 8)*/
-/* SST25VF010 capacity is 1Mbit (128Kbit x 8) = 128Kb (16Kb x 8*/
-/* SST25VF520 capacity is 2Mbit (256Kbit x 8) = 256Kb (32Kb x 8) */
-/* SST25VF540 capacity is 4Mbit (512Kbit x 8) = 512Kb (64Kb x 8) */
-/* SST25VF080 capacity is 8Mbit (1024Kbit x 8) = 1Mb (128Kb x 8) */
-/* SST25VF016 capacity is 16Mbit (2048Kbit x 8) = 2Mb (256Kb x 8) */
-/* Not yet supported */
-
-/* SST25VF032 capacity is 32Mbit (4096Kbit x 8) = 4Mb (512kb x 8) */
-
-#define SST25_VF032_SECTOR_SHIFT 12 /* Sector size 1 << 12 = 4Kb */
-#define SST25_VF032_NSECTORS 1024 /* 1024 sectors x 4096 bytes/sector = 4Mb */
-
-#ifdef CONFIG_SST25_SECTOR512 /* Simulate a 512 byte sector */
-# define SST25_SECTOR_SHIFT 9 /* Sector size 1 << 9 = 512 bytes */
-# define SST25_SECTOR_SIZE 512 /* Sector size = 512 bytes */
-#endif
-
-#define SST25_ERASED_STATE 0xff /* State of FLASH when erased */
-
-/* Cache flags */
-
-#define SST25_CACHE_VALID (1 << 0) /* 1=Cache has valid data */
-#define SST25_CACHE_DIRTY (1 << 1) /* 1=Cache is dirty */
-#define SST25_CACHE_ERASED (1 << 2) /* 1=Backing FLASH is erased */
-
-#define IS_VALID(p) ((((p)->flags) & SST25_CACHE_VALID) != 0)
-#define IS_DIRTY(p) ((((p)->flags) & SST25_CACHE_DIRTY) != 0)
-#define IS_ERASED(p) ((((p)->flags) & SST25_CACHE_DIRTY) != 0)
-
-#define SET_VALID(p) do { (p)->flags |= SST25_CACHE_VALID; } while (0)
-#define SET_DIRTY(p) do { (p)->flags |= SST25_CACHE_DIRTY; } while (0)
-#define SET_ERASED(p) do { (p)->flags |= SST25_CACHE_DIRTY; } while (0)
-
-#define CLR_VALID(p) do { (p)->flags &= ~SST25_CACHE_VALID; } while (0)
-#define CLR_DIRTY(p) do { (p)->flags &= ~SST25_CACHE_DIRTY; } while (0)
-#define CLR_ERASED(p) do { (p)->flags &= ~SST25_CACHE_DIRTY; } while (0)
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-/* This type represents the state of the MTD device. The struct mtd_dev_s must
- * appear at the beginning of the definition so that you can freely cast between
- * pointers to struct mtd_dev_s and struct sst25_dev_s.
- */
-
-struct sst25_dev_s
-{
- struct mtd_dev_s mtd; /* MTD interface */
- FAR struct spi_dev_s *dev; /* Saved SPI interface instance */
- uint16_t nsectors; /* Number of erase sectors */
- uint8_t sectorshift; /* Log2 of erase sector size */
-
-#if defined(CONFIG_SST25_SECTOR512) && !defined(CONFIG_SST25_READONLY)
- uint8_t flags; /* Buffered sector flags */
- uint16_t esectno; /* Erase sector number in the cache*/
- FAR uint8_t *sector; /* Allocated sector data */
-#endif
-};
-
-/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-
-/* Helpers */
-
-static void sst25_lock(FAR struct spi_dev_s *dev);
-static inline void sst25_unlock(FAR struct spi_dev_s *dev);
-static inline int sst25_readid(FAR struct sst25_dev_s *priv);
-#ifndef CONFIG_SST25_READONLY
-static void sst25_unprotect(FAR struct spi_dev_s *dev);
-#endif
-static uint8_t sst25_waitwritecomplete(FAR struct sst25_dev_s *priv);
-static inline void sst25_wren(FAR struct sst25_dev_s *priv);
-static inline void sst25_wrdi(FAR struct sst25_dev_s *priv);
-static void sst25_sectorerase(FAR struct sst25_dev_s *priv, off_t offset);
-static inline int sst25_chiperase(FAR struct sst25_dev_s *priv);
-static void sst25_byteread(FAR struct sst25_dev_s *priv, FAR uint8_t *buffer,
- off_t address, size_t nbytes);
-#ifndef CONFIG_SST25_READONLY
-#ifdef CONFIG_SST25_SLOWWRITE
-static void sst25_bytewrite(FAR struct sst25_dev_s *priv, FAR const uint8_t *buffer,
- off_t address, size_t nbytes);
-#else
-static void sst25_wordwrite(FAR struct sst25_dev_s *priv, FAR const uint8_t *buffer,
- off_t address, size_t nbytes);
-#endif
-#ifdef CONFIG_SST25_SECTOR512
-static void sst25_cacheflush(struct sst25_dev_s *priv);
-static FAR uint8_t *sst25_cacheread(struct sst25_dev_s *priv, off_t sector);
-static void sst25_cacheerase(struct sst25_dev_s *priv, off_t sector);
-static void sst25_cachewrite(FAR struct sst25_dev_s *priv, FAR const uint8_t *buffer,
- off_t sector, size_t nsectors);
-#endif
-#endif
-
-/* MTD driver methods */
-
-static int sst25_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks);
-static ssize_t sst25_bread(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR uint8_t *buf);
-static ssize_t sst25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR const uint8_t *buf);
-static ssize_t sst25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer);
-static int sst25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
-
-/************************************************************************************
- * Private Data
- ************************************************************************************/
-
-/************************************************************************************
- * Private Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: sst25_lock
- ************************************************************************************/
-
-static void sst25_lock(FAR struct spi_dev_s *dev)
-{
- /* On SPI busses where there are multiple devices, it will be necessary to
- * lock SPI to have exclusive access to the busses for a sequence of
- * transfers. The bus should be locked before the chip is selected.
- *
- * This is a blocking call and will not return until we have exclusiv access to
- * the SPI buss. We will retain that exclusive access until the bus is unlocked.
- */
-
- (void)SPI_LOCK(dev, true);
-
- /* After locking the SPI bus, the we also need call the setfrequency, setbits, and
- * setmode methods to make sure that the SPI is properly configured for the device.
- * If the SPI buss is being shared, then it may have been left in an incompatible
- * state.
- */
-
- SPI_SETMODE(dev, CONFIG_SST25_SPIMODE);
- SPI_SETBITS(dev, 8);
- (void)SPI_SETFREQUENCY(dev, CONFIG_SST25_SPIFREQUENCY);
-}
-
-/************************************************************************************
- * Name: sst25_unlock
- ************************************************************************************/
-
-static inline void sst25_unlock(FAR struct spi_dev_s *dev)
-{
- (void)SPI_LOCK(dev, false);
-}
-
-/************************************************************************************
- * Name: sst25_readid
- ************************************************************************************/
-
-static inline int sst25_readid(struct sst25_dev_s *priv)
-{
- uint16_t manufacturer;
- uint16_t memory;
- uint16_t capacity;
-
- fvdbg("priv: %p\n", priv);
-
- /* Lock the SPI bus, configure the bus, and select this FLASH part. */
-
- sst25_lock(priv->dev);
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send the "Read ID (RDID)" command and read the first three ID bytes */
-
- (void)SPI_SEND(priv->dev, SST25_JEDEC_ID);
- manufacturer = SPI_SEND(priv->dev, SST25_DUMMY);
- memory = SPI_SEND(priv->dev, SST25_DUMMY);
- capacity = SPI_SEND(priv->dev, SST25_DUMMY);
-
- /* Deselect the FLASH and unlock the bus */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- sst25_unlock(priv->dev);
-
- fvdbg("manufacturer: %02x memory: %02x capacity: %02x\n",
- manufacturer, memory, capacity);
-
- /* Check for a valid manufacturer and memory type */
-
- if (manufacturer == SST25_JEDEC_MANUFACTURER && memory == SST25_JEDEC_MEMORY_TYPE)
- {
- /* Okay.. is it a FLASH capacity that we understand? This should be extended
- * support other members of the SST25 family.
- */
-
- if (capacity == SST25_JEDEC_MEMORY_CAPACITY)
- {
- /* Save the FLASH geometry */
-
- priv->sectorshift = SST25_VF032_SECTOR_SHIFT;
- priv->nsectors = SST25_VF032_NSECTORS;
- return OK;
- }
- }
-
- return -ENODEV;
-}
-
-/************************************************************************************
- * Name: sst25_unprotect
- ************************************************************************************/
-
-#ifndef CONFIG_SST25_READONLY
-static void sst25_unprotect(FAR struct spi_dev_s *dev)
-{
- /* Select this FLASH part */
-
- SPI_SELECT(dev, SPIDEV_FLASH, true);
-
- /* Send "Write enable status (EWSR)" */
-
- SPI_SEND(dev, SST25_EWSR);
-
- /* Re-select this FLASH part (This might not be necessary... but is it shown in
- * the timing diagrams)
- */
-
- SPI_SELECT(dev, SPIDEV_FLASH, false);
- SPI_SELECT(dev, SPIDEV_FLASH, true);
-
- /* Send "Write enable status (EWSR)" */
-
- SPI_SEND(dev, SST25_WRSR);
-
- /* Following by the new status value */
-
- SPI_SEND(dev, 0);
-}
-#endif
-
-/************************************************************************************
- * Name: sst25_waitwritecomplete
- ************************************************************************************/
-
-static uint8_t sst25_waitwritecomplete(struct sst25_dev_s *priv)
-{
- uint8_t status;
-
- /* Are we the only device on the bus? */
-
-#ifdef CONFIG_SPI_OWNBUS
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read Status Register (RDSR)" command */
-
- (void)SPI_SEND(priv->dev, SST25_RDSR);
-
- /* Loop as long as the memory is busy with a write cycle */
-
- do
- {
- /* Send a dummy byte to generate the clock needed to shift out the status */
-
- status = SPI_SEND(priv->dev, SST25_DUMMY);
- }
- while ((status & SST25_SR_BUSY) != 0);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-
-#else
-
- /* Loop as long as the memory is busy with a write cycle */
-
- do
- {
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read Status Register (RDSR)" command */
-
- (void)SPI_SEND(priv->dev, SST25_RDSR);
-
- /* Send a dummy byte to generate the clock needed to shift out the status */
-
- status = SPI_SEND(priv->dev, SST25_DUMMY);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-
- /* Given that writing could take up to few tens of milliseconds, and erasing
- * could take more. The following short delay in the "busy" case will allow
- * other peripherals to access the SPI bus.
- */
-
-#if 0 /* Makes writes too slow */
- if ((status & SST25_SR_BUSY) != 0)
- {
- sst25_unlock(priv->dev);
- usleep(1000);
- sst25_lock(priv->dev);
- }
-#endif
- }
- while ((status & SST25_SR_BUSY) != 0);
-#endif
-
- return status;
-}
-
-/************************************************************************************
- * Name: sst25_wren
- ************************************************************************************/
-
-static inline void sst25_wren(struct sst25_dev_s *priv)
-{
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Write Enable (WREN)" command */
-
- (void)SPI_SEND(priv->dev, SST25_WREN);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-}
-
-/************************************************************************************
- * Name: sst25_wrdi
- ************************************************************************************/
-
-static inline void sst25_wrdi(struct sst25_dev_s *priv)
-{
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Write Disable (WRDI)" command */
-
- (void)SPI_SEND(priv->dev, SST25_WRDI);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-}
-
-/************************************************************************************
- * Name: sst25_sectorerase
- ************************************************************************************/
-
-static void sst25_sectorerase(struct sst25_dev_s *priv, off_t sector)
-{
- off_t address = sector << priv->sectorshift;
-
- fvdbg("sector: %08lx\n", (long)sector);
-
- /* Wait for any preceding write or erase operation to complete. */
-
- (void)sst25_waitwritecomplete(priv);
-
- /* Send write enable instruction */
-
- sst25_wren(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send the "Sector Erase (SE)" instruction */
-
- (void)SPI_SEND(priv->dev, SST25_SE);
-
- /* Send the sector address high byte first. Only the most significant bits (those
- * corresponding to the sector) have any meaning.
- */
-
- (void)SPI_SEND(priv->dev, (address >> 16) & 0xff);
- (void)SPI_SEND(priv->dev, (address >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, address & 0xff);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-}
-
-/************************************************************************************
- * Name: sst25_chiperase
- ************************************************************************************/
-
-static inline int sst25_chiperase(struct sst25_dev_s *priv)
-{
- fvdbg("priv: %p\n", priv);
-
- /* Wait for any preceding write or erase operation to complete. */
-
- (void)sst25_waitwritecomplete(priv);
-
- /* Send write enable instruction */
-
- sst25_wren(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send the "Chip Erase (CE)" instruction */
-
- (void)SPI_SEND(priv->dev, SST25_CE);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- fvdbg("Return: OK\n");
- return OK;
-}
-
-/************************************************************************************
- * Name: sst25_byteread
- ************************************************************************************/
-
-static void sst25_byteread(FAR struct sst25_dev_s *priv, FAR uint8_t *buffer,
- off_t address, size_t nbytes)
-{
- uint8_t status;
-
- fvdbg("address: %08lx nbytes: %d\n", (long)address, (int)nbytes);
-
- /* Wait for any preceding write or erase operation to complete. */
-
- status = sst25_waitwritecomplete(priv);
- DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == 0);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Read from Memory " instruction */
-
-#ifdef CONFIG_SST25_SLOWREAD
- (void)SPI_SEND(priv->dev, SST25_READ);
-#else
- (void)SPI_SEND(priv->dev, SST25_FAST_READ);
-#endif
-
- /* Send the address high byte first. */
-
- (void)SPI_SEND(priv->dev, (address >> 16) & 0xff);
- (void)SPI_SEND(priv->dev, (address >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, address & 0xff);
-
- /* Send a dummy byte */
-
-#ifndef CONFIG_SST25_SLOWREAD
- (void)SPI_SEND(priv->dev, SST25_DUMMY);
-#endif
-
- /* Then read all of the requested bytes */
-
- SPI_RECVBLOCK(priv->dev, buffer, nbytes);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-}
-
-/************************************************************************************
- * Name: sst25_bytewrite
- ************************************************************************************/
-
-#if defined(CONFIG_SST25_SLOWWRITE) && !defined(CONFIG_SST25_READONLY)
-static void sst25_bytewrite(struct sst25_dev_s *priv, FAR const uint8_t *buffer,
- off_t address, size_t nbytes)
-{
- uint8_t status;
-
- fvdbg("address: %08lx nwords: %d\n", (long)address, (int)nbytes);
- DEBUGASSERT(priv && buffer);
-
- /* Write each byte individually */
-
- for (; nbytes > 0; nbytes--)
- {
- /* Skip over bytes that are begin written to the erased state */
-
- if (*buffer != SST25_ERASED_STATE)
- {
- /* Wait for any preceding write or erase operation to complete. */
-
- status = sst25_waitwritecomplete(priv);
- DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == 0);
-
- /* Enable write access to the FLASH */
-
- sst25_wren(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Byte Program (BP)" command */
-
- (void)SPI_SEND(priv->dev, SST25_BP);
-
- /* Send the byte address high byte first. */
-
- (void)SPI_SEND(priv->dev, (address >> 16) & 0xff);
- (void)SPI_SEND(priv->dev, (address >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, address & 0xff);
-
- /* Then write the single byte */
-
- (void)SPI_SEND(priv->dev, *buffer);
-
- /* Deselect the FLASH and setup for the next pass through the loop */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
- }
-
- /* Advance to the next byte */
-
- buffer++;
- address++;
- }
-}
-#endif
-
-/************************************************************************************
- * Name: sst25_wordwrite
- ************************************************************************************/
-
-#if !defined(CONFIG_SST25_SLOWWRITE) && !defined(CONFIG_SST25_READONLY)
-static void sst25_wordwrite(struct sst25_dev_s *priv, FAR const uint8_t *buffer,
- off_t address, size_t nbytes)
-{
- size_t nwords = (nbytes + 1) >> 1;
- uint8_t status;
-
- fvdbg("address: %08lx nwords: %d\n", (long)address, (int)nwords);
- DEBUGASSERT(priv && buffer);
-
- /* Loop until all of the bytes have been written */
-
- while (nwords > 0)
- {
- /* Skip over any data that is being written to the erased state */
-
- while (nwords > 0 &&
- buffer[0] == SST25_ERASED_STATE &&
- buffer[1] == SST25_ERASED_STATE)
- {
- /* Decrement the word count and advance the write position */
-
- nwords--;
- buffer += 2;
- address += 2;
- }
-
- /* If there are no further non-erased bytes in the user buffer, then
- * we are finished.
- */
-
- if (nwords <= 0)
- {
- return;
- }
-
- /* Wait for any preceding write or erase operation to complete. */
-
- status = sst25_waitwritecomplete(priv);
- DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == 0);
-
- /* Enable write access to the FLASH */
-
- sst25_wren(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Auto Address Increment (AAI)" command */
-
- (void)SPI_SEND(priv->dev, SST25_AAI);
-
- /* Send the word address high byte first. */
-
- (void)SPI_SEND(priv->dev, (address >> 16) & 0xff);
- (void)SPI_SEND(priv->dev, (address >> 8) & 0xff);
- (void)SPI_SEND(priv->dev, address & 0xff);
-
- /* Then write one 16-bit word */
-
- SPI_SNDBLOCK(priv->dev, buffer, 2);
-
- /* Deselect the FLASH: Chip Select high */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-
- /* Decrement the word count and advance the write position */
-
- nwords--;
- buffer += 2;
- address += 2;
-
- /* Now loop, writing 16-bits of data on each pass through the loop
- * until all of the words have been transferred or until we encounter
- * data to be written to the erased state.
- */
-
- while (nwords > 0 &&
- (buffer[0] != SST25_ERASED_STATE ||
- buffer[1] != SST25_ERASED_STATE))
- {
- /* Wait for the preceding write to complete. */
-
- status = sst25_waitwritecomplete(priv);
- DEBUGASSERT((status & (SST25_SR_WEL|SST25_SR_BP_MASK|SST25_SR_AAI)) == (SST25_SR_WEL|SST25_SR_AAI));
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
-
- /* Send "Auto Address Increment (AAI)" command with no address */
-
- (void)SPI_SEND(priv->dev, SST25_AAI);
-
- /* Then write one 16-bit word */
-
- SPI_SNDBLOCK(priv->dev, buffer, 2);
-
- /* Deselect the FLASH: Chip Select high */
-
- SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
-
- /* Decrement the word count and advance the write position */
-
- nwords--;
- buffer += 2;
- address += 2;
- }
-
- /* Disable writing */
-
- sst25_wrdi(priv);
- }
-}
-#endif
-
-/************************************************************************************
- * Name: sst25_cacheflush
- ************************************************************************************/
-
-#if defined(CONFIG_SST25_SECTOR512) && !defined(CONFIG_SST25_READONLY)
-static void sst25_cacheflush(struct sst25_dev_s *priv)
-{
- /* If the cached is dirty (meaning that it no longer matches the old FLASH contents)
- * or was erased (with the cache containing the correct FLASH contents), then write
- * the cached erase block to FLASH.
- */
-
- if (IS_DIRTY(priv) || IS_ERASED(priv))
- {
- /* Write entire erase block to FLASH */
-
-#ifdef CONFIG_SST25_SLOWWRITE
- sst25_bytewrite(priv, priv->sector, (off_t)priv->esectno << priv->sectorshift,
- (1 << priv->sectorshift));
-#else
- sst25_wordwrite(priv, priv->sector, (off_t)priv->esectno << priv->sectorshift,
- (1 << priv->sectorshift));
-#endif
-
- /* The case is no long dirty and the FLASH is no longer erased */
-
- CLR_DIRTY(priv);
- CLR_ERASED(priv);
- }
-}
-#endif
-
-/************************************************************************************
- * Name: sst25_cacheread
- ************************************************************************************/
-
-#if defined(CONFIG_SST25_SECTOR512) && !defined(CONFIG_SST25_READONLY)
-static FAR uint8_t *sst25_cacheread(struct sst25_dev_s *priv, off_t sector)
-{
- off_t esectno;
- int shift;
- int index;
-
- /* Convert from the 512 byte sector to the erase sector size of the device. For
- * exmample, if the actual erase sector size if 4Kb (1 << 12), then we first
- * shift to the right by 3 to get the sector number in 4096 increments.
- */
-
- shift = priv->sectorshift - SST25_SECTOR_SHIFT;
- esectno = sector >> shift;
- fvdbg("sector: %ld esectno: %d shift=%d\n", sector, esectno, shift);
-
- /* Check if the requested erase block is already in the cache */
-
- if (!IS_VALID(priv) || esectno != priv->esectno)
- {
- /* No.. Flush any dirty erase block currently in the cache */
-
- sst25_cacheflush(priv);
-
- /* Read the erase block into the cache */
-
- sst25_byteread(priv, priv->sector, (esectno << priv->sectorshift), 1 << priv->sectorshift);
-
- /* Mark the sector as cached */
-
- priv->esectno = esectno;
-
- SET_VALID(priv); /* The data in the cache is valid */
- CLR_DIRTY(priv); /* It should match the FLASH contents */
- CLR_ERASED(priv); /* The underlying FLASH has not been erased */
- }
-
- /* Get the index to the 512 sector in the erase block that holds the argument */
-
- index = sector & ((1 << shift) - 1);
-
- /* Return the address in the cache that holds this sector */
-
- return &priv->sector[index << SST25_SECTOR_SHIFT];
-}
-#endif
-
-/************************************************************************************
- * Name: sst25_cacheerase
- ************************************************************************************/
-
-#if defined(CONFIG_SST25_SECTOR512) && !defined(CONFIG_SST25_READONLY)
-static void sst25_cacheerase(struct sst25_dev_s *priv, off_t sector)
-{
- FAR uint8_t *dest;
-
- /* First, make sure that the erase block containing the 512 byte sector is in
- * the cache.
- */
-
- dest = sst25_cacheread(priv, sector);
-
- /* Erase the block containing this sector if it is not already erased.
- * The erased indicated will be cleared when the data from the erase sector
- * is read into the cache and set here when we erase the block.
- */
-
- if (!IS_ERASED(priv))
- {
- off_t esectno = sector >> (priv->sectorshift - SST25_SECTOR_SHIFT);
- fvdbg("sector: %ld esectno: %d\n", sector, esectno);
-
- sst25_sectorerase(priv, esectno);
- SET_ERASED(priv);
- }
-
- /* Put the cached sector data into the erase state and mart the cache as dirty
- * (but don't update the FLASH yet. The caller will do that at a more optimal
- * time).
- */
-
- memset(dest, SST25_ERASED_STATE, SST25_SECTOR_SIZE);
- SET_DIRTY(priv);
-}
-#endif
-
-/************************************************************************************
- * Name: sst25_cachewrite
- ************************************************************************************/
-
-#if defined(CONFIG_SST25_SECTOR512) && !defined(CONFIG_SST25_READONLY)
-static void sst25_cachewrite(FAR struct sst25_dev_s *priv, FAR const uint8_t *buffer,
- off_t sector, size_t nsectors)
-{
- FAR uint8_t *dest;
-
- for (; nsectors > 0; nsectors--)
- {
- /* First, make sure that the erase block containing 512 byte sector is in
- * memory.
- */
-
- dest = sst25_cacheread(priv, sector);
-
- /* Erase the block containing this sector if it is not already erased.
- * The erased indicated will be cleared when the data from the erase sector
- * is read into the cache and set here when we erase the sector.
- */
-
- if (!IS_ERASED(priv))
- {
- off_t esectno = sector >> (priv->sectorshift - SST25_SECTOR_SHIFT);
- fvdbg("sector: %ld esectno: %d\n", sector, esectno);
-
- sst25_sectorerase(priv, esectno);
- SET_ERASED(priv);
- }
-
- /* Copy the new sector data into cached erase block */
-
- memcpy(dest, buffer, SST25_SECTOR_SIZE);
- SET_DIRTY(priv);
-
- /* Set up for the next 512 byte sector */
-
- buffer += SST25_SECTOR_SIZE;
- sector++;
- }
-
- /* Flush the last erase block left in the cache */
-
- sst25_cacheflush(priv);
-}
-#endif
-
-/************************************************************************************
- * Name: sst25_erase
- ************************************************************************************/
-
-static int sst25_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks)
-{
-#ifdef CONFIG_SST25_READONLY
- return -EACESS
-#else
- FAR struct sst25_dev_s *priv = (FAR struct sst25_dev_s *)dev;
- size_t blocksleft = nblocks;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Lock access to the SPI bus until we complete the erase */
-
- sst25_lock(priv->dev);
-
- while (blocksleft-- > 0)
- {
- /* Erase each sector */
-
-#ifdef CONFIG_SST25_SECTOR512
- sst25_cacheerase(priv, startblock);
-#else
- sst25_sectorerase(priv, startblock);
-#endif
- startblock++;
- }
-
-#ifdef CONFIG_SST25_SECTOR512
- /* Flush the last erase block left in the cache */
-
- sst25_cacheflush(priv);
-#endif
-
- sst25_unlock(priv->dev);
- return (int)nblocks;
-#endif
-}
-
-/************************************************************************************
- * Name: sst25_bread
- ************************************************************************************/
-
-static ssize_t sst25_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR uint8_t *buffer)
-{
-#ifdef CONFIG_SST25_SECTOR512
- ssize_t nbytes;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* On this device, we can handle the block read just like the byte-oriented read */
-
- nbytes = sst25_read(dev, startblock << SST25_SECTOR_SHIFT, nblocks << SST25_SECTOR_SHIFT, buffer);
- if (nbytes > 0)
- {
- return nbytes >> SST25_SECTOR_SHIFT;
- }
-
- return (int)nbytes;
-#else
- FAR struct sst25_dev_s *priv = (FAR struct sst25_dev_s *)dev;
- ssize_t nbytes;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* On this device, we can handle the block read just like the byte-oriented read */
-
- nbytes = sst25_read(dev, startblock << priv->sectorshift, nblocks << priv->sectorshift, buffer);
- if (nbytes > 0)
- {
- return nbytes >> priv->sectorshift;
- }
-
- return (int)nbytes;
-#endif
-}
-
-/************************************************************************************
- * Name: sst25_bwrite
- ************************************************************************************/
-
-static ssize_t sst25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR const uint8_t *buffer)
-{
-#ifdef CONFIG_SST25_READONLY
- return -EACCESS;
-#else
- FAR struct sst25_dev_s *priv = (FAR struct sst25_dev_s *)dev;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Lock the SPI bus and write all of the pages to FLASH */
-
- sst25_lock(priv->dev);
-
-#if defined(CONFIG_SST25_SECTOR512)
- sst25_cachewrite(priv, buffer, startblock, nblocks);
-#elif defined(CONFIG_SST25_SLOWWRITE)
- sst25_bytewrite(priv, buffer, startblock << priv->sectorshift,
- nblocks << priv->sectorshift);
-#else
- sst25_wordwrite(priv, buffer, startblock << priv->sectorshift,
- nblocks << priv->sectorshift);
-#endif
- sst25_unlock(priv->dev);
-
- return nblocks;
-#endif
-}
-
-/************************************************************************************
- * Name: sst25_read
- ************************************************************************************/
-
-static ssize_t sst25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer)
-{
- FAR struct sst25_dev_s *priv = (FAR struct sst25_dev_s *)dev;
-
- fvdbg("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
-
- /* Lock the SPI bus and select this FLASH part */
-
- sst25_lock(priv->dev);
- sst25_byteread(priv, buffer, offset, nbytes);
- sst25_unlock(priv->dev);
-
- fvdbg("return nbytes: %d\n", (int)nbytes);
- return nbytes;
-}
-
-/************************************************************************************
- * Name: sst25_ioctl
- ************************************************************************************/
-
-static int sst25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
-{
- FAR struct sst25_dev_s *priv = (FAR struct sst25_dev_s *)dev;
- int ret = -EINVAL; /* Assume good command with bad parameters */
-
- fvdbg("cmd: %d \n", cmd);
-
- switch (cmd)
- {
- case MTDIOC_GEOMETRY:
- {
- FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg);
- if (geo)
- {
- /* Populate the geometry structure with information need to know
- * the capacity and how to access the device.
- *
- * NOTE: that the device is treated as though it where just an array
- * of fixed size blocks. That is most likely not true, but the client
- * will expect the device logic to do whatever is necessary to make it
- * appear so.
- */
-
-#ifdef CONFIG_SST25_SECTOR512
- geo->blocksize = (1 << SST25_SECTOR_SHIFT);
- geo->erasesize = (1 << SST25_SECTOR_SHIFT);
- geo->neraseblocks = priv->nsectors << (priv->sectorshift - );
-#else
- geo->blocksize = (1 << priv->sectorshift);
- geo->erasesize = (1 << priv->sectorshift);
- geo->neraseblocks = priv->nsectors;
-#endif
- ret = OK;
-
- fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n",
- geo->blocksize, geo->erasesize, geo->neraseblocks);
- }
- }
- break;
-
- case MTDIOC_BULKERASE:
- {
- /* Erase the entire device */
-
- sst25_lock(priv->dev);
- ret = sst25_chiperase(priv);
- sst25_unlock(priv->dev);
- }
- break;
-
- case MTDIOC_XIPBASE:
- default:
- ret = -ENOTTY; /* Bad command */
- break;
- }
-
- fvdbg("return %d\n", ret);
- return ret;
-}
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: sst25_initialize
- *
- * Description:
- * Create an initialize MTD device instance. MTD devices are not registered
- * in the file system, but are created as instances that can be bound to
- * other functions (such as a block or character driver front end).
- *
- ************************************************************************************/
-
-FAR struct mtd_dev_s *sst25_initialize(FAR struct spi_dev_s *dev)
-{
- FAR struct sst25_dev_s *priv;
- int ret;
-
- fvdbg("dev: %p\n", dev);
-
- /* Allocate a state structure (we allocate the structure instead of using
- * a fixed, static allocation so that we can handle multiple FLASH devices.
- * The current implementation would handle only one FLASH part per SPI
- * device (only because of the SPIDEV_FLASH definition) and so would have
- * to be extended to handle multiple FLASH parts on the same SPI bus.
- */
-
- priv = (FAR struct sst25_dev_s *)kzalloc(sizeof(struct sst25_dev_s));
- if (priv)
- {
- /* Initialize the allocated structure */
-
- priv->mtd.erase = sst25_erase;
- priv->mtd.bread = sst25_bread;
- priv->mtd.bwrite = sst25_bwrite;
- priv->mtd.read = sst25_read;
- priv->mtd.ioctl = sst25_ioctl;
- priv->dev = dev;
-
- /* Deselect the FLASH */
-
- SPI_SELECT(dev, SPIDEV_FLASH, false);
-
- /* Identify the FLASH chip and get its capacity */
-
- ret = sst25_readid(priv);
- if (ret != OK)
- {
- /* Unrecognized! Discard all of that work we just did and return NULL */
-
- fdbg("Unrecognized\n");
- kfree(priv);
- priv = NULL;
- }
- else
- {
- /* Make sure the the FLASH is unprotected so that we can write into it */
-
-#ifndef CONFIG_SST25_READONLY
- sst25_unprotect(priv->dev);
-#endif
-
-#ifdef CONFIG_SST25_SECTOR512 /* Simulate a 512 byte sector */
- /* Allocate a buffer for the erase block cache */
-
- priv->sector = (FAR uint8_t *)kmalloc(1 << priv->sectorshift);
- if (!priv->sector)
- {
- /* Allocation failed! Discard all of that work we just did and return NULL */
-
- fdbg("Allocation failed\n");
- kfree(priv);
- priv = NULL;
- }
-#endif
- }
- }
-
- /* Return the implementation-specific state structure as the MTD device */
-
- fvdbg("Return %p\n", priv);
- return (FAR struct mtd_dev_s *)priv;
-}
diff --git a/nuttx/drivers/mtd/w25.c b/nuttx/drivers/mtd/w25.c
deleted file mode 100644
index bd6680fdf..000000000
--- a/nuttx/drivers/mtd/w25.c
+++ /dev/null
@@ -1,1179 +0,0 @@
-/************************************************************************************
- * drivers/mtd/w25.c
- * Driver for SPI-based W25x16, x32, and x64 and W25q16, q32, q64, and q128 FLASH
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/spi.h>
-#include <nuttx/mtd.h>
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-/* Configuration ********************************************************************/
-/* Per the data sheet, the W25 parts can be driven with either SPI mode 0 (CPOL=0
- * and CPHA=0) or mode 3 (CPOL=1 and CPHA=1). But I have heard that other devices
- * can operate in mode 0 or 1. So you may need to specify CONFIG_W25_SPIMODE to
- * select the best mode for your device. If CONFIG_W25_SPIMODE is not defined,
- * mode 0 will be used.
- */
-
-#ifndef CONFIG_W25_SPIMODE
-# define CONFIG_W25_SPIMODE SPIDEV_MODE0
-#endif
-
-/* SPI Frequency. May be up to 25MHz. */
-
-#ifndef CONFIG_W25_SPIFREQUENCY
-# define CONFIG_W25_SPIFREQUENCY 20000000
-#endif
-
-/* W25 Instructions *****************************************************************/
-/* Command Value Description */
-/* */
-#define W25_WREN 0x06 /* Write enable */
-#define W25_WRDI 0x04 /* Write Disable */
-#define W25_RDSR 0x05 /* Read status register */
-#define W25_WRSR 0x01 /* Write Status Register */
-#define W25_RDDATA 0x03 /* Read data bytes */
-#define W25_FRD 0x0b /* Higher speed read */
-#define W25_FRDD 0x3b /* Fast read, dual output */
-#define W25_PP 0x02 /* Program page */
-#define W25_BE 0xd8 /* Block Erase (64KB) */
-#define W25_SE 0x20 /* Sector erase (4KB) */
-#define W25_CE 0xc7 /* Chip erase */
-#define W25_PD 0xb9 /* Power down */
-#define W25_PURDID 0xab /* Release PD, Device ID */
-#define W25_RDMFID 0x90 /* Read Manufacturer / Device */
-#define W25_JEDEC_ID 0x9f /* JEDEC ID read */
-
-/* W25 Registers ********************************************************************/
-/* Read ID (RDID) register values */
-
-#define W25_MANUFACTURER 0xef /* Winbond Serial Flash */
-#define W25X16_DEVID 0x14 /* W25X16 device ID (0xab, 0x90) */
-#define W25X32_DEVID 0x15 /* W25X16 device ID (0xab, 0x90) */
-#define W25X64_DEVID 0x16 /* W25X16 device ID (0xab, 0x90) */
-
-/* JEDEC Read ID register values */
-
-#define W25_JEDEC_MANUFACTURER 0xef /* SST manufacturer ID */
-#define W25X_JEDEC_MEMORY_TYPE 0x30 /* W25X memory type */
-#define W25Q_JEDEC_MEMORY_TYPE_A 0x40 /* W25Q memory type */
-#define W25Q_JEDEC_MEMORY_TYPE_B 0x60 /* W25Q memory type */
-
-#define W25_JEDEC_CAPACITY_16MBIT 0x15 /* 512x4096 = 16Mbit memory capacity */
-#define W25_JEDEC_CAPACITY_32MBIT 0x16 /* 1024x4096 = 32Mbit memory capacity */
-#define W25_JEDEC_CAPACITY_64MBIT 0x17 /* 2048x4096 = 64Mbit memory capacity */
-#define W25_JEDEC_CAPACITY_128MBIT 0x18 /* 4096x4096 = 128Mbit memory capacity */
-
-#define NSECTORS_16MBIT 512 /* 512 sectors x 4096 bytes/sector = 2Mb */
-#define NSECTORS_32MBIT 1024 /* 1024 sectors x 4096 bytes/sector = 4Mb */
-#define NSECTORS_64MBIT 2048 /* 2048 sectors x 4096 bytes/sector = 8Mb */
-#define NSECTORS_128MBIT 4096 /* 4096 sectors x 4096 bytes/sector = 16Mb */
-
-/* Status register bit definitions */
-
-#define W25_SR_BUSY (1 << 0) /* Bit 0: Write in progress */
-#define W25_SR_WEL (1 << 1) /* Bit 1: Write enable latch bit */
-#define W25_SR_BP_SHIFT (2) /* Bits 2-5: Block protect bits */
-#define W25_SR_BP_MASK (15 << W25_SR_BP_SHIFT)
-# define W25X16_SR_BP_NONE (0 << W25_SR_BP_SHIFT) /* Unprotected */
-# define W25X16_SR_BP_UPPER32nd (1 << W25_SR_BP_SHIFT) /* Upper 32nd */
-# define W25X16_SR_BP_UPPER16th (2 << W25_SR_BP_SHIFT) /* Upper 16th */
-# define W25X16_SR_BP_UPPER8th (3 << W25_SR_BP_SHIFT) /* Upper 8th */
-# define W25X16_SR_BP_UPPERQTR (4 << W25_SR_BP_SHIFT) /* Upper quarter */
-# define W25X16_SR_BP_UPPERHALF (5 << W25_SR_BP_SHIFT) /* Upper half */
-# define W25X16_SR_BP_ALL (6 << W25_SR_BP_SHIFT) /* All sectors */
-# define W25X16_SR_BP_LOWER32nd (9 << W25_SR_BP_SHIFT) /* Lower 32nd */
-# define W25X16_SR_BP_LOWER16th (10 << W25_SR_BP_SHIFT) /* Lower 16th */
-# define W25X16_SR_BP_LOWER8th (11 << W25_SR_BP_SHIFT) /* Lower 8th */
-# define W25X16_SR_BP_LOWERQTR (12 << W25_SR_BP_SHIFT) /* Lower quarter */
-# define W25X16_SR_BP_LOWERHALF (13 << W25_SR_BP_SHIFT) /* Lower half */
-
-# define W25X32_SR_BP_NONE (0 << W25_SR_BP_SHIFT) /* Unprotected */
-# define W25X32_SR_BP_UPPER64th (1 << W25_SR_BP_SHIFT) /* Upper 64th */
-# define W25X32_SR_BP_UPPER32nd (2 << W25_SR_BP_SHIFT) /* Upper 32nd */
-# define W25X32_SR_BP_UPPER16th (3 << W25_SR_BP_SHIFT) /* Upper 16th */
-# define W25X32_SR_BP_UPPER8th (4 << W25_SR_BP_SHIFT) /* Upper 8th */
-# define W25X32_SR_BP_UPPERQTR (5 << W25_SR_BP_SHIFT) /* Upper quarter */
-# define W25X32_SR_BP_UPPERHALF (6 << W25_SR_BP_SHIFT) /* Upper half */
-# define W25X32_SR_BP_ALL (7 << W25_SR_BP_SHIFT) /* All sectors */
-# define W25X32_SR_BP_LOWER64th (9 << W25_SR_BP_SHIFT) /* Lower 64th */
-# define W25X32_SR_BP_LOWER32nd (10 << W25_SR_BP_SHIFT) /* Lower 32nd */
-# define W25X32_SR_BP_LOWER16th (11 << W25_SR_BP_SHIFT) /* Lower 16th */
-# define W25X32_SR_BP_LOWER8th (12 << W25_SR_BP_SHIFT) /* Lower 8th */
-# define W25X32_SR_BP_LOWERQTR (13 << W25_SR_BP_SHIFT) /* Lower quarter */
-# define W25X32_SR_BP_LOWERHALF (14 << W25_SR_BP_SHIFT) /* Lower half */
-
-# define W25X64_SR_BP_NONE (0 << W25_SR_BP_SHIFT) /* Unprotected */
-# define W25X64_SR_BP_UPPER64th (1 << W25_SR_BP_SHIFT) /* Upper 64th */
-# define W25X64_SR_BP_UPPER32nd (2 << W25_SR_BP_SHIFT) /* Upper 32nd */
-# define W25X64_SR_BP_UPPER16th (3 << W25_SR_BP_SHIFT) /* Upper 16th */
-# define W25X64_SR_BP_UPPER8th (4 << W25_SR_BP_SHIFT) /* Upper 8th */
-# define W25X64_SR_BP_UPPERQTR (5 << W25_SR_BP_SHIFT) /* Upper quarter */
-# define W25X64_SR_BP_UPPERHALF (6 << W25_SR_BP_SHIFT) /* Upper half */
-# define W25X46_SR_BP_ALL (7 << W25_SR_BP_SHIFT) /* All sectors */
-# define W25X64_SR_BP_LOWER64th (9 << W25_SR_BP_SHIFT) /* Lower 64th */
-# define W25X64_SR_BP_LOWER32nd (10 << W25_SR_BP_SHIFT) /* Lower 32nd */
-# define W25X64_SR_BP_LOWER16th (11 << W25_SR_BP_SHIFT) /* Lower 16th */
-# define W25X64_SR_BP_LOWER8th (12 << W25_SR_BP_SHIFT) /* Lower 8th */
-# define W25X64_SR_BP_LOWERQTR (13 << W25_SR_BP_SHIFT) /* Lower quarter */
-# define W25X64_SR_BP_LOWERHALF (14 << W25_SR_BP_SHIFT) /* Lower half */
- /* Bit 6: Reserved */
-#define W25_SR_SRP (1 << 7) /* Bit 7: Status register write protect */
-
-#define W25_DUMMY 0xa5
-
-/* Chip Geometries ******************************************************************/
-/* All members of the family support uniform 4K-byte sectors and 256 byte pages */
-
-#define W25_SECTOR_SHIFT 12 /* Sector size 1 << 12 = 4Kb */
-#define W25_SECTOR_SIZE (1 << 12) /* Sector size 1 << 12 = 4Kb */
-#define W25_PAGE_SHIFT 8 /* Sector size 1 << 8 = 256b */
-#define W25_PAGE_SIZE (1 << 8) /* Sector size 1 << 8 = 256b */
-
-#ifdef CONFIG_W25_SECTOR512 /* Simulate a 512 byte sector */
-# define W25_SECTOR512_SHIFT 9 /* Sector size 1 << 9 = 512 bytes */
-# define W25_SECTOR512_SIZE (1 << 9) /* Sector size 1 << 9 = 512 bytes */
-#endif
-
-#define W25_ERASED_STATE 0xff /* State of FLASH when erased */
-
-/* Cache flags */
-
-#define W25_CACHE_VALID (1 << 0) /* 1=Cache has valid data */
-#define W25_CACHE_DIRTY (1 << 1) /* 1=Cache is dirty */
-#define W25_CACHE_ERASED (1 << 2) /* 1=Backing FLASH is erased */
-
-#define IS_VALID(p) ((((p)->flags) & W25_CACHE_VALID) != 0)
-#define IS_DIRTY(p) ((((p)->flags) & W25_CACHE_DIRTY) != 0)
-#define IS_ERASED(p) ((((p)->flags) & W25_CACHE_DIRTY) != 0)
-
-#define SET_VALID(p) do { (p)->flags |= W25_CACHE_VALID; } while (0)
-#define SET_DIRTY(p) do { (p)->flags |= W25_CACHE_DIRTY; } while (0)
-#define SET_ERASED(p) do { (p)->flags |= W25_CACHE_DIRTY; } while (0)
-
-#define CLR_VALID(p) do { (p)->flags &= ~W25_CACHE_VALID; } while (0)
-#define CLR_DIRTY(p) do { (p)->flags &= ~W25_CACHE_DIRTY; } while (0)
-#define CLR_ERASED(p) do { (p)->flags &= ~W25_CACHE_DIRTY; } while (0)
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-/* This type represents the state of the MTD device. The struct mtd_dev_s must
- * appear at the beginning of the definition so that you can freely cast between
- * pointers to struct mtd_dev_s and struct w25_dev_s.
- */
-
-struct w25_dev_s
-{
- struct mtd_dev_s mtd; /* MTD interface */
- FAR struct spi_dev_s *spi; /* Saved SPI interface instance */
- uint16_t nsectors; /* Number of erase sectors */
-
-#if defined(CONFIG_W25_SECTOR512) && !defined(CONFIG_W25_READONLY)
- uint8_t flags; /* Buffered sector flags */
- uint16_t esectno; /* Erase sector number in the cache*/
- FAR uint8_t *sector; /* Allocated sector data */
-#endif
-};
-
-/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-
-/* Helpers */
-
-static void w25_lock(FAR struct spi_dev_s *spi);
-static inline void w25_unlock(FAR struct spi_dev_s *spi);
-static inline int w25_readid(FAR struct w25_dev_s *priv);
-#ifndef CONFIG_W25_READONLY
-static void w25_unprotect(FAR struct w25_dev_s *priv);
-#endif
-static uint8_t w25_waitwritecomplete(FAR struct w25_dev_s *priv);
-static inline void w25_wren(FAR struct w25_dev_s *priv);
-static inline void w25_wrdi(FAR struct w25_dev_s *priv);
-static void w25_sectorerase(FAR struct w25_dev_s *priv, off_t offset);
-static inline int w25_chiperase(FAR struct w25_dev_s *priv);
-static void w25_byteread(FAR struct w25_dev_s *priv, FAR uint8_t *buffer,
- off_t address, size_t nbytes);
-#ifndef CONFIG_W25_READONLY
-static void w25_pagewrite(FAR struct w25_dev_s *priv, FAR const uint8_t *buffer,
- off_t address, size_t nbytes);
-#endif
-#ifdef CONFIG_W25_SECTOR512
-static void w25_cacheflush(struct w25_dev_s *priv);
-static FAR uint8_t *w25_cacheread(struct w25_dev_s *priv, off_t sector);
-static void w25_cacheerase(struct w25_dev_s *priv, off_t sector);
-static void w25_cachewrite(FAR struct w25_dev_s *priv, FAR const uint8_t *buffer,
- off_t sector, size_t nsectors);
-#endif
-
-/* MTD driver methods */
-
-static int w25_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks);
-static ssize_t w25_bread(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR uint8_t *buf);
-static ssize_t w25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock,
- size_t nblocks, FAR const uint8_t *buf);
-static ssize_t w25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer);
-static int w25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg);
-
-/************************************************************************************
- * Private Data
- ************************************************************************************/
-
-/************************************************************************************
- * Private Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: w25_lock
- ************************************************************************************/
-
-static void w25_lock(FAR struct spi_dev_s *spi)
-{
- /* On SPI busses where there are multiple devices, it will be necessary to
- * lock SPI to have exclusive access to the busses for a sequence of
- * transfers. The bus should be locked before the chip is selected.
- *
- * This is a blocking call and will not return until we have exclusiv access to
- * the SPI buss. We will retain that exclusive access until the bus is unlocked.
- */
-
- (void)SPI_LOCK(spi, true);
-
- /* After locking the SPI bus, the we also need call the setfrequency, setbits, and
- * setmode methods to make sure that the SPI is properly configured for the device.
- * If the SPI buss is being shared, then it may have been left in an incompatible
- * state.
- */
-
- SPI_SETMODE(spi, CONFIG_W25_SPIMODE);
- SPI_SETBITS(spi, 8);
- (void)SPI_SETFREQUENCY(spi, CONFIG_W25_SPIFREQUENCY);
-}
-
-/************************************************************************************
- * Name: w25_unlock
- ************************************************************************************/
-
-static inline void w25_unlock(FAR struct spi_dev_s *spi)
-{
- (void)SPI_LOCK(spi, false);
-}
-
-/************************************************************************************
- * Name: w25_readid
- ************************************************************************************/
-
-static inline int w25_readid(struct w25_dev_s *priv)
-{
- uint16_t manufacturer;
- uint16_t memory;
- uint16_t capacity;
-
- fvdbg("priv: %p\n", priv);
-
- /* Lock the SPI bus, configure the bus, and select this FLASH part. */
-
- w25_lock(priv->spi);
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send the "Read ID (RDID)" command and read the first three ID bytes */
-
- (void)SPI_SEND(priv->spi, W25_JEDEC_ID);
- manufacturer = SPI_SEND(priv->spi, W25_DUMMY);
- memory = SPI_SEND(priv->spi, W25_DUMMY);
- capacity = SPI_SEND(priv->spi, W25_DUMMY);
-
- /* Deselect the FLASH and unlock the bus */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
- w25_unlock(priv->spi);
-
- fvdbg("manufacturer: %02x memory: %02x capacity: %02x\n",
- manufacturer, memory, capacity);
-
- /* Check for a valid manufacturer and memory type */
-
- if (manufacturer == W25_JEDEC_MANUFACTURER &&
- (memory == W25X_JEDEC_MEMORY_TYPE ||
- memory == W25Q_JEDEC_MEMORY_TYPE_A ||
- memory == W25Q_JEDEC_MEMORY_TYPE_B))
- {
- /* Okay.. is it a FLASH capacity that we understand? If so, save
- * the FLASH capacity.
- */
-
- /* 16M-bit / 2M-byte (2,097,152)
- *
- * W24X16, W25Q16BV, W25Q16CL, W25Q16CV, W25Q16DW
- */
-
- if (capacity == W25_JEDEC_CAPACITY_16MBIT)
- {
- priv->nsectors = NSECTORS_16MBIT;
- }
-
- /* 32M-bit / M-byte (4,194,304)
- *
- * W25X32, W25Q32BV, W25Q32DW
- */
-
- else if (capacity == W25_JEDEC_CAPACITY_32MBIT)
- {
- priv->nsectors = NSECTORS_32MBIT;
- }
-
- /* 64M-bit / 8M-byte (8,388,608)
- *
- * W25X64, W25Q64BV, W25Q64CV, W25Q64DW
- */
-
- else if (capacity == W25_JEDEC_CAPACITY_64MBIT)
- {
- priv->nsectors = NSECTORS_64MBIT;
- }
-
- /* 128M-bit / 16M-byte (16,777,216)
- *
- * W25Q128BV
- */
-
- else if (capacity == W25_JEDEC_CAPACITY_128MBIT)
- {
- priv->nsectors = NSECTORS_128MBIT;
- }
- else
- {
- /* Nope.. we don't understand this capacity. */
-
- return -ENODEV;
- }
-
- return OK;
- }
-
- /* We don't understand the manufacturer or the memory type */
-
- return -ENODEV;
-}
-
-/************************************************************************************
- * Name: w25_unprotect
- ************************************************************************************/
-
-#ifndef CONFIG_W25_READONLY
-static void w25_unprotect(FAR struct w25_dev_s *priv)
-{
- /* Select this FLASH part */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send "Write enable (WREN)" */
-
- w25_wren(priv);
-
- /* Re-select this FLASH part (This might not be necessary... but is it shown in
- * the SST25 timing diagrams from which this code was leveraged.)
- */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send "Write enable status (EWSR)" */
-
- SPI_SEND(priv->spi, W25_WRSR);
-
- /* Following by the new status value */
-
- SPI_SEND(priv->spi, 0);
- SPI_SEND(priv->spi, 0);
-}
-#endif
-
-/************************************************************************************
- * Name: w25_waitwritecomplete
- ************************************************************************************/
-
-static uint8_t w25_waitwritecomplete(struct w25_dev_s *priv)
-{
- uint8_t status;
-
- /* Are we the only device on the bus? */
-
-#ifdef CONFIG_SPI_OWNBUS
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send "Read Status Register (RDSR)" command */
-
- (void)SPI_SEND(priv->spi, W25_RDSR);
-
- /* Loop as long as the memory is busy with a write cycle */
-
- do
- {
- /* Send a dummy byte to generate the clock needed to shift out the status */
-
- status = SPI_SEND(priv->spi, W25_DUMMY);
- }
- while ((status & W25_SR_BUSY) != 0);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-
-#else
-
- /* Loop as long as the memory is busy with a write cycle */
-
- do
- {
- /* Select this FLASH part */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send "Read Status Register (RDSR)" command */
-
- (void)SPI_SEND(priv->spi, W25_RDSR);
-
- /* Send a dummy byte to generate the clock needed to shift out the status */
-
- status = SPI_SEND(priv->spi, W25_DUMMY);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-
- /* Given that writing could take up to few tens of milliseconds, and erasing
- * could take more. The following short delay in the "busy" case will allow
- * other peripherals to access the SPI bus.
- */
-
-#if 0 /* Makes writes too slow */
- if ((status & W25_SR_BUSY) != 0)
- {
- w25_unlock(priv->spi);
- usleep(1000);
- w25_lock(priv->spi);
- }
-#endif
- }
- while ((status & W25_SR_BUSY) != 0);
-#endif
-
- return status;
-}
-
-/************************************************************************************
- * Name: w25_wren
- ************************************************************************************/
-
-static inline void w25_wren(struct w25_dev_s *priv)
-{
- /* Select this FLASH part */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send "Write Enable (WREN)" command */
-
- (void)SPI_SEND(priv->spi, W25_WREN);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-}
-
-/************************************************************************************
- * Name: w25_wrdi
- ************************************************************************************/
-
-static inline void w25_wrdi(struct w25_dev_s *priv)
-{
- /* Select this FLASH part */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send "Write Disable (WRDI)" command */
-
- (void)SPI_SEND(priv->spi, W25_WRDI);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-}
-
-/************************************************************************************
- * Name: w25_sectorerase
- ************************************************************************************/
-
-static void w25_sectorerase(struct w25_dev_s *priv, off_t sector)
-{
- off_t address = sector << W25_SECTOR_SHIFT;
-
- fvdbg("sector: %08lx\n", (long)sector);
-
- /* Wait for any preceding write or erase operation to complete. */
-
- (void)w25_waitwritecomplete(priv);
-
- /* Send write enable instruction */
-
- w25_wren(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send the "Sector Erase (SE)" instruction */
-
- (void)SPI_SEND(priv->spi, W25_SE);
-
- /* Send the sector address high byte first. Only the most significant bits (those
- * corresponding to the sector) have any meaning.
- */
-
- (void)SPI_SEND(priv->spi, (address >> 16) & 0xff);
- (void)SPI_SEND(priv->spi, (address >> 8) & 0xff);
- (void)SPI_SEND(priv->spi, address & 0xff);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-}
-
-/************************************************************************************
- * Name: w25_chiperase
- ************************************************************************************/
-
-static inline int w25_chiperase(struct w25_dev_s *priv)
-{
- fvdbg("priv: %p\n", priv);
-
- /* Wait for any preceding write or erase operation to complete. */
-
- (void)w25_waitwritecomplete(priv);
-
- /* Send write enable instruction */
-
- w25_wren(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send the "Chip Erase (CE)" instruction */
-
- (void)SPI_SEND(priv->spi, W25_CE);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
- fvdbg("Return: OK\n");
- return OK;
-}
-
-/************************************************************************************
- * Name: w25_byteread
- ************************************************************************************/
-
-static void w25_byteread(FAR struct w25_dev_s *priv, FAR uint8_t *buffer,
- off_t address, size_t nbytes)
-{
- uint8_t status;
-
- fvdbg("address: %08lx nbytes: %d\n", (long)address, (int)nbytes);
-
- /* Wait for any preceding write or erase operation to complete. */
-
- status = w25_waitwritecomplete(priv);
- DEBUGASSERT((status & (W25_SR_WEL|W25_SR_BP_MASK)) == 0);
-
- /* Make sure that writing is disabled */
-
- w25_wrdi(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send "Read from Memory " instruction */
-
-#ifdef CONFIG_W25_SLOWREAD
- (void)SPI_SEND(priv->spi, W25_RDDATA);
-#else
- (void)SPI_SEND(priv->spi, W25_FRD);
-#endif
-
- /* Send the address high byte first. */
-
- (void)SPI_SEND(priv->spi, (address >> 16) & 0xff);
- (void)SPI_SEND(priv->spi, (address >> 8) & 0xff);
- (void)SPI_SEND(priv->spi, address & 0xff);
-
- /* Send a dummy byte */
-
-#ifndef CONFIG_W25_SLOWREAD
- (void)SPI_SEND(priv->spi, W25_DUMMY);
-#endif
-
- /* Then read all of the requested bytes */
-
- SPI_RECVBLOCK(priv->spi, buffer, nbytes);
-
- /* Deselect the FLASH */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-}
-
-/************************************************************************************
- * Name: w25_pagewrite
- ************************************************************************************/
-
-#ifndef CONFIG_W25_READONLY
-static void w25_pagewrite(struct w25_dev_s *priv, FAR const uint8_t *buffer,
- off_t address, size_t nbytes)
-{
- uint8_t status;
-
- fvdbg("address: %08lx nwords: %d\n", (long)address, (int)nbytes);
- DEBUGASSERT(priv && buffer && (address & 0xff) == 0 &&
- (nbytes & 0xff) == 0);
-
- for (; nbytes > 0; nbytes -= W25_PAGE_SIZE)
- {
- /* Wait for any preceding write or erase operation to complete. */
-
- status = w25_waitwritecomplete(priv);
- DEBUGASSERT((status & (W25_SR_WEL|W25_SR_BP_MASK)) == 0);
-
- /* Enable write access to the FLASH */
-
- w25_wren(priv);
-
- /* Select this FLASH part */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, true);
-
- /* Send the "Page Program (W25_PP)" Command */
-
- SPI_SEND(priv->spi, W25_PP);
-
- /* Send the address high byte first. */
-
- (void)SPI_SEND(priv->spi, (address >> 16) & 0xff);
- (void)SPI_SEND(priv->spi, (address >> 8) & 0xff);
- (void)SPI_SEND(priv->spi, address & 0xff);
-
- /* Then send the page of data */
-
- SPI_SNDBLOCK(priv->spi, buffer, W25_PAGE_SIZE);
-
- /* Deselect the FLASH and setup for the next pass through the loop */
-
- SPI_SELECT(priv->spi, SPIDEV_FLASH, false);
-
- /* Update addresses */
-
- address += W25_PAGE_SIZE;
- buffer += W25_PAGE_SIZE;
- }
-
- /* Disable writing */
-
- w25_wrdi(priv);
-}
-#endif
-
-/************************************************************************************
- * Name: w25_cacheflush
- ************************************************************************************/
-
-#if defined(CONFIG_W25_SECTOR512) && !defined(CONFIG_W25_READONLY)
-static void w25_cacheflush(struct w25_dev_s *priv)
-{
- /* If the cached is dirty (meaning that it no longer matches the old FLASH contents)
- * or was erased (with the cache containing the correct FLASH contents), then write
- * the cached erase block to FLASH.
- */
-
- if (IS_DIRTY(priv) || IS_ERASED(priv))
- {
- /* Write entire erase block to FLASH */
-
- w25_pagewrite(priv, priv->sector, (off_t)priv->esectno << W25_SECTOR_SHIFT,
- W25_SECTOR_SIZE);
-
- /* The case is no long dirty and the FLASH is no longer erased */
-
- CLR_DIRTY(priv);
- CLR_ERASED(priv);
- }
-}
-#endif
-
-/************************************************************************************
- * Name: w25_cacheread
- ************************************************************************************/
-
-#if defined(CONFIG_W25_SECTOR512) && !defined(CONFIG_W25_READONLY)
-static FAR uint8_t *w25_cacheread(struct w25_dev_s *priv, off_t sector)
-{
- off_t esectno;
- int shift;
- int index;
-
- /* Convert from the 512 byte sector to the erase sector size of the device. For
- * exmample, if the actual erase sector size if 4Kb (1 << 12), then we first
- * shift to the right by 3 to get the sector number in 4096 increments.
- */
-
- shift = W25_SECTOR_SHIFT - W25_SECTOR512_SHIFT;
- esectno = sector >> shift;
- fvdbg("sector: %ld esectno: %d shift=%d\n", sector, esectno, shift);
-
- /* Check if the requested erase block is already in the cache */
-
- if (!IS_VALID(priv) || esectno != priv->esectno)
- {
- /* No.. Flush any dirty erase block currently in the cache */
-
- w25_cacheflush(priv);
-
- /* Read the erase block into the cache */
-
- w25_byteread(priv, priv->sector, (esectno << W25_SECTOR_SHIFT), W25_SECTOR_SIZE);
-
- /* Mark the sector as cached */
-
- priv->esectno = esectno;
-
- SET_VALID(priv); /* The data in the cache is valid */
- CLR_DIRTY(priv); /* It should match the FLASH contents */
- CLR_ERASED(priv); /* The underlying FLASH has not been erased */
- }
-
- /* Get the index to the 512 sector in the erase block that holds the argument */
-
- index = sector & ((1 << shift) - 1);
-
- /* Return the address in the cache that holds this sector */
-
- return &priv->sector[index << W25_SECTOR512_SHIFT];
-}
-#endif
-
-/************************************************************************************
- * Name: w25_cacheerase
- ************************************************************************************/
-
-#if defined(CONFIG_W25_SECTOR512) && !defined(CONFIG_W25_READONLY)
-static void w25_cacheerase(struct w25_dev_s *priv, off_t sector)
-{
- FAR uint8_t *dest;
-
- /* First, make sure that the erase block containing the 512 byte sector is in
- * the cache.
- */
-
- dest = w25_cacheread(priv, sector);
-
- /* Erase the block containing this sector if it is not already erased.
- * The erased indicated will be cleared when the data from the erase sector
- * is read into the cache and set here when we erase the block.
- */
-
- if (!IS_ERASED(priv))
- {
- off_t esectno = sector >> (W25_SECTOR_SHIFT - W25_SECTOR512_SHIFT);
- fvdbg("sector: %ld esectno: %d\n", sector, esectno);
-
- w25_sectorerase(priv, esectno);
- SET_ERASED(priv);
- }
-
- /* Put the cached sector data into the erase state and mart the cache as dirty
- * (but don't update the FLASH yet. The caller will do that at a more optimal
- * time).
- */
-
- memset(dest, W25_ERASED_STATE, W25_SECTOR512_SIZE);
- SET_DIRTY(priv);
-}
-#endif
-
-/************************************************************************************
- * Name: w25_cachewrite
- ************************************************************************************/
-
-#if defined(CONFIG_W25_SECTOR512) && !defined(CONFIG_W25_READONLY)
-static void w25_cachewrite(FAR struct w25_dev_s *priv, FAR const uint8_t *buffer,
- off_t sector, size_t nsectors)
-{
- FAR uint8_t *dest;
-
- for (; nsectors > 0; nsectors--)
- {
- /* First, make sure that the erase block containing 512 byte sector is in
- * memory.
- */
-
- dest = w25_cacheread(priv, sector);
-
- /* Erase the block containing this sector if it is not already erased.
- * The erased indicated will be cleared when the data from the erase sector
- * is read into the cache and set here when we erase the sector.
- */
-
- if (!IS_ERASED(priv))
- {
- off_t esectno = sector >> (W25_SECTOR_SHIFT - W25_SECTOR512_SHIFT);
- fvdbg("sector: %ld esectno: %d\n", sector, esectno);
-
- w25_sectorerase(priv, esectno);
- SET_ERASED(priv);
- }
-
- /* Copy the new sector data into cached erase block */
-
- memcpy(dest, buffer, W25_SECTOR512_SIZE);
- SET_DIRTY(priv);
-
- /* Set up for the next 512 byte sector */
-
- buffer += W25_SECTOR512_SIZE;
- sector++;
- }
-
- /* Flush the last erase block left in the cache */
-
- w25_cacheflush(priv);
-}
-#endif
-
-/************************************************************************************
- * Name: w25_erase
- ************************************************************************************/
-
-static int w25_erase(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks)
-{
-#ifdef CONFIG_W25_READONLY
- return -EACESS
-#else
- FAR struct w25_dev_s *priv = (FAR struct w25_dev_s *)dev;
- size_t blocksleft = nblocks;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Lock access to the SPI bus until we complete the erase */
-
- w25_lock(priv->spi);
-
- while (blocksleft-- > 0)
- {
- /* Erase each sector */
-
-#ifdef CONFIG_W25_SECTOR512
- w25_cacheerase(priv, startblock);
-#else
- w25_sectorerase(priv, startblock);
-#endif
- startblock++;
- }
-
-#ifdef CONFIG_W25_SECTOR512
- /* Flush the last erase block left in the cache */
-
- w25_cacheflush(priv);
-#endif
-
- w25_unlock(priv->spi);
- return (int)nblocks;
-#endif
-}
-
-/************************************************************************************
- * Name: w25_bread
- ************************************************************************************/
-
-static ssize_t w25_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR uint8_t *buffer)
-{
- ssize_t nbytes;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* On this device, we can handle the block read just like the byte-oriented read */
-
-#ifdef CONFIG_W25_SECTOR512
- nbytes = w25_read(dev, startblock << W25_SECTOR512_SHIFT, nblocks << W25_SECTOR512_SHIFT, buffer);
- if (nbytes > 0)
- {
- nbytes >>= W25_SECTOR512_SHIFT;
- }
-#else
- nbytes = w25_read(dev, startblock << W25_SECTOR_SHIFT, nblocks << W25_SECTOR_SHIFT, buffer);
- if (nbytes > 0)
- {
- nbytes >>= W25_SECTOR_SHIFT;
- }
-#endif
-
- return nbytes;
-}
-
-/************************************************************************************
- * Name: w25_bwrite
- ************************************************************************************/
-
-static ssize_t w25_bwrite(FAR struct mtd_dev_s *dev, off_t startblock, size_t nblocks,
- FAR const uint8_t *buffer)
-{
-#ifdef CONFIG_W25_READONLY
- return -EACCESS;
-#else
- FAR struct w25_dev_s *priv = (FAR struct w25_dev_s *)dev;
-
- fvdbg("startblock: %08lx nblocks: %d\n", (long)startblock, (int)nblocks);
-
- /* Lock the SPI bus and write all of the pages to FLASH */
-
- w25_lock(priv->spi);
-
-#if defined(CONFIG_W25_SECTOR512)
- w25_cachewrite(priv, buffer, startblock, nblocks);
-#else
- w25_pagewrite(priv, buffer, startblock << W25_SECTOR_SHIFT,
- nblocks << W25_SECTOR_SHIFT);
-#endif
- w25_unlock(priv->spi);
-
- return nblocks;
-#endif
-}
-
-/************************************************************************************
- * Name: w25_read
- ************************************************************************************/
-
-static ssize_t w25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
- FAR uint8_t *buffer)
-{
- FAR struct w25_dev_s *priv = (FAR struct w25_dev_s *)dev;
-
- fvdbg("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
-
- /* Lock the SPI bus and select this FLASH part */
-
- w25_lock(priv->spi);
- w25_byteread(priv, buffer, offset, nbytes);
- w25_unlock(priv->spi);
-
- fvdbg("return nbytes: %d\n", (int)nbytes);
- return nbytes;
-}
-
-/************************************************************************************
- * Name: w25_ioctl
- ************************************************************************************/
-
-static int w25_ioctl(FAR struct mtd_dev_s *dev, int cmd, unsigned long arg)
-{
- FAR struct w25_dev_s *priv = (FAR struct w25_dev_s *)dev;
- int ret = -EINVAL; /* Assume good command with bad parameters */
-
- fvdbg("cmd: %d \n", cmd);
-
- switch (cmd)
- {
- case MTDIOC_GEOMETRY:
- {
- FAR struct mtd_geometry_s *geo = (FAR struct mtd_geometry_s *)((uintptr_t)arg);
- if (geo)
- {
- /* Populate the geometry structure with information need to know
- * the capacity and how to access the device.
- *
- * NOTE: that the device is treated as though it where just an array
- * of fixed size blocks. That is most likely not true, but the client
- * will expect the device logic to do whatever is necessary to make it
- * appear so.
- */
-
-#ifdef CONFIG_W25_SECTOR512
- geo->blocksize = (1 << W25_SECTOR512_SHIFT);
- geo->erasesize = (1 << W25_SECTOR512_SHIFT);
- geo->neraseblocks = priv->nsectors << (W25_SECTOR_SHIFT - W25_SECTOR512_SHIFT);
-#else
- geo->blocksize = W25_SECTOR_SIZE;
- geo->erasesize = W25_SECTOR_SIZE;
- geo->neraseblocks = priv->nsectors;
-#endif
- ret = OK;
-
- fvdbg("blocksize: %d erasesize: %d neraseblocks: %d\n",
- geo->blocksize, geo->erasesize, geo->neraseblocks);
- }
- }
- break;
-
- case MTDIOC_BULKERASE:
- {
- /* Erase the entire device */
-
- w25_lock(priv->spi);
- ret = w25_chiperase(priv);
- w25_unlock(priv->spi);
- }
- break;
-
- case MTDIOC_XIPBASE:
- default:
- ret = -ENOTTY; /* Bad command */
- break;
- }
-
- fvdbg("return %d\n", ret);
- return ret;
-}
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: w25_initialize
- *
- * Description:
- * Create an initialize MTD device instance. MTD devices are not registered
- * in the file system, but are created as instances that can be bound to
- * other functions (such as a block or character driver front end).
- *
- ************************************************************************************/
-
-FAR struct mtd_dev_s *w25_initialize(FAR struct spi_dev_s *spi)
-{
- FAR struct w25_dev_s *priv;
- int ret;
-
- fvdbg("spi: %p\n", spi);
-
- /* Allocate a state structure (we allocate the structure instead of using
- * a fixed, static allocation so that we can handle multiple FLASH devices.
- * The current implementation would handle only one FLASH part per SPI
- * device (only because of the SPIDEV_FLASH definition) and so would have
- * to be extended to handle multiple FLASH parts on the same SPI bus.
- */
-
- priv = (FAR struct w25_dev_s *)kzalloc(sizeof(struct w25_dev_s));
- if (priv)
- {
- /* Initialize the allocated structure */
-
- priv->mtd.erase = w25_erase;
- priv->mtd.bread = w25_bread;
- priv->mtd.bwrite = w25_bwrite;
- priv->mtd.read = w25_read;
- priv->mtd.ioctl = w25_ioctl;
- priv->spi = spi;
-
- /* Deselect the FLASH */
-
- SPI_SELECT(spi, SPIDEV_FLASH, false);
-
- /* Identify the FLASH chip and get its capacity */
-
- ret = w25_readid(priv);
- if (ret != OK)
- {
- /* Unrecognized! Discard all of that work we just did and return NULL */
-
- fdbg("Unrecognized\n");
- kfree(priv);
- priv = NULL;
- }
- else
- {
- /* Make sure the the FLASH is unprotected so that we can write into it */
-
-#ifndef CONFIG_W25_READONLY
- w25_unprotect(priv);
-#endif
-
-#ifdef CONFIG_W25_SECTOR512 /* Simulate a 512 byte sector */
- /* Allocate a buffer for the erase block cache */
-
- priv->sector = (FAR uint8_t *)kmalloc(W25_SECTOR_SIZE);
- if (!priv->sector)
- {
- /* Allocation failed! Discard all of that work we just did and return NULL */
-
- fdbg("Allocation failed\n");
- kfree(priv);
- priv = NULL;
- }
-#endif
- }
- }
-
- /* Return the implementation-specific state structure as the MTD device */
-
- fvdbg("Return %p\n", priv);
- return (FAR struct mtd_dev_s *)priv;
-}
diff --git a/nuttx/drivers/net/Kconfig b/nuttx/drivers/net/Kconfig
deleted file mode 100644
index d8878ecaf..000000000
--- a/nuttx/drivers/net/Kconfig
+++ /dev/null
@@ -1,95 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-config NET_DM90x0
- bool "Davicom dm9000/dm9010 support"
- default n
- ---help---
- References: Davicom data sheets (DM9000-DS-F03-041906.pdf,
- DM9010-DS-F01-103006.pdf) and looking at lots of other DM90x0
- drivers.
-
-config NET_CS89x0
- bool "CS89x0 support"
- default n
- depends on EXPERIMENTAL
- ---help---
- Under construction -- do not use
-
-config ENC28J60
- bool "Microchip ENC28J60 support"
- default n
- select SPI
- ---help---
- References:
- ENC28J60 Data Sheet, Stand-Alone Ethernet Controller with SPI Interface,
- DS39662C, 2008 Microchip Technology Inc.
-
-if ENC28J60
-config ENC28J60_NINTERFACES
- int "Number of physical ENC28J60"
- default 1
- range 1,1
- ---help---
- Specifies the number of physical ENC28J60
- devices that will be supported.
-
-config ENC28J60_SPIMODE
- int "SPI mode"
- default 0
- ---help---
- Controls the SPI mode. The ENC28J60 spec says that it supports SPI
- mode 0,0 only: "The implementation used on this device supports SPI
- mode 0,0 only. In addition, the SPI port requires that SCK be at Idle
- in a low state; selectable clock polarity is not supported."
- However, sometimes you need to tinker with these things.
-
-config ENC28J60_FREQUENCY
- int "SPI frequency"
- default 20000000
- ---help---
- Define to use a different bus frequency
-
-config ENC28J60_STATS
- bool "Network statistics support"
- default n
- ---help---
- Collect network statistics
-
-config ENC28J60_HALFDUPPLEX
- bool "Enable half dupplex"
- default n
- ---help---
- Default is full duplex
-
-config ENC28J60_DUMPPACKET
- bool "Dump Packets"
- default n
- ---help---
- If selected, the ENC28J60 driver will dump the contents of each
- packet to the console.
-
-config ENC28J60_REGDEBUG
- bool "Register-Level Debug"
- default n
- depends on DEBUG && DEBUG_NET
- ---help---
- Enable very low-level register access debug. Depends on DEBUG and DEBUG_NET.
-
-endif
-
-config NET_E1000
- bool "E1000 support"
- default n
-
-config NET_SLIP
- bool "SLIP (serial line) support"
- default n
- ---help---
- Reference: RFC 1055
-
-config NET_VNET
- bool "VNET support"
- default n
-
diff --git a/nuttx/drivers/net/Make.defs b/nuttx/drivers/net/Make.defs
deleted file mode 100644
index bb0d6a718..000000000
--- a/nuttx/drivers/net/Make.defs
+++ /dev/null
@@ -1,71 +0,0 @@
-############################################################################
-# drivers/net/Make.defs
-#
-# Copyright (C) 2007, 2010-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-# Include nothing if networking is disabled
-
-ifeq ($(CONFIG_NET),y)
-
-# Include network interface drivers
-
-ifeq ($(CONFIG_NET_DM90x0),y)
- CSRCS += dm90x0.c
-endif
-
-ifeq ($(CONFIG_NET_CS89x0),y)
- CSRCS += cs89x0.c
-endif
-
-ifeq ($(CONFIG_ENC28J60),y)
- CSRCS += enc28j60.c
-endif
-
-ifeq ($(CONFIG_NET_VNET),y)
- CSRCS += vnet.c
-endif
-
-ifeq ($(CONFIG_NET_E1000),y)
- CSRCS += e1000.c
-endif
-
-ifeq ($(CONFIG_NET_SLIP),y)
- CSRCS += slip.c
-endif
-
-# Include network build support
-
-DEPPATH += --dep-path net
-VPATH += :net
-endif
-
diff --git a/nuttx/drivers/net/cs89x0.c b/nuttx/drivers/net/cs89x0.c
deleted file mode 100644
index 22b9b87a5..000000000
--- a/nuttx/drivers/net/cs89x0.c
+++ /dev/null
@@ -1,959 +0,0 @@
-/****************************************************************************
- * drivers/net/cs89x0.c
- *
- * Copyright (C) 2009-2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-#if defined(CONFIG_NET) && defined(CONFIG_NET_CS89x0)
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <time.h>
-#include <string.h>
-#include <debug.h>
-#include <wdog.h>
-#include <errno.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include <nuttx/net/uip/uip.h>
-#include <nuttx/net/uip/uip-arp.h>
-#include <nuttx/net/uip/uip-arch.h>
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-#error "Under construction -- do not use"
-
-/* CONFIG_CS89x0_NINTERFACES determines the number of physical interfaces
- * that will be supported.
- */
-
-#ifndef CONFIG_CS89x0_NINTERFACES
-# define CONFIG_CS89x0_NINTERFACES 1
-#endif
-
-/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */
-
-#define CS89x0_WDDELAY (1*CLK_TCK)
-#define CS89x0_POLLHSEC (1*2)
-
-/* TX timeout = 1 minute */
-
-#define CS89x0_TXTIMEOUT (60*CLK_TCK)
-
-/* This is a helper pointer for accessing the contents of the Ethernet header */
-
-#define BUF ((struct uip_eth_hdr *)cs89x0->cs_dev.d_buf)
-
-/* If there is only one CS89x0 instance, then mapping the CS89x0 IRQ to
- * a driver state instance is trivial.
- */
-
-#if CONFIG_CS89x0_NINTERFACES == 1
-# define cs89x0_mapirq(irq) g_cs89x0[0]
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static FAR struct cs89x0_driver_s *g_cs89x0[CONFIG_CS89x0_NINTERFACES];
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* CS89x0 register access */
-
-static uint16_t cs89x0_getreg(struct cs89x0_driver_s *cs89x0, int offset);
-static void cs89x0_putreg(struct cs89x0_driver_s *cs89x0, int offset,
- uint16_t value);
-static uint16_t cs89x0_getppreg(struct cs89x0_driver_s *cs89x0, int addr);
-static void cs89x0_putppreg(struct cs89x0_driver_s *cs89x0, int addr,
- uint16_t value);
-
-/* Common TX logic */
-
-static int cs89x0_transmit(struct cs89x0_driver_s *cs89x0);
-static int cs89x0_uiptxpoll(struct uip_driver_s *dev);
-
-/* Interrupt handling */
-
-static void cs89x0_receive(struct cs89x0_driver_s *cs89x0);
-static void cs89x0_txdone(struct cs89x0_driver_s *cs89x0, uint16_t isq);
-#if CONFIG_CS89x0_NINTERFACES > 1
-static inline FAR struct cs89x0_driver_s *cs89x0_mapirq(int irq);
-#endif
-static int cs89x0_interrupt(int irq, FAR void *context);
-
-/* Watchdog timer expirations */
-
-static void cs89x0_polltimer(int argc, uint32_t arg, ...);
-static void cs89x0_txtimeout(int argc, uint32_t arg, ...);
-
-/* NuttX callback functions */
-
-static int cs89x0_ifup(struct uip_driver_s *dev);
-static int cs89x0_ifdown(struct uip_driver_s *dev);
-static int cs89x0_txavail(struct uip_driver_s *dev);
-#ifdef CONFIG_NET_IGMP
-static int cs89x0_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-static int cs89x0_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: cs89x0_getreg and cs89x0_putreg
- *
- * Description:
- * Read from and write to a CS89x0 register
- *
- * Parameters:
- * cs89x0 - Reference to the driver state structure
- * offset - Offset to the CS89x0 register
- * value - Value to be written (cs89x0_putreg only)
- *
- * Returned Value:
- * cs89x0_getreg: The 16-bit value of the register
- * cs89x0_putreg: None
- *
- ****************************************************************************/
-
-static uint16_t cs89x0_getreg(struct cs89x0_driver_s *cs89x0, int offset)
-{
-#ifdef CONFIG_CS89x0_ALIGN16
- return getreg16(s89x0->cs_base + offset);
-#else
- return (uint16_t)getreg32(s89x0->cs_base + offset);
-#endif
-}
-
-static void cs89x0_putreg(struct cs89x0_driver_s *cs89x0, int offset, uint16_t value)
-{
-#ifdef CONFIG_CS89x0_ALIGN16
- return putreg16(value, s89x0->cs_base + offset);
-#else
- return (uint16_t)putreg32((uint32_t)value, s89x0->cs_base + offset);
-#endif
-}
-
-/****************************************************************************
- * Function: cs89x0_getppreg and cs89x0_putppreg
- *
- * Description:
- * Read from and write to a CS89x0 page packet register
- *
- * Parameters:
- * cs89x0 - Reference to the driver state structure
- * addr - Address of the CS89x0 page packet register
- * value - Value to be written (cs89x0_putppreg only)
- *
- * Returned Value:
- * cs89x0_getppreg: The 16-bit value of the page packet register
- * cs89x0_putppreg: None
- *
- ****************************************************************************/
-
-static uint16_t cs89x0_getppreg(struct cs89x0_driver_s *cs89x0, int addr)
-{
- /* In memory mode, the CS89x0's internal registers and frame buffers are mapped
- * into a contiguous 4kb block providing direct access to the internal registers
- * and frame buffers.
- */
-
-#ifdef CONFIG_CS89x0_MEMMODE
- if (cs89x0->cs_memmode)
- {
-#ifdef CONFIG_CS89x0_ALIGN16
- return getreg16(s89x0->cs_ppbase + (CS89x0_PDATA_OFFSET << ??));
-#else
- return (uint16_t)getreg32(s89x0->cs_ppbase + (CS89x0_PDATA_OFFSET << ??));
-#endif
- }
-
- /* When configured in I/O mode, the CS89x0 is accessed through eight, 16-bit
- * I/O ports that in the host system's I/O space.
- */
-
- else
-#endif
- {
-#ifdef CONFIG_CS89x0_ALIGN16
- putreg16((uint16_t)addr, cs89x0->cs_base + CS89x0_PPTR_OFFSET);
- return getreg16(s89x0->cs_base + CS89x0_PDATA_OFFSET);
-#else
- putreg32((uint32_t)addr, cs89x0->cs_base + CS89x0_PPTR_OFFSET);
- return (uint16_t)getreg32(s89x0->cs_base + CS89x0_PDATA_OFFSET);
-#endif
- }
-}
-
-static void cs89x0_putppreg(struct cs89x0_driver_s *cs89x0, int addr, uint16_t value)
-{
- /* In memory mode, the CS89x0's internal registers and frame buffers are mapped
- * into a contiguous 4kb block providing direct access to the internal registers
- * and frame buffers.
- */
-
-#ifdef CONFIG_CS89x0_MEMMODE
- if (cs89x0->cs_memmode)
- {
-#ifdef CONFIG_CS89x0_ALIGN16
- putreg16(value), cs89x0->cs_ppbase + (CS89x0_PDATA_OFFSET << ??));
-#else
- putreg32((uint32_t)value, cs89x0->cs_ppbase + (CS89x0_PDATA_OFFSET << ??));
-#endif
- }
-
- /* When configured in I/O mode, the CS89x0 is accessed through eight, 16-bit
- * I/O ports that in the host system's I/O space.
- */
-
- else
-#endif
- {
-#ifdef CONFIG_CS89x0_ALIGN16
- putreg16((uint16_t)addr, cs89x0->cs_base + CS89x0_PPTR_OFFSET);
- putreg16(value, cs89x0->cs_base + CS89x0_PDATA_OFFSET);
-#else
- putreg32((uint32_t)addr, cs89x0->cs_base + CS89x0_PPTR_OFFSET);
- putreg32((uint32_t)value, cs89x0->cs_base + CS89x0_PDATA_OFFSET);
-#endif
- }
-}
-
-/****************************************************************************
- * Function: cs89x0_transmit
- *
- * Description:
- * Start hardware transmission. Called either from the txdone interrupt
- * handling or from watchdog based polling.
- *
- * Parameters:
- * cs89x0 - Reference to the driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int cs89x0_transmit(struct cs89x0_driver_s *cs89x0)
-{
- /* Verify that the hardware is ready to send another packet */
-#warning "Missing logic"
-
- /* Increment statistics */
-#warning "Missing logic"
-
- /* Disable Ethernet interrupts */
-#warning "Missing logic"
-
- /* Send the packet: address=cs89x0->cs_dev.d_buf, length=cs89x0->cs_dev.d_len */
-#warning "Missing logic"
-
- /* Restore Ethernet interrupts */
-#warning "Missing logic"
-
- /* Setup the TX timeout watchdog (perhaps restarting the timer) */
-
- (void)wd_start(cs89x0->cs_txtimeout, CS89x0_TXTIMEOUT, cs89x0_txtimeout, 1, (uint32_t)cs89x0);
- return OK;
-}
-
-/****************************************************************************
- * Function: cs89x0_uiptxpoll
- *
- * Description:
- * The transmitter is available, check if uIP has any outgoing packets ready
- * to send. This is a callback from uip_poll(). uip_poll() may be called:
- *
- * 1. When the preceding TX packet send is complete,
- * 2. When the preceding TX packet send timesout and the interface is reset
- * 3. During normal TX polling
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int cs89x0_uiptxpoll(struct uip_driver_s *dev)
-{
- struct cs89x0_driver_s *cs89x0 = (struct cs89x0_driver_s *)dev->d_private;
-
- /* If the polling resulted in data that should be sent out on the network,
- * the field d_len is set to a value > 0.
- */
-
- if (cs89x0->cs_dev.d_len > 0)
- {
- uip_arp_out(&cs89x0->cs_dev);
- cs89x0_transmit(cs89x0);
-
- /* Check if there is room in the CS89x0 to hold another packet. If not,
- * return a non-zero value to terminate the poll.
- */
-#warning "Missing logic"
- }
-
- /* If zero is returned, the polling will continue until all connections have
- * been examined.
- */
-
- return 0;
-}
-
-/****************************************************************************
- * Function: cs89x0_receive
- *
- * Description:
- * An interrupt was received indicating the availability of a new RX packet
- *
- * Parameters:
- * cs89x0 - Reference to the driver state structure
- * isq - Interrupt status queue value read by interrupt handler
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void cs89x0_receive(struct cs89x0_driver_s *cs89x0, uint16_t isq)
-{
- uint16_t *dest;
- uint16_t rxlength;
- int nbytes;
-
- /* Check for errors and update statistics */
-
- rxlength = cs89x0_getreg(PPR_RXLENGTH);
- if ((isq & RX_OK) == 0)
- {
-#ifdef CONFIG_C89x0_STATISTICS
- cd89x0->cs_stats.rx_errors++;
- if ((isq & RX_RUNT) != 0)
- {
- cd89x0->cs_stats.rx_lengtherrors++;
- }
- if ((isq & RX_EXTRA_DATA) != 0)
- {
- cd89x0->cs_stats.rx_lengtherrors++;
- }
- if (isq & RX_CRC_ERROR) != 0)
- {
- if (!(isq & (RX_EXTRA_DATA|RX_RUNT)))
- {
- cd89x0->cs_stats.rx_crcerrors++;
- }
- }
- if ((isq & RX_DRIBBLE) != 0)
- {
- cd89x0->cs_stats.rx_frameerrors++;
- }
-#endif
- return;
- }
-
- /* Check if the packet is a valid size for the uIP buffer configuration */
-
- if (rxlength > ???)
- {
-#ifdef CONFIG_C89x0_STATISTICS
- cd89x0->cs_stats.rx_errors++;
- cd89x0->cs_stats.rx_lengtherrors++;
-#endif
- return;
- }
-
- /* Copy the data data from the hardware to cs89x0->cs_dev.d_buf. Set
- * amount of data in cs89x0->cs_dev.d_len
- */
-
- dest = (uint16_t*)cs89x0->cs_dev.d_buf;
- for (nbytes = 0; nbytes < rxlength; nbytes += sizeof(uint16_t))
- {
- *dest++ = cs89x0_getreg(PPR_RXFRAMELOCATION);
- }
-
-#ifdef CONFIG_C89x0_STATISTICS
- cd89x0->cs_stats.rx_packets++;
-#endif
- /* We only accept IP packets of the configured type and ARP packets */
-
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
-#else
- if (BUF->type == HTONS(UIP_ETHTYPE_IP))
-#endif
- {
- uip_arp_ipin(&cs89x0->cs_dev);
- uip_input(&cs89x0->cs_dev);
-
- /* If the above function invocation resulted in data that should be
- * sent out on the network, the field d_len will set to a value > 0.
- */
-
- if (cs89x0->cs_dev.d_len > 0)
- {
- uip_arp_out(&cs89x0->cs_dev);
- cs89x0_transmit(cs89x0);
- }
- }
- else if (BUF->type == htons(UIP_ETHTYPE_ARP))
- {
- uip_arp_arpin(&cs89x0->cs_dev);
-
- /* If the above function invocation resulted in data that should be
- * sent out on the network, the field d_len will set to a value > 0.
- */
-
- if (cs89x0->cs_dev.d_len > 0)
- {
- cs89x0_transmit(cs89x0);
- }
- }
-}
-
-/****************************************************************************
- * Function: cs89x0_txdone
- *
- * Description:
- * An interrupt was received indicating that the last TX packet(s) is done
- *
- * Parameters:
- * cs89x0 - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void cs89x0_txdone(struct cs89x0_driver_s *cs89x0, uint16_t isq)
-{
- /* Check for errors and update statistics. The lower 6-bits of the ISQ
- * hold the register address causing the interrupt. We got here because
- * those bits indicated */
-
-#ifdef CONFIG_C89x0_STATISTICS
- cd89x0->cs_stats.tx_packets++;
- if ((isq & ISQ_TXEVENT_TXOK) == 0)
- {
- cd89x0->cs_stats.tx_errors++;
- }
- if ((isq & ISQ_TXEVENT_LOSSOFCRS) != 0)
- {
- cd89x0->cs_stats.tx_carriererrors++;
- }
- if ((isq & ISQ_TXEVENT_SQEERROR) != 0)
- {
- cd89x0->cs_stats.tx_heartbeaterrors++;
- }
- if (i(sq & ISQ_TXEVENT_OUTWINDOW) != 0)
- {
- cd89x0->cs_stats.tx_windowerrors++;
- }
- if (isq & TX_16_COL)
- {
- cd89x0->cs_stats.tx_abortederrors++;
- }
-#endif
-
- /* If no further xmits are pending, then cancel the TX timeout */
-
- wd_cancel(cs89x0->cs_txtimeout);
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&cs89x0->cs_dev, cs89x0_uiptxpoll);
-}
-
-/****************************************************************************
- * Function: cs89x0_mapirq
- *
- * Description:
- * Map an IRQ number to a CS89x0 device state instance. This is only
- * necessary to handler the case where the architecture includes more than
- * on CS89x0 chip.
- *
- * Parameters:
- * irq - Number of the IRQ that generated the interrupt
- *
- * Returned Value:
- * A reference to device state structure (NULL if irq does not correspond
- * to any CS89x0 device).
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#if CONFIG_CS89x0_NINTERFACES > 1
-static inline FAR struct cs89x0_driver_s *cs89x0_mapirq(int irq)
-{
- int i;
- for (i = 0; i < CONFIG_CS89x0_NINTERFACES; i++)
- {
- if (g_cs89x0[i] && g_cs89x0[i].irq == irq)
- {
- return g_cs89x0[i];
- }
- }
- return NULL;
-}
-#endif
-
-/****************************************************************************
- * Function: cs89x0_interrupt
- *
- * Description:
- * Hardware interrupt handler
- *
- * Parameters:
- * irq - Number of the IRQ that generated the interrupt
- * context - Interrupt register state save info (architecture-specific)
- *
- * Returned Value:
- * OK on success
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int cs89x0_interrupt(int irq, FAR void *context)
-{
- register struct cs89x0_driver_s *cs89x0 = s89x0_mapirq(irq);
- uint16_t isq;
-
-#ifdef CONFIG_DEBUG
- if (!cs89x0)
- {
- return -ENODEV;
- }
-#endif
-
- /* Read and process all of the events from the ISQ */
-
- while ((isq = cs89x0_getreg(dev, CS89x0_ISQ_OFFSET)) != 0)
- {
- nvdbg("ISQ: %04x\n", isq);
- switch (isq & ISQ_EVENTMASK)
- {
- case ISQ_RXEVENT:
- cs89x0_receive(cs89x0);
- break;
-
- case ISQ_TXEVENT:
- cs89x0_txdone(cs89x0, isq);
- break;
-
- case ISQ_BUFEVENT:
- if ((isq & ISQ_BUFEVENT_TXUNDERRUN) != 0)
- {
- ndbg("Transmit underrun\n");
-#ifdef CONFIG_CS89x0_XMITEARLY
- cd89x0->cs_txunderrun++;
- if (cd89x0->cs_txunderrun == 3)
- {
- cd89x0->cs_txstart = PPR_TXCMD_TXSTART381;
- }
- else if (cd89x0->cs_txunderrun == 6)
- {
- cd89x0->cs_txstart = PPR_TXCMD_TXSTARTFULL;
- }
-#endif
- }
- break;
-
- case ISQ_RXMISSEVENT:
-#ifdef CONFIG_C89x0_STATISTICS
- cd89x0->cs_stats.rx_missederrors += (isq >>6);
-#endif
- break;
-
- case ISQ_TXCOLEVENT:
-#ifdef CONFIG_C89x0_STATISTICS
- cd89x0->cs_stats.collisions += (isq >>6);
-#endif
- break;
- }
- }
- return OK;
-}
-
-/****************************************************************************
- * Function: cs89x0_txtimeout
- *
- * Description:
- * Our TX watchdog timed out. Called from the timer interrupt handler.
- * The last TX never completed. Reset the hardware and start again.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void cs89x0_txtimeout(int argc, uint32_t arg, ...)
-{
- struct cs89x0_driver_s *cs89x0 = (struct cs89x0_driver_s *)arg;
-
- /* Increment statistics and dump debug info */
-#warning "Missing logic"
-
- /* Then reset the hardware */
-#warning "Missing logic"
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&cs89x0->cs_dev, cs89x0_uiptxpoll);
-}
-
-/****************************************************************************
- * Function: cs89x0_polltimer
- *
- * Description:
- * Periodic timer handler. Called from the timer interrupt handler.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void cs89x0_polltimer(int argc, uint32_t arg, ...)
-{
- struct cs89x0_driver_s *cs89x0 = (struct cs89x0_driver_s *)arg;
-
- /* Check if there is room in the send another TXr packet. */
-#warning "Missing logic"
-
- /* If so, update TCP timing states and poll uIP for new XMIT data */
-
- (void)uip_timer(&cs89x0->cs_dev, cs89x0_uiptxpoll, CS89x0_POLLHSEC);
-
- /* Setup the watchdog poll timer again */
-
- (void)wd_start(cs89x0->cs_txpoll, CS89x0_WDDELAY, cs89x0_polltimer, 1, arg);
-}
-
-/****************************************************************************
- * Function: cs89x0_ifup
- *
- * Description:
- * NuttX Callback: Bring up the Ethernet interface when an IP address is
- * provided
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int cs89x0_ifup(struct uip_driver_s *dev)
-{
- struct cs89x0_driver_s *cs89x0 = (struct cs89x0_driver_s *)dev->d_private;
-
- ndbg("Bringing up: %d.%d.%d.%d\n",
- dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
- (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
-
- /* Initialize the Ethernet interface */
-#warning "Missing logic"
-
- /* Set and activate a timer process */
-
- (void)wd_start(cs89x0->cs_txpoll, CS89x0_WDDELAY, cs89x0_polltimer, 1, (uint32_t)cs89x0);
-
- /* Enable the Ethernet interrupt */
-
- cs89x0->cs_bifup = true;
- up_enable_irq(CONFIG_CS89x0_IRQ);
- return OK;
-}
-
-/****************************************************************************
- * Function: cs89x0_ifdown
- *
- * Description:
- * NuttX Callback: Stop the interface.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int cs89x0_ifdown(struct uip_driver_s *dev)
-{
- struct cs89x0_driver_s *cs89x0 = (struct cs89x0_driver_s *)dev->d_private;
- irqstate_t flags;
-
- /* Disable the Ethernet interrupt */
-
- flags = irqsave();
- up_disable_irq(CONFIG_CS89x0_IRQ);
-
- /* Cancel the TX poll timer and TX timeout timers */
-
- wd_cancel(cs89x0->cs_txpoll);
- wd_cancel(cs89x0->cs_txtimeout);
-
- /* Reset the device */
-
- cs89x0->cs_bifup = false;
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Function: cs89x0_txavail
- *
- * Description:
- * Driver callback invoked when new TX data is available. This is a
- * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
- * latency.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Called in normal user mode
- *
- ****************************************************************************/
-
-static int cs89x0_txavail(struct uip_driver_s *dev)
-{
- struct cs89x0_driver_s *cs89x0 = (struct cs89x0_driver_s *)dev->d_private;
- irqstate_t flags;
-
- flags = irqsave();
-
- /* Ignore the notification if the interface is not yet up */
-
- if (cs89x0->cs_bifup)
- {
- /* Check if there is room in the hardware to hold another outgoing packet. */
-#warning "Missing logic"
-
- /* If so, then poll uIP for new XMIT data */
-
- (void)uip_poll(&cs89x0->cs_dev, cs89x0_uiptxpoll);
- }
-
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Function: cs89x0_addmac
- *
- * Description:
- * NuttX Callback: Add the specified MAC address to the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be added
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int cs89x0_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct cs89x0_driver_s *priv = (FAR struct cs89x0_driver_s *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
-#warning "Multicast MAC support not implemented"
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Function: cs89x0_rmmac
- *
- * Description:
- * NuttX Callback: Remove the specified MAC address from the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be removed
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int cs89x0_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct cs89x0_driver_s *priv = (FAR struct cs89x0_driver_s *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
-#warning "Multicast MAC support not implemented"
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: cs89x0_initialize
- *
- * Description:
- * Initialize the Ethernet driver
- *
- * Parameters:
- * impl - decribes the implementation of the cs89x00 implementation.
- * This reference is retained so so must remain stable throughout the
- * life of the driver instance.
- * devno - Identifies the device number. This must be a number between
- * zero CONFIG_CS89x0_NINTERFACES and the same devno must not be
- * initialized twice. The associated network device will be referred
- * to with the name "eth" followed by this number (eth0, eth1, etc).
- *
- * Returned Value:
- * OK on success; Negated errno on failure.
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-/* Initialize the CS89x0 chip and driver */
-
-int cs89x0_initialize(FAR const cs89x0_driver_s *cs89x0, int devno)
-{
- /* Sanity checks -- only performed with debug enabled */
-
-#ifdef CONFIG_DEBUG
- if (!cs89x0 || (unsigned)devno > CONFIG_CS89x0_NINTERFACES || g_cs89x00[devno])
- {
- return -EINVAL;
- }
-#endif
-
- /* Check if a Ethernet chip is recognized at its I/O base */
-
-#warning "Missing logic"
-
- /* Attach the IRQ to the driver */
-
- if (irq_attach(cs89x0->irq, cs89x0_interrupt))
- {
- /* We could not attach the ISR to the ISR */
-
- return -EAGAIN;
- }
-
- /* Initialize the driver structure */
-
- g_cs89x[devno] = cs89x0; /* Used to map IRQ back to instance */
- cs89x0->cs_dev.d_ifup = cs89x0_ifup; /* I/F down callback */
- cs89x0->cs_dev.d_ifdown = cs89x0_ifdown; /* I/F up (new IP address) callback */
- cs89x0->cs_dev.d_txavail = cs89x0_txavail; /* New TX data callback */
-#ifdef CONFIG_NET_IGMP
- cs89x0->cs_dev.d_addmac = cs89x0_addmac; /* Add multicast MAC address */
- cs89x0->cs_dev.d_rmmac = cs89x0_rmmac; /* Remove multicast MAC address */
-#endif
- cs89x0->cs_dev.d_private = (void*)cs89x0; /* Used to recover private state from dev */
-
- /* Create a watchdog for timing polling for and timing of transmisstions */
-
- cs89x0->cs_txpoll = wd_create(); /* Create periodic poll timer */
- cs89x0->cs_txtimeout = wd_create(); /* Create TX timeout timer */
-
- /* Read the MAC address from the hardware into cs89x0->cs_dev.d_mac.ether_addr_octet */
-
- /* Register the device with the OS so that socket IOCTLs can be performed */
-
- (void)netdev_register(&cs89x0->cs_dev);
- return OK;
-}
-
-#endif /* CONFIG_NET && CONFIG_NET_CS89x0 */
-
diff --git a/nuttx/drivers/net/cs89x0.h b/nuttx/drivers/net/cs89x0.h
deleted file mode 100644
index f6d99120a..000000000
--- a/nuttx/drivers/net/cs89x0.h
+++ /dev/null
@@ -1,326 +0,0 @@
-/****************************************************************************
- * drivers/net/cs89x0.h
- *
- * Copyright (C) 2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_NET_CS89x0_H
-#define __DRIVERS_NET_CS89x0_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* CONFIG_CS89x0_ALIGN16/32 determines if the 16-bit CS89x0 registers are
- * aligned to 16-bit or 32-bit address boundaries. NOTE: If there multiple
- * CS89x00 parts in the board architecture, we assume that the address
- * alignment is the same for all implementations. If that is not the
- * case, then it will be necessary to move a shift value into
- * the cs89x0_driver_s structure and calculate the offsets dynamically in
- * the putreg and getreg functions.
- */
-
-#if defined(CONFIG_CS89x0_ALIGN16)
-# define CS89x0_RTDATA_OFFSET (0 << 1)
-# define CS89x0_TxCMD_OFFSET (2 << 1)
-# define CS89x0_TxLEN_OFFSET (3 << 1)
-# define CS89x0_ISQ_OFFSET (4 << 1)
-# define CS89x0_PPTR_OFFSET (5 << 1)
-# define CS89x0_PDATA_OFFSET (6 << 1)
-#elif defined(CONFIG_CS89x0_ALIGN32)
-# define CS89x0_RTDATA_OFFSET (0 << 2)
-# define CS89x0_TxCMD_OFFSET (2 << 2)
-# define CS89x0_TxLEN_OFFSET (3 << 2)
-# define CS89x0_ISQ_OFFSET (4 << 2)
-# define CS89x0_PPTR_OFFSET (5 << 2)
-# define CS89x0_PDATA_OFFSET (6 << 2)
-#else
-# error "CS89x00 address alignment is not defined"
-#endif
-
-/* ISQ register bit definitions */
-
-#define ISQ_EVENTMASK 0x003f /* Bits 0-5 indicate the status register */
-#define ISQ_RXEVENT 0x0004
-#define ISQ_TXEVENT 0x0008
-#define ISQ_BUFEVENT 0x000c
-#define ISQ_RXMISSEVENT 0x0010
-#define ISQ_TXCOLEVENT 0x0012
-
-/* ISQ register TxEVENT bit definitions*/
-
-#define ISQ_RXEVENT_IAHASH (1 << 6)
-#define ISQ_RXEVENT_DRIBBLE (1 << 7)
-#define ISQ_RXEVENT_RXOK (1 << 8)
-#define ISQ_RXEVENT_HASHED (1 << 9)
-#define ISQ_RXEVENT_HASHNDX_SHIFT 10
-#define ISQ_RXEVENT_HASHNDX_MASK (0x3f << ISQ_RXEVENT_HASHNDX_SHIFT)
-
-/* ISQ register TxEVENT bit definitions*/
-
-#define ISQ_TXEVENT_LOSSOFCRS (1 << 6)
-#define ISQ_TXEVENT_SQEERROR (1 << 7)
-#define ISQ_TXEVENT_TXOK (1 << 8)
-#define ISQ_TXEVENT_OUTWINDOW (1 << 9)
-#define ISQ_TXEVENT_JABBER (1 << 10)
-#define ISQ_TXEVENT_NCOLLISION_SHIFT 11
-#define ISQ_TXEVENT_NCOLLISION_MASK (15 << ISQ_TXEVENT_NCOLLISION_SHIFT)
-#define ISQ_TXEVENT_16COLL (1 << 15)
-
-/* ISQ register BufEVENT bit definitions */
-
-#define ISQ_BUFEVENT_SWINT (1 << 6)
-#define ISQ_BUFEVENT_RXDMAFRAME (1 << 7)
-#define ISQ_BUFEVENT_RDY4TX (1 << 8)
-#define ISQ_BUFEVENT_TXUNDERRUN (1 << 9)
-#define ISQ_BUFEVENT_RXMISS (1 << 10)
-#define ISQ_BUFEVENT_RX128 (1 << 11)
-#define ISQ_BUFEVENT_RXDEST (1 << 15)
-
-/* Packet page register offsets *********************************************/
-
-/* 0x0000 Bus interface registers */
-
-#define PPR_CHIPID 0x0000 /* Chip identifier - must be 0x630E */
-#define PPR_CHIPREV 0x0002 /* Chip revision, model codes */
-#define PPR_IOBASEADDRESS 0x0020 /* I/O Base Address */
-#define PPR_INTREG 0x0022 /* Interrupt configuration */
-# define PPR_INTREG_IRQ0 0x0000 /* Use INTR0 pin */
-# define PPR_INTREG_IRQ1 0x0001 /* Use INTR1 pin */
-# define PPR_INTREG_IRQ2 0x0002 /* Use INTR2 pin */
-# define PPR_INTREG_IRQ3 0x0003 /* Use INTR3 pin */
-
-#define PPR_DMACHANNELNUMBER 0x0024 /* DMA Channel Number (0,1, or 2) */
-#define PPR_DMASTARTOFFRAME 0x0026 /* DMA Start of Frame */
-#define PPR_DMAFRAMECOUNT 0x0028 /* DMA Frame Count (12-bits) */
-#define PPR_RXDMABYTECOUNT 0x002a /* Rx DMA Byte Count */
-#define PPR_MEMORYBASEADDRESS 0x002c /* Memory Base Address Register (20-bit) */
-#define PPR_BOOTPROMBASEADDRESS 0x0030 /* Boot PROM Base Address */
-#define PPR_BOOTPROMADDRESSMASK 0x0034 /* Boot PROM Address Mask */
-#define PPR_EEPROMCOMMAND 0x0040 /* EEPROM Command */
-#define PPR_EEPROMDATA 0x0042 /* EEPROM Data */
-#define PPR_RECVFRAMEBYTES 0x0050 /* Received Frame Byte Counter */
-
-/* 0x0100 - Configuration and control registers */
-
-#define PPR_RXCFG 0x0102 /* Receiver configuration */
-# define PPR_RXCFG_SKIP1 (1 << 6) /* Skip (discard) current frame */
-# define PPR_RXCFG_STREAM (1 << 7) /* Enable streaming mode */
-# define PPR_RXCFG_RXOK (1 << 8) /* RxOK interrupt enable */
-# define PPR_RxCFG_RxDMAonly (1 << 9) /* Use RxDMA for all frames */
-# define PPR_RxCFG_AutoRxDMA (1 << 10) /* Select RxDMA automatically */
-# define PPR_RxCFG_BufferCRC (1 << 11) /* Include CRC characters in frame */
-# define PPR_RxCFG_CRC (1 << 12) /* Enable interrupt on CRC error */
-# define PPR_RxCFG_RUNT (1 << 13) /* Enable interrupt on RUNT frames */
-# define PPR_RxCFG_EXTRA (1 << 14) /* Enable interrupt on frames with extra data */
-
-#define PPR_RXCTL 0x0104 /* Receiver control */
-# define PPR_RXCTL_IAHASH (1 << 6) /* Accept frames that match hash */
-# define PPR_RXCTL_PROMISCUOUS (1 << 7) /* Accept any frame */
-# define PPR_RXCTL_RXOK (1 << 8) /* Accept well formed frames */
-# define PPR_RXCTL_MULTICAST (1 << 9) /* Accept multicast frames */
-# define PPR_RXCTL_IA (1 << 10) /* Accept frame that matches IA */
-# define PPR_RXCTL_BROADCAST (1 << 11) /* Accept broadcast frames */
-# define PPR_RXCTL_CRC (1 << 12) /* Accept frames with bad CRC */
-# define PPR_RXCTL_RUNT (1 << 13) /* Accept runt frames */
-# define PPR_RXCTL_EXTRA (1 << 14) /* Accept frames that are too long */
-
-#define PPR_TXCFG 0x0106 /* Transmit configuration */
-# define PPR_TXCFG_CRS (1 << 6) /* Enable interrupt on loss of carrier */
-# define PPR_TXCFG_SQE (1 << 7) /* Enable interrupt on Signal Quality Error */
-# define PPR_TXCFG_TXOK (1 << 8) /* Enable interrupt on successful xmits */
-# define PPR_TXCFG_LATE (1 << 9) /* Enable interrupt on "out of window" */
-# define PPR_TXCFG_JABBER (1 << 10) /* Enable interrupt on jabber detect */
-# define PPR_TXCFG_COLLISION (1 << 11) /* Enable interrupt if collision */
-# define PPR_TXCFG_16COLLISIONS (1 << 15) /* Enable interrupt if > 16 collisions */
-
-#define PPR_TXCMD 0x0108 /* Transmit command status */
-# define PPR_TXCMD_TXSTART5 (0 << 6) /* Start after 5 bytes in buffer */
-# define PPR_TXCMD_TXSTART381 (1 << 6) /* Start after 381 bytes in buffer */
-# define PPR_TXCMD_TXSTART1021 (2 << 6) /* Start after 1021 bytes in buffer */
-# define PPR_TXCMD_TXSTARTFULL (3 << 6) /* Start after all bytes loaded */
-# define PPR_TXCMD_FORCE (1 << 8) /* Discard any pending packets */
-# define PPR_TXCMD_ONECOLLISION (1 << 9) /* Abort after a single collision */
-# define PPR_TXCMD_NOCRC (1 << 12) /* Do not add CRC */
-# define PPR_TXCMD_NOPAD (1 << 13) /* Do not pad short packets */
-
-#define PPR_BUFCFG 0x010a /* Buffer configuration */
-# define PPR_BUFCFG_SWI (1 << 6) /* Force interrupt via software */
-# define PPR_BUFCFG_RXDMA (1 << 7) /* Enable interrupt on Rx DMA */
-# define PPR_BUFCFG_TXRDY (1 << 8) /* Enable interrupt when ready for Tx */
-# define PPR_BUFCFG_TXUE (1 << 9) /* Enable interrupt in Tx underrun */
-# define PPR_BUFCFG_RXMISS (1 << 10) /* Enable interrupt on missed Rx packets */
-# define PPR_BUFCFG_RX128 (1 << 11) /* Enable Rx interrupt after 128 bytes */
-# define PPR_BUFCFG_TXCOL (1 << 12) /* Enable int on Tx collision ctr overflow */
-# define PPR_BUFCFG_MISS (1 << 13) /* Enable int on Rx miss ctr overflow */
-# define PPR_BUFCFG_RXDEST (1 << 15) /* Enable int on Rx dest addr match */
-
-#define PPR_LINECTL 0x0112 /* Line control */
-# define PPR_LINECTL_RX (1 << 6) /* Enable receiver */
-# define PPR_LINECTL_TX (1 << 7) /* Enable transmitter */
-# define PPR_LINECTL_AUIONLY (1 << 8) /* AUI interface only */
-# define PPR_LINECTL_AUTOAUI10BT (1 << 9) /* Autodetect AUI or 10BaseT interface */
-# define PPR_LINECTL_MODBACKOFFE (1 << 11) /* Enable modified backoff algorithm */
-# define PPR_LINECTL_POLARITYDIS (1 << 12) /* Disable Rx polarity autodetect */
-# define PPR_LINECTL_2PARTDEFDIS (1 << 13) /* Disable two-part defferal */
-# define PPR_LINECTL_LORXSQUELCH (1 << 14) /* Reduce receiver squelch threshold */
-
-#define PPR_SELFCTL 0x0114 /* Chip self control */
-# define PPR_SELFCTL_RESET (1 << 6) /* Self-clearing reset */
-# define PPR_SELFCTL_SWSUSPEND (1 << 8) /* Initiate suspend mode */
-# define PPR_SELFCTL_HWSLEEPE (1 << 9) /* Enable SLEEP input */
-# define PPR_SELFCTL_HWSTANDBYE (1 << 10) /* Enable standby mode */
-# define PPR_SELFCTL_HC0E (1 << 12) /* Use HCB0 for LINK LED */
-# define PPR_SELFCTL_HC1E (1 << 13) /* Use HCB1 for BSTATUS LED */
-# define PPR_SELFCTL_HCB0 (1 << 14) /* Control LINK LED if HC0E set */
-# define PPR_SELFCTL_HCB1 (1 << 15) /* Cntrol BSTATUS LED if HC1E set */
-
-#define PPR_BUSCTL 0x0116 /* Bus control */
-# define PPR_BUSCTL_RESETRXDMA (1 << 6) /* Reset RxDMA pointer */
-# define PPR_BUSCTL_DMAEXTEND (1 << 8) /* Extend DMA cycle */
-# define PPR_BUSCTL_USESA (1 << 9) /* Assert MEMCS16 on address decode */
-# define PPR_BUSCTL_MEMORYE (1 << 10) /* Enable memory mode */
-# define PPR_BUSCTL_DMABURST (1 << 11) /* Limit DMA access burst */
-# define PPR_BUSCTL_IOCHRDYE (1 << 12) /* Set IOCHRDY high impedence */
-# define PPR_BUSCTL_RXDMASIZE (1 << 13) /* Set DMA buffer size 64KB */
-# define PPR_BUSCTL_ENABLEIRQ (1 << 15) /* Generate interrupt on interrupt event */
-
-#define PPR_TESTCTL 0x0118 /* Test control */
-# define PPR_TESTCTL_DISABLELT (1 << 7) /* Disable link status */
-# define PPR_TESTCTL_ENDECLOOP (1 << 9) /* Internal loopback */
-# define PPR_TESTCTL_AUILOOP (1 << 10) /* AUI loopback */
-# define PPR_TESTCTL_DISBACKOFF (1 << 11) /* Disable backoff algorithm */
-# define PPR_TESTCTL_FDX (1 << 14) /* Enable full duplex mode */
-
-/* 0x0120 - Status and Event Registers */
-
-#define PPR_ISQ 0x0120 /* Interrupt Status Queue */
-#define PPR_RER 0x0124 /* Receive event */
-# define PPR_RER_IAHASH (1 << 6) /* Frame hash match */
-# define PPR_RER_DRIBBLE (1 << 7) /* Frame had 1-7 extra bits after last byte */
-# define PPR_RER_RXOK (1 << 8) /* Frame received with no errors */
-# define PPR_RER_HASHED (1 << 9) /* Frame address hashed OK */
-# define PPR_RER_IA (1 << 10) /* Frame address matched IA */
-# define PPR_RER_BROADCAST (1 << 11) /* Broadcast frame */
-# define PPR_RER_CRC (1 << 12) /* Frame had CRC error */
-# define PPR_RER_RUNT (1 << 13) /* Runt frame */
-# define PPR_RER_EXTRA (1 << 14) /* Frame was too long */
-
-#define PPR_TER 0x0128 /* Transmit event */
-# define PPR_TER_CRS (1 << 6) /* Carrier lost */
-# define PPR_TER_SQE (1 << 7) /* Signal Quality Error */
-# define PPR_TER_TXOK (1 << 8) /* Packet sent without error */
-# define PPR_TER_LATE (1 << 9) /* Out of window */
-# define PPR_TER_JABBER (1 << 10) /* Stuck transmit? */
-# define PPR_TER_NUMCOLLISIONS_SHIFT 11
-# define PPR_TER_NUMCOLLISIONS_MASK (15 << PPR_TER_NUMCOLLISIONS_SHIFT)
-# define PPR_TER_16COLLISIONS (1 << 15) /* > 16 collisions */
-
-#define PPR_BER 0x012C /* Buffer event */
-# define PPR_BER_SWINT (1 << 6) /* Software interrupt */
-# define PPR_BER_RXDMAFRAME (1 << 7) /* Received framed DMAed */
-# define PPR_BER_RDY4TX (1 << 8) /* Ready for transmission */
-# define PPR_BER_TXUNDERRUN (1 << 9) /* Transmit underrun */
-# define PPR_BER_RXMISS (1 << 10) /* Received frame missed */
-# define PPR_BER_RX128 (1 << 11) /* 128 bytes received */
-# define PPR_BER_RXDEST (1 << 15) /* Received framed passed address filter */
-
-#define PPR_RXMISS 0x0130 /* Receiver miss counter */
-#define PPR_TXCOL 0x0132 /* Transmit collision counter */
-#define PPR_LINESTAT 0x0134 /* Line status */
-# define PPR_LINESTAT_LINKOK (1 << 7) /* Line is connected and working */
-# define PPR_LINESTAT_AUI (1 << 8) /* Connected via AUI */
-# define PPR_LINESTAT_10BT (1 << 9) /* Connected via twisted pair */
-# define PPR_LINESTAT_POLARITY (1 << 12) /* Line polarity OK (10BT only) */
-# define PPR_LINESTAT_CRS (1 << 14) /* Frame being received */
-
-#define PPR_SELFSTAT 0x0136 /* Chip self status */
-# define PPR_SELFSTAT_33VACTIVE (1 << 6) /* supply voltage is 3.3V */
-# define PPR_SELFSTAT_INITD (1 << 7) /* Chip initialization complete */
-# define PPR_SELFSTAT_SIBSY (1 << 8) /* EEPROM is busy */
-# define PPR_SELFSTAT_EEPROM (1 << 9) /* EEPROM present */
-# define PPR_SELFSTAT_EEPROMOK (1 << 10) /* EEPROM checks out */
-# define PPR_SELFSTAT_ELPRESENT (1 << 11) /* External address latch logic available */
-# define PPR_SELFSTAT_EESIZE (1 << 12) /* Size of EEPROM */
-
-#define PPR_BUSSTAT 0x0138 /* Bus status */
-# define PPR_BUSSTAT_TXBID (1 << 7) /* Tx error */
-# define PPR_BUSSTAT_TXRDY (1 << 8) /* Ready for Tx data */
-
-#define PPR_TDR 0x013C /* AUI Time Domain Reflectometer */
-
-/* 0x0144 - Initiate transmit registers */
-
-#define PPR_TXCOMMAND 0x0144 /* Tx Command */
-#define PPR_TXLENGTH 0x0146 /* Tx Length */
-
-/* 0x0150 - Address filter registers */
-
-#define PPR_LAF 0x0150 /* Logical address filter (6 bytes) */
-#define PPR_IA 0x0158 /* Individual address (MAC) */
-
-/* 0x0400 - Frame location registers */
-
-#define PPR_RXSTATUS 0x0400 /* Rx Status */
-#define PPR_RXLENGTH 0x0402 /* Rx Length */
-#define PPR_RXFRAMELOCATION 0x0404 /* Rx Frame Location */
-#define PPR_TXFRAMELOCATION 0x0a00 /* Tx Frame Location */
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DRIVERS_NET_CS89x0_H */
diff --git a/nuttx/drivers/net/dm90x0.c b/nuttx/drivers/net/dm90x0.c
deleted file mode 100644
index 2f5b26abb..000000000
--- a/nuttx/drivers/net/dm90x0.c
+++ /dev/null
@@ -1,1815 +0,0 @@
-/****************************************************************************
- * drivers/net/dm9x.c
- *
- * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References: Davicom data sheets (DM9000-DS-F03-041906.pdf,
- * DM9010-DS-F01-103006.pdf) and looking at lots of other DM90x0
- * drivers.
- *
- * 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 <nuttx/config.h>
-#if defined(CONFIG_NET) && defined(CONFIG_NET_DM90x0)
-
-/* Only one hardware interface supported at present (although there are
- * hooks throughout the design to that extending the support to multiple
- * interfaces should not be that difficult)
- */
-
-#undef CONFIG_DM9X_NINTERFACES
-#define CONFIG_DM9X_NINTERFACES 1
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <time.h>
-#include <string.h>
-#include <debug.h>
-#include <wdog.h>
-#include <errno.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include <net/ethernet.h>
-#include <nuttx/net/uip/uip.h>
-#include <nuttx/net/uip/uip-arp.h>
-#include <nuttx/net/uip/uip-arch.h>
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-/* DM90000 and DM9010 register offets */
-
-#define DM9X_NETC 0x00 /* Network control register */
-#define DM9X_NETS 0x01 /* Network Status register */
-#define DM9X_TXC 0x02 /* TX control register */
-#define DM9X_TXS1 0x03 /* TX status register 1 */
-#define DM9X_TXS2 0x03 /* TX status register 2 */
-#define DM9X_RXC 0x05 /* RX control register */
-#define DM9X_RXS 0x06 /* RX status register */
-#define DM9X_RXOVF 0x07 /* Receive overflow counter register */
-#define DM9X_BPTHRES 0x08 /* Back pressure threshold register */
-#define DM9X_FCTHRES 0x09 /* Flow control threshold register */
-#define DM9X_FC 0x0a /* RX/TX flow control register */
-#define DM9X_EEPHYC 0x0b /* EEPROM & PHY control register */
-#define DM9X_EEPHYA 0x0c /* EEPROM & PHY address register */
-#define DM9X_EEPHYDL 0x0d /* EEPROM & PHY data register (lo) */
-#define DM9X_EEPHYDH 0x0e /* EEPROM & PHY data register (hi) */
-#define DM9X_WAKEUP 0x0f /* Wake-up control register */
-#define DM9X_PAB0 0x10 /* Physical address register (byte 0) */
-#define DM9X_PAB1 0x11 /* Physical address register (byte 1) */
-#define DM9X_PAB2 0x12 /* Physical address register (byte 2) */
-#define DM9X_PAB3 0x13 /* Physical address register (byte 3) */
-#define DM9X_PAB4 0x14 /* Physical address register (byte 4) */
-#define DM9X_PAB5 0x15 /* Physical address register (byte 5) */
-#define DM9X_MAB0 0x16 /* Multicast address register (byte 0) */
-#define DM9X_MAB1 0x17 /* Multicast address register (byte 1) */
-#define DM9X_MAB2 0x18 /* Multicast address register (byte 2) */
-#define DM9X_MAB3 0x19 /* Multicast address register (byte 3) */
-#define DM9X_MAB4 0x1a /* Multicast address register (byte 4) */
-#define DM9X_MAB5 0x1b /* Multicast address register (byte 5) */
-#define DM9X_MAB6 0x1c /* Multicast address register (byte 6) */
-#define DM9X_MAB7 0x1d /* Multicast address register (byte 7) */
-#define DM9X_GPC 0x1e /* General purpose control register */
-#define DM9X_GPD 0x1f /* General purpose register */
-
-#define DM9X_TRPAL 0x22 /* TX read pointer address (lo) */
-#define DM9X_TRPAH 0x23 /* TX read pointer address (hi) */
-#define DM9X_RWPAL 0x24 /* RX write pointer address (lo) */
-#define DM9X_RWPAH 0x25 /* RX write pointer address (hi) */
-
-#define DM9X_VIDL 0x28 /* Vendor ID (lo) */
-#define DM9X_VIDH 0x29 /* Vendor ID (hi) */
-#define DM9X_PIDL 0x2a /* Product ID (lo) */
-#define DM9X_PIDH 0x2b /* Product ID (hi) */
-#define DM9X_CHIPR 0x2c /* Product ID (lo) */
-#define DM9X_TXC2 0x2d /* Transmit control register 2 (dm9010) */
-#define DM9X_OTC 0x2e /* Operation test control register (dm9010) */
-#define DM9X_SMODEC 0x2f /* Special mode control register */
-#define DM9X_ETXCSR 0x30 /* Early transmit control/status register (dm9010) */
-#define DM9X_TCCR 0x31 /* Transmit checksum control register (dm9010) */
-#define DM9X_RCSR 0x32 /* Receive checksum control/status register (dm9010) */
-#define DM9X_EPHYA 0x33 /* External PHY address register (dm9010) */
-#define DM9X_GPC2 0x34 /* General purpose control register 2 (dm9010) */
-#define DM9X_GPD2 0x35 /* General purpose register 2 */
-#define DM9X_GPC3 0x36 /* General purpose control register 3 (dm9010) */
-#define DM9X_GPD3 0x37 /* General purpose register 3 */
-#define DM9X_PBUSC 0x38 /* Processor bus control register (dm9010) */
-#define DM9X_IPINC 0x39 /* INT pin control register (dm9010) */
-
-#define DM9X_MON1 0x40 /* Monitor register 1 (dm9010) */
-#define DM9X_MON2 0x41 /* Monitor register 2 (dm9010) */
-
-#define DM9X_SCLKC 0x50 /* System clock turn ON control register (dm9010) */
-#define DM9X_SCLKR 0x51 /* Resume system clock control register (dm9010) */
-
-#define DM9X_MRCMDX 0xf0 /* Memory data pre-fetch read command without address increment */
-#define DM9X_MRCMDX1 0xf1 /* memory data read command without address increment (dm9010) */
-#define DM9X_MRCMD 0xf2 /* Memory data read command with address increment */
-#define DM9X_MDRAL 0xf4 /* Memory data read address register (lo) */
-#define DM9X_MDRAH 0xf5 /* Memory data read address register (hi) */
-#define DM9X_MWCMDX 0xf6 /* Memory data write command without address increment */
-#define DM9X_MWCMD 0xf8 /* Memory data write command with address increment */
-#define DM9X_MDWAL 0xfa /* Memory data write address register (lo) */
-#define DM9X_MDWAH 0xfb /* Memory data write address register (lo) */
-#define DM9X_TXPLL 0xfc /* Memory data write address register (lo) */
-#define DM9X_TXPLH 0xfd /* Memory data write address register (hi) */
-#define DM9X_ISR 0xfe /* Interrupt status register */
-#define DM9X_IMR 0xff /* Interrupt mask register */
-
-/* Network control register bit definitions */
-
-#define DM9X_NETC_RST (1 << 0) /* Software reset */
-#define DM9X_NETC_LBKM (3 << 1) /* Loopback mode mask */
-#define DM9X_NETC_LBK0 (0 << 1) /* 0: Normal */
-#define DM9X_NETC_LBK1 (1 << 1) /* 1: MAC internal loopback */
-#define DM9X_NETC_LBK2 (2 << 1) /* 2: Internal PHY 100M mode loopback */
-#define DM9X_NETC_FDX (1 << 3) /* Full dupliex mode */
-#define DM9X_NETC_FCOL (1 << 4) /* Force collision mode */
-#define DM9X_NETC_WAKEEN (1 << 6) /* Wakeup event enable */
-#define DM9X_NETC_EXTPHY (1 << 7) /* Select external PHY */
-
-/* Network status bit definitions */
-
-#define DM9X_NETS_RXOV (1 << 1) /* RX Fifo overflow */
-#define DM9X_NETS_TX1END (1 << 2) /* TX packet 1 complete status */
-#define DM9X_NETS_TX2END (1 << 3) /* TX packet 2 complete status */
-#define DM9X_NETS_WAKEST (1 << 5) /* Wakeup event status */
-#define DM9X_NETS_LINKST (1 << 6) /* Link status */
-#define DM9X_NETS_SPEED (1 << 7) /* Media speed */
-
-/* IMR/ISR bit definitions */
-
-#define DM9X_INT_PR (1 << 0) /* Packet received interrupt */
-#define DM9X_INT_PT (1 << 1) /* Packet transmitted interrupt */
-#define DM9X_INT_RO (1 << 2) /* Receive overflow interrupt */
-#define DM9X_INT_ROO (1 << 3) /* Receive overflow counter overflow int */
-#define DM9X_INT_UDRUN (1 << 4) /* Transmit underrun interrupt */
-#define DM9X_INT_LNKCHG (1 << 5) /* Link status change interrupt */
-#define DM9X_INT_ALL (0x3f)
-
-#define DM9X_IMR_UNUSED (1 << 6) /* (not used) */
-#define DM9X_IMR_PAR (1 << 7) /* Enable auto R/W pointer reset */
-
-#define DM9X_ISR_IOMODEM (3 << 6) /* IO mode mask */
-#define DM9X_ISR_IOMODE8 (2 << 6) /* IO mode = 8 bit */
-#define DM9X_ISR_IOMODE16 (0 << 6) /* IO mode = 16 bit */
-#define DM9X_ISR_IOMODE32 (1 << 6) /* IO mode = 32 bit */
-
-#define DM9X_IMRENABLE (DM9X_INT_PR|DM9X_INT_PT|DM9X_INT_LNKCHG|DM9X_IMR_PAR)
-#define DM9X_IMRRXDISABLE (DM9X_INT_PT|DM9X_INT_LNKCHG|DM9X_IMR_PAR)
-#define DM9X_IMRDISABLE (DM9X_IMR_PAR)
-
-/* EEPROM/PHY control regiser bits */
-
-#define DM9X_EEPHYC_ERRE (1 << 0) /* EEPROM (vs PHY) access status */
-#define DM9X_EEPHYC_ERPRW (1 << 1) /* EEPROM/PHY write access */
-#define DM9X_EEPHYC_ERPRR (1 << 2) /* EEPROM/PHY read access */
-#define DM9X_EEPHYC_EPOS (1 << 3) /* EEPROM/PHY operation select */
-#define DM9X_EEPHYC_WEP (1 << 4) /* Write EEPROM enable */
-#define DM9X_EEPHYC_REEP (1 << 5) /* Reload EEPROM */
-
-/* Supported values from the vendor and product ID register */
-
-#define DM9X_DAVICOMVID 0x0a46
-#define DM9X_DM9000PID 0x9000
-#define DM9X_DM9010PID 0x9010
-
-/* RX control register bit settings */
-
-#define DM9X_RXC_RXEN (1 << 0) /* RX enable */
-#define DM9X_RXC_PRMSC (1 << 1) /* Promiscuous mode */
-#define DM9X_RXC_RUNT (1 << 2) /* Pass runt packet */
-#define DM9X_RXC_ALL (1 << 3) /* Pass all multicast */
-#define DM9X_RXC_DISCRC (1 << 4) /* Discard CRC error packets */
-#define DM9X_RXC_DISLONG (1 << 5) /* Discard long packets */
-#define DM9X_RXC_WTDIS (1 << 6) /* Disable watchdog timer */
-#define DM9X_RXC_HASHALL (1 << 7) /* Filter all addresses in hash table */
-
-#define DM9X_RXCSETUP (DM9X_RXC_DISCRC|DM9X_RXC_DISLONG)
-
-/* EEPHY bit settings */
-
-#define DM9X_EEPHYA_EROA 0x40 /* PHY register address 0x01 */
-
-#define DM9X_PKTRDY 0x01 /* Packet ready to receive */
-
-/* The RX interrupt will be disabled if more than the following RX
- * interrupts are received back-to-back.
- */
-
-#define DM9X_CRXTHRES 10
-
-/* All access is via an index register and a data regist. Select accecss
- * according to user supplied base address and bus width.
- */
-
-#if defined(CONFIG_DM9X_BUSWIDTH8)
-# define DM9X_INDEX *(volatile uint8_t*)(CONFIG_DM9X_BASE)
-# define DM9X_DATA *(volatile uint8_t*)(CONFIG_DM9X_BASE + 2)
-#elif defined(CONFIG_DM9X_BUSWIDTH16)
-# define DM9X_INDEX *(volatile uint16_t*)(CONFIG_DM9X_BASE)
-# define DM9X_DATA *(volatile uint16_t*)(CONFIG_DM9X_BASE + 2)
-#elif defined(CONFIG_DM9X_BUSWIDTH32)
-# define DM9X_INDEX *(volatile uint32_t*)(CONFIG_DM9X_BASE)
-# define DM9X_DATA *(volatile uint32_t*)(CONFIG_DM9X_BASE + 2)
-#endif
-
-/* Phy operating mode. Default is AUTO, but this setting can be overridden
- * in the NuttX configuration file.
- */
-
-#define DM9X_MODE_AUTO 0
-#define DM9X_MODE_10MHD 1
-#define DM9X_MODE_100MHD 2
-#define DM9X_MODE_10MFD 3
-#define DM9X_MODE_100MFD 4
-
-#ifndef CONFIG_DM9X_MODE
-# define CONFIG_DM9X_MODE DM9X_MODE_AUTO
-#endif
-
-/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */
-
-#define DM6X_WDDELAY (1*CLK_TCK)
-#define DM6X_POLLHSEC (1*2)
-
-/* TX timeout = 1 minute */
-
-#define DM6X_TXTIMEOUT (60*CLK_TCK)
-
-/* This is a helper pointer for accessing the contents of the Ethernet header */
-
-#define BUF ((struct uip_eth_hdr *)dm9x->dm_dev.d_buf)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-union rx_desc_u
-{
- uint8_t rx_buf[4];
- struct
- {
- uint8_t rx_byte;
- uint8_t rx_status;
- uint16_t rx_len;
- } desc;
-};
-
-/* The dm9x_driver_s encapsulates all DM90x0 state information for a single
- * DM90x0 hardware interface
- */
-
-struct dm9x_driver_s
-{
- bool dm_bifup; /* true:ifup false:ifdown */
- bool dm_b100M; /* true:speed == 100M; false:speed == 10M */
- WDOG_ID dm_txpoll; /* TX poll timer */
- WDOG_ID dm_txtimeout; /* TX timeout timer */
- uint8_t dm_ntxpending; /* Count of packets pending transmission */
- uint8_t ncrxpackets; /* Number of continuous rx packets */
-
- /* Mode-dependent function to move data in 8/16/32 I/O modes */
-
- void (*dm_read)(uint8_t *ptr, int len);
- void (*dm_write)(const uint8_t *ptr, int len);
- void (*dm_discard)(int len);
-
-#if defined(CONFIG_DM9X_STATS)
- uint32_t dm_ntxpackets; /* Count of packets sent */
- uint32_t dm_ntxbytes; /* Count of bytes sent */
- uint32_t dm_ntxerrors; /* Count of TX errors */
- uint32_t dm_nrxpackets; /* Count of packets received */
- uint32_t dm_nrxbytes; /* Count of bytes received */
- uint32_t dm_nrxfifoerrors; /* Count of RX FIFO overflow errors */
- uint32_t dm_nrxcrcerrors; /* Count of RX CRC errors */
- uint32_t dm_nrxlengtherrors; /* Count of RX length errors */
- uint32_t dm_nphyserrors; /* Count of physical layer errors */
- uint32_t dm_nresets; /* Counts number of resets */
- uint32_t dm_ntxtimeouts; /* Counts resets caused by TX timeouts */
-#endif
-
- /* This holds the information visible to uIP/NuttX */
-
- struct uip_driver_s dm_dev;
-};
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* At present, only a single DM90x0 device is supported. */
-
-static struct dm9x_driver_s g_dm9x[CONFIG_DM9X_NINTERFACES];
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Utility functions */
-
-static uint8_t getreg(int reg);
-static void putreg(int reg, uint8_t value);
-static void read8(uint8_t *ptr, int len);
-static void read16(uint8_t *ptr, int len);
-static void read32(uint8_t *ptr, int len);
-static void discard8(int len);
-static void discard16(int len);
-static void discard32(int len);
-static void write8(const uint8_t *ptr, int len);
-static void write16(const uint8_t *ptr, int len);
-static void write32(const uint8_t *ptr, int len);
-
-/* static uint16_t dm9x_readsrom(struct dm9x_driver_s *dm9x, int offset); */
-static uint16_t dm9x_phyread(struct dm9x_driver_s *dm9x, int reg);
-static void dm9x_phywrite(struct dm9x_driver_s *dm9x, int reg, uint16_t value);
-
-#if defined(CONFIG_DM9X_STATS)
-static void dm9x_resetstatistics(struct dm9x_driver_s *dm9x);
-#else
-# define dm9x_resetstatistics(dm9x)
-#endif
-
-#if defined(CONFIG_DM9X_STATS) && defined(CONFIG_DEBUG)
-static void dm9x_dumpstatistics(struct dm9x_driver_s *dm9x);
-#else
-# define dm9x_dumpstatistics(dm9x)
-#endif
-
-#if defined(CONFIG_DM9X_CHECKSUM)
-static bool dm9x_rxchecksumready(uint8_t);
-#else
-# define dm9x_rxchecksumready(a) ((a) == 0x01)
-#endif
-
-/* Common TX logic */
-
-static int dm9x_transmit(struct dm9x_driver_s *dm9x);
-static int dm9x_uiptxpoll(struct uip_driver_s *dev);
-
-/* Interrupt handling */
-
-static void dm9x_receive(struct dm9x_driver_s *dm9x);
-static void dm9x_txdone(struct dm9x_driver_s *dm9x);
-static int dm9x_interrupt(int irq, FAR void *context);
-
-/* Watchdog timer expirations */
-
-static void dm9x_polltimer(int argc, uint32_t arg, ...);
-static void dm9x_txtimeout(int argc, uint32_t arg, ...);
-
-/* NuttX callback functions */
-
-static int dm9x_ifup(struct uip_driver_s *dev);
-static int dm9x_ifdown(struct uip_driver_s *dev);
-static int dm9x_txavail(struct uip_driver_s *dev);
-#ifdef CONFIG_NET_IGMP
-static int dm9x_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-static int dm9x_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-#endif
-
-/* Initialization functions */
-
-static void dm9x_bringup(struct dm9x_driver_s *dm9x);
-static void dm9x_reset(struct dm9x_driver_s *dm9x);
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: getreg and setreg
- *
- * Description:
- * Access to memory-mapped DM90x0 8-bit registers
- *
- * Parameters:
- * reg - Register number
- * value - Value to write to the register (setreg only)
- *
- * Returned Value:
- * Value read from the register (getreg only)
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static uint8_t getreg(int reg)
-{
- DM9X_INDEX = reg;
- return DM9X_DATA & 0xff;
-}
-
-static void putreg(int reg, uint8_t value)
-{
- DM9X_INDEX = reg;
- DM9X_DATA = value & 0xff;
-}
-
-/****************************************************************************
- * Function: read8, read16, read32
- *
- * Description:
- * Read packet data from the DM90x0 SRAM based on its current I/O mode
- *
- * Parameters:
- * ptr - Location to write the packet data
- * len - The number of bytes to read
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void read8(uint8_t *ptr, int len)
-{
- nvdbg("Read %d bytes (8-bit mode)\n", len);
- for (; len > 0; len--)
- {
- *ptr++ = DM9X_DATA;
- }
-}
-
-static void read16(uint8_t *ptr, int len)
-{
- register uint16_t *ptr16 = (uint16_t*)ptr;
- nvdbg("Read %d bytes (16-bit mode)\n", len);
- for (; len > 0; len -= sizeof(uint16_t))
- {
- *ptr16++ = DM9X_DATA;
- }
-}
-
-static void read32(uint8_t *ptr, int len)
-{
- register uint32_t *ptr32 = (uint32_t*)ptr;
- nvdbg("Read %d bytes (32-bit mode)\n", len);
- for (; len > 0; len -= sizeof(uint32_t))
- {
- *ptr32++ = DM9X_DATA;
- }
-}
-
-/****************************************************************************
- * Function: discard8, discard16, discard32
- *
- * Description:
- * Read and discard packet data in the DM90x0 SRAM based on its current
- * I/O mode
- *
- * Parameters:
- * len - The number of bytes to discard
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void discard8(int len)
-{
- nvdbg("Discard %d bytes (8-bit mode)\n", len);
- for (; len > 0; len--)
- {
- DM9X_DATA;
- }
-}
-
-static void discard16(int len)
-{
- nvdbg("Discard %d bytes (16-bit mode)\n", len);
- for (; len > 0; len -= sizeof(uint16_t))
- {
- DM9X_DATA;
- }
-}
-
-static void discard32(int len)
-{
- nvdbg("Discard %d bytes (32-bit mode)\n", len);
- for (; len > 0; len -= sizeof(uint32_t))
- {
- DM9X_DATA;
- }
-}
-
-/****************************************************************************
- * Function: write8, write16, write32
- *
- * Description:
- * Write packet data into the DM90x0 SRAM based on its current I/O mode
- *
- * Parameters:
- * ptr - Location to write the packet data
- * len - The number of bytes to read
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void write8(const uint8_t *ptr, int len)
-{
- nvdbg("Write %d bytes (8-bit mode)\n", len);
- for (; len > 0; len--)
- {
- DM9X_DATA = (*ptr++ & 0xff);
- }
-}
-
-static void write16(const uint8_t *ptr, int len)
-{
- register uint16_t *ptr16 = (uint16_t*)ptr;
- nvdbg("Write %d bytes (16-bit mode)\n", len);
-
- for (; len > 0; len -= sizeof(uint16_t))
- {
- DM9X_DATA = *ptr16++;
- }
-}
-
-static void write32(const uint8_t *ptr, int len)
-{
- register uint32_t *ptr32 = (uint32_t*)ptr;
- nvdbg("Write %d bytes (32-bit mode)\n", len);
- for (; len > 0; len -= sizeof(uint32_t))
- {
- DM9X_DATA = *ptr32++;
- }
-}
-
-/****************************************************************************
- * Function: dm9x_readsrom
- *
- * Description:
- * Read a word from SROM
- *
- * Parameters:
- * dm9x - Reference to the driver state structure
- * offset - SROM offset to read from
- *
- * Returned Value:
- * SROM content at that offset
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#if 0 /* Not used */
-static uint16_t dm9x_readsrom(struct dm9x_driver_s *dm9x, int offset)
-{
- putreg(DM9X_EEPHYA, offset);
- putreg(DM9X_EEPHYC, DM9X_EEPHYC_ERPRR);
- up_udelay(200);
- putreg(DM9X_EEPHYC, 0x00);
- return (getreg(DM9X_EEPHYDL) + (getreg(DM9X_EEPHYDH) << 8) );
-}
-#endif
-
-/****************************************************************************
- * Function: dm9x_phyread and dm9x_phywrite
- *
- * Description:
- * Read/write data from/to the PHY
- *
- * Parameters:
- * dm9x - Reference to the driver state structure
- * reg - PHY register offset
- * value - The value to write to the PHY register (dm9x_write only)
- *
- * Returned Value:
- * The value read from the PHY (dm9x_read only)
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static uint16_t dm9x_phyread(struct dm9x_driver_s *dm9x, int reg)
-{
- /* Setup DM9X_EEPHYA, the EEPROM/PHY address register */
-
- putreg(DM9X_EEPHYA, DM9X_EEPHYA_EROA | reg);
-
- /* Issue PHY read command pulse in the EEPROM/PHY control register */
-
- putreg(DM9X_EEPHYC, (DM9X_EEPHYC_ERPRR|DM9X_EEPHYC_EPOS));
- up_udelay(100);
- putreg(DM9X_EEPHYC, 0x00);
-
- /* Return the data from the EEPROM/PHY data register pair */
-
- return (((uint16_t)getreg(DM9X_EEPHYDH)) << 8) | (uint16_t)getreg(DM9X_EEPHYDL);
-}
-
-static void dm9x_phywrite(struct dm9x_driver_s *dm9x, int reg, uint16_t value)
-{
- /* Setup DM9X_EEPHYA, the EEPROM/PHY address register */
-
- putreg(DM9X_EEPHYA, DM9X_EEPHYA_EROA | reg);
-
- /* Put the data to write in the EEPROM/PHY data register pair */
-
- putreg(DM9X_EEPHYDL, (value & 0xff));
- putreg(DM9X_EEPHYDH, ((value >> 8) & 0xff));
-
- /* Issue PHY write command pulse in the EEPROM/PHY control register */
-
- putreg(DM9X_EEPHYC, (DM9X_EEPHYC_ERPRW|DM9X_EEPHYC_EPOS));
- up_udelay(500);
- putreg(DM9X_EEPHYC, 0x0);
-}
-
-/****************************************************************************
- * Function: dm9x_resetstatistics
- *
- * Description:
- * Reset all DM90x0 statistics
- *
- * Parameters:
- * dm9x - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#if defined(CONFIG_DM9X_STATS)
-static void dm9x_resetstatistics(struct dm9x_driver_s *dm9x)
-{
- dm9x->dm_ntxpackets = 0; /* Count of packets sent */
- dm9x->dm_ntxbytes = 0; /* Count of bytes sent */
- dm9x->dm_ntxerrors = 0; /* Count of TX errors */
- dm9x->dm_nrxpackets = 0; /* Count of packets received */
- dm9x->dm_nrxbytes = 0; /* Count of bytes received */
- dm9x->dm_nrxfifoerrors = 0; /* Count of RX FIFO overflow errors */
- dm9x->dm_nrxcrcerrors = 0; /* Count of RX CRC errors */
- dm9x->dm_nrxlengtherrors = 0; /* Count of RX length errors */
- dm9x->dm_nphyserrors = 0; /* Count of physical layer errors */
- dm9x->dm_nresets = 0; /* Counts number of resets */
- dm9x->dm_ntxtimeouts = 0; /* Counts resets caused by TX timeouts */
-}
-#endif
-
-/****************************************************************************
- * Function: dm9x_dumpstatistics
- *
- * Description:
- * Print the current value of all DM90x0 statistics
- *
- * Parameters:
- * dm9x - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#if defined(CONFIG_DM9X_STATS) && defined(CONFIG_DEBUG)
-static void dm9x_dumpstatistics(struct dm9x_driver_s *dm9x)
-{
- ndbg("TX packets: %d\n", dm9x->dm_ntxpackets);
- ndbg(" bytes: %d\n", dm9x->dm_ntxbytes);
- ndbg(" errors: %d\n", dm9x->dm_ntxerrors);
- ndbg("RX packets: %d\n", dm9x->dm_nrxpackets);
- ndbg(" bytes: %d\n", dm9x->dm_nrxbytes);
- ndbg(" FIFO overflows: %d\n", dm9x->dm_nrxfifoerrors);
- ndbg(" CRC errors: %d\n", dm9x->dm_nrxcrcerrors);
- ndbg(" length errors: %d\n", dm9x->dm_nrxlengtherrors);
- ndbg("Physical layer errors: %d\n", dm9x->dm_nphyserrors);
- ndbg("Resets: %d\n", dm9x->dm_nresets);
- ndbg("TX timeout resets: %d\n", dm9x->dm_ntxtimeouts);
-}
-#endif
-
-/****************************************************************************
- * Function: dm9x_rxchecksumready
- *
- * Description:
- * Return true if the RX checksum is available
- *
- * Parameters:
- * rxbyte
- *
- * Returned Value:
- * true: checksum is ready
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#if defined(CONFIG_DM9X_CHECKSUM)
-static inline bool dm9x_rxchecksumready(uint8_t rxbyte)
-{
- if ((rxbyte & 0x01) == 0)
- {
- return false;
- }
-
- return ((rxbyte >> 4) | 0x01) != 0;
-}
-#endif
-
-/****************************************************************************
- * Function: dm9x_transmit
- *
- * Description:
- * Start hardware transmission. Called either from the txdone interrupt
- * handling or from watchdog based polling.
- *
- * Parameters:
- * dm9x - Reference to the driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int dm9x_transmit(struct dm9x_driver_s *dm9x)
-{
- /* Check if there is room in the DM90x0 to hold another packet. In 100M mode,
- * that can be 2 packets, otherwise it is a single packet.
- */
-
- if (dm9x->dm_ntxpending < 1 || (dm9x->dm_b100M && dm9x->dm_ntxpending < 2))
- {
- /* Increment count of packets transmitted */
-
- dm9x->dm_ntxpending++;
-#if defined(CONFIG_DM9X_STATS)
- dm9x->dm_ntxpackets++;
- dm9x->dm_ntxbytes += dm9x->dm_dev.d_len;
-#endif
-
- /* Disable all DM90x0 interrupts */
-
- putreg(DM9X_IMR, DM9X_IMRDISABLE);
-
- /* Set the TX length */
-
- putreg(DM9X_TXPLL, (dm9x->dm_dev.d_len & 0xff));
- putreg(DM9X_TXPLH, (dm9x->dm_dev.d_len >> 8) & 0xff);
-
- /* Move the data to be sent into TX SRAM */
-
- DM9X_INDEX = DM9X_MWCMD;
- dm9x->dm_write(dm9x->dm_dev.d_buf, dm9x->dm_dev.d_len);
-
-#if !defined(CONFIG_DM9X_ETRANS)
- /* Issue TX polling command */
-
- putreg(DM9X_TXC, 0x1); /* Cleared after TX complete*/
-#endif
-
- /* Clear count of back-to-back RX packet transfers */
-
- dm9x->ncrxpackets = 0;
-
- /* Re-enable DM90x0 interrupts */
-
- putreg(DM9X_IMR, DM9X_IMRENABLE);
-
- /* Setup the TX timeout watchdog (perhaps restarting the timer) */
-
- (void)wd_start(dm9x->dm_txtimeout, DM6X_TXTIMEOUT, dm9x_txtimeout, 1, (uint32_t)dm9x);
- return OK;
- }
- return -EBUSY;
-}
-
-/****************************************************************************
- * Function: dm9x_uiptxpoll
- *
- * Description:
- * The transmitter is available, check if uIP has any outgoing packets ready
- * to send. This is a callback from uip_poll(). uip_poll() may be called:
- *
- * 1. When the preceding TX packet send is complete,
- * 2. When the preceding TX packet send timesout and the DM90x0 is reset
- * 3. During normal TX polling
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int dm9x_uiptxpoll(struct uip_driver_s *dev)
-{
- struct dm9x_driver_s *dm9x = (struct dm9x_driver_s *)dev->d_private;
-
- /* If the polling resulted in data that should be sent out on the network,
- * the field d_len is set to a value > 0.
- */
-
- if (dm9x->dm_dev.d_len > 0)
- {
- uip_arp_out(&dm9x->dm_dev);
- dm9x_transmit(dm9x);
-
- /* Check if there is room in the DM90x0 to hold another packet. In 100M mode,
- * that can be 2 packets, otherwise it is a single packet.
- */
-
- if (dm9x->dm_ntxpending > 1 || !dm9x->dm_b100M)
- {
- /* Returning a non-zero value will terminate the poll operation */
-
- return 1;
- }
- }
-
- /* If zero is returned, the polling will continue until all connections have
- * been examined.
- */
-
- return 0;
-}
-
-/****************************************************************************
- * Function: dm9x_receive
- *
- * Description:
- * An interrupt was received indicating the availability of a new RX packet
- *
- * Parameters:
- * dm9x - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void dm9x_receive(struct dm9x_driver_s *dm9x)
-{
- union rx_desc_u rx;
- bool bchecksumready;
- uint8_t mdrah;
- uint8_t mdral;
- uint8_t rxbyte;
-
- nvdbg("Packet received\n");
-
- do
- {
- /* Store the value of memory data read address register */
-
- mdrah = getreg(DM9X_MDRAH);
- mdral = getreg(DM9X_MDRAL);
-
- getreg(DM9X_MRCMDX); /* Dummy read */
- rxbyte = (uint8_t)DM9X_DATA; /* Get the most up-to-date data */
-
- /* Packet ready for receive check */
-
- bchecksumready = dm9x_rxchecksumready(rxbyte);
- if (!bchecksumready)
- {
- break;
- }
-
- /* A packet is ready now. Get status/length */
-
- DM9X_INDEX = DM9X_MRCMD; /* set read ptr ++ */
-
- /* Read packet status & length */
-
- dm9x->dm_read((uint8_t*)&rx, 4);
-
- /* Check if any errors were reported by the hardware */
-
- if (rx.desc.rx_status & 0xbf)
- {
- /* Bad RX packet... update statistics */
-
-#if defined(CONFIG_DM9X_STATS)
- if (rx.desc.rx_status & 0x01)
- {
- dm9x->dm_nrxfifoerrors++;
- ndbg("RX FIFO error: %d\n", dm9x->dm_nrxfifoerrors);
- }
-
- if (rx.desc.rx_status & 0x02)
- {
- dm9x->dm_nrxcrcerrors++;
- ndbg("RX CRC error: %d\n", dm9x->dm_nrxcrcerrors);
- }
-
- if (rx.desc.rx_status & 0x80)
- {
- dm9x->dm_nrxlengtherrors++;
- ndbg("RX length error: %d\n", dm9x->dm_nrxlengtherrors);
- }
-
- if (rx.desc.rx_status & 0x08)
- {
- dm9x->dm_nphyserrors++;
- ndbg("Physical Layer error: %d\n", dm9x->dm_nphyserrors);
- }
-#else
- ndbg("Received packet with errors: %02x\n", rx.desc.rx_status);
-#endif
- /* Drop this packet and continue to check the next packet */
-
- dm9x->dm_discard(rx.desc.rx_len);
- }
-
- /* Also check if the packet is a valid size for the uIP configuration */
-
- else if (rx.desc.rx_len < UIP_LLH_LEN || rx.desc.rx_len > (CONFIG_NET_BUFSIZE + 2))
- {
-#if defined(CONFIG_DM9X_STATS)
- dm9x->dm_nrxlengtherrors++;
- ndbg("RX length error: %d\n", dm9x->dm_nrxlengtherrors);
-#endif
- /* Drop this packet and continue to check the next packet */
-
- dm9x->dm_discard(rx.desc.rx_len);
- }
- else
- {
- /* Good packet... Copy the packet data out of SRAM and pass it one to uIP */
-
- dm9x->dm_dev.d_len = rx.desc.rx_len;
- dm9x->dm_read(dm9x->dm_dev.d_buf, rx.desc.rx_len);
-
- /* We only accept IP packets of the configured type and ARP packets */
-
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
-#else
- if (BUF->type == HTONS(UIP_ETHTYPE_IP))
-#endif
- {
- uip_arp_ipin(&dm9x->dm_dev);
- uip_input(&dm9x->dm_dev);
-
- /* If the above function invocation resulted in data that should be
- * sent out on the network, the field d_len will set to a value > 0.
- */
-
- if (dm9x->dm_dev.d_len > 0)
- {
- uip_arp_out(&dm9x->dm_dev);
- dm9x_transmit(dm9x);
- }
- }
- else if (BUF->type == htons(UIP_ETHTYPE_ARP))
- {
- uip_arp_arpin(&dm9x->dm_dev);
-
- /* If the above function invocation resulted in data that should be
- * sent out on the network, the field d_len will set to a value > 0.
- */
-
- if (dm9x->dm_dev.d_len > 0)
- {
- dm9x_transmit(dm9x);
- }
- }
- }
-
-#if defined(CONFIG_DM9X_STATS)
- dm9x->dm_nrxpackets++;
- dm9x->dm_nrxbytes += rx.desc.rx_len;
-#endif
- dm9x->ncrxpackets++;
- }
- while ((rxbyte & 0x01) == DM9X_PKTRDY && dm9x->ncrxpackets < DM9X_CRXTHRES);
- nvdbg("All RX packets processed\n");
-}
-
-/****************************************************************************
- * Function: dm9x_txdone
- *
- * Description:
- * An interrupt was received indicating that the last TX packet(s) is done
- *
- * Parameters:
- * dm9x - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void dm9x_txdone(struct dm9x_driver_s *dm9x)
-{
- int nsr;
-
- nvdbg("TX done\n");
-
- /* Another packet has completed transmission. Decrement the count of
- * of pending TX transmissions.
- */
-
- nsr = getreg(DM9X_NETS);
- if (nsr & DM9X_NETS_TX1END)
- {
- if (dm9x->dm_ntxpending)
- {
- dm9x->dm_ntxpending--;
- }
- else
- {
- ndbg("Bad TX count (TX1END)\n");
- }
- }
-
- if (nsr & DM9X_NETS_TX2END)
- {
- if (dm9x->dm_ntxpending)
- {
- dm9x->dm_ntxpending--;
- }
- else
- {
- ndbg("Bad TX count (TX2END)\n");
- }
- }
-
- /* Cancel the TX timeout */
-
- if (dm9x->dm_ntxpending == 0)
- {
- wd_cancel(dm9x->dm_txtimeout);
- }
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&dm9x->dm_dev, dm9x_uiptxpoll);
-}
-
-/****************************************************************************
- * Function: dm9x_interrupt
- *
- * Description:
- * DM90x0 interrupt handler
- *
- * Parameters:
- * irq - Number of the IRQ that generated the interrupt
- * context - Interrupt register state save info (architecture-specific)
- *
- * Returned Value:
- * OK on success
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int dm9x_interrupt(int irq, FAR void *context)
-{
-#if CONFIG_DM9X_NINTERFACES == 1
- register struct dm9x_driver_s *dm9x = &g_dm9x[0];
-#else
-# error "Additional logic needed to support multiple interfaces"
-#endif
- uint8_t isr;
- uint8_t save;
- int i;
-
- /* Save previous register address */
-
- save = (uint8_t)DM9X_INDEX;
-
- /* Disable all DM90x0 interrupts */
-
- putreg(DM9X_IMR, DM9X_IMRDISABLE);
-
- /* Get and clear the DM90x0 interrupt status bits */
-
- isr = getreg(DM9X_ISR);
- putreg(DM9X_ISR, isr);
- nvdbg("Interrupt status: %02x\n", isr);
-
- /* Check for link status change */
-
- if (isr & DM9X_INT_LNKCHG)
- {
- /* Wait up to 0.5s for link OK */
-
- for (i = 0; i < 500; i++)
- {
- dm9x_phyread(dm9x,0x1);
- if (dm9x_phyread(dm9x,0x1) & 0x4) /*Link OK*/
- {
- /* Wait to get detected speed */
-
- for (i = 0; i < 200; i++)
- {
- up_mdelay(1);
- }
-
- /* Set the new network speed */
-
- if (dm9x_phyread(dm9x, 0) & 0x2000)
- {
- dm9x->dm_b100M = true;
- }
- else
- {
- dm9x->dm_b100M = false;
- }
- break;
- }
- up_mdelay(1);
- }
- ndbg("delay: %dmS speed: %s\n", i, dm9x->dm_b100M ? "100M" : "10M");
- }
-
- /* Check if we received an incoming packet */
-
- if (isr & DM9X_INT_PR)
- {
- dm9x_receive(dm9x);
- }
-
- /* Check if we are able to transmit a packet */
-
- if (isr & DM9X_INT_PT)
- {
- dm9x_txdone(dm9x);
- }
-
- /* If the number of consecutive receive packets exceeds a threshold,
- * then disable the RX interrupt.
- */
-
- if (dm9x->ncrxpackets >= DM9X_CRXTHRES)
- {
- /* Eanble all DM90x0 interrupts EXCEPT for RX */
-
- putreg(DM9X_IMR, DM9X_IMRRXDISABLE);
- }
- else
- {
- /* Enable all DM90x0 interrupts */
-
- putreg(DM9X_IMR, DM9X_IMRENABLE);
- }
-
- /* Restore previous register address */
-
- DM9X_INDEX = save;
- return OK;
-}
-
-/****************************************************************************
- * Function: dm9x_txtimeout
- *
- * Description:
- * Our TX watchdog timed out. Called from the timer interrupt handler.
- * The last TX never completed. Reset the DM90x0 and start again.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void dm9x_txtimeout(int argc, uint32_t arg, ...)
-{
- struct dm9x_driver_s *dm9x = (struct dm9x_driver_s *)arg;
-
- ndbg("TX timeout\n");
-
- /* Increment statistics and dump debug info */
-
-#if defined(CONFIG_DM9X_STATS)
- dm9x->dm_ntxtimeouts++;
- dm9x->dm_ntxerrors++;
-#endif
-
- ndbg(" TX packet count: %d\n", dm9x->dm_ntxpending);
-#if defined(CONFIG_DM9X_STATS)
- ndbg(" TX timeouts: %d\n", dm9x->dm_ntxtimeouts);
-#endif
- ndbg(" TX read pointer address: 0x%02x:%02x\n",
- getreg(DM9X_TRPAH), getreg(DM9X_TRPAL));
- ndbg(" Memory data write address: 0x%02x:%02x (DM9010)\n",
- getreg(DM9X_MDWAH), getreg(DM9X_MDWAL));
-
- /* Then reset the DM90x0 */
-
- dm9x_reset(dm9x);
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&dm9x->dm_dev, dm9x_uiptxpoll);
-}
-
-/****************************************************************************
- * Function: dm9x_polltimer
- *
- * Description:
- * Periodic timer handler. Called from the timer interrupt handler.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void dm9x_polltimer(int argc, uint32_t arg, ...)
-{
- struct dm9x_driver_s *dm9x = (struct dm9x_driver_s *)arg;
-
- /* If the number of contiguous RX packets exceeds a threshold, reset the counter and
- * re-enable RX interrupts
- */
-
- if (dm9x->ncrxpackets >= DM9X_CRXTHRES)
- {
- dm9x->ncrxpackets = 0;
- putreg(DM9X_IMR, DM9X_IMRENABLE);
- }
-
- /* Check if there is room in the DM90x0 to hold another packet. In 100M mode,
- * that can be 2 packets, otherwise it is a single packet.
- */
-
- if (dm9x->dm_ntxpending < 1 || (dm9x->dm_b100M && dm9x->dm_ntxpending < 2))
- {
- /* If so, update TCP timing states and poll uIP for new XMIT data */
-
- (void)uip_timer(&dm9x->dm_dev, dm9x_uiptxpoll, DM6X_POLLHSEC);
- }
-
- /* Setup the watchdog poll timer again */
-
- (void)wd_start(dm9x->dm_txpoll, DM6X_WDDELAY, dm9x_polltimer, 1, arg);
-}
-
-/****************************************************************************
- * Function: dm9x_phymode
- *
- * Description:
- * Configure the PHY operating mode
- *
- * Parameters:
- * dm9x - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static inline void dm9x_phymode(struct dm9x_driver_s *dm9x)
-{
- uint16_t phyreg0;
- uint16_t phyreg4;
-
-#if CONFIG_DM9X_MODE == DM9X_MODE_AUTO
- phyreg0 = 0x1200; /* Auto-negotiation & Restart Auto-negotiation */
- phyreg4 = 0x01e1; /* Default flow control disable*/
-#elif CONFIG_DM9X_MODE == DM9X_MODE_10MHD
- phyreg4 = 0x21;
- phyreg0 = 0x1000;
-#elif CONFIG_DM9X_MODE == DM9X_MODE_10MFD
- phyreg4 = 0x41;
- phyreg0 = 0x1100;
-#elif CONFIG_DM9X_MODE == DM9X_MODE_100MHD
- phyreg4 = 0x81;
- phyreg0 = 0x3000;
-#elif CONFIG_DM9X_MODE == DM9X_MODE_100MFD
- phyreg4 = 0x101;
- phyreg0 = 0x3100;
-#else
-# error "Recognized PHY mode"
-#endif
-
- dm9x_phywrite(dm9x, 0, phyreg0);
- dm9x_phywrite(dm9x, 4, phyreg4);
-}
-
-/****************************************************************************
- * Function: dm9x_ifup
- *
- * Description:
- * NuttX Callback: Bring up the DM90x0 interface when an IP address is
- * provided
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int dm9x_ifup(struct uip_driver_s *dev)
-{
- struct dm9x_driver_s *dm9x = (struct dm9x_driver_s *)dev->d_private;
- uint8_t netstatus;
- int i;
-
- ndbg("Bringing up: %d.%d.%d.%d\n",
- dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
- (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
-
- /* Initilize DM90x0 chip */
-
- dm9x_bringup(dm9x);
-
- /* Check link state and media speed (waiting up to 3s for link OK) */
-
- dm9x->dm_b100M = false;
- for (i = 0; i < 3000; i++)
- {
- netstatus = getreg(DM9X_NETS);
- if (netstatus & DM9X_NETS_LINKST)
- {
- /* Link OK... Wait a bit before getting the detected speed */
-
- up_mdelay(200);
- netstatus = getreg(DM9X_NETS);
- if ((netstatus & DM9X_NETS_SPEED) == 0)
- {
- dm9x->dm_b100M = true;
- }
- break;
- }
- i++;
- up_mdelay(1);
- }
-
- ndbg("delay: %dmS speed: %s\n", i, dm9x->dm_b100M ? "100M" : "10M");
-
- /* Set and activate a timer process */
-
- (void)wd_start(dm9x->dm_txpoll, DM6X_WDDELAY, dm9x_polltimer, 1, (uint32_t)dm9x);
-
- /* Enable the DM9X interrupt */
-
- dm9x->dm_bifup = true;
- up_enable_irq(CONFIG_DM9X_IRQ);
- return OK;
-}
-
-/****************************************************************************
- * Function: dm9x_ifdown
- *
- * Description:
- * NuttX Callback: Stop the interface.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int dm9x_ifdown(struct uip_driver_s *dev)
-{
- struct dm9x_driver_s *dm9x = (struct dm9x_driver_s *)dev->d_private;
- irqstate_t flags;
-
- ndbg("Stopping\n");
-
- /* Disable the DM9X interrupt */
-
- flags = irqsave();
- up_disable_irq(CONFIG_DM9X_IRQ);
-
- /* Cancel the TX poll timer and TX timeout timers */
-
- wd_cancel(dm9x->dm_txpoll);
- wd_cancel(dm9x->dm_txtimeout);
-
- /* Reset the device */
-
- dm9x_phywrite(dm9x, 0x00, 0x8000); /* PHY reset */
- putreg(DM9X_GPD, 0x01); /* Power-down PHY (GEPIO0=1) */
- putreg(DM9X_IMR, DM9X_IMRDISABLE); /* Disable all interrupts */
- putreg(DM9X_RXC, 0x00); /* Disable RX */
- putreg(DM9X_ISR, DM9X_INT_ALL); /* Clear interrupt status */
-
- dm9x->dm_bifup = false;
- irqrestore(flags);
-
- /* Dump statistics */
-
- dm9x_dumpstatistics(dm9x);
- return OK;
-}
-
-/****************************************************************************
- * Function: dm9x_txavail
- *
- * Description:
- * Driver callback invoked when new TX data is available. This is a
- * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
- * latency.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Called in normal user mode
- *
- ****************************************************************************/
-
-static int dm9x_txavail(struct uip_driver_s *dev)
-{
- struct dm9x_driver_s *dm9x = (struct dm9x_driver_s *)dev->d_private;
- irqstate_t flags;
-
- ndbg("Polling\n");
- flags = irqsave();
-
- /* Ignore the notification if the interface is not yet up */
-
- if (dm9x->dm_bifup)
- {
-
- /* Check if there is room in the DM90x0 to hold another packet. In 100M
- * mode, that can be 2 packets, otherwise it is a single packet.
- */
-
- if (dm9x->dm_ntxpending < 1 || (dm9x->dm_b100M && dm9x->dm_ntxpending < 2))
- {
- /* If so, then poll uIP for new XMIT data */
-
- (void)uip_poll(&dm9x->dm_dev, dm9x_uiptxpoll);
- }
- }
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Function: dm9x_addmac
- *
- * Description:
- * NuttX Callback: Add the specified MAC address to the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be added
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int dm9x_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct dm9x_driver_s *priv = (FAR struct dm9x_driver_s *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
-#warning "Multicast MAC support not implemented"
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Function: dm9x_rmmac
- *
- * Description:
- * NuttX Callback: Remove the specified MAC address from the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be removed
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int dm9x_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct dm9x_driver_s *priv = (FAR struct dm9x_driver_s *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
-#warning "Multicast MAC support not implemented"
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Function: dm9x_bringup
- *
- * Description:
- * Initialize the dm90x0 chip
- *
- * Parameters:
- * dm9x - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void dm9x_bringup(struct dm9x_driver_s *dm9x)
-{
- ndbg("Initializing\n");
-
- /* Set the internal PHY power-on, GPIOs normal, and wait 2ms */
-
- putreg(DM9X_GPD, 0x01); /* Power-down the PHY (GEPIO0=1) */
- up_udelay(500);
- putreg(DM9X_GPD, 0x00); /* Preactivate PHY (GPIO0=0 */
- up_udelay(20); /* Wait 20us for PHY power-on ready */
-
- /* Do a software reset and wait 20us (twice). The reset autoclears
- * in 10us; 20us guarantees completion of the reset
- */
-
- putreg(DM9X_NETC, (DM9X_NETC_RST|DM9X_NETC_LBK1));
- up_udelay(20);
- putreg(DM9X_NETC, (DM9X_NETC_RST|DM9X_NETC_LBK1));
- up_udelay(20);
-
- /* Configure I/O mode */
-
- switch (getreg(DM9X_ISR) & DM9X_ISR_IOMODEM)
- {
- case DM9X_ISR_IOMODE8:
- dm9x->dm_read = read8;
- dm9x->dm_write = write8;
- dm9x->dm_discard = discard8;
- break;
-
- case DM9X_ISR_IOMODE16:
- dm9x->dm_read = read16;
- dm9x->dm_write = write16;
- dm9x->dm_discard = discard16;
- break;
-
- case DM9X_ISR_IOMODE32:
- dm9x->dm_read = read32;
- dm9x->dm_write = write32;
- dm9x->dm_discard = discard32;
- break;
-
- default:
- break;
- }
-
- /* Program PHY operating mode */
-
- dm9x_phymode(dm9x);
-
- /* Program operating mode */
-
- putreg(DM9X_NETC, 0x00); /* Network control */
- putreg(DM9X_TXC, 0x00); /* Clear TX Polling */
- putreg(DM9X_BPTHRES, 0x3f); /* Less 3kb, 600us */
- putreg(DM9X_SMODEC, 0x00); /* Special mode */
- putreg(DM9X_NETS, (DM9X_NETS_WAKEST|DM9X_NETS_TX1END|DM9X_NETS_TX2END)); /* Clear TX status */
- putreg(DM9X_ISR, DM9X_INT_ALL); /* Clear interrupt status */
-
-#if defined(CONFIG_DM9X_CHECKSUM)
- putreg(DM9X_TCCR, 0x07); /* TX UDP/TCP/IP checksum enable */
- putreg(DM9X_RCSR, 0x02); /* Receive checksum enable */
-#endif
-
-#if defined(CONFIG_DM9X_ETRANS)
- putreg(DM9X_ETXCSR, 0x83);
-#endif
-
- /* Initialize statistics */
-
- dm9x->ncrxpackets = 0; /* Number of continuous RX packets */
- dm9x->dm_ntxpending = 0; /* Number of pending TX packets */
- dm9x_resetstatistics(dm9x);
-
- /* Activate DM9000A/DM9010 */
-
- putreg(DM9X_RXC, DM9X_RXCSETUP | 1); /* RX enable */
- putreg(DM9X_IMR, DM9X_IMRENABLE); /* Enable TX/RX interrupts */
-}
-
-/****************************************************************************
- * Function: dm9x_reset
- *
- * Description:
- * Stop, reset, re-initialize, and restart the DM90x0 chip and driver. At
- * present, the chip is only reset after a TX timeout.
- *
- * Parameters:
- * dm9x - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void dm9x_reset(struct dm9x_driver_s *dm9x)
-{
- uint8_t save;
- int i;
-
- /* Cancel the TX poll timer and TX timeout timers */
-
- wd_cancel(dm9x->dm_txpoll);
- wd_cancel(dm9x->dm_txtimeout);
-
- /* Save previous register address */
-
- save = (uint8_t)DM9X_INDEX;
-
-#if defined(CONFIG_DM9X_STATS)
- dm9x->dm_nresets++;
-#endif
- dm9x_bringup(dm9x);
-
- /* Wait up to 1 second for the link to be OK */
-
- dm9x->dm_b100M = false;
- for (i = 0; i < 1000; i++)
- {
- if (dm9x_phyread(dm9x,0x1) & 0x4)
- {
- if (dm9x_phyread(dm9x, 0) &0x2000)
- {
- dm9x->dm_b100M = true;
- }
- break;
- }
- up_mdelay(1);
- }
-
- /* Restore previous register address */
-
- DM9X_INDEX = save;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: dm9x_initialize
- *
- * Description:
- * Initialize the DM90x0 driver
- *
- * Parameters:
- * None
- *
- * Returned Value:
- * OK on success; Negated errno on failure.
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-/* Initialize the DM90x0 chip and driver */
-
-int dm9x_initialize(void)
-{
- uint8_t *mptr;
- uint16_t vid;
- uint16_t pid;
- int i;
- int j;
-
- /* Get the chip vendor ID and product ID */
-
- vid = (((uint16_t)getreg(DM9X_VIDH)) << 8) | (uint16_t)getreg(DM9X_VIDL);
- pid = (((uint16_t)getreg(DM9X_PIDH)) << 8) | (uint16_t)getreg(DM9X_PIDL);
- nlldbg("I/O base: %08x VID: %04x PID: %04x\n", CONFIG_DM9X_BASE, vid, pid);
-
- /* Check if a DM90x0 chip is recognized at this I/O base */
-
- if (vid != DM9X_DAVICOMVID || (pid != DM9X_DM9000PID && pid != DM9X_DM9010PID))
- {
- nlldbg("DM90x0 vendor/product ID not found at this base address\n");
- return -ENODEV;
- }
-
- /* Attach the IRQ to the driver */
-
- if (irq_attach(CONFIG_DM9X_IRQ, dm9x_interrupt))
- {
- /* We could not attach the ISR to the ISR */
-
- nlldbg("irq_attach() failed\n");
- return -EAGAIN;
- }
-
- /* Initialize the driver structure */
-
- memset(g_dm9x, 0, CONFIG_DM9X_NINTERFACES*sizeof(struct dm9x_driver_s));
- g_dm9x[0].dm_dev.d_ifup = dm9x_ifup; /* I/F down callback */
- g_dm9x[0].dm_dev.d_ifdown = dm9x_ifdown; /* I/F up (new IP address) callback */
- g_dm9x[0].dm_dev.d_txavail = dm9x_txavail; /* New TX data callback */
-#ifdef CONFIG_NET_IGMP
- g_dm9x[0].dm_dev.d_addmac = dm9x_addmac; /* Add multicast MAC address */
- g_dm9x[0].dm_dev.d_rmmac = dm9x_rmmac; /* Remove multicast MAC address */
-#endif
- g_dm9x[0].dm_dev.d_private = (void*)g_dm9x; /* Used to recover private state from dev */
-
- /* Create a watchdog for timing polling for and timing of transmisstions */
-
- g_dm9x[0].dm_txpoll = wd_create(); /* Create periodic poll timer */
- g_dm9x[0].dm_txtimeout = wd_create(); /* Create TX timeout timer */
-
- /* Read the MAC address */
-
- mptr = g_dm9x[0].dm_dev.d_mac.ether_addr_octet;
- for (i = 0, j = DM9X_PAB0; i < ETHER_ADDR_LEN; i++, j++)
- {
- mptr[i] = getreg(j);
- }
-
- nlldbg("MAC: %0x:%0x:%0x:%0x:%0x:%0x\n",
- mptr[0], mptr[1], mptr[2], mptr[3], mptr[4], mptr[5]);
-
- /* Register the device with the OS so that socket IOCTLs can be performed */
-
- (void)netdev_register(&g_dm9x[0].dm_dev);
- return OK;
-}
-
-#endif /* CONFIG_NET && CONFIG_NET_DM90x0 */
-
diff --git a/nuttx/drivers/net/e1000.c b/nuttx/drivers/net/e1000.c
deleted file mode 100644
index cae6f39b4..000000000
--- a/nuttx/drivers/net/e1000.c
+++ /dev/null
@@ -1,1042 +0,0 @@
-/****************************************************************************
- * drivers/net/e1000.c
- *
- * Copyright (C) 2011 Yu Qiang. All rights reserved.
- * Author: Yu Qiang <yuq825@gmail.com>
- *
- * This file is a part of NuttX:
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- *
- * 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 <nuttx/config.h>
-#include <nuttx/kmalloc.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <time.h>
-#include <debug.h>
-#include <wdog.h>
-#include <errno.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include <nuttx/net/uip/uip.h>
-#include <nuttx/net/uip/uip-arp.h>
-#include <nuttx/net/uip/uip-arch.h>
-
-#include <rgmp/pmap.h>
-#include <rgmp/string.h>
-#include <rgmp/stdio.h>
-#include <rgmp/utils.h>
-#include <rgmp/arch/pci.h>
-#include <rgmp/memio.h>
-#include "e1000.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */
-
-#define E1000_WDDELAY (1*CLK_TCK)
-#define E1000_POLLHSEC (1*2)
-
-/* TX timeout = 1 minute */
-
-#define E1000_TXTIMEOUT (60*CLK_TCK)
-
-/* This is a helper pointer for accessing the contents of the Ethernet header */
-
-#define BUF ((struct uip_eth_hdr *)e1000->uip_dev.d_buf)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct tx_ring {
- struct tx_desc *desc;
- char *buf;
- int tail; // where to write desc
-};
-
-struct rx_ring {
- struct rx_desc *desc;
- char *buf;
- int head; // where to read
- int tail; // where to release free desc
- int free; // number of freed desc
-};
-
-struct e1000_dev {
- uint32_t phy_mem_base;
- uint32_t io_mem_base;
- uint32_t mem_size;
- int pci_dev_id;
- uint16_t pci_addr;
- unsigned char src_mac[6];
- unsigned char dst_mac[6];
- struct irq_action int_desc;
- struct tx_ring tx_ring;
- struct rx_ring rx_ring;
- struct e1000_dev *next;
-
- // NuttX net data
- bool bifup; /* true:ifup false:ifdown */
- WDOG_ID txpoll; /* TX poll timer */
- WDOG_ID txtimeout; /* TX timeout timer */
-
- /* This holds the information visible to uIP/NuttX */
-
- struct uip_driver_s uip_dev; /* Interface understood by uIP */
-};
-
-struct e1000_dev_head {
- struct e1000_dev *next;
-};
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static struct e1000_dev_head e1000_list = {0};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Common TX logic */
-
-static int e1000_transmit(struct e1000_dev *e1000);
-static int e1000_uiptxpoll(struct uip_driver_s *dev);
-
-/* Interrupt handling */
-
-static void e1000_receive(struct e1000_dev *e1000);
-
-/* Watchdog timer expirations */
-
-static void e1000_polltimer(int argc, uint32_t arg, ...);
-static void e1000_txtimeout(int argc, uint32_t arg, ...);
-
-/* NuttX callback functions */
-
-static int e1000_ifup(struct uip_driver_s *dev);
-static int e1000_ifdown(struct uip_driver_s *dev);
-static int e1000_txavail(struct uip_driver_s *dev);
-#ifdef CONFIG_NET_IGMP
-static int e1000_addmac(struct uip_driver_s *dev, const uint8_t *mac);
-static int e1000_rmmac(struct uip_driver_s *dev, const uint8_t *mac);
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-static inline void e1000_outl(struct e1000_dev *dev, int reg, uint32_t val)
-{
- writel(dev->io_mem_base+reg, val);
-}
-
-static inline uint32_t e1000_inl(struct e1000_dev *dev, int reg)
-{
- return readl(dev->io_mem_base+reg);
-}
-
-/****************************** e1000 driver ********************************/
-
-void e1000_reset(struct e1000_dev *dev)
-{
- uint32_t dev_control;
-
- // Reset the network controller hardware
- dev_control = 0;
- dev_control |= (1<<0); // FD-bit (Full Duplex)
- dev_control |= (0<<2); // GIOMD-bit (GIO Master Disable)
- dev_control |= (1<<3); // LRST-bit (Link Reset)
- dev_control |= (1<<6); // SLU-bit (Set Link Up)
- dev_control |= (2<<8); // SPEED=2 (1000Mbps)
- dev_control |= (0<<11); // FRCSPD-bit (Force Speed)
- dev_control |= (0<<12); // FRCDPLX-bit (Force Duplex)
- dev_control |= (0<<20); // ADVD3WUC-bit (Advertise D3 Wake Up Cap)
- dev_control |= (1<<26); // RST-bit (Device Reset)
- dev_control |= (1<<27); // RFCE-bit (Receive Flow Control Enable)
- dev_control |= (1<<28); // TFCE-bit (Transmit Flow Control Enable)
- dev_control |= (0<<30); // VME-bit (VLAN Mode Enable)
- dev_control |= (0<<31); // PHY_RST-bit (PHY Reset)
-
- e1000_outl(dev, E1000_IMC, 0xFFFFFFFF);
- e1000_outl(dev, E1000_STATUS, 0x00000000);
- e1000_outl(dev, E1000_CTRL, dev_control);
- dev_control &= ~(1<<26); // clear RST-bit (Device Reset)
- e1000_outl(dev, E1000_CTRL, dev_control);
- up_mdelay(10);
- e1000_outl(dev, E1000_CTRL_EXT, 0x001401C0);
- e1000_outl(dev, E1000_IMC, 0xFFFFFFFF);
-}
-
-void e1000_turn_on(struct e1000_dev *dev)
-{
- int tx_control, rx_control;
- uint32_t ims = 0;
-
- // turn on the controller's receive engine
- rx_control = e1000_inl(dev, E1000_RCTL);
- rx_control |= (1<<1);
- e1000_outl(dev, E1000_RCTL, rx_control);
-
- // turn on the controller's transmit engine
- tx_control = e1000_inl(dev, E1000_TCTL);
- tx_control |= (1<<1);
- e1000_outl(dev, E1000_TCTL, tx_control);
-
- // enable the controller's interrupts
- e1000_outl(dev, E1000_ICR, 0xFFFFFFFF);
- e1000_outl(dev, E1000_IMC, 0xFFFFFFFF);
-
- ims |= 1<<0; // TXDW
- ims |= 1<<1; // TXQE
- ims |= 1<<2; // LSC
- ims |= 1<<4; // RXDMT0
- ims |= 1<<7; // RXT0
- e1000_outl(dev, E1000_IMS, ims);
-}
-
-void e1000_turn_off(struct e1000_dev *dev)
-{
- int tx_control, rx_control;
-
- // turn off the controller's receive engine
- rx_control = e1000_inl(dev, E1000_RCTL);
- rx_control &= ~(1<<1);
- e1000_outl(dev, E1000_RCTL, rx_control);
-
- // turn off the controller's transmit engine
- tx_control = e1000_inl(dev, E1000_TCTL);
- tx_control &= ~(1<<1);
- e1000_outl(dev, E1000_TCTL, tx_control);
-
- // turn off the controller's interrupts
- e1000_outl(dev, E1000_IMC, 0xFFFFFFFF);
-}
-
-void e1000_init(struct e1000_dev *dev)
-{
- uint32_t rxd_phys, txd_phys, kmem_phys;
- uint32_t rx_control, tx_control;
- uint32_t pba;
- int i;
-
- e1000_reset(dev);
-
- // configure the controller's 'receive' engine
- rx_control = 0;
- rx_control |= (0<<1); // EN-bit (Enable)
- rx_control |= (0<<2); // SPB-bit (Store Bad Packets)
- rx_control |= (0<<3); // UPE-bit (Unicast Promiscuous Mode)
- rx_control |= (1<<4); // MPE-bit (Multicast Promiscuous Mode)
- rx_control |= (0<<5); // LPE-bit (Long Packet Enable)
- rx_control |= (0<<6); // LBM=0 (Loop-Back Mode)
- rx_control |= (0<<8); // RDMTS=0 (Rx Descriptor Min Threshold Size)
- rx_control |= (0<<10); // DTYPE=0 (Descriptor Type)
- rx_control |= (0<<12); // MO=0 (Multicast Offset)
- rx_control |= (1<<15); // BAM-bit (Broadcast Address Mode)
- rx_control |= (0<<16); // BSIZE=0 (Buffer Size = 2048)
- rx_control |= (0<<18); // VLE-bit (VLAN filter Enable)
- rx_control |= (0<<19); // CFIEN-bit (Canonical Form Indicator Enable)
- rx_control |= (0<<20); // CFI-bit (Canonical Form Indicator)
- rx_control |= (1<<22); // DPF-bit (Discard Pause Frames)
- rx_control |= (0<<23); // PMCF-bit (Pass MAC Control Frames)
- rx_control |= (0<<25); // BSEX=0 (Buffer Size EXtension)
- rx_control |= (1<<26); // SECRC-bit (Strip Ethernet CRC)
- rx_control |= (0<<27); // FLEXBUF=0 (Flexible Buffer size)
- e1000_outl(dev, E1000_RCTL, rx_control);
-
- // configure the controller's 'transmit' engine
- tx_control = 0;
- tx_control |= (0<<1); // EN-bit (Enable)
- tx_control |= (1<<3); // PSP-bit (Pad Short Packets)
- tx_control |= (15<<4); // CT=15 (Collision Threshold)
- tx_control |= (63<<12); // COLD=63 (Collision Distance)
- tx_control |= (0<<22); // SWXOFF-bit (Software XOFF)
- tx_control |= (1<<24); // RTLC-bit (Re-Transmit on Late Collision)
- tx_control |= (0<<25); // UNORTX-bit (Underrun No Re-Transmit)
- tx_control |= (0<<26); // TXCSCMT=0 (TxDesc Mininum Threshold)
- tx_control |= (0<<28); // MULR-bit (Multiple Request Support)
- e1000_outl(dev, E1000_TCTL, tx_control);
-
- // hardware flow control
- pba = e1000_inl(dev, E1000_PBA);
- // get receive FIFO size
- pba = (pba & 0x000000ff)<<10;
- e1000_outl(dev, E1000_FCAL, 0x00C28001);
- e1000_outl(dev, E1000_FCAH, 0x00000100);
- e1000_outl(dev, E1000_FCT, 0x00008808);
- e1000_outl(dev, E1000_FCTTV, 0x00000680);
- e1000_outl(dev, E1000_FCRTL, (pba*8/10)|0x80000000);
- e1000_outl(dev, E1000_FCRTH, pba*9/10);
-
- // setup tx rings
- txd_phys = PADDR((uintptr_t)dev->tx_ring.desc);
- kmem_phys = PADDR((uintptr_t)dev->tx_ring.buf);
- for (i=0; i<CONFIG_E1000_N_TX_DESC; i++,kmem_phys+=CONFIG_E1000_BUFF_SIZE) {
- dev->tx_ring.desc[i].base_address = kmem_phys;
- dev->tx_ring.desc[i].packet_length = 0;
- dev->tx_ring.desc[i].cksum_offset = 0;
- dev->tx_ring.desc[i].cksum_origin = 0;
- dev->tx_ring.desc[i].desc_status = 1;
- dev->tx_ring.desc[i].desc_command = (1<<0)|(1<<1)|(1<<3);
- dev->tx_ring.desc[i].special_info = 0;
- }
- dev->tx_ring.tail = 0;
- e1000_outl(dev, E1000_TDT, 0);
- e1000_outl(dev, E1000_TDH, 0);
- // tell controller the location, size, and fetch-policy for Tx queue
- e1000_outl(dev, E1000_TDBAL, txd_phys);
- e1000_outl(dev, E1000_TDBAH, 0x00000000);
- e1000_outl(dev, E1000_TDLEN, CONFIG_E1000_N_TX_DESC*16);
- e1000_outl(dev, E1000_TXDCTL, 0x01010000);
-
- // setup rx rings
- rxd_phys = PADDR((uintptr_t)dev->rx_ring.desc);
- kmem_phys = PADDR((uintptr_t)dev->rx_ring.buf);
- for (i=0; i<CONFIG_E1000_N_RX_DESC; i++,kmem_phys+=CONFIG_E1000_BUFF_SIZE) {
- dev->rx_ring.desc[i].base_address = kmem_phys;
- dev->rx_ring.desc[i].packet_length = 0;
- dev->rx_ring.desc[i].packet_cksum = 0;
- dev->rx_ring.desc[i].desc_status = 0;
- dev->rx_ring.desc[i].desc_errors = 0;
- dev->rx_ring.desc[i].vlan_tag = 0;
- }
- dev->rx_ring.head = 0;
- dev->rx_ring.tail = CONFIG_E1000_N_RX_DESC-1;
- dev->rx_ring.free = 0;
- // give the controller ownership of all receive descriptors
- e1000_outl(dev, E1000_RDH, 0);
- e1000_outl(dev, E1000_RDT, CONFIG_E1000_N_RX_DESC-1);
- // tell controller the location, size, and fetch-policy for RX queue
- e1000_outl(dev, E1000_RDBAL, rxd_phys);
- e1000_outl(dev, E1000_RDBAH, 0x00000000);
- e1000_outl(dev, E1000_RDLEN, CONFIG_E1000_N_RX_DESC*16);
- e1000_outl(dev, E1000_RXDCTL, 0x01010000);
-
- e1000_turn_on(dev);
-}
-
-/****************************************************************************
- * Function: e1000_transmit
- *
- * Description:
- * Start hardware transmission. Called either from the txdone interrupt
- * handling or from watchdog based polling.
- *
- * Parameters:
- * e1000 - Reference to the driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- * May or may not be called from an interrupt handler. In either case,
- * global interrupts are disabled, either explicitly or indirectly through
- * interrupt handling logic.
- *
- ****************************************************************************/
-
-static int e1000_transmit(struct e1000_dev *e1000)
-{
- int tail = e1000->tx_ring.tail;
- unsigned char *cp = (unsigned char *)
- (e1000->tx_ring.buf + tail * CONFIG_E1000_BUFF_SIZE);
- int count = e1000->uip_dev.d_len;
-
- /* Verify that the hardware is ready to send another packet. If we get
- * here, then we are committed to sending a packet; Higher level logic
- * must have assured that there is not transmission in progress.
- */
-
- if (!e1000->tx_ring.desc[tail].desc_status)
- return -1;
-
- /* Increment statistics */
-
- /* Send the packet: address=skel->sk_dev.d_buf, length=skel->sk_dev.d_len */
- memcpy(cp, e1000->uip_dev.d_buf, e1000->uip_dev.d_len);
-
- // prepare the transmit-descriptor
- e1000->tx_ring.desc[tail].packet_length = count<60 ? 60:count;
- e1000->tx_ring.desc[tail].desc_status = 0;
-
- // give ownership of this descriptor to the network controller
- tail = (tail + 1) % CONFIG_E1000_N_TX_DESC;
- e1000->tx_ring.tail = tail;
- e1000_outl(e1000, E1000_TDT, tail);
-
- /* Enable Tx interrupts */
-
- /* Setup the TX timeout watchdog (perhaps restarting the timer) */
-
- wd_start(e1000->txtimeout, E1000_TXTIMEOUT, e1000_txtimeout, 1, (uint32_t)e1000);
- return OK;
-}
-
-/****************************************************************************
- * Function: e1000_uiptxpoll
- *
- * Description:
- * The transmitter is available, check if uIP has any outgoing packets ready
- * to send. This is a callback from uip_poll(). uip_poll() may be called:
- *
- * 1. When the preceding TX packet send is complete,
- * 2. When the preceding TX packet send timesout and the interface is reset
- * 3. During normal TX polling
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- * May or may not be called from an interrupt handler. In either case,
- * global interrupts are disabled, either explicitly or indirectly through
- * interrupt handling logic.
- *
- ****************************************************************************/
-
-static int e1000_uiptxpoll(struct uip_driver_s *dev)
-{
- struct e1000_dev *e1000 = (struct e1000_dev *)dev->d_private;
- int tail = e1000->tx_ring.tail;
-
- /* If the polling resulted in data that should be sent out on the network,
- * the field d_len is set to a value > 0.
- */
-
- if (e1000->uip_dev.d_len > 0) {
- uip_arp_out(&e1000->uip_dev);
- e1000_transmit(e1000);
-
- /* Check if there is room in the device to hold another packet. If not,
- * return a non-zero value to terminate the poll.
- */
- if (!e1000->tx_ring.desc[tail].desc_status)
- return -1;
- }
-
- /* If zero is returned, the polling will continue until all connections have
- * been examined.
- */
-
- return 0;
-}
-
-/****************************************************************************
- * Function: e1000_receive
- *
- * Description:
- * An interrupt was received indicating the availability of a new RX packet
- *
- * Parameters:
- * e1000 - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by interrupt handling logic.
- *
- ****************************************************************************/
-
-static void e1000_receive(struct e1000_dev *e1000)
-{
- int head = e1000->rx_ring.head;
- unsigned char *cp = (unsigned char *)
- (e1000->rx_ring.buf + head * CONFIG_E1000_BUFF_SIZE);
- int cnt;
-
- while (e1000->rx_ring.desc[head].desc_status) {
-
- /* Check for errors and update statistics */
-
- // Here we do not handle packets that exceed packet-buffer size
- if ((e1000->rx_ring.desc[head].desc_status & 3) == 1) {
- cprintf("NIC READ: Oversized packet\n");
- goto next;
- }
-
- /* Check if the packet is a valid size for the uIP buffer configuration */
-
- // get the number of actual data-bytes in this packet
- cnt = e1000->rx_ring.desc[head].packet_length;
-
- if (cnt > CONFIG_NET_BUFSIZE || cnt < 14) {
- cprintf("NIC READ: invalid package size\n");
- goto next;
- }
-
- /* Copy the data data from the hardware to e1000->uip_dev.d_buf. Set
- * amount of data in e1000->uip_dev.d_len
- */
-
- // now we try to copy these data-bytes to the UIP buffer
- memcpy(e1000->uip_dev.d_buf, cp, cnt);
- e1000->uip_dev.d_len = cnt;
-
- /* We only accept IP packets of the configured type and ARP packets */
-
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
-#else
- if (BUF->type == HTONS(UIP_ETHTYPE_IP))
-#endif
- {
- uip_arp_ipin(&e1000->uip_dev);
- uip_input(&e1000->uip_dev);
-
- /* If the above function invocation resulted in data that should be
- * sent out on the network, the field d_len will set to a value > 0.
- */
-
- if (e1000->uip_dev.d_len > 0) {
- uip_arp_out(&e1000->uip_dev);
- e1000_transmit(e1000);
- }
- }
- else if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
- uip_arp_arpin(&e1000->uip_dev);
-
- /* If the above function invocation resulted in data that should be
- * sent out on the network, the field d_len will set to a value > 0.
- */
-
- if (e1000->uip_dev.d_len > 0) {
- e1000_transmit(e1000);
- }
- }
-
- next:
- e1000->rx_ring.desc[head].desc_status = 0;
- e1000->rx_ring.head = (head + 1) % CONFIG_E1000_N_RX_DESC;
- e1000->rx_ring.free++;
- head = e1000->rx_ring.head;
- cp = (unsigned char *)(e1000->rx_ring.buf + head * CONFIG_E1000_BUFF_SIZE);
- }
-}
-
-/****************************************************************************
- * Function: e1000_txtimeout
- *
- * Description:
- * Our TX watchdog timed out. Called from the timer interrupt handler.
- * The last TX never completed. Reset the hardware and start again.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by the watchdog logic.
- *
- ****************************************************************************/
-
-static void e1000_txtimeout(int argc, uint32_t arg, ...)
-{
- struct e1000_dev *e1000 = (struct e1000_dev *)arg;
-
- /* Increment statistics and dump debug info */
-
- /* Then reset the hardware */
- e1000_init(e1000);
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&e1000->uip_dev, e1000_uiptxpoll);
-}
-
-/****************************************************************************
- * Function: e1000_polltimer
- *
- * Description:
- * Periodic timer handler. Called from the timer interrupt handler.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by the watchdog logic.
- *
- ****************************************************************************/
-
-static void e1000_polltimer(int argc, uint32_t arg, ...)
-{
- struct e1000_dev *e1000 = (struct e1000_dev *)arg;
- int tail = e1000->tx_ring.tail;
-
- /* Check if there is room in the send another TX packet. We cannot perform
- * the TX poll if he are unable to accept another packet for transmission.
- */
- if (!e1000->tx_ring.desc[tail].desc_status)
- return;
-
- /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm..
- * might be bug here. Does this mean if there is a transmit in progress,
- * we will missing TCP time state updates?
- */
-
- (void)uip_timer(&e1000->uip_dev, e1000_uiptxpoll, E1000_POLLHSEC);
-
- /* Setup the watchdog poll timer again */
-
- (void)wd_start(e1000->txpoll, E1000_WDDELAY, e1000_polltimer, 1, arg);
-}
-
-/****************************************************************************
- * Function: e1000_ifup
- *
- * Description:
- * NuttX Callback: Bring up the Ethernet interface when an IP address is
- * provided
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int e1000_ifup(struct uip_driver_s *dev)
-{
- struct e1000_dev *e1000 = (struct e1000_dev *)dev->d_private;
-
- ndbg("Bringing up: %d.%d.%d.%d\n",
- dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
- (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
-
- /* Initialize PHYs, the Ethernet interface, and setup up Ethernet interrupts */
- e1000_init(e1000);
-
- /* Set and activate a timer process */
-
- (void)wd_start(e1000->txpoll, E1000_WDDELAY, e1000_polltimer, 1, (uint32_t)e1000);
-
- if (e1000_inl(e1000, E1000_STATUS) & 2)
- e1000->bifup = true;
- else
- e1000->bifup = false;
-
- return OK;
-}
-
-/****************************************************************************
- * Function: e1000_ifdown
- *
- * Description:
- * NuttX Callback: Stop the interface.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int e1000_ifdown(struct uip_driver_s *dev)
-{
- struct e1000_dev *e1000 = (struct e1000_dev *)dev->d_private;
- irqstate_t flags;
-
- /* Disable the Ethernet interrupt */
-
- flags = irqsave();
-
- e1000_turn_off(e1000);
-
- /* Cancel the TX poll timer and TX timeout timers */
-
- wd_cancel(e1000->txpoll);
- wd_cancel(e1000->txtimeout);
-
- /* Put the the EMAC is its reset, non-operational state. This should be
- * a known configuration that will guarantee the skel_ifup() always
- * successfully brings the interface back up.
- */
- //e1000_reset(e1000);
-
- /* Mark the device "down" */
-
- e1000->bifup = false;
- irqrestore(flags);
-
- return OK;
-}
-
-/****************************************************************************
- * Function: e1000_txavail
- *
- * Description:
- * Driver callback invoked when new TX data is available. This is a
- * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
- * latency.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Called in normal user mode
- *
- ****************************************************************************/
-
-static int e1000_txavail(struct uip_driver_s *dev)
-{
- struct e1000_dev *e1000 = (struct e1000_dev *)dev->d_private;
- int tail = e1000->tx_ring.tail;
- irqstate_t flags;
-
- /* Disable interrupts because this function may be called from interrupt
- * level processing.
- */
-
- flags = irqsave();
-
- /* Ignore the notification if the interface is not yet up */
-
- if (e1000->bifup) {
- /* Check if there is room in the hardware to hold another outgoing packet. */
- if (e1000->tx_ring.desc[tail].desc_status)
- (void)uip_poll(&e1000->uip_dev, e1000_uiptxpoll);
- }
-
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Function: e1000_addmac
- *
- * Description:
- * NuttX Callback: Add the specified MAC address to the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be added
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int e1000_addmac(struct uip_driver_s *dev, const uint8_t *mac)
-{
- struct e1000_dev *e1000 = (struct e1000_dev *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Function: e1000_rmmac
- *
- * Description:
- * NuttX Callback: Remove the specified MAC address from the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be removed
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int e1000_rmmac(struct uip_driver_s *dev, const uint8_t *mac)
-{
- struct e1000_dev *e1000 = (struct e1000_dev *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
- return OK;
-}
-#endif
-
-static irqreturn_t e1000_interrupt_handler(int irq, void *dev_id)
-{
- struct e1000_dev *e1000 = (struct e1000_dev *)dev_id;
-
- /* Get and clear interrupt status bits */
- int intr_cause = e1000_inl(e1000, E1000_ICR);
- e1000_outl(e1000, E1000_ICR, intr_cause);
-
- // not for me
- if (intr_cause == 0)
- return IRQ_NONE;
-
- /* Handle interrupts according to status bit settings */
-
- // Link status change
- if (intr_cause & (1<<2)) {
- if (e1000_inl(e1000, E1000_STATUS) & 2)
- e1000->bifup = true;
- else
- e1000->bifup = false;
- }
-
- /* Check if we received an incoming packet, if so, call skel_receive() */
-
- // Rx-descriptor Timer expired
- if (intr_cause & (1<<7))
- e1000_receive(e1000);
-
- // Tx queue empty
- if (intr_cause & (1<<1))
- wd_cancel(e1000->txtimeout);
-
- /* Check is a packet transmission just completed. If so, call skel_txdone.
- * This may disable further Tx interrupts if there are no pending
- * tansmissions.
- */
-
- // Tx-descriptor Written back
- if (intr_cause & (1<<0))
- uip_poll(&e1000->uip_dev, e1000_uiptxpoll);
-
-
- // Rx-Descriptors Low
- if (intr_cause & (1<<4)) {
- int tail;
- tail = e1000->rx_ring.tail + e1000->rx_ring.free;
- tail %= CONFIG_E1000_N_RX_DESC;
- e1000->rx_ring.tail = tail;
- e1000->rx_ring.free = 0;
- e1000_outl(e1000, E1000_RDT, tail);
- }
-
- return IRQ_HANDLED;
-}
-
-/******************************* PCI driver *********************************/
-
-static pci_id_t e1000_id_table[] = {
- {.sep = {INTEL_VENDERID, E1000_82573L}},
- {.sep = {INTEL_VENDERID, E1000_82540EM}},
- {.sep = {INTEL_VENDERID, E1000_82574L}},
- {.sep = {INTEL_VENDERID, E1000_82567LM}},
- {.sep = {INTEL_VENDERID, E1000_82541PI}},
- {.sep = {0,0}}
-};
-
-static int e1000_probe(uint16_t addr, pci_id_t id)
-{
- uint32_t mmio_base, mmio_size;
- uint32_t size;
- int err;
- void *kmem, *omem;
- struct e1000_dev *dev;
-
- // alloc e1000_dev memory
- if ((dev = kzalloc(sizeof(struct e1000_dev))) == NULL)
- return -1;
-
- // save pci addr
- dev->pci_addr = addr;
-
- // enable device
- if ((err = pci_enable_device(addr, PCI_BUS_MASTER)) < 0)
- goto error;
-
- // get e1000 device type
- dev->pci_dev_id = id.join;
-
- // remap the controller's i/o-memory into kernel's address-space
- mmio_base = pci_resource_start(addr, 0);
- mmio_size = pci_resource_len(addr, 0);
- err = rgmp_memmap_nocache(mmio_base, mmio_size, mmio_base);
- if (err)
- goto error;
- dev->phy_mem_base = mmio_base;
- dev->io_mem_base = mmio_base;
- dev->mem_size = mmio_size;
-
- // MAC address
- memset(dev->dst_mac, 0xFF, 6);
- memcpy(dev->src_mac, (void *)(dev->io_mem_base+E1000_RA), 6);
-
- // IRQ setup
- dev->int_desc.handler = e1000_interrupt_handler;
- dev->int_desc.dev_id = dev;
- if ((err = pci_request_irq(addr, &dev->int_desc, 0)) < 0)
- goto err0;
-
- // Here we alloc a big block of memory once and make it
- // aligned to page boundary and multiple of page size. This
- // is because the memory can be modified by E1000 DMA and
- // should be mapped no-cache which will hugely reduce memory
- // access performance. The page size alloc will restrict
- // this bad effect only within the memory we alloc here.
- //
- // NEED FIX: the memalign may alloc memory continous in
- // virtual address but dis-continous in physical address
- // due to RGMP memory setup.
- size = CONFIG_E1000_N_TX_DESC * sizeof(struct tx_desc) +
- CONFIG_E1000_N_TX_DESC * CONFIG_E1000_BUFF_SIZE +
- CONFIG_E1000_N_RX_DESC * sizeof(struct rx_desc) +
- CONFIG_E1000_N_RX_DESC * CONFIG_E1000_BUFF_SIZE;
- size = ROUNDUP(size, PGSIZE);
- omem = kmem = memalign(PGSIZE, size);
- if (kmem == NULL) {
- err = -ENOMEM;
- goto err1;
- }
- rgmp_memremap_nocache((uintptr_t)kmem, size);
-
- // alloc memory for tx ring
- dev->tx_ring.desc = (struct tx_desc*)kmem;
- kmem += CONFIG_E1000_N_TX_DESC * sizeof(struct tx_desc);
- dev->tx_ring.buf = kmem;
- kmem += CONFIG_E1000_N_TX_DESC * CONFIG_E1000_BUFF_SIZE;
-
- // alloc memory for rx rings
- dev->rx_ring.desc = (struct rx_desc*)kmem;
- kmem += CONFIG_E1000_N_RX_DESC * sizeof(struct rx_desc);
- dev->rx_ring.buf = kmem;
-
- /* Initialize the driver structure */
-
- dev->uip_dev.d_ifup = e1000_ifup; /* I/F up (new IP address) callback */
- dev->uip_dev.d_ifdown = e1000_ifdown; /* I/F down callback */
- dev->uip_dev.d_txavail = e1000_txavail; /* New TX data callback */
-#ifdef CONFIG_NET_IGMP
- dev->uip_dev.d_addmac = e1000_addmac; /* Add multicast MAC address */
- dev->uip_dev.d_rmmac = e1000_rmmac; /* Remove multicast MAC address */
-#endif
- dev->uip_dev.d_private = dev; /* Used to recover private state from dev */
-
- /* Create a watchdog for timing polling for and timing of transmisstions */
-
- dev->txpoll = wd_create(); /* Create periodic poll timer */
- dev->txtimeout = wd_create(); /* Create TX timeout timer */
-
- // Put the interface in the down state.
- // e1000 reset
- e1000_reset(dev);
-
- /* Read the MAC address from the hardware */
- memcpy(dev->uip_dev.d_mac.ether_addr_octet, (void *)(dev->io_mem_base+E1000_RA), 6);
-
- /* Register the device with the OS so that socket IOCTLs can be performed */
- err = netdev_register(&dev->uip_dev);
- if (err)
- goto err2;
-
- // insert into e1000_list
- dev->next = e1000_list.next;
- e1000_list.next = dev;
- cprintf("bring up e1000 device: %04x %08x\n", addr, id.join);
-
- return 0;
-
-err2:
- rgmp_memremap((uintptr_t)omem, size);
- free(omem);
-err1:
- pci_free_irq(addr);
-err0:
- rgmp_memunmap(mmio_base, mmio_size);
-error:
- kfree(dev);
- cprintf("e1000 device probe fail: %d\n", err);
- return err;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-void e1000_mod_init(void)
-{
- pci_probe_device(e1000_id_table, e1000_probe);
-}
-
-void e1000_mod_exit(void)
-{
- uint32_t size;
- struct e1000_dev *dev;
-
- size = CONFIG_E1000_N_TX_DESC * sizeof(struct tx_desc) +
- CONFIG_E1000_N_TX_DESC * CONFIG_E1000_BUFF_SIZE +
- CONFIG_E1000_N_RX_DESC * sizeof(struct rx_desc) +
- CONFIG_E1000_N_RX_DESC * CONFIG_E1000_BUFF_SIZE;
- size = ROUNDUP(size, PGSIZE);
-
- for (dev=e1000_list.next; dev!=NULL; dev=dev->next) {
- netdev_unregister(&dev->uip_dev);
- e1000_reset(dev);
- wd_delete(dev->txpoll);
- wd_delete(dev->txtimeout);
- rgmp_memremap((uintptr_t)dev->tx_ring.desc, size);
- free(dev->tx_ring.desc);
- pci_free_irq(dev->pci_addr);
- rgmp_memunmap((uintptr_t)dev->io_mem_base, dev->mem_size);
- kfree(dev);
- }
-
- e1000_list.next = NULL;
-}
diff --git a/nuttx/drivers/net/e1000.h b/nuttx/drivers/net/e1000.h
deleted file mode 100644
index 63ff53e3c..000000000
--- a/nuttx/drivers/net/e1000.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
- * drivers/net/e1000.h
- *
- * Copyright (C) 2011 Yu Qiang. All rights reserved.
- * Author: Yu Qiang <yuq825@gmail.com>
- *
- * This file is a part of NuttX:
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_NET_E1000_H
-#define __DRIVERS_NET_E1000_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <stdint.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/************** PCI ID ***************/
-
-#define INTEL_VENDERID 0x8086
-#define E1000_82573L 0x109a
-#define E1000_82540EM 0x100e
-#define E1000_82574L 0x10d3
-#define E1000_82567LM 0x10f5
-#define E1000_82541PI 0x107c
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-enum e1000_registers {
- E1000_CTRL = 0x0000, // Device Control
- E1000_STATUS = 0x0008, // Device Status
- E1000_CTRL_EXT = 0x0018, // Device Control Extension
- E1000_FCAL = 0x0028, // Flow Control Address Low
- E1000_FCAH = 0x002C, // Flow Control Address High
- E1000_FCT = 0x0030, // Flow Control Type
- E1000_ICR = 0x00C0, // Interrupt Cause Read
- E1000_ICS = 0x00C8, // Interrupt Cause Set
- E1000_IMS = 0x00D0, // Interrupt Mask Set
- E1000_IMC = 0x00D8, // Interrupt Mask Clear
- E1000_RCTL = 0x0100, // Receive Control
- E1000_FCTTV = 0x0170, // Flow Control Transmit Timer Value
- E1000_TCTL = 0x0400, // Transmit Control
- E1000_PBA = 0x1000, // Packet Buffer Allocation
- E1000_FCRTL = 0x2160, // Flow Control Receive Threshold Low
- E1000_FCRTH = 0x2168, // Flow Control Receive Threshold High
- E1000_RDBAL = 0x2800, // Rx Descriptor Base Address Low
- E1000_RDBAH = 0x2804, // Rx Descriptor Base Address High
- E1000_RDLEN = 0x2808, // Rx Descriptor Length
- E1000_RDH = 0x2810, // Rx Descriptor Head
- E1000_RDT = 0x2818, // Rx Descriptor Tail
- E1000_RXDCTL = 0x2828, // Rx Descriptor Control
- E1000_TDBAL = 0x3800, // Tx Descriptor Base Address Low
- E1000_TDBAH = 0x3804, // Tx Descriptor Base Address High
- E1000_TDLEN = 0x3808, // Tx Descriptor Length
- E1000_TDH = 0x3810, // Tx Descriptor Head
- E1000_TDT = 0x3818, // Tx Descriptor Tail
- E1000_TXDCTL = 0x3828, // Tx Descriptor Control
- E1000_TPR = 0x40D0, // Total Packets Received
- E1000_TPT = 0x40D4, // Total Packets Transmitted
- E1000_RA = 0x5400, // Receive-filter Array
-};
-
-/***************** e1000 device structure *****************/
-
-struct tx_desc {
- uint64_t base_address;
- uint16_t packet_length;
- uint8_t cksum_offset;
- uint8_t desc_command;
- uint8_t desc_status;
- uint8_t cksum_origin;
- uint16_t special_info;
-};
-
-struct rx_desc {
- uint64_t base_address;
- uint16_t packet_length;
- uint16_t packet_cksum;
- uint8_t desc_status;
- uint8_t desc_errors;
- uint16_t vlan_tag;
-};
-
-#endif
diff --git a/nuttx/drivers/net/enc28j60.c b/nuttx/drivers/net/enc28j60.c
deleted file mode 100644
index 203259aeb..000000000
--- a/nuttx/drivers/net/enc28j60.c
+++ /dev/null
@@ -1,2624 +0,0 @@
-/****************************************************************************
- * drivers/net/enc28j60.c
- *
- * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * - ENC28J60 Data Sheet, Stand-Alone Ethernet Controller with SPI Interface,
- * DS39662C, 2008 Microchip Technology Inc.
- *
- * 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 <nuttx/config.h>
-
-#if defined(CONFIG_NET) && defined(CONFIG_ENC28J60)
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <time.h>
-#include <string.h>
-#include <debug.h>
-#include <wdog.h>
-#include <errno.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-#include <nuttx/spi.h>
-#include <nuttx/wqueue.h>
-#include <nuttx/clock.h>
-#include <nuttx/net/enc28j60.h>
-
-#include <nuttx/net/uip/uip.h>
-#include <nuttx/net/uip/uip-arp.h>
-#include <nuttx/net/uip/uip-arch.h>
-
-#include "enc28j60.h"
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-/* Configuration ************************************************************/
-
-/* ENC28J60 Configuration Settings:
- *
- * CONFIG_ENC28J60 - Enabled ENC28J60 support
- * CONFIG_ENC28J60_SPIMODE - Controls the SPI mode
- * CONFIG_ENC28J60_FREQUENCY - Define to use a different bus frequency
- * CONFIG_ENC28J60_NINTERFACES - Specifies the number of physical ENC28J60
- * devices that will be supported.
- * CONFIG_ENC28J60_STATS - Collect network statistics
- * CONFIG_ENC28J60_HALFDUPPLEX - Default is full duplex
- */
-
-/* The ENC28J60 spec says that it supports SPI mode 0,0 only: "The
- * implementation used on this device supports SPI mode 0,0 only. In
- * addition, the SPI port requires that SCK be at Idle in a low state;
- * selectable clock polarity is not supported." However, sometimes you
- * need to tinker with these things.
- */
-
-#ifndef CONFIG_ENC28J60_SPIMODE
-# define CONFIG_ENC28J60_SPIMODE SPIDEV_MODE0
-#endif
-
-/* CONFIG_ENC28J60_NINTERFACES determines the number of physical interfaces
- * that will be supported.
- */
-
-#ifndef CONFIG_ENC28J60_NINTERFACES
-# define CONFIG_ENC28J60_NINTERFACES 1
-#endif
-
-/* CONFIG_NET_BUFSIZE must always be defined */
-
-#if !defined(CONFIG_NET_BUFSIZE) && (CONFIG_NET_BUFSIZE <= MAX_FRAMELEN)
-# error "CONFIG_NET_BUFSIZE is not valid for the ENC28J60"
-#endif
-
-/* We need to have the work queue to handle SPI interrupts */
-
-#ifndef CONFIG_SCHED_WORKQUEUE
-# error "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)"
-#endif
-
-/* CONFIG_ENC28J60_DUMPPACKET will dump the contents of each packet to the console. */
-
-#ifdef CONFIG_ENC28J60_DUMPPACKET
-# define enc_dumppacket(m,a,n) lib_dumpbuffer(m,a,n)
-#else
-# define enc_dumppacket(m,a,n)
-#endif
-
-/* The ENC28J60 will not do interrupt level processing */
-
-#ifndef CONFIG_NET_NOINTS
-# warrning "CONFIG_NET_NOINTS should be set"
-#endif
-
-/* Low-level register debug */
-
-#if !defined(CONFIG_DEBUG) || !defined(CONFIG_DEBUG_NET)
-# undef CONFIG_ENC28J60_REGDEBUG
-#endif
-
-/* Timing *******************************************************************/
-
-/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */
-
-#define ENC_WDDELAY (1*CLK_TCK)
-#define ENC_POLLHSEC (1*2)
-
-/* TX timeout = 1 minute */
-
-#define ENC_TXTIMEOUT (60*CLK_TCK)
-
-/* Poll timeout */
-
-#define ENC_POLLTIMEOUT MSEC2TICK(50)
-
-/* Packet Memory ************************************************************/
-
-/* Packet memory layout */
-
-#define ALIGNED_BUFSIZE ((CONFIG_NET_BUFSIZE + 255) & ~255)
-
-#define PKTMEM_TX_START 0x0000 /* Start TX buffer at 0 */
-#define PKTMEM_TX_ENDP1 ALIGNED_BUFSIZE /* Allow TX buffer for one frame */
-#define PKTMEM_RX_START PKTMEM_TX_ENDP1 /* Followed by RX buffer */
-#define PKTMEM_RX_END PKTMEM_END /* RX buffer goes to the end of SRAM */
-
-/* Misc. Helper Macros ******************************************************/
-
-#define enc_rdgreg(priv,ctrlreg) \
- enc_rdgreg2(priv, ENC_RCR | GETADDR(ctrlreg))
-#define enc_wrgreg(priv,ctrlreg,wrdata) \
- enc_wrgreg2(priv, ENC_WCR | GETADDR(ctrlreg), wrdata)
-#define enc_bfcgreg(priv,ctrlreg,clrbits) \
- enc_wrgreg2(priv, ENC_BFC | GETADDR(ctrlreg), clrbits)
-#define enc_bfsgreg(priv,ctrlreg,setbits) \
- enc_wrgreg2(priv, ENC_BFS | GETADDR(ctrlreg), setbits)
-
-/* This is a helper pointer for accessing the contents of the Ethernet header */
-
-#define BUF ((struct uip_eth_hdr *)priv->dev.d_buf)
-
-/* Debug ********************************************************************/
-
-#ifdef CONFIG_ENC28J60_REGDEBUG
-# define enc_wrdump(a,v) lowsyslog("ENC28J60: %02x<-%02x\n", a, v);
-# define enc_rddump(a,v) lowsyslog("ENC28J60: %02x->%02x\n", a, v);
-# define enc_cmddump(c) lowsyslog("ENC28J60: CMD: %02x\n", c);
-# define enc_bmdump(c,b,s) lowsyslog("ENC28J60: CMD: %02x buffer: %p length: %d\n", c,b,s);
-#else
-# define enc_wrdump(a,v)
-# define enc_rddump(a,v)
-# define enc_cmddump(c)
-# define enc_bmdump(c,b,s)
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* The state of the interface */
-
-enum enc_state_e
-{
- ENCSTATE_UNINIT = 0, /* The interface is in an uninitialized state */
- ENCSTATE_DOWN, /* The interface is down */
- ENCSTATE_UP /* The interface is up */
-};
-
-/* The enc_driver_s encapsulates all state information for a single hardware
- * interface
- */
-
-struct enc_driver_s
-{
- /* Device control */
-
- uint8_t ifstate; /* Interface state: See ENCSTATE_* */
- uint8_t bank; /* Currently selected bank */
- uint16_t nextpkt; /* Next packet address */
- FAR const struct enc_lower_s *lower; /* Low-level MCU-specific support */
-
- /* Timing */
-
- WDOG_ID txpoll; /* TX poll timer */
- WDOG_ID txtimeout; /* TX timeout timer */
-
- /* If we don't own the SPI bus, then we cannot do SPI accesses from the
- * interrupt handler.
- */
-
- struct work_s irqwork; /* Interrupt continuation work queue support */
- struct work_s towork; /* Tx timeout work queue support */
- struct work_s pollwork; /* Poll timeout work queue support */
-
- /* This is the contained SPI driver intstance */
-
- FAR struct spi_dev_s *spi;
-
- /* This holds the information visible to uIP/NuttX */
-
- struct uip_driver_s dev; /* Interface understood by uIP */
-
- /* Statistics */
-
-#ifdef CONFIG_ENC28J60_STATS
- struct enc_stats_s stats;
-#endif
-};
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static struct enc_driver_s g_enc28j60[CONFIG_ENC28J60_NINTERFACES];
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Low-level SPI helpers */
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void enc_configspi(FAR struct spi_dev_s *spi);
-# define enc_lock(priv);
-# define enc_unlock(priv);
-#else
-# define enc_configspi(spi)
-static void enc_lock(FAR struct enc_driver_s *priv);
-static inline void enc_unlock(FAR struct enc_driver_s *priv);
-#endif
-
-/* SPI control register access */
-
-static uint8_t enc_rdgreg2(FAR struct enc_driver_s *priv, uint8_t cmd);
-static void enc_wrgreg2(FAR struct enc_driver_s *priv, uint8_t cmd,
- uint8_t wrdata);
-static inline void enc_src(FAR struct enc_driver_s *priv);
-static void enc_setbank(FAR struct enc_driver_s *priv, uint8_t bank);
-static uint8_t enc_rdbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg);
-static void enc_wrbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg,
- uint8_t wrdata);
-static int enc_waitbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg,
- uint8_t bits, uint8_t value);
-
-#if 0 /* Sometimes useful */
-static void enc_rxdump(FAR struct enc_driver_s *priv);
-static void enc_txdump(FAR struct enc_driver_s *priv);
-#endif
-
-/* SPI buffer transfers */
-
-static void enc_rdbuffer(FAR struct enc_driver_s *priv, FAR uint8_t *buffer,
- size_t buflen);
-static inline void enc_wrbuffer(FAR struct enc_driver_s *priv,
- FAR const uint8_t *buffer, size_t buflen);
-
-/* PHY register access */
-
-static uint16_t enc_rdphy(FAR struct enc_driver_s *priv, uint8_t phyaddr);
-static void enc_wrphy(FAR struct enc_driver_s *priv, uint8_t phyaddr,
- uint16_t phydata);
-
-/* Common TX logic */
-
-static int enc_transmit(FAR struct enc_driver_s *priv);
-static int enc_uiptxpoll(struct uip_driver_s *dev);
-
-/* Interrupt handling */
-
-static void enc_linkstatus(FAR struct enc_driver_s *priv);
-static void enc_txif(FAR struct enc_driver_s *priv);
-static void enc_txerif(FAR struct enc_driver_s *priv);
-static void enc_txerif(FAR struct enc_driver_s *priv);
-static void enc_rxerif(FAR struct enc_driver_s *priv);
-static void enc_rxdispatch(FAR struct enc_driver_s *priv);
-static void enc_pktif(FAR struct enc_driver_s *priv);
-static void enc_irqworker(FAR void *arg);
-static int enc_interrupt(int irq, FAR void *context);
-
-/* Watchdog timer expirations */
-
-static void enc_toworker(FAR void *arg);
-static void enc_txtimeout(int argc, uint32_t arg, ...);
-static void enc_pollworker(FAR void *arg);
-static void enc_polltimer(int argc, uint32_t arg, ...);
-
-/* NuttX callback functions */
-
-static int enc_ifup(struct uip_driver_s *dev);
-static int enc_ifdown(struct uip_driver_s *dev);
-static int enc_txavail(struct uip_driver_s *dev);
-#ifdef CONFIG_NET_IGMP
-static int enc_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-static int enc_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-#endif
-
-/* Initialization */
-
-static void enc_pwrsave(FAR struct enc_driver_s *priv);
-static void enc_pwrfull(FAR struct enc_driver_s *priv);
-static void enc_setmacaddr(FAR struct enc_driver_s *priv);
-static int enc_reset(FAR struct enc_driver_s *priv);
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: enc_configspi
- *
- * Description:
- * Configure the SPI for use with the ENC28J60
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_SPI_OWNBUS
-static inline void enc_configspi(FAR struct spi_dev_s *spi)
-{
- /* Configure SPI for the ENC28J60. But only if we own the SPI bus.
- * Otherwise, don't bother because it might change.
- */
-
- SPI_SETMODE(spi, CONFIG_ENC28J60_SPIMODE);
- SPI_SETBITS(spi, 8);
- SPI_SETFREQUENCY(spi, CONFIG_ENC28J60_FREQUENCY)
-}
-#endif
-
-/****************************************************************************
- * Function: enc_lock
- *
- * Description:
- * Select the SPI, locking and re-configuring if necessary
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static void enc_lock(FAR struct enc_driver_s *priv)
-{
- /* Lock the SPI bus in case there are multiple devices competing for the SPI
- * bus.
- */
-
- SPI_LOCK(priv->spi, true);
-
- /* Now make sure that the SPI bus is configured for the ENC28J60 (it
- * might have gotten configured for a different device while unlocked)
- */
-
- SPI_SETMODE(priv->spi, CONFIG_ENC28J60_SPIMODE);
- SPI_SETBITS(priv->spi, 8);
- SPI_SETFREQUENCY(priv->spi, CONFIG_ENC28J60_FREQUENCY);
-}
-#endif
-
-/****************************************************************************
- * Function: enc_unlock
- *
- * Description:
- * De-select the SPI
- *
- * Parameters:
- * spi - Reference to the SPI driver structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifndef CONFIG_SPI_OWNBUS
-static inline void enc_unlock(FAR struct enc_driver_s *priv)
-{
- /* Relinquish the lock on the bus. */
-
- SPI_LOCK(priv->spi, false);
-}
-#endif
-
-/****************************************************************************
- * Function: enc_rdgreg2
- *
- * Description:
- * Read a global register (EIE, EIR, ESTAT, ECON2, or ECON1). The cmd
- * include the CMD 'OR'd with the the global address register.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * cmd - The full command to received (cmd | address)
- *
- * Returned Value:
- * The value read from the register
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static uint8_t enc_rdgreg2(FAR struct enc_driver_s *priv, uint8_t cmd)
-{
- uint8_t rddata;
-
- DEBUGASSERT(priv && priv->spi);
-
- /* Select ENC28J60 chip */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);;
-
- /* Send the read command and collect the data. The sequence requires
- * 16-clocks: 8 to clock out the cmd + 8 to clock in the data.
- */
-
- (void)SPI_SEND(priv->spi, cmd); /* Clock out the command */
- rddata = SPI_SEND(priv->spi, 0); /* Clock in the data */
-
- /* De-select ENC28J60 chip */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, false);
-
- enc_rddump(cmd, rddata);
- return rddata;
-}
-
-/****************************************************************************
- * Function: enc_wrgreg2
- *
- * Description:
- * Write to a global register (EIE, EIR, ESTAT, ECON2, or ECON1). The cmd
- * include the CMD 'OR'd with the the global address register.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * cmd - The full command to received (cmd | address)
- * wrdata - The data to send
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_wrgreg2(FAR struct enc_driver_s *priv, uint8_t cmd,
- uint8_t wrdata)
-{
- DEBUGASSERT(priv && priv->spi);
-
- /* Select ENC28J60 chip */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);;
-
- /* Send the write command and data. The sequence requires 16-clocks:
- * 8 to clock out the cmd + 8 to clock out the data.
- */
-
- (void)SPI_SEND(priv->spi, cmd); /* Clock out the command */
- (void)SPI_SEND(priv->spi, wrdata); /* Clock out the data */
-
- /* De-select ENC28J60 chip. */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, false);
- enc_wrdump(cmd, wrdata);
-}
-
-/****************************************************************************
- * Function: enc_src
- *
- * Description:
- * Send the single byte system reset command (SRC).
- *
- * "The System Reset Command (SRC) allows the host controller to issue a
- * System Soft Reset command. Unlike other SPI commands, the SRC is
- * only a single byte command and does not operate on any register. The
- * command is started by pulling the CS pin low. The SRC opcode is the
- * sent, followed by a 5-bit Soft Reset command constant of 1Fh. The
- * SRC operation is terminated by raising the CS pin."
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static inline void enc_src(FAR struct enc_driver_s *priv)
-{
- DEBUGASSERT(priv && priv->spi);
-
- /* Select ENC28J60 chip */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);;
-
- /* Send the system reset command. */
-
- (void)SPI_SEND(priv->spi, ENC_SRC);
-
- /* Check CLKRDY bit to see when the reset is complete. There is an errata
- * that says the CLKRDY may be invalid. We'll wait a couple of msec to
- * workaround this condition.
- *
- * Also, "After a System Reset, all PHY registers should not be read or
- * written to until at least 50 µs have passed since the Reset has ended.
- * All registers will revert to their Reset default values. The dual
- * port buffer memory will maintain state throughout the System Reset."
- */
-
- up_mdelay(2);
- /* while ((enc_rdgreg(priv, ENC_ESTAT) & ESTAT_CLKRDY) != 0); */
-
- /* De-select ENC28J60 chip. */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, false);
- enc_cmddump(ENC_SRC);
-}
-
-/****************************************************************************
- * Function: enc_setbank
- *
- * Description:
- * Set the bank for these next control register access.
- *
- * Assumption:
- * The caller has exclusive access to the SPI bus
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * bank - The bank to select (0-3)
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_setbank(FAR struct enc_driver_s *priv, uint8_t bank)
-{
- /* Check if the bank setting has changed*/
-
- if (bank != priv->bank)
- {
- /* Select bank 0 (just so that all of the bits are cleared) */
-
- enc_bfcgreg(priv, ENC_ECON1, ECON1_BSEL_MASK);
-
- /* Then OR in bits to get the correct bank */
-
- if (bank != 0)
- {
- enc_bfsgreg(priv, ENC_ECON1, (bank << ECON1_BSEL_SHIFT));
- }
-
- /* Then remember the bank setting */
-
- priv->bank = bank;
- }
-}
-
-/****************************************************************************
- * Function: enc_rdbreg
- *
- * Description:
- * Read from a banked control register using the RCR command.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * ctrlreg - Bit encoded address of banked register to read
- *
- * Returned Value:
- * The byte read from the banked register
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static uint8_t enc_rdbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg)
-{
- uint8_t rddata;
-
- DEBUGASSERT(priv && priv->spi);
-
- /* Set the bank */
-
- enc_setbank(priv, GETBANK(ctrlreg));
-
- /* Re-select ENC28J60 chip */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);;
-
- /* Send the RCR command and collect the data. How we collect the data
- * depends on if this is a PHY/CAN or not. The normal sequence requires
- * 16-clocks: 8 to clock out the cmd and 8 to clock in the data.
- */
-
- (void)SPI_SEND(priv->spi, ENC_RCR | GETADDR(ctrlreg)); /* Clock out the command */
- if (ISPHYMAC(ctrlreg))
- {
- /* The PHY/MAC sequence requires 24-clocks: 8 to clock out the cmd,
- * 8 dummy bits, and 8 to clock in the PHY/MAC data.
- */
-
- (void)SPI_SEND(priv->spi, 0); /* Clock in the dummy byte */
- }
-
- rddata = SPI_SEND(priv->spi, 0); /* Clock in the data */
-
- /* De-select ENC28J60 chip */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, false);
- enc_rddump(ENC_RCR | GETADDR(ctrlreg), rddata);
- return rddata;
-}
-
-/****************************************************************************
- * Function: enc_wrbreg
- *
- * Description:
- * Write to a banked control register using the WCR command. Unlike
- * reading, this same SPI sequence works for normal, MAC, and PHY
- * registers.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * ctrlreg - Bit encoded address of banked register to write
- * wrdata - The data to send
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_wrbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg,
- uint8_t wrdata)
-{
- DEBUGASSERT(priv && priv->spi);
-
- /* Set the bank */
-
- enc_setbank(priv, GETBANK(ctrlreg));
-
- /* Re-select ENC28J60 chip */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);;
-
- /* Send the WCR command and data. The sequence requires 16-clocks:
- * 8 to clock out the cmd + 8 to clock out the data.
- */
-
- (void)SPI_SEND(priv->spi, ENC_WCR | GETADDR(ctrlreg)); /* Clock out the command */
- (void)SPI_SEND(priv->spi, wrdata); /* Clock out the data */
-
- /* De-select ENC28J60 chip. */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, false);
- enc_wrdump(ENC_WCR | GETADDR(ctrlreg), wrdata);
-}
-
-/****************************************************************************
- * Function: enc_waitbreg
- *
- * Description:
- * Wait until banked register bit(s) take a specific value (or a timeout
- * occurs).
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * ctrlreg - Bit encoded address of banked register to check
- * bits - The bits to check (a mask)
- * value - The value of the bits to return (value under mask)
- *
- * Returned Value:
- * OK on success, negated errno on failure
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int enc_waitbreg(FAR struct enc_driver_s *priv, uint8_t ctrlreg,
- uint8_t bits, uint8_t value)
-{
- uint32_t start = clock_systimer();
- uint32_t elapsed;
- uint8_t rddata;
-
- /* Loop until the exit condition is met */
-
- do
- {
- /* Read the byte from the requested banked register */
-
- rddata = enc_rdbreg(priv, ctrlreg);
- elapsed = clock_systimer() - start;
- }
- while ((rddata & bits) != value || elapsed > ENC_POLLTIMEOUT);
-
- return (rddata & bits) == value ? -ETIMEDOUT : OK;
-}
-
-/****************************************************************************
- * Function: enc_txdump enc_rxdump
- *
- * Description:
- * Dump registers associated with receiving or sending packets.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#if 0 /* Sometimes useful */
-static void enc_rxdump(FAR struct enc_driver_s *priv)
-{
- lowsyslog("Rx Registers:\n");
- lowsyslog(" EIE: %02x EIR: %02x\n",
- enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR));
- lowsyslog(" ESTAT: %02x ECON1: %02x ECON2: %02x\n",
- enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1),
- enc_rdgreg(priv, ENC_ECON2));
- lowsyslog(" ERXST: %02x %02x\n",
- enc_rdbreg(priv, ENC_ERXSTH), enc_rdbreg(priv, ENC_ERXSTL));
- lowsyslog(" ERXND: %02x %02x\n",
- enc_rdbreg(priv, ENC_ERXNDH), enc_rdbreg(priv, ENC_ERXNDL));
- lowsyslog(" ERXRDPT: %02x %02x\n",
- enc_rdbreg(priv, ENC_ERXRDPTH), enc_rdbreg(priv, ENC_ERXRDPTL));
- lowsyslog(" ERXFCON: %02x EPKTCNT: %02x\n",
- enc_rdbreg(priv, ENC_ERXFCON), enc_rdbreg(priv, ENC_EPKTCNT));
- lowsyslog(" MACON1: %02x MACON3: %02x\n",
- enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3));
- lowsyslog(" MAMXFL: %02x %02x\n",
- enc_rdbreg(priv, ENC_MAMXFLH), enc_rdbreg(priv, ENC_MAMXFLL));
- lowsyslog(" MAADR: %02x:%02x:%02x:%02x:%02x:%02x\n",
- enc_rdbreg(priv, ENC_MAADR1), enc_rdbreg(priv, ENC_MAADR2),
- enc_rdbreg(priv, ENC_MAADR3), enc_rdbreg(priv, ENC_MAADR4),
- enc_rdbreg(priv, ENC_MAADR5), enc_rdbreg(priv, ENC_MAADR6));
-}
-#endif
-
-#if 0 /* Sometimes useful */
-static void enc_txdump(FAR struct enc_driver_s *priv)
-{
- lowsyslog("Tx Registers:\n");
- lowsyslog(" EIE: %02x EIR: %02x ESTAT: %02x\n",
- enc_rdgreg(priv, ENC_EIE), enc_rdgreg(priv, ENC_EIR),);
- lowsyslog(" ESTAT: %02x ECON1: %02x\n",
- enc_rdgreg(priv, ENC_ESTAT), enc_rdgreg(priv, ENC_ECON1));
- lowsyslog(" ETXST: %02x %02x\n",
- enc_rdbreg(priv, ENC_ETXSTH), enc_rdbreg(priv, ENC_ETXSTL));
- lowsyslog(" ETXND: %02x %02x\n",
- enc_rdbreg(priv, ENC_ETXNDH), enc_rdbreg(priv, ENC_ETXNDL));
- lowsyslog(" MACON1: %02x MACON3: %02x MACON4: %02x\n",
- enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3),
- enc_rdbreg(priv, ENC_MACON4));
- lowsyslog(" MACON1: %02x MACON3: %02x MACON4: %02x\n",
- enc_rdbreg(priv, ENC_MACON1), enc_rdbreg(priv, ENC_MACON3),
- enc_rdbreg(priv, ENC_MACON4));
- lowsyslog(" MABBIPG: %02x MAIPG %02x %02x\n",
- enc_rdbreg(priv, ENC_MABBIPG), enc_rdbreg(priv, ENC_MAIPGH),
- enc_rdbreg(priv, ENC_MAIPGL));
- lowsyslog(" MACLCON1: %02x MACLCON2: %02x\n",
- enc_rdbreg(priv, ENC_MACLCON1), enc_rdbreg(priv, ENC_MACLCON2));
- lowsyslog(" MAMXFL: %02x %02x\n",
- enc_rdbreg(priv, ENC_MAMXFLH), enc_rdbreg(priv, ENC_MAMXFLL));
-}
-#endif
-
-/****************************************************************************
- * Function: enc_rdbuffer
- *
- * Description:
- * Read a buffer of data.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * buffer - A pointer to the buffer to read into
- * buflen - The number of bytes to read
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Read pointer is set to the correct address
- *
- ****************************************************************************/
-
-static void enc_rdbuffer(FAR struct enc_driver_s *priv, FAR uint8_t *buffer,
- size_t buflen)
-{
- DEBUGASSERT(priv && priv->spi);
-
- /* Select ENC28J60 chip */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);;
-
- /* Send the read buffer memory command (ignoring the response) */
-
- (void)SPI_SEND(priv->spi, ENC_RBM);
-
- /* Then read the buffer data */
-
- SPI_RECVBLOCK(priv->spi, buffer, buflen);
-
- /* De-select ENC28J60 chip. */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, false);
- enc_bmdump(ENC_WBM, buffer, buflen);
-}
-
-/****************************************************************************
- * Function: enc_wrbuffer
- *
- * Description:
- * Write a buffer of data.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * buffer - A pointer to the buffer to write from
- * buflen - The number of bytes to write
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Read pointer is set to the correct address
- *
- ****************************************************************************/
-
-static inline void enc_wrbuffer(FAR struct enc_driver_s *priv,
- FAR const uint8_t *buffer, size_t buflen)
-{
- DEBUGASSERT(priv && priv->spi);
-
- /* Select ENC28J60 chip
- *
- * "The WBM command is started by lowering the CS pin. ..."
- */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, true);;
-
- /* Send the write buffer memory command (ignoring the response)
- *
- * "...The [3-bit]WBM opcode should then be sent to the ENC28J60,
- * followed by the 5-bit constant, 1Ah."
- */
-
- (void)SPI_SEND(priv->spi, ENC_WBM);
-
- /* "...the ENC28J60 requires a single per packet control byte to
- * precede the packet for transmission."
- *
- * POVERRIDE: Per Packet Override bit (Not set):
- * 1 = The values of PCRCEN, PPADEN and PHUGEEN will override the
- * configuration defined by MACON3.
- * 0 = The values in MACON3 will be used to determine how the packet
- * will be transmitted
- * PCRCEN: Per Packet CRC Enable bit (Set, but won't be used because
- * POVERRIDE is zero).
- * PPADEN: Per Packet Padding Enable bit (Set, but won't be used because
- * POVERRIDE is zero).
- * PHUGEEN: Per Packet Huge Frame Enable bit (Set, but won't be used
- * because POVERRIDE is zero).
- */
-
- (void)SPI_SEND(priv->spi,
- (PKTCTRL_PCRCEN | PKTCTRL_PPADEN | PKTCTRL_PHUGEEN));
-
- /* Then send the buffer
- *
- * "... After the WBM command and constant are sent, the data to
- * be stored in the memory pointed to by EWRPT should be shifted
- * out MSb first to the ENC28J60. After 8 data bits are received,
- * the Write Pointer will automatically increment if AUTOINC is
- * set. The host controller can continue to provide clocks on the
- * SCK pin and send data on the SI pin, without raising CS, to
- * keep writing to the memory. In this manner, with AUTOINC
- * enabled, it is possible to continuously write sequential bytes
- * to the buffer memory without any extra SPI command
- * overhead.
- */
-
- SPI_SNDBLOCK(priv->spi, buffer, buflen);
-
- /* De-select ENC28J60 chip
- *
- * "The WBM command is terminated by bringing up the CS pin. ..."
- */
-
- SPI_SELECT(priv->spi, SPIDEV_ETHERNET, false);
- enc_bmdump(ENC_WBM, buffer, buflen+1);
-}
-
-/****************************************************************************
- * Function: enc_rdphy
- *
- * Description:
- * Read 16-bits of PHY data.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * phyaddr - The PHY register address
- *
- * Returned Value:
- * 16-bit value read from the PHY
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static uint16_t enc_rdphy(FAR struct enc_driver_s *priv, uint8_t phyaddr)
-{
- uint16_t data = 0;
-
- /* "To read from a PHY register:
- *
- * 1. Write the address of the PHY register to read from into the MIREGADR
- * register.
- */
-
- enc_wrbreg(priv, ENC_MIREGADR, phyaddr);
-
- /* 2. Set the MICMD.MIIRD bit. The read operation begins and the
- * MISTAT.BUSY bit is set.
- */
-
- enc_wrbreg(priv, ENC_MICMD, MICMD_MIIRD);
-
- /* 3. Wait 10.24 µs. Poll the MISTAT.BUSY bit to be certain that the
- * operation is complete. While busy, the host controller should not
- * start any MIISCAN operations or write to the MIWRH register.
- *
- * When the MAC has obtained the register contents, the BUSY bit will
- * clear itself.
- */
-
- up_udelay(12);
- if (enc_waitbreg(priv, ENC_MISTAT, MISTAT_BUSY, 0x00) == OK);
- {
- /* 4. Clear the MICMD.MIIRD bit. */
-
- enc_wrbreg(priv, ENC_MICMD, 0x00);
-
- /* 5. Read the desired data from the MIRDL and MIRDH registers. The
- * order that these bytes are accessed is unimportant."
- */
-
- data = (uint16_t)enc_rdbreg(priv, ENC_MIRDL);
- data |= (uint16_t)enc_rdbreg(priv, ENC_MIRDH) << 8;
- }
-
- return data;
-}
-
-/****************************************************************************
- * Function: enc_wrphy
- *
- * Description:
- * write 16-bits of PHY data.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * phyaddr - The PHY register address
- * phydata - 16-bit data to write to the PHY
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_wrphy(FAR struct enc_driver_s *priv, uint8_t phyaddr,
- uint16_t phydata)
-{
- /* "To write to a PHY register:
- *
- * 1. Write the address of the PHY register to write to into the
- * MIREGADR register.
- */
-
- enc_wrbreg(priv, ENC_MIREGADR, phyaddr);
-
- /* 2. Write the lower 8 bits of data to write into the MIWRL register. */
-
- enc_wrbreg(priv, ENC_MIWRL, phydata);
-
- /* 3. Write the upper 8 bits of data to write into the MIWRH register.
- * Writing to this register automatically begins the MIIM transaction,
- * so it must be written to after MIWRL. The MISTAT.BUSY bit becomes
- * set.
- */
-
- enc_wrbreg(priv, ENC_MIWRH, phydata >> 8);
-
- /* The PHY register will be written after the MIIM operation completes,
- * which takes 10.24 µs. When the write operation has completed, the BUSY
- * bit will clear itself.
- *
- * The host controller should not start any MIISCAN or MIIRD operations
- * while busy."
- */
-
- up_udelay(12);
- enc_waitbreg(priv, ENC_MISTAT, MISTAT_BUSY, 0x00);
-}
-
-/****************************************************************************
- * Function: enc_transmit
- *
- * Description:
- * Start hardware transmission. Called either from:
- *
- * - pkif interrupt when an application responds to the receipt of data
- * by trying to send something, or
- * - From watchdog based polling.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int enc_transmit(FAR struct enc_driver_s *priv)
-{
- uint16_t txend;
-
- /* Increment statistics */
-
- nllvdbg("Sending packet, pktlen: %d\n", priv->dev.d_len);
-#ifdef CONFIG_ENC28J60_STATS
- priv->stats.txrequests++;
-#endif
-
- /* Verify that the hardware is ready to send another packet. The driver
- * starts a transmission process by setting ECON1.TXRTS. When the packet is
- * finished transmitting or is aborted due to an error/cancellation, the
- * ECON1.TXRTS bit will be cleared.
- *
- * NOTE: If we got here, then we have committed to sending a packet.
- * higher level logic must have assured that (1) there is no transmission
- * in progress, and that (2) TX-related interrupts are disabled.
- */
-
- DEBUGASSERT((enc_rdgreg(priv, ENC_ECON1) & ECON1_TXRTS) == 0);
-
- /* Send the packet: address=priv->dev.d_buf, length=priv->dev.d_len */
-
- enc_dumppacket("Transmit Packet", priv->dev.d_buf, priv->dev.d_len);
-
- /* Set transmit buffer start (is this necessary?). */
-
- enc_wrbreg(priv, ENC_ETXSTL, PKTMEM_TX_START & 0xff);
- enc_wrbreg(priv, ENC_ETXSTH, PKTMEM_TX_START >> 8);
-
- /* Reset the write pointer to start of transmit buffer */
-
- enc_wrbreg(priv, ENC_EWRPTL, PKTMEM_TX_START & 0xff);
- enc_wrbreg(priv, ENC_EWRPTH, PKTMEM_TX_START >> 8);
-
- /* Set the TX End pointer based on the size of the packet to send. Note
- * that the offset accounts for the control byte at the beginning the
- * buffer plus the size of the packet data.
- */
-
- txend = PKTMEM_TX_START + priv->dev.d_len;
- enc_wrbreg(priv, ENC_ETXNDL, txend & 0xff);
- enc_wrbreg(priv, ENC_ETXNDH, txend >> 8);
-
- /* Send the WBM command and copy the packet itself into the transmit
- * buffer at the position of the EWRPT register.
- */
-
- enc_wrbuffer(priv, priv->dev.d_buf, priv->dev.d_len);
-
- /* Set TXRTS to send the packet in the transmit buffer */
-
- enc_bfsgreg(priv, ENC_ECON1, ECON1_TXRTS);
-
- /* Setup the TX timeout watchdog (perhaps restarting the timer). Note:
- * Is there a race condition. Could the TXIF interrupt occur before
- * the timer is started?
- */
-
- (void)wd_start(priv->txtimeout, ENC_TXTIMEOUT, enc_txtimeout, 1, (uint32_t)priv);
- return OK;
-}
-
-/****************************************************************************
- * Function: enc_uiptxpoll
- *
- * Description:
- * The transmitter is available, check if uIP has any outgoing packets ready
- * to send. This is a callback from uip_poll(). uip_poll() may be called:
- *
- * 1. When the preceding TX packet send is complete,
- * 2. When the preceding TX packet send timesout and the interface is reset
- * 3. During normal TX polling
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- * Interrupts are enabled but the caller holds the uIP lock.
- *
- ****************************************************************************/
-
-static int enc_uiptxpoll(struct uip_driver_s *dev)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)dev->d_private;
-
- /* If the polling resulted in data that should be sent out on the network,
- * the field d_len is set to a value > 0.
- */
-
- nllvdbg("Poll result: d_len=%d\n", priv->dev.d_len);
- if (priv->dev.d_len > 0)
- {
- uip_arp_out(&priv->dev);
- enc_transmit(priv);
-
- /* Stop the poll now because we can queue only one packet */
-
- return -EBUSY;
- }
-
- /* If zero is returned, the polling will continue until all connections have
- * been examined.
- */
-
- return OK;
-}
-
-/****************************************************************************
- * Function: enc_linkstatus
- *
- * Description:
- * The current link status can be obtained from the PHSTAT1.LLSTAT or
- * PHSTAT2.LSTAT.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_linkstatus(FAR struct enc_driver_s *priv)
-{
-#if 0
- uint16_t regval = enc_rdphy(priv, ENC_PHSTAT2);
- priv->duplex = ((regval & PHSTAT2_DPXSTAT) != 0);
- priv->carrier = ((regval & PHSTAT2_LSTAT) != 0);
-#endif
-}
-
-/****************************************************************************
- * Function: enc_txif
- *
- * Description:
- * An TXIF interrupt was received indicating that the last TX packet(s) is
- * done
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Interrupts are enabled but the caller holds the uIP lock.
- *
- ****************************************************************************/
-
-static void enc_txif(FAR struct enc_driver_s *priv)
-{
- /* Update statistics */
-
-#ifdef CONFIG_ENC28J60_STATS
- priv->stats.txifs++;
- if (enc_rdgreg(priv, ENC_ESTAT) & ESTAT_TXABRT)
- {
- priv->stats.txabrts++;
- }
-#endif
-
- /* Clear the request to send bit */
-
- enc_bfcgreg(priv, ENC_ECON1, ECON1_TXRTS);
-
- /* If no further xmits are pending, then cancel the TX timeout */
-
- wd_cancel(priv->txtimeout);
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&priv->dev, enc_uiptxpoll);
-}
-
-/****************************************************************************
- * Function: enc_txerif
- *
- * Description:
- * An TXERIF interrupt was received indicating that a TX abort has occurred.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_txerif(FAR struct enc_driver_s *priv)
-{
- /* Update statistics */
-
-#ifdef CONFIG_ENC28J60_STATS
- priv->stats.txerifs++;
-#endif
-
- /* Reset TX */
-
- enc_bfsgreg(priv, ENC_ECON1, ECON1_TXRST);
- enc_bfcgreg(priv, ENC_ECON1, ECON1_TXRST | ECON1_TXRTS);
-
- /* Here we really should re-transmit (I fact, if we want half duplex to
- * work right, then it is necessary to do this!):
- *
- * 1. Read the TSV:
- * - Read ETXNDL to get the end pointer
- * - Read 7 bytes from that pointer + 1 using ENC_RMB.
- * 2. Determine if we need to retransmit. Check the LATE COLLISION bit, if
- * set, then we need to transmit.
- * 3. Retranmit by resetting ECON1_TXRTS.
- */
-
-#ifdef CONFIG_ENC28J60_HALFDUPLEX
-# error "Missing logic for half duplex"
-#endif
-}
-
-/****************************************************************************
- * Function: enc_rxerif
- *
- * Description:
- * An RXERIF interrupt was received indicating that the last TX packet(s) is
- * done
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_rxerif(FAR struct enc_driver_s *priv)
-{
- /* Update statistics */
-
-#ifdef CONFIG_ENC28J60_STATS
- priv->stats.rxerifs++;
-#endif
-}
-
-/****************************************************************************
- * Function: enc_rxdispatch
- *
- * Description:
- * Give the newly received packet to uIP.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Interrupts are enabled but the caller holds the uIP lock.
- *
- ****************************************************************************/
-
-static void enc_rxdispatch(FAR struct enc_driver_s *priv)
-{
- /* We only accept IP packets of the configured type and ARP packets */
-
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
-#else
- if (BUF->type == HTONS(UIP_ETHTYPE_IP))
-#endif
- {
- nllvdbg("IP packet received (%02x)\n", BUF->type);
- uip_arp_ipin(&priv->dev);
- uip_input(&priv->dev);
-
- /* If the above function invocation resulted in data that should be
- * sent out on the network, the field d_len will set to a value > 0.
- */
-
- if (priv->dev.d_len > 0)
- {
- uip_arp_out(&priv->dev);
- enc_transmit(priv);
- }
- }
- else if (BUF->type == htons(UIP_ETHTYPE_ARP))
- {
- nllvdbg("ARP packet received (%02x)\n", BUF->type);
- uip_arp_arpin(&priv->dev);
-
- /* If the above function invocation resulted in data that should be
- * sent out on the network, the field d_len will set to a value > 0.
- */
-
- if (priv->dev.d_len > 0)
- {
- enc_transmit(priv);
- }
- }
- else
- {
- nlldbg("Unsupported packet type dropped (%02x)\n", htons(BUF->type));
- }
-}
-
-/****************************************************************************
- * Function: enc_pktif
- *
- * Description:
- * An interrupt was received indicating the availability of a new RX packet
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Interrupts are enabled but the caller holds the uIP lock.
- *
- ****************************************************************************/
-
-static void enc_pktif(FAR struct enc_driver_s *priv)
-{
- uint8_t rsv[6];
- uint16_t pktlen;
- uint16_t rxstat;
-
- /* Update statistics */
-
-#ifdef CONFIG_ENC28J60_STATS
- priv->stats.pktifs++;
-#endif
-
- /* Set the read pointer to the start of the received packet (ERDPT) */
-
- DEBUGASSERT(priv->nextpkt <= PKTMEM_RX_END);
- enc_wrbreg(priv, ENC_ERDPTL, (priv->nextpkt));
- enc_wrbreg(priv, ENC_ERDPTH, (priv->nextpkt) >> 8);
-
- /* Read the next packet pointer and the 4 byte read status vector (RSV)
- * at the beginning of the received packet. (ERDPT should auto-increment
- * and wrap to the beginning of the read buffer as necessary)
- */
-
- enc_rdbuffer(priv, rsv, 6);
-
- /* Decode the new next packet pointer, and the RSV. The
- * RSV is encoded as:
- *
- * Bits 0-15: Indicates length of the received frame. This includes the
- * destination address, source address, type/length, data,
- * padding and CRC fields. This field is stored in little-
- * endian format.
- * Bits 16-31: Bit encoded RX status.
- */
-
- priv->nextpkt = (uint16_t)rsv[1] << 8 | (uint16_t)rsv[0];
- pktlen = (uint16_t)rsv[3] << 8 | (uint16_t)rsv[2];
- rxstat = (uint16_t)rsv[5] << 8 | (uint16_t)rsv[4];
-
- nllvdbg("Receiving packet, nextpkt: %04x pktlen: %d rxstat: %04x\n",
- priv->nextpkt, pktlen, rxstat);
-
- /* Check if the packet was received OK */
-
- if ((rxstat & RXSTAT_OK) == 0)
- {
- nlldbg("ERROR: RXSTAT: %04x\n", rxstat);
-#ifdef CONFIG_ENC28J60_STATS
- priv->stats.rxnotok++;
-#endif
- }
-
- /* Check for a usable packet length (4 added for the CRC) */
-
- else if (pktlen > (CONFIG_NET_BUFSIZE + 4) || pktlen <= (UIP_LLH_LEN + 4))
- {
- nlldbg("Bad packet size dropped (%d)\n", pktlen);
-#ifdef CONFIG_ENC28J60_STATS
- priv->stats.rxpktlen++;
-#endif
- }
-
- /* Otherwise, read and process the packet */
-
- else
- {
- /* Save the packet length (without the 4 byte CRC) in priv->dev.d_len*/
-
- priv->dev.d_len = pktlen - 4;
-
- /* Copy the data data from the receive buffer to priv->dev.d_buf.
- * ERDPT should be correctly positioned from the last call to to
- * end_rdbuffer (above).
- */
-
- enc_rdbuffer(priv, priv->dev.d_buf, priv->dev.d_len);
- enc_dumppacket("Received Packet", priv->dev.d_buf, priv->dev.d_len);
-
- /* Dispatch the packet to uIP */
-
- enc_rxdispatch(priv);
- }
-
- /* Move the RX read pointer to the start of the next received packet.
- * This frees the memory we just read.
- */
-
- enc_wrbreg(priv, ENC_ERXRDPTL, (priv->nextpkt));
- enc_wrbreg(priv, ENC_ERXRDPTH, (priv->nextpkt) >> 8);
-
- /* Decrement the packet counter indicate we are done with this packet */
-
- enc_bfsgreg(priv, ENC_ECON2, ECON2_PKTDEC);
-}
-
-/****************************************************************************
- * Function: enc_irqworker
- *
- * Description:
- * Perform interrupt handling logic outside of the interrupt handler (on
- * the work queue thread).
- *
- * Parameters:
- * arg - The reference to the driver structure (case to void*)
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_irqworker(FAR void *arg)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)arg;
- uip_lock_t lock;
- uint8_t eir;
-
- DEBUGASSERT(priv);
-
- /* Get exclusive access to both uIP and the SPI bus. */
-
- lock = uip_lock();
- enc_lock(priv);
-
- /* Disable further interrupts by clearing the global interrupt enable bit.
- * "After an interrupt occurs, the host controller should clear the global
- * enable bit for the interrupt pin before servicing the interrupt. Clearing
- * the enable bit will cause the interrupt pin to return to the non-asserted
- * state (high). Doing so will prevent the host controller from missing a
- * falling edge should another interrupt occur while the immediate interrupt
- * is being serviced."
- */
-
- enc_bfcgreg(priv, ENC_EIE, EIE_INTIE);
-
- /* Loop until all interrupts have been processed (EIR==0). Note that
- * there is no infinite loop check... if there are always pending interrupts,
- * we are just broken.
- */
-
- while ((eir = enc_rdgreg(priv, ENC_EIR) & EIR_ALLINTS) != 0)
- {
- /* Handle interrupts according to interrupt register register bit
- * settings.
- */
-
- nllvdbg("EIR: %02x\n", eir);
-
- /* DMAIF: The DMA interrupt indicates that the DMA module has completed
- * its memory copy or checksum calculation. Additionally, this interrupt
- * will be caused if the host controller cancels a DMA operation by
- * manually clearing the DMAST bit. Once set, DMAIF can only be cleared
- * by the host controller or by a Reset condition.
- */
-
- if ((eir & EIR_DMAIF) != 0) /* DMA interrupt */
- {
- /* Not used by this driver. Just clear the interrupt request. */
-
- enc_bfcgreg(priv, ENC_EIR, EIR_DMAIF);
- }
-
- /* LINKIF: The LINKIF indicates that the link status has changed.
- * The actual current link status can be obtained from the
- * PHSTAT1.LLSTAT or PHSTAT2.LSTAT. Unlike other interrupt sources, the
- * link status change interrupt is created in the integrated PHY
- * module.
- *
- * To receive it, the host controller must set the PHIE.PLNKIE and
- * PGEIE bits. After setting the two PHY interrupt enable bits, the
- * LINKIF bit will then shadow the contents of the PHIR.PGIF bit.
- *
- * Once LINKIF is set, it can only be cleared by the host controller or
- * by a Reset. The LINKIF bit is read-only. Performing an MII read on
- * the PHIR register will clear the LINKIF, PGIF and PLNKIF bits
- * automatically and allow for future link status change interrupts.
- */
-
- if ((eir & EIR_LINKIF) != 0) /* Link change interrupt */
- {
- enc_linkstatus(priv); /* Get current link status */
- enc_rdphy(priv, ENC_PHIR); /* Clear the LINKIF interrupt */
- }
-
- /* TXIF: The Transmit Interrupt Flag (TXIF) is used to indicate that
- * the requested packet transmission has ended. Upon transmission
- * completion, abort or transmission cancellation by the host
- * controller, the EIR.TXIF flag will be set to 1.
- *
- * Once TXIF is set, it can only be cleared by the host controller
- * or by a Reset condition. Once processed, the host controller should
- * use the BFC command to clear the EIR.TXIF bit.
- */
-
- if ((eir & EIR_TXIF) != 0) /* Transmit interrupt */
- {
- enc_txif(priv); /* Handle TX completion */
- enc_bfcgreg(priv, ENC_EIR, EIR_TXIF); /* Clear the TXIF interrupt */
- }
-
- /* TXERIF: The Transmit Error Interrupt Flag (TXERIF) is used to
- * indicate that a transmit abort has occurred. An abort can occur
- * because of any of the following:
- *
- * 1. Excessive collisions occurred as defined by the Retransmission
- * Maximum (RETMAX) bits in the MACLCON1 register.
- * 2. A late collision occurred as defined by the Collision Window
- * (COLWIN) bits in the MACLCON2 register.
- * 3. A collision after transmitting 64 bytes occurred (ESTAT.LATECOL
- * set).
- * 4. The transmission was unable to gain an opportunity to transmit
- * the packet because the medium was constantly occupied for too long.
- * The deferral limit (2.4287 ms) was reached and the MACON4.DEFER bit
- * was clear.
- * 5. An attempt to transmit a packet larger than the maximum frame
- * length defined by the MAMXFL registers was made without setting
- * the MACON3.HFRMEN bit or per packet POVERRIDE and PHUGEEN bits.
- *
- * Upon any of these conditions, the EIR.TXERIF flag is set to 1. Once
- * set, it can only be cleared by the host controller or by a Reset
- * condition.
- *
- * After a transmit abort, the TXRTS bit will be cleared, the
- * ESTAT.TXABRT bit will be set and the transmit status vector will be
- * written at ETXND + 1. The MAC will not automatically attempt to
- * retransmit the packet. The host controller may wish to read the
- * transmit status vector and LATECOL bit to determine the cause of
- * the abort. After determining the problem and solution, the host
- * controller should clear the LATECOL (if set) and TXABRT bits so
- * that future aborts can be detected accurately.
- *
- * In Full-Duplex mode, condition 5 is the only one that should cause
- * this interrupt. Collisions and other problems related to sharing
- * the network are not possible on full-duplex networks. The conditions
- * which cause the transmit error interrupt meet the requirements of the
- * transmit interrupt. As a result, when this interrupt occurs, TXIF
- * will also be simultaneously set.
- */
-
- if ((eir & EIR_TXERIF) != 0) /* Transmit Error Interrupts */
- {
- enc_txerif(priv); /* Handle the TX error */
- enc_bfcgreg(priv, ENC_EIR, EIR_TXERIF); /* Clear the TXERIF interrupt */
- }
-
- /* PKTIF The Receive Packet Pending Interrupt Flag (PKTIF) is used to
- * indicate the presence of one or more data packets in the receive
- * buffer and to provide a notification means for the arrival of new
- * packets. When the receive buffer has at least one packet in it,
- * EIR.PKTIF will be set. In other words, this interrupt flag will be
- * set anytime the Ethernet Packet Count register (EPKTCNT) is non-zero.
- *
- * The PKTIF bit can only be cleared by the host controller or by a Reset
- * condition. In order to clear PKTIF, the EPKTCNT register must be
- * decremented to 0. If the last data packet in the receive buffer is
- * processed, EPKTCNT will become zero and the PKTIF bit will automatically
- * be cleared.
- */
-
- /* Ignore PKTIF because is unreliable. Use EPKTCNT instead */
- /* if ((eir & EIR_PKTIF) != 0) */
- {
- uint8_t pktcnt = enc_rdbreg(priv, ENC_EPKTCNT);
- if (pktcnt > 0)
- {
- nllvdbg("EPKTCNT: %02x\n", pktcnt);
-
-#ifdef CONFIG_ENC28J60_STATS
- if (pktcnt > priv->stats.maxpktcnt)
- {
- priv->stats.maxpktcnt = pktcnt;
- }
-#endif
- /* Handle packet receipt */
-
- enc_pktif(priv);
- }
- }
-
- /* RXERIF: The Receive Error Interrupt Flag (RXERIF) is used to
- * indicate a receive buffer overflow condition. Alternately, this
- * interrupt may indicate that too many packets are in the receive
- * buffer and more cannot be stored without overflowing the EPKTCNT
- * register. When a packet is being received and the receive buffer
- * runs completely out of space, or EPKTCNT is 255 and cannot be
- * incremented, the packet being received will be aborted (permanently
- * lost) and the EIR.RXERIF bit will be set to 1.
- *
- * Once set, RXERIF can only be cleared by the host controller or by a
- * Reset condition. Normally, upon the receive error condition, the
- * host controller would process any packets pending from the receive
- * buffer and then make additional room for future packets by
- * advancing the ERXRDPT registers (low byte first) and decrementing
- * the EPKTCNT register.
- *
- * Once processed, the host controller should use the BFC command to
- * clear the EIR.RXERIF bit.
- */
-
- if ((eir & EIR_RXERIF) != 0) /* Receive Errror Interrupts */
- {
- enc_rxerif(priv); /* Handle the RX error */
- enc_bfcgreg(priv, ENC_EIR, EIR_RXERIF); /* Clear the RXERIF interrupt */
- }
- }
-
- /* Enable Ethernet interrupts */
-
- enc_bfsgreg(priv, ENC_EIE, EIE_INTIE);
-
- /* Release lock on the SPI bus and uIP */
-
- enc_unlock(priv);
- uip_unlock(lock);
-
- /* Enable GPIO interrupts */
-
- priv->lower->enable(priv->lower);
-}
-
-/****************************************************************************
- * Function: enc_interrupt
- *
- * Description:
- * Hardware interrupt handler
- *
- * Parameters:
- * irq - Number of the IRQ that generated the interrupt
- * context - Interrupt register state save info (architecture-specific)
- *
- * Returned Value:
- * OK on success
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int enc_interrupt(int irq, FAR void *context)
-{
- register FAR struct enc_driver_s *priv = &g_enc28j60[0];
-
- /* In complex environments, we cannot do SPI transfers from the interrupt
- * handler because semaphores are probably used to lock the SPI bus. In
- * this case, we will defer processing to the worker thread. This is also
- * much kinder in the use of system resources and is, therefore, probably
- * a good thing to do in any event.
- */
-
- DEBUGASSERT(work_available(&priv->irqwork));
-
- /* Notice that further GPIO interrupts are disabled until the work is
- * actually performed. This is to prevent overrun of the worker thread.
- * Interrupts are re-enabled in enc_irqworker() when the work is completed.
- */
-
- priv->lower->disable(priv->lower);
- return work_queue(HPWORK, &priv->irqwork, enc_irqworker, (FAR void *)priv, 0);
-}
-
-/****************************************************************************
- * Function: enc_toworker
- *
- * Description:
- * Our TX watchdog timed out. This is the worker thread continuation of
- * the watchdog timer interrupt. Reset the hardware and start again.
- *
- * Parameters:
- * arg - The reference to the driver structure (case to void*)
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_toworker(FAR void *arg)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)arg;
- uip_lock_t lock;
- int ret;
-
- nlldbg("Tx timeout\n");
- DEBUGASSERT(priv);
-
- /* Get exclusive access to both uIP and the SPI bus. */
-
- lock = uip_lock();
- enc_lock(priv);
-
- /* Increment statistics and dump debug info */
-
-#ifdef CONFIG_ENC28J60_STATS
- priv->stats.txtimeouts++;
-#endif
-
- /* Then reset the hardware: Take the interface down, then bring it
- * back up
- */
-
- ret = enc_ifdown(&priv->dev);
- DEBUGASSERT(ret == OK);
- ret = enc_ifup(&priv->dev);
- DEBUGASSERT(ret == OK);
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&priv->dev, enc_uiptxpoll);
-
- /* Release lock on the SPI bus and uIP */
-
- enc_unlock(priv);
- uip_unlock(lock);
-}
-
-/****************************************************************************
- * Function: enc_txtimeout
- *
- * Description:
- * Our TX watchdog timed out. Called from the timer interrupt handler.
- * The last TX never completed. Perform work on the worker thread.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_txtimeout(int argc, uint32_t arg, ...)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)arg;
- int ret;
-
- /* In complex environments, we cannot do SPI transfers from the timout
- * handler because semaphores are probably used to lock the SPI bus. In
- * this case, we will defer processing to the worker thread. This is also
- * much kinder in the use of system resources and is, therefore, probably
- * a good thing to do in any event.
- */
-
- DEBUGASSERT(priv && work_available(&priv->towork));
-
- /* Notice that Tx timeout watchdog is not active so further Tx timeouts
- * can occur until we restart the Tx timeout watchdog.
- */
-
- ret = work_queue(HPWORK, &priv->towork, enc_toworker, (FAR void *)priv, 0);
- DEBUGASSERT(ret == OK);
-}
-
-/****************************************************************************
- * Function: enc_pollworker
- *
- * Description:
- * Periodic timer handler continuation.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_pollworker(FAR void *arg)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)arg;
- uip_lock_t lock;
-
- DEBUGASSERT(priv);
-
- /* Get exclusive access to both uIP and the SPI bus. */
-
- lock = uip_lock();
- enc_lock(priv);
-
- /* Verify that the hardware is ready to send another packet. The driver
- * start a transmission process by setting ECON1.TXRTS. When the packet is
- * finished transmitting or is aborted due to an error/cancellation, the
- * ECON1.TXRTS bit will be cleared.
- */
-
- if ((enc_rdgreg(priv, ENC_ECON1) & ECON1_TXRTS) == 0)
- {
- /* Yes.. update TCP timing states and poll uIP for new XMIT data. Hmmm..
- * looks like a bug here to me. Does this mean if there is a transmit
- * in progress, we will missing TCP time state updates?
- */
-
- (void)uip_timer(&priv->dev, enc_uiptxpoll, ENC_POLLHSEC);
- }
-
- /* Release lock on the SPI bus and uIP */
-
- enc_unlock(priv);
- uip_unlock(lock);
-
- /* Setup the watchdog poll timer again */
-
- (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, arg);
-}
-
-/****************************************************************************
- * Function: enc_polltimer
- *
- * Description:
- * Periodic timer handler. Called from the timer interrupt handler.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_polltimer(int argc, uint32_t arg, ...)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)arg;
- int ret;
-
- /* In complex environments, we cannot do SPI transfers from the timout
- * handler because semaphores are probably used to lock the SPI bus. In
- * this case, we will defer processing to the worker thread. This is also
- * much kinder in the use of system resources and is, therefore, probably
- * a good thing to do in any event.
- */
-
- DEBUGASSERT(priv && work_available(&priv->pollwork));
-
- /* Notice that poll watchdog is not active so further poll timeouts can
- * occur until we restart the poll timeout watchdog.
- */
-
- ret = work_queue(HPWORK, &priv->pollwork, enc_pollworker, (FAR void *)priv, 0);
- DEBUGASSERT(ret == OK);
-}
-
-/****************************************************************************
- * Function: enc_ifup
- *
- * Description:
- * NuttX Callback: Bring up the Ethernet interface when an IP address is
- * provided
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int enc_ifup(struct uip_driver_s *dev)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)dev->d_private;
- int ret;
-
- nlldbg("Bringing up: %d.%d.%d.%d\n",
- dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
- (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
-
- /* Lock the SPI bus so that we have exclusive access */
-
- enc_lock(priv);
-
- /* Initialize Ethernet interface, set the MAC address, and make sure that
- * the ENC28J80 is not in power save mode.
- */
-
- ret = enc_reset(priv);
- if (ret == OK)
- {
- enc_setmacaddr(priv);
- enc_pwrfull(priv);
-
- /* Enable interrupts at the ENC28J60. Interrupts are still disabled
- * at the interrupt controller.
- */
-
- enc_wrphy(priv, ENC_PHIE, PHIE_PGEIE | PHIE_PLNKIE);
- enc_bfcgreg(priv, ENC_EIR, EIR_ALLINTS);
- enc_wrgreg(priv, ENC_EIE, EIE_INTIE | EIE_PKTIE | EIE_LINKIE |
- EIE_TXIE | EIE_TXERIE | EIE_RXERIE);
-
- /* Enable the receiver */
-
- enc_bfsgreg(priv, ENC_ECON1, ECON1_RXEN);
-
- /* Set and activate a timer process */
-
- (void)wd_start(priv->txpoll, ENC_WDDELAY, enc_polltimer, 1, (uint32_t)priv);
-
- /* Mark the interface up and enable the Ethernet interrupt at the
- * controller
- */
-
- priv->ifstate = ENCSTATE_UP;
- priv->lower->enable(priv->lower);
- }
-
- /* Un-lock the SPI bus */
-
- enc_unlock(priv);
- return ret;
-}
-
-/****************************************************************************
- * Function: enc_ifdown
- *
- * Description:
- * NuttX Callback: Stop the interface.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int enc_ifdown(struct uip_driver_s *dev)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)dev->d_private;
- irqstate_t flags;
- int ret;
-
- nlldbg("Taking down: %d.%d.%d.%d\n",
- dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
- (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
-
- /* Lock the SPI bus so that we have exclusive access */
-
- enc_lock(priv);
-
- /* Disable the Ethernet interrupt */
-
- flags = irqsave();
- priv->lower->disable(priv->lower);
-
- /* Cancel the TX poll timer and TX timeout timers */
-
- wd_cancel(priv->txpoll);
- wd_cancel(priv->txtimeout);
-
- /* Reset the device and leave in the power save state */
-
- ret = enc_reset(priv);
- enc_pwrsave(priv);
-
- priv->ifstate = ENCSTATE_DOWN;
- irqrestore(flags);
-
- /* Un-lock the SPI bus */
-
- enc_unlock(priv);
- return ret;
-}
-
-/****************************************************************************
- * Function: enc_txavail
- *
- * Description:
- * Driver callback invoked when new TX data is available. This is a
- * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
- * latency.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Called in normal user mode
- *
- ****************************************************************************/
-
-static int enc_txavail(struct uip_driver_s *dev)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)dev->d_private;
- irqstate_t flags;
-
- /* Lock the SPI bus so that we have exclusive access */
-
- enc_lock(priv);
-
- /* Ignore the notification if the interface is not yet up */
-
- flags = irqsave();
- if (priv->ifstate == ENCSTATE_UP)
- {
- /* Check if the hardware is ready to send another packet. The driver
- * starts a transmission process by setting ECON1.TXRTS. When the packet is
- * finished transmitting or is aborted due to an error/cancellation, the
- * ECON1.TXRTS bit will be cleared.
- */
-
- if ((enc_rdgreg(priv, ENC_ECON1) & ECON1_TXRTS) == 0)
- {
- /* The interface is up and TX is idle; poll uIP for new XMIT data */
-
- (void)uip_poll(&priv->dev, enc_uiptxpoll);
- }
- }
-
- /* Un-lock the SPI bus */
-
- irqrestore(flags);
- enc_unlock(priv);
- return OK;
-}
-
-/****************************************************************************
- * Function: enc_addmac
- *
- * Description:
- * NuttX Callback: Add the specified MAC address to the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be added
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int enc_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)dev->d_private;
-
- /* Lock the SPI bus so that we have exclusive access */
-
- enc_lock(priv);
-
- /* Add the MAC address to the hardware multicast routing table */
-
-#warning "Multicast MAC support not implemented"
-
- /* Un-lock the SPI bus */
-
- enc_unlock(priv);
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Function: enc_rmmac
- *
- * Description:
- * NuttX Callback: Remove the specified MAC address from the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be removed
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int enc_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct enc_driver_s *priv = (FAR struct enc_driver_s *)dev->d_private;
-
- /* Lock the SPI bus so that we have exclusive access */
-
- enc_lock(priv);
-
- /* Add the MAC address to the hardware multicast routing table */
-
-#warning "Multicast MAC support not implemented"
-
- /* Un-lock the SPI bus */
-
- enc_unlock(priv);
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Function: enc_pwrsave
- *
- * Description:
- * The ENC28J60 may be commanded to power-down via the SPI interface.
- * When powered down, it will no longer be able to transmit and receive
- * any packets. To maximize power savings:
- *
- * 1. Turn off packet reception by clearing ECON1.RXEN.
- * 2. Wait for any in-progress packets to finish being received by
- * polling ESTAT.RXBUSY. This bit should be clear before proceeding.
- * 3. Wait for any current transmissions to end by confirming ECON1.TXRTS
- * is clear.
- * 4. Set ECON2.VRPS (if not already set).
- * 5. Enter Sleep by setting ECON2.PWRSV. All MAC, MII and PHY registers
- * become inaccessible as a result. Setting PWRSV also clears
- * ESTAT.CLKRDY automatically.
- *
- * In Sleep mode, all registers and buffer memory will maintain their
- * states. The ETH registers and buffer memory will still be accessible
- * by the host controller. Additionally, the clock driver will continue
- * to operate. The CLKOUT function will be unaffected.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_pwrsave(FAR struct enc_driver_s *priv)
-{
- nllvdbg("Set PWRSV\n");
-
- /* 1. Turn off packet reception by clearing ECON1.RXEN. */
-
- enc_bfcgreg(priv, ENC_ECON1, ECON1_RXEN);
-
- /* 2. Wait for any in-progress packets to finish being received by
- * polling ESTAT.RXBUSY. This bit should be clear before proceeding.
- */
-
- if (enc_waitbreg(priv, ENC_ESTAT, ESTAT_RXBUSY, 0) == OK)
- {
- /* 3. Wait for any current transmissions to end by confirming
- * ECON1.TXRTS is clear.
- */
-
- enc_waitbreg(priv, ENC_ECON1, ECON1_TXRTS, 0);
-
- /* 4. Set ECON2.VRPS (if not already set). */
- /* enc_bfsgreg(priv, ENC_ECON2, ECON2_VRPS); <-- Set in enc_reset() */
-
- /* 5. Enter Sleep by setting ECON2.PWRSV. */
-
- enc_bfsgreg(priv, ENC_ECON2, ECON2_PWRSV);
- }
-}
-
-/****************************************************************************
- * Function: enc_pwrfull
- *
- * Description:
- * When normal operation is desired, the host controller must perform
- * a slightly modified procedure:
- *
- * 1. Wake-up by clearing ECON2.PWRSV.
- * 2. Wait at least 300 ìs for the PHY to stabilize. To accomplish the
- * delay, the host controller may poll ESTAT.CLKRDY and wait for it
- * to become set.
- * 3. Restore receive capability by setting ECON1.RXEN.
- *
- * After leaving Sleep mode, there is a delay of many milliseconds
- * before a new link is established (assuming an appropriate link
- * partner is present). The host controller may wish to wait until
- * the link is established before attempting to transmit any packets.
- * The link status can be determined by polling the PHSTAT2.LSTAT bit.
- * Alternatively, the link change interrupt may be used if it is
- * enabled.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_pwrfull(FAR struct enc_driver_s *priv)
-{
- nllvdbg("Clear PWRSV\n");
-
- /* 1. Wake-up by clearing ECON2.PWRSV. */
-
- enc_bfcgreg(priv, ENC_ECON2, ECON2_PWRSV);
-
- /* 2. Wait at least 300 ìs for the PHY to stabilize. To accomplish the
- * delay, the host controller may poll ESTAT.CLKRDY and wait for it to
- * become set.
- */
-
- enc_waitbreg(priv, ENC_ESTAT, ESTAT_CLKRDY, ESTAT_CLKRDY);
-
- /* 3. Restore receive capability by setting ECON1.RXEN.
- *
- * The caller will do this when it is read to receive packets
- */
-}
-
-/****************************************************************************
- * Function: enc_setmacaddr
- *
- * Description:
- * Set the MAC address to the configured value. This is done after ifup
- * or after a TX timeout. Note that this means that the interface must
- * be down before configuring the MAC addr.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void enc_setmacaddr(FAR struct enc_driver_s *priv)
-{
- /* Program the hardware with it's MAC address (for filtering).
- * MAADR1 MAC Address Byte 1 (MAADR<47:40>), OUI Byte 1
- * MAADR2 MAC Address Byte 2 (MAADR<39:32>), OUI Byte 2
- * MAADR3 MAC Address Byte 3 (MAADR<31:24>), OUI Byte 3
- * MAADR4 MAC Address Byte 4 (MAADR<23:16>)
- * MAADR5 MAC Address Byte 5 (MAADR<15:8>)
- * MAADR6 MAC Address Byte 6 (MAADR<7:0>)
- */
-
- enc_wrbreg(priv, ENC_MAADR1, priv->dev.d_mac.ether_addr_octet[0]);
- enc_wrbreg(priv, ENC_MAADR2, priv->dev.d_mac.ether_addr_octet[1]);
- enc_wrbreg(priv, ENC_MAADR3, priv->dev.d_mac.ether_addr_octet[2]);
- enc_wrbreg(priv, ENC_MAADR4, priv->dev.d_mac.ether_addr_octet[3]);
- enc_wrbreg(priv, ENC_MAADR5, priv->dev.d_mac.ether_addr_octet[4]);
- enc_wrbreg(priv, ENC_MAADR6, priv->dev.d_mac.ether_addr_octet[5]);
-}
-
-/****************************************************************************
- * Function: enc_reset
- *
- * Description:
- * Stop, reset, re-initialize, and restart the ENC28J60. This is done
- * initially, on ifup, and after a TX timeout.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int enc_reset(FAR struct enc_driver_s *priv)
-{
- uint8_t regval;
-
- nlldbg("Reset\n");
-
- /* Configure SPI for the ENC28J60 */
-
- enc_configspi(priv->spi);
-
- /* Reset the ENC28J60 */
-
- enc_src(priv);
-
- /* Initialize ECON1: Clear ECON1 */
-
- enc_wrgreg(priv, ENC_ECON1, 0x00);
-
- /* Initialize ECON2: Enable address auto increment and voltage
- * regulator powersave.
- */
-
- enc_wrgreg(priv, ENC_ECON2, ECON2_AUTOINC | ECON2_VRPS);
-
- /* Initialize receive buffer.
- * First, set the receive buffer start address.
- */
-
- priv->nextpkt = PKTMEM_RX_START;
- enc_wrbreg(priv, ENC_ERXSTL, PKTMEM_RX_START & 0xff);
- enc_wrbreg(priv, ENC_ERXSTH, PKTMEM_RX_START >> 8);
-
- /* Set the receive data pointer */
-
- enc_wrbreg(priv, ENC_ERXRDPTL, PKTMEM_RX_START & 0xff);
- enc_wrbreg(priv, ENC_ERXRDPTH, PKTMEM_RX_START >> 8);
-
- /* Set the receive buffer end. */
-
- enc_wrbreg(priv, ENC_ERXNDL, PKTMEM_RX_END & 0xff);
- enc_wrbreg(priv, ENC_ERXNDH, PKTMEM_RX_END >> 8);
-
- /* Set transmit buffer start. */
-
- enc_wrbreg(priv, ENC_ETXSTL, PKTMEM_TX_START & 0xff);
- enc_wrbreg(priv, ENC_ETXSTH, PKTMEM_TX_START >> 8);
-
- /* Check if we are actually communicating with the ENC28J60. If its
- * 0x00 or 0xff, then we are probably not communicating correctly
- * via SPI.
- */
-
- regval = enc_rdbreg(priv, ENC_EREVID);
- if (regval == 0x00 || regval == 0xff)
- {
- nlldbg("Bad Rev ID: %02x\n", regval);
- return -ENODEV;
- }
-
- nllvdbg("Rev ID: %02x\n", regval);
-
- /* Set filter mode: unicast OR broadcast AND crc valid */
-
- enc_wrbreg(priv, ENC_ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN);
-
- /* Enable MAC receive */
-
- enc_wrbreg(priv, ENC_MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS);
-
- /* Enable automatic padding and CRC operations */
-
-#ifdef CONFIG_ENC28J60_HALFDUPLEX
- enc_wrbreg(priv, ENC_MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN);
- enc_wrbreg(priv, ENC_MACON4, MACON4_DEFER); /* Defer transmission enable */
-
- /* Set Non-Back-to-Back Inter-Packet Gap */
-
- enc_wrbreg(priv, ENC_MAIPGL, 0x12);
- enc_wrbreg(priv, ENC_MAIPGH, 0x0c);
-
- /* Set Back-to-Back Inter-Packet Gap */
-
- enc_wrbreg(priv, ENC_MABBIPG, 0x12);
-#else
- /* Set filter mode: unicast OR broadcast AND crc valid AND Full Duplex */
-
- enc_wrbreg(priv, ENC_MACON3,
- MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX);
-
- /* Set Non-Back-to-Back Inter-Packet Gap */
-
- enc_wrbreg(priv, ENC_MAIPGL, 0x12);
-
- /* Set Back-to-Back Inter-Packet Gap */
-
- enc_wrbreg(priv, ENC_MABBIPG, 0x15);
-#endif
-
- /* Set the maximum packet size which the controller will accept */
-
- enc_wrbreg(priv, ENC_MAMXFLL, CONFIG_NET_BUFSIZE & 0xff);
- enc_wrbreg(priv, ENC_MAMXFLH, CONFIG_NET_BUFSIZE >> 8);
-
- /* Configure LEDs (No, just use the defaults for now) */
- /* enc_wrphy(priv, ENC_PHLCON, ??); */
-
- /* Setup up PHCON1 & 2 */
-
-#ifdef CONFIG_ENC28J60_HALFDUPLEX
- enc_wrphy(priv, ENC_PHCON1, 0x00);
- enc_wrphy(priv, ENC_PHCON2, PHCON2_HDLDIS);
-#else
- enc_wrphy(priv, ENC_PHCON1, PHCON1_PDPXMD);
- enc_wrphy(priv, ENC_PHCON2, 0x00);
-#endif
- return OK;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: enc_initialize
- *
- * Description:
- * Initialize the Ethernet driver. The ENC28J60 device is assumed to be
- * in the post-reset state upon entry to this function.
- *
- * Parameters:
- * spi - A reference to the platform's SPI driver for the ENC28J60
- * lower - The MCU-specific interrupt used to control low-level MCU
- * functions (i.e., ENC28J60 GPIO interrupts).
- * devno - If more than one ENC28J60 is supported, then this is the
- * zero based number that identifies the ENC28J60;
- *
- * Returned Value:
- * OK on success; Negated errno on failure.
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-int enc_initialize(FAR struct spi_dev_s *spi,
- FAR const struct enc_lower_s *lower, unsigned int devno)
-{
- FAR struct enc_driver_s *priv;
-
- DEBUGASSERT(devno < CONFIG_ENC28J60_NINTERFACES);
- priv = &g_enc28j60[devno];
-
- /* Initialize the driver structure */
-
- memset(g_enc28j60, 0, CONFIG_ENC28J60_NINTERFACES*sizeof(struct enc_driver_s));
- priv->dev.d_ifup = enc_ifup; /* I/F down callback */
- priv->dev.d_ifdown = enc_ifdown; /* I/F up (new IP address) callback */
- priv->dev.d_txavail = enc_txavail; /* New TX data callback */
-#ifdef CONFIG_NET_IGMP
- priv->dev.d_addmac = enc_addmac; /* Add multicast MAC address */
- priv->dev.d_rmmac = enc_rmmac; /* Remove multicast MAC address */
-#endif
- priv->dev.d_private = priv; /* Used to recover private state from dev */
-
- /* Create a watchdog for timing polling for and timing of transmisstions */
-
- priv->txpoll = wd_create(); /* Create periodic poll timer */
- priv->txtimeout = wd_create(); /* Create TX timeout timer */
- priv->spi = spi; /* Save the SPI instance */
- priv->lower = lower; /* Save the low-level MCU interface */
-
- /* The interface should be in the down state. However, this function is called
- * too early in initalization to perform the ENC28J60 reset in enc_ifdown. We
- * are depending upon the fact that the application level logic will call enc_ifdown
- * later to reset the ENC28J60. NOTE: The MAC address will not be set up until
- * enc_ifup() is called. That gives the app time to set the MAC address before
- * bringing the interface up.
- */
-
- priv->ifstate = ENCSTATE_UNINIT;
-
- /* Attach the interrupt to the driver (but don't enable it yet) */
-
- if (lower->attach(lower, enc_interrupt))
- {
- /* We could not attach the ISR to the interrupt */
-
- return -EAGAIN;
- }
-
- /* Register the device with the OS so that socket IOCTLs can be performed */
-
- return netdev_register(&priv->dev);
-}
-
-/****************************************************************************
- * Function: enc_stats
- *
- * Description:
- * Return accumulated ENC28J60 statistics. Statistics are cleared after
- * being returned.
- *
- * Parameters:
- * devno - If more than one ENC28J60 is supported, then this is the
- * zero based number that identifies the ENC28J60;
- * stats - The user-provided location to return the statistics.
- *
- * Returned Value:
- * OK on success; Negated errno on failure.
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_ENC28J60_STATS
-int enc_stats(unsigned int devno, struct enc_stats_s *stats)
-{
- FAR struct enc_driver_s *priv ;
- irqstate_t flags;
-
- DEBUGASSERT(devno < CONFIG_ENC28J60_NINTERFACES);
- priv = &g_enc28j60[devno];
-
- /* Disable the Ethernet interrupt */
-
- flags = irqsave();
- memcpy(stats, &priv->stats, sizeof(struct enc_stats_s));
- memset(&priv->stats, 0, sizeof(struct enc_stats_s));
- irqrestore(flags);
- return OK;
-}
-#endif
-#endif /* CONFIG_NET && CONFIG_ENC28J60_NET */
-
diff --git a/nuttx/drivers/net/enc28j60.h b/nuttx/drivers/net/enc28j60.h
deleted file mode 100644
index 6a0553a95..000000000
--- a/nuttx/drivers/net/enc28j60.h
+++ /dev/null
@@ -1,477 +0,0 @@
-/****************************************************************************
- * drivers/net/enc28j60.h
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * References:
- * - ENC28J60 Data Sheet, Stand-Alone Ethernet Controller with SPI Interface,
- * DS39662C, 2008 Microchip Technology Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_NET_ENC28J60_H
-#define __DRIVERS_NET_ENC28J60_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* ENC28J60 Commands ********************************************************/
-/* A total of seven instructions are implemented on the ENC28J60. Where:
- *
- * aaaaaa is the 5-bit address of a control register, and
- * dddddddd is one or more bytes of data that may accompany the command.
- */
-
-#define ENC_RCR (0x00) /* Read Control Register
- * 000 | aaaaa | (Register value returned)) */
-#define ENC_RBM (0x3a) /* Read Buffer Memory
- * 001 | 11010 | (Read buffer data follows) */
-#define ENC_WCR (0x40) /* Write Control Register
- * 010 | aaaaa | dddddddd */
-#define ENC_WBM (0x7a) /* Write Buffer Memory
- * 011 | 11010 | (Write buffer data follows) */
-#define ENC_BFS (0x80) /* Bit Field Set
- * 100 | aaaaa | dddddddd */
-#define ENC_BFC (0xa0) /* Bit Field Clear
- * 101 | aaaaa | dddddddd */
-#define ENC_SRC (0xff) /* System Reset
- * 111 | 11111 | (No data) */
-
-/* Global Control Registers *************************************************/
-/* Control registers are accessed with the RCR, RBM, WCR, BFS, and BFC
- * commands. The following identifies all ENC28J60 control registers. The
- * control register memory is partitioned into four banks, selectable by the
- * bank select bits, BSEL1:BSEL0, in the ECON1 register.
- *
- * The last five locations (0x1b to 0x1f) of all banks point to a common set
- * of registers: EIE, EIR, ESTAT, ECON2 and ECON1. These are key registers
- * used in controlling and monitoring the operation of the device. Their
- * common mapping allows easy access without switching the bank.
- *
- * Control registers for the ENC28J60 are generically grouped as ETH, MAC and
- * MII registers. Register names starting with E belong to the ETH group.
- * Similarly, registers names starting with MA belong to the MAC group and
- * registers prefixed with MI belong to the MII group.
- */
-
-#define ENC_EIE (0x1b) /* Ethernet Interrupt Enable Register */
-#define ENC_EIR (0x1c) /* Ethernet Interupt Request Register */
-#define ENC_ESTAT (0x1d) /* Ethernet Status Register */
-#define ENC_ECON2 (0x1e) /* Ethernet Control 2 Register */
-#define ENC_ECON1 (0x1f) /* Ethernet Control 1 Register */
-
-/* Ethernet Interrupt Enable Register Bit Definitions */
-
-#define EIE_RXERIE (1 << 0) /* Bit 0: Receive Error Interrupt Enable */
-#define EIE_TXERIE (1 << 1) /* Bit 1: Transmit Error Interrupt Enable */
- /* Bit 2: Reserved */
-#define EIE_TXIE (1 << 3) /* Bit 3: Transmit Enable */
-#define EIE_LINKIE (1 << 4) /* Bit 4: Link Status Change Interrupt Enable */
-#define EIE_DMAIE (1 << 5) /* Bit 5: DMA Interrupt Enable */
-#define EIE_PKTIE (1 << 6) /* Bit 6: Receive Packet Pending Interrupt Enable */
-#define EIE_INTIE (1 << 7) /* Bit 7: Global INT Interrupt Enable */
-
-/* Ethernet Interrupt Request Register Bit Definitions */
-
-#define EIR_RXERIF (1 << 0) /* Bit 0: Receive Error Interrupt */
-#define EIR_TXERIF (1 << 1) /* Bit 1: Transmit Error Interrupt */
- /* Bit 2: Reserved */
-#define EIR_TXIF (1 << 3) /* Bit 3: Transmit Interrupt */
-#define EIR_LINKIF (1 << 4) /* Bit 4: Link Change Interrupt */
-#define EIR_DMAIF (1 << 5) /* Bit 5: DMA Interrupt */
-#define EIR_PKTIF (1 << 6) /* Bit 6: Receive Packet Pending Interrupt */
- /* Bit 7: Reserved */
-#define EIR_ALLINTS (0x7b) /* All interrupts */
-
-/* Ethernet Status Register Bit Definitions */
-
-#define ESTAT_CLKRDY (1 << 0) /* Bit 0: Clock Ready */
-#define ESTAT_TXABRT (1 << 1) /* Bit 1: Transmit Abort Error */
-#define ESTAT_RXBUSY (1 << 2) /* Bit 2: Receive Busy */
- /* Bit 3: Reserved */
-#define ESTAT_LATECOL (1 << 4) /* Bit 4: Late Collision Error */
- /* Bit 5: Reserved */
-#define ESTAT_BUFER (1 << 6) /* Bit 6: Ethernet Buffer Error Status */
-#define ESTAT_INT (1 << 7) /* Bit 7: INT Interrupt */
-
-/* Ethernet Control 1 Register Bit Definitions */
-
-#define ECON1_BSEL_SHIFT (0) /* Bits 0-1: Bank select */
-#define ECON1_BSEL_MASK (3 << ECON1_BSEL_SHIFT)
-# define ECON1_BSEL_BANK0 (0 << ECON1_BSEL_SHIFT) /* Bank 0 */
-# define ECON1_BSEL_BANK1 (1 << ECON1_BSEL_SHIFT) /* Bank 1 */
-# define ECON1_BSEL_BANK2 (2 << ECON1_BSEL_SHIFT) /* Bank 2 */
-# define ECON1_BSEL_BANK3 (3 << ECON1_BSEL_SHIFT) /* Bank 3 */
-#define ECON1_RXEN (1 << 2) /* Bit 2: Receive Enable */
-#define ECON1_TXRTS (1 << 3) /* Bit 3: Transmit Request to Send */
-#define ECON1_CSUMEN (1 << 4) /* Bit 4: DMA Checksum Enable */
-#define ECON1_DMAST (1 << 5) /* Bit 5: DMA Start and Busy Status */
-#define ECON1_RXRST (1 << 6) /* Bit 6: Receive Logic Reset */
-#define ECON1_TXRST (1 << 7) /* Bit 7: Transmit Logic Reset */
-
-/* Ethernet Control 2 Register */
- /* Bits 0-2: Reserved */
-#define ECON2_VRPS (1 << 3) /* Bit 3: Voltage Regulator Power Save Enable */
- /* Bit 4: Reserved */
-#define ECON2_PWRSV (1 << 5) /* Bit 5: Power Save Enable */
-#define ECON2_PKTDEC (1 << 6) /* Bit 6: Packet Decrement */
-#define ECON2_AUTOINC (1 << 7) /* Bit 7: Automatic Buffer Pointer Increment Enable */
-
-/* Banked Control Registers *************************************************/
-/* The remaining control registers are identified with a a 5 bit address and
- * a bank selection. We pack the bank number and an indication if this is
- * a MAC/PHY register access together with the control register address
- * together to keep the design simpler.
- */
-
-#define ENC_ADDR_SHIFT (0) /* Bits 0-4: Register address */
-#define ENC_ADDR_MASK (0x1f << ENC_ADDR_SHIFT)
-#define ENC_BANK_SHIFT (5) /* Bits 5-6: Bank number */
-#define ENC_BANK_MASK (3 << ENC_BSEL_SHIFT)
-# define ENC_BANK0 (0 << ENC_BSEL_SHIFT)
-# define ENC_BANK1 (1 << ENC_BSEL_SHIFT)
-# define ENC_BANK2 (2 << ENC_BSEL_SHIFT)
-# define ENC_BANK3 (3 << ENC_BSEL_SHIFT)
-#define ENC_PHYMAC_SHIFT (7) /* Bit 7: This is a PHY/MAC command */
-#define ENC_PHYMAC (1 << ENC_PHYMAC_SHIFT)
-
-#define REGADDR(a,b,m) ((m) << ENC_PHYMAC_SHIFT | (b) << ENC_BANK_SHIFT | (a))
-#define GETADDR(a) ((a) & ENC_ADDR_MASK)
-#define GETBANK(a) (((a) >> ENC_BANK_SHIFT) & 3)
-#define ISPHYMAC(a) (((a) & ENC_PHYMAC) != 0)
-
-/* Bank 0 Control Register Addresses */
-
-#define ENC_ERDPTL REGADDR(0x00, 0, 0) /* Read Pointer Low Byte (ERDPT<7:0> */
-#define ENC_ERDPTH REGADDR(0x01, 0, 0) /* Read Pointer High Byte (ERDPT<12:8>) */
-#define ENC_EWRPTL REGADDR(0x02, 0, 0) /* Write Pointer Low Byte (EWRPT<7:0>) */
-#define ENC_EWRPTH REGADDR(0x03, 0, 0) /* Write Pointer High Byte (EWRPT<12:8>) */
-#define ENC_ETXSTL REGADDR(0x04, 0, 0) /* TX Start Low Byte (ETXST<7:0>) */
-#define ENC_ETXSTH REGADDR(0x05, 0, 0) /* TX Start High Byte (ETXST<12:8>) */
-#define ENC_ETXNDL REGADDR(0x06, 0, 0) /* TX End Low Byte (ETXND<7:0>) */
-#define ENC_ETXNDH REGADDR(0x07, 0, 0) /* TX End High Byte (ETXND<12:8>) */
-#define ENC_ERXSTL REGADDR(0x08, 0, 0) /* RX Start Low Byte (ERXST<7:0>) */
-#define ENC_ERXSTH REGADDR(0x09, 0, 0) /* RX Start High Byte (ERXST<12:8>) */
-#define ENC_ERXNDL REGADDR(0x0a, 0, 0) /* RX End Low Byte (ERXND<7:0>) */
-#define ENC_ERXNDH REGADDR(0x0b, 0, 0) /* RX End High Byte (ERXND<12:8>) */
-#define ENC_ERXRDPTL REGADDR(0x0c, 0, 0) /* RX RD Pointer Low Byte (ERXRDPT<7:0>) */
-#define ENC_ERXRDPTH REGADDR(0x0d, 0, 0) /* RX RD Pointer High Byte (ERXRDPT<12:8>) */
-#define ENC_ERXWRPTL REGADDR(0x0e, 0, 0) /* RX WR Pointer Low Byte (ERXWRPT<7:0>) */
-#define ENC_ERXWRPTH REGADDR(0x0f, 0, 0) /* RX WR Pointer High Byte (ERXWRPT<12:8>) */
-#define ENC_EDMASTL REGADDR(0x10, 0, 0) /* DMA Start Low Byte (EDMAST<7:0>) */
-#define ENC_EDMASTH REGADDR(0x11, 0, 0) /* DMA Start High Byte (EDMAST<12:8>) */
-#define ENC_EDMANDL REGADDR(0x12, 0, 0) /* DMA End Low Byte (EDMAND<7:0>) */
-#define ENC_EDMANDH REGADDR(0x13, 0, 0) /* DMA End High Byte (EDMAND<12:8>) */
-#define ENC_EDMADSTL REGADDR(0x14, 0, 0) /* DMA Destination Low Byte (EDMADST<7:0>) */
-#define ENC_EDMADSTH REGADDR(0x15, 0, 0) /* DMA Destination High Byte (EDMADST<12:8>) */
-#define ENC_EDMACSL REGADDR(0x16, 0, 0) /* DMA Checksum Low Byte (EDMACS<7:0>) */
-#define ENC_EDMACSH REGADDR(0x17, 0, 0) /* DMA Checksum High Byte (EDMACS<15:8>) */
- /* 0x18-0x1a: Reserved */
- /* 0x1b-0x1f: EIE, EIR, ESTAT, ECON2, ECON1 */
-/* Bank 1 Control Register Addresses */
-
-#define ENC_EHT0 REGADDR(0x00, 1, 0) /* Hash Table Byte 0 (EHT<7:0>) */
-#define ENC_EHT1 REGADDR(0x01, 1, 0) /* Hash Table Byte 1 (EHT<15:8>) */
-#define ENC_EHT2 REGADDR(0x02, 1, 0) /* Hash Table Byte 2 (EHT<23:16>) */
-#define ENC_EHT3 REGADDR(0x03, 1, 0) /* Hash Table Byte 3 (EHT<31:24>) */
-#define ENC_EHT4 REGADDR(0x04, 1, 0) /* Hash Table Byte 4 (EHT<39:32>) */
-#define ENC_EHT5 REGADDR(0x05, 1, 0) /* Hash Table Byte 5 (EHT<47:40>) */
-#define ENC_EHT6 REGADDR(0x06, 1, 0) /* Hash Table Byte 6 (EHT<55:48>) */
-#define ENC_EHT7 REGADDR(0x07, 1, 0) /* Hash Table Byte 7 (EHT<63:56>) */
-#define ENC_EPMM0 REGADDR(0x08, 1, 0) /* Pattern Match Mask Byte 0 (EPMM<7:0>) */
-#define ENC_EPMM1 REGADDR(0x09, 1, 0) /* Pattern Match Mask Byte 1 (EPMM<15:8>) */
-#define ENC_EPMM2 REGADDR(0x0a, 1, 0) /* Pattern Match Mask Byte 2 (EPMM<23:16>) */
-#define ENC_EPMM3 REGADDR(0x0b, 1, 0) /* Pattern Match Mask Byte 3 (EPMM<31:24>) */
-#define ENC_EPMM4 REGADDR(0x0c, 1, 0) /* Pattern Match Mask Byte 4 (EPMM<39:32>) */
-#define ENC_EPMM5 REGADDR(0x0d, 1, 0) /* Pattern Match Mask Byte 5 (EPMM<47:40>) */
-#define ENC_EPMM6 REGADDR(0x0e, 1, 0) /* Pattern Match Mask Byte 6 (EPMM<55:48>) */
-#define ENC_EPMM7 REGADDR(0x0f, 1, 0) /* Pattern Match Mask Byte 7 (EPMM<63:56>) */
-#define ENC_EPMCSL REGADDR(0x10, 1, 0) /* Pattern Match Checksum Low Byte (EPMCS<7:0>) */
-#define ENC_EPMCSH REGADDR(0x11, 1, 0) /* Pattern Match Checksum High Byte (EPMCS<15:0>) */
- /* 0x12-0x13: Reserved */
-#define ENC_EPMOL REGADDR(0x14, 1, 0) /* Pattern Match Offset Low Byte (EPMO<7:0>) */
-#define ENC_EPMOH REGADDR(0x15, 1, 0) /* Pattern Match Offset High Byte (EPMO<12:8>) */
- /* 0x16-0x17: Reserved */
-#define ENC_ERXFCON REGADDR(0x18, 1, 0) /* Receive Filter Configuration */
-#define ENC_EPKTCNT REGADDR(0x19, 1, 0) /* Ethernet Packet Count */
- /* 0x1a: Reserved */
- /* 0x1b-0x1f: EIE, EIR, ESTAT, ECON2, ECON1 */
-
-/* Receive Filter Configuration Bit Definitions */
-
-#define ERXFCON_BCEN (1 << 0) /* Bit 0: Broadcast Filter Enable */
-#define ERXFCON_MCEN (1 << 1) /* Bit 1: Multicast Filter Enable */
-#define ERXFCON_HTEN (1 << 2) /* Bit 2: Hash Table Filter Enable */
-#define ERXFCON_MPEN (1 << 3) /* Bit 3: Magic Packet Filter Enable */
-#define ERXFCON_PMEN (1 << 4) /* Bit 4: Pattern Match Filter Enable */
-#define ERXFCON_CRCEN (1 << 5) /* Bit 5: Post-Filter CRC Check Enable */
-#define ERXFCON_ANDOR (1 << 6) /* Bit 6: AND/OR Filter Select */
-#define ERXFCON_UCEN (1 << 7) /* Bit 7: Unicast Filter Enable */
-
-/* Bank 2 Control Register Addresses */
-
-#define ENC_MACON1 REGADDR(0x00, 2, 1) /* MAC Control 1 */
- /* 0x01: Reserved */
-#define ENC_MACON3 REGADDR(0x02, 2, 1) /* MAC Control 3 */
-#define ENC_MACON4 REGADDR(0x03, 2, 1) /* MAC Control 4 */
-#define ENC_MABBIPG REGADDR(0x04, 2, 1) /* Back-to-Back Inter-Packet Gap (BBIPG<6:0>) */
- /* 0x05: Reserved */
-#define ENC_MAIPGL REGADDR(0x06, 2, 1) /* Non-Back-to-Back Inter-Packet Gap Low Byte (MAIPGL<6:0>) */
-#define ENC_MAIPGH REGADDR(0x07, 2, 1) /* Non-Back-to-Back Inter-Packet Gap High Byte (MAIPGH<6:0>) */
-#define ENC_MACLCON1 REGADDR(0x08, 2, 1) /* MAC Collision Control 1 */
-#define ENC_MACLCON2 REGADDR(0x09, 2, 1) /* MAC Collision Control 2 */
-#define ENC_MAMXFLL REGADDR(0x0a, 2, 1) /* Maximum Frame Length Low Byte (MAMXFL<7:0>) */
-#define ENC_MAMXFLH REGADDR(0x0b, 2, 1) /* Maximum Frame Length High Byte (MAMXFL<15:8>) */
- /* 0x0c-0x11: Reserved */
-#define ENC_MICMD REGADDR(0x12, 2, 1) /* MII Command Register */
- /* 0x13: Reserved */
-#define ENC_MIREGADR REGADDR(0x14, 2, 1) /* MII Register Address */
- /* 0x15: Reserved */
-#define ENC_MIWRL REGADDR(0x16, 2, 1) /* MII Write Data Low Byte (MIWR<7:0>) */
-#define ENC_MIWRH REGADDR(0x17, 2, 1) /* MII Write Data High Byte (MIWR<15:8>) */
-#define ENC_MIRDL REGADDR(0x18, 2, 1) /* MII Read Data Low Byte (MIRD<7:0>) */
-#define ENC_MIRDH REGADDR(0x19, 2, 1) /* MII Read Data High Byte(MIRD<15:8>) */
- /* 0x1a: Reserved */
- /* 0x1b-0x1f: EIE, EIR, ESTAT, ECON2, ECON1 */
-
-/* MAC Control 1 Register Bit Definitions */
-
-#define MACON1_MARXEN (1 << 0) /* Bit 0: MAC Receive Enable */
-#define MACON1_PASSALL (1 << 1) /* Bit 1: Pass All Received Frames Enable */
-#define MACON1_RXPAUS (1 << 2) /* Bit 2: Pause Control Frame Reception Enable */
-#define MACON1_TXPAUS (1 << 3) /* Bit 3: Pause Control Frame Transmission Enable */
- /* Bits 4-7: Unimplemented or reserved */
-
-/* MAC Control 1 Register Bit Definitions */
-
-#define MACON3_FULDPX (1 << 0) /* Bit 0: MAC Full-Duplex Enable */
-#define MACON3_FRMLNEN (1 << 1) /* Bit 1: Frame Length Checking Enable */
-#define MACON3_HFRMLEN (1 << 2) /* Bit 2: Huge Frame Enable */
-#define MACON3_PHDRLEN (1 << 3) /* Bit 3: Proprietary Header Enable */
-#define MACON3_TXCRCEN (1 << 4) /* Bit 4: Transmit CRC Enable */
-#define MACON3_PADCFG0 (1 << 5) /* Bit 5: Automatic Pad and CRC Configuration */
-#define MACON3_PADCFG1 (1 << 6) /* Bit 6: " " " " " " " " " " */
-#define MACON3_PADCFG2 (1 << 7) /* Bit 7: " " " " " " " " " " */
-
-/* MAC Control 1 Register Bit Definitions */
-
-#define MACON4_NOBKOFF (1 << 4) /* Bit 4: No Backoff Enable */
-#define MACON4_BPEN (1 << 5) /* Bit 5: No Backoff During Backpressure Enable */
-#define MACON4_DEFER (1 << 6) /* Bit 6: Defer Transmission Enable bit */
-
-/* MII Command Register Bit Definitions */
-
-#define MICMD_MIIRD (1 << 0) /* Bit 0: MII Read Enable */
-#define MICMD_MIISCAN (1 << 1) /* Bit 1: MII Scan Enable */
-
-/* Bank 3 Control Register Addresses */
-
-#define ENC_MAADR5 REGADDR(0x00, 3, 1) /* MAC Address Byte 5 (MAADR<15:8>) */
-#define ENC_MAADR6 REGADDR(0x01, 3, 1) /* MAC Address Byte 6 (MAADR<7:0>) */
-#define ENC_MAADR3 REGADDR(0x02, 3, 1) /* MAC Address Byte 3 (MAADR<31:24>), OUI Byte 3 */
-#define ENC_MAADR4 REGADDR(0x03, 3, 1) /* MAC Address Byte 4 (MAADR<23:16>) */
-#define ENC_MAADR1 REGADDR(0x04, 3, 1) /* MAC Address Byte 1 (MAADR<47:40>), OUI Byte 1 */
-#define ENC_MAADR2 REGADDR(0x05, 3, 1) /* MAC Address Byte 2 (MAADR<39:32>), OUI Byte 2 */
-#define ENC_EBSTSD REGADDR(0x06, 3, 0) /* Built-in Self-Test Fill Seed (EBSTSD<7:0>) */
-#define ENC_EBSTCON REGADDR(0x07, 3, 0) /* Built-in Self-Test Control */
-#define ENC_EBSTCSL REGADDR(0x08, 3, 0) /* Built-in Self-Test Checksum Low Byte (EBSTCS<7:0>) */
-#define ENC_EBSTCSH REGADDR(0x09, 3, 0) /* Built-in Self-Test Checksum High Byte (EBSTCS<15:8>) */
-#define ENC_MISTAT REGADDR(0x0a, 3, 1) /* MII Status Register */
- /* 0x0b-0x11: Reserved */
-#define ENC_EREVID REGADDR(0x12, 3, 0) /* Ethernet Revision ID */
- /* 0x13-0x14: Reserved */
-#define ENC_ECOCON REGADDR(0x15, 3, 0) /* Clock Output Control */
- /* 0x16: Reserved */
-#define ENC_EFLOCON REGADDR(0x17, 3, 0) /* Ethernet Flow Control */
-#define ENC_EPAUSL REGADDR(0x18, 3, 0) /* Pause Timer Value Low Byte (EPAUS<7:0>) */
-#define ENC_EPAUSH REGADDR(0x19, 3, 0) /* Pause Timer Value High Byte (EPAUS<15:8>) */
- /* 0x1a: Reserved */
- /* 0x1b-0x1f: EIE, EIR, ESTAT, ECON2, ECON1 */
-
-/* Built-in Self-Test Control Register Bit Definitions */
-
-#define EBSTCON_BISTST (1 << 0) /* Bit 0: Built-in Self-Test Start/Busy */
-#define EBSTCON_TME (1 << 1) /* Bit 1: Test Mode Enable */
-#define EBSTCON_TMSEL0 (1 << 2) /* Bit 2: Test Mode Select */
-#define EBSTCON_TMSEL1 (1 << 3) /* Bit 3: " " " " " " */
-#define EBSTCON_PSEL (1 << 4) /* Bit 4: Port Select */
-#define EBSTCON_PSV0 (1 << 5) /* Bit 5: Pattern Shift Value */
-#define EBSTCON_PSV1 (1 << 6) /* Bit 6: " " " " " */
-#define EBSTCON_PSV2 (1 << 7) /* Bit 7: " " " " " */
-
-/* MII Status Register Register Bit Definitions */
-
-#define MISTAT_BUSY (1 << 0) /* Bit 0: MII Management Busy */
-#define MISTAT_SCAN (1 << 1) /* Bit 1: MII Management Scan Operation */
-#define MISTAT_NVALID (1 << 2) /* Bit 2: MII Management Read Data Not Valid */
- /* Bits 3-7: Reserved or unimplemented */
-
-/* Ethernet Flow Control Register Bit Definitions */
-
-#define EFLOCON_FCEN0 (1 << 0) /* Bit 0: Flow Control Enable */
-#define EFLOCON_FCEN1 (1 << 1) /* Bit 1: " " " " " " */
-#define EFLOCON_FULDPXS (1 << 2) /* Bit 2: Read-Only MAC Full-Duplex Shadow */
- /* Bits 3-7: Reserved or unimplemented */
-
-/* PHY Registers ************************************************************/
-
-#define ENC_PHCON1 (0x00) /* PHY Control Register 1 */
-#define ENC_PHSTAT1 (0x01) /* PHY Status 1 */
-#define ENC_PHID1 (0x02) /* PHY ID Register 1 */
-#define ENC_PHID2 (0x03) /* PHY ID Register 2 */
-#define ENC_PHCON2 (0x10) /* PHY Control Register 2 */
-#define ENC_PHSTAT2 (0x11) /* PHY Status 2 */
-#define ENC_PHIE (0x12) /* PHY Interrupt Enable Register */
-#define ENC_PHIR (0x13) /* PHY Interrupt Request Register */
-#define ENC_PHLCON (0x14)
-
-/* PHY Control Register 1 Register Bit Definitions */
-
-#define PHCON1_PDPXMD (1 << 8) /* Bit 8: PHY Duplex Mode */
-#define PHCON1_PPWRSV (1 << 11) /* Bit 11: PHY Power-Down */
-#define PHCON1_PLOOPBK (1 << 14) /* Bit 14: PHY Loopback */
-#define PHCON1_PRST (1 << 15) /* Bit 15: PHY Software Reset */
-
-/* PHY Status 1 Register Bit Definitions */
-
-#define PHSTAT1_JBSTAT (1 << 1) /* Bit 1: PHY Latching Jabber Status */
-#define PHSTAT1_LLSTAT (1 << 2) /* Bit 2: PHY Latching Link Status */
-#define PHSTAT1_PHDPX (1 << 11) /* Bit 11: PHY Half-Duplex Capable */
-#define PHSTAT1_PFDPX (1 << 12) /* Bit 12: PHY Full-Duplex Capable */
-
-/* PHY Control Register 2 Register Bit Definitions */
-
-#define PHCON2_HDLDIS (1 << 8) /* Bit 8: PHY Half-Duplex Loopback Disable */
-#define PHCON2_JABBER (1 << 10) /* Bit 10: Jabber Correction Disable */
-#define PHCON2_TXDIS (1 << 13) /* Bit 13: Twisted-Pair Transmitter Disable */
-#define PHCON2_FRCLINK (1 << 14) /* Bit 14: PHY Force Linkup */
-
-/* PHY Status 2 Register Bit Definitions */
-
-#define PHSTAT2_PLRITY (1 << 5) /* Bit 5: Polarity Status */
-#define PHSTAT2_DPXSTAT (1 << 9) /* Bit 9: PHY Duplex Status */
-#define PHSTAT2_LSTAT (1 << 10) /* Bit 10: PHY Link Status */
-#define PHSTAT2_COLSTAT (1 << 11) /* Bit 11: PHY Collision Status */
-#define PHSTAT2_RXSTAT (1 << 12) /* Bit 12: PHY Receive Status */
-#define PHSTAT2_TXSTAT (1 << 13) /* Bit 13: PHY Transmit Status */
-
-/* PHY Interrupt Enable Register Bit Definitions */
-
-#define PHIE_PGEIE (1 << 1) /* Bit 1: PHY Global Interrupt Enable */
-#define PHIE_PLNKIE (1 << 4) /* Bit 4: PHY Link Change Interrupt Enable */
-
-/* PHIR Regiser Bit Definitions */
-
-#define PHIR_PGIF (1 << 2) /* Bit 2: PHY Global Interrupt */
-#define PHIR_PLNKIF (1 << 4) /* Bit 4: PHY Link Change Interrupt */
-
-/* PHLCON Regiser Bit Definitions */
- /* Bit 0: Reserved */
-#define PHLCON_STRCH (1 << 1) /* Bit 1: LED Pulse Stretching Enable */
-#define PHLCON_LFRQ0 (1 << 2) /* Bit 2: LED Pulse Stretch Time Configuration */
-#define PHLCON_LFRQ1 (1 << 3) /* Bit 3: " " " " " " " " " */
-#define PHLCON_LBCFG0 (1 << 4) /* Bit 4: LEDB Configuration */
-#define PHLCON_LBCFG1 (1 << 5) /* Bit 5: " " " " */
-#define PHLCON_LBCFG2 (1 << 6) /* Bit 6: " " " " */
-#define PHLCON_LBCFG3 (1 << 7) /* Bit 7: " " " " */
-#define PHLCON_LACFG0 (1 << 8) /* Bit 8: LEDA Configuration */
-#define PHLCON_LACFG1 (1 << 9) /* Bit 9: " " " " */
-#define PHLCON_LACFG2 (1 << 10) /* Bit 10: " " " " */
-#define PHLCON_LACFG3 (1 << 11) /* Bit 11: " " " " */
-
-/* Packet Memory ************************************************************/
-
-/* 8-Kbyte Transmit/Receive Packet Dual Port SRAM */
-
-#define PKTMEM_START 0x0000
-#define PKTMEM_END 0x1fff
-
-/* Ethernet frames are between 64 and 1518 bytes long */
-
-#define MIN_FRAMELEN 64
-#define MAX_FRAMELEN 1518
-
-/* Packet Control Bits Definitions ******************************************/
-
-#define PKTCTRL_POVERRIDE (1 << 0) /* Bit 0: Per Packet Override */
-#define PKTCTRL_PCRCEN (1 << 1) /* Bit 1: Per Packet CRC Enable */
-#define PKTCTRL_PPADEN (1 << 2) /* Bit 2: Per Packet Padding Enable */
-#define PKTCTRL_PHUGEEN (1 << 3) /* Bit 3: Per Packet Huge Frame Enable */
-
-/* RX Status Bit Definitions ************************************************/
-
-#define RXSTAT_LDEVENT (1 << 0) /* Bit 0: Long event or pack dropped */
- /* Bit 1: Reserved */
-#define RXSTAT_CEPS (1 << 2) /* Bit 2: Carrier event previously seen */
- /* Bit 3: Reserved */
-#define RXSTAT_CRCERROR (1 << 4) /* Bit 4: Frame CRC field bad */
-#define RXSTAT_LENERROR (1 << 5) /* Bit 5: Packet length != data length */
-#define RXSTAT_LENRANGE (1 << 6) /* Bit 6: Type/length field > 1500 bytes */
-#define RXSTAT_OK (1 << 7) /* Bit 7: Packet with valid CRC and no symbol errors */
-#define RXSTAT_MCAST (1 << 8) /* Bit 8: Packet with multicast address */
-#define RXSTAT_BCAST (1 << 9) /* Bit 9: Packet with broadcast address */
-#define RXSTAT_DRIBBLE (1 << 10) /* Bit 10: Additional bits received after packet */
-#define RXSTAT_CTRLFRAME (1 << 11) /* Bit 11: Control frame with valid type/length */
-#define RXSTAT_PAUSE (1 << 12) /* Bit 12: Control frame with pause frame opcde */
-#define RXSTAT_UNKOPCODE (1 << 13) /* Bit 13: Control frame with unknown opcode */
-#define RXSTAT_VLANTYPE (1 << 14) /* Bit 14: Current frame is a VLAN tagged frame */
- /* Bit 15: Zero */
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#ifdef __cplusplus
-#define EXTERN extern "C"
-extern "C" {
-#else
-#define EXTERN extern
-#endif
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DRIVERS_NET_ENC28J60_H */
diff --git a/nuttx/drivers/net/skeleton.c b/nuttx/drivers/net/skeleton.c
deleted file mode 100644
index 00ebea35f..000000000
--- a/nuttx/drivers/net/skeleton.c
+++ /dev/null
@@ -1,692 +0,0 @@
-/****************************************************************************
- * drivers/net/skeleton.c
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-#if defined(CONFIG_NET) && defined(CONFIG_NET_skeleton)
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <time.h>
-#include <string.h>
-#include <debug.h>
-#include <wdog.h>
-#include <errno.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include <nuttx/net/uip/uip.h>
-#include <nuttx/net/uip/uip-arp.h>
-#include <nuttx/net/uip/uip-arch.h>
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-/* CONFIG_skeleton_NINTERFACES determines the number of physical interfaces
- * that will be supported.
- */
-
-#ifndef CONFIG_skeleton_NINTERFACES
-# define CONFIG_skeleton_NINTERFACES 1
-#endif
-
-/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */
-
-#define skeleton_WDDELAY (1*CLK_TCK)
-#define skeleton_POLLHSEC (1*2)
-
-/* TX timeout = 1 minute */
-
-#define skeleton_TXTIMEOUT (60*CLK_TCK)
-
-/* This is a helper pointer for accessing the contents of the Ethernet header */
-
-#define BUF ((struct uip_eth_hdr *)skel->sk_dev.d_buf)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* The skel_driver_s encapsulates all state information for a single hardware
- * interface
- */
-
-struct skel_driver_s
-{
- bool sk_bifup; /* true:ifup false:ifdown */
- WDOG_ID sk_txpoll; /* TX poll timer */
- WDOG_ID sk_txtimeout; /* TX timeout timer */
-
- /* This holds the information visible to uIP/NuttX */
-
- struct uip_driver_s sk_dev; /* Interface understood by uIP */
-};
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static struct skel_driver_s g_skel[CONFIG_skeleton_NINTERFACES];
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Common TX logic */
-
-static int skel_transmit(FAR struct skel_driver_s *skel);
-static int skel_uiptxpoll(struct uip_driver_s *dev);
-
-/* Interrupt handling */
-
-static void skel_receive(FAR struct skel_driver_s *skel);
-static void skel_txdone(FAR struct skel_driver_s *skel);
-static int skel_interrupt(int irq, FAR void *context);
-
-/* Watchdog timer expirations */
-
-static void skel_polltimer(int argc, uint32_t arg, ...);
-static void skel_txtimeout(int argc, uint32_t arg, ...);
-
-/* NuttX callback functions */
-
-static int skel_ifup(struct uip_driver_s *dev);
-static int skel_ifdown(struct uip_driver_s *dev);
-static int skel_txavail(struct uip_driver_s *dev);
-#ifdef CONFIG_NET_IGMP
-static int skel_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-static int skel_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: skel_transmit
- *
- * Description:
- * Start hardware transmission. Called either from the txdone interrupt
- * handling or from watchdog based polling.
- *
- * Parameters:
- * skel - Reference to the driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- * May or may not be called from an interrupt handler. In either case,
- * global interrupts are disabled, either explicitly or indirectly through
- * interrupt handling logic.
- *
- ****************************************************************************/
-
-static int skel_transmit(FAR struct skel_driver_s *skel)
-{
- /* Verify that the hardware is ready to send another packet. If we get
- * here, then we are committed to sending a packet; Higher level logic
- * must have assured that there is no transmission in progress.
- */
-
- /* Increment statistics */
-
- /* Send the packet: address=skel->sk_dev.d_buf, length=skel->sk_dev.d_len */
-
- /* Enable Tx interrupts */
-
- /* Setup the TX timeout watchdog (perhaps restarting the timer) */
-
- (void)wd_start(skel->sk_txtimeout, skeleton_TXTIMEOUT, skel_txtimeout, 1, (uint32_t)skel);
- return OK;
-}
-
-/****************************************************************************
- * Function: skel_uiptxpoll
- *
- * Description:
- * The transmitter is available, check if uIP has any outgoing packets ready
- * to send. This is a callback from uip_poll(). uip_poll() may be called:
- *
- * 1. When the preceding TX packet send is complete,
- * 2. When the preceding TX packet send timesout and the interface is reset
- * 3. During normal TX polling
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- * May or may not be called from an interrupt handler. In either case,
- * global interrupts are disabled, either explicitly or indirectly through
- * interrupt handling logic.
- *
- ****************************************************************************/
-
-static int skel_uiptxpoll(struct uip_driver_s *dev)
-{
- FAR struct skel_driver_s *skel = (FAR struct skel_driver_s *)dev->d_private;
-
- /* If the polling resulted in data that should be sent out on the network,
- * the field d_len is set to a value > 0.
- */
-
- if (skel->sk_dev.d_len > 0)
- {
- uip_arp_out(&skel->sk_dev);
- skel_transmit(skel);
-
- /* Check if there is room in the device to hold another packet. If not,
- * return a non-zero value to terminate the poll.
- */
- }
-
- /* If zero is returned, the polling will continue until all connections have
- * been examined.
- */
-
- return 0;
-}
-
-/****************************************************************************
- * Function: skel_receive
- *
- * Description:
- * An interrupt was received indicating the availability of a new RX packet
- *
- * Parameters:
- * skel - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by interrupt handling logic.
- *
- ****************************************************************************/
-
-static void skel_receive(FAR struct skel_driver_s *skel)
-{
- do
- {
- /* Check for errors and update statistics */
-
- /* Check if the packet is a valid size for the uIP buffer configuration */
-
- /* Copy the data data from the hardware to skel->sk_dev.d_buf. Set
- * amount of data in skel->sk_dev.d_len
- */
-
- /* We only accept IP packets of the configured type and ARP packets */
-
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
-#else
- if (BUF->type == HTONS(UIP_ETHTYPE_IP))
-#endif
- {
- uip_arp_ipin(&skel->sk_dev);
- uip_input(&skel->sk_dev);
-
- /* If the above function invocation resulted in data that should be
- * sent out on the network, the field d_len will set to a value > 0.
- */
-
- if (skel->sk_dev.d_len > 0)
- {
- uip_arp_out(&skel->sk_dev);
- skel_transmit(skel);
- }
- }
- else if (BUF->type == htons(UIP_ETHTYPE_ARP))
- {
- uip_arp_arpin(&skel->sk_dev);
-
- /* If the above function invocation resulted in data that should be
- * sent out on the network, the field d_len will set to a value > 0.
- */
-
- if (skel->sk_dev.d_len > 0)
- {
- skel_transmit(skel);
- }
- }
- }
- while (); /* While there are more packets to be processed */
-}
-
-/****************************************************************************
- * Function: skel_txdone
- *
- * Description:
- * An interrupt was received indicating that the last TX packet(s) is done
- *
- * Parameters:
- * skel - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by the watchdog logic.
- *
- ****************************************************************************/
-
-static void skel_txdone(FAR struct skel_driver_s *skel)
-{
- /* Check for errors and update statistics */
-
- /* If no further xmits are pending, then cancel the TX timeout and
- * disable further Tx interrupts.
- */
-
- wd_cancel(skel->sk_txtimeout);
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&skel->sk_dev, skel_uiptxpoll);
-}
-
-/****************************************************************************
- * Function: skel_interrupt
- *
- * Description:
- * Hardware interrupt handler
- *
- * Parameters:
- * irq - Number of the IRQ that generated the interrupt
- * context - Interrupt register state save info (architecture-specific)
- *
- * Returned Value:
- * OK on success
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int skel_interrupt(int irq, FAR void *context)
-{
- register FAR struct skel_driver_s *skel = &g_skel[0];
-
- /* Get and clear interrupt status bits */
-
- /* Handle interrupts according to status bit settings */
-
- /* Check if we received an incoming packet, if so, call skel_receive() */
-
- skel_receive(skel);
-
- /* Check if a packet transmission just completed. If so, call skel_txdone.
- * This may disable further Tx interrupts if there are no pending
- * tansmissions.
- */
-
- skel_txdone(skel);
-
- return OK;
-}
-
-/****************************************************************************
- * Function: skel_txtimeout
- *
- * Description:
- * Our TX watchdog timed out. Called from the timer interrupt handler.
- * The last TX never completed. Reset the hardware and start again.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by the watchdog logic.
- *
- ****************************************************************************/
-
-static void skel_txtimeout(int argc, uint32_t arg, ...)
-{
- FAR struct skel_driver_s *skel = (FAR struct skel_driver_s *)arg;
-
- /* Increment statistics and dump debug info */
-
- /* Then reset the hardware */
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&skel->sk_dev, skel_uiptxpoll);
-}
-
-/****************************************************************************
- * Function: skel_polltimer
- *
- * Description:
- * Periodic timer handler. Called from the timer interrupt handler.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by the watchdog logic.
- *
- ****************************************************************************/
-
-static void skel_polltimer(int argc, uint32_t arg, ...)
-{
- FAR struct skel_driver_s *skel = (FAR struct skel_driver_s *)arg;
-
- /* Check if there is room in the send another TX packet. We cannot perform
- * the TX poll if he are unable to accept another packet for transmission.
- */
-
- /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm..
- * might be bug here. Does this mean if there is a transmit in progress,
- * we will missing TCP time state updates?
- */
-
- (void)uip_timer(&skel->sk_dev, skel_uiptxpoll, skeleton_POLLHSEC);
-
- /* Setup the watchdog poll timer again */
-
- (void)wd_start(skel->sk_txpoll, skeleton_WDDELAY, skel_polltimer, 1, arg);
-}
-
-/****************************************************************************
- * Function: skel_ifup
- *
- * Description:
- * NuttX Callback: Bring up the Ethernet interface when an IP address is
- * provided
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int skel_ifup(struct uip_driver_s *dev)
-{
- FAR struct skel_driver_s *skel = (FAR struct skel_driver_s *)dev->d_private;
-
- ndbg("Bringing up: %d.%d.%d.%d\n",
- dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
- (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
-
- /* Initialize PHYs, the Ethernet interface, and setup up Ethernet interrupts */
-
- /* Set and activate a timer process */
-
- (void)wd_start(skel->sk_txpoll, skeleton_WDDELAY, skel_polltimer, 1, (uint32_t)skel);
-
- /* Enable the Ethernet interrupt */
-
- skel->sk_bifup = true;
- up_enable_irq(CONFIG_skeleton_IRQ);
- return OK;
-}
-
-/****************************************************************************
- * Function: skel_ifdown
- *
- * Description:
- * NuttX Callback: Stop the interface.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int skel_ifdown(struct uip_driver_s *dev)
-{
- FAR struct skel_driver_s *skel = (FAR struct skel_driver_s *)dev->d_private;
- irqstate_t flags;
-
- /* Disable the Ethernet interrupt */
-
- flags = irqsave();
- up_disable_irq(CONFIG_skeleton_IRQ);
-
- /* Cancel the TX poll timer and TX timeout timers */
-
- wd_cancel(skel->sk_txpoll);
- wd_cancel(skel->sk_txtimeout);
-
- /* Put the EMAC in its reset, non-operational state. This should be
- * a known configuration that will guarantee the skel_ifup() always
- * successfully brings the interface back up.
- */
-
- /* Mark the device "down" */
-
- skel->sk_bifup = false;
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Function: skel_txavail
- *
- * Description:
- * Driver callback invoked when new TX data is available. This is a
- * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
- * latency.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Called in normal user mode
- *
- ****************************************************************************/
-
-static int skel_txavail(struct uip_driver_s *dev)
-{
- FAR struct skel_driver_s *skel = (FAR struct skel_driver_s *)dev->d_private;
- irqstate_t flags;
-
- /* Disable interrupts because this function may be called from interrupt
- * level processing.
- */
-
- flags = irqsave();
-
- /* Ignore the notification if the interface is not yet up */
-
- if (skel->sk_bifup)
- {
- /* Check if there is room in the hardware to hold another outgoing packet. */
-
- /* If so, then poll uIP for new XMIT data */
-
- (void)uip_poll(&skel->sk_dev, skel_uiptxpoll);
- }
-
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Function: skel_addmac
- *
- * Description:
- * NuttX Callback: Add the specified MAC address to the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be added
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int skel_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct skel_driver_s *skel = (FAR struct skel_driver_s *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Function: skel_rmmac
- *
- * Description:
- * NuttX Callback: Remove the specified MAC address from the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be removed
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int skel_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct skel_driver_s *skel = (FAR struct skel_driver_s *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: skel_initialize
- *
- * Description:
- * Initialize the Ethernet controller and driver
- *
- * Parameters:
- * intf - In the case where there are multiple EMACs, this value
- * identifies which EMAC is to be initialized.
- *
- * Returned Value:
- * OK on success; Negated errno on failure.
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-int skel_initialize(int intf)
-{
- struct skel_driver_s *priv;
-
- /* Get the interface structure associated with this interface number. */
-
- DEBUGASSERT(inf < CONFIG_skeleton_NINTERFACES);
- priv = &g_skel[intf];
-
- /* Check if a Ethernet chip is recognized at its I/O base */
-
- /* Attach the IRQ to the driver */
-
- if (irq_attach(CONFIG_skeleton_IRQ, skel_interrupt))
- {
- /* We could not attach the ISR to the interrupt */
-
- return -EAGAIN;
- }
-
- /* Initialize the driver structure */
-
- memset(priv, 0, sizeof(struct skel_driver_s));
- priv->sk_dev.d_ifup = skel_ifup; /* I/F up (new IP address) callback */
- priv->sk_dev.d_ifdown = skel_ifdown; /* I/F down callback */
- priv->sk_dev.d_txavail = skel_txavail; /* New TX data callback */
-#ifdef CONFIG_NET_IGMP
- priv->sk_dev.d_addmac = skel_addmac; /* Add multicast MAC address */
- priv->sk_dev.d_rmmac = skel_rmmac; /* Remove multicast MAC address */
-#endif
- priv->sk_dev.d_private = (void*)g_skel; /* Used to recover private state from dev */
-
- /* Create a watchdog for timing polling for and timing of transmisstions */
-
- priv->sk_txpoll = wd_create(); /* Create periodic poll timer */
- priv->sk_txtimeout = wd_create(); /* Create TX timeout timer */
-
- /* Put the interface in the down state. This usually amounts to resetting
- * the device and/or calling skel_ifdown().
- */
-
- /* Read the MAC address from the hardware into priv->sk_dev.d_mac.ether_addr_octet */
-
- /* Register the device with the OS so that socket IOCTLs can be performed */
-
- (void)netdev_register(&priv->sk_dev);
- return OK;
-}
-
-#endif /* CONFIG_NET && CONFIG_NET_skeleton */
diff --git a/nuttx/drivers/net/slip.c b/nuttx/drivers/net/slip.c
deleted file mode 100644
index 31f44cbb9..000000000
--- a/nuttx/drivers/net/slip.c
+++ /dev/null
@@ -1,1017 +0,0 @@
-/****************************************************************************
- * drivers/net/slip.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Reference: RFC 1055
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/net/net.h>
-
-#include <nuttx/net/uip/uip.h>
-#include <nuttx/net/uip/uip-arch.h>
-
-#if defined(CONFIG_NET) && defined(CONFIG_NET_SLIP)
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* NOTE: Slip requires UART hardware handshake. If hardware handshake is
- * not available with your UART, then you might try the 'slattach' option
- * -L which enable "3-wire operation." That allows operation without the
- * hardware handshake (but with the possibility of data overrun).
- */
-
-/* Configuration ************************************************************/
-
-#if UIP_LLH_LEN > 0
-# error "UIP_LLH_LEN must be set to zero"
-#endif
-
-#ifndef CONFIG_NET_NOINTS
-# warning "CONFIG_NET_NOINTS must be set"
-#endif
-
-#ifndef CONFIG_NET_MULTIBUFFER
-# warning "CONFIG_NET_MULTIBUFFER must be set"
-#endif
-
-#ifndef CONFIG_SLIP_STACKSIZE
-# define CONFIG_SLIP_STACKSIZE 2048
-#endif
-
-#ifndef CONFIG_SLIP_DEFPRIO
-# define CONFIG_SLIP_DEFPRIO 128
-#endif
-
-/* 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_BUFSIZE 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
- * uIP to 128 bytes (possibly by modifying the uip_mss() macro).
- */
-
-#if CONFIG_NET_BUFSIZE < 296
-# error "CONFIG_NET_BUFSIZE >= 296 is required"
-#elif CONFIG_NET_BUFSIZE > 296
-# warning "CONFIG_NET_BUFSIZE == 296 is optimal"
-#endif
-
-/* CONFIG_SLIP_NINTERFACES determines the number of physical interfaces
- * that will be supported.
- */
-
-#ifndef CONFIG_SLIP_NINTERFACES
-# define CONFIG_SLIP_NINTERFACES 1
-#endif
-
-/* SLIP special character codes *******************************************/
-
-#define SLIP_END 0300 /* Indicates end of packet */
-#define SLIP_ESC 0333 /* Indicates byte stuffing */
-#define SLIP_ESC_END 0334 /* ESC ESC_END means SLIP_END data byte */
-#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */
-
-/* General driver definitions **********************************************/
-
-/* TX poll delay = 1 second = 1000000 microseconds. */
-
-#define SLIP_WDDELAY (1*1000000)
-#define SLIP_POLLHSEC (1*2)
-
-/* Statistics helper */
-
-#ifdef CONFIG_NET_STATISTICS
-# define SLIP_STAT(p,f) (p->stats.f)++
-#else
-# define SLIP_STAT(p,f)
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* Driver statistics */
-
-#ifdef CONFIG_NET_STATISTICS
-struct slip_statistics_s
-{
- uint32_t transmitted; /* Number of packets transmitted */
- uint32_t received /* Number of packets received */
-};
-#endif
-
-/* The slip_driver_s encapsulates all state information for a single hardware
- * interface
- */
-
-struct slip_driver_s
-{
- volatile bool bifup; /* true:ifup false:ifdown */
- int fd; /* TTY file descriptor */
- pid_t rxpid; /* Receiver thread ID */
- pid_t txpid; /* Transmitter thread ID */
- sem_t waitsem; /* Mutually exclusive access to uIP */
- uint16_t rxlen; /* The number of bytes in rxbuf */
-
- /* Driver statistics */
-
-#ifdef CONFIG_NET_STATISTICS
- struct slip_statistics_s stats;
-#endif
-
- /* This holds the information visible to uIP/NuttX */
-
- struct uip_driver_s dev; /* Interface understood by uIP */
- uint8_t rxbuf[CONFIG_NET_BUFSIZE + 2];
- uint8_t txbuf[CONFIG_NET_BUFSIZE + 2];
-};
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
- /* We really should get rid of CONFIG_SLIP_NINTERFACES and, instead,
- * kmalloc() new interface instances as needed.
- */
-
-static struct slip_driver_s g_slip[CONFIG_SLIP_NINTERFACES];
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static void slip_semtake(FAR struct slip_driver_s *priv);
-
-/* Common TX logic */
-
-static void slip_write(FAR struct slip_driver_s *priv, const uint8_t *buffer, int len);
-static void slip_putc(FAR struct slip_driver_s *priv, int ch);
-static int slip_transmit(FAR struct slip_driver_s *priv);
-static int slip_uiptxpoll(struct uip_driver_s *dev);
-static void slip_txtask(int argc, char *argv[]);
-
-/* Packet receiver task */
-
-static int slip_getc(FAR struct slip_driver_s *priv);
-static inline void slip_receive(FAR struct slip_driver_s *priv);
-static int slip_rxtask(int argc, char *argv[]);
-
-/* NuttX callback functions */
-
-static int slip_ifup(struct uip_driver_s *dev);
-static int slip_ifdown(struct uip_driver_s *dev);
-static int slip_txavail(struct uip_driver_s *dev);
-#ifdef CONFIG_NET_IGMP
-static int slip_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-static int slip_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: slip_semtake
- ****************************************************************************/
-
-static void slip_semtake(FAR struct slip_driver_s *priv)
-{
- /* Take the semaphore (perhaps waiting) */
-
- while (sem_wait(&priv->waitsem) != 0)
- {
- /* The only case that an error should occur here is if
- * the wait was awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-}
-
-#define slip_semgive(p) sem_post(&(p)->waitsem);
-
-/****************************************************************************
- * Function: slip_write
- *
- * Description:
- * Just an inline wrapper around fwrite with error checking.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * buffer - Buffer data to send
- * len - Buffer length in bytes
- *
- ****************************************************************************/
-
-static inline void slip_write(FAR struct slip_driver_s *priv,
- const uint8_t *buffer, int len)
-{
- /* Handle the case where the write is awakened by a signal */
-
- while (write(priv->fd, buffer, len) < 0)
- {
- DEBUGASSERT(errno == EINTR);
- }
-}
-
-/****************************************************************************
- * Function: slip_putc
- *
- * Description:
- * Just an inline wrapper around putc with error checking.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- * ch - The character to send
- *
- ****************************************************************************/
-
-static inline void slip_putc(FAR struct slip_driver_s *priv, int ch)
-{
- uint8_t buffer = (uint8_t)ch;
- slip_write(priv, &buffer, 1);
-}
-
-/****************************************************************************
- * Function: slip_transmit
- *
- * Description:
- * Start hardware transmission. Called either from the txdone interrupt
- * handling or from watchdog based polling.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- ****************************************************************************/
-
-static int slip_transmit(FAR struct slip_driver_s *priv)
-{
- uint8_t *src;
- uint8_t *start;
- uint8_t esc;
- int remaining;
- int len;
-
- /* Increment statistics */
-
- nvdbg("Sending packet size %d\n", priv->dev.d_len);
- SLIP_STAT(priv, transmitted);
-
- /* Send an initial END character to flush out any data that may have
- * accumulated in the receiver due to line noise
- */
-
- slip_putc(priv, SLIP_END);
-
- /* For each byte in the packet, send the appropriate character sequence */
-
- src = priv->dev.d_buf;
- remaining = priv->dev.d_len;
- start = src;
- len = 0;
-
- while (remaining-- > 0)
- {
- switch (*src)
- {
- /* If it's the same code as an END character, we send a special two
- * character code so as not to make the receiver think we sent an
- * END
- */
-
- case SLIP_END:
- esc = SLIP_ESC_END;
- goto escape;
-
- /* If it's the same code as an ESC character, we send a special two
- * character code so as not to make the receiver think we sent an
- * ESC
- */
-
- case SLIP_ESC:
- esc = SLIP_ESC_ESC;
-
- escape:
- {
- /* Flush any unsent data */
-
- if (len > 0)
- {
- slip_write(priv, start, len);
-
- /* Reset */
-
- start = src + 1;
- len = 0;
- }
-
- /* Then send the escape sequence */
-
- slip_putc(priv, SLIP_ESC);
- slip_putc(priv, esc);
- }
- break;
-
- /* otherwise, just bump up the count */
-
- default:
- len++;
- break;
- }
-
- /* Point to the next character in the packet */
-
- src++;
- }
-
- /* We have looked at every character in the packet. Now flush any unsent
- * data
- */
-
- if (len > 0)
- {
- slip_write(priv, start, len);
- }
-
- /* And send the END token */
-
- slip_putc(priv, SLIP_END);
- return OK;
-}
-
-/****************************************************************************
- * Function: slip_uiptxpoll
- *
- * Description:
- * Check if uIP has any outgoing packets ready to send. This is a
- * callback from uip_poll(). uip_poll() may be called:
- *
- * 1. When the preceding TX packet send is complete, or
- * 2. When the preceding TX packet send times o ]ut and the interface is reset
- * 3. During normal TX polling
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- * The initiator of the poll holds the priv->waitsem;
- *
- ****************************************************************************/
-
-static int slip_uiptxpoll(struct uip_driver_s *dev)
-{
- FAR struct slip_driver_s *priv = (FAR struct slip_driver_s *)dev->d_private;
-
- /* If the polling resulted in data that should be sent out on the network,
- * the field d_len is set to a value > 0.
- */
-
- if (priv->dev.d_len > 0)
- {
- slip_transmit(priv);
- }
-
- /* If zero is returned, the polling will continue until all connections have
- * been examined.
- */
-
- return 0;
-}
-
-/****************************************************************************
- * Function: slip_txtask
- *
- * Description:
- * Polling and transmission is performed on tx thread.
- *
- * Parameters:
- * arg - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-static void slip_txtask(int argc, char *argv[])
-{
- FAR struct slip_driver_s *priv;
- unsigned int index = *(argv[1]) - '0';
- uip_lock_t flags;
-
- ndbg("index: %d\n", index);
- DEBUGASSERT(index < CONFIG_SLIP_NINTERFACES);
-
- /* Get our private data structure instance and wake up the waiting
- * initialization logic.
- */
-
- priv = &g_slip[index];
- slip_semgive(priv);
-
- /* Loop forever */
-
- for (;;)
- {
- /* Wait for the timeout to expire (or until we are signaled by by */
-
- usleep(SLIP_WDDELAY);
-
- /* Is the interface up? */
-
- if (priv->bifup)
- {
- /* Get exclusive access to uIP (if it it is already being used
- * slip_rxtask, then we have to wait).
- */
-
- slip_semtake(priv);
-
- /* Poll uIP for new XMIT data. BUG: We really need to calculate
- * the number of hsecs! When we are awakened by slip_txavail, the
- * number will be smaller; when we have to wait for the semaphore
- * (above), it may be larger.
- */
-
- flags = uip_lock();
- priv->dev.d_buf = priv->txbuf;
- (void)uip_timer(&priv->dev, slip_uiptxpoll, SLIP_POLLHSEC);
- uip_unlock(flags);
- slip_semgive(priv);
- }
- }
-}
-
-/****************************************************************************
- * Function: slip_getc
- *
- * Description:
- * Get one byte from the serial input.
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * The returned byte
- *
- ****************************************************************************/
-
-static inline int slip_getc(FAR struct slip_driver_s *priv)
-{
- uint8_t ch;
-
- while (read(priv->fd, &ch, 1) < 0)
- {
- DEBUGASSERT(errno == EINTR);
- }
-
- return (int)ch;
-}
-
-/****************************************************************************
- * Function: slip_receive
- *
- * Description:
- * Read a packet from the serial input
- *
- * Parameters:
- * priv - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-static inline void slip_receive(FAR struct slip_driver_s *priv)
-{
- uint8_t ch;
-
- /* Copy the data data from the hardware to to the RX buffer until we
- * put together a whole packet. Make sure not to copy them into the
- * packet if we run out of room.
- */
-
- nvdbg("Receiving packet\n");
- for (;;)
- {
- /* Get the next character in the stream. */
-
- ch = slip_getc(priv);
-
- /* Handle bytestuffing if necessary */
-
- switch (ch)
- {
- /* If it's an END character then we're done with the packet.
- * (OR we are just starting a packet)
- */
-
- case SLIP_END:
- nvdbg("END\n");
-
- /* A minor optimization: if there is no data in the packet, ignore
- * it. This is meant to avoid bothering IP with all the empty
- * packets generated by the duplicate END characters which are in
- * turn sent to try to detect line noise.
- */
-
- if (priv->rxlen > 0)
- {
- nvdbg("Received packet size %d\n", priv->rxlen);
- return;
- }
- break;
-
- /* if it's the same code as an ESC character, wait and get another
- * character and then figure out what to store in the packet based
- * on that.
- */
-
- case SLIP_ESC:
- nvdbg("ESC\n");
- ch = slip_getc(priv);
-
- /* if "ch" is not one of these two, then we have a protocol
- * violation. The best bet seems to be to leave the byte alone
- * and just stuff it into the packet
- */
-
- switch (ch)
- {
- case SLIP_ESC_END:
- nvdbg("ESC-END\n");
- ch = SLIP_END;
- break;
- case SLIP_ESC_ESC:
- nvdbg("ESC-ESC\n");
- ch = SLIP_ESC;
- break;
- default:
- ndbg("ERROR: Protocol violation: %02x\n", ch);
- break;
- }
-
- /* Here we fall into the default handler and let it store the
- * character for us
- */
-
- default:
- if (priv->rxlen < CONFIG_NET_BUFSIZE+2)
- {
- priv->rxbuf[priv->rxlen++] = ch;
- }
- break;
- }
- }
-}
-
-/****************************************************************************
- * Function: slip_rxtask
- *
- * Description:
- * Wait for incoming data.
- *
- * Parameters:
- * argc
- * argv
- *
- * Returned Value:
- * (Does not return)
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int slip_rxtask(int argc, char *argv[])
-{
- FAR struct slip_driver_s *priv;
- unsigned int index = *(argv[1]) - '0';
- uip_lock_t flags;
- int ch;
-
- ndbg("index: %d\n", index);
- DEBUGASSERT(index < CONFIG_SLIP_NINTERFACES);
-
- /* Get our private data structure instance and wake up the waiting
- * initialization logic.
- */
-
- priv = &g_slip[index];
- slip_semgive(priv);
-
- /* Loop forever */
-
- for (;;)
- {
- /* Wait for the next character to be available on the input stream. */
-
- nvdbg("Waiting...\n");
- ch = slip_getc(priv);
-
- /* Ignore any input that we receive before the interface is up. */
-
- if (!priv->bifup)
- {
- continue;
- }
-
- /* We have something...
- *
- * END characters may appear at packet boundaries BEFORE as well as
- * after the beginning of the packet. This is normal and expected.
- */
-
- if (ch == SLIP_END)
- {
- priv->rxlen = 0;
- }
-
- /* Otherwise, we are in danger of being out-of-sync. Apparently the
- * leading END character is optional. Let's try to continue.
- */
-
- else
- {
- priv->rxbuf[0] = (uint8_t)ch;
- priv->rxlen = 1;
- }
-
- /* Copy the data data from the hardware to priv->rxbuf until we put
- * together a whole packet.
- */
-
- slip_receive(priv);
- SLIP_STAT(priv, received);
-
- /* All packets are assumed to be IP packets (we don't have a choice..
- * there is no Ethernet header containing the EtherType). So pass the
- * received packet on for IP processing -- but only if it is big
- * enough to hold an IP header.
- */
-
- if (priv->rxlen >= UIP_IPH_LEN)
- {
- /* Handle the IP input. Get exclusive access to uIP. */
-
- slip_semtake(priv);
- priv->dev.d_buf = priv->rxbuf;
- priv->dev.d_len = priv->rxlen;
-
- flags = uip_lock();
- uip_input(&priv->dev);
-
- /* If the above function invocation resulted in data that should
- * be sent out on the network, the field d_len will set to a
- * value > 0. NOTE that we are transmitting using the RX buffer!
- */
-
- if (priv->dev.d_len > 0)
- {
- slip_transmit(priv);
- }
- uip_unlock(flags);
- slip_semgive(priv);
- }
- else
- {
- SLIP_STAT(priv, rxsmallpacket);
- }
- }
-
- /* We won't get here */
-
- return OK;
-}
-
-/****************************************************************************
- * Function: slip_ifup
- *
- * Description:
- * NuttX Callback: Bring up the Ethernet interface when an IP address is
- * provided
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int slip_ifup(struct uip_driver_s *dev)
-{
- FAR struct slip_driver_s *priv = (FAR struct slip_driver_s *)dev->d_private;
-
- ndbg("Bringing up: %d.%d.%d.%d\n",
- dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
- (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
-
- /* Mark the interface up */
-
- priv->bifup = true;
- return OK;
-}
-
-/****************************************************************************
- * Function: slip_ifdown
- *
- * Description:
- * NuttX Callback: Stop the interface.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int slip_ifdown(struct uip_driver_s *dev)
-{
- FAR struct slip_driver_s *priv = (FAR struct slip_driver_s *)dev->d_private;
-
- /* Mark the device "down" */
-
- priv->bifup = false;
- return OK;
-}
-
-/****************************************************************************
- * Function: slip_txavail
- *
- * Description:
- * Driver callback invoked when new TX data is available. This is a
- * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
- * latency.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-static int slip_txavail(struct uip_driver_s *dev)
-{
- FAR struct slip_driver_s *priv = (FAR struct slip_driver_s *)dev->d_private;
-
- /* Ignore the notification if the interface is not yet up */
-
- if (priv->bifup)
- {
- /* Wake up the TX polling thread */
-
- kill(priv->txpid, SIGALRM);
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Function: slip_addmac
- *
- * Description:
- * NuttX Callback: Add the specified MAC address to the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be added
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int slip_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct slip_driver_s *priv = (FAR struct slip_driver_s *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Function: slip_rmmac
- *
- * Description:
- * NuttX Callback: Remove the specified MAC address from the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be removed
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int slip_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct slip_driver_s *priv = (FAR struct slip_driver_s *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: slip_initialize
- *
- * 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
- *
- * Returned Value:
- * OK on success; Negated errno on failure.
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-int slip_initialize(int intf, const char *devname)
-{
- struct slip_driver_s *priv;
- char buffer[8];
- const char *argv[2];
-
- /* Get the interface structure associated with this interface number. */
-
- DEBUGASSERT(intf < CONFIG_SLIP_NINTERFACES);
- priv = &g_slip[intf];
-
- /* Initialize the driver structure */
-
- memset(priv, 0, sizeof(struct slip_driver_s));
- priv->dev.d_ifup = slip_ifup; /* I/F up (new IP address) callback */
- priv->dev.d_ifdown = slip_ifdown; /* I/F down callback */
- priv->dev.d_txavail = slip_txavail; /* New TX data callback */
-#ifdef CONFIG_NET_IGMP
- priv->dev.d_addmac = slip_addmac; /* Add multicast MAC address */
- priv->dev.d_rmmac = slip_rmmac; /* Remove multicast MAC address */
-#endif
- priv->dev.d_private = priv; /* Used to recover private state from dev */
-
- /* Open the device */
-
- priv->fd = open(devname, O_RDWR, 0666);
- if (priv->fd < 0)
- {
- ndbg("ERROR: Failed to open %s: %d\n", devname, errno);
- return -errno;
- }
-
- /* Initialize the wait semaphore */
-
- sem_init(&priv->waitsem, 0, 0);
-
- /* Put the interface in the down state. This usually amounts to resetting
- * the device and/or calling slip_ifdown().
- */
-
- slip_ifdown(&priv->dev);
-
- /* Start the SLIP receiver task */
-
- snprintf(buffer, 8, "%d", intf);
- argv[0] = buffer;
- argv[1] = NULL;
-
-#ifndef CONFIG_CUSTOM_STACK
- priv->rxpid = task_create("rxslip", CONFIG_SLIP_DEFPRIO,
- CONFIG_SLIP_STACKSIZE, (main_t)slip_rxtask, argv);
-#else
- priv->rxpid = task_create("rxslip", CONFIG_SLIP_DEFPRIO,
- (main_t)slip_rxtask, argv);
-#endif
- if (priv->rxpid < 0)
- {
- ndbg("ERROR: Failed to start receiver task\n");
- return -errno;
- }
-
- /* Wait and make sure that the receive task is started. */
-
- slip_semtake(priv);
-
- /* Start the SLIP transmitter task */
-
-#ifndef CONFIG_CUSTOM_STACK
- priv->txpid = task_create("txslip", CONFIG_SLIP_DEFPRIO,
- CONFIG_SLIP_STACKSIZE, (main_t)slip_txtask, argv);
-#else
- priv->txpid = task_create("txslip", CONFIG_SLIP_DEFPRIO,
- (main_t)slip_txtask, argv);
-#endif
- if (priv->txpid < 0)
- {
- ndbg("ERROR: Failed to start receiver task\n");
- return -errno;
- }
-
- /* Wait and make sure that the transmit task is started. */
-
- slip_semtake(priv);
-
- /* Bump the semaphore count so that it can now be used as a mutex */
-
- slip_semgive(priv);
-
- /* Register the device with the OS so that socket IOCTLs can be performed */
-
- (void)netdev_register(&priv->dev);
-
- /* When the RX and TX tasks were created, the TTY file descriptor was
- * dup'ed for each task. This task no longer needs the file descriptor
- * and we can safely close it.
- */
-
- close(priv->fd);
- return OK;
-}
-
-#endif /* CONFIG_NET && CONFIG_NET_SLIP */
-
diff --git a/nuttx/drivers/net/vnet.c b/nuttx/drivers/net/vnet.c
deleted file mode 100644
index e05a39675..000000000
--- a/nuttx/drivers/net/vnet.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/****************************************************************************
- * drivers/net/vnet.c
- *
- * Copyright (C) 2011 Yu Qiang. All rights reserved.
- * Author: Yu Qiang <yuq825@gmail.com>
- *
- * This file is a part of NuttX:
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- *
- * 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 <nuttx/config.h>
-#if defined(CONFIG_NET) && defined(CONFIG_NET_VNET)
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <time.h>
-#include <string.h>
-#include <debug.h>
-#include <wdog.h>
-#include <errno.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include <nuttx/net/uip/uip.h>
-#include <nuttx/net/uip/uip-arp.h>
-#include <nuttx/net/uip/uip-arch.h>
-
-#include <rgmp/vnet.h>
-#include <rgmp/stdio.h>
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-/* CONFIG_VNET_NINTERFACES determines the number of physical interfaces
- * that will be supported.
- */
-
-#ifndef CONFIG_VNET_NINTERFACES
-# define CONFIG_VNET_NINTERFACES 1
-#endif
-
-/* TX poll deley = 1 seconds. CLK_TCK is the number of clock ticks per second */
-
-#define VNET_WDDELAY (1*CLK_TCK)
-#define VNET_POLLHSEC (1*2)
-
-/* TX timeout = 1 minute */
-
-#define VNET_TXTIMEOUT (60*CLK_TCK)
-
-/* This is a helper pointer for accessing the contents of the Ethernet header */
-
-#define BUF ((struct uip_eth_hdr *)vnet->sk_dev.d_buf)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* The vnet_driver_s encapsulates all state information for a single hardware
- * interface
- */
-
-struct vnet_driver_s
-{
- bool sk_bifup; /* true:ifup false:ifdown */
- WDOG_ID sk_txpoll; /* TX poll timer */
- //WDOG_ID sk_txtimeout; /* TX timeout timer */
-
- /* This holds the information visible to uIP/NuttX */
- struct rgmp_vnet *vnet;
- struct uip_driver_s sk_dev; /* Interface understood by uIP */
-};
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static struct vnet_driver_s g_vnet[CONFIG_VNET_NINTERFACES];
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Common TX logic */
-
-static int vnet_transmit(FAR struct vnet_driver_s *vnet);
-static int vnet_uiptxpoll(struct uip_driver_s *dev);
-
-/* Interrupt handling */
-
-static void vnet_txdone(FAR struct vnet_driver_s *vnet);
-
-/* Watchdog timer expirations */
-
-static void vnet_polltimer(int argc, uint32_t arg, ...);
-static void vnet_txtimeout(int argc, uint32_t arg, ...);
-
-/* NuttX callback functions */
-
-static int vnet_ifup(struct uip_driver_s *dev);
-static int vnet_ifdown(struct uip_driver_s *dev);
-static int vnet_txavail(struct uip_driver_s *dev);
-#ifdef CONFIG_NET_IGMP
-static int vnet_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-static int vnet_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac);
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: vnet_transmit
- *
- * Description:
- * Start hardware transmission. Called either from the txdone interrupt
- * handling or from watchdog based polling.
- *
- * Parameters:
- * vnet - Reference to the driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- * May or may not be called from an interrupt handler. In either case,
- * global interrupts are disabled, either explicitly or indirectly through
- * interrupt handling logic.
- *
- ****************************************************************************/
-
-static int vnet_transmit(FAR struct vnet_driver_s *vnet)
-{
- int err;
-
- /* Verify that the hardware is ready to send another packet. If we get
- * here, then we are committed to sending a packet; Higher level logic
- * must have assured that there is not transmission in progress.
- */
-
- /* Increment statistics */
-
- /* Send the packet: address=vnet->sk_dev.d_buf, length=vnet->sk_dev.d_len */
- err = vnet_xmit(vnet->vnet, (char *)vnet->sk_dev.d_buf, vnet->sk_dev.d_len);
- if (err) {
- /* Setup the TX timeout watchdog (perhaps restarting the timer) */
- //(void)wd_start(vnet->sk_txtimeout, VNET_TXTIMEOUT, vnet_txtimeout, 1, (uint32_t)vnet);
-
- // When vnet_xmit fail, it means TX buffer is full. Watchdog
- // is of no use here because no TX done INT will happen. So
- // we reset the TX buffer directly.
-#ifdef CONFIG_DEBUG
- cprintf("VNET: TX buffer is full\n");
-#endif
- return ERROR;
- }
- else {
- // this step may be unnecessary here
- vnet_txdone(vnet);
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Function: vnet_uiptxpoll
- *
- * Description:
- * The transmitter is available, check if uIP has any outgoing packets ready
- * to send. This is a callback from uip_poll(). uip_poll() may be called:
- *
- * 1. When the preceding TX packet send is complete,
- * 2. When the preceding TX packet send timesout and the interface is reset
- * 3. During normal TX polling
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * OK on success; a negated errno on failure
- *
- * Assumptions:
- * May or may not be called from an interrupt handler. In either case,
- * global interrupts are disabled, either explicitly or indirectly through
- * interrupt handling logic.
- *
- ****************************************************************************/
-
-static int vnet_uiptxpoll(struct uip_driver_s *dev)
-{
- FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)dev->d_private;
-
- /* If the polling resulted in data that should be sent out on the network,
- * the field d_len is set to a value > 0.
- */
-
- if (vnet->sk_dev.d_len > 0)
- {
- uip_arp_out(&vnet->sk_dev);
- vnet_transmit(vnet);
-
- /* Check if there is room in the device to hold another packet. If not,
- * return a non-zero value to terminate the poll.
- */
- if (vnet_is_txbuff_full(vnet->vnet))
- return 1;
- }
-
- /* If zero is returned, the polling will continue until all connections have
- * been examined.
- */
-
- return 0;
-}
-
-/****************************************************************************
- * Function: rtos_vnet_recv
- *
- * Description:
- * An interrupt was received indicating the availability of a new RX packet
- *
- * Parameters:
- * vnet - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by interrupt handling logic.
- *
- ****************************************************************************/
-
-void rtos_vnet_recv(struct rgmp_vnet *rgmp_vnet, char *data, int len)
-{
- struct vnet_driver_s *vnet = rgmp_vnet->priv;
-
- do {
- /* Check for errors and update statistics */
-
- /* Check if the packet is a valid size for the uIP buffer configuration */
- if (len > CONFIG_NET_BUFSIZE || len < 14) {
-#ifdef CONFIG_DEBUG
- cprintf("VNET: receive invalid packet of size %d\n", len);
-#endif
- return;
- }
-
- // Copy the data data from the hardware to vnet->sk_dev.d_buf. Set
- // amount of data in vnet->sk_dev.d_len
- memcpy(vnet->sk_dev.d_buf, data, len);
- vnet->sk_dev.d_len = len;
-
- /* We only accept IP packets of the configured type and ARP packets */
-
-#ifdef CONFIG_NET_IPv6
- if (BUF->type == HTONS(UIP_ETHTYPE_IP6))
-#else
- if (BUF->type == HTONS(UIP_ETHTYPE_IP))
-#endif
- {
- uip_arp_ipin(&vnet->sk_dev);
- uip_input(&vnet->sk_dev);
-
- // If the above function invocation resulted in data that should be
- // sent out on the network, the field d_len will set to a value > 0.
- if (vnet->sk_dev.d_len > 0) {
- uip_arp_out(&vnet->sk_dev);
- vnet_transmit(vnet);
- }
- }
- else if (BUF->type == htons(UIP_ETHTYPE_ARP)) {
- uip_arp_arpin(&vnet->sk_dev);
-
- // If the above function invocation resulted in data that should be
- // sent out on the network, the field d_len will set to a value > 0.
- if (vnet->sk_dev.d_len > 0) {
- vnet_transmit(vnet);
- }
- }
- }
- while (0); /* While there are more packets to be processed */
-}
-
-/****************************************************************************
- * Function: vnet_txdone
- *
- * Description:
- * An interrupt was received indicating that the last TX packet(s) is done
- *
- * Parameters:
- * vnet - Reference to the driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by the watchdog logic.
- *
- ****************************************************************************/
-
-static void vnet_txdone(FAR struct vnet_driver_s *vnet)
-{
- /* Check for errors and update statistics */
-
- /* If no further xmits are pending, then cancel the TX timeout and
- * disable further Tx interrupts.
- */
-
- //wd_cancel(vnet->sk_txtimeout);
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&vnet->sk_dev, vnet_uiptxpoll);
-}
-
-/****************************************************************************
- * Function: vnet_txtimeout
- *
- * Description:
- * Our TX watchdog timed out. Called from the timer interrupt handler.
- * The last TX never completed. Reset the hardware and start again.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by the watchdog logic.
- *
- ****************************************************************************/
-
-static void vnet_txtimeout(int argc, uint32_t arg, ...)
-{
- FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)arg;
-
- /* Increment statistics and dump debug info */
-
- /* Then reset the hardware */
-
- /* Then poll uIP for new XMIT data */
-
- (void)uip_poll(&vnet->sk_dev, vnet_uiptxpoll);
-}
-
-/****************************************************************************
- * Function: vnet_polltimer
- *
- * Description:
- * Periodic timer handler. Called from the timer interrupt handler.
- *
- * Parameters:
- * argc - The number of available arguments
- * arg - The first argument
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Global interrupts are disabled by the watchdog logic.
- *
- ****************************************************************************/
-
-static void vnet_polltimer(int argc, uint32_t arg, ...)
-{
- FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)arg;
-
- /* Check if there is room in the send another TX packet. We cannot perform
- * the TX poll if he are unable to accept another packet for transmission.
- */
- if (vnet_is_txbuff_full(vnet->vnet)) {
-#ifdef CONFIG_DEBUG
- cprintf("VNET: TX buffer is full\n");
-#endif
- return;
- }
-
- /* If so, update TCP timing states and poll uIP for new XMIT data. Hmmm..
- * might be bug here. Does this mean if there is a transmit in progress,
- * we will missing TCP time state updates?
- */
-
- (void)uip_timer(&vnet->sk_dev, vnet_uiptxpoll, VNET_POLLHSEC);
-
- /* Setup the watchdog poll timer again */
-
- (void)wd_start(vnet->sk_txpoll, VNET_WDDELAY, vnet_polltimer, 1, arg);
-}
-
-/****************************************************************************
- * Function: vnet_ifup
- *
- * Description:
- * NuttX Callback: Bring up the Ethernet interface when an IP address is
- * provided
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int vnet_ifup(struct uip_driver_s *dev)
-{
- FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)dev->d_private;
-
- ndbg("Bringing up: %d.%d.%d.%d\n",
- dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
- (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24 );
-
- /* Initialize PHYs, the Ethernet interface, and setup up Ethernet interrupts */
-
- /* Set and activate a timer process */
-
- (void)wd_start(vnet->sk_txpoll, VNET_WDDELAY, vnet_polltimer, 1, (uint32_t)vnet);
-
- vnet->sk_bifup = true;
- return OK;
-}
-
-/****************************************************************************
- * Function: vnet_ifdown
- *
- * Description:
- * NuttX Callback: Stop the interface.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static int vnet_ifdown(struct uip_driver_s *dev)
-{
- FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)dev->d_private;
- irqstate_t flags;
-
- /* Disable the Ethernet interrupt */
-
- flags = irqsave();
-
- /* Cancel the TX poll timer and TX timeout timers */
-
- wd_cancel(vnet->sk_txpoll);
- //wd_cancel(vnet->sk_txtimeout);
-
- /* Put the the EMAC is its reset, non-operational state. This should be
- * a known configuration that will guarantee the vnet_ifup() always
- * successfully brings the interface back up.
- */
-
- /* Mark the device "down" */
-
- vnet->sk_bifup = false;
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Function: vnet_txavail
- *
- * Description:
- * Driver callback invoked when new TX data is available. This is a
- * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
- * latency.
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Called in normal user mode
- *
- ****************************************************************************/
-
-static int vnet_txavail(struct uip_driver_s *dev)
-{
- FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)dev->d_private;
- irqstate_t flags;
-
- /* Disable interrupts because this function may be called from interrupt
- * level processing.
- */
-
- flags = irqsave();
-
- /* Ignore the notification if the interface is not yet up */
-
- if (vnet->sk_bifup)
- {
- /* Check if there is room in the hardware to hold another outgoing packet. */
- if (vnet_is_txbuff_full(vnet->vnet)) {
-#ifdef CONFIG_DEBUG
- cprintf("VNET: TX buffer is full\n");
-#endif
- goto out;
- }
-
- /* If so, then poll uIP for new XMIT data */
-
- (void)uip_poll(&vnet->sk_dev, vnet_uiptxpoll);
- }
-
-out:
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Function: vnet_addmac
- *
- * Description:
- * NuttX Callback: Add the specified MAC address to the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be added
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int vnet_addmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Function: vnet_rmmac
- *
- * Description:
- * NuttX Callback: Remove the specified MAC address from the hardware multicast
- * address filtering
- *
- * Parameters:
- * dev - Reference to the NuttX driver state structure
- * mac - The MAC address to be removed
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_IGMP
-static int vnet_rmmac(struct uip_driver_s *dev, FAR const uint8_t *mac)
-{
- FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)dev->d_private;
-
- /* Add the MAC address to the hardware multicast routing table */
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Function: vnet_initialize
- *
- * Description:
- * Initialize the Ethernet controller and driver
- *
- * Parameters:
- * intf - In the case where there are multiple EMACs, this value
- * identifies which EMAC is to be initialized.
- *
- * Returned Value:
- * OK on success; Negated errno on failure.
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-int vnet_init(struct rgmp_vnet *vnet)
-{
- struct vnet_driver_s *priv;
- static int i = 0;
-
- if (i >= CONFIG_VNET_NINTERFACES)
- return -1;
-
- priv = &g_vnet[i++];
-
- /* Initialize the driver structure */
-
- memset(priv, 0, sizeof(struct vnet_driver_s));
- priv->sk_dev.d_ifup = vnet_ifup; /* I/F down callback */
- priv->sk_dev.d_ifdown = vnet_ifdown; /* I/F up (new IP address) callback */
- priv->sk_dev.d_txavail = vnet_txavail; /* New TX data callback */
-#ifdef CONFIG_NET_IGMP
- priv->sk_dev.d_addmac = vnet_addmac; /* Add multicast MAC address */
- priv->sk_dev.d_rmmac = vnet_rmmac; /* Remove multicast MAC address */
-#endif
- priv->sk_dev.d_private = (void*)priv; /* Used to recover private state from dev */
-
- /* Create a watchdog for timing polling for and timing of transmisstions */
-
- priv->sk_txpoll = wd_create(); /* Create periodic poll timer */
- //priv->sk_txtimeout = wd_create(); /* Create TX timeout timer */
-
- priv->vnet = vnet;
- vnet->priv = priv;
-
- /* Register the device with the OS */
-
- (void)netdev_register(&priv->sk_dev);
-
- return 0;
-}
-
-#endif /* CONFIG_NET && CONFIG_NET_VNET */
diff --git a/nuttx/drivers/pipes/Kconfig b/nuttx/drivers/pipes/Kconfig
deleted file mode 100644
index ae2bf3130..000000000
--- a/nuttx/drivers/pipes/Kconfig
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
diff --git a/nuttx/drivers/pipes/Make.defs b/nuttx/drivers/pipes/Make.defs
deleted file mode 100644
index 836505481..000000000
--- a/nuttx/drivers/pipes/Make.defs
+++ /dev/null
@@ -1,46 +0,0 @@
-############################################################################
-# drivers/pipes/Make.defs
-#
-# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
-
-# Include pipe driver
-
-CSRCS += pipe.c fifo.c pipe_common.c
-
-# Include pipe build support
-
-DEPPATH += --dep-path pipes
-VPATH += :pipes
-endif
diff --git a/nuttx/drivers/pipes/fifo.c b/nuttx/drivers/pipes/fifo.c
deleted file mode 100644
index 03aafd0f0..000000000
--- a/nuttx/drivers/pipes/fifo.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
- * drivers/pipes/fifo.c
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <nuttx/fs/fs.h>
-#include <errno.h>
-
-#include "pipe_common.h"
-
-#if CONFIG_DEV_PIPE_SIZE > 0
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations fifo_fops =
-{
- pipecommon_open, /* open */
- pipecommon_close, /* close */
- pipecommon_read, /* read */
- pipecommon_write, /* write */
- 0, /* seek */
- 0 /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , pipecommon_poll /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: mkfifo
- *
- * Description:
- * mkfifo() makes a FIFO device driver file with name 'pathname.' Unlike
- * Linux, a NuttX FIFO is not a special file type but simply a device driver
- * instance. 'mode' specifies the FIFO's permissions.
- *
- * Once the FIFO has been created by mkfifo(), any thread can open it for
- * reading or writing, in the same way as an ordinary file. However, it must
- * have been opened from both reading and writing before input or output
- * can be performed. This FIFO implementation will block all attempts to
- * open a FIFO read-only until at least one thread has opened the FIFO for
- * writing.
- *
- * If all threads that write to the FIFO have closed, subsequent calls to
- * read() on the FIFO will return 0 (end-of-file).
- *
- * Inputs:
- * pathname - The full path to the FIFO instance to attach to or to create
- * (if not already created).
- * mode - Ignored for now
- *
- * Return:
- * 0 is returned on success; otherwise, -1 is returned with errno set
- * appropriately.
- *
- ****************************************************************************/
-
-int mkfifo(FAR const char *pathname, mode_t mode)
-{
- struct pipe_dev_s *dev;
- int ret;
-
- /* Allocate and initialize a new device structure instance */
-
- dev = pipecommon_allocdev();
- if (!dev)
- {
- return -ENOMEM;
- }
-
- ret = register_driver(pathname, &fifo_fops, mode, (void*)dev);
- if (ret != 0)
- {
- pipecommon_freedev(dev);
- }
-
- return ret;
-}
-
-#endif /* CONFIG_DEV_PIPE_SIZE > 0 */
diff --git a/nuttx/drivers/pipes/pipe.c b/nuttx/drivers/pipes/pipe.c
deleted file mode 100644
index 20c160475..000000000
--- a/nuttx/drivers/pipes/pipe.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/****************************************************************************
- * drivers/pipes/pipe.c
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Compilation Switches
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <nuttx/fs/fs.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <semaphore.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include "pipe_common.h"
-
-#if CONFIG_DEV_PIPE_SIZE > 0
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-#define MAX_PIPES 32
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int pipe_close(FAR struct file *filep);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations pipe_fops =
-{
- pipecommon_open, /* open */
- pipe_close, /* close */
- pipecommon_read, /* read */
- pipecommon_write, /* write */
- 0, /* seek */
- 0 /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , pipecommon_poll /* poll */
-#endif
-};
-
-static sem_t g_pipesem = { 1 };
-static uint32_t g_pipeset = 0;
-static uint32_t g_pipecreated = 0;
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pipe_allocate
- ****************************************************************************/
-
-static inline int pipe_allocate(void)
-{
- int pipeno;
- int ret = -ENFILE;
-
- for (pipeno = 0; pipeno < MAX_PIPES; pipeno++)
- {
- if ((g_pipeset & (1 << pipeno)) == 0)
- {
- g_pipeset |= (1 << pipeno);
- ret = pipeno;
- break;
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: pipe_free
- ****************************************************************************/
-
-static inline void pipe_free(int pipeno)
-{
- int ret = sem_wait(&g_pipesem);
- if (ret == 0)
- {
- g_pipeset &= ~(1 << pipeno);
- (void)sem_post(&g_pipesem);
- }
-}
-
-/****************************************************************************
- * Name: pipe_close
- ****************************************************************************/
-
-static int pipe_close(FAR struct file *filep)
-{
- struct inode *inode = filep->f_inode;
- struct pipe_dev_s *dev = inode->i_private;
- int ret;
-
- /* Some sanity checking */
-#if CONFIG_DEBUG
- if (!dev)
- {
- return -EBADF;
- }
-#endif
-
- /* Perform common close operations */
-
- ret = pipecommon_close(filep);
- if (ret == 0 && dev->d_refs == 0)
- {
- /* Release the pipe when there are no further open references to it. */
-
- pipe_free(dev->d_pipeno);
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pipe
- *
- * Description:
- * pipe() creates a pair of file descriptors, pointing to a pipe inode, and
- * places them in the array pointed to by 'filedes'. filedes[0] is for reading,
- * filedes[1] is for writing.
- *
- * Inputs:
- * filedes[2] - The user provided array in which to catch the pipe file
- * descriptors
- *
- * Return:
- * 0 is returned on success; otherwise, -1 is returned with errno set
- * appropriately.
- *
- ****************************************************************************/
-
-int pipe(int filedes[2])
-{
- struct pipe_dev_s *dev = NULL;
- char devname[16];
- int pipeno;
- int err;
- int ret;
-
- /* Get exclusive access to the pipe allocation data */
-
- ret = sem_wait(&g_pipesem);
- if (ret < 0)
- {
- /* sem_wait() will have already set errno */
-
- return ERROR;
- }
-
- /* Allocate a minor number for the pipe device */
-
- pipeno = pipe_allocate();
- if (pipeno < 0)
- {
- (void)sem_post(&g_pipesem);
- err = -pipeno;
- goto errout;
- }
-
- /* Create a pathname to the pipe device */
-
- sprintf(devname, "/dev/pipe%d", pipeno);
-
- /* Check if the pipe device has already been created */
-
- if ((g_pipecreated & (1 << pipeno)) == 0)
- {
- /* No.. Allocate and initialize a new device structure instance */
-
- dev = pipecommon_allocdev();
- if (!dev)
- {
- (void)sem_post(&g_pipesem);
- err = ENOMEM;
- goto errout_with_pipe;
- }
-
- dev->d_pipeno = pipeno;
-
- /* Register the pipe device */
-
- ret = register_driver(devname, &pipe_fops, 0666, (void*)dev);
- if (ret != 0)
- {
- (void)sem_post(&g_pipesem);
- err = -ret;
- goto errout_with_dev;
- }
-
- /* Remember that we created this device */
-
- g_pipecreated |= (1 << pipeno);
- }
-
- (void)sem_post(&g_pipesem);
-
- /* Get a write file descriptor */
-
- filedes[1] = open(devname, O_WRONLY);
- if (filedes[1] < 0)
- {
- err = -filedes[1];
- goto errout_with_driver;
- }
-
- /* Get a read file descriptor */
-
- filedes[0] = open(devname, O_RDONLY);
- if (filedes[0] < 0)
- {
- err = -filedes[0];
- goto errout_with_wrfd;
- }
-
- return OK;
-
-errout_with_wrfd:
- close(filedes[1]);
-errout_with_driver:
- unregister_driver(devname);
-errout_with_dev:
- pipecommon_freedev(dev);
-errout_with_pipe:
- pipe_free(pipeno);
-errout:
- errno = err;
- return ERROR;
-}
-
-#endif /* CONFIG_DEV_PIPE_SIZE > 0 */
diff --git a/nuttx/drivers/pipes/pipe_common.c b/nuttx/drivers/pipes/pipe_common.c
deleted file mode 100644
index 5f61fdd8e..000000000
--- a/nuttx/drivers/pipes/pipe_common.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/****************************************************************************
- * drivers/pipes/pipe_common.c
- *
- * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sched.h>
-#include <semaphore.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-#if CONFIG_DEBUG
-# include <nuttx/arch.h>
-#endif
-
-#include "pipe_common.h"
-
-#if CONFIG_DEV_PIPE_SIZE > 0
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* CONFIG_DEV_PIPEDUMP will dump the contents of each transfer into and out
- * of the pipe.
- */
-
-#ifdef CONFIG_DEV_PIPEDUMP
-# define pipe_dumpbuffer(m,a,n) lib_dumpbuffer(m,a,n)
-#else
-# define pipe_dumpbuffer(m,a,n)
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static void pipecommon_semtake(sem_t *sem);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pipecommon_semtake
- ****************************************************************************/
-
-static void pipecommon_semtake(sem_t *sem)
-{
- while (sem_wait(sem) != 0)
- {
- /* The only case that an error should occur here is if the wait was
- * awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-}
-
-/****************************************************************************
- * Name: pipecommon_pollnotify
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static void pipecommon_pollnotify(FAR struct pipe_dev_s *dev, pollevent_t eventset)
-{
- int i;
-
- for (i = 0; i < CONFIG_DEV_PIPE_NPOLLWAITERS; i++)
- {
- struct pollfd *fds = dev->d_fds[i];
- if (fds)
- {
- fds->revents |= (fds->events & eventset);
- if (fds->revents != 0)
- {
- fvdbg("Report events: %02x\n", fds->revents);
- sem_post(fds->sem);
- }
- }
- }
-}
-#else
-# define pipecommon_pollnotify(dev,event)
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pipecommon_allocdev
- ****************************************************************************/
-
-FAR struct pipe_dev_s *pipecommon_allocdev(void)
-{
- struct pipe_dev_s *dev;
-
- /* Allocate a private structure to manage the pipe */
-
- dev = (struct pipe_dev_s *)kmalloc(sizeof(struct pipe_dev_s));
- if (dev)
- {
- /* Initialize the private structure */
-
- memset(dev, 0, sizeof(struct pipe_dev_s));
- sem_init(&dev->d_bfsem, 0, 1);
- sem_init(&dev->d_rdsem, 0, 0);
- sem_init(&dev->d_wrsem, 0, 0);
- }
-
- return dev;
-}
-
-/****************************************************************************
- * Name: pipecommon_freedev
- ****************************************************************************/
-
-void pipecommon_freedev(FAR struct pipe_dev_s *dev)
-{
- sem_destroy(&dev->d_bfsem);
- sem_destroy(&dev->d_rdsem);
- sem_destroy(&dev->d_wrsem);
- kfree(dev);
-}
-
-/****************************************************************************
- * Name: pipecommon_open
- ****************************************************************************/
-
-int pipecommon_open(FAR struct file *filep)
-{
- struct inode *inode = filep->f_inode;
- struct pipe_dev_s *dev = inode->i_private;
- int sval;
- int ret;
-
- /* Some sanity checking */
-#if CONFIG_DEBUG
- if (!dev)
- {
- return -EBADF;
- }
-#endif
-
- /* Make sure that we have exclusive access to the device structure. The
- * sem_wait() call should fail only if we are awakened by a signal.
- */
-
- ret = sem_wait(&dev->d_bfsem);
- if (ret != OK)
- {
- fdbg("sem_wait failed: %d\n", errno);
- DEBUGASSERT(errno > 0);
- return -errno;
- }
-
- /* If this the first reference on the device, then allocate the buffer */
-
- if (dev->d_refs == 0)
- {
- dev->d_buffer = (uint8_t*)kmalloc(CONFIG_DEV_PIPE_SIZE);
- if (!dev->d_buffer)
- {
- (void)sem_post(&dev->d_bfsem);
- return -ENOMEM;
- }
- }
-
- /* Increment the reference count on the pipe instance */
-
- dev->d_refs++;
-
- /* If opened for writing, increment the count of writers on on the pipe instance */
-
- if ((filep->f_oflags & O_WROK) != 0)
- {
- dev->d_nwriters++;
-
- /* If this this is the first writer, then the read semaphore indicates the
- * number of readers waiting for the first writer. Wake them all up.
- */
-
- if (dev->d_nwriters == 1)
- {
- while (sem_getvalue(&dev->d_rdsem, &sval) == 0 && sval < 0)
- {
- sem_post(&dev->d_rdsem);
- }
- }
- }
-
- /* If opened for read-only, then wait for at least one writer on the pipe */
-
- sched_lock();
- (void)sem_post(&dev->d_bfsem);
- if ((filep->f_oflags & O_RDWR) == O_RDONLY && dev->d_nwriters < 1)
- {
- /* NOTE: d_rdsem is normally used when the read logic waits for more
- * data to be written. But until the first writer has opened the
- * pipe, the meaning is different: it is used prevent O_RDONLY open
- * calls from returning until there is at least one writer on the pipe.
- * This is required both by spec and also because it prevents
- * subsequent read() calls from returning end-of-file because there is
- * no writer on the pipe.
- */
-
- ret = sem_wait(&dev->d_rdsem);
- if (ret != OK)
- {
- /* The sem_wait() call should fail only if we are awakened by
- * a signal.
- */
-
- fdbg("sem_wait failed: %d\n", errno);
- DEBUGASSERT(errno > 0);
- ret = -errno;
-
- /* Immediately close the pipe that we just opened */
-
- (void)pipecommon_close(filep);
- }
- }
-
- sched_unlock();
- return ret;
-}
-
-/****************************************************************************
- * Name: pipecommon_close
- ****************************************************************************/
-
-int pipecommon_close(FAR struct file *filep)
-{
- struct inode *inode = filep->f_inode;
- struct pipe_dev_s *dev = inode->i_private;
- int sval;
-
- /* Some sanity checking */
-#if CONFIG_DEBUG
- if (!dev)
- {
- return -EBADF;
- }
-#endif
-
- /* Make sure that we have exclusive access to the device structure.
- * NOTE: close() is supposed to return EINTR if interrupted, however
- * I've never seen anyone check that.
- */
-
- pipecommon_semtake(&dev->d_bfsem);
-
- /* Check if the decremented reference count would go to zero */
-
- if (dev->d_refs > 1)
- {
- /* No.. then just decrement the reference count */
-
- dev->d_refs--;
-
- /* If opened for writing, decrement the count of writers on on the pipe instance */
-
- if ((filep->f_oflags & O_WROK) != 0)
- {
- /* If there are no longer any writers on the pipe, then notify all of the
- * waiting readers that they must return end-of-file.
- */
-
- if (--dev->d_nwriters <= 0)
- {
- while (sem_getvalue(&dev->d_rdsem, &sval) == 0 && sval < 0)
- {
- sem_post(&dev->d_rdsem);
- }
- }
- }
- }
- else
- {
- /* Yes... deallocate the buffer */
-
- kfree(dev->d_buffer);
- dev->d_buffer = NULL;
-
- /* And reset all counts and indices */
-
- dev->d_wrndx = 0;
- dev->d_rdndx = 0;
- dev->d_refs = 0;
- dev->d_nwriters = 0;
- }
-
- sem_post(&dev->d_bfsem);
- return OK;
-}
-
-/****************************************************************************
- * Name: pipecommon_read
- ****************************************************************************/
-
-ssize_t pipecommon_read(FAR struct file *filep, FAR char *buffer, size_t len)
-{
- struct inode *inode = filep->f_inode;
- struct pipe_dev_s *dev = inode->i_private;
-#ifdef CONFIG_DEV_PIPEDUMP
- FAR uint8_t *start = (uint8_t*)buffer;
-#endif
- ssize_t nread = 0;
- int sval;
- int ret;
-
- /* Some sanity checking */
-#if CONFIG_DEBUG
- if (!dev)
- {
- return -ENODEV;
- }
-#endif
-
- /* Make sure that we have exclusive access to the device structure */
-
- if (sem_wait(&dev->d_bfsem) < 0)
- {
- return ERROR;
- }
-
- /* If the pipe is empty, then wait for something to be written to it */
-
- while (dev->d_wrndx == dev->d_rdndx)
- {
- /* If O_NONBLOCK was set, then return EGAIN */
-
- if (filep->f_oflags & O_NONBLOCK)
- {
- sem_post(&dev->d_bfsem);
- return -EAGAIN;
- }
-
- /* If there are no writers on the pipe, then return end of file */
-
- if (dev->d_nwriters <= 0)
- {
- sem_post(&dev->d_bfsem);
- return 0;
- }
-
- /* Otherwise, wait for something to be written to the pipe */
-
- sched_lock();
- sem_post(&dev->d_bfsem);
- ret = sem_wait(&dev->d_rdsem);
- sched_unlock();
-
- if (ret < 0 || sem_wait(&dev->d_bfsem) < 0)
- {
- return ERROR;
- }
- }
-
- /* Then return whatever is available in the pipe (which is at least one byte) */
-
- nread = 0;
- while (nread < len && dev->d_wrndx != dev->d_rdndx)
- {
- *buffer++ = dev->d_buffer[dev->d_rdndx];
- if (++dev->d_rdndx >= CONFIG_DEV_PIPE_SIZE)
- {
- dev->d_rdndx = 0;
- }
- nread++;
- }
-
- /* Notify all waiting writers that bytes have been removed from the buffer */
-
- while (sem_getvalue(&dev->d_wrsem, &sval) == 0 && sval < 0)
- {
- sem_post(&dev->d_wrsem);
- }
-
- /* Notify all poll/select waiters that they can write to the FIFO */
-
- pipecommon_pollnotify(dev, POLLOUT);
-
- sem_post(&dev->d_bfsem);
- pipe_dumpbuffer("From PIPE:", start, nread);
- return nread;
-}
-
-/****************************************************************************
- * Name: pipecommon_write
- ****************************************************************************/
-
-ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer, size_t len)
-{
- struct inode *inode = filep->f_inode;
- struct pipe_dev_s *dev = inode->i_private;
- ssize_t nwritten = 0;
- ssize_t last;
- int nxtwrndx;
- int sval;
-
- /* Some sanity checking */
-
-#if CONFIG_DEBUG
- if (!dev)
- {
- return -ENODEV;
- }
-#endif
-
- pipe_dumpbuffer("To PIPE:", (uint8_t*)buffer, len);
-
- /* At present, this method cannot be called from interrupt handlers. That is
- * because it calls sem_wait (via pipecommon_semtake below) and sem_wait cannot
- * be called from interrupt level. This actually happens fairly commonly
- * IF dbg() is called from interrupt handlers and stdout is being redirected
- * via a pipe. In that case, the debug output will try to go out the pipe
- * (interrupt handlers should use the lldbg() APIs).
- *
- * On the other hand, it would be very valuable to be able to feed the pipe
- * from an interrupt handler! TODO: Consider disabling interrupts instead
- * of taking semaphores so that pipes can be written from interupt handlers
- */
-
- DEBUGASSERT(up_interrupt_context() == false)
-
- /* Make sure that we have exclusive access to the device structure */
-
- if (sem_wait(&dev->d_bfsem) < 0)
- {
- return ERROR;
- }
-
- /* Loop until all of the bytes have been written */
-
- last = 0;
- for (;;)
- {
- /* Calculate the write index AFTER the next byte is written */
-
- nxtwrndx = dev->d_wrndx + 1;
- if (nxtwrndx >= CONFIG_DEV_PIPE_SIZE)
- {
- nxtwrndx = 0;
- }
-
- /* Would the next write overflow the circular buffer? */
-
- if (nxtwrndx != dev->d_rdndx)
- {
- /* No... copy the byte */
-
- dev->d_buffer[dev->d_wrndx] = *buffer++;
- dev->d_wrndx = nxtwrndx;
-
- /* Is the write complete? */
-
- if (++nwritten >= len)
- {
- /* Yes.. Notify all of the waiting readers that more data is available */
-
- while (sem_getvalue(&dev->d_rdsem, &sval) == 0 && sval < 0)
- {
- sem_post(&dev->d_rdsem);
- }
-
- /* Notify all poll/select waiters that they can write to the FIFO */
-
- pipecommon_pollnotify(dev, POLLIN);
-
- /* Return the number of bytes written */
-
- sem_post(&dev->d_bfsem);
- return len;
- }
- }
- else
- {
- /* There is not enough room for the next byte. Was anything written in this pass? */
-
- if (last < nwritten)
- {
- /* Yes.. Notify all of the waiting readers that more data is available */
-
- while (sem_getvalue(&dev->d_rdsem, &sval) == 0 && sval < 0)
- {
- sem_post(&dev->d_rdsem);
- }
- }
- last = nwritten;
-
- /* If O_NONBLOCK was set, then return partial bytes written or EGAIN */
-
- if (filep->f_oflags & O_NONBLOCK)
- {
- if (nwritten == 0)
- {
- nwritten = -EAGAIN;
- }
- sem_post(&dev->d_bfsem);
- return nwritten;
- }
-
- /* There is more to be written.. wait for data to be removed from the pipe */
-
- sched_lock();
- sem_post(&dev->d_bfsem);
- pipecommon_semtake(&dev->d_wrsem);
- sched_unlock();
- pipecommon_semtake(&dev->d_bfsem);
- }
- }
-}
-
-/****************************************************************************
- * Name: pipecommon_poll
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds,
- bool setup)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct pipe_dev_s *dev = inode->i_private;
- pollevent_t eventset;
- pipe_ndx_t nbytes;
- int ret = OK;
- int i;
-
- /* Some sanity checking */
-
-#if CONFIG_DEBUG
- if (!dev || !fds)
- {
- return -ENODEV;
- }
-#endif
-
- /* Are we setting up the poll? Or tearing it down? */
-
- pipecommon_semtake(&dev->d_bfsem);
- if (setup)
- {
- /* This is a request to set up the poll. Find an available
- * slot for the poll structure reference
- */
-
- for (i = 0; i < CONFIG_DEV_PIPE_NPOLLWAITERS; i++)
- {
- /* Find an available slot */
-
- if (!dev->d_fds[i])
- {
- /* Bind the poll structure and this slot */
-
- dev->d_fds[i] = fds;
- fds->priv = &dev->d_fds[i];
- break;
- }
- }
-
- if (i >= CONFIG_DEV_PIPE_NPOLLWAITERS)
- {
- fds->priv = NULL;
- ret = -EBUSY;
- goto errout;
- }
-
- /* Should immediately notify on any of the requested events?
- * First, determine how many bytes are in the buffer
- */
-
- if (dev->d_wrndx >= dev->d_rdndx)
- {
- nbytes = dev->d_wrndx - dev->d_rdndx;
- }
- else
- {
- nbytes = (CONFIG_DEV_PIPE_SIZE-1) + dev->d_wrndx - dev->d_rdndx;
- }
-
- /* Notify the POLLOUT event if the pipe is not full */
-
- eventset = 0;
- if (nbytes < (CONFIG_DEV_PIPE_SIZE-1))
- {
- eventset |= POLLOUT;
- }
-
- /* Notify the POLLIN event if the pipe is not empty */
-
- if (nbytes > 0)
- {
- eventset |= POLLIN;
- }
-
- if (eventset)
- {
- pipecommon_pollnotify(dev, eventset);
- }
- }
- else
- {
- /* This is a request to tear down the poll. */
-
- struct pollfd **slot = (struct pollfd **)fds->priv;
-
-#ifdef CONFIG_DEBUG
- if (!slot)
- {
- ret = -EIO;
- goto errout;
- }
-#endif
-
- /* Remove all memory of the poll setup */
-
- *slot = NULL;
- fds->priv = NULL;
- }
-
-errout:
- sem_post(&dev->d_bfsem);
- return ret;
-}
-#endif
-
-#endif /* CONFIG_DEV_PIPE_SIZE > 0 */
diff --git a/nuttx/drivers/pipes/pipe_common.h b/nuttx/drivers/pipes/pipe_common.h
deleted file mode 100644
index 44822e07f..000000000
--- a/nuttx/drivers/pipes/pipe_common.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
- * drivers/pipe/pipe_common.h
- *
- * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_PIPES_PIPE_COMMON_H
-#define __DRIVERS_PIPES_PIPE_COMMON_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <poll.h>
-
-#ifndef CONFIG_DEV_PIPE_SIZE
-# define CONFIG_DEV_PIPE_SIZE 1024
-#endif
-
-#if CONFIG_DEV_PIPE_SIZE > 0
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Maximum number of threads than can be waiting for POLL events */
-
-#ifndef CONFIG_DEV_PIPE_NPOLLWAITERS
-# define CONFIG_DEV_PIPE_NPOLLWAITERS 2
-#endif
-
-/* Maximum number of open's supported on pipe */
-
-#define CONFIG_DEV_PIPE_MAXUSER 255
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/* Make the buffer index as small as possible for the configured pipe size */
-
-#if CONFIG_DEV_PIPE_SIZE > 65535
-typedef uint32_t pipe_ndx_t; /* 32-bit index */
-#elif CONFIG_DEV_PIPE_SIZE > 255
-typedef uint16_t pipe_ndx_t; /* 16-bit index */
-#else
-typedef uint8_t pipe_ndx_t; /* 8-bit index */
-#endif
-
-/* This structure represents the state of one pipe. A reference to this
- * structure is retained in the i_private field of the inode whenthe pipe/fifo
- * device is registered.
- */
-
-struct pipe_dev_s
-{
- sem_t d_bfsem; /* Used to serialize access to d_buffer and indices */
- sem_t d_rdsem; /* Empty buffer - Reader waits for data write */
- sem_t d_wrsem; /* Full buffer - Writer waits for data read */
- pipe_ndx_t d_wrndx; /* Index in d_buffer to save next byte written */
- pipe_ndx_t d_rdndx; /* Index in d_buffer to return the next byte read */
- uint8_t d_refs; /* References counts on pipe (limited to 255) */
- uint8_t d_nwriters; /* Number of reference counts for write access */
- uint8_t d_pipeno; /* Pipe minor number */
- uint8_t *d_buffer; /* Buffer allocated when device opened */
-
- /* The following is a list if poll structures of threads waiting for
- * driver events. The 'struct pollfd' reference for each open is also
- * retained in the f_priv field of the 'struct file'.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- struct pollfd *d_fds[CONFIG_DEV_PIPE_NPOLLWAITERS];
-#endif
-};
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-#ifdef __cplusplus
-# define EXTERN extern "C"
-extern "C" {
-#else
-# define EXTERN extern
-#endif
-
-EXTERN FAR struct pipe_dev_s *pipecommon_allocdev(void);
-EXTERN void pipecommon_freedev(FAR struct pipe_dev_s *dev);
-EXTERN int pipecommon_open(FAR struct file *filep);
-EXTERN int pipecommon_close(FAR struct file *filep);
-EXTERN ssize_t pipecommon_read(FAR struct file *, FAR char *, size_t);
-EXTERN ssize_t pipecommon_write(FAR struct file *, FAR const char *, size_t);
-#ifndef CONFIG_DISABLE_POLL
-EXTERN int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds,
- bool setup);
-#endif
-
-#undef EXTERN
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* CONFIG_DEV_PIPE_SIZE > 0 */
-#endif /* __DRIVERS_PIPES_PIPE_COMMON_H */
diff --git a/nuttx/drivers/power/Kconfig b/nuttx/drivers/power/Kconfig
deleted file mode 100644
index ac76331b6..000000000
--- a/nuttx/drivers/power/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-config BATTERY
- bool "Battery support"
- default n
-
-config MAX1704X
- bool "MAX1704X Battery charger support"
- default n
- select I2C
- select I2C_MAX1704X
- depends on BATTERY
- ---help---
- The MAX17040/MAX17041 are ultra-compact, low-cost, host-side fuel-gauge
- systems for lithium-ion (Li+) batteries in handheld and portable equipment.
- The MAX17040 is configured to operate with a single lithium cell and the
- MAX17041 is configured for a dual-cell 2S pack.
-
-config I2C_MAX1704X
- bool
- default y if MAX1704X
diff --git a/nuttx/drivers/power/Make.defs b/nuttx/drivers/power/Make.defs
deleted file mode 100644
index e3452120d..000000000
--- a/nuttx/drivers/power/Make.defs
+++ /dev/null
@@ -1,84 +0,0 @@
-############################################################################
-# drivers/power/Make.defs
-#
-# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-POWER_DEPPATH =
-POWER_VPATH =
-POWER_CFLAGS =
-
-# Include power management sources
-
-ifeq ($(CONFIG_PM),y)
-
-CSRCS += pm_activity.c pm_changestate.c pm_checkstate.c pm_initialize.c pm_register.c pm_update.c
-
-# Include power management in the build
-
-POWER_DEPPATH := --dep-path power
-POWER_VPATH := :power
-POWER_CFLAGS := ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)power}
-
-endif
-
-# Add battery drivers
-
-ifeq ($(CONFIG_BATTERY),y)
-
-CSRCS += battery.c
-
-# Add I2C-based battery drivers
-
-ifeq ($(CONFIG_I2C),y)
-
-# Add the MAX1704x I2C-based battery driver
-
-ifeq ($(CONFIG_I2C_MAX1704X),y)
-CSRCS += max1704x.c
-endif
-
-endif
-
-# Include battery suport in the build
-
-POWER_DEPPATH := --dep-path power
-POWER_VPATH := :power
-POWER_CFLAGS := ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)power}
-
-endif
-
-# Include power management in the build
-
-DEPPATH += $(POWER_DEPPATH)
-VPATH += $(POWER_VPATH)
-CFLAGS += $(POWER_CFLAGS)
diff --git a/nuttx/drivers/power/battery.c b/nuttx/drivers/power/battery.c
deleted file mode 100644
index 698e5571b..000000000
--- a/nuttx/drivers/power/battery.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/****************************************************************************
- * drivers/power/battery.c
- * Upper-half, character driver for batteries.
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <stdbool.h>
-#include <semaphore.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/power/battery.h>
-
-/* This driver requires:
- *
- * CONFIG_BATTERY - Upper half battery driver support
- */
-
-#if defined(CONFIG_BATTERY)
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Character driver methods */
-
-static int bat_open(FAR struct file *filep);
-static int bat_close(FAR struct file *filep);
-static ssize_t bat_read(FAR struct file *, FAR char *, size_t nbytes);
-static ssize_t bat_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
-static int bat_ioctl(FAR struct file *filep,int cmd,unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations g_batteryops =
-{
- bat_open,
- bat_close,
- bat_read,
- bat_write,
- 0,
- bat_ioctl
-#ifndef CONFIG_DISABLE_POLL
- , 0
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-/****************************************************************************
- * Name: bat_open
- *
- * Description:
- * This function is called whenever the battery device is opened.
- *
- ****************************************************************************/
-
-static int bat_open(FAR struct file *filep)
-{
- return OK;
-}
-
-/****************************************************************************
- * Name: bat_close
- *
- * Description:
- * This routine is called when the battery device is closed.
- *
- ****************************************************************************/
-
-static int bat_close(FAR struct file *filep)
-{
- return OK;
-}
-
-/****************************************************************************
- * Name: bat_read
- ****************************************************************************/
-
-static ssize_t bat_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- /* Return nothing read */
-
- return 0;
-}
-
-/****************************************************************************
- * Name: bat_write
- ****************************************************************************/
-
-static ssize_t bat_write(FAR struct file *filep, FAR const char *buffer,
- size_t buflen)
-{
- /* Return nothing written */
-
- return 0;
-}
-
-/****************************************************************************
- * Name: bat_ioctl
- ****************************************************************************/
-
-static int bat_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct battery_dev_s *dev = inode->i_private;
- int ret = -EINVAL;
-
- /* Inforce mutually exclusive access to the battery driver */
-
- ret = sem_wait(&dev->batsem);
- if (ret < 0)
- {
- return -errno; /* Probably EINTR */
- }
-
- /* Procss the IOCTL command */
-
- ret = -EINVAL; /* Assume a bad argument */
- switch (cmd)
- {
- case BATIOC_STATE:
- {
- FAR int *ptr = (FAR int *)((uintptr_t)arg);
- if (ptr)
- {
- ret = dev->ops->state(dev, ptr);
- }
- }
- break;
-
- case BATIOC_ONLINE:
- {
- FAR bool *ptr = (FAR bool *)((uintptr_t)arg);
- if (ptr)
- {
- ret = dev->ops->online(dev, ptr);
- }
- }
- break;
-
- case BATIOC_VOLTAGE:
- {
- FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg);
- if (ptr)
- {
- ret = dev->ops->voltage(dev, ptr);
- }
- }
- break;
-
- case BATIOC_CAPACITY:
- {
- FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg);
- if (ptr)
- {
- ret = dev->ops->capacity(dev, ptr);
- }
- }
- break;
-
- default:
- dbg("Unrecognized cmd: %d\n", cmd);
- ret = -ENOTTY;
- break;
- }
-
- sem_post(&dev->batsem);
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: battery_register
- *
- * Description:
- * Register a lower half battery driver with the common, upper-half
- * battery driver.
- *
- * Input parameters:
- * devpath - The location in the pseudo-filesystem to create the driver.
- * Recommended standard is "/dev/bat0", "/dev/bat1", etc.
- * dev - An instance of the battery state structure .
- *
- * Returned value:
- * Zero on success or a negated errno value on failure.
- *
- ****************************************************************************/
-
-int battery_register(FAR const char *devpath, FAR struct battery_dev_s *dev)
-{
- int ret;
-
- /* Register the character driver */
-
- ret = register_driver(devpath, &g_batteryops, 0555, dev);
- if (ret < 0)
- {
- dbg("Failed to register driver: %d\n", ret);
- }
- return ret;
-}
-#endif /* CONFIG_BATTERY */
diff --git a/nuttx/drivers/power/max1704x.c b/nuttx/drivers/power/max1704x.c
deleted file mode 100644
index ec50515e6..000000000
--- a/nuttx/drivers/power/max1704x.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/****************************************************************************
- * drivers/power/max1704x.c
- * Lower half driver for MAX1704x battery charger
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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.
- *
- ****************************************************************************/
-
-/* "The MAX17040/MAX17041 are ultra-compact, low-cost, host-side fuel-gauge
- * systems for lithium-ion (Li+) batteries in handheld and portable equipment.
- * The MAX17040 is configured to operate with a single lithium cell and the
- * MAX17041 is configured for a dual-cell 2S pack.
- */
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/i2c.h>
-#include <nuttx/power/battery.h>
-
-/* This driver requires:
- *
- * CONFIG_BATTERY - Upper half battery driver support
- * CONFIG_I2C - I2C support
- * CONFIG_I2C_MAX1704X - And the driver must be explictly selected.
- */
-
-#if defined(CONFIG_BATTERY) && defined(CONFIG_I2C) && defined(CONFIG_I2C_MAX1704X)
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Configuration ************************************************************/
-/* CONFIG_I2C_MAX17040 or CONFIG_I2C_MAX17041 - The driver must know which
- * chip is on the board in order to scale the voltage correctly.
- */
-
-#if !defined(CONFIG_I2C_MAX17040) && !defined(CONFIG_I2C_MAX17041)
-# warning "Assuming CONFIG_I2C_MAX17040"
-# define CONFIG_I2C_MAX17040 1
-#endif
-
-/* MAX1704x Register Definitions ********************************************/
-/* "All host interaction with the MAX17040/MAX17041 is handled by writing to
- * and reading from register locations. The MAX17040/MAX17041 have six 16-bit
- * registers: SOC, VCELL, MODE, VERSION, RCOMP, and COMMAND. Register reads
- * and writes are only valid if all 16 bits are transferred..."
- */
-
-/* "VCELL Register. Battery voltage is measured at the CELL pin input with
- * respect to GND over a 0 to 5.00V range for the MAX17040 and 0 to 10.00V
- * for the MAX17041 with resolutions of 1.25mV and 2.50mV, respectively..."
- */
-
-#define MAX1407X_VCELL_ADDR 0x02 /* Bits 4-15: Bits 0-11 of the battery voltage */
-
-/* VCELL conversion macros */
-
-#define MAX14700_VCELL_CONV 82 /* 0.00125 v * 65536 */
-#define MAX14070_VCELL(v) ((b16_t)(v) * MAX14700_VCELL_CONV)
-
-#define MAX14701_VCELL_CONV 163 /* 0.0025 v * 65536 */
-#define MAX14071_VCELL(v) ((b16_t)(v) * MAX14701_VCELL_CONV)
-
-#ifdef CONFIG_I2C_MAX17040
-# define MAX1407X_VCELL(v) MAX14070_VCELL(v)
-#else
-# define MAX1407X_VCELL(v) MAX14071_VCELL(v)
-#endif
-
-/* "SOC Register. The SOC register is a read-only register that displays the
- * state of charge of the cell as calculated by the ModelGauge algorithm. The
- * result is displayed as a percentage of the cell’s full capacity...
- *
- * "...Units of % can be directly determined by observing only the high byte
- * of the SOC register. The low byte provides additional resolution in units
- * 1/256%.
- */
-
-#define MAX1407X_SOC_ADDR 0x04 /* Bits 0-15: Full SOC */
-
-/* SoC conversion macros */
-
-#define MAX1407X_SOC(s) ((b16_t)(s) << 8)
-#define MAX17040_SOC_FULL itob16(95) /* We say full if Soc >= 95% */
-
-/* "MODE Register.The MODE register allows the host processor to send special
- * commands to the IC."
- */
-
-#define MAX1407X_MODE_ADDR 0x06 /* Bits 0-15: 16-bit MODE */
-
-/* Supported modes */
-
-#define MAX1407X_MODE_QUICKSTART 0x4000
-
-/* "The VERSION register is a read-only register that contains a value
- * indicating the production version of the MAX17040/MAX17041."
- */
-
-#define MAX1407X_VERSION_ADDR 0x08 /* Bits 0-15: 16-bit VERSION */
-
-/* "RCOMP Register. RCOMP is a 16-bit value used to compensate the ModelGauge
- * algorithm. RCOMP can be adjusted to optimize performance for different
- * lithium chemistries or different operating temperatures... The factory-
- * default value for RCOMP is 9700h."
- */
-
-#define MAX1407X_RCOMP_ADDR 0x0c /* Bits 0-15: 16-bit RCOMP */
-
-/* "COMMAND Register. The COMMAND register allows the host processor to send
- * special commands to the IC..."
- */
-
-#define MAX1407X_COMMAND_ADDR 0xfe /* Bits 0-7: 16-bit COMMAND */
-
-/* Supported copmmands */
-
-#define MAX1407X_COMMAND_POR 0x5400
-
-/* Debug ********************************************************************/
-
-#ifdef CONFIG_DEBUG_MAX1704X
-# define batdbg dbg
-#else
-# ifdef CONFIG_CPP_HAVE_VARARGS
-# define batdbg(x...)
-# else
-# define batdbg (void)
-# endif
-#endif
-
-/****************************************************************************
- * Private
- ****************************************************************************/
-
-struct max1704x_dev_s
-{
- /* The common part of the battery driver visible to the upper-half driver */
-
- FAR const struct battery_operations_s *ops; /* Battery operations */
- sem_t batsem; /* Enforce mutually exclusive access */
-
- /* Data fields specific to the lower half MAX1704x driver follow */
-
- FAR struct i2c_dev_s *i2c; /* I2C interface */
- uint8_t addr; /* I2C address */
- uint32_t frequency; /* I2C frequency */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-/* I2C support */
-
-static int max1704x_getreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr,
- FAR uint16_t *regval);
-static int max1704x_putreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr,
- uint16_t regval);
-
-static inline int max1704x_getvcell(FAR struct max1704x_dev_s *priv,
- b16_t *vcell);
-static inline int max1704x_getsoc(FAR struct max1704x_dev_s *priv,
- b16_t *soc);
-static inline int max1704x_setquikstart(FAR struct max1704x_dev_s *priv);
-static inline int max1704x_getversion(FAR struct max1704x_dev_s *priv,
- uint16_t *version);
-static inline int max1704x_reset(FAR struct max1704x_dev_s *priv);
-
-/* Battery driver lower half methods */
-
-static int max1704x_state(struct battery_dev_s *dev, int *status);
-static int max1704x_online(struct battery_dev_s *dev, bool *status);
-static int max1704x_voltage(struct battery_dev_s *dev, b16_t *value);
-static int max1704x_capacity(struct battery_dev_s *dev, b16_t *value);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct battery_operations_s g_max1704xops =
-{
- max1704x_state,
- max1704x_online,
- max1704x_voltage,
- max1704x_capacity
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: max1704x_getreg16
- *
- * Description:
- * Read a 16-bit value from a MAX1704x register pair.
- *
- * START <I2C write address> ACK <Reg address> ACK
- * REPEATED-START <I2C read address> ACK Data0 ACK Data1 NO-ACK STOP
- *
- ****************************************************************************/
-
-static int max1704x_getreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr,
- FAR uint16_t *regval)
-{
- uint8_t buffer[2];
- int ret;
-
- /* Set the I2C address and address size */
-
- I2C_SETADDRESS(priv->i2c, priv->addr, 7);
-
- /* Write the register address */
-
- ret = I2C_WRITE(priv->i2c, &regaddr, 1);
- if (ret < 0)
- {
- batdbg("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)
- {
- batdbg("I2C_READ failed: %d\n", ret);
- return ret;
- }
-
- /* Return the 16-bit value */
-
- return (uint16_t)buffer[0] << 8 | (uint16_t)buffer[1];
- return OK;
-}
-
-/****************************************************************************
- * Name: max1704x_putreg16
- *
- * Description:
- * Write a 16-bit value to a MAX1704x register pair.
- *
- * START <I2C write address> ACK <Reg address> ACK Data0 ACK Data1 ACK STOP
- *
- ****************************************************************************/
-
-static int max1704x_putreg16(FAR struct max1704x_dev_s *priv, uint8_t regaddr,
- uint16_t regval)
-{
- uint8_t buffer[3];
-
- batdbg("addr: %02x regval: %08x\n", regaddr, regval);
-
- /* Set up a 3 byte message to send */
-
- buffer[0] = regaddr;
- buffer[1] = (uint8_t)(regval >> 8);
- buffer[2] = (uint8_t)(regval & 0xff);
-
- /* Set the I2C address and address size */
-
- I2C_SETADDRESS(priv->i2c, priv->addr, 7);
-
- /* Write the register address followed by the data (no RESTART) */
-
- return I2C_WRITE(priv->i2c, buffer, 3);
-}
-
-/****************************************************************************
- * Name: max1704x_getvcell
- *
- * Description:
- * Read the VCELL register and scale the returned value
- *
- ****************************************************************************/
-
-static inline int max1704x_getvcell(FAR struct max1704x_dev_s *priv,
- b16_t *vcell)
-{
- uint16_t regval = 0;
- int ret;
-
- ret = max1704x_getreg16(priv, MAX1407X_VCELL_ADDR, &regval);
- if (ret == OK)
- {
- *vcell = MAX1407X_VCELL(regval);
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: max1704x_getsoc
- *
- * Description:
- * Read the SOC register and scale the returned value
- *
- ****************************************************************************/
-
-static inline int max1704x_getsoc(FAR struct max1704x_dev_s *priv,
- b16_t *soc)
-{
- uint16_t regval = 0;
- int ret;
-
- ret = max1704x_getreg16(priv, MAX1407X_VCELL_ADDR, &regval);
- if (ret == OK)
- {
- *soc = MAX1407X_SOC(regval);
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: max1704x_setquikstart
- *
- * Description:
- * Set Quickstart mode
- *
- ****************************************************************************/
-
-static inline int max1704x_setquikstart(FAR struct max1704x_dev_s *priv)
-{
- return max1704x_putreg16(priv, MAX1407X_MODE_ADDR, MAX1407X_MODE_QUICKSTART);
-}
-
-/****************************************************************************
- * Name: max1704x_getversion
- *
- * Description:
- * Read the SOC register and scale the returned value
- *
- ****************************************************************************/
-
-static inline int max1704x_getversion(FAR struct max1704x_dev_s *priv,
- uint16_t *version)
-{
- return max1704x_getreg16(priv, MAX1407X_VCELL_ADDR, version);
-}
-
-/****************************************************************************
- * Name: max1704x_setrcomp
- *
- * Description:
- * Set Quickstart mode
- *
- ****************************************************************************/
-
-static inline int max1704x_setrcomp(FAR struct max1704x_dev_s *priv, uint16_t rcomp)
-{
- return max1704x_putreg16(priv, MAX1407X_RCOMP_ADDR, rcomp);
-}
-
-/****************************************************************************
- * Name: max1704x_reset
- *
- * Description:
- * Reset the MAX1704x
- *
- ****************************************************************************/
-
-static inline int max1704x_reset(FAR struct max1704x_dev_s *priv)
-{
- return max1704x_putreg16(priv, MAX1407X_COMMAND_ADDR, MAX1407X_COMMAND_POR);
-}
-
-/****************************************************************************
- * Name: max1704x_state
- *
- * Description:
- * Return the current battery state
- *
- ****************************************************************************/
-
-static int max1704x_state(struct battery_dev_s *dev, int *status)
-{
- FAR struct max1704x_dev_s *priv = (FAR struct max1704x_dev_s *)dev;
- b16_t soc = 0;
- int ret;
-
- /* Only a few of the possible battery states are supported by this driver:
- *
- * BATTERY_UNKNOWN - Returned on error conditions
- * BATTERY_IDLE - This is what will usually be reported
- * BATTERY_FULL - This will be reported if the SoC is greater than 95%
- * BATTERY_CHARGING and BATTERY_DISCHARGING - I don't think this hardware
- * knows anything about current (charging or dischargin).
- */
-
- ret = max1704x_getsoc(priv, &soc);
- if (ret < 0)
- {
- *status = BATTERY_UNKNOWN;
- return ret;
- }
-
- /* Is the battery fully charged? */
-
- if (soc > MAX17040_SOC_FULL)
- {
- *status = BATTERY_FULL;
- }
- else
- {
- *status = BATTERY_IDLE;
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: max1704x_online
- *
- * Description:
- * Return true if the batter is online
- *
- ****************************************************************************/
-
-static int max1704x_online(struct battery_dev_s *dev, bool *status)
-{
- /* There is no concept of online/offline in this driver */
-
- *status = true;
- return OK;
-}
-
-/****************************************************************************
- * Name: max1704x_voltage
- *
- * Description:
- * Current battery voltage
- *
- ****************************************************************************/
-
-static int max1704x_voltage(struct battery_dev_s *dev, b16_t *value)
-{
- FAR struct max1704x_dev_s *priv = (FAR struct max1704x_dev_s *)dev;
- return max1704x_getvcell(priv, value);
-}
-
-/****************************************************************************
- * Name: max1704x_capacity
- *
- * Description:
- * Battery capacity
- *
- ****************************************************************************/
-
-static int max1704x_capacity(struct battery_dev_s *dev, b16_t *value)
-{
- FAR struct max1704x_dev_s *priv = (FAR struct max1704x_dev_s *)dev;
- return max1704x_getsoc(priv, value);
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: max1704x_initialize
- *
- * Description:
- * Initialize the MAX1704x battery driver and return an instance of the
- * lower_half interface that may be used with battery_register();
- *
- * This driver requires:
- *
- * CONFIG_BATTERY - Upper half battery driver support
- * CONFIG_I2C - I2C support
- * CONFIG_I2C_MAX1704X - And the driver must be explictly selected.
- * CONFIG_I2C_MAX17040 or CONFIG_I2C_MAX17041 - The driver must know which
- * chip is on the board in order to scale the voltage correctly.
- *
- * Input Parameters:
- * i2c - An instance of the I2C interface to use to communicate with the MAX1704x
- * addr - The I2C address of the MAX1704x (Better be 0x36).
- * frequency - The I2C frequency
- *
- * Returned Value:
- * A pointer to the intialized lower-half driver instance. A NULL pointer
- * is returned on a failure to initialize the MAX1704x lower half.
- *
- ****************************************************************************/
-
-FAR struct battery_dev_s *max1704x_initialize(FAR struct i2c_dev_s *i2c,
- uint8_t addr, uint32_t frequency)
-{
- FAR struct max1704x_dev_s *priv;
-#if 0
- int ret;
-#endif
-
- /* Initialize the MAX1704x device structure */
-
- priv = (FAR struct max1704x_dev_s *)kzalloc(sizeof(struct max1704x_dev_s));
- if (priv)
- {
- /* Initialize the MAX1704x device structure */
-
- sem_init(&priv->batsem, 0, 1);
- priv->ops = &g_max1704xops;
- priv->i2c = i2c;
- priv->addr = addr;
- priv->frequency = frequency;
-
- /* Set the I2C frequency (ignoring the returned, actual frequency) */
-
- (void)I2C_SETFREQUENCY(i2c, priv->frequency);
-
- /* Reset the MAX1704x (mostly just to make sure that we can talk to it) */
-
-#if 0
- ret = max1704x_reset(priv);
- if (ret < 0)
- {
- batdbg("Failed to reset the MAX1704x: %d\n", ret);
- kfree(priv);
- return NULL;
- }
-#endif
- }
- return (FAR struct battery_dev_s *)priv;
-}
-
-#endif /* CONFIG_BATTERY && CONFIG_I2C && CONFIG_I2C_MAX1704X */
diff --git a/nuttx/drivers/power/pm_activity.c b/nuttx/drivers/power/pm_activity.c
deleted file mode 100644
index d3c8a52e7..000000000
--- a/nuttx/drivers/power/pm_activity.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/****************************************************************************
- * drivers/power/pm_activity.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <nuttx/power/pm.h>
-#include <nuttx/clock.h>
-#include <arch/irq.h>
-
-#include "pm_internal.h"
-
-#ifdef CONFIG_PM
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pm_activity
- *
- * Description:
- * This function is called by a device driver to indicate that it is
- * performing meaningful activities (non-idle). This increments an activity
- * count and/or will restart a idle timer and prevent entering reduced
- * power states.
- *
- * Input Parameters:
- * priority - Activity priority, range 0-9. Larger values correspond to
- * higher priorities. Higher priority activity can prevent the system
- * from entering reduced power states for a longer period of time.
- *
- * As an example, a button press might be higher priority activity because
- * it means that the user is actively interacting with the device.
- *
- * Returned Value:
- * None.
- *
- * Assumptions:
- * This function may be called from an interrupt handler (this is the ONLY
- * PM function that may be called from an interrupt handler!).
- *
- ****************************************************************************/
-
-void pm_activity(int priority)
-{
- uint32_t now;
- uint32_t accum;
- irqstate_t flags;
-
- /* Just increment the activity count in the current time slice. The priority
- * is simply the number of counts that are added.
- */
-
- if (priority > 0)
- {
- /* Add the priority to the accumulated counts in a critical section. */
-
- flags = irqsave();
- accum = (uint32_t)g_pmglobals.accum + priority;
-
- /* Make sure that we do not overflow the underlying uint16_t representation */
-
- if (accum > INT16_MAX)
- {
- accum = INT16_MAX;
- }
-
- /* Save the updated count */
-
- g_pmglobals.accum = (int16_t)accum;
-
- /* Check the elapsed time. In periods of low activity, time slicing is
- * controlled by IDLE loop polling; in periods of higher activity, time
- * slicing is controlled by driver activity. In either case, the duration
- * of the time slice is only approximate; during times of heavy activity,
- * time slices may be become longer and the activity level may be over-
- * estimated.
- */
-
- now = clock_systimer();
- if (now - g_pmglobals.stime >= TIME_SLICE_TICKS)
- {
- int16_t tmp;
-
- /* Sample the count, reset the time and count, and assess the PM
- * state. This is an atomic operation because interrupts are
- * still disabled.
- */
-
- tmp = g_pmglobals.accum;
- g_pmglobals.stime = now;
- g_pmglobals.accum = 0;
-
- /* Reassessing the PM state may require some computation. However,
- * the work will actually be performed on a worker thread at a user-
- * controlled priority.
- */
-
- (void)pm_update(accum);
- }
-
- irqrestore(flags);
- }
-}
-
-#endif /* CONFIG_PM */ \ No newline at end of file
diff --git a/nuttx/drivers/power/pm_changestate.c b/nuttx/drivers/power/pm_changestate.c
deleted file mode 100644
index f64760f55..000000000
--- a/nuttx/drivers/power/pm_changestate.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/****************************************************************************
- * drivers/power/pm_changestate.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <nuttx/power/pm.h>
-#include <arch/irq.h>
-
-#include "pm_internal.h"
-
-#ifdef CONFIG_PM
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pm_prepall
- *
- * Description:
- * Prepare every driver for the state change.
- *
- * Input Parameters:
- * newstate - Identifies the new PM state
- *
- * Returned Value:
- * 0 (OK) means that the callback function for all registered drivers
- * returned OK (meaning that they accept the state change). Non-zero
- * means that one of the drivers refused the state change. In this case,
- * the system will revert to the preceding state.
- *
- * Assumptions:
- * Interrupts are disabled.
- *
- ****************************************************************************/
-
-static int pm_prepall(enum pm_state_e newstate)
-{
- FAR sq_entry_t *entry;
- int ret = OK;
-
- /* Visit each registered callback structure. */
-
- for (entry = sq_peek(&g_pmglobals.registry);
- entry && ret == OK;
- entry = sq_next(entry))
- {
- /* Is the prepare callback supported? */
-
- FAR struct pm_callback_s *cb = (FAR struct pm_callback_s *)entry;
- if (cb->prepare)
- {
- /* Yes.. prepare the driver */
-
- ret = cb->prepare(cb, newstate);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: pm_changeall
- *
- * Description:
- * Inform all drivers of the state change.
- *
- * Input Parameters:
- * newstate - Identifies the new PM state
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * Interrupts are disabled.
- *
- ****************************************************************************/
-
-static inline void pm_changeall(enum pm_state_e newstate)
-{
- FAR sq_entry_t *entry;
-
- /* Visit each registered callback structure. */
-
- for (entry = sq_peek(&g_pmglobals.registry); entry; entry = sq_next(entry))
- {
- /* Is the notification callback supported? */
-
- FAR struct pm_callback_s *cb = (FAR struct pm_callback_s *)entry;
- if (cb->notify)
- {
- /* Yes.. notify the driver */
-
- cb->notify(cb, newstate);
- }
- }
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pm_changestate
- *
- * Description:
- * This function is used by platform-specific power management logic. It
- * will announce the power management power management state change to all
- * drivers that have registered for power management event callbacks.
- *
- * Input Parameters:
- * newstate - Identifies the new PM state
- *
- * Returned Value:
- * 0 (OK) means that the callback function for all registered drivers
- * returned OK (meaning that they accept the state change). Non-zero
- * means that one of the drivers refused the state change. In this case,
- * the system will revert to the preceding state.
- *
- * Assumptions:
- * It is assumed that interrupts are disabled when this function is
- * called. This function is probably called from the IDLE loop... the
- * lowest priority task in the system. Changing driver power management
- * states may result in renewed system activity and, as a result, can
- * suspend the IDLE thread before it completes the entire state change
- * unless interrupts are disabled throughout the state change.
- *
- ****************************************************************************/
-
-int pm_changestate(enum pm_state_e newstate)
-{
- irqstate_t flags;
- int ret;
-
- /* Disable interrupts throught this operation... changing driver states
- * could cause additional driver activity that might interfere with the
- * state change. When the state change is complete, interrupts will be
- * re-enabled.
- */
-
- flags = irqsave();
-
- /* First, prepare the drivers for the state change. In this phase,
- * drivers may refuse the state state change.
- */
-
- ret = pm_prepall(newstate);
- if (ret != OK)
- {
- /* One or more drivers is not ready for this state change. Revert to
- * the preceding state.
- */
-
- newstate = g_pmglobals.state;
- (void)pm_prepall(newstate);
- }
-
- /* All drivers have agreed to the state change (or, one or more have
- * disagreed and the state has been reverted). Set the new state.
- */
-
- pm_changeall(newstate);
- g_pmglobals.state = newstate;
-
- /* Restore the interrupt state */
-
- irqrestore(flags);
- return ret;
-}
-
-#endif /* CONFIG_PM */
diff --git a/nuttx/drivers/power/pm_checkstate.c b/nuttx/drivers/power/pm_checkstate.c
deleted file mode 100644
index 9b0e1045e..000000000
--- a/nuttx/drivers/power/pm_checkstate.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
- * drivers/power/pm_checkstate.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <nuttx/power/pm.h>
-#include <nuttx/clock.h>
-#include <arch/irq.h>
-
-#include "pm_internal.h"
-
-#ifdef CONFIG_PM
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pm_checkstate
- *
- * Description:
- * This function is called from the MCU-specific IDLE loop to monitor the
- * the power management conditions. This function returns the "recommended"
- * power management state based on the PM configuration and activity
- * reported in the last sampling periods. The power management state is
- * not automatically changed, however. The IDLE loop must call
- * pm_changestate() in order to make the state change.
- *
- * These two steps are separated because the plaform-specific IDLE loop may
- * have additional situational information that is not available to the
- * the PM sub-system. For example, the IDLE loop may know that the
- * battery charge level is very low and may force lower power states
- * even if there is activity.
- *
- * NOTE: That these two steps are separated in time and, hence, the IDLE
- * loop could be suspended for a long period of time between calling
- * pm_checkstate() and pm_changestate(). The IDLE loop may need to make
- * these calls atomic by either disabling interrupts until the state change
- * is completed.
- *
- * Input Parameters:
- * None
- *
- * Returned Value:
- * The recommended power management state.
- *
- ****************************************************************************/
-
-enum pm_state_e pm_checkstate(void)
-{
- uint32_t now;
- irqstate_t flags;
-
- /* Check for the end of the current time slice. This must be performed
- * with interrupts disabled so that it does not conflict with the similar
- * logic in pm_activity().
- */
-
- flags = irqsave();
-
- /* Check the elapsed time. In periods of low activity, time slicing is
- * controlled by IDLE loop polling; in periods of higher activity, time
- * slicing is controlled by driver activity. In either case, the duration
- * of the time slice is only approximate; during times of heavy activity,
- * time slices may be become longer and the activity level may be over-
- * estimated.
- */
-
- now = clock_systimer();
- if (now - g_pmglobals.stime >= TIME_SLICE_TICKS)
- {
- int16_t accum;
-
- /* Sample the count, reset the time and count, and assess the PM
- * state. This is an atomic operation because interrupts are
- * still disabled.
- */
-
- accum = g_pmglobals.accum;
- g_pmglobals.stime = now;
- g_pmglobals.accum = 0;
-
- /* Reassessing the PM state may require some computation. However,
- * the work will actually be performed on a worker thread at a user-
- * controlled priority.
- */
-
- (void)pm_update(accum);
- }
- irqrestore(flags);
-
- /* Return the recommended state. Assuming that we are called from the
- * IDLE thread at the lowest priority level, any updates scheduled on the
- * worker thread above should have already been peformed and the recommended
- * state should be current:
- */
-
- return g_pmglobals.recommended;
-}
-
-#endif /* CONFIG_PM */
diff --git a/nuttx/drivers/power/pm_initialize.c b/nuttx/drivers/power/pm_initialize.c
deleted file mode 100644
index 9401fba9e..000000000
--- a/nuttx/drivers/power/pm_initialize.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
- * drivers/power/pm_initialize.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <semaphore.h>
-
-#include <nuttx/power/pm.h>
-
-#include "pm_internal.h"
-
-#ifdef CONFIG_PM
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/* All PM global data: */
-
-struct pm_global_s g_pmglobals;
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pm_initialize
- *
- * Description:
- * This function is called by MCU-specific one-time at power on reset in
- * order to initialize the power management capabilities. This function
- * must be called *very* early in the intialization sequence *before* any
- * other device drivers are initialize (since they may attempt to register
- * with the power management subsystem).
- *
- * Input parameters:
- * None.
- *
- * Returned value:
- * None.
- *
- ****************************************************************************/
-
-void pm_initialize(void)
-{
- /* Initialize the registry and the PM global data structures. The PM
- * global data structure resides in .bss which is zeroed at boot time. So
- * it is only required to initialize non-zero elements of the PM global
- * data structure here.
- */
-
- sq_init(&g_pmglobals.registry);
- sem_init(&g_pmglobals.regsem, 0, 1);
-}
-
-#endif /* CONFIG_PM */ \ No newline at end of file
diff --git a/nuttx/drivers/power/pm_internal.h b/nuttx/drivers/power/pm_internal.h
deleted file mode 100644
index f98624f15..000000000
--- a/nuttx/drivers/power/pm_internal.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/****************************************************************************
- * drivers/power/pm_internal.h
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_POWER_PM_INTERNAL_H
-#define __DRIVERS_POWER_PM_INTERNAL_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <semaphore.h>
-#include <queue.h>
-
-#include <nuttx/power/pm.h>
-#include <nuttx/wqueue.h>
-
-#ifdef CONFIG_PM
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-/* Configuration ************************************************************/
-
-#ifndef CONFIG_SCHED_WORKQUEUE
-# warning "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)"
-#endif
-
-/* Convert the time slice interval into system clock ticks.
- *
- * CONFIG_PM_SLICEMS provides the duration of one time slice in milliseconds.
- * CLOCKS_PER_SEC provides the number of timer ticks in one second.
- *
- * slice ticks = (CONFIG_PM_SLICEMS msec / 1000 msec/sec) /
- * (CLOCKS_PER_SEC ticks/sec)
- */
-
-#define TIME_SLICE_TICKS ((CONFIG_PM_SLICEMS * CLOCKS_PER_SEC) / 1000)
-
-/* Function-like macros *****************************************************/
-/****************************************************************************
- * Name: pm_lock
- *
- * Descripton:
- * Lock the power management registry. NOTE: This function may return
- * an error if a signal is received while what (errno == EINTR).
- *
- ****************************************************************************/
-
-#define pm_lock() sem_wait(&g_pmglobals.regsem);
-
-/****************************************************************************
- * Name: pm_unlock
- *
- * Descripton:
- * Unlock the power management registry.
- *
- ****************************************************************************/
-
-#define pm_unlock() sem_post(&g_pmglobals.regsem);
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-/* This structure encapsulates all of the global data used by the PM module */
-
-struct pm_global_s
-{
- /* state - The current state (as determined by an explicit call to
- * pm_changestate()
- * recommended - The recommended state based on the PM algorithm in
- * function pm_update().
- * mndex - The index to the next slot in the memory[] array to use.
- * mcnt - A tiny counter used only at start up. The actual
- * algorithm cannot be applied until CONFIG_PM_MEMORY
- * samples have been collected.
- */
-
- uint8_t state;
- uint8_t recommended;
- uint8_t mndx;
- uint8_t mcnt;
-
- /* accum - The accumulated counts in this time interval
- * thrcnt - The number of below threshold counts seen.
- */
-
- int16_t accum;
- uint16_t thrcnt;
-
- /* This is the averaging "memory." The averaging algorithm is simply:
- * Y = (An*X + SUM(Ai*Yi))/SUM(Aj), where i = 1..n-1 and j= 1..n, n is the
- * length of the "memory", Ai is the weight applied to each value, and X is
- * the current activity.
- *
- * CONFIG_PM_MEMORY provides the memory for the algorithm. Default: 2
- * CONFIG_PM_COEFn provides weight for each sample. Default: 1
- */
-
-#if CONFIG_PM_MEMORY > 1
- int16_t memory[CONFIG_PM_MEMORY-1];
-#endif
-
- /* stime - The time (in ticks) at the start of the current time slice */
-
- uint32_t stime;
-
- /* This semaphore manages mutually exclusive access to the power management
- * registry. It must be initialized to the value 1.
- */
-
- sem_t regsem;
-
- /* For work that has been deferred to the worker thread */
-
- struct work_s work;
-
- /* registry is a singly-linked list of registered power management
- * callback structures. To ensure mutually exclusive access, this list
- * must be locked by calling pm_lock() before it is accessed.
- */
-
- sq_queue_t registry;
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-# define EXTERN extern "C"
-extern "C"
-{
-#else
-# define EXTERN extern
-#endif
-
-/* All PM global data: */
-
-EXTERN struct pm_global_s g_pmglobals;
-
-/************************************************************************************
- * Public Function Prototypes
- ************************************************************************************/
-
-/****************************************************************************
- * Name: pm_update
- *
- * Description:
- * This internal function is called at the end of a time slice in order to
- * update driver activity metrics and recommended states.
- *
- * Input Parameters:
- * accum - The value of the activity accumulator at the end of the time
- * slice.
- *
- * Returned Value:
- * None.
- *
- * Assumptions:
- * This function may be called from a driver, perhaps even at the interrupt
- * level. It may also be called from the IDLE loop at the lowest possible
- * priority level. To reconcile these various conditions, all work is
- * performed on the worker thread at a user-selectable priority.
- *
- ****************************************************************************/
-
-EXTERN void pm_update(int16_t accum);
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* CONFIG_PM */
-#endif /* #define __DRIVERS_POWER_PM_INTERNAL_H */
diff --git a/nuttx/drivers/power/pm_register.c b/nuttx/drivers/power/pm_register.c
deleted file mode 100644
index 19f94cb02..000000000
--- a/nuttx/drivers/power/pm_register.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
- * drivers/power/pm_register.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <queue.h>
-#include <assert.h>
-
-#include <nuttx/power/pm.h>
-
-#include "pm_internal.h"
-
-#ifdef CONFIG_PM
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pm_register
- *
- * Description:
- * This function is called by a device driver in order to register to
- * receive power management event callbacks.
- *
- * Input parameters:
- * callbacks - An instance of struct pm_callback_s providing the driver
- * callback functions.
- *
- * Returned value:
- * Zero (OK) on success; otherwise a negater errno value is returned.
- *
- ****************************************************************************/
-
-int pm_register(FAR struct pm_callback_s *callbacks)
-{
- int ret;
-
- DEBUGASSERT(callbacks);
-
- /* Add the new entry to the end of the list of registered callbacks */
-
- ret = pm_lock();
- if (ret == OK)
- {
- sq_addlast(&callbacks->entry, &g_pmglobals.registry);
- pm_unlock();
- }
- return ret;
-}
-
-#endif /* CONFIG_PM */ \ No newline at end of file
diff --git a/nuttx/drivers/power/pm_update.c b/nuttx/drivers/power/pm_update.c
deleted file mode 100644
index 4b6b58c55..000000000
--- a/nuttx/drivers/power/pm_update.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/****************************************************************************
- * drivers/power/pm_update.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <assert.h>
-
-#include <nuttx/power/pm.h>
-#include <nuttx/wqueue.h>
-
-#include "pm_internal.h"
-
-#ifdef CONFIG_PM
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-/* CONFIG_PM_MEMORY is the total number of time slices (including the current
- * time slice. The histor or previous values is then CONFIG_PM_MEMORY-1.
- */
-
-#if CONFIG_PM_MEMORY > 1
-static const int16_t g_pmcoeffs[CONFIG_PM_MEMORY-1] =
-{
- CONFIG_PM_COEF1
-#if CONFIG_PM_MEMORY > 2
- , CONFIG_PM_COEF2
-#endif
-#if CONFIG_PM_MEMORY > 3
- , CONFIG_PM_COEF3
-#endif
-#if CONFIG_PM_MEMORY > 4
- , CONFIG_PM_COEF4
-#endif
-#if CONFIG_PM_MEMORY > 5
- , CONFIG_PM_COEF5
-#endif
-#if CONFIG_PM_MEMORY > 6
-# warning "This logic needs to be extended"
-#endif
-};
-#endif
-
-/* Threshold activity values to enter into the next lower power consumption
- * state. Indexing is next state 0:IDLE, 1:STANDBY, 2:SLEEP.
- */
-
-static const int16_t g_pmenterthresh[3] =
-{
- CONFIG_PM_IDLEENTER_THRESH,
- CONFIG_PM_STANDBYENTER_THRESH,
- CONFIG_PM_SLEEPENTER_THRESH
-};
-
-/* Threshold activity values to leave the current low power consdumption
- * state. Indexing is current state 0:IDLE, 1: STANDBY, 2: SLEEP.
- */
-
-static const int16_t g_pmexitthresh[3] =
-{
- CONFIG_PM_IDLEEXIT_THRESH,
- CONFIG_PM_STANDBYEXIT_THRESH,
- CONFIG_PM_SLEEPEXIT_THRESH
-};
-
-/* Threshold time slice count to enter the next low power consdumption
- * state. Indexing is next state 0:IDLE, 1: STANDBY, 2: SLEEP.
- */
-
-static const uint16_t g_pmcount[3] =
-{
- CONFIG_PM_IDLEENTER_COUNT,
- CONFIG_PM_STANDBYENTER_COUNT,
- CONFIG_PM_SLEEPENTER_COUNT
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pm_worker
- *
- * Description:
- * This worker function is queue at the end of a time slice in order to
- * update driver activity metrics and recommended states.
- *
- * Input Parameters:
- * arg - The value of the activity accumulator at the end of the time
- * slice.
- *
- * Returned Value:
- * None.
- *
- * Assumptions:
- * This function runs on the worker thread.
- *
- ****************************************************************************/
-
-void pm_worker(FAR void *arg)
-{
- int16_t accum = (int16_t)((intptr_t)arg);
- int32_t Y;
- int index;
-
-#if CONFIG_PM_MEMORY > 1
- int32_t denom;
- int i, j;
-
- /* We won't bother to do anything until we have accumulated
- * CONFIG_PM_MEMORY-1 samples.
- */
-
- if (g_pmglobals.mcnt < CONFIG_PM_MEMORY-1)
- {
- g_pmglobals.memory[g_pmglobals.mcnt] = accum;
- g_pmglobals.mcnt++;
- return;
- }
-
- /* The averaging algorithm is simply: Y = (An*X + SUM(Ai*Yi))/SUM(Aj), where
- * i = 1..n-1 and j= 1..n, n is the length of the "memory", Ai is the
- * weight applied to each value, and X is the current activity.
- *
- * CONFIG_PM_MEMORY provides the memory for the algorithm. Default: 2
- * CONFIG_PM_COEFn provides weight for each sample. Default: 1
- *
- * First, calclate Y = An*X
- */
-
- Y = CONFIG_PM_COEFN * accum;
- denom = CONFIG_PM_COEFN;
-
- /* Then calculate Y += SUM(Ai*Yi), i = 1..n-1. The oldest sample will
- * reside at g_pmglobals.mndx (and this is the value that we will overwrite
- * with the new value).
- */
-
- for (i = 0, j = g_pmglobals.mndx; i < CONFIG_PM_MEMORY-1; i++, j++)
- {
- if (j >= CONFIG_PM_MEMORY-1)
- {
- j = 0;
- }
-
- Y += g_pmcoeffs[i] * g_pmglobals.memory[j];
- denom += g_pmcoeffs[i];
- }
-
- /* Compute and save the new activity value */
-
- Y /= denom;
- g_pmglobals.memory[g_pmglobals.mndx] = Y;
- g_pmglobals.mndx++;
- if (g_pmglobals.mndx >= CONFIG_PM_MEMORY-1)
- {
- g_pmglobals.mndx = 0;
- }
-
-#else
-
- /* No smoothing */
-
- Y = accum;
-
-#endif
-
- /* First check if increased activity should cause us to return to the
- * normal operating state. This would be unlikely for the lowest power
- * consumption states because the CPU is probably asleep. However this
- * probably does apply for the IDLE state.
- */
-
- if (g_pmglobals.state > PM_NORMAL)
- {
- /* Get the table index for the current state (which will be the
- * current state minus one)
- */
-
- index = g_pmglobals.state - 1;
-
- /* Has the threshold to return to normal power consumption state been
- * exceeded?
- */
-
- if (Y > g_pmexitthresh[index])
- {
- /* Yes... reset the count and recommend the normal state. */
-
- g_pmglobals.thrcnt = 0;
- g_pmglobals.recommended = PM_NORMAL;
- return;
- }
- }
-
- /* Now, compare this new activity level to the thresholds and counts for
- * the next lower power consumption state. If we are already in the SLEEP
- * state, then there is nothing more to be done (in fact, I would be
- * surprised to be executing!).
- */
-
- if (g_pmglobals.state < PM_SLEEP)
- {
- unsigned int nextstate;
-
- /* Get the next state and the table index for the next state (which will
- * be the current state)
- */
-
- index = g_pmglobals.state;
- nextstate = g_pmglobals.state + 1;
-
- /* Has the threshold to enter the next lower power consumption state
- * been exceeded?
- */
-
- if (Y > g_pmenterthresh[index])
- {
- /* No... reset the count and recommend the current state */
-
- g_pmglobals.thrcnt = 0;
- g_pmglobals.recommended = g_pmglobals.state;
- }
-
- /* Yes.. have we already recommended this state? If so, do nothing */
-
- else if (g_pmglobals.recommended < nextstate)
- {
- /* No.. increment the count. Has is passed the the count required
- * for a state transition?
- */
-
- if (++g_pmglobals.thrcnt >= g_pmcount[index])
- {
- /* Yes, recommend the new state and set up for the next
- * transition.
- */
-
- g_pmglobals.thrcnt = 0;
- g_pmglobals.recommended = nextstate;
- }
- }
- }
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pm_update
- *
- * Description:
- * This internal function is called at the end of a time slice in order to
- * update driver activity metrics and recommended states.
- *
- * Input Parameters:
- * accum - The value of the activity accumulator at the end of the time
- * slice.
- *
- * Returned Value:
- * None.
- *
- * Assumptions:
- * This function may be called from a driver, perhaps even at the interrupt
- * level. It may also be called from the IDLE loop at the lowest possible
- * priority level. To reconcile these various conditions, all work is
- * performed on the worker thread at a user-selectable priority. This will
- * also serialize all of the updates and eliminate any need for additional
- * protection.
- *
- ****************************************************************************/
-
-void pm_update(int16_t accum)
-{
- /* The work will be performed on the worker thread */
-
- DEBUGASSERT(g_pmglobals.work.worker == NULL);
- (void)work_queue(HPWORK, &g_pmglobals.work, pm_worker, (FAR void*)((intptr_t)accum), 0);
-}
-
-#endif /* CONFIG_PM */
diff --git a/nuttx/drivers/pwm.c b/nuttx/drivers/pwm.c
deleted file mode 100644
index 62fb4d2fb..000000000
--- a/nuttx/drivers/pwm.c
+++ /dev/null
@@ -1,676 +0,0 @@
-/****************************************************************************
- * drivers/pwm.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Compilation Switches
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <semaphore.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/arch.h>
-#include <nuttx/pwm.h>
-
-#include <arch/irq.h>
-
-#ifdef CONFIG_PWM
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Debug ********************************************************************/
-/* Non-standard debug that may be enabled just for testing PWM */
-
-#ifdef CONFIG_DEBUG_PWM
-# define pwmdbg dbg
-# define pwmvdbg vdbg
-# define pwmlldbg lldbg
-# define pwmllvdbg llvdbg
-#else
-# define pwmdbg(x...)
-# define pwmvdbg(x...)
-# define pwmlldbg(x...)
-# define pwmllvdbg(x...)
-#endif
-
-/****************************************************************************
- * Private Type Definitions
- ****************************************************************************/
-
-/* This structure describes the state of the upper half driver */
-
-struct pwm_upperhalf_s
-{
- uint8_t crefs; /* The number of times the device has been opened */
- volatile bool started; /* True: pulsed output is being generated */
-#ifdef CONFIG_PWM_PULSECOUNT
- volatile bool waiting; /* True: Caller is waiting for the pulse count to expire */
-#endif
- sem_t exclsem; /* Supports mutual exclusion */
-#ifdef CONFIG_PWM_PULSECOUNT
- sem_t waitsem; /* Used to wait for the pulse count to expire */
-#endif
- struct pwm_info_s info; /* Pulsed output characteristics */
- FAR struct pwm_lowerhalf_s *dev; /* lower-half state */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int pwm_open(FAR struct file *filep);
-static int pwm_close(FAR struct file *filep);
-static ssize_t pwm_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
-static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
-static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags);
-static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations g_pwmops =
-{
- pwm_open, /* open */
- pwm_close, /* close */
- pwm_read, /* read */
- pwm_write, /* write */
- 0, /* seek */
- pwm_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , 0 /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/************************************************************************************
- * Name: pwm_open
- *
- * Description:
- * This function is called whenever the PWM device is opened.
- *
- ************************************************************************************/
-
-static int pwm_open(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct pwm_upperhalf_s *upper = inode->i_private;
- uint8_t tmp;
- int ret;
-
- pwmvdbg("crefs: %d\n", upper->crefs);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0)
- {
- ret = -errno;
- goto errout;
- }
-
- /* Increment the count of references to the device. If this the first
- * time that the driver has been opened for this device, then initialize
- * the device.
- */
-
- tmp = upper->crefs + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- goto errout_with_sem;
- }
-
- /* Check if this is the first time that the driver has been opened. */
-
- if (tmp == 1)
- {
- FAR struct pwm_lowerhalf_s *lower = upper->dev;
-
- /* Yes.. perform one time hardware initialization. */
-
- DEBUGASSERT(lower->ops->setup != NULL);
- pwmvdbg("calling setup\n");
-
- ret = lower->ops->setup(lower);
- if (ret < 0)
- {
- goto errout_with_sem;
- }
- }
-
- /* Save the new open count on success */
-
- upper->crefs = tmp;
- ret = OK;
-
-errout_with_sem:
- sem_post(&upper->exclsem);
-
-errout:
- return ret;
-}
-
-/************************************************************************************
- * Name: pwm_close
- *
- * Description:
- * This function is called when the PWM device is closed.
- *
- ************************************************************************************/
-
-static int pwm_close(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct pwm_upperhalf_s *upper = inode->i_private;
- int ret;
-
- pwmvdbg("crefs: %d\n", upper->crefs);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0)
- {
- ret = -errno;
- goto errout;
- }
-
- /* Decrement the references to the driver. If the reference count will
- * decrement to 0, then uninitialize the driver.
- */
-
- if (upper->crefs > 1)
- {
- upper->crefs--;
- }
- else
- {
- FAR struct pwm_lowerhalf_s *lower = upper->dev;
-
- /* There are no more references to the port */
-
- upper->crefs = 0;
-
- /* Disable the PWM device */
-
- DEBUGASSERT(lower->ops->shutdown != NULL);
- pwmvdbg("calling shutdown: %d\n");
-
- lower->ops->shutdown(lower);
- }
- ret = OK;
-
-//errout_with_sem:
- sem_post(&upper->exclsem);
-
-errout:
- return ret;
-}
-
-/************************************************************************************
- * Name: pwm_read
- *
- * Description:
- * A dummy read method. This is provided only to satsify the VFS layer.
- *
- ************************************************************************************/
-
-static ssize_t pwm_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- /* Return zero -- usually meaning end-of-file */
-
- return 0;
-}
-
-/************************************************************************************
- * Name: pwm_write
- *
- * Description:
- * A dummy write method. This is provided only to satsify the VFS layer.
- *
- ************************************************************************************/
-
-static ssize_t pwm_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
-{
- return 0;
-}
-
-/************************************************************************************
- * Name: pwm_start
- *
- * Description:
- * Handle the PWMIOC_START ioctl command
- *
- ************************************************************************************/
-
-#ifdef CONFIG_PWM_PULSECOUNT
-static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags)
-{
- FAR struct pwm_lowerhalf_s *lower = upper->dev;
- irqstate_t flags;
- int ret = OK;
-
- DEBUGASSERT(upper != NULL && lower->ops->start != NULL);
-
- /* Verify that the PWM is not already running */
-
- if (!upper->started)
- {
- /* Disable interrupts to avoid race conditions */
-
- flags = irqsave();
-
- /* Indicate that if will be waiting for the pulse count to complete.
- * Note that we will only wait if a non-zero pulse count is specified
- * and if the PWM driver was opened in normal, blocking mode. Also
- * assume for now that the pulse train will be successfully started.
- *
- * We do these things before starting the PWM to avoid race conditions.
- */
-
- upper->waiting = (upper->info.count > 0) && ((oflags & O_NONBLOCK) == 0);
- upper->started = true;
-
- /* Invoke the bottom half method to start the pulse train */
-
- ret = lower->ops->start(lower, &upper->info, upper);
-
- /* A return value of zero means that the pulse train was started
- * successfully.
- */
-
- if (ret == OK)
- {
- /* Should we wait for the pulse output to complete? Loop in
- * in case the wakeup form sem_wait() is a false alarm.
- */
-
- while (upper->waiting)
- {
- /* Wait until we are awakened by pwm_expired(). When
- * pwm_expired is called, it will post the waitsem and
- * clear the waiting flag.
- */
-
- int tmp = sem_wait(&upper->waitsem);
- DEBUGASSERT(tmp == OK || errno == EINTR);
- }
- }
- else
- {
- /* Looks like we won't be waiting after all */
-
- pwmvdbg("start failed: %d\n", ret);
- upper->started = false;
- upper->waiting = false;
- }
-
- irqrestore(flags);
- }
-
- return ret;
-}
-#else
-static int pwm_start(FAR struct pwm_upperhalf_s *upper, unsigned int oflags)
-{
- FAR struct pwm_lowerhalf_s *lower = upper->dev;
- int ret = OK;
-
- DEBUGASSERT(upper != NULL && lower->ops->start != NULL);
-
- /* Verify that the PWM is not already running */
-
- if (!upper->started)
- {
- /* Invoke the bottom half method to start the pulse train */
-
- ret = lower->ops->start(lower, &upper->info);
-
- /* A return value of zero means that the pulse train was started
- * successfully.
- */
-
- if (ret == OK)
- {
- /* Indicate that the pulse train has started */
-
- upper->started = true;
- }
- }
-
- return ret;
-}
-#endif
-
-/************************************************************************************
- * Name: pwm_ioctl
- *
- * Description:
- * The standard ioctl method. This is where ALL of the PWM work is done.
- *
- ************************************************************************************/
-
-static int pwm_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct pwm_upperhalf_s *upper = inode->i_private;
- FAR struct pwm_lowerhalf_s *lower = upper->dev;
- int ret;
-
- pwmvdbg("cmd: %d arg: %ld\n", cmd, arg);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0)
- {
- return ret;
- }
-
- /* Handle built-in ioctl commands */
-
- switch (cmd)
- {
- /* PWMIOC_SETCHARACTERISTICS - Set the characteristics of the next pulsed
- * output. This command will neither start nor stop the pulsed output.
- * It will either setup the configuration that will be used when the
- * output is started; or it will change the characteristics of the pulsed
- * output on the fly if the timer is already started.
- *
- * ioctl argument: A read-only reference to struct pwm_info_s that provides
- * the characteristics of the pulsed output.
- */
-
- case PWMIOC_SETCHARACTERISTICS:
- {
- FAR const struct pwm_info_s *info = (FAR const struct pwm_info_s*)((uintptr_t)arg);
- DEBUGASSERT(info != NULL && lower->ops->start != NULL);
-
-#ifdef CONFIG_PWM_PULSECOUNT
- pwmvdbg("PWMIOC_SETCHARACTERISTICS frequency: %d duty: %08x count: %d started: %d\n",
- info->frequency, info->duty, info->count, upper->started);
-#else
- pwmvdbg("PWMIOC_SETCHARACTERISTICS frequency: %d duty: %08x started: %d\n",
- info->frequency, info->duty, upper->started);
-#endif
-
- /* Save the pulse train characteristics */
-
- memcpy(&upper->info, info, sizeof(struct pwm_info_s));
-
- /* If PWM is already running, then re-start it with the new characteristics */
-
- if (upper->started)
- {
-#ifdef CONFIG_PWM_PULSECOUNT
- ret = lower->ops->start(lower, &upper->info, upper);
-#else
- ret = lower->ops->start(lower, &upper->info);
-#endif
- }
- }
- break;
-
- /* PWMIOC_GETCHARACTERISTICS - Get the currently selected characteristics of
- * the pulsed output (independent of whether the output is start or stopped).
- *
- * ioctl argument: A reference to struct pwm_info_s to recevie the
- * characteristics of the pulsed output.
- */
-
- case PWMIOC_GETCHARACTERISTICS:
- {
- FAR struct pwm_info_s *info = (FAR struct pwm_info_s*)((uintptr_t)arg);
- DEBUGASSERT(info != NULL);
-
- memcpy(info, &upper->info, sizeof(struct pwm_info_s));
-
-#ifdef CONFIG_PWM_PULSECOUNT
- pwmvdbg("PWMIOC_GETCHARACTERISTICS frequency: %d duty: %08x count: %d\n",
- info->frequency, info->duty, info->count);
-#else
- pwmvdbg("PWMIOC_GETCHARACTERISTICS frequency: %d duty: %08x\n",
- info->frequency, info->duty);
-#endif
- }
- break;
-
- /* PWMIOC_START - Start the pulsed output. The PWMIOC_SETCHARACTERISTICS
- * command must have previously been sent.
- *
- * ioctl argument: None
- */
-
- case PWMIOC_START:
- {
-#ifdef CONFIG_PWM_PULSECOUNT
- pwmvdbg("PWMIOC_START frequency: %d duty: %08x count: %d started: %d\n",
- upper->info.frequency, upper->info.duty, upper->info.count,
- upper->started);
-#else
- pwmvdbg("PWMIOC_START frequency: %d duty: %08x started: %d\n",
- upper->info.frequency, upper->info.duty, upper->started);
-#endif
- DEBUGASSERT(lower->ops->start != NULL);
-
- /* Start the pulse train */
-
- ret = pwm_start(upper, filep->f_oflags);
- }
- break;
-
- /* PWMIOC_STOP - Stop the pulsed output.
- *
- * ioctl argument: None
- */
-
- case PWMIOC_STOP:
- {
- pwmvdbg("PWMIOC_STOP: started: %d\n", upper->started);
- DEBUGASSERT(lower->ops->stop != NULL);
-
- if (upper->started)
- {
- ret = lower->ops->stop(lower);
- upper->started = false;
-#ifdef CONFIG_PWM_PULSECOUNT
- if (upper->waiting)
- {
- upper->waiting = FALSE;
- }
-#endif
- }
- }
- break;
-
- /* Any unrecognized IOCTL commands might be platform-specific ioctl commands */
-
- default:
- {
- pwmvdbg("Forwarding unrecognized cmd: %d arg: %ld\n", cmd, arg);
- DEBUGASSERT(lower->ops->ioctl != NULL);
- ret = lower->ops->ioctl(lower, cmd, arg);
- }
- break;
- }
-
- sem_post(&upper->exclsem);
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: pwm_register
- *
- * Description:
- * This function binds an instance of a "lower half" timer driver with the
- * "upper half" PWM device and registers that device so that can be used
- * by application code.
- *
- * When this function is called, the "lower half" driver should be in the
- * reset state (as if the shutdown() method had already been called).
- *
- * Input parameters:
- * path - The full path to the driver to be registers in the NuttX pseudo-
- * filesystem. The recommended convention is to name all PWM drivers
- * as "/dev/pwm0", "/dev/pwm1", etc. where the driver path differs only
- * in the "minor" number at the end of the device name.
- * dev - A pointer to an instance of lower half timer driver. This instance
- * is bound to the PWM driver and must persists as long as the driver
- * persists.
- *
- * Returned Value:
- * Zero on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int pwm_register(FAR const char *path, FAR struct pwm_lowerhalf_s *dev)
-{
- FAR struct pwm_upperhalf_s *upper;
-
- /* Allocate the upper-half data structure */
-
- upper = (FAR struct pwm_upperhalf_s *)zalloc(sizeof(struct pwm_upperhalf_s));
- if (!upper)
- {
- pwmdbg("Allocation failed\n");
- return -ENOMEM;
- }
-
- /* Initialize the PWM device structure (it was already zeroed by zalloc()) */
-
- sem_init(&upper->exclsem, 0, 1);
-#ifdef CONFIG_PWM_PULSECOUNT
- sem_init(&upper->waitsem, 0, 0);
-#endif
- upper->dev = dev;
-
- /* Register the PWM device */
-
- pwmvdbg("Registering %s\n", path);
- return register_driver(path, &g_pwmops, 0666, upper);
-}
-
-/****************************************************************************
- * Name: pwm_expired
- *
- * Description:
- * If CONFIG_PWM_PULSECOUNT is defined and the pulse count was configured
- * to a non-zero value, then the "upper half" driver will wait for the
- * pulse count to expire. The sequence of expected events is as follows:
- *
- * 1. The upper half driver calls the start method, providing the lower
- * half driver with the pulse train characteristics. If a fixed
- * number of pulses is required, the 'count' value will be nonzero.
- * 2. The lower half driver's start() methoc must verify that it can
- * support the request pulse train (frequency, duty, AND pulse count).
- * It it cannot, it should return an error. If the pulse count is
- * non-zero, it should set up the hardware for that number of pulses
- * and return success. NOTE: That is CONFIG_PWM_PULSECOUNT is
- * defined, the start() method receives an additional parameter
- * that must be used in this callback.
- * 3. When the start() method returns success, the upper half driver
- * will "sleep" until the pwm_expired method is called.
- * 4. When the lower half detects that the pulse count has expired
- * (probably through an interrupt), it must call the pwm_expired
- * interface using the handle that was previously passed to the
- * start() method
- *
- * Input parameters:
- * handle - This is the handle that was provided to the lower-half
- * start() method.
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * This function may be called from an interrupt handler.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_PWM_PULSECOUNT
-void pwm_expired(FAR void *handle)
-{
- FAR struct pwm_upperhalf_s *upper = (FAR struct pwm_upperhalf_s *)handle;
-
- pwmllvdbg("started: %d waiting: %d\n", upper->started, upper->waiting);
-
- /* Make sure that the PWM is started */
-
- if (upper->started)
- {
- /* Is there a thread waiting for the pulse train to complete? */
-
- if (upper->waiting)
- {
- /* Yes.. clear the waiting flag and awakened the waiting thread */
-
- upper->waiting = false;
- sem_post(&upper->waitsem);
- }
-
- /* The PWM is now stopped */
-
- upper->started = false;
- }
-}
-#endif
-
-#endif /* CONFIG_PWM */
diff --git a/nuttx/drivers/ramdisk.c b/nuttx/drivers/ramdisk.c
deleted file mode 100644
index 91912b25c..000000000
--- a/nuttx/drivers/ramdisk.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/****************************************************************************
- * drivers/ramdisk.c
- *
- * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <debug.h>
-#include <errno.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/ramdisk.h>
-
-/****************************************************************************
- * Private Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct rd_struct_s
-{
- uint32_t rd_nsectors; /* Number of sectors on device */
- uint16_t rd_sectsize; /* The size of one sector */
-#ifdef CONFIG_FS_WRITABLE
- bool rd_writeenabled; /* true: can write to ram disk */
- uint8_t *rd_buffer; /* RAM disk backup memory */
-#else
- const uint8_t *rd_buffer; /* ROM disk backup memory */
-#endif
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int rd_open(FAR struct inode *inode);
-static int rd_close(FAR struct inode *inode);
-static ssize_t rd_read(FAR struct inode *inode, unsigned char *buffer,
- size_t start_sector, unsigned int nsectors);
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t rd_write(FAR struct inode *inode, const unsigned char *buffer,
- size_t start_sector, unsigned int nsectors);
-#endif
-static int rd_geometry(FAR struct inode *inode, struct geometry *geometry);
-static int rd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct block_operations g_bops =
-{
- rd_open, /* open */
- rd_close, /* close */
- rd_read, /* read */
-#ifdef CONFIG_FS_WRITABLE
- rd_write, /* write */
-#else
- NULL, /* write */
-#endif
- rd_geometry, /* geometry */
- rd_ioctl /* ioctl */
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: rd_open
- *
- * Description: Open the block device
- *
- ****************************************************************************/
-
-static int rd_open(FAR struct inode *inode)
-{
- fvdbg("Entry\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: rd_closel
- *
- * Description: close the block device
- *
- ****************************************************************************/
-
-static int rd_close(FAR struct inode *inode)
-{
- fvdbg("Entry\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: rd_read
- *
- * Description: Read the specified numer of sectors
- *
- ****************************************************************************/
-
-static ssize_t rd_read(FAR struct inode *inode, unsigned char *buffer,
- size_t start_sector, unsigned int nsectors)
-{
- struct rd_struct_s *dev;
-
- DEBUGASSERT(inode && inode->i_private);
- dev = (struct rd_struct_s *)inode->i_private;
-
- fvdbg("sector: %d nsectors: %d sectorsize: %d\n",
- start_sector, dev->rd_sectsize, nsectors);
-
- if (start_sector < dev->rd_nsectors &&
- start_sector + nsectors <= dev->rd_nsectors)
- {
- fvdbg("Transfer %d bytes from %p\n",
- nsectors * dev->rd_sectsize,
- &dev->rd_buffer[start_sector * dev->rd_sectsize]);
-
- memcpy(buffer,
- &dev->rd_buffer[start_sector * dev->rd_sectsize],
- nsectors * dev->rd_sectsize);
- return nsectors;
- }
-
- return -EINVAL;
-}
-
-/****************************************************************************
- * Name: rd_write
- *
- * Description: Write the specified number of sectors
- *
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t rd_write(FAR struct inode *inode, const unsigned char *buffer,
- size_t start_sector, unsigned int nsectors)
-{
- struct rd_struct_s *dev;
-
- DEBUGASSERT(inode && inode->i_private);
- dev = (struct rd_struct_s *)inode->i_private;
-
- fvdbg("sector: %d nsectors: %d sectorsize: %d\n",
- start_sector, dev->rd_sectsize, nsectors);
-
- if (!dev->rd_writeenabled)
- {
- return -EACCES;
- }
- else if (start_sector < dev->rd_nsectors &&
- start_sector + nsectors <= dev->rd_nsectors)
- {
- fvdbg("Transfer %d bytes from %p\n",
- nsectors * dev->rd_sectsize,
- &dev->rd_buffer[start_sector * dev->rd_sectsize]);
-
- memcpy(&dev->rd_buffer[start_sector * dev->rd_sectsize],
- buffer,
- nsectors * dev->rd_sectsize);
- return nsectors;
- }
-
- return -EFBIG;
-}
-#endif
-
-/****************************************************************************
- * Name: rd_geometry
- *
- * Description: Return device geometry
- *
- ****************************************************************************/
-
-static int rd_geometry(FAR struct inode *inode, struct geometry *geometry)
-{
- struct rd_struct_s *dev;
-
- fvdbg("Entry\n");
-
- DEBUGASSERT(inode);
- if (geometry)
- {
- dev = (struct rd_struct_s *)inode->i_private;
- geometry->geo_available = true;
- geometry->geo_mediachanged = false;
-#ifdef CONFIG_FS_WRITABLE
- geometry->geo_writeenabled = dev->rd_writeenabled;
-#else
- geometry->geo_writeenabled = false;
-#endif
- geometry->geo_nsectors = dev->rd_nsectors;
- geometry->geo_sectorsize = dev->rd_sectsize;
-
- fvdbg("available: true mediachanged: false writeenabled: %s\n",
- geometry->geo_writeenabled ? "true" : "false");
- fvdbg("nsectors: %d sectorsize: %d\n",
- geometry->geo_nsectors, geometry->geo_sectorsize);
-
- return OK;
- }
-
- return -EINVAL;
-}
-
-/****************************************************************************
- * Name: rd_ioctl
- *
- * Description: Return device geometry
- *
- ****************************************************************************/
-
-static int rd_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
-{
- struct rd_struct_s *dev ;
- void **ppv = (void**)((uintptr_t)arg);
-
- fvdbg("Entry\n");
-
- /* Only one ioctl command is supported */
-
- DEBUGASSERT(inode && inode->i_private);
- if (cmd == BIOC_XIPBASE && ppv)
- {
- dev = (struct rd_struct_s *)inode->i_private;
- *ppv = (void*)dev->rd_buffer;
-
- fvdbg("ppv: %p\n", *ppv);
- return OK;
- }
-
- return -ENOTTY;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: ramdisk_register
- *
- * Description: Register the a ramdisk
-
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITABLE
-int ramdisk_register(int minor, uint8_t *buffer, uint32_t nsectors,
- uint16_t sectsize, bool writeenabled)
-#else
-int romdisk_register(int minor, uint8_t *buffer, uint32_t nsectors,
- uint16_t sectsize)
-#endif
-{
- struct rd_struct_s *dev;
- char devname[16];
- int ret = -ENOMEM;
-
- fvdbg("buffer: %p nsectors: %d sectsize: %d\n", buffer, nsectors, sectsize);
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (minor < 0 || minor > 255 || !buffer || !nsectors || !sectsize)
- {
- return -EINVAL;
- }
-#endif
-
- /* Allocate a ramdisk device structure */
-
- dev = (struct rd_struct_s *)kmalloc(sizeof(struct rd_struct_s));
- if (dev)
- {
- /* Initialize the ramdisk device structure */
-
- dev->rd_nsectors = nsectors; /* Number of sectors on device */
- dev->rd_sectsize = sectsize; /* The size of one sector */
-#ifdef CONFIG_FS_WRITABLE
- dev->rd_writeenabled = writeenabled; /* true: can write to ram disk */
-#endif
- dev->rd_buffer = buffer; /* RAM disk backup memory */
-
- /* Create a ramdisk device name */
-
- snprintf(devname, 16, "/dev/ram%d", minor);
-
- /* Inode private data is a reference to the ramdisk device stgructure */
-
- ret = register_blockdriver(devname, &g_bops, 0, dev);
- if (ret < 0)
- {
- fdbg("register_blockdriver failed: %d\n", -ret);
- kfree(dev);
- }
- }
- return ret;
-}
diff --git a/nuttx/drivers/rwbuffer.c b/nuttx/drivers/rwbuffer.c
deleted file mode 100644
index 076ebc781..000000000
--- a/nuttx/drivers/rwbuffer.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/****************************************************************************
- * drivers/rwbuffer.c
- *
- * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <assert.h>
-#include <semaphore.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/wqueue.h>
-#include <nuttx/rwbuffer.h>
-
-#if defined(CONFIG_FS_WRITEBUFFER) || defined(CONFIG_FS_READAHEAD)
-
-/****************************************************************************
- * Preprocessor Definitions
- ****************************************************************************/
-
-/* Configuration ************************************************************/
-
-#ifndef CONFIG_SCHED_WORKQUEUE
-# error "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)"
-#endif
-
-#ifndef CONFIG_FS_WRDELAY
-# define CONFIG_FS_WRDELAY 350
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Variables
- ****************************************************************************/
-
-/****************************************************************************
- * Public Variables
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: rwb_semtake
- ****************************************************************************/
-
-static void rwb_semtake(sem_t *sem)
-{
- /* Take the semaphore (perhaps waiting) */
-
- while (sem_wait(sem) != 0)
- {
- /* The only case that an error should occr here is if
- * the wait was awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-}
-
-/****************************************************************************
- * Name: rwb_semgive
- ****************************************************************************/
-
-#define rwb_semgive(s) sem_post(s)
-
-/****************************************************************************
- * Name: rwb_overlap
- ****************************************************************************/
-
-static inline bool rwb_overlap(off_t blockstart1, size_t nblocks1,
- off_t blockstart2, size_t nblocks2)
-{
- off_t blockend1 = blockstart1 + nblocks1;
- off_t blockend2 = blockstart2 + nblocks2;
-
- /* If the buffer 1 is wholly outside of buffer 2, return false */
-
- if ((blockend1 < blockstart2) || /* Wholly "below" */
- (blockstart1 > blockend2)) /* Wholly "above" */
- {
- return false;
- }
- else
- {
- return true;
- }
-}
-
-/****************************************************************************
- * Name: rwb_resetwrbuffer
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITEBUFFER
-static inline void rwb_resetwrbuffer(struct rwbuffer_s *rwb)
-{
- /* We assume that the caller holds the wrsem */
-
- rwb->wrnblocks = 0;
- rwb->wrblockstart = (off_t)-1;
- rwb->wrexpectedblock = (off_t)-1;
-}
-#endif
-
-/****************************************************************************
- * Name: rwb_wrflush
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITEBUFFER
-static void rwb_wrflush(struct rwbuffer_s *rwb)
-{
- int ret;
-
- fvdbg("Timeout!\n");
-
- rwb_semtake(&rwb->wrsem);
- if (rwb->wrnblocks)
- {
- fvdbg("Flushing: blockstart=0x%08lx nblocks=%d from buffer=%p\n",
- (long)rwb->wrblockstart, rwb->wrnblocks, rwb->wrbuffer);
-
- /* Flush cache. On success, the flush method will return the number
- * of blocks written. Anything other than the number requested is
- * an error.
- */
-
- ret = rwb->wrflush(rwb->dev, rwb->wrbuffer, rwb->wrblockstart, rwb->wrnblocks);
- if (ret != rwb->wrnblocks)
- {
- fdbg("ERROR: Error flushing write buffer: %d\n", ret);
- }
-
- rwb_resetwrbuffer(rwb);
- }
-
- rwb_semgive(&rwb->wrsem);
-}
-#endif
-
-/****************************************************************************
- * Name: rwb_wrtimeout
- ****************************************************************************/
-
-static void rwb_wrtimeout(FAR void *arg)
-{
- /* The following assumes that the size of a pointer is 4-bytes or less */
-
- FAR struct rwbuffer_s *rwb = (struct rwbuffer_s *)arg;
- DEBUGASSERT(rwb != NULL);
-
- /* If a timeout elpases with with write buffer activity, this watchdog
- * handler function will be evoked on the thread of execution of the
- * worker thread.
- */
-
- rwb_wrflush(rwb);
-}
-
-/****************************************************************************
- * Name: rwb_wrstarttimeout
- ****************************************************************************/
-
-static void rwb_wrstarttimeout(FAR struct rwbuffer_s *rwb)
-{
- /* CONFIG_FS_WRDELAY provides the delay period in milliseconds. CLK_TCK
- * provides the clock tick of the system (frequency in Hz).
- */
-
- int ticks = (CONFIG_FS_WRDELAY + CLK_TCK/2) / CLK_TCK;
- (void)work_queue(LPWORK, &rwb->work, rwb_wrtimeout, (FAR void *)rwb, ticks);
-}
-
-/****************************************************************************
- * Name: rwb_wrcanceltimeout
- ****************************************************************************/
-
-static inline void rwb_wrcanceltimeout(struct rwbuffer_s *rwb)
-{
- (void)work_cancel(LPWORK, &rwb->work);
-}
-
-/****************************************************************************
- * Name: rwb_writebuffer
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITEBUFFER
-static ssize_t rwb_writebuffer(FAR struct rwbuffer_s *rwb,
- off_t startblock, uint32_t nblocks,
- FAR const uint8_t *wrbuffer)
-{
- int ret;
-
- /* Write writebuffer Logic */
-
- rwb_wrcanceltimeout(rwb);
-
- /* First: Should we flush out our cache? We would do that if (1) we already
- * buffering blocks and the next block writing is not in the same sequence,
- * or (2) the number of blocks would exceed our allocated buffer capacity
- */
-
- if (((startblock != rwb->wrexpectedblock) && (rwb->wrnblocks)) ||
- ((rwb->wrnblocks + nblocks) > rwb->wrmaxblocks))
- {
- fvdbg("writebuffer miss, expected: %08x, given: %08x\n",
- rwb->wrexpectedblock, startblock);
-
- /* Flush the write buffer */
-
- ret = rwb->wrflush(rwb, rwb->wrbuffer, rwb->wrblockstart, rwb->wrnblocks);
- if (ret < 0)
- {
- fdbg("ERROR: Error writing multiple from cache: %d\n", -ret);
- return ret;
- }
-
- rwb_resetwrbuffer(rwb);
- }
-
- /* writebuffer is empty? Then initialize it */
-
- if (!rwb->wrnblocks)
- {
- fvdbg("Fresh cache starting at block: 0x%08x\n", startblock);
- rwb->wrblockstart = startblock;
- }
-
- /* Add data to cache */
-
- fvdbg("writebuffer: copying %d bytes from %p to %p\n",
- nblocks * wrb->blocksize, wrbuffer,
- &rwb->wrbuffer[rwb->wrnblocks * rwb->blocksize]);
- memcpy(&rwb->wrbuffer[rwb->wrnblocks * rwb->blocksize],
- wrbuffer, nblocks * rwb->blocksize);
-
- rwb->wrnblocks += nblocks;
- rwb->wrexpectedblock = rwb->wrblockstart + rwb->wrnblocks;
- rwb_wrstarttimeout(rwb);
- return nblocks;
-}
-#endif
-
-/****************************************************************************
- * Name: rwb_resetrhbuffer
- ****************************************************************************/
-
-#ifdef CONFIG_FS_READAHEAD
-static inline void rwb_resetrhbuffer(struct rwbuffer_s *rwb)
-{
- /* We assume that the caller holds the readAheadBufferSemphore */
-
- rwb->rhnblocks = 0;
- rwb->rhblockstart = (off_t)-1;
-}
-#endif
-
-/****************************************************************************
- * Name: rwb_bufferread
- ****************************************************************************/
-
-#ifdef CONFIG_FS_READAHEAD
-static inline void
-rwb_bufferread(struct rwbuffer_s *rwb, off_t startblock,
- size_t nblocks, uint8_t **rdbuffer)
-{
- /* We assume that (1) the caller holds the readAheadBufferSemphore, and (2)
- * that the caller already knows that all of the blocks are in the
- * read-ahead buffer.
- */
-
- /* Convert the units from blocks to bytes */
-
- off_t blockoffset = startblock - rwb->rhblockstart;
- off_t byteoffset = rwb->blocksize * blockoffset;
- size_t nbytes = rwb->blocksize * nblocks;
-
- /* Get the byte address in the read-ahead buffer */
-
- uint8_t *rhbuffer = rwb->rhbuffer + byteoffset;
-
- /* Copy the data from the read-ahead buffer into the IO buffer */
-
- memcpy(*rdbuffer, rhbuffer, nbytes);
-
- /* Update the caller's copy for the next address */
-
- *rdbuffer += nbytes;
-}
-#endif
-
-/****************************************************************************
- * Name: rwb_rhreload
- ****************************************************************************/
-
-#ifdef CONFIG_FS_READAHEAD
-static int rwb_rhreload(struct rwbuffer_s *rwb, off_t startblock)
-{
- /* Get the block number +1 of the last block that will fit in the
- * read-ahead buffer
- */
-
- off_t endblock = startblock + rwb->rhmaxblocks;
- size_t nblocks;
- int ret;
-
- /* Reset the read buffer */
-
- rwb_resetrhbuffer(rwb);
-
- /* Make sure that we don't read past the end of the device */
-
- if (endblock > rwb->nblocks)
- {
- endblock = rwb->nblocks;
- }
-
- nblocks = endblock - startblock;
-
- /* Now perform the read */
-
- ret = rwb->rhreload(rwb->dev, rwb->rhbuffer, startblock, nblocks);
- if (ret == nblocks)
- {
- /* Update information about what is in the read-ahead buffer */
-
- rwb->rhnblocks = nblocks;
- rwb->rhblockstart = startblock;
-
- /* The return value is not the number of blocks we asked to be loaded. */
-
- return nblocks;
- }
-
- return -EIO;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-/****************************************************************************
- * Name: rwb_initialize
- ****************************************************************************/
-
-int rwb_initialize(FAR struct rwbuffer_s *rwb)
-{
- uint32_t allocsize;
-
- /* Sanity checking */
-
- DEBUGASSERT(rwb != NULL);
- DEBUGASSERT(rwb->blocksize > 0);
- DEBUGASSERT(rwb->nblocks > 0);
- DEBUGASSERT(rwb->dev != NULL);
-
- /* Setup so that rwb_uninitialize can handle a failure */
-
-#ifdef CONFIG_FS_WRITEBUFFER
- DEBUGASSERT(rwb->wrflush!= NULL);
- rwb->wrbuffer = NULL;
-#endif
-#ifdef CONFIG_FS_READAHEAD
- DEBUGASSERT(rwb->rhreload != NULL);
- rwb->rhbuffer = NULL;
-#endif
-
-#ifdef CONFIG_FS_WRITEBUFFER
- fvdbg("Initialize the write buffer\n");
-
- /* Initialize the write buffer access semaphore */
-
- sem_init(&rwb->wrsem, 0, 1);
-
- /* Initialize write buffer parameters */
-
- rwb_resetwrbuffer(rwb);
-
- /* Allocate the write buffer */
-
- rwb->wrbuffer = NULL;
- if (rwb->wrmaxblocks > 0)
- {
- allocsize = rwb->wrmaxblocks * rwb->blocksize;
- rwb->wrbuffer = kmalloc(allocsize);
- if (!rwb->wrbuffer)
- {
- fdbg("Write buffer kmalloc(%d) failed\n", allocsizee);
- return -ENOMEM;
- }
- }
-
- fvdbg("Write buffer size: %d bytes\n", allocsize);
-#endif /* CONFIG_FS_WRITEBUFFER */
-
-#ifdef CONFIG_FS_READAHEAD
- fvdbg("Initialize the read-ahead buffer\n");
-
- /* Initialize the read-ahead buffer access semaphore */
-
- sem_init(&rwb->rhsem, 0, 1);
-
- /* Initialize read-ahead buffer parameters */
-
- rwb_resetrhbuffer(rwb);
-
- /* Allocate the read-ahead buffer */
-
- rwb->rhbuffer = NULL;
- if (rwb->rhmaxblocks > 0)
- {
- allocsize = rwb->rhmaxblocks * rwb->blocksize;
- rwb->rhbuffer = kmalloc(allocsize);
- if (!rwb->rhbuffer)
- {
- fdbg("Read-ahead buffer kmalloc(%d) failed\n", allocsize);
- return -ENOMEM;
- }
- }
-
- fvdbg("Read-ahead buffer size: %d bytes\n", allocsize);
-#endif /* CONFIG_FS_READAHEAD */
- return 0;
-}
-
-/****************************************************************************
- * Name: rwb_uninitialize
- ****************************************************************************/
-
-void rwb_uninitialize(FAR struct rwbuffer_s *rwb)
-{
-#ifdef CONFIG_FS_WRITEBUFFER
- rwb_wrcanceltimeout(rwb);
- sem_destroy(&rwb->wrsem);
- if (rwb->wrbuffer)
- {
- kfree(rwb->wrbuffer);
- }
-#endif
-
-#ifdef CONFIG_FS_READAHEAD
- sem_destroy(&rwb->rhsem);
- if (rwb->rhbuffer)
- {
- kfree(rwb->rhbuffer);
- }
-#endif
-}
-
-/****************************************************************************
- * Name: rwb_read
- ****************************************************************************/
-
-int rwb_read(FAR struct rwbuffer_s *rwb, off_t startblock, uint32_t nblocks,
- FAR uint8_t *rdbuffer)
-{
- uint32_t remaining;
-
- fvdbg("startblock=%ld nblocks=%ld rdbuffer=%p\n",
- (long)startblock, (long)nblocks, rdbuffer);
-
-#ifdef CONFIG_FS_WRITEBUFFER
- /* If the new read data overlaps any part of the write buffer, then
- * flush the write data onto the physical media before reading. We
- * could attempt some more exotic handling -- but this simple logic
- * is well-suited for simple streaming applications.
- */
-
- if (rwb->wrmaxblocks > 0)
- {
- /* If the write buffer overlaps the block(s) requested, then flush the
- * write buffer.
- */
-
- rwb_semtake(&rwb->wrsem);
- if (rwb_overlap(rwb->wrblockstart, rwb->wrnblocks, startblock, nblocks))
- {
- rwb_wrflush(rwb);
- }
- rwb_semgive(&rwb->wrsem);
- }
-#endif
-
-#ifdef CONFIG_FS_READAHEAD
- /* Loop until we have read all of the requested blocks */
-
- rwb_semtake(&rwb->rhsem);
- for (remaining = nblocks; remaining > 0;)
- {
- /* Is there anything in the read-ahead buffer? */
-
- if (rwb->rhnblocks > 0)
- {
- off_t startblock = startblock;
- size_t nbufblocks = 0;
- off_t bufferend;
-
- /* Loop for each block we find in the read-head buffer. Count the
- * number of buffers that we can read from read-ahead buffer.
- */
-
- bufferend = rwb->rhblockstart + rwb->rhnblocks;
-
- while ((startblock >= rwb->rhblockstart) &&
- (startblock < bufferend) &&
- (remaining > 0))
- {
- /* This is one more that we will read from the read ahead buffer */
-
- nbufblocks++;
-
- /* And one less that we will read from the media */
-
- startblock++;
- remaining--;
- }
-
- /* Then read the data from the read-ahead buffer */
-
- rwb_bufferread(rwb, startblock, nbufblocks, &rdbuffer);
- }
-
- /* If we did not get all of the data from the buffer, then we have to refill
- * the buffer and try again.
- */
-
- if (remaining > 0)
- {
- int ret = rwb_rhreload(rwb, startblock);
- if (ret < 0)
- {
- fdbg("ERROR: Failed to fill the read-ahead buffer: %d\n", -ret);
- return ret;
- }
- }
- }
-
- /* On success, return the number of blocks that we were requested to read.
- * This is for compatibility with the normal return of a block driver read
- * method
- */
-
- rwb_semgive(&rwb->rhsem);
- return 0;
-#else
- return rwb->rhreload(rwb->dev, startblock, nblocks, rdbuffer);
-#endif
-}
-
-/****************************************************************************
- * Name: rwb_write
- ****************************************************************************/
-
-int rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock,
- size_t nblocks, FAR const uint8_t *wrbuffer)
-{
- int ret;
-
-#ifdef CONFIG_FS_READAHEAD
- /* If the new write data overlaps any part of the read buffer, then
- * flush the data from the read buffer. We could attempt some more
- * exotic handling -- but this simple logic is well-suited for simple
- * streaming applications.
- */
-
- rwb_semtake(&rwb->rhsem);
- if (rwb_overlap(rwb->rhblockstart, rwb->rhnblocks, startblock, nblocks))
- {
- rwb_resetrhbuffer(rwb);
- }
- rwb_give(&rwb->rhsem);
-#endif
-
-#ifdef CONFIG_FS_WRITEBUFFER
- fvdbg("startblock=%d wrbuffer=%p\n", startblock, wrbuffer);
-
- /* Use the block cache unless the buffer size is bigger than block cache */
-
- if (nblocks > rwb->wrmaxblocks)
- {
- /* First flush the cache */
-
- rwb_semtake(&rwb->wrsem);
- rwb_wrflush(rwb);
- rwb_semgive(&rwb->wrsem);
-
- /* Then transfer the data directly to the media */
-
- ret = rwb->wrflush(rwb->dev, startblock, nblocks, wrbuffer);
- }
- else
- {
- /* Buffer the data in the write buffer */
-
- ret = rwb_writebuffer(rwb, startblock, nblocks, wrbuffer);
- }
-
- /* On success, return the number of blocks that we were requested to write.
- * This is for compatibility with the normal return of a block driver write
- * method
- */
-
- return ret;
-
-#else
-
- return rwb->wrflush(rwb->dev, startblock, nblocks, wrbuffer);
-
-#endif
-}
-
-/****************************************************************************
- * Name: rwb_mediaremoved
- *
- * Description:
- * The following function is called when media is removed
- *
- ****************************************************************************/
-
-int rwb_mediaremoved(FAR struct rwbuffer_s *rwb)
-{
-#ifdef CONFIG_FS_WRITEBUFFER
- rwb_semtake(&rwb->wrsem);
- rwb_resetwrbuffer(rwb);
- rwb_semgive(&rwb->wrsem);
-#endif
-
-#ifdef CONFIG_FS_READAHEAD
- rwb_semtake(&rwb->rhsem);
- rwb_resetrhbuffer(rwb);
- rwb_semgive(&rwb->rhsem);
-#endif
- return 0;
-}
-
-#endif /* CONFIG_FS_WRITEBUFFER || CONFIG_FS_READAHEAD */
-
diff --git a/nuttx/drivers/sensors/Kconfig b/nuttx/drivers/sensors/Kconfig
deleted file mode 100644
index 386cdc3a8..000000000
--- a/nuttx/drivers/sensors/Kconfig
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-config LIS331DL
- bool "ST LIS331DL device support"
- default n
- select I2C
-
-config I2C_LM75
- bool
- default y if LM75
-
-config LM75
- bool "STMicro LM-75 Temperature Sensor support"
- default n
- select I2C
- select I2C_LM75
-
-config DEBUG_LM75
- bool "Enable LM-75 debug"
- default n
- depends on LM75
-
-config QENCODER
- bool "Qencoder"
- default n
-
-config DEBUG_QENCODER
- bool "Enable Qencoder Debug"
- default n
- depends on QENCODER
-
diff --git a/nuttx/drivers/sensors/Make.defs b/nuttx/drivers/sensors/Make.defs
deleted file mode 100644
index 1713edb99..000000000
--- a/nuttx/drivers/sensors/Make.defs
+++ /dev/null
@@ -1,60 +0,0 @@
-############################################################################
-# drivers/sensors/Make.defs
-#
-# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-# Include sensor drivers
-# These drivers depend on I2C support
-
-ifeq ($(CONFIG_I2C),y)
-
-ifeq ($(CONFIG_I2C_TRANSFER),y)
- CSRCS += lis331dl.c
-endif
-
-ifeq ($(CONFIG_I2C_LM75),y)
- CSRCS += lm75.c
-endif
-endif
-
-# Quadrature encoder upper half
-
-ifeq ($(CONFIG_QENCODER),y)
- CSRCS += qencoder.c
-endif
-
-# Include sensor driver build support
-
-DEPPATH += --dep-path sensors
-VPATH += :sensors
-CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)sensors}
diff --git a/nuttx/drivers/sensors/lis331dl.c b/nuttx/drivers/sensors/lis331dl.c
deleted file mode 100644
index 2117a7ebd..000000000
--- a/nuttx/drivers/sensors/lis331dl.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/****************************************************************************
- * drivers/sensors/lis331dl.c
- *
- * Copyright (C) 2011 Uros Platise. All rights reserved.
- *
- * Authors: Uros Platise <uros.platise@isotel.eu>
- *
- * 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.
- *
- ****************************************************************************/
-
-/** \file
- * \author Uros Platise
- * \brief ST LIS331DL I2C Device Driver
- **/
-
-#include <nuttx/config.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/sensors/lis331dl.h>
-
-/************************************************************************************
- * LIS331DL Internal Registers
- ************************************************************************************/
-
-#define ST_LIS331DL_WHOAMI 0x0F /* who am I register */
-#define ST_LIS331DL_WHOAMI_VALUE 0x3B /* Valid result is 0x3B */
-
-#define ST_LIS331DL_CTRL_REG1 0x20
-#define ST_LIS331DL_CR1_DR 0x80 /* Data-rate selection 0: 100 Hz, 1: 400 Hz */
-#define ST_LIS331DL_CR1_PD 0x40 /* Active Mode (1) / Power-down (0) */
-#define ST_LIS331DL_CR1_FS 0x20 /* Full Scale (1) +-9g or Normal Scale (0) +-2g */
-#define ST_LIS331DL_CR1_ST 0x18 /* Self test enable */
-#define ST_LIS331DL_CR1_ZEN 0x04 /* Z-Axis Enable */
-#define ST_LIS331DL_CR1_YEN 0x02 /* Y-Axis Enable */
-#define ST_LIS331DL_CR1_XEN 0x01 /* X-Axis Enable */
-
-#define ST_LIS331DL_CTRL_REG2 0x21
-#define ST_LIS331DL_CTRL_REG3 0x22
-
-#define ST_LIS331DL_HP_FILTER_RESET 0x23
-
-#define ST_LIS331DL_STATUS_REG 0x27 /* Status Register */
-#define ST_LIS331DL_SR_ZYXOR 0x80 /* OR'ed X,Y and Z data over-run */
-#define ST_LIS331DL_SR_ZOR 0x40 /* individual data over-run ... */
-#define ST_LIS331DL_SR_YOR 0x20
-#define ST_LIS331DL_SR_XOR 0x10
-#define ST_LIS331DL_SR_ZYXDA 0x08 /* OR'ed X,Y and Z data available */
-#define ST_LIS331DL_SR_ZDA 0x04 /* individual data available ... */
-#define ST_LIS331DL_SR_YDA 0x02
-#define ST_LIS331DL_SR_XDA 0x01
-
-#define ST_LIS331DL_OUT_X 0x29
-#define ST_LIS331DL_OUT_Y 0x2B
-#define ST_LIS331DL_OUT_Z 0x2D
-
-
-/************************************************************************************
- * Private Data Types
- ************************************************************************************/
-
-struct lis331dl_dev_s {
- struct i2c_dev_s * i2c;
-
- uint8_t address;
- struct lis331dl_vector_s a;
- uint8_t cr1;
- uint8_t cr2;
- uint8_t cr3;
-};
-
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/** LIS331DL Access with range check
- *
- * \param dev LIS331 DL Private Structure
- * \param subaddr LIS331 Sub Address
- * \param buf Pointer to buffer, either for read or write access
- * \param length when >0 it denotes read access, when <0 it denotes write access of -length
- * \return OK on success or errno is set.
- **/
-int lis331dl_access(struct lis331dl_dev_s * dev, uint8_t subaddr, uint8_t *buf, int length)
-{
- uint16_t flags = 0;
- int retval;
-
- if (length > 0) {
- flags = I2C_M_READ;
- }
- else {
- flags = I2C_M_NORESTART;
- length = -length;
- }
-
- /* Check valid address ranges and set auto address increment flag */
-
- if (subaddr == 0x0F) {
- if (length > 1) length = 1;
- }
- else if (subaddr >= 0x20 && subaddr < 0x24) {
- if (length > (0x24 - subaddr) ) length = 0x24 - subaddr;
- }
- else if (subaddr >= 0x27 && subaddr < 0x2E) {
- if (length > (0x2E - subaddr) ) length = 0x2E - subaddr;
- }
- else if (subaddr >= 0x30 && subaddr < 0x40) {
- if (length > (0x40 - subaddr) ) length = 0x40 - subaddr;
- }
- else {
- errno = EFAULT;
- return ERROR;
- }
-
- if (length > 1) subaddr |= 0x80;
-
- /* Create message and send */
-
- struct i2c_msg_s msgv[2] = {
- {
- .addr = dev->address,
- .flags = 0,
- .buffer = &subaddr,
- .length = 1
- },
- {
- .addr = dev->address,
- .flags = flags,
- .buffer = buf,
- .length = length
- }
- };
-
- if ( (retval = I2C_TRANSFER(dev->i2c, msgv, 2)) == OK )
- return length;
-
- return retval;
-}
-
-
-int lis331dl_readregs(struct lis331dl_dev_s * dev)
-{
- if (lis331dl_access(dev, ST_LIS331DL_CTRL_REG1, &dev->cr1, 3) != 3) return ERROR;
- return OK;
-}
-
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-struct lis331dl_dev_s * lis331dl_init(struct i2c_dev_s * i2c, uint16_t address)
-{
- struct lis331dl_dev_s * dev;
- uint8_t retval;
-
- ASSERT(i2c);
- ASSERT(address);
-
- if ( (dev = kmalloc( sizeof(struct lis331dl_dev_s) )) == NULL ) {
- errno = ENOMEM;
- return NULL;
- }
-
- memset(dev, 0, sizeof(struct lis331dl_dev_s));
- dev->i2c = i2c;
- dev->address = address;
-
- /* Probe device */
-
- if (lis331dl_access(dev, ST_LIS331DL_WHOAMI, &retval, 1) > 0) {
-
- /* Check chip identification, in the future several more compatible parts
- * may be added here.
- */
-
- if (retval == ST_LIS331DL_WHOAMI_VALUE) {
-
- /* Copy LIS331DL registers to our private structure and power-up device */
-
- if (lis331dl_readregs(dev)==OK && lis331dl_powerup(dev)==OK) {
-
- /* Normal exit point */
- errno = 0;
- return dev;
- }
- retval = errno;
- }
-
- /* Otherwise, we mark an invalid device found at given address */
- retval = ENODEV;
- }
- else {
- /* No response at given address is marked as */
- retval = EFAULT;
- }
-
- /* Error exit */
- kfree(dev);
- errno = retval;
- return NULL;
-}
-
-
-int lis331dl_deinit(struct lis331dl_dev_s * dev)
-{
- ASSERT(dev);
-
- lis331dl_powerdown(dev);
- kfree(dev);
-
- return OK;
-}
-
-
-int lis331dl_powerup(struct lis331dl_dev_s * dev)
-{
- dev->cr1 = ST_LIS331DL_CR1_PD |
- ST_LIS331DL_CR1_ZEN | ST_LIS331DL_CR1_YEN | ST_LIS331DL_CR1_XEN;
- dev->cr2 = 0;
- dev->cr3 = 0;
-
- if (lis331dl_access(dev, ST_LIS331DL_CTRL_REG1, &dev->cr1, -3) == 3) return OK;
- return ERROR;
-}
-
-
-int lis331dl_powerdown(struct lis331dl_dev_s * dev)
-{
- dev->cr1 = ST_LIS331DL_CR1_ZEN | ST_LIS331DL_CR1_YEN | ST_LIS331DL_CR1_XEN;
- dev->cr2 = 0;
- dev->cr3 = 0;
-
- if (lis331dl_access(dev, ST_LIS331DL_CTRL_REG1, &dev->cr1, -3) == 3) return OK;
- return ERROR;
-}
-
-
-int lis331dl_setconversion(struct lis331dl_dev_s * dev, bool full, bool fast)
-{
- dev->cr1 = ST_LIS331DL_CR1_PD |
- (full ? ST_LIS331DL_CR1_FS : 0) | (fast ? ST_LIS331DL_CR1_DR : 0) |
- ST_LIS331DL_CR1_ZEN | ST_LIS331DL_CR1_YEN | ST_LIS331DL_CR1_XEN;
-
- if (lis331dl_access(dev, ST_LIS331DL_CTRL_REG1, &dev->cr1, -1) == 1) return OK;
- return ERROR;
-}
-
-
-int lis331dl_getprecision(struct lis331dl_dev_s * dev)
-{
- if (dev->cr1 & ST_LIS331DL_CR1_FS)
- return 9200/127; /* typ. 9.2g full scale */
- return 2300/127; /* typ. 2.3g full scale */
-}
-
-
-int lis331dl_getsamplerate(struct lis331dl_dev_s * dev)
-{
- if (dev->cr1 & ST_LIS331DL_CR1_DR)
- return 400;
- return 100;
-}
-
-
-const struct lis331dl_vector_s * lis331dl_getreadings(struct lis331dl_dev_s * dev)
-{
- uint8_t retval[7];
-
- ASSERT(dev);
-
- if (lis331dl_access(dev, ST_LIS331DL_STATUS_REG, retval, 7) == 7) {
-
- /* If result is not yet ready, return NULL */
-
- if ( !(retval[0] & ST_LIS331DL_SR_ZYXDA) ) {
- errno = EAGAIN;
- return NULL;
- }
-
- dev->a.x = retval[2];
- dev->a.y = retval[4];
- dev->a.z = retval[6];
- return &dev->a;
- }
-
- return NULL;
-}
diff --git a/nuttx/drivers/sensors/lm75.c b/nuttx/drivers/sensors/lm75.c
deleted file mode 100644
index 2d3346447..000000000
--- a/nuttx/drivers/sensors/lm75.c
+++ /dev/null
@@ -1,537 +0,0 @@
-/****************************************************************************
- * drivers/sensors/lm75.c
- * Character driver for the STMicro LM-75 Temperature Sensor
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <stdlib.h>
-#include <fixedmath.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/i2c.h>
-#include <nuttx/sensors/lm75.h>
-
-#if defined(CONFIG_I2C) && defined(CONFIG_I2C_LM75)
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Centigrade to Fahrenheit conversion: F = 9*C/5 + 32 */
-
-#define B16_9DIV5 (9 * 65536 / 5)
-#define B16_32 (32 * 65536)
-
-/* Debug for this file only */
-
-#ifdef CONFIG_DEBUG_LM75
-# define lm75dbg dbg
-#else
-# ifdef CONFIG_CPP_HAVE_VARARGS
-# define lm75dbg(x...)
-# else
-# define lm75dbg (void)
-# endif
-#endif
-
-/****************************************************************************
- * Private
- ****************************************************************************/
-
-struct lm75_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 lm75_readb16(FAR struct lm75_dev_s *priv, uint8_t regaddr,
- FAR b16_t *regvalue);
-static int lm75_writeb16(FAR struct lm75_dev_s *priv, uint8_t regaddr,
- b16_t regval);
-static int lm75_readtemp(FAR struct lm75_dev_s *priv, FAR b16_t *temp);
-static int lm75_readconf(FAR struct lm75_dev_s *priv, FAR uint8_t *conf);
-static int lm75_writeconf(FAR struct lm75_dev_s *priv, uint8_t conf);
-
-/* Character driver methods */
-
-static int lm75_open(FAR struct file *filep);
-static int lm75_close(FAR struct file *filep);
-static ssize_t lm75_read(FAR struct file *, FAR char *, size_t);
-static ssize_t lm75_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
-static int lm75_ioctl(FAR struct file *filep,int cmd,unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations g_lm75fops =
-{
- lm75_open,
- lm75_close,
- lm75_read,
- lm75_write,
- 0,
- lm75_ioctl
-#ifndef CONFIG_DISABLE_POLL
- , 0
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-/****************************************************************************
- * Name: lm75_readb16
- *
- * Description:
- * Read a 16-bit register (LM75_TEMP_REG, LM75_THYS_REG, or LM75_TOS_REG)
- *
- ****************************************************************************/
-
-static int lm75_readb16(FAR struct lm75_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, &regaddr, 1);
- if (ret < 0)
- {
- lm75dbg("I2C_WRITE failed: %d\n", ret);
- return ret;
- }
-
- /* Restart and read 16-bits from the register (discarding 7) */
-
- ret = I2C_READ(priv->i2c, buffer, 2);
- if (ret < 0)
- {
- lm75dbg("I2C_READ failed: %d\n", ret);
- return ret;
- }
-
- /* Data format is: TTTTTTTT Txxxxxxx where TTTTTTTTT is a nine-bit,
- * signed temperature value with LSB = 0.5 degrees centigrade. So the
- * raw data is b8_t
- */
-
- *regvalue = b8tob16((b8_t)buffer[0] << 8 | (b8_t)buffer[1]);
- lm75dbg("addr: %02x value: %08x ret: %d\n", regaddr, *regvalue, ret);
- return OK;
-}
-
-/****************************************************************************
- * Name: lm75_writeb16
- *
- * Description:
- * Write to a 16-bit register (LM75_TEMP_REG, LM75_THYS_REG, or LM75_TOS_REG)
- *
- ****************************************************************************/
-
-static int lm75_writeb16(FAR struct lm75_dev_s *priv, uint8_t regaddr,
- b16_t regval)
-{
- uint8_t buffer[3];
- b8_t regb8;
-
- lm75dbg("addr: %02x value: %08x\n", regaddr, regval);
-
- /* Set up a 3 byte message to send */
-
- buffer[0] = regaddr;
-
- regb8 = b16tob8(regval);
- buffer[1] = (uint8_t)(regb8 >> 8);
- buffer[2] = (uint8_t)regb8;
-
- /* 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: lm75_readtemp
- *
- * Description:
- * Read the temperature register with special scaling (LM75_TEMP_REG)
- *
- ****************************************************************************/
-
-static int lm75_readtemp(FAR struct lm75_dev_s *priv, FAR b16_t *temp)
-{
- b16_t temp16;
- int ret;
-
- /* Read the raw temperature data (b16_t) */
-
- ret = lm75_readb16(priv, LM75_TEMP_REG, &temp16);
- if (ret < 0)
- {
- lm75dbg("lm75_readb16 failed: %d\n", ret);
- return ret;
- }
- lm75dbg("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;
- lm75dbg("Fahrenheit: %08x\n", temp16);
- }
-
- *temp = temp16;
- return OK;
-}
-
-/****************************************************************************
- * Name: lm75_readconf
- *
- * Description:
- * Read the 8-bit LM75 configuration register
- *
- ****************************************************************************/
-
-static int lm75_readconf(FAR struct lm75_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 = LM75_CONF_REG;
- ret = I2C_WRITE(priv->i2c, &buffer, 1);
- if (ret < 0)
- {
- lm75dbg("I2C_WRITE failed: %d\n", ret);
- return ret;
- }
-
- /* Restart and read 8-bits from the register */
-
- ret = I2C_READ(priv->i2c, conf, 1);
- lm75dbg("conf: %02x ret: %d\n", *conf, ret);
- return ret;
-}
-
-/****************************************************************************
- * Name: lm75_writeconf
- *
- * Description:
- * Write to a 8-bit LM75 configuration register.
- *
- ****************************************************************************/
-
-static int lm75_writeconf(FAR struct lm75_dev_s *priv, uint8_t conf)
-{
- uint8_t buffer[2];
-
- lm75dbg("conf: %02x\n", conf);
-
- /* Set up a 2 byte message to send */
-
- buffer[0] = LM75_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: lm75_open
- *
- * Description:
- * This function is called whenever the LM-75 device is opened.
- *
- ****************************************************************************/
-
-static int lm75_open(FAR struct file *filep)
-{
- return OK;
-}
-
-/****************************************************************************
- * Name: lm75_close
- *
- * Description:
- * This routine is called when the LM-75 device is closed.
- *
- ****************************************************************************/
-
-static int lm75_close(FAR struct file *filep)
-{
- return OK;
-}
-
-/****************************************************************************
- * Name: lm75_read
- ****************************************************************************/
-
-static ssize_t lm75_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct lm75_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;
-
- lm75dbg("buflen: %d nsamples: %d\n", buflen, nsamples);
-
- /* Get the requested number of samples */
-
- for (i = 0; i < nsamples; i++)
- {
- b16_t temp;
-
- /* Read the next b16_t temperature value */
-
- ret = lm75_readtemp(priv, &temp);
- if (ret < 0)
- {
- lm75dbg("lm75_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: lm75_write
- ****************************************************************************/
-
-static ssize_t lm75_write(FAR struct file *filep, FAR const char *buffer,
- size_t buflen)
-{
- return -ENOSYS;
-}
-
-/****************************************************************************
- * Name: lm75_ioctl
- ****************************************************************************/
-
-static int lm75_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct lm75_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 = lm75_readconf(priv, ptr);
- lm75dbg("conf: %02x ret: %d\n", *ptr, ret);
- }
- break;
-
- /* Wrtie to the configuration register. Arg: uint8_t value */
-
- case SNIOC_WRITECONF:
- ret = lm75_writeconf(priv, (uint8_t)arg);
- lm75dbg("conf: %02x ret: %d\n", *(uint8_t*)arg, ret);
- break;
-
- /* Shutdown the LM75, Arg: None */
-
- case SNIOC_SHUTDOWN:
- {
- uint8_t conf;
- ret = lm75_readconf(priv, &conf);
- if (ret == OK)
- {
- ret = lm75_writeconf(priv, conf | LM75_CONF_SHUTDOWN);
- }
- lm75dbg("conf: %02x ret: %d\n", conf | LM75_CONF_SHUTDOWN, ret);
- }
- break;
-
- /* Powerup the LM75, Arg: None */
-
- case SNIOC_POWERUP:
- {
- uint8_t conf;
- ret = lm75_readconf(priv, &conf);
- if (ret == OK)
- {
- ret = lm75_writeconf(priv, conf & ~LM75_CONF_SHUTDOWN);
- }
- lm75dbg("conf: %02x ret: %d\n", conf & ~LM75_CONF_SHUTDOWN, ret);
- }
- break;
-
- /* Report samples in Fahrenheit */
-
- case SNIOC_FAHRENHEIT:
- priv->fahrenheit = true;
- lm75dbg("Fahrenheit\n");
- break;
-
- /* Report Samples in Centigrade */
-
- case SNIOC_CENTIGRADE:
- priv->fahrenheit = false;
- lm75dbg("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 = lm75_readb16(priv, LM75_THYS_REG, ptr);
- lm75dbg("THYS: %08x ret: %d\n", *ptr, ret);
- }
- break;
-
- /* Write THYS temperature register. Arg: b16_t value */
-
- case SNIOC_WRITETHYS:
- ret = lm75_writeb16(priv, LM75_THYS_REG, (b16_t)arg);
- lm75dbg("THYS: %08x ret: %d\n", (b16_t)arg, ret);
- break;
-
- /* Read TOS (Over-temp Shutdown Threshold) Register. Arg: b16_t* pointer */
-
- case SNIOC_READTOS:
- {
- FAR b16_t *ptr = (FAR b16_t *)((uintptr_t)arg);
- ret = lm75_readb16(priv, LM75_TOS_REG, ptr);
- lm75dbg("TOS: %08x ret: %d\n", *ptr, ret);
- }
- break;
-
- /* Write TOS (Over-temp Shutdown Threshold) Register. Arg: b16_t value */
-
- case SNIOC_WRITRETOS:
- ret = lm75_writeb16(priv, LM75_TOS_REG, (b16_t)arg);
- lm75dbg("TOS: %08x ret: %d\n", (b16_t)arg, ret);
- break;
-
- default:
- lm75dbg("Unrecognized cmd: %d\n", cmd);
- ret = -ENOTTY;
- break;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: lm75_register
- *
- * Description:
- * Register the LM-75 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 LM75
- * addr - The I2C address of the LM-75. The base I2C address of the LM75
- * is 0x48. Bits 0-3 can be controlled to get 8 unique addresses from 0x48
- * through 0x4f.
- *
- * Returned Value:
- * Zero (OK) on success; a negated errno value on failure.
- *
- ****************************************************************************/
-
-int lm75_register(FAR const char *devpath, FAR struct i2c_dev_s *i2c, uint8_t addr)
-{
- FAR struct lm75_dev_s *priv;
- int ret;
-
- /* Initialize the LM-75 device structure */
-
- priv = (FAR struct lm75_dev_s *)malloc(sizeof(struct lm75_dev_s));
- if (!priv)
- {
- lm75dbg("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_lm75fops, 0666, priv);
- if (ret < 0)
- {
- lm75dbg("Failed to register driver: %d\n", ret);
- free(priv);
- }
- return ret;
-}
-#endif /* CONFIG_I2C && CONFIG_I2C_LM75 */
diff --git a/nuttx/drivers/sensors/qencoder.c b/nuttx/drivers/sensors/qencoder.c
deleted file mode 100644
index a56adec9a..000000000
--- a/nuttx/drivers/sensors/qencoder.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/****************************************************************************
- * drivers/sensors/qencoder.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Compilation Switches
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <semaphore.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/arch.h>
-#include <nuttx/sensors/qencoder.h>
-
-#include <arch/irq.h>
-
-#ifdef CONFIG_QENCODER
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Debug ********************************************************************/
-/* Non-standard debug that may be enabled just for testing PWM */
-
-#ifdef CONFIG_DEBUG_QENCODER
-# define qedbg dbg
-# define qevdbg vdbg
-# define qelldbg lldbg
-# define qellvdbg llvdbg
-#else
-# define qedbg(x...)
-# define qevdbg(x...)
-# define qelldbg(x...)
-# define qellvdbg(x...)
-#endif
-
-/****************************************************************************
- * Private Type Definitions
- ****************************************************************************/
-
-/* This structure describes the state of the upper half drivere */
-
-struct qe_upperhalf_s
-{
- uint8_t crefs; /* The number of times the device has been opened */
- sem_t exclsem; /* Supports mutual exclusion */
- FAR struct qe_lowerhalf_s *lower; /* lower-half state */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int qe_open(FAR struct file *filep);
-static int qe_close(FAR struct file *filep);
-static ssize_t qe_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
-static ssize_t qe_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
-static int qe_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations g_qeops =
-{
- qe_open, /* open */
- qe_close, /* close */
- qe_read, /* read */
- qe_write, /* write */
- 0, /* seek */
- qe_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , 0 /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/************************************************************************************
- * Name: qe_open
- *
- * Description:
- * This function is called whenever the PWM device is opened.
- *
- ************************************************************************************/
-
-static int qe_open(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct qe_upperhalf_s *upper = inode->i_private;
- uint8_t tmp;
- int ret;
-
- qevdbg("crefs: %d\n", upper->crefs);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0)
- {
- ret = -errno;
- goto errout;
- }
-
- /* Increment the count of references to the device. If this the first
- * time that the driver has been opened for this device, then initialize
- * the device.
- */
-
- tmp = upper->crefs + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- goto errout_with_sem;
- }
-
- /* Check if this is the first time that the driver has been opened. */
-
- if (tmp == 1)
- {
- FAR struct qe_lowerhalf_s *lower = upper->lower;
-
- /* Yes.. perform one time hardware initialization. */
-
- DEBUGASSERT(lower->ops->setup != NULL);
- qevdbg("calling setup\n");
-
- ret = lower->ops->setup(lower);
- if (ret < 0)
- {
- goto errout_with_sem;
- }
- }
-
- /* Save the new open count on success */
-
- upper->crefs = tmp;
- ret = OK;
-
-errout_with_sem:
- sem_post(&upper->exclsem);
-
-errout:
- return ret;
-}
-
-/************************************************************************************
- * Name: qe_close
- *
- * Description:
- * This function is called when the PWM device is closed.
- *
- ************************************************************************************/
-
-static int qe_close(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct qe_upperhalf_s *upper = inode->i_private;
- int ret;
-
- qevdbg("crefs: %d\n", upper->crefs);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0)
- {
- ret = -errno;
- goto errout;
- }
-
- /* Decrement the references to the driver. If the reference count will
- * decrement to 0, then uninitialize the driver.
- */
-
- if (upper->crefs > 1)
- {
- upper->crefs--;
- }
- else
- {
- FAR struct qe_lowerhalf_s *lower = upper->lower;
-
- /* There are no more references to the port */
-
- upper->crefs = 0;
-
- /* Disable the PWM device */
-
- DEBUGASSERT(lower->ops->shutdown != NULL);
- qevdbg("calling shutdown: %d\n");
-
- lower->ops->shutdown(lower);
- }
- ret = OK;
-
-//errout_with_sem:
- sem_post(&upper->exclsem);
-
-errout:
- return ret;
-}
-
-/************************************************************************************
- * Name: qe_read
- *
- * Description:
- * A dummy read method. This is provided only to satsify the VFS layer.
- *
- ************************************************************************************/
-
-static ssize_t qe_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- /* Return zero -- usually meaning end-of-file */
-
- return 0;
-}
-
-/************************************************************************************
- * Name: qe_write
- *
- * Description:
- * A dummy write method. This is provided only to satsify the VFS layer.
- *
- ************************************************************************************/
-
-static ssize_t qe_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
-{
- /* Return a failure */
-
- return -EPERM;
-}
-
-/************************************************************************************
- * Name: qe_ioctl
- *
- * Description:
- * The standard ioctl method. This is where ALL of the PWM work is done.
- *
- ************************************************************************************/
-
-static int qe_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct qe_upperhalf_s *upper = inode->i_private;
- FAR struct qe_lowerhalf_s *lower = upper->lower;
- int ret;
-
- qevdbg("cmd: %d arg: %ld\n", cmd, arg);
- DEBUGASSERT(upper && lower);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0)
- {
- return ret;
- }
-
- /* Handle built-in ioctl commands */
-
- switch (cmd)
- {
- /* QEIOC_POSITION - Get the current position from the encoder.
- * Argument: int32_t pointer to the location to return the position.
- */
-
- case QEIOC_POSITION:
- {
- FAR int32_t *ptr = (FAR int32_t *)((uintptr_t)arg);
- DEBUGASSERT(lower->ops->position != NULL && ptr);
- ret = lower->ops->position(lower, ptr);
- }
- break;
-
- /* QEIOC_RESET - Reset the position to zero.
- * Argument: None
- */
-
- case QEIOC_RESET:
- {
- DEBUGASSERT(lower->ops->reset != NULL);
- ret = lower->ops->reset(lower);
- }
- break;
-
- /* Any unrecognized IOCTL commands might be platform-specific ioctl commands */
-
- default:
- {
- qevdbg("Forwarding unrecognized cmd: %d arg: %ld\n", cmd, arg);
- DEBUGASSERT(lower->ops->ioctl != NULL);
- ret = lower->ops->ioctl(lower, cmd, arg);
- }
- break;
- }
-
- sem_post(&upper->exclsem);
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: qe_register
- *
- * Description:
- * Register the Quadrature Encoder lower half device as 'devpath'
- *
- * Input Parameters:
- * devpath - The full path to the driver to register. E.g., "/dev/qe0"
- * lower - An instance of the lower half interface
- *
- * Returned Value:
- * Zero (OK) on success; a negated errno value on failure. The following
- * possible error values may be returned (most are returned by
- * register_driver()):
- *
- * EINVAL - 'path' is invalid for this operation
- * EEXIST - An inode already exists at 'path'
- * ENOMEM - Failed to allocate in-memory resources for the operation
- *
- ****************************************************************************/
-
-int qe_register(FAR const char *devpath, FAR struct qe_lowerhalf_s *lower)
-{
- FAR struct qe_upperhalf_s *upper;
-
- /* Allocate the upper-half data structure */
-
- upper = (FAR struct qe_upperhalf_s *)zalloc(sizeof(struct qe_upperhalf_s));
- if (!upper)
- {
- qedbg("Allocation failed\n");
- return -ENOMEM;
- }
-
- /* Initialize the PWM device structure (it was already zeroed by zalloc()) */
-
- sem_init(&upper->exclsem, 0, 1);
- upper->lower = lower;
-
- /* Register the PWM device */
-
- qevdbg("Registering %s\n", devpath);
- return register_driver(devpath, &g_qeops, 0666, upper);
-}
-
-#endif /* CONFIG_QENCODER */
diff --git a/nuttx/drivers/sercomm/Kconfig b/nuttx/drivers/sercomm/Kconfig
deleted file mode 100644
index ae2bf3130..000000000
--- a/nuttx/drivers/sercomm/Kconfig
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
diff --git a/nuttx/drivers/sercomm/Make.defs b/nuttx/drivers/sercomm/Make.defs
deleted file mode 100644
index 0cf93d4c8..000000000
--- a/nuttx/drivers/sercomm/Make.defs
+++ /dev/null
@@ -1,55 +0,0 @@
-############################################################################
-# drivers/serial/Make.defs
-#
-# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-# File descriptor support is needed for this driver
-
-ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
-
-# The sercomm driver should not be build for all platforms. Only build it
-# is so configured
-
-ifeq ($(CONFIG_SERCOMM_CONSOLE),y)
-
-# Include serial drivers
-
-CSRCS += console.c uart.c
-
-# Include sercomm build support
-
-DEPPATH += --dep-path sercomm
-VPATH += :sercomm
-
-endif
-endif
diff --git a/nuttx/drivers/sercomm/README.txt b/nuttx/drivers/sercomm/README.txt
deleted file mode 100644
index a9239a204..000000000
--- a/nuttx/drivers/sercomm/README.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-drivers/sercomm README
-======================
-
-If CONFIG_SERCOMM_CONSOLE is defined in the NuttX configuration file, NuttX
-will attempt to use sercomm (HDLC protocol) to communicate with the
-host system. Sercomm is the transport used by osmocom-bb that runs on top
-of serial. See http://bb.osmocom.org/trac/wiki/nuttx-bb/run for detailed
-the usage of nuttx with sercomm.
-
-The drivers/sercomm build that you have the osmocom-bb project directory
-at same level as the nuttx project:
-
- |- nuttx
- |- apps
- `- osmocom-bb
-
-If you attempt to build this driver without osmocom-bb, you will get
-compilation errors because ofheader files that are needed from the
-osmocom-bb directory.
diff --git a/nuttx/drivers/sercomm/console.c b/nuttx/drivers/sercomm/console.c
deleted file mode 100644
index 3d038af7c..000000000
--- a/nuttx/drivers/sercomm/console.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/****************************************************************************
- * drivers/sercomm/console.c
- * Driver for NuttX Console
- *
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2011 Stefan Richter <ichgeh@l--putt.de>
- *
- * This source code is derivated from Osmocom-BB project and was
- * relicensed as BSD with permission from original authors.
- *
- * 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.
- *
- **************************************************************************/
-
-#include <nuttx/config.h>
-#include <nuttx/arch.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/serial/serial.h>
-
-#include <errno.h>
-#include <debug.h>
-#include <string.h>
-
-#include "uart.h"
-#include <nuttx/sercomm/sercomm.h>
-
-/* stubs to make serial driver happy */
-void sercomm_recvchars(void *a) { }
-void sercomm_xmitchars(void *a) { }
-
-/* Stubs to make memory allocator happy */
-void cons_puts(void *foo){}
-void delay_ms(int ms){}
-
-/************************************************************************************
- * Fileops Prototypes and Structures
- ************************************************************************************/
-
-typedef FAR struct file file_t;
-
-static ssize_t sc_console_read(file_t *filep, FAR char *buffer, size_t buflen);
-static ssize_t sc_console_write(file_t *filep, FAR const char *buffer, size_t buflen);
-static int sc_console_ioctl(file_t *filep, int cmd, unsigned long arg);
-#ifndef CONFIG_DISABLE_POLL
-static int sc_console_poll(file_t *filep, FAR struct pollfd *fds, bool setup);
-#endif
-
-static const struct file_operations g_sercom_console_ops =
-{
- 0, /* open, always opened */
- 0, /* close, stays open */
- sc_console_read, /* read */
- sc_console_write, /* write */
- 0, /* seek, not supported */
- sc_console_ioctl, /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- sc_console_poll /* poll */
-#endif
-};
-
-/****************************************************************************
- * Helper functions
- ****************************************************************************/
-static FAR uart_dev_t *readdev = NULL;
-static struct msgb *recvmsg = NULL;
-static void recv_cb(uint8_t dlci, struct msgb *msg)
-{
- sem_post(&readdev->recvsem);
- recvmsg = msg;
-}
-
-/****************************************************************************
- * Fileops
- ****************************************************************************/
-
-/* XXX: recvmsg is overwritten when multiple msg arrive! */
-static ssize_t sc_console_read(file_t *filep, FAR char *buffer, size_t buflen)
-{
- size_t len;
- struct msgb *tmp;
-
- /* Wait until data is received */
- while(recvmsg == NULL) {
- sem_wait(&readdev->recvsem);
- }
-
- len = recvmsg->len > buflen ? buflen : recvmsg->len;
- memcpy(buffer, msgb_get(recvmsg, len), len);
-
- if(recvmsg->len == 0) {
- /* prevent inconsistent msg by first invalidating it, then free it */
- tmp = recvmsg;
- recvmsg = NULL;
- msgb_free(tmp);
- }
-
- return len;
-}
-
-/* XXX: redirect to old Osmocom-BB comm/sercomm_cons.c -> 2 buffers */
-extern int sercomm_puts(const char *s);
-static ssize_t sc_console_write(file_t *filep, FAR const char *buffer, size_t buflen)
-{
- int i, cnt;
- char dstbuf[32];
-
- if (buflen >= 31)
- cnt = 31;
- else
- cnt = buflen;
-
- memcpy(dstbuf, buffer, cnt);
- dstbuf[cnt] = '\0';
-
- /* print part of our buffer */
- sercomm_puts(dstbuf);
-
- /* wait a little bit to get data transfered */
- up_mdelay(1);
-
- return cnt;
-}
-
-/* Forward ioctl to uart driver */
-static int sc_console_ioctl(struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR uart_dev_t *dev = inode->i_private;
-
- return dev->ops->ioctl(filep, cmd, arg);
-}
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/* Use sercomm on uart driver, register console driver */
-int sercomm_register(FAR const char *path, FAR uart_dev_t *dev)
-{
- /* XXX: initialize MODEMUART to be used for sercomm*/
- uart_init(SERCOMM_UART_NR, 1);
- uart_baudrate(SERCOMM_UART_NR, UART_115200);
- readdev = dev;
- sercomm_register_rx_cb(SC_DLCI_LOADER, &recv_cb);
-
- sem_init(&dev->xmit.sem, 0, 1);
- sem_init(&dev->recv.sem, 0, 1);
- sem_init(&dev->closesem, 0, 1);
- sem_init(&dev->xmitsem, 0, 0);
- sem_init(&dev->recvsem, 0, 0);
-#ifndef CONFIG_DISABLE_POLL
- sem_init(&dev->pollsem, 0, 1);
-#endif
-
- dbg("Registering %s\n", path);
- return register_driver(path, &g_sercom_console_ops, 0666, NULL);
-}
diff --git a/nuttx/drivers/sercomm/loadwriter.py b/nuttx/drivers/sercomm/loadwriter.py
deleted file mode 100644
index 6234d6f0d..000000000
--- a/nuttx/drivers/sercomm/loadwriter.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/python
-from socket import *
-import time
-
-SOCKET_NAME = '/tmp/osmocom_loader'
-
-s = socket(AF_UNIX, SOCK_STREAM)
-s.connect(SOCKET_NAME)
-
-while 1:
- try:
- x = raw_input(">")
- y = len(x) + 1
- s.send(chr(y>>8) + chr(y&255) + x + "\n")
- except:
- print ''
- break
-
-s.close()
diff --git a/nuttx/drivers/sercomm/uart.c b/nuttx/drivers/sercomm/uart.c
deleted file mode 100644
index 691bba9ec..000000000
--- a/nuttx/drivers/sercomm/uart.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/****************************************************************************
- * drivers/sercomm/uart.c
- * Calypso DBB internal UART Driver
- *
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Ingo Albrecht <prom@berlin.ccc.de>
- *
- * 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.
- *
- **************************************************************************/
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <nuttx/config.h>
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-
-#include <arch/calypso/memory.h>
-#include <arch/calypso/debug.h>
-
-#include <arch/calypso/defines.h>
-//#include <arch/calypso/console.h>
-#include <nuttx/sercomm/sercomm.h>
-
-#include "uart.h"
-
-#define BASE_ADDR_UART_MODEM 0xffff5000
-#define OFFSET_IRDA 0x800
-
-#define UART_REG(n,m) (BASE_ADDR_UART_MODEM + ((n)*OFFSET_IRDA)+(m))
-
-#define LCR7BIT 0x80
-#define LCRBFBIT 0x40
-#define MCR6BIT 0x20
-#define REG_OFFS(m) ((m) & ~(LCR7BIT|LCRBFBIT|MCR6BIT))
-/* read access LCR[7] = 0 */
-enum uart_reg {
- RHR = 0,
- IER = 1,
- IIR = 2,
- LCR = 3,
- MCR = 4,
- LSR = 5,
- MSR = 6,
- SPR = 7,
- MDR1 = 8,
- DMR2 = 9,
- SFLSR = 0x0a,
- RESUME = 0x0b,
- SFREGL = 0x0c,
- SFREGH = 0x0d,
- BLR = 0x0e,
- ACREG = 0x0f,
- SCR = 0x10,
- SSR = 0x11,
- EBLR = 0x12,
-/* read access LCR[7] = 1 */
- DLL = RHR | LCR7BIT,
- DLH = IER | LCR7BIT,
- DIV1_6 = ACREG | LCR7BIT,
-/* read/write access LCR[7:0] = 0xbf */
- EFR = IIR | LCRBFBIT,
- XON1 = MCR | LCRBFBIT,
- XON2 = LSR | LCRBFBIT,
- XOFF1 = MSR | LCRBFBIT,
- XOFF2 = SPR | LCRBFBIT,
-/* read/write access if EFR[4] = 1 and MCR[6] = 1 */
- TCR = MSR | MCR6BIT,
- TLR = SPR | MCR6BIT,
-};
-/* write access LCR[7] = 0 */
-#define THR RHR
-#define FCR IIR /* only if EFR[4] = 1 */
-#define TXFLL SFLSR
-#define TXFLH RESUME
-#define RXFLL SFREGL
-#define RXFLH SFREGH
-
-enum fcr_bits {
- FIFO_EN = (1 << 0),
- RX_FIFO_CLEAR = (1 << 1),
- TX_FIFO_CLEAR = (1 << 2),
- DMA_MODE = (1 << 3),
-};
-#define TX_FIFO_TRIG_SHIFT 4
-#define RX_FIFO_TRIG_SHIFT 6
-
-enum iir_bits {
- IIR_INT_PENDING = 0x01,
- IIR_INT_TYPE = 0x3E,
- IIR_INT_TYPE_RX_STATUS_ERROR = 0x06,
- IIR_INT_TYPE_RX_TIMEOUT = 0x0C,
- IIR_INT_TYPE_RHR = 0x04,
- IIR_INT_TYPE_THR = 0x02,
- IIR_INT_TYPE_MSR = 0x00,
- IIR_INT_TYPE_XOFF = 0x10,
- IIR_INT_TYPE_FLOW = 0x20,
- IIR_FCR0_MIRROR = 0xC0,
-};
-
-#define UART_REG_UIR 0xffff6000
-
-/* enable or disable the divisor latch for access to DLL, DLH */
-static void uart_set_lcr7bit(int uart, int on)
-{
- uint8_t reg;
-
- reg = readb(UART_REG(uart, LCR));
- if (on)
- reg |= (1 << 7);
- else
- reg &= ~(1 << 7);
- writeb(reg, UART_REG(uart, LCR));
-}
-
-static uint8_t old_lcr;
-static void uart_set_lcr_bf(int uart, int on)
-{
- if (on) {
- old_lcr = readb(UART_REG(uart, LCR));
- writeb(0xBF, UART_REG(uart, LCR));
- } else {
- writeb(old_lcr, UART_REG(uart, LCR));
- }
-}
-
-/* Enable or disable the TCR_TLR latch bit in MCR[6] */
-static void uart_set_mcr6bit(int uart, int on)
-{
- uint8_t mcr;
- /* we assume EFR[4] is always set to 1 */
- mcr = readb(UART_REG(uart, MCR));
- if (on)
- mcr |= (1 << 6);
- else
- mcr &= ~(1 << 6);
- writeb(mcr, UART_REG(uart, MCR));
-}
-
-static void uart_reg_write(int uart, enum uart_reg reg, uint8_t val)
-{
- if (reg & LCRBFBIT)
- uart_set_lcr_bf(uart, 1);
- else if (reg & LCR7BIT)
- uart_set_lcr7bit(uart, 1);
- else if (reg & MCR6BIT)
- uart_set_mcr6bit(uart, 1);
-
- writeb(val, UART_REG(uart, REG_OFFS(reg)));
-
- if (reg & LCRBFBIT)
- uart_set_lcr_bf(uart, 0);
- else if (reg & LCR7BIT)
- uart_set_lcr7bit(uart, 0);
- else if (reg & MCR6BIT)
- uart_set_mcr6bit(uart, 0);
-}
-
-/* read from a UART register, applying any required latch bits */
-static uint8_t uart_reg_read(int uart, enum uart_reg reg)
-{
- uint8_t ret;
-
- if (reg & LCRBFBIT)
- uart_set_lcr_bf(uart, 1);
- else if (reg & LCR7BIT)
- uart_set_lcr7bit(uart, 1);
- else if (reg & MCR6BIT)
- uart_set_mcr6bit(uart, 1);
-
- ret = readb(UART_REG(uart, REG_OFFS(reg)));
-
- if (reg & LCRBFBIT)
- uart_set_lcr_bf(uart, 0);
- else if (reg & LCR7BIT)
- uart_set_lcr7bit(uart, 0);
- else if (reg & MCR6BIT)
- uart_set_mcr6bit(uart, 0);
-
- return ret;
-}
-
-#if 0
-static void uart_irq_handler_cons(__unused enum irq_nr irqnr)
-{
- const uint8_t uart = CONS_UART_NR;
- uint8_t iir;
-
- //uart_putchar_nb(uart, 'U');
-
- iir = uart_reg_read(uart, IIR);
- if (iir & IIR_INT_PENDING)
- return;
-
- switch (iir & IIR_INT_TYPE) {
- case IIR_INT_TYPE_RHR:
- break;
- case IIR_INT_TYPE_THR:
- if (cons_rb_flush() == 1) {
- /* everything was flushed, disable THR IRQ */
- uint8_t ier = uart_reg_read(uart, IER);
- ier &= ~(1 << 1);
- uart_reg_write(uart, IER, ier);
- }
- break;
- case IIR_INT_TYPE_MSR:
- break;
- case IIR_INT_TYPE_RX_STATUS_ERROR:
- break;
- case IIR_INT_TYPE_RX_TIMEOUT:
- break;
- case IIR_INT_TYPE_XOFF:
- break;
- }
-}
-#endif
-
-static void uart_irq_handler_sercomm(__unused enum irq_nr irqnr, __unused void *context)
-{
- const uint8_t uart = SERCOMM_UART_NR;
- uint8_t iir, ch;
-
- //uart_putchar_nb(uart, 'U');
-
- iir = uart_reg_read(uart, IIR);
- if (iir & IIR_INT_PENDING)
- return;
-
- switch (iir & IIR_INT_TYPE) {
- case IIR_INT_TYPE_RX_TIMEOUT:
- case IIR_INT_TYPE_RHR:
- /* as long as we have rx data available */
- while (uart_getchar_nb(uart, &ch)) {
- if (sercomm_drv_rx_char(ch) < 0) {
- /* sercomm cannot receive more data right now */
- uart_irq_enable(uart, UART_IRQ_RX_CHAR, 0);
- }
- }
- break;
- case IIR_INT_TYPE_THR:
- /* as long as we have space in the FIFO */
- while (!uart_tx_busy(uart)) {
- /* get a byte from sercomm */
- if (!sercomm_drv_pull(&ch)) {
- /* no more bytes in sercomm, stop TX interrupts */
- uart_irq_enable(uart, UART_IRQ_TX_EMPTY, 0);
- break;
- }
- /* write the byte into the TX FIFO */
- uart_putchar_nb(uart, ch);
- }
- break;
- case IIR_INT_TYPE_MSR:
- printf("UART IRQ MSR\n");
- break;
- case IIR_INT_TYPE_RX_STATUS_ERROR:
- printf("UART IRQ RX_SE\n");
- break;
- case IIR_INT_TYPE_XOFF:
- printf("UART IRQXOFF\n");
- break;
- }
-}
-
-static const uint8_t uart2irq[] = {
- [0] = IRQ_UART_IRDA,
- [1] = IRQ_UART_MODEM,
-};
-
-void uart_init(uint8_t uart, uint8_t interrupts)
-{
- uint8_t irq = uart2irq[uart];
-
- uart_reg_write(uart, IER, 0x00);
-
- if (uart == SERCOMM_UART_NR) {
- sercomm_init();
- irq_attach(IRQ_UART_MODEM, (xcpt_t)uart_irq_handler_sercomm);
- up_enable_irq(IRQ_UART_MODEM);
- uart_irq_enable(uart, UART_IRQ_RX_CHAR, 1);
- }
-
-#if 0
- if (uart == CONS_UART_NR) {
- cons_init();
- if(interrupts) {
- irq_register_handler(irq, &uart_irq_handler_cons);
- irq_config(irq, 0, 0, 0xff);
- irq_enable(irq);
- }
- } else {
- sercomm_init();
- if(interrupts) {
- irq_register_handler(irq, &uart_irq_handler_sercomm);
- irq_config(irq, 0, 0, 0xff);
- irq_enable(irq);
- }
- uart_irq_enable(uart, UART_IRQ_RX_CHAR, 1);
- }
-#endif
-#if 0
- if (uart == 1) {
- /* assign UART to MCU and unmask interrupts*/
- writeb(UART_REG_UIR, 0x00);
- }
-#endif
-
- /* if we don't initialize these, we get strange corruptions in the
- received data... :-( */
- uart_reg_write(uart, MDR1, 0x07); /* turn off UART */
- uart_reg_write(uart, XON1, 0x00); /* Xon1/Addr Register */
- uart_reg_write(uart, XON2, 0x00); /* Xon2/Addr Register */
- uart_reg_write(uart, XOFF1, 0x00); /* Xoff1 Register */
- uart_reg_write(uart, XOFF2, 0x00); /* Xoff2 Register */
- uart_reg_write(uart, EFR, 0x00); /* Enhanced Features Register */
-
- /* select UART mode */
- uart_reg_write(uart, MDR1, 0);
- /* no XON/XOFF flow control, ENHANCED_EN, no auto-RTS/CTS */
- uart_reg_write(uart, EFR, (1 << 4));
- /* enable Tx/Rx FIFO, Tx trigger at 56 spaces, Rx trigger at 60 chars */
- uart_reg_write(uart, FCR, FIFO_EN | RX_FIFO_CLEAR | TX_FIFO_CLEAR |
- (3 << TX_FIFO_TRIG_SHIFT) | (3 << RX_FIFO_TRIG_SHIFT));
-
- /* THR interrupt only when TX FIFO and TX shift register are empty */
- uart_reg_write(uart, SCR, (1 << 0));// | (1 << 3));
-
- /* 8 bit, 1 stop bit, no parity, no break */
- uart_reg_write(uart, LCR, 0x03);
-
- uart_set_lcr7bit(uart, 0);
-}
-
-void uart_poll(uint8_t uart) {
-/* if(uart == CONS_UART_NR) {
- uart_irq_handler_cons(0);
- } else
-*/ {
- uart_irq_handler_sercomm(0, NULL);
- }
-}
-
-void uart_irq_enable(uint8_t uart, enum uart_irq irq, int on)
-{
- uint8_t ier = uart_reg_read(uart, IER);
- uint8_t mask = 0;
-
- switch (irq) {
- case UART_IRQ_TX_EMPTY:
- mask = (1 << 1);
- break;
- case UART_IRQ_RX_CHAR:
- mask = (1 << 0);
- break;
- }
-
- if (on)
- ier |= mask;
- else
- ier &= ~mask;
-
- uart_reg_write(uart, IER, ier);
-}
-
-
-void uart_putchar_wait(uint8_t uart, int c)
-{
- /* wait while TX FIFO indicates full */
- while (readb(UART_REG(uart, SSR)) & 0x01) { }
-
- /* put character in TX FIFO */
- writeb(c, UART_REG(uart, THR));
-}
-
-int uart_putchar_nb(uint8_t uart, int c)
-{
- /* if TX FIFO indicates full, abort */
- if (readb(UART_REG(uart, SSR)) & 0x01)
- return 0;
-
- writeb(c, UART_REG(uart, THR));
- return 1;
-}
-
-int uart_getchar_nb(uint8_t uart, uint8_t *ch)
-{
- uint8_t lsr;
-
- lsr = readb(UART_REG(uart, LSR));
-
- /* something strange happened */
- if (lsr & 0x02)
- printf("LSR RX_OE\n");
- if (lsr & 0x04)
- printf("LSR RX_PE\n");
- if (lsr & 0x08)
- printf("LSR RX_FE\n");
- if (lsr & 0x10)
- printf("LSR RX_BI\n");
- if (lsr & 0x80)
- printf("LSR RX_FIFO_STS\n");
-
- /* is the Rx FIFO empty? */
- if (!(lsr & 0x01))
- return 0;
-
- *ch = readb(UART_REG(uart, RHR));
- //printf("getchar_nb(%u) = %02x\n", uart, *ch);
- return 1;
-}
-
-int uart_tx_busy(uint8_t uart)
-{
- if (readb(UART_REG(uart, SSR)) & 0x01)
- return 1;
- return 0;
-}
-
-static const uint16_t divider[] = {
- [UART_38400] = 21, /* 38,690 */
- [UART_57600] = 14, /* 58,035 */
- [UART_115200] = 7, /* 116,071 */
- [UART_230400] = 4, /* 203,125! (-3% would be 223,488) */
- [UART_460800] = 2, /* 406,250! (-3% would be 446,976) */
- [UART_921600] = 1, /* 812,500! (-3% would be 893,952) */
-};
-
-int uart_baudrate(uint8_t uart, enum uart_baudrate bdrt)
-{
- uint16_t div;
-
- if (bdrt > ARRAY_SIZE(divider))
- return -1;
-
- div = divider[bdrt];
- uart_set_lcr7bit(uart, 1);
- writeb(div & 0xff, UART_REG(uart, DLL));
- writeb(div >> 8, UART_REG(uart, DLH));
- uart_set_lcr7bit(uart, 0);
-
- return 0;
-}
diff --git a/nuttx/drivers/sercomm/uart.h b/nuttx/drivers/sercomm/uart.h
deleted file mode 100644
index 81d7a1560..000000000
--- a/nuttx/drivers/sercomm/uart.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _UART_H
-#define _UART_H
-
-#include <stdint.h>
-
-enum uart_baudrate {
- UART_38400,
- UART_57600,
- UART_115200,
- UART_230400,
- UART_460800,
- UART_614400,
- UART_921600,
-};
-
-void uart_init(uint8_t uart, uint8_t interrupts);
-void uart_putchar_wait(uint8_t uart, int c);
-int uart_putchar_nb(uint8_t uart, int c);
-int uart_getchar_nb(uint8_t uart, uint8_t *ch);
-int uart_tx_busy(uint8_t uart);
-int uart_baudrate(uint8_t uart, enum uart_baudrate bdrt);
-
-enum uart_irq {
- UART_IRQ_TX_EMPTY,
- UART_IRQ_RX_CHAR,
-};
-
-void uart_irq_enable(uint8_t uart, enum uart_irq irq, int on);
-
-void uart_poll(uint8_t uart);
-
-#endif /* _UART_H */
diff --git a/nuttx/drivers/serial/Kconfig b/nuttx/drivers/serial/Kconfig
deleted file mode 100644
index 119923a69..000000000
--- a/nuttx/drivers/serial/Kconfig
+++ /dev/null
@@ -1,1054 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-config DEV_LOWCONSOLE
- bool "Low-level console support"
- default n
- depends on ARCH_LOWPUTC
- ---help---
- Use the simple, low-level, write-only serial console driver (minimal support)
-
-config SERIAL_REMOVABLE
- bool
-
-config 16550_UART
- bool "16550 UART Chip support"
- default n
-
-if 16550_UART
-config 16550_UART0
- bool "16550 UART0"
- default n
-
-if 16550_UART0
-config 16550_UART0_BASE
- hex "16550 UART0 base address"
-
-config 16550_UART0_CLOCK
- int "16550 UART0 clock"
-
-config 16550_UART0_IRQ
- int "16550 UART0 IRQ number"
-
-config 16550_UART0_BAUD
- int "16550 UART0 BAUD"
- default 115200
-
-config 16550_UART0_PARITY
- int "16550 UART0 parity"
- default 0
- ---help---
- 16550 UART0 parity. 0=None, 1=Odd, 2=Even. Default: None
-
-config 16550_UART0_BITS
- int "16550 UART0 number of bits"
- default 8
- ---help---
- 16550 UART0 number of bits. Default: 8
-
-config 16550_UART0_2STOP
- int "16550 UART0 two stop bits"
- default 0
- ---help---
- 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
-
-config 16550_UART0_RXBUFSIZE
- int "16550 UART0 Rx buffer size"
- default 256
- ---help---
- 16550 UART0 Rx buffer size. Default: 256
-
-config 16550_UART0_TXBUFSIZE
- int "16550 UART0 Tx buffer size"
- default 256
- ---help---
- 16550 UART0 Tx buffer size. Default: 256
-
-endif
-
-config 16550_UART1
- bool "16550 UART1"
- default n
-
-if 16550_UART1
-config 16550_UART1_BASE
- hex "16550 UART1 base address"
-
-config 16550_UART1_CLOCK
- int "16550 UART1 clock"
-
-config 16550_UART1_IRQ
- int "16550 UART1 IRQ number"
-
-config 16550_UART1_BAUD
- int "16550 UART1 BAUD"
- default 115200
-
-config 16550_UART1_PARITY
- int "16550 UART1 parity"
- default 0
- ---help---
- 16550 UART1 parity. 0=None, 1=Odd, 2=Even. Default: None
-
-config 16550_UART1_BITS
- int "16550 UART1 number of bits"
- default 8
- ---help---
- 16550 UART1 number of bits. Default: 8
-
-config 16550_UART1_2STOP
- int "16550 UART1 two stop bits"
- default 0
- ---help---
- 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
-
-config 16550_UART1_RXBUFSIZE
- int "16550 UART1 Rx buffer size"
- default 256
- ---help---
- 16550 UART1 Rx buffer size. Default: 256
-
-config 16550_UART1_TXBUFSIZE
- int "16550 UART1 Tx buffer size"
- default 256
- ---help---
- 16550 UART1 Tx buffer size. Default: 256
-
-endif
-
-config 16550_UART2
- bool "16550 UART2"
- default n
-
-if 16550_UART2
-config 16550_UART2_BASE
- hex "16550 UART2 base address"
-
-config 16550_UART2_CLOCK
- int "16550 UART2 clock"
-
-config 16550_UART2_IRQ
- int "16550 UART2 IRQ number"
-
-config 16550_UART2_BAUD
- int "16550 UART2 BAUD"
- default 115200
-
-config 16550_UART2_PARITY
- int "16550 UART2 parity"
- default 0
- ---help---
- 16550 UART2 parity. 0=None, 1=Odd, 2=Even. Default: None
-
-config 16550_UART2_BITS
- int "16550 UART2 number of bits"
- default 8
- ---help---
- 16550 UART2 number of bits. Default: 8
-
-config 16550_UART2_2STOP
- int "16550 UART2 two stop bits"
- default 0
- ---help---
- 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
-
-config 16550_UART2_RXBUFSIZE
- int "16550 UART2 Rx buffer size"
- default 256
- ---help---
- 16550 UART2 Rx buffer size. Default: 256
-
-config 16550_UART2_TXBUFSIZE
- int "16550 UART2 Tx buffer size"
- default 256
- ---help---
- 16550 UART2 Tx buffer size. Default: 256
-
-endif
-
-config 16550_UART3
- bool "16550 UART3"
- default n
-
-if 16550_UART3
-config 16550_UART3_BASE
- hex "16550 UART3 base address"
-
-config 16550_UART3_CLOCK
- int "16550 UART3 clock"
-
-config 16550_UART3_IRQ
- int "16550 UART3 IRQ number"
-
-config 16550_UART3_BAUD
- int "16550 UART3 BAUD"
- default 115200
-
-config 16550_UART3_PARITY
- int "16550 UART3 parity"
- default 0
- ---help---
- 16550 UART3 parity. 0=None, 1=Odd, 2=Even. Default: None
-
-config 16550_UART3_BITS
- int "16550 UART3 number of bits"
- default 8
- ---help---
- 16550 UART3 number of bits. Default: 8
-
-config 16550_UART3_2STOP
- int "16550 UART3 two stop bits"
- default 0
- ---help---
- 0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
-
-config 16550_UART3_RXBUFSIZE
- int "16550 UART3 Rx buffer size"
- default 256
- ---help---
- 16550 UART3 Rx buffer size. Default: 256
-
-config 16550_UART3_TXBUFSIZE
- int "16550 UART3 Tx buffer size"
- default 256
- ---help---
- 16550 UART3 Tx buffer size. Default: 256
-
-endif
-
-choice
- prompt "16550 Serial Console"
- default 16550_NO_SERIAL_CONSOLE
-
-config 16550_UART0_SERIAL_CONSOLE
- bool "16550 UART0 serial console"
- depends on 16550_UART0
-
-config 16550_UART1_SERIAL_CONSOLE
- bool "16550 UART1 serial console"
- depends on 16550_UART1
-
-config 16550_UART2_SERIAL_CONSOLE
- bool "16550 UART2 serial console"
- depends on 16550_UART2
-
-config 16550_UART3_SERIAL_CONSOLE
- bool "16550 UART3 serial console"
- depends on 16550_UART3
-
-config 16550_NO_SERIAL_CONSOLE
- bool "No 16550 serial console"
-
-endchoice
-
-config 16550_SUPRESS_CONFIG
- bool "Suppress 16550 configuration"
- default n
- ---help---
- This option is useful, for example, if you are using a bootloader
- that configures the 16550_UART. In that case, you may want to
- just leave the existing console configuration in place. Default: n
-
-config 16550_REGINCR
- int "Address increment between 16550 registers"
- default 1
- ---help---
- The address increment between 16550 registers. Options are 1, 2, or 4.
- Default: 1
-
-config 16550_REGWIDTH
- int "Bit width of 16550 registers"
- default 8
- ---help---
- The bit width of registers. Options are 8, 16, or 32. Default: 8
-
-config 16550_ADDRWIDTH
- int "Address width of 16550 registers"
- default 8
- ---help---
- The bit width of registers. Options are 8, 16, or 32. Default: 8
-
-endif
-
-#
-# MCU serial peripheral driver?
-#
-
-config ARCH_HAVE_UART
- bool
-config ARCH_HAVE_UART0
- bool
-config ARCH_HAVE_UART1
- bool
-config ARCH_HAVE_UART2
- bool
-config ARCH_HAVE_UART3
- bool
-config ARCH_HAVE_UART4
- bool
-config ARCH_HAVE_UART5
- bool
-config ARCH_HAVE_UART6
- bool
-
-config ARCH_HAVE_USART0
- bool
-config ARCH_HAVE_USART1
- bool
-config ARCH_HAVE_USART2
- bool
-config ARCH_HAVE_USART3
- bool
-config ARCH_HAVE_USART4
- bool
-config ARCH_HAVE_USART5
- bool
-config ARCH_HAVE_USART6
- bool
-
-config MCU_SERIAL
- bool
- default y if ARCH_HAVE_UART || ARCH_HAVE_UART0 || ARCH_HAVE_USART0 || ARCH_HAVE_UART1 || ARCH_HAVE_USART1 || \
- ARCH_HAVE_UART2 || ARCH_HAVE_USART2 || ARCH_HAVE_UART3 || ARCH_HAVE_USART3 || \
- ARCH_HAVE_UART4 || ARCH_HAVE_USART4 || ARCH_HAVE_UART5 || ARCH_HAVE_USART5 || ARCH_HAVE_UART6 || ARCH_HAVE_USART6
-
-#
-# Standard serial driver configuration
-#
-
-config STANDARD_SERIAL
- bool "Enable standard \"upper-half\" serial driver"
- default y if MCU_SERIAL
- default n if !MCU_SERIAL
- depends on !DEV_LOWCONSOLE
- ---help---
- Enable the standard, upper-half serial driver used by most MCU serial peripherals.
-
-config CONFIG_SERIAL_NPOLLWAITERS
- int "Number of poll threads"
- default 2
- depends on !DISABLE_POLL && STANDARD_SERIAL
- ---help---
- Maximum number of threads than can be waiting for POLL events.
- Default: 2
-
-#
-# U[S]ARTn_XYZ settings for MCU serial drivers
-#
-
-choice
- prompt "Serial console"
- depends on MCU_SERIAL
- default NO_SERIAL_CONSOLE
-
-config UART_SERIAL_CONSOLE
- bool "UART"
- depends on ARCH_HAVE_UART
-
-config UART0_SERIAL_CONSOLE
- bool "UART0"
- depends on ARCH_HAVE_UART0
-
-config USART0_SERIAL_CONSOLE
- bool "USART0"
- depends on ARCH_HAVE_USART0
-
-config UART1_SERIAL_CONSOLE
- bool "UART1"
- depends on ARCH_HAVE_UART1
-
-config USART1_SERIAL_CONSOLE
- bool "USART1"
- depends on ARCH_HAVE_USART1
-
-config UART2_SERIAL_CONSOLE
- bool "UART2"
- depends on ARCH_HAVE_UART2
-
-config USART2_SERIAL_CONSOLE
- bool "USART2"
- depends on ARCH_HAVE_USART2
-
-config UART3_SERIAL_CONSOLE
- bool "UART3"
- depends on ARCH_HAVE_UART3
-
-config USART3_SERIAL_CONSOLE
- bool "USART3"
- depends on ARCH_HAVE_USART3
-
-config UART4_SERIAL_CONSOLE
- bool "UART4"
- depends on ARCH_HAVE_UART4
-
-config USART4_SERIAL_CONSOLE
- bool "USART4"
- depends on ARCH_HAVE_USART4
-
-config UART5_SERIAL_CONSOLE
- bool "UART5"
- depends on ARCH_HAVE_UART5
-
-config USART5_SERIAL_CONSOLE
- bool "USART5"
- depends on ARCH_HAVE_USART5
-
-config UART6_SERIAL_CONSOLE
- bool "UART6"
- depends on ARCH_HAVE_UART6
-
-config USART6_SERIAL_CONSOLE
- bool "USART6"
- depends on ARCH_HAVE_USART6
-
-config NO_SERIAL_CONSOLE
- bool "No serial console"
-
-endchoice
-
-menu "UART Configuration"
- depends on ARCH_HAVE_UART
-
-config UART_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config UART_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config UART_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the UART.
-
-config UART_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config UART_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config UART_2STOP
- int "use 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "UART0 Configuration"
- depends on ARCH_HAVE_UART0
-
-config UART0_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config UART0_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config UART0_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the UART.
-
-config UART0_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config UART0_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config UART0_2STOP
- int "use 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "USART0 Configuration"
- depends on ARCH_HAVE_USART0
-
-config USART0_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config USART0_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config USART0_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the USART.
-
-config USART0_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config USART0_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config USART0_2STOP
- int "use 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "UART1 Configuration"
- depends on ARCH_HAVE_UART1
-
-config UART1_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config UART1_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config UART1_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the UART.
-
-config UART1_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config UART1_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config UART1_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "USART1 Configuration"
- depends on ARCH_HAVE_USART1
-
-config USART1_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config USART1_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config USART1_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the USART.
-
-config USART1_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config USART1_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config USART1_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "UART2 Configuration"
- depends on ARCH_HAVE_UART2
-
-config UART2_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config UART2_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config UART2_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the UART.
-
-config UART2_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config UART2_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config UART2_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "USART2 Configuration"
- depends on ARCH_HAVE_USART2
-
-config USART2_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config USART2_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config USART2_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the USART.
-
-config USART2_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config USART2_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config USART2_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "UART3 Configuration"
- depends on ARCH_HAVE_UART3
-
-config UART3_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config UART3_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config UART3_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the UART.
-
-config UART3_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config UART3_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config UART3_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "USART3 Configuration"
- depends on ARCH_HAVE_USART3
-
-config USART3_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config USART3_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config USART3_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the USART.
-
-config USART3_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config USART3_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config USART3_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "UART4 Configuration"
- depends on ARCH_HAVE_UART4
-
-config UART4_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config UART4_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config UART4_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the UART.
-
-config UART4_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config UART4_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config UART4_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "USART4 Configuration"
- depends on ARCH_HAVE_USART4
-
-config USART4_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config USART4_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config USART4_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the USART.
-
-config USART4_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config USART4_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config USART4_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "UART5 Configuration"
- depends on ARCH_HAVE_UART5
-
-config UART5_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config UART5_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config UART5_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the UART.
-
-config UART5_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config UART5_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config UART5_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "USART5 Configuration"
- depends on ARCH_HAVE_USART5
-
-config USART5_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config USART5_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config USART5_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the USART.
-
-config USART5_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config USART5_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config USART5_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "USART6 Configuration"
- depends on ARCH_HAVE_USART6
-
-config USART6_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config USART6_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config USART6_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the USART.
-
-config USART6_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config USART6_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config USART6_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
-
-menu "UART6 Configuration"
- depends on ARCH_HAVE_UART6
-
-config UART6_RXBUFSIZE
- int "receive buffer size"
- default 256
- help
- Characters are buffered as they are received. This specifies
- the size of the receive buffer.
-
-config UART6_TXBUFSIZE
- int "transmit buffer size"
- default 256
- help
- Characters are buffered before being sent. This specifies
- the size of the transmit buffer.
-
-config UART6_BAUD
- int "baud rate"
- default 115200
- help
- The configured BAUD of the UART.
-
-config UART6_BITS
- int "character size"
- default 8
- help
- The number of bits. Must be either 7 or 8.
-
-config UART6_PARITY
- int "parity setting"
- default 0
- help
- 0=no parity, 1=odd parity, 2=even parity
-
-config UART6_2STOP
- int "uses 2 stop bits"
- default 0
- help
- 1=Two stop bits
-
-endmenu
diff --git a/nuttx/drivers/serial/Make.defs b/nuttx/drivers/serial/Make.defs
deleted file mode 100644
index b99f4eb36..000000000
--- a/nuttx/drivers/serial/Make.defs
+++ /dev/null
@@ -1,50 +0,0 @@
-############################################################################
-# drivers/serial/Make.defs
-#
-# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-ifneq ($(CONFIG_NFILE_DESCRIPTORS),0)
-
-# Include serial drivers
-
-CSRCS += serial.c serialirq.c lowconsole.c
-
-ifeq ($(CONFIG_16550_UART),y)
- CSRCS += uart_16550.c
-endif
-
-# Include serial build support
-
-DEPPATH += --dep-path serial
-VPATH += :serial
-endif
diff --git a/nuttx/drivers/serial/lowconsole.c b/nuttx/drivers/serial/lowconsole.c
deleted file mode 100644
index 1fac49a57..000000000
--- a/nuttx/drivers/serial/lowconsole.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
- * drivers/serial/lowconsole.c
- *
- * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/fs/fs.h>
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-/* The architecture must provide up_putc for this driver */
-
-#ifndef CONFIG_ARCH_LOWPUTC
-# error "Architecture must provide up_putc() for this driver"
-#endif
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static ssize_t lowconsole_read(struct file *filep, char *buffer, size_t buflen);
-static ssize_t lowconsole_write(struct file *filep, const char *buffer, size_t buflen);
-static int lowconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
-
-/****************************************************************************
- * Private Variables
- ****************************************************************************/
-
-static const struct file_operations g_consoleops =
-{
- 0, /* open */
- 0, /* close */
- lowconsole_read, /* read */
- lowconsole_write, /* write */
- 0, /* seek */
- lowconsole_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , 0 /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: lowconsole_ioctl
- ****************************************************************************/
-
-static int lowconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
-{
- return -ENOTTY;
-}
-
-/****************************************************************************
- * Name: lowconsole_read
- ****************************************************************************/
-
-static ssize_t lowconsole_read(struct file *filep, char *buffer, size_t buflen)
-{
- return 0;
-}
-
-/****************************************************************************
- * Name: lowconsole_write
- ****************************************************************************/
-
-static ssize_t lowconsole_write(struct file *filep, const char *buffer, size_t buflen)
-{
- ssize_t ret = buflen;
-
- for (; buflen; buflen--)
- {
- up_putc(*buffer++);
- }
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: lowconsole_init
-****************************************************************************/
-
-void lowconsole_init(void)
-{
- (void)register_driver("/dev/console", &g_consoleops, 0666, NULL);
-}
diff --git a/nuttx/drivers/serial/serial.c b/nuttx/drivers/serial/serial.c
deleted file mode 100644
index 0fed1d6c5..000000000
--- a/nuttx/drivers/serial/serial.c
+++ /dev/null
@@ -1,1377 +0,0 @@
-/************************************************************************************
- * drivers/serial/serial.c
- *
- * Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <semaphore.h>
-#include <string.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/serial/serial.h>
-
-/************************************************************************************
- * Definitions
- ************************************************************************************/
-
-/* The architecture must provide up_putc for this driver */
-
-#ifndef CONFIG_ARCH_LOWPUTC
-# error "Architecture must provide up_putc() for this driver"
-#endif
-
-#define uart_putc(ch) up_putc(ch)
-
-#define HALF_SECOND_MSEC 500
-#define HALF_SECOND_USEC 500000L
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-
-static int uart_open(FAR struct file *filep);
-static int uart_close(FAR struct file *filep);
-static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
-static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
-static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
-#ifndef CONFIG_DISABLE_POLL
-static int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup);
-#endif
-
-/************************************************************************************
- * Private Variables
- ************************************************************************************/
-
-static const struct file_operations g_serialops =
-{
- uart_open, /* open */
- uart_close, /* close */
- uart_read, /* read */
- uart_write, /* write */
- 0, /* seek */
- uart_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , uart_poll /* poll */
-#endif
-};
-
-/************************************************************************************
- * Private Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: uart_takesem
- ************************************************************************************/
-
-static int uart_takesem(FAR sem_t *sem, bool errout)
-{
- /* Loop, ignoring interrupts, until we have successfully acquired the semaphore */
-
- while (sem_wait(sem) != OK)
- {
- /* The only case that an error should occur here is if the wait was awakened
- * by a signal.
- */
-
- ASSERT(get_errno() == EINTR);
-
- /* When the signal is received, should we errout? Or should we just continue
- * waiting until we have the semaphore?
- */
-
- if (errout)
- {
- return -EINTR;
- }
- }
-
- return OK;
-}
-
-/************************************************************************************
- * Name: uart_givesem
- ************************************************************************************/
-
-#define uart_givesem(sem) (void)sem_post(sem)
-
-/****************************************************************************
- * Name: uart_pollnotify
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static void uart_pollnotify(FAR uart_dev_t *dev, pollevent_t eventset)
-{
- int i;
-
- for (i = 0; i < CONFIG_SERIAL_NPOLLWAITERS; i++)
- {
- struct pollfd *fds = dev->fds[i];
- if (fds)
- {
-#ifdef CONFIG_SERIAL_REMOVABLE
- fds->revents |= ((fds->events | (POLLERR|POLLHUP)) & eventset);
-#else
- fds->revents |= (fds->events & eventset);
-#endif
- if (fds->revents != 0)
- {
- fvdbg("Report events: %02x\n", fds->revents);
- sem_post(fds->sem);
- }
- }
- }
-}
-#else
-# define uart_pollnotify(dev,event)
-#endif
-
-/************************************************************************************
- * Name: uart_putxmitchar
- ************************************************************************************/
-
-static int uart_putxmitchar(FAR uart_dev_t *dev, int ch)
-{
- irqstate_t flags;
- int nexthead;
- int ret;
-
- /* Increment to see what the next head pointer will be. We need to use the "next"
- * head pointer to determine when the circular buffer would overrun
- */
-
- nexthead = dev->xmit.head + 1;
- if (nexthead >= dev->xmit.size)
- {
- nexthead = 0;
- }
-
- /* Loop until we are able to add the character to the TX buffer */
-
- for (;;)
- {
- if (nexthead != dev->xmit.tail)
- {
- dev->xmit.buffer[dev->xmit.head] = ch;
- dev->xmit.head = nexthead;
- return OK;
- }
- else
- {
- /* Inform the interrupt level logic that we are waiting. This and
- * the following steps must be atomic.
- */
-
- flags = irqsave();
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- /* Check if the removable device is no longer connected while we
- * have interrupts off. We do not want the transition to occur
- * as a race condition before we begin the wait.
- */
-
- if (dev->disconnected)
- {
- irqrestore(flags);
- return -ENOTCONN;
- }
-#endif
- /* Wait for some characters to be sent from the buffer with the TX
- * interrupt enabled. When the TX interrupt is enabled, uart_xmitchars
- * should execute and remove some of the data from the TX buffer.
- */
-
- dev->xmitwaiting = true;
- uart_enabletxint(dev);
- ret = uart_takesem(&dev->xmitsem, true);
- uart_disabletxint(dev);
- irqrestore(flags);
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- /* Check if the removable device was disconnected while we were
- * waiting.
- */
-
- if (dev->disconnected)
- {
- return -ENOTCONN;
- }
-#endif
- /* Check if we were awakened by signal. */
-
- if (ret < 0)
- {
- /* A signal received while waiting for the xmit buffer to become
- * non-full will abort the transfer.
- */
-
- return -EINTR;
- }
- }
- }
-
- /* We won't get here. Some compilers may complain that this code is
- * unreachable.
- */
-
- return OK;
-}
-
-/************************************************************************************
- * Name: uart_irqwrite
- ************************************************************************************/
-
-static inline ssize_t uart_irqwrite(FAR uart_dev_t *dev, FAR const char *buffer, size_t buflen)
-{
- ssize_t ret = buflen;
-
- /* Force each character through the low level interface */
-
- for (; buflen; buflen--)
- {
- int ch = *buffer++;
-
- /* If this is the console, then we should replace LF with CR-LF */
-
- if (ch == '\n')
- {
- uart_putc('\r');
- }
-
- /* Output the character, using the low-level direct UART interfaces */
-
- uart_putc(ch);
- }
-
- return ret;
-}
-
-/************************************************************************************
- * Name: uart_write
- ************************************************************************************/
-
-static ssize_t uart_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR uart_dev_t *dev = inode->i_private;
- ssize_t nread = buflen;
- int ret;
- char ch;
-
- /* We may receive console writes through this path from interrupt handlers and
- * from debug output in the IDLE task! In these cases, we will need to do things
- * a little differently.
- */
-
- if (up_interrupt_context() || getpid() == 0)
- {
-#ifdef CONFIG_SERIAL_REMOVABLE
- /* If the removable device is no longer connected, refuse to write to
- * the device.
- */
-
- if (dev->disconnected)
- {
- return -ENOTCONN;
- }
-#endif
-
- /* up_putc() will be used to generate the output in a busy-wait loop.
- * up_putc() is only available for the console device.
- */
-
- if (dev->isconsole)
- {
- irqstate_t flags = irqsave();
- ret = uart_irqwrite(dev, buffer, buflen);
- irqrestore(flags);
- return ret;
- }
- else
- {
- return -EPERM;
- }
- }
-
- /* Only one user can access dev->xmit.head at a time */
-
- ret = (ssize_t)uart_takesem(&dev->xmit.sem, true);
- if (ret < 0)
- {
- /* A signal received while waiting for access to the xmit.head will
- * abort the transfer.
- */
-
- return ret;
- }
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- /* If the removable device is no longer connected, refuse to write to the
- * device. This check occurs after taking the xmit.sem because the
- * disconnection event might have occurred while we were waiting for
- * access to the transmit buffers.
- */
-
- if (dev->disconnected)
- {
- uart_givesem(&dev->xmit.sem);
- return -ENOTCONN;
- }
-#endif
-
- /* Loop while we still have data to copy to the transmit buffer.
- * we add data to the head of the buffer; uart_xmitchars takes the
- * data from the end of the buffer.
- */
-
- uart_disabletxint(dev);
- for (; buflen; buflen--)
- {
- ch = *buffer++;
-
- /* Do output post-processing */
-
-#ifdef CONFIG_SERIAL_TERMIOS
-
- if (dev->tc_oflag & OPOST)
- {
-
- /* Mapping CR to NL? */
-
- if ((ch == '\r') && (dev->tc_oflag & OCRNL))
- {
- ch = '\n';
- }
-
- /* Are we interested in newline processing? */
-
- if ((ch == '\n') && (dev->tc_oflag & (ONLCR | ONLRET)))
- {
- ret = uart_putxmitchar(dev, '\r');
-
- if (ret != OK)
- {
- break;
- }
- }
-
- /* Specifically not handled:
- *
- * OXTABS - primarily a full-screen terminal optimisation
- * ONOEOT - Unix interoperability hack
- * OLCUC - Not specified by Posix
- * ONOCR - low-speed interactive optimisation
- */
-
- }
-
-#else /* !CONFIG_SERIAL_TERMIOS */
-
- /* If this is the console, convert \n -> \r\n */
-
- if (dev->isconsole && ch == '\n')
- {
- ret = uart_putxmitchar(dev, '\r');
- }
-
-#endif
-
- /* Put the character into the transmit buffer */
-
- ret = uart_putxmitchar(dev, ch);
-
- if (ret != OK)
- {
- break;
- }
-
- }
-
- if (dev->xmit.head != dev->xmit.tail)
- {
- uart_enabletxint(dev);
- }
-
- uart_givesem(&dev->xmit.sem);
-
- /* uart_putxmitchar() might return an error under one of two
- * conditions: (1) The wait for buffer space might have been
- * interrupted by a signal (ret should be -EINTR), or (2) if
- * CONFIG_SERIAL_REMOVABLE is defined, then uart_putxmitchar()
- * might also return if the serial device was disconnected
- * (wtih -ENOTCONN).
- */
-
- if (ret < 0)
- {
- /* POSIX requires that we return -1 and errno set if no data was
- * transferred. Otherwise, we return the number of bytes in the
- * interrupted transfer.
- */
-
- if (buflen < nread)
- {
- /* Some data was transferred. Return the number of bytes that were
- * successfully transferred.
- */
-
- nread -= buflen;
- }
- else
- {
- /* No data was transferred. Return the negated error. The VFS layer
- * will set the errno value appropriately).
- */
-
- nread = -ret;
- }
- }
-
- return nread;
-}
-
-/************************************************************************************
- * Name: uart_read
- ************************************************************************************/
-
-static ssize_t uart_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR uart_dev_t *dev = inode->i_private;
- irqstate_t flags;
- ssize_t recvd = 0;
- int16_t tail;
- int ret;
- char ch;
-
- /* Only one user can access dev->recv.tail at a time */
-
- ret = uart_takesem(&dev->recv.sem, true);
- if (ret < 0)
- {
- /* A signal received while waiting for access to the recv.tail will avort
- * the transfer. After the transfer has started, we are committed and
- * signals will be ignored.
- */
-
- return ret;
- }
-
- /* Loop while we still have data to copy to the receive buffer.
- * we add data to the head of the buffer; uart_xmitchars takes the
- * data from the end of the buffer.
- */
-
- while (recvd < buflen)
- {
-#ifdef CONFIG_SERIAL_REMOVABLE
- /* If the removable device is no longer connected, refuse to read any
- * further from the device.
- */
-
- if (dev->disconnected)
- {
- if (recvd == 0)
- {
- recvd = -ENOTCONN;
- }
-
- break;
- }
-#endif
-
- /* Check if there is more data to return in the circular buffer.
- * NOTE: Rx interrupt handling logic may aynchronously increment
- * the head index but must not modify the tail index. The tail
- * index is only modified in this function. Therefore, no
- * special handshaking is required here.
- *
- * The head and tail pointers are 16-bit values. The only time that
- * the following could be unsafe is if the CPU made two non-atomic
- * 8-bit accesses to obtain the 16-bit head index.
- */
-
- tail = dev->recv.tail;
- if (dev->recv.head != tail)
- {
- /* Take the next character from the tail of the buffer */
-
- ch = dev->recv.buffer[tail];
-
- /* Increment the tail index. Most operations are done using the
- * local variable 'tail' so that the final dev->recv.tail update
- * is atomic.
- */
-
- if (++tail >= dev->recv.size)
- {
- tail = 0;
- }
-
- dev->recv.tail = tail;
-
-#ifdef CONFIG_SERIAL_TERMIOS
-
- /* Do input processing if any is enabled */
-
- if (dev->tc_iflag & (INLCR | IGNCR | ICRNL))
- {
-
- /* \n -> \r or \r -> \n translation? */
-
- if ((ch == '\n') && (dev->tc_iflag & INLCR))
- {
- ch = '\r';
- }
- else if ((ch == '\r') && (dev->tc_iflag & ICRNL))
- {
- ch = '\n';
- }
-
- /* discarding \r ? */
- if ((ch == '\r') & (dev->tc_iflag & IGNCR))
- {
- continue;
- }
-
- }
-
- /* Specifically not handled:
- *
- * All of the local modes; echo, line editing, etc.
- * Anything to do with break or parity errors.
- * ISTRIP - we should be 8-bit clean.
- * IUCLC - Not Posix
- * IXON/OXOFF - no xon/xoff flow control.
- */
-
-#endif
-
- /* store the received character */
-
- *buffer++ = ch;
- recvd++;
-
- }
-
-#ifdef CONFIG_DEV_SERIAL_FULLBLOCKS
- /* No... then we would have to wait to get receive more data.
- * If the user has specified the O_NONBLOCK option, then just
- * return what we have.
- */
-
- else if (filep->f_oflags & O_NONBLOCK)
- {
- /* If nothing was transferred, then return the -EAGAIN
- * error (not zero which means end of file).
- */
-
- if (recvd < 1)
- {
- recvd = -EAGAIN;
- }
-
- break;
- }
-#else
- /* No... the circular buffer is empty. Have we returned anything
- * to the caller?
- */
-
- else if (recvd > 0)
- {
- /* Yes.. break out of the loop and return the number of bytes
- * received up to the wait condition.
- */
-
- break;
- }
-
- /* No... then we would have to wait to get receive some data.
- * If the user has specified the O_NONBLOCK option, then do not
- * wait.
- */
-
- else if (filep->f_oflags & O_NONBLOCK)
- {
- /* Break out of the loop returning -EAGAIN */
-
- recvd = -EAGAIN;
- break;
- }
-#endif
- /* Otherwise we are going to have to wait for data to arrive */
-
- else
- {
- /* Disable Rx interrupts and test again... */
-
- uart_disablerxint(dev);
-
- /* If the Rx ring buffer still empty? Bytes may have been addded
- * between the last time that we checked and when we disabled Rx
- * interrupts.
- */
-
- if (dev->recv.head == dev->recv.tail)
- {
- /* Yes.. the buffer is still empty. Wait for some characters
- * to be received into the buffer with the RX interrupt re-
- * enabled. All interrupts are disabled briefly to assure
- * that the following operations are atomic.
- */
-
- flags = irqsave();
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- /* Check if the removable device is no longer connected while
- * we have interrupts off. We do not want the transition to
- * occur as a race condition before we begin the wait.
- */
-
- if (dev->disconnected)
- {
- uart_enablerxint(dev);
- irqrestore(flags);
- ret = -ENOTCONN;
- break;
- }
-#endif
- /* Now wait with the Rx interrupt re-enabled. NuttX will
- * automatically re-enable global interrupts when this thread
- * goes to sleep.
- */
-
- dev->recvwaiting = true;
- uart_enablerxint(dev);
- ret = uart_takesem(&dev->recvsem, true);
- irqrestore(flags);
-
- /* Was a signal received while waiting for data to be
- * received? Was a removable device disconnected while
- * we were waiting?
- */
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- if (ret < 0 || dev->disconnected)
-#else
- if (ret < 0)
-#endif
- {
- /* POSIX requires that we return after a signal is received.
- * If some bytes were read, we need to return the number of bytes
- * read; if no bytes were read, we need to return -1 with the
- * errno set correctly.
- */
-
- if (recvd == 0)
- {
- /* No bytes were read, return -EINTR (the VFS layer will
- * set the errno value appropriately.
- */
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- recvd = dev->disconnected ? -ENOTCONN : -EINTR;
-#else
- recvd = -EINTR;
-#endif
- }
-
- break;
- }
- }
- else
- {
- /* No... the ring buffer is no longer empty. Just re-enable Rx
- * interrupts and accept the new data on the next time through
- * the loop.
- */
-
- uart_enablerxint(dev);
- }
- }
- }
-
- uart_givesem(&dev->recv.sem);
- return recvd;
-}
-
-/************************************************************************************
- * Name: uart_ioctl
- ************************************************************************************/
-
-static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR uart_dev_t *dev = inode->i_private;
-
- /* Handle TTY-level IOCTLs here */
- /* Let low-level driver handle the call first */
-
- int ret = dev->ops->ioctl(filep, cmd, arg);
-
- /*
- * The device ioctl() handler returns -ENOTTY when it doesn't know
- * how to handle the command. Check if we can handle it here.
- */
- if (ret == -ENOTTY)
- {
- switch (cmd)
- {
-
- case FIONREAD:
- {
- int count;
- irqstate_t state = irqsave();
-
- /* determine the number of bytes available in the buffer */
-
- if (dev->recv.tail <= dev->recv.head)
- {
- count = dev->recv.head - dev->recv.tail;
- }
- else
- {
- count = dev->recv.size - (dev->recv.tail - dev->recv.head);
- }
-
- irqrestore(state);
-
- *(int *)arg = count;
- ret = 0;
-
- break;
- }
-
- case FIONWRITE:
- {
- int count;
- irqstate_t state = irqsave();
-
- /* determine the number of bytes free in the buffer */
-
- if (dev->xmit.head < dev->xmit.tail)
- {
- count = dev->xmit.tail - dev->xmit.head - 1;
- }
- else
- {
- count = dev->xmit.size - (dev->xmit.head - dev->xmit.tail) - 1;
- }
-
- irqrestore(state);
-
- *(int *)arg = count;
- ret = 0;
-
- break;
- }
- }
- }
-
- /* Append any higher level TTY flags */
-
- else if (ret == OK)
- {
- switch (cmd)
- {
-#ifdef CONFIG_SERIAL_TERMIOS
- case TCGETS:
- {
- struct termios *termiosp = (struct termios*)arg;
-
- if (!termiosp)
- {
- ret = -EINVAL;
- break;
- }
-
- /* and update with flags from this layer */
-
- termiosp->c_iflag = dev->tc_iflag;
- termiosp->c_oflag = dev->tc_oflag;
- termiosp->c_lflag = dev->tc_lflag;
- }
-
- break;
-
- case TCSETS:
- {
- struct termios *termiosp = (struct termios*)arg;
-
- if (!termiosp)
- {
- ret = -EINVAL;
- break;
- }
-
- /* update the flags we keep at this layer */
-
- dev->tc_iflag = termiosp->c_iflag;
- dev->tc_oflag = termiosp->c_oflag;
- dev->tc_lflag = termiosp->c_lflag;
- }
-
- break;
-#endif
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: uart_poll
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-int uart_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR uart_dev_t *dev = inode->i_private;
- pollevent_t eventset;
- int ndx;
- int ret;
- int i;
-
- /* Some sanity checking */
-
-#if CONFIG_DEBUG
- if (!dev || !fds)
- {
- return -ENODEV;
- }
-#endif
-
- /* Are we setting up the poll? Or tearing it down? */
-
- ret = uart_takesem(&dev->pollsem, true);
- if (ret < 0)
- {
- /* A signal received while waiting for access to the poll data
- * will abort the operation.
- */
-
- return ret;
- }
-
- if (setup)
- {
- /* This is a request to set up the poll. Find an available
- * slot for the poll structure reference
- */
-
- for (i = 0; i < CONFIG_SERIAL_NPOLLWAITERS; i++)
- {
- /* Find an available slot */
-
- if (!dev->fds[i])
- {
- /* Bind the poll structure and this slot */
-
- dev->fds[i] = fds;
- fds->priv = &dev->fds[i];
- break;
- }
- }
-
- if (i >= CONFIG_SERIAL_NPOLLWAITERS)
- {
- fds->priv = NULL;
- ret = -EBUSY;
- goto errout;
- }
-
- /* Should we immediately notify on any of the requested events?
- * First, check if the xmit buffer is full.
- *
- * Get exclusive access to the xmit buffer indices. NOTE: that we do not
- * let this wait be interrupted by a signal (we probably should, but that
- * would be a little awkward).
- */
-
- eventset = 0;
- (void)uart_takesem(&dev->xmit.sem, false);
-
- ndx = dev->xmit.head + 1;
- if (ndx >= dev->xmit.size)
- {
- ndx = 0;
- }
-
- if (ndx != dev->xmit.tail)
- {
- eventset |= (fds->events & POLLOUT);
- }
-
- uart_givesem(&dev->xmit.sem);
-
- /* Check if the receive buffer is empty.
- *
- * Get exclusive access to the recv buffer indices. NOTE: that we do not
- * let this wait be interrupted by a signal (we probably should, but that
- * would be a little awkward).
- */
-
- (void)uart_takesem(&dev->recv.sem, false);
- if (dev->recv.head != dev->recv.tail)
- {
- eventset |= (fds->events & POLLIN);
- }
-
- uart_givesem(&dev->recv.sem);
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- /* Check if a removable device has been disconnected. */
-
- if (dev->disconnected)
- {
- eventset |= (POLLERR|POLLHUP);
- }
-#endif
-
- if (eventset)
- {
- uart_pollnotify(dev, eventset);
- }
-
- }
- else if (fds->priv)
- {
- /* This is a request to tear down the poll. */
-
- struct pollfd **slot = (struct pollfd **)fds->priv;
-
-#ifdef CONFIG_DEBUG
- if (!slot)
- {
- ret = -EIO;
- goto errout;
- }
-#endif
-
- /* Remove all memory of the poll setup */
-
- *slot = NULL;
- fds->priv = NULL;
- }
-
-errout:
- uart_givesem(&dev->pollsem);
- return ret;
-}
-#endif
-
-/************************************************************************************
- * Name: uart_close
- *
- * Description:
- * This routine is called when the serial port gets closed.
- * It waits for the last remaining data to be sent.
- *
- ************************************************************************************/
-
-static int uart_close(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR uart_dev_t *dev = inode->i_private;
- irqstate_t flags;
-
- /* Get exclusive access to the close semaphore (to synchronize open/close operations.
- * NOTE: that we do not let this wait be interrupted by a signal. Technically, we
- * should, but almost no one every checks the return value from close() so we avoid
- * a potential memory leak by ignoring signals in this case.
- */
-
- (void)uart_takesem(&dev->closesem, false);
- if (dev->open_count > 1)
- {
- dev->open_count--;
- uart_givesem(&dev->closesem);
- return OK;
- }
-
- /* There are no more references to the port */
-
- dev->open_count = 0;
-
- /* Stop accepting input */
-
- uart_disablerxint(dev);
-
- /* Now we wait for the transmit buffer to clear */
-
- while (dev->xmit.head != dev->xmit.tail)
- {
-#ifndef CONFIG_DISABLE_SIGNALS
- usleep(HALF_SECOND_USEC);
-#else
- up_mdelay(HALF_SECOND_MSEC);
-#endif
- }
-
- /* And wait for the TX fifo to drain */
-
- while (!uart_txempty(dev))
- {
-#ifndef CONFIG_DISABLE_SIGNALS
- usleep(HALF_SECOND_USEC);
-#else
- up_mdelay(HALF_SECOND_MSEC);
-#endif
- }
-
- /* Free the IRQ and disable the UART */
-
- flags = irqsave(); /* Disable interrupts */
- uart_detach(dev); /* Detach interrupts */
- if (!dev->isconsole) /* Check for the serial console UART */
- {
- uart_shutdown(dev); /* Disable the UART */
- }
-
- irqrestore(flags);
-
- uart_givesem(&dev->closesem);
- return OK;
- }
-
-/************************************************************************************
- * Name: uart_open
- *
- * Description:
- * This routine is called whenever a serial port is opened.
- *
- ************************************************************************************/
-
-static int uart_open(FAR struct file *filep)
-{
- struct inode *inode = filep->f_inode;
- uart_dev_t *dev = inode->i_private;
- uint8_t tmp;
- int ret;
-
- /* If the port is the middle of closing, wait until the close is finished.
- * If a signal is received while we are waiting, then return EINTR.
- */
-
- ret = uart_takesem(&dev->closesem, true);
- if (ret < 0)
- {
- /* A signal received while waiting for the last close operation. */
-
- return ret;
- }
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- /* If the removable device is no longer connected, refuse to open the
- * device. We check this after obtaining the close semaphore because
- * we might have been waiting when the device was disconnected.
- */
-
- if (dev->disconnected)
- {
- ret = -ENOTCONN;
- goto errout_with_sem;
- }
-#endif
-
- /* Start up serial port */
- /* Increment the count of references to the device. */
-
- tmp = dev->open_count + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- goto errout_with_sem;
- }
-
- /* Check if this is the first time that the driver has been opened. */
-
- if (tmp == 1)
- {
- irqstate_t flags = irqsave();
-
- /* If this is the console, then the UART has already been initialized. */
-
- if (!dev->isconsole)
- {
- /* Perform one time hardware initialization */
-
- ret = uart_setup(dev);
- if (ret < 0)
- {
- irqrestore(flags);
- goto errout_with_sem;
- }
- }
-
- /* In any event, we do have to configure for interrupt driven mode of
- * operation. Attach the hardware IRQ(s). Hmm.. should shutdown() the
- * the device in the rare case that uart_attach() fails, tmp==1, and
- * this is not the console.
- */
-
- ret = uart_attach(dev);
- if (ret < 0)
- {
- uart_shutdown(dev);
- irqrestore(flags);
- goto errout_with_sem;
- }
-
- /* Mark the io buffers empty */
-
- dev->xmit.head = 0;
- dev->xmit.tail = 0;
- dev->recv.head = 0;
- dev->recv.tail = 0;
-
- /* initialise termios state */
-
-#ifdef CONFIG_SERIAL_TERMIOS
-
- dev->tc_iflag = 0;
- if (dev->isconsole == true)
- {
-
- /* enable \n -> \r\n translation for the console */
-
- dev->tc_oflag = OPOST | ONLCR;
- }
- else
- {
- dev->tc_oflag = 0;
- }
-
-#endif
-
- /* Enable the RX interrupt */
-
- uart_enablerxint(dev);
- irqrestore(flags);
- }
-
- /* Save the new open count on success */
-
- dev->open_count = tmp;
-
-errout_with_sem:
- uart_givesem(&dev->closesem);
- return ret;
-}
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: uart_register
- *
- * Description:
- * Register serial console and serial ports.
- *
- ************************************************************************************/
-
-int uart_register(FAR const char *path, FAR uart_dev_t *dev)
-{
- sem_init(&dev->xmit.sem, 0, 1);
- sem_init(&dev->recv.sem, 0, 1);
- sem_init(&dev->closesem, 0, 1);
- sem_init(&dev->xmitsem, 0, 0);
- sem_init(&dev->recvsem, 0, 0);
-#ifndef CONFIG_DISABLE_POLL
- sem_init(&dev->pollsem, 0, 1);
-#endif
-
- /* Setup termios flags */
-
-#ifdef CONFIG_SERIAL_TERMIOS
-
- if (dev->isconsole == true)
- {
-
- /* enable \n -> \r\n translation for the console as early as possible */
-
- dev->tc_oflag = OPOST | ONLCR;
- dev->tc_iflag = 0;
- }
-
-#endif
-
- dbg("Registering %s\n", path);
- return register_driver(path, &g_serialops, 0666, dev);
-}
-
-/************************************************************************************
- * Name: uart_datareceived
- *
- * Description:
- * This function is called from uart_recvchars when new serial data is place in
- * the driver's circular buffer. This function will wake-up any stalled read()
- * operations that are waiting for incoming data.
- *
- ************************************************************************************/
-
-void uart_datareceived(FAR uart_dev_t *dev)
-{
- /* Is there a thread waiting for read data? */
-
- if (dev->recvwaiting)
- {
- /* Yes... wake it up */
-
- dev->recvwaiting = false;
- (void)sem_post(&dev->recvsem);
- }
-
- /* Notify all poll/select waiters that they can read from the recv buffer */
-
- uart_pollnotify(dev, POLLIN);
-
-}
-
-/************************************************************************************
- * Name: uart_datasent
- *
- * Description:
- * This function is called from uart_xmitchars after serial data has been sent,
- * freeing up some space in the driver's circular buffer. This function will
- * wake-up any stalled write() operations that was waiting for space to buffer
- * outgoing data.
- *
- ************************************************************************************/
-
-void uart_datasent(FAR uart_dev_t *dev)
-{
- /* Is there a thread waiting for space in xmit.buffer? */
-
- if (dev->xmitwaiting)
- {
- /* Yes... wake it up */
-
- dev->xmitwaiting = false;
- (void)sem_post(&dev->xmitsem);
- }
-
- /* Notify all poll/select waiters that they can write to xmit buffer */
-
- uart_pollnotify(dev, POLLOUT);
-}
-
-/************************************************************************************
- * Name: uart_connected
- *
- * Description:
- * Serial devices (like USB serial) can be removed. In that case, the "upper
- * half" serial driver must be informed that there is no longer a valid serial
- * channel associated with the driver.
- *
- * In this case, the driver will terminate all pending transfers wint ENOTCONN and
- * will refuse all further transactions while the "lower half" is disconnected.
- * The driver will continue to be registered, but will be in an unusable state.
- *
- * Conversely, the "upper half" serial driver needs to know when the serial
- * device is reconnected so that it can resume normal operations.
- *
- * Assumptions/Limitations:
- * This function may be called from an interrupt handler.
- *
- ************************************************************************************/
-
-#ifdef CONFIG_SERIAL_REMOVABLE
-void uart_connected(FAR uart_dev_t *dev, bool connected)
-{
- irqstate_t flags;
-
- /* Is the device disconnected? */
-
- flags = irqsave();
- dev->disconnected = !connected;
- if (!connected)
- {
- /* Yes.. wake up all waiting threads. Each thread should detect the
- * disconnection and return the ENOTCONN error.
- */
-
- /* Is there a thread waiting for space in xmit.buffer? */
-
- if (dev->xmitwaiting)
- {
- /* Yes... wake it up */
-
- dev->xmitwaiting = false;
- (void)sem_post(&dev->xmitsem);
- }
-
- /* Is there a thread waiting for read data? */
-
- if (dev->recvwaiting)
- {
- /* Yes... wake it up */
-
- dev->recvwaiting = false;
- (void)sem_post(&dev->recvsem);
- }
-
- /* Notify all poll/select waiters that and hangup occurred */
-
- uart_pollnotify(dev, (POLLERR|POLLHUP));
- }
-
- irqrestore(flags);
-}
-#endif
-
-
-
diff --git a/nuttx/drivers/serial/serialirq.c b/nuttx/drivers/serial/serialirq.c
deleted file mode 100644
index fda5b4afb..000000000
--- a/nuttx/drivers/serial/serialirq.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/************************************************************************************
- * drivers/serial/serialirq.c
- *
- * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <semaphore.h>
-#include <debug.h>
-#include <nuttx/serial/serial.h>
-
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-
-/************************************************************************************
- * Private Variables
- ************************************************************************************/
-
-/************************************************************************************
- * Private Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Public Functions
- ************************************************************************************/
-
-/************************************************************************************
- * Name: uart_xmitchars
- *
- * Description:
- * This function is called from the UART interrupt handler when an interrupt
- * is received indicating that there is more space in the transmit FIFO. This
- * function will send characters from the tail of the xmit buffer while the driver
- * write() logic adds data to the head of the xmit buffer.
- *
- ************************************************************************************/
-
-void uart_xmitchars(FAR uart_dev_t *dev)
-{
- uint16_t nbytes = 0;
-
- /* Send while we still have data & room in the fifo */
-
- while (dev->xmit.head != dev->xmit.tail && uart_txready(dev))
- {
- /* Send the next byte */
-
- uart_send(dev, dev->xmit.buffer[dev->xmit.tail]);
- nbytes++;
-
- /* Increment the tail index */
-
- if (++(dev->xmit.tail) >= dev->xmit.size)
- {
- dev->xmit.tail = 0;
- }
- }
-
- /* When all of the characters have been sent from the buffer disable the TX
- * interrupt.
- */
-
- if (dev->xmit.head == dev->xmit.tail)
- {
- uart_disabletxint(dev);
- }
-
- /* If any bytes were removed from the buffer, inform any waiters there there is
- * space available.
- */
-
- if (nbytes)
- {
- uart_datasent(dev);
- }
-}
-
-/************************************************************************************
- * Name: uart_receivechars
- *
- * Description:
- * This function is called from the UART interrupt handler when an interrupt
- * is received indicating that are bytes available in the receive fifo. This
- * function will add chars to head of receive buffer. Driver read() logic will
- * take characters from the tail of the buffer.
- *
- ************************************************************************************/
-
-void uart_recvchars(FAR uart_dev_t *dev)
-{
- unsigned int status;
- int nexthead = dev->recv.head + 1;
- uint16_t nbytes = 0;
-
- if (nexthead >= dev->recv.size)
- {
- nexthead = 0;
- }
-
- /* Loop putting characters into the receive buffer until either there are no
- * further characters to available.
- */
-
- while (uart_rxavailable(dev))
- {
- char ch = uart_receive(dev, &status);
-
- /* If the RX buffer becomes full, then the serial data is discarded. This is
- * necessary because on most serial hardware, you must read the data in order
- * to clear the RX interrupt. An option on some hardware might be to simply
- * disable RX interrupts until the RX buffer becomes non-FULL. However, that
- * would probably just cause the overrun to occur in hardware (unless it has
- * some large internal buffering).
- */
-
- if (nexthead != dev->recv.tail)
- {
- /* Add the character to the buffer */
-
- dev->recv.buffer[dev->recv.head] = ch;
- nbytes++;
-
- /* Increment the head index */
-
- dev->recv.head = nexthead;
- if (++nexthead >= dev->recv.size)
- {
- nexthead = 0;
- }
- }
- }
-
- /* If any bytes were added to the buffer, inform any waiters there there is new
- * incoming data available.
- */
-
- if (nbytes)
- {
- uart_datareceived(dev);
- }
-}
diff --git a/nuttx/drivers/serial/uart_16550.c b/nuttx/drivers/serial/uart_16550.c
deleted file mode 100644
index 8fb71bfd2..000000000
--- a/nuttx/drivers/serial/uart_16550.c
+++ /dev/null
@@ -1,1164 +0,0 @@
-/****************************************************************************
- * drivers/serial/uart_16550.c
- * Serial driver for 16550 UART
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <semaphore.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
-#include <nuttx/serial/serial.h>
-#include <nuttx/fs/ioctl.h>
-#include <nuttx/serial/uart_16550.h>
-
-#include <arch/board/board.h>
-
-#ifdef CONFIG_16550_UART
-
-/****************************************************************************
- * Pre-processor definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct u16550_s
-{
- uart_addrwidth_t uartbase; /* Base address of UART registers */
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- uint32_t baud; /* Configured baud */
- uint32_t uartclk; /* UART clock frequency */
-#endif
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- uart_datawidth_t ier; /* Saved IER value */
- uint8_t irq; /* IRQ associated with this UART */
-#endif
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- uint8_t parity; /* 0=none, 1=odd, 2=even */
- uint8_t bits; /* Number of bits (7 or 8) */
- bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */
-#endif
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int u16550_setup(struct uart_dev_s *dev);
-static void u16550_shutdown(struct uart_dev_s *dev);
-static int u16550_attach(struct uart_dev_s *dev);
-static void u16550_detach(struct uart_dev_s *dev);
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
-static int u16550_interrupt(int irq, void *context);
-#endif
-static int u16550_ioctl(struct file *filep, int cmd, unsigned long arg);
-static int u16550_receive(struct uart_dev_s *dev, uint32_t *status);
-static void u16550_rxint(struct uart_dev_s *dev, bool enable);
-static bool u16550_rxavailable(struct uart_dev_s *dev);
-static void u16550_send(struct uart_dev_s *dev, int ch);
-static void u16550_txint(struct uart_dev_s *dev, bool enable);
-static bool u16550_txready(struct uart_dev_s *dev);
-static bool u16550_txempty(struct uart_dev_s *dev);
-
-/****************************************************************************
- * Private Variables
- ****************************************************************************/
-
-struct uart_ops_s g_uart_ops =
-{
- .setup = u16550_setup,
- .shutdown = u16550_shutdown,
- .attach = u16550_attach,
- .detach = u16550_detach,
- .ioctl = u16550_ioctl,
- .receive = u16550_receive,
- .rxint = u16550_rxint,
- .rxavailable = u16550_rxavailable,
- .send = u16550_send,
- .txint = u16550_txint,
- .txready = u16550_txready,
- .txempty = u16550_txempty,
-};
-
-/* I/O buffers */
-
-#ifdef CONFIG_16550_UART0
-static char g_uart0rxbuffer[CONFIG_16550_UART0_RXBUFSIZE];
-static char g_uart0txbuffer[CONFIG_16550_UART0_TXBUFSIZE];
-#endif
-#ifdef CONFIG_16550_UART1
-static char g_uart1rxbuffer[CONFIG_16550_UART1_RXBUFSIZE];
-static char g_uart1txbuffer[CONFIG_16550_UART1_TXBUFSIZE];
-#endif
-#ifdef CONFIG_16550_UART2
-static char g_uart2rxbuffer[CONFIG_16550_UART2_RXBUFSIZE];
-static char g_uart2txbuffer[CONFIG_16550_UART2_TXBUFSIZE];
-#endif
-#ifdef CONFIG_16550_UART3
-static char g_uart3rxbuffer[CONFIG_16550_UART3_RXBUFSIZE];
-static char g_uart3txbuffer[CONFIG_16550_UART3_TXBUFSIZE];
-#endif
-
-/* This describes the state of the LPC17xx uart0 port. */
-
-#ifdef CONFIG_16550_UART0
-static struct u16550_s g_uart0priv =
-{
- .uartbase = CONFIG_16550_UART0_BASE,
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- .baud = CONFIG_16550_UART0_BAUD,
- .uartclk = CONFIG_16550_UART0_CLOCK,
-#endif
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- .irq = CONFIG_16550_UART0_IRQ,
-#endif
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- .parity = CONFIG_16550_UART0_PARITY,
- .bits = CONFIG_16550_UART0_BITS,
- .stopbits2 = CONFIG_16550_UART0_2STOP,
-#endif
-};
-
-static uart_dev_t g_uart0port =
-{
- .recv =
- {
- .size = CONFIG_16550_UART0_RXBUFSIZE,
- .buffer = g_uart0rxbuffer,
- },
- .xmit =
- {
- .size = CONFIG_16550_UART0_TXBUFSIZE,
- .buffer = g_uart0txbuffer,
- },
- .ops = &g_uart_ops,
- .priv = &g_uart0priv,
-};
-#endif
-
-/* This describes the state of the LPC17xx uart1 port. */
-
-#ifdef CONFIG_16550_UART1
-static struct u16550_s g_uart1priv =
-{
- .uartbase = CONFIG_16550_UART1_BASE,
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- .baud = CONFIG_16550_UART1_BAUD,
- .uartclk = CONFIG_16550_UART1_CLOCK,
-#endif
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- .irq = CONFIG_16550_UART1_IRQ,
-#endif
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- .parity = CONFIG_16550_UART1_PARITY,
- .bits = CONFIG_16550_UART1_BITS,
- .stopbits2 = CONFIG_16550_UART1_2STOP,
-#endif
-};
-
-static uart_dev_t g_uart1port =
-{
- .recv =
- {
- .size = CONFIG_16550_UART1_RXBUFSIZE,
- .buffer = g_uart1rxbuffer,
- },
- .xmit =
- {
- .size = CONFIG_16550_UART1_TXBUFSIZE,
- .buffer = g_uart1txbuffer,
- },
- .ops = &g_uart_ops,
- .priv = &g_uart1priv,
-};
-#endif
-
-/* This describes the state of the LPC17xx uart1 port. */
-
-#ifdef CONFIG_16550_UART2
-static struct u16550_s g_uart2priv =
-{
- .uartbase = CONFIG_16550_UART2_BASE,
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- .baud = CONFIG_16550_UART2_BAUD,
- .uartclk = CONFIG_16550_UART2_CLOCK,
-#endif
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- .irq = CONFIG_16550_UART2_IRQ,
-#endif
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- .parity = CONFIG_16550_UART2_PARITY,
- .bits = CONFIG_16550_UART2_BITS,
- .stopbits2 = CONFIG_16550_UART2_2STOP,
-#endif
-};
-
-static uart_dev_t g_uart2port =
-{
- .recv =
- {
- .size = CONFIG_16550_UART2_RXBUFSIZE,
- .buffer = g_uart2rxbuffer,
- },
- .xmit =
- {
- .size = CONFIG_16550_UART2_TXBUFSIZE,
- .buffer = g_uart2txbuffer,
- },
- .ops = &g_uart_ops,
- .priv = &g_uart2priv,
-};
-#endif
-
-/* This describes the state of the LPC17xx uart1 port. */
-
-#ifdef CONFIG_16550_UART3
-static struct u16550_s g_uart3priv =
-{
- .uartbase = CONFIG_16550_UART3_BASE,
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- .baud = CONFIG_16550_UART3_BAUD,
- .uartclk = CONFIG_16550_UART3_CLOCK,
-#endif
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- .irq = CONFIG_16550_UART3_IRQ,
-#endif
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- .parity = CONFIG_16550_UART3_PARITY,
- .bits = CONFIG_16550_UART3_BITS,
- .stopbits2 = CONFIG_16550_UART3_2STOP,
-#endif
-};
-
-static uart_dev_t g_uart3port =
-{
- .recv =
- {
- .size = CONFIG_16550_UART3_RXBUFSIZE,
- .buffer = g_uart3rxbuffer,
- },
- .xmit =
- {
- .size = CONFIG_16550_UART3_TXBUFSIZE,
- .buffer = g_uart3txbuffer,
- },
- .ops = &g_uart_ops,
- .priv = &g_uart3priv,
-};
-#endif
-
-/* Which UART with be tty0/console and which tty1? tty2? tty3? */
-
-#if defined(CONFIG_16550_UART0_SERIAL_CONSOLE)
-# define CONSOLE_DEV g_uart0port /* UART0=console */
-# define TTYS0_DEV g_uart0port /* UART0=ttyS0 */
-# ifdef CONFIG_16550_UART1
-# define TTYS1_DEV g_uart1port /* UART0=ttyS0;UART1=ttyS1 */
-# ifdef CONFIG_16550_UART2
-# define TTYS2_DEV g_uart2port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2 */
-# ifdef CONFIG_16550_UART3
-# define TTYS3_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2;UART3=ttyS3 */
-# else
-# undef TTYS3_DEV /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS;No ttyS3 */
-# endif
-# else
-# ifdef CONFIG_16550_UART3
-# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART3=ttys2;No ttyS3 */
-# else
-# undef TTYS2_DEV /* UART0=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS3_DEV /* No ttyS3 */
-# endif
-# else
-# ifdef CONFIG_16550_UART2
-# define TTYS1_DEV g_uart2port /* UART0=ttyS0;UART2=ttyS1;No ttyS3 */
-# ifdef CONFIG_16550_UART3
-# define TTYS2_DEV g_uart3port /* UART0=ttyS0;UART2=ttyS1;UART3=ttyS2;No ttyS3 */
-# else
-# undef TTYS2_DEV /* UART0=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS3_DEV /* No ttyS3 */
-# else
-# ifdef CONFIG_16550_UART3
-# define TTYS1_DEV g_uart3port /* UART0=ttyS0;UART3=ttyS1;No ttyS2;No ttyS3 */
-# else
-# undef TTYS1_DEV /* UART0=ttyS0;No ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS2_DEV /* No ttyS2 */
-# undef TTYS3_DEV /* No ttyS3 */
-# endif
-# endif
-#elif defined(CONFIG_16550_UART1_SERIAL_CONSOLE)
-# define CONSOLE_DEV g_uart1port /* UART1=console */
-# define TTYS0_DEV g_uart1port /* UART1=ttyS0 */
-# ifdef CONFIG_16550_UART
-# define TTYS1_DEV g_uart0port /* UART1=ttyS0;UART0=ttyS1 */
-# ifdef CONFIG_16550_UART2
-# define TTYS2_DEV g_uart2port /* UART1=ttyS0;UART0=ttyS1;UART2=ttyS2 */
-# ifdef CONFIG_16550_UART3
-# define TTYS3_DEV g_uart3port /* UART1=ttyS0;UART0=ttyS1;UART2=ttyS2;UART3=ttyS3 */
-# else
-# undef TTYS3_DEV /* UART1=ttyS0;UART0=ttyS1;UART2=ttyS;No ttyS3 */
-# endif
-# else
-# ifdef CONFIG_16550_UART3
-# define TTYS2_DEV g_uart3port /* UART1=ttyS0;UART0=ttyS1;UART3=ttys2;No ttyS3 */
-# else
-# undef TTYS2_DEV /* UART1=ttyS0;UART0=ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS3_DEV /* No ttyS3 */
-# endif
-# else
-# ifdef CONFIG_16550_UART2
-# define TTYS1_DEV g_uart2port /* UART1=ttyS0;UART2=ttyS1 */
-# ifdef CONFIG_16550_UART3
-# define TTYS2_DEV g_uart3port /* UART1=ttyS0;UART2=ttyS1;UART3=ttyS2;No ttyS3 */
-# else
-# undef TTYS2_DEV /* UART1=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS3_DEV /* No ttyS3 */
-# else
-# ifdef CONFIG_16550_UART3
-# define TTYS1_DEV g_uart3port /* UART1=ttyS0;UART3=ttyS1;No ttyS2;No ttyS3 */
-# else
-# undef TTYS1_DEV /* UART1=ttyS0;No ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS2_DEV /* No ttyS2 */
-# undef TTYS3_DEV /* No ttyS3 */
-# endif
-# endif
-#elif defined(CONFIG_16550_UART2_SERIAL_CONSOLE)
-# define CONSOLE_DEV g_uart2port /* UART2=console */
-# define TTYS0_DEV g_uart2port /* UART2=ttyS0 */
-# ifdef CONFIG_16550_UART
-# define TTYS1_DEV g_uart0port /* UART2=ttyS0;UART0=ttyS1 */
-# ifdef CONFIG_16550_UART1
-# define TTYS2_DEV g_uart1port /* UART2=ttyS0;UART0=ttyS1;UART1=ttyS2 */
-# ifdef CONFIG_16550_UART3
-# define TTYS3_DEV g_uart3port /* UART2=ttyS0;UART0=ttyS1;UART1=ttyS2;UART3=ttyS3 */
-# else
-# undef TTYS3_DEV /* UART2=ttyS0;UART0=ttyS1;UART1=ttyS;No ttyS3 */
-# endif
-# else
-# ifdef CONFIG_16550_UART3
-# define TTYS2_DEV g_uart3port /* UART2=ttyS0;UART0=ttyS1;UART3=ttys2;No ttyS3 */
-# else
-# undef TTYS2_DEV /* UART2=ttyS0;UART0=ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS3_DEV /* No ttyS3 */
-# endif
-# else
-# ifdef CONFIG_16550_UART1
-# define TTYS1_DEV g_uart1port /* UART2=ttyS0;UART1=ttyS1 */
-# ifdef CONFIG_16550_UART3
-# define TTYS2_DEV g_uart3port /* UART2=ttyS0;UART1=ttyS1;UART3=ttyS2 */
-# else
-# undef TTYS2_DEV /* UART2=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS3_DEV /* No ttyS3 */
-# else
-# ifdef CONFIG_16550_UART3
-# define TTYS1_DEV g_uart3port /* UART2=ttyS0;UART3=ttyS1;No ttyS3 */
-# else
-# undef TTYS1_DEV /* UART2=ttyS0;No ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS2_DEV /* No ttyS2 */
-# undef TTYS3_DEV /* No ttyS3 */
-# endif
-# endif
-#elif defined(CONFIG_16550_UART3_SERIAL_CONSOLE)
-# define CONSOLE_DEV g_uart3port /* UART3=console */
-# define TTYS0_DEV g_uart3port /* UART3=ttyS0 */
-# ifdef CONFIG_16550_UART
-# define TTYS1_DEV g_uart0port /* UART3=ttyS0;UART0=ttyS1 */
-# ifdef CONFIG_16550_UART1
-# define TTYS2_DEV g_uart1port /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS2 */
-# ifdef CONFIG_16550_UART2
-# define TTYS3_DEV g_uart2port /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS2;UART2=ttyS3 */
-# else
-# undef TTYS3_DEV /* UART3=ttyS0;UART0=ttyS1;UART1=ttyS;No ttyS3 */
-# endif
-# else
-# ifdef CONFIG_16550_UART2
-# define TTYS2_DEV g_uart2port /* UART3=ttyS0;UART0=ttyS1;UART2=ttys2;No ttyS3 */
-# else
-# undef TTYS2_DEV /* UART3=ttyS0;UART0=ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS3_DEV /* No ttyS3 */
-# endif
-# else
-# ifdef CONFIG_16550_UART1
-# define TTYS1_DEV g_uart1port /* UART3=ttyS0;UART1=ttyS1 */
-# ifdef CONFIG_16550_UART2
-# define TTYS2_DEV g_uart2port /* UART3=ttyS0;UART1=ttyS1;UART2=ttyS2;No ttyS3 */
-# else
-# undef TTYS2_DEV /* UART3=ttyS0;UART1=ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS3_DEV /* No ttyS3 */
-# else
-# ifdef CONFIG_16550_UART2
-# define TTYS1_DEV g_uart2port /* UART3=ttyS0;UART2=ttyS1;No ttyS3;No ttyS3 */
-# undef TTYS3_DEV /* UART3=ttyS0;UART2=ttyS1;No ttyS2;No ttyS3 */
-# else
-# undef TTYS1_DEV /* UART3=ttyS0;No ttyS1;No ttyS2;No ttyS3 */
-# endif
-# undef TTYS2_DEV /* No ttyS2 */
-# undef TTYS3_DEV /* No ttyS3 */
-# endif
-# endif
-#endif
-
-/************************************************************************************
- * Inline Functions
- ************************************************************************************/
-
-/****************************************************************************
- * Name: u16550_serialin
- ****************************************************************************/
-
-static inline uart_datawidth_t u16550_serialin(struct u16550_s *priv, int offset)
-{
- return uart_getreg(priv->uartbase, offset);
-}
-
-/****************************************************************************
- * Name: u16550_serialout
- ****************************************************************************/
-
-static inline void u16550_serialout(struct u16550_s *priv, int offset, uart_datawidth_t value)
-{
- uart_putreg(priv->uartbase, offset, value);
-}
-
-/****************************************************************************
- * Name: u16550_disableuartint
- ****************************************************************************/
-
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
-static inline void u16550_disableuartint(struct u16550_s *priv, uart_datawidth_t *ier)
-{
- if (ier)
- {
- *ier = priv->ier & UART_IER_ALLIE;
- }
-
- priv->ier &= ~UART_IER_ALLIE;
- u16550_serialout(priv, UART_IER_OFFSET, priv->ier);
-}
-#else
-# define u16550_disableuartint(priv,ier)
-#endif
-
-/****************************************************************************
- * Name: u16550_restoreuartint
- ****************************************************************************/
-
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
-static inline void u16550_restoreuartint(struct u16550_s *priv, uint32_t ier)
-{
- priv->ier |= ier & UART_IER_ALLIE;
- u16550_serialout(priv, UART_IER_OFFSET, priv->ier);
-}
-#else
-# define u16550_restoreuartint(priv,ier)
-#endif
-
-/****************************************************************************
- * Name: u16550_enablebreaks
- ****************************************************************************/
-
-static inline void u16550_enablebreaks(struct u16550_s *priv, bool enable)
-{
- uint32_t lcr = u16550_serialin(priv, UART_LCR_OFFSET);
- if (enable)
- {
- lcr |= UART_LCR_BRK;
- }
- else
- {
- lcr &= ~UART_LCR_BRK;
- }
- u16550_serialout(priv, UART_LCR_OFFSET, lcr);
-}
-
-/************************************************************************************
- * Name: u16550_divisor
- *
- * Descrption:
- * Select a divider to produce the BAUD from the UART_CLK.
- *
- * BAUD = UART_CLK / (16 * DL), or
- * DIV = UART_CLK / BAUD / 16
- *
- * Ignoring the fractional divider for now.
- *
- ************************************************************************************/
-
-#ifndef CONFIG_16550_SUPRESS_CONFIG
-static inline uint32_t u16550_divisor(struct u16550_s *priv)
-{
- return (priv->uartclk + (priv->baud << 3)) / (priv->baud << 4);
-}
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: u16550_setup
- *
- * Description:
- * Configure the UART baud, bits, parity, fifos, etc. This
- * method is called the first time that the serial port is
- * opened.
- *
- ****************************************************************************/
-
-static int u16550_setup(struct uart_dev_s *dev)
-{
-#ifndef CONFIG_16550_SUPRESS_CONFIG
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- uint16_t div;
- uint32_t lcr;
-
- /* Clear fifos */
-
- u16550_serialout(priv, UART_FCR_OFFSET, (UART_FCR_RXRST|UART_FCR_TXRST));
-
- /* Set trigger */
-
- u16550_serialout(priv, UART_FCR_OFFSET, (UART_FCR_FIFOEN|UART_FCR_RXTRIGGER_8));
-
- /* Set up the IER */
-
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- priv->ier = u16550_serialin(priv, UART_IER_OFFSET);
-#endif
-
- /* Set up the LCR */
-
- lcr = 0;
- switch (priv->bits)
- {
- case 5 :
- lcr |= UART_LCR_WLS_7BIT;
- break;
-
- case 6 :
- lcr |= UART_LCR_WLS_7BIT;
- break;
-
- case 7 :
- lcr |= UART_LCR_WLS_7BIT;
- break;
-
- default:
- case 8 :
- lcr |= UART_LCR_WLS_7BIT;
- break;
- }
-
- if (priv->stopbits2)
- {
- lcr |= UART_LCR_STB;
- }
-
- if (priv->parity == 1)
- {
- lcr |= UART_LCR_PEN;
- }
- else if (priv->parity == 2)
- {
- lcr |= (UART_LCR_PEN|UART_LCR_EPS);
- }
-
- /* Enter DLAB=1 */
-
- u16550_serialout(priv, UART_LCR_OFFSET, (lcr | UART_LCR_DLAB));
-
- /* Set the BAUD divisor */
-
- div = u16550_divisor(priv);
- u16550_serialout(priv, UART_DLM_OFFSET, div >> 8);
- u16550_serialout(priv, UART_DLL_OFFSET, div & 0xff);
-
- /* Clear DLAB */
-
- u16550_serialout(priv, UART_LCR_OFFSET, lcr);
-
- /* Configure the FIFOs */
-
- u16550_serialout(priv, UART_FCR_OFFSET,
- (UART_FCR_RXTRIGGER_8|UART_FCR_TXRST|UART_FCR_RXRST|UART_FCR_FIFOEN));
-#endif
- return OK;
-}
-
-/****************************************************************************
- * Name: u16550_shutdown
- *
- * Description:
- * Disable the UART. This method is called when the serial
- * port is closed
- *
- ****************************************************************************/
-
-static void u16550_shutdown(struct uart_dev_s *dev)
-{
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- u16550_disableuartint(priv, NULL);
-}
-
-/****************************************************************************
- * Name: u16550_attach
- *
- * Description:
- * Configure the UART to operation in interrupt driven mode. This method is
- * called when the serial port is opened. Normally, this is just after the
- * the setup() method is called, however, the serial console may operate in
- * a non-interrupt driven mode during the boot phase.
- *
- * RX and TX interrupts are not enabled when by the attach method (unless the
- * hardware supports multiple levels of interrupt enabling). The RX and TX
- * interrupts are not enabled until the txint() and rxint() methods are called.
- *
- ****************************************************************************/
-
-static int u16550_attach(struct uart_dev_s *dev)
-{
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- int ret;
-
- /* Attach and enable the IRQ */
-
- ret = irq_attach(priv->irq, u16550_interrupt);
-#ifndef CONFIG_ARCH_NOINTC
- if (ret == OK)
- {
- /* Enable the interrupt (RX and TX interrupts are still disabled
- * in the UART
- */
-
- up_enable_irq(priv->irq);
- }
-#endif
- return ret;
-#else
- return OK;
-#endif
-}
-
-/****************************************************************************
- * Name: u16550_detach
- *
- * Description:
- * Detach UART interrupts. This method is called when the serial port is
- * closed normally just before the shutdown method is called. The exception is
- * the serial console which is never shutdown.
- *
- ****************************************************************************/
-
-static void u16550_detach(struct uart_dev_s *dev)
-{
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
-#ifndef CONFIG_ARCH_NOINTC
- up_disable_irq(priv->irq);
-#endif
- irq_detach(priv->irq);
-#endif
-}
-
-/****************************************************************************
- * Name: u16550_interrupt
- *
- * Description:
- * This is the UART interrupt handler. It will be invoked when an
- * interrupt received on the 'irq' It should call uart_transmitchars or
- * uart_receivechar to perform the appropriate data transfers. The
- * interrupt handling logic must be able to map the 'irq' number into the
- * appropriate u16550_s structure in order to call these functions.
- *
- ****************************************************************************/
-
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
-static int u16550_interrupt(int irq, void *context)
-{
- struct uart_dev_s *dev = NULL;
- struct u16550_s *priv;
- uint32_t status;
- int passes;
-
-#ifdef CONFIG_16550_UART0
- if (g_uart0priv.irq == irq)
- {
- dev = &g_uart0port;
- }
- else
-#endif
-#ifdef CONFIG_16550_UART1
- if (g_uart1priv.irq == irq)
- {
- dev = &g_uart1port;
- }
- else
-#endif
-#ifdef CONFIG_16550_UART2
- if (g_uart2priv.irq == irq)
- {
- dev = &g_uart2port;
- }
- else
-#endif
-#ifdef CONFIG_16550_UART3
- if (g_uart3priv.irq == irq)
- {
- dev = &g_uart3port;
- }
-#endif
- ASSERT(dev != NULL);
- priv = (struct u16550_s*)dev->priv;
-
- /* Loop until there are no characters to be transferred or,
- * until we have been looping for a long time.
- */
-
- for (passes = 0; passes < 256; passes++)
- {
- /* Get the current UART status and check for loop
- * termination conditions
- */
-
- status = u16550_serialin(priv, UART_IIR_OFFSET);
-
- /* The UART_IIR_INTSTATUS bit should be zero if there are pending
- * interrupts
- */
-
- if ((status & UART_IIR_INTSTATUS) != 0)
- {
- /* Break out of the loop when there is no longer a
- * pending interrupt
- */
-
- break;
- }
-
- /* Handle the interrupt by its interrupt ID field */
-
- switch (status & UART_IIR_INTID_MASK)
- {
- /* Handle incoming, receive bytes (with or without timeout) */
-
- case UART_IIR_INTID_RDA:
- case UART_IIR_INTID_CTI:
- {
- uart_recvchars(dev);
- break;
- }
-
- /* Handle outgoing, transmit bytes */
-
- case UART_IIR_INTID_THRE:
- {
- uart_xmitchars(dev);
- break;
- }
-
- /* Just clear modem status interrupts (UART1 only) */
-
- case UART_IIR_INTID_MSI:
- {
- /* Read the modem status register (MSR) to clear */
-
- status = u16550_serialin(priv, UART_MSR_OFFSET);
- vdbg("MSR: %02x\n", status);
- break;
- }
-
- /* Just clear any line status interrupts */
-
- case UART_IIR_INTID_RLS:
- {
- /* Read the line status register (LSR) to clear */
-
- status = u16550_serialin(priv, UART_LSR_OFFSET);
- vdbg("LSR: %02x\n", status);
- break;
- }
-
- /* There should be no other values */
-
- default:
- {
- dbg("Unexpected IIR: %02x\n", status);
- break;
- }
- }
- }
-
- return OK;
-}
-#endif
-
-/****************************************************************************
- * Name: u16550_ioctl
- *
- * Description:
- * All ioctl calls will be routed through this method
- *
- ****************************************************************************/
-
-static int u16550_ioctl(struct file *filep, int cmd, unsigned long arg)
-{
- struct inode *inode = filep->f_inode;
- struct uart_dev_s *dev = inode->i_private;
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- int ret = OK;
-
- switch (cmd)
- {
- case TIOCSERGSTRUCT:
- {
- struct u16550_s *user = (struct u16550_s*)arg;
- if (!user)
- {
- set_errno(EINVAL);
- ret = ERROR;
- }
- else
- {
- memcpy(user, dev, sizeof(struct u16550_s));
- }
- }
- break;
-
- case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
- {
- irqstate_t flags = irqsave();
- u16550_enablebreaks(priv, true);
- irqrestore(flags);
- }
- break;
-
- case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
- {
- irqstate_t flags;
- flags = irqsave();
- u16550_enablebreaks(priv, false);
- irqrestore(flags);
- }
- break;
-
- default:
- set_errno(ENOTTY);
- ret = ERROR;
- break;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: u16550_receive
- *
- * Description:
- * Called (usually) from the interrupt level to receive one
- * character from the UART. Error bits associated with the
- * receipt are provided in the return 'status'.
- *
- ****************************************************************************/
-
-static int u16550_receive(struct uart_dev_s *dev, uint32_t *status)
-{
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- uint32_t rbr;
-
- *status = u16550_serialin(priv, UART_LSR_OFFSET);
- rbr = u16550_serialin(priv, UART_RBR_OFFSET);
- return rbr;
-}
-
-/****************************************************************************
- * Name: u16550_rxint
- *
- * Description:
- * Call to enable or disable RX interrupts
- *
- ****************************************************************************/
-
-static void u16550_rxint(struct uart_dev_s *dev, bool enable)
-{
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- if (enable)
- {
- priv->ier |= UART_IER_ERBFI;
- }
- else
- {
- priv->ier &= ~UART_IER_ERBFI;
- }
- u16550_serialout(priv, UART_IER_OFFSET, priv->ier);
-#endif
-}
-
-/****************************************************************************
- * Name: u16550_rxavailable
- *
- * Description:
- * Return true if the receive fifo is not empty
- *
- ****************************************************************************/
-
-static bool u16550_rxavailable(struct uart_dev_s *dev)
-{
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- return ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_DR) != 0);
-}
-
-/****************************************************************************
- * Name: u16550_send
- *
- * Description:
- * This method will send one byte on the UART
- *
- ****************************************************************************/
-
-static void u16550_send(struct uart_dev_s *dev, int ch)
-{
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- u16550_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch);
-}
-
-/****************************************************************************
- * Name: u16550_txint
- *
- * Description:
- * Call to enable or disable TX interrupts
- *
- ****************************************************************************/
-
-static void u16550_txint(struct uart_dev_s *dev, bool enable)
-{
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- irqstate_t flags;
-
- flags = irqsave();
- if (enable)
- {
- priv->ier |= UART_IER_ETBEI;
- u16550_serialout(priv, UART_IER_OFFSET, priv->ier);
-
- /* Fake a TX interrupt here by just calling uart_xmitchars() with
- * interrupts disabled (note this may recurse).
- */
-
- uart_xmitchars(dev);
- }
- else
- {
- priv->ier &= ~UART_IER_ETBEI;
- u16550_serialout(priv, UART_IER_OFFSET, priv->ier);
- }
-
- irqrestore(flags);
-#endif
-}
-
-/****************************************************************************
- * Name: u16550_txready
- *
- * Description:
- * Return true if the tranmsit fifo is not full
- *
- ****************************************************************************/
-
-static bool u16550_txready(struct uart_dev_s *dev)
-{
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- return ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0);
-}
-
-/****************************************************************************
- * Name: u16550_txempty
- *
- * Description:
- * Return true if the transmit fifo is empty
- *
- ****************************************************************************/
-
-static bool u16550_txempty(struct uart_dev_s *dev)
-{
- struct u16550_s *priv = (struct u16550_s*)dev->priv;
- return ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0);
-}
-
-/****************************************************************************
- * Name: u16550_putc
- *
- * Description:
- * Write one character to the UART (polled)
- *
- ****************************************************************************/
-
-static void u16550_putc(struct u16550_s *priv, int ch)
-{
- while ((u16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0);
- u16550_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch);
-}
-
-/****************************************************************************
- * Public Funtions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: up_earlyserialinit
- *
- * Description:
- * Performs the low level UART initialization early in debug so that the
- * serial console will be available during bootup. This must be called
- * before uart_serialinit.
- *
- * NOTE: Configuration of the CONSOLE UART was performed by uart_lowsetup()
- * very early in the boot sequence.
- *
- ****************************************************************************/
-
-void up_earlyserialinit(void)
-{
- /* Configure all UARTs (except the CONSOLE UART) and disable interrupts */
-
-#ifdef CONFIG_16550_UART0
- u16550_disableuartint(&g_uart0priv, NULL);
-#endif
-#ifdef CONFIG_16550_UART1
- u16550_disableuartint(&g_uart1priv, NULL);
-#endif
-#ifdef CONFIG_16550_UART2
- u16550_disableuartint(&g_uart2priv, NULL);
-#endif
-#ifdef CONFIG_16550_UART3
- u16550_disableuartint(&g_uart3priv, NULL);
-#endif
-
- /* Configuration whichever one is the console */
-
-#ifdef CONSOLE_DEV
- CONSOLE_DEV.isconsole = true;
- u16550_setup(&CONSOLE_DEV);
-#endif
-}
-
-/****************************************************************************
- * Name: up_serialinit
- *
- * Description:
- * Register serial console and serial ports. This assumes that
- * up_earlyserialinit was called previously.
- *
- ****************************************************************************/
-
-void up_serialinit(void)
-{
-#ifdef CONSOLE_DEV
- (void)uart_register("/dev/console", &CONSOLE_DEV);
-#endif
-#ifdef TTYS0_DEV
- (void)uart_register("/dev/ttyS0", &TTYS0_DEV);
-#endif
-#ifdef TTYS1_DEV
- (void)uart_register("/dev/ttyS1", &TTYS1_DEV);
-#endif
-#ifdef TTYS2_DEV
- (void)uart_register("/dev/ttyS2", &TTYS2_DEV);
-#endif
-#ifdef TTYS3_DEV
- (void)uart_register("/dev/ttyS3", &TTYS3_DEV);
-#endif
-}
-
-/****************************************************************************
- * Name: up_putc
- *
- * Description:
- * Provide priority, low-level access to support OS debug writes
- *
- ****************************************************************************/
-
-#ifdef HAVE_16550_CONSOLE
-int up_putc(int ch)
-{
- struct u16550_s *priv = (struct u16550_s*)CONSOLE_DEV.priv;
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- uart_datawidth_t ier;
-
- u16550_disableuartint(priv, &ier);
-#endif
-
- /* Check for LF */
-
- if (ch == '\n')
- {
- /* Add CR */
-
- u16550_putc(priv, '\r');
- }
-
- u16550_putc(priv, ch);
-#ifndef CONFIG_SUPPRESS_SERIAL_INTS
- u16550_restoreuartint(priv, ier);
-#endif
- return ch;
-}
-#endif
-
-#endif /* CONFIG_16550_UART */
diff --git a/nuttx/drivers/syslog/Kconfig b/nuttx/drivers/syslog/Kconfig
deleted file mode 100644
index 3ec8c7490..000000000
--- a/nuttx/drivers/syslog/Kconfig
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-comment "System Logging"
-
-config RAMLOG
- bool "RAM log device support"
- default n
- ---help---
- This is a driver that was intended to support debugging output,
- aka syslogging, when the normal serial output is not available.
- For example, if you are using a telnet or USB serial console,
- the debug output will get lost. However, the RAMLOG device should
- be usable even if system logging is disabled.
-
- This driver is similar to a pipe in that it saves the debugging
- output in a FIFO in RAM. It differs from a pipe in numerous
- details as needed to support logging.
-
-if RAMLOG
-config RAMLOG_SYSLOG
- bool "Use RAMLOG for SYSLOG"
- default n
- depends on SYSLOG
- ---help---
- Use the RAM logging device for the syslogging interface. If this feature
- is enabled (along with SYSLOG), then all debug output (only) will be re-directed
- to the circular buffer in RAM. This RAM log can be view from NSH using the
- 'dmesg'command.
-
- Do not enable more than one SYSLOG device.
-
-config RAMLOG_CONSOLE
- bool "Use RAMLOG for /dev/console"
- default n
- depends on DEV_CONSOLE
- ---help---
- Use the RAM logging device as a system console. If this feature is enabled (along
- with DEV_CONSOLE), then all console output will be re-directed to a circular
- buffer in RAM. This is useful, for example, if the only console is a Telnet
- console. Then in that case, console output from non-Telnet threads will go to
- the circular buffer and can be viewed using the NSH 'dmesg' command.
-
-config RAMLOG_CONSOLE_BUFSIZE
- int "RAMLOG buffer size"
- default 1024
- depends on RAMLOG_SYSLOG || RAMLOG_CONSOLE
- ---help---
- Size of the console RAM log. Default: 1024
-
-config RAMLOG_CRLF
- bool "RAMLOG CR/LF"
- default n
- ---help---
- Pre-pend a carriage return before every linefeed that goes into the RAM log.
-
-config RAMLOG_NONBLOCKING
- bool "RAMLOG non-block reads"
- default y
- ---help---
- Reading from the RAMLOG will never block if the RAMLOG is empty. If the RAMLOG
- is empty, then zero is returned (usually interpreted as end-of-file).
-
-config RAMLOG_NPOLLWAITERS
- int "RAMLOG number of poll waiters"
- default 4
- depends on !DISABLE_POLL
- ---help---
- The maximum number of threads that may be waiting on the poll method.
-
-endif
diff --git a/nuttx/drivers/syslog/Make.defs b/nuttx/drivers/syslog/Make.defs
deleted file mode 100644
index aa0ab19b8..000000000
--- a/nuttx/drivers/syslog/Make.defs
+++ /dev/null
@@ -1,68 +0,0 @@
-############################################################################
-# drivers/syslog/Make.defs
-# These drivers support system logging devices
-#
-# Copyright (C) 2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-# Include SYSLOG drivers (only one should be enabled)
-
-ifeq ($(CONFIG_SYSLOG),y)
-
-# If no special loggin devices are implemented, then the default SYSLOG
-# logic at fs/fs_syslog.c will be used
-
-# (Add other SYSLOG drivers here)
-
-ifeq ($(CONFIG_RAMLOG),y)
- CSRCS += ramlog.c
-endif
-
-# Include SYSLOG build support
-
-DEPPATH += --dep-path syslog
-VPATH += :syslog
-
-else
-
-# The RAMLOG can be used even if system logging is not enabled.
-
-ifeq ($(CONFIG_RAMLOG),y)
-
-# Include RAMLOG build support
-
-CSRCS += ramlog.c
-DEPPATH += --dep-path syslog
-VPATH += :syslog
-
-endif
-endif
diff --git a/nuttx/drivers/syslog/README.txt b/nuttx/drivers/syslog/README.txt
deleted file mode 100644
index bfef73ae8..000000000
--- a/nuttx/drivers/syslog/README.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-drivers/syslog README File
-==========================
-
-This README file discusses the SYLOG drivers that can be found in the
-drivers/syslog directory. In NuttX, syslog output is equivalent to
-debug output and, therefore, the syslogging interfaces are defined in the
-header file include/debug.h.
-
-By default, all system log output goes to console (/dev/console). But that
-behavior can be changed by the defining CONFIG_SYSLOG in the NuttX
-configuration. In that, case all low-level debug output will go through
-syslog_putc().
-
-One version of syslog_putc() is defined in fs/fs_syslog.c; that version is
-used when CONFIG_SYSLOG_CHAR is defined. That version of syslog_putc()
-just integrates with the file system to re-direct debug output to a
-character device or to a file. A disadvantage of using the generic character
-device for the SYSLOG is that it cannot handle debug output generated from
-interrupt level handles.
-
-If CONFIG_SYSLOG_CHAR is not defined, then other custom SYSLOG drivers
-can be used. These custom SYSLOG drivers can do things like handle
-unusual logging media and since they can avoid the general file system
-interfaces, can be designed to support debug output from interrupt handlers.
-
-Those custom SYSLOG drivers reside in this directory.
-
-ramlog.c
---------
- The RAM logging driver is a driver that was intended to support debugging
- output (syslogging) when the normal serial output is not available. For
- example, if you are using a telnet or USB serial console, the debug
- output will get lost.
-
- The RAM logging driver is similar to a pipe in that it saves the
- debugging output in a FIFO in RAM. It differs from a pipe in numerous
- details as needed to support logging.
-
- This driver is built when CONFIG_RAMLOG is defined in the Nuttx
- configuration.
-
- Configuration options:
-
- CONFIG_RAMLOG - Enables the RAM logging feature
- CONFIG_RAMLOG_CONSOLE - Use the RAM logging device as a system console.
- If this feature is enabled (along with CONFIG_DEV_CONSOLE), then all
- console output will be re-directed to a circular buffer in RAM. This
- is useful, for example, if the only console is a Telnet console. Then
- in that case, console output from non-Telnet threads will go to the
- circular buffer and can be viewed using the NSH 'dmesg' command.
- CONFIG_RAMLOG_SYSLOG - Use the RAM logging device for the syslogging
- interface. If this feature is enabled (along with CONFIG_SYSLOG),
- then all debug output (only) will be re-directed to the circular
- buffer in RAM. This RAM log can be view from NSH using the 'dmesg'
- command. NOTE: Unlike the limited, generic character driver SYSLOG
- device, the RAMLOG *can* be used to generate debug output from interrupt
- level handlers.
- CONFIG_RAMLOG_NPOLLWAITERS - The number of threads than can be waiting
- for this driver on poll(). Default: 4
-
- If CONFIG_RAMLOG_CONSOLE or CONFIG_RAMLOG_SYSLOG is selected, then the
- following may also be provided:
-
- CONFIG_RAMLOG_CONSOLE_BUFSIZE - Size of the console RAM log. Default: 1024
diff --git a/nuttx/drivers/syslog/ramlog.c b/nuttx/drivers/syslog/ramlog.c
deleted file mode 100644
index 08bbbfb59..000000000
--- a/nuttx/drivers/syslog/ramlog.c
+++ /dev/null
@@ -1,770 +0,0 @@
-/****************************************************************************
- * drivers/syslog/ramlog.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <string.h>
-#include <poll.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/arch.h>
-#include <nuttx/ramlog.h>
-
-#include <arch/irq.h>
-
-#ifdef CONFIG_RAMLOG
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct ramlog_dev_s
-{
-#ifndef CONFIG_RAMLOG_NONBLOCKING
- volatile uint8_t rl_nwaiters; /* Number of threads waiting for data */
-#endif
- volatile uint16_t rl_head; /* The head index (where data is added) */
- volatile uint16_t rl_tail; /* The tail index (where data is removed) */
- sem_t rl_exclsem; /* Enforces mutually exclusive access */
-#ifndef CONFIG_RAMLOG_NONBLOCKING
- sem_t rl_waitsem; /* Used to wait for data */
-#endif
- size_t rl_bufsize; /* Size of the RAM buffer */
- FAR char *rl_buffer; /* Circular RAM buffer */
-
- /* The following is a list if poll structures of threads waiting for
- * driver events. The 'struct pollfd' reference for each open is also
- * retained in the f_priv field of the 'struct file'.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- struct pollfd *rl_fds[CONFIG_RAMLOG_NPOLLWAITERS];
-#endif
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-/* Helper functions */
-
-#ifndef CONFIG_DISABLE_POLL
-static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv,
- pollevent_t eventset);
-#endif
-static ssize_t ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch);
-
-/* Character driver methods */
-
-static ssize_t ramlog_read(FAR struct file *, FAR char *, size_t);
-static ssize_t ramlog_write(FAR struct file *, FAR const char *, size_t);
-#ifndef CONFIG_DISABLE_POLL
-static int ramlog_poll(FAR struct file *filep, FAR struct pollfd *fds,
- bool setup);
-#endif
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations g_ramlogfops =
-{
- 0, /* open */
- 0, /* close */
- ramlog_read, /* read */
- ramlog_write, /* write */
- 0, /* seek */
- 0 /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , ramlog_poll /* poll */
-#endif
-};
-
-/* This is the pre-allocated buffer used for the console RAM log and/or
- * for the syslogging function.
- */
-
-#if defined(CONFIG_RAMLOG_CONSOLE) || defined(CONFIG_RAMLOG_SYSLOG)
-static char g_sysbuffer[CONFIG_RAMLOG_CONSOLE_BUFSIZE];
-
-/* This is the device structure for the console or syslogging function. It
- * must be statically initialized because the RAMLOG syslog_putc function
- * could be called before the driver initialization logic executes.
- */
-
-static struct ramlog_dev_s g_sysdev =
-{
-#ifndef CONFIG_RAMLOG_NONBLOCKING
- 0, /* rl_nwaiters */
-#endif
- 0, /* rl_head */
- 0, /* rl_tail */
- SEM_INITIALIZER(1), /* rl_exclsem */
-#ifndef CONFIG_RAMLOG_NONBLOCKING
- SEM_INITIALIZER(0), /* rl_waitsem */
-#endif
- CONFIG_RAMLOG_CONSOLE_BUFSIZE, /* rl_bufsize */
- g_sysbuffer /* rl_buffer */
-};
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: ramlog_pollnotify
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv,
- pollevent_t eventset)
-{
- FAR struct pollfd *fds;
- irqstate_t flags;
- int i;
-
- /* This function may be called from an interrupt handler */
-
- for (i = 0; i < CONFIG_RAMLOG_NPOLLWAITERS; i++)
- {
- flags = irqsave();
- fds = priv->rl_fds[i];
- if (fds)
- {
- fds->revents |= (fds->events & eventset);
- if (fds->revents != 0)
- {
- sem_post(fds->sem);
- }
- }
- irqrestore(flags);
- }
-}
-#else
-# define ramlog_pollnotify(priv,event)
-#endif
-
-/****************************************************************************
- * Name: ramlog_addchar
- ****************************************************************************/
-
-static int ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch)
-{
- irqstate_t flags;
- int nexthead;
-
- /* Disable interrupts (in case we are NOT called from interrupt handler) */
-
- flags = irqsave();
-
- /* Calculate the write index AFTER the next byte is written */
-
- nexthead = priv->rl_head + 1;
- if (nexthead >= priv->rl_bufsize)
- {
- nexthead = 0;
- }
-
- /* Would the next write overflow the circular buffer? */
-
- if (nexthead == priv->rl_tail)
- {
- /* Yes... Return an indication that nothing was saved in the buffer. */
-
- irqrestore(flags);
- return -EBUSY;
- }
-
- /* No... copy the byte and re-enable interrupts */
-
- priv->rl_buffer[priv->rl_head] = ch;
- priv->rl_head = nexthead;
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Name: ramlog_read
- ****************************************************************************/
-
-static ssize_t ramlog_read(FAR struct file *filep, FAR char *buffer, size_t len)
-{
- struct inode *inode = filep->f_inode;
- struct ramlog_dev_s *priv;
- ssize_t nread;
- char ch;
- int ret;
-
- /* Some sanity checking */
-
- DEBUGASSERT(inode && inode->i_private);
- priv = inode->i_private;
-
- /* If the circular buffer is empty, then wait for something to be written
- * to it. This function may NOT be called from an interrupt handler.
- */
-
- DEBUGASSERT(!up_interrupt_context());
-
- /* Get exclusive access to the rl_tail index */
-
- ret = sem_wait(&priv->rl_exclsem);
- if (ret < 0)
- {
- return ret;
- }
-
- /* Loop until something is read */
-
- for (nread = 0; nread < len; )
- {
- /* Get the next byte from the buffer */
-
- if (priv->rl_head == priv->rl_tail)
- {
- /* The circular buffer is empty. */
-
-#ifdef CONFIG_RAMLOG_NONBLOCKING
- /* Return what we have (with zero mean the end-of-file) */
-
- break;
-#else
- /* Did we read anything? */
-
- if (nread > 0)
- {
- /* Yes.. re-enable interrupts and the break out to return what
- * we have.
- */
-
- break;
- }
-
- /* If the driver was opened with O_NONBLOCK option, then don't wait.
- * Re-enable interrupts and return EGAIN.
- */
-
- if (filep->f_oflags & O_NONBLOCK)
- {
- nread = -EAGAIN;
- break;
- }
-
- /* Otherwise, wait for something to be written to the circular
- * buffer. Increment the number of waiters so that the ramlog_write()
- * will not that it needs to post the semaphore to wake us up.
- */
-
- sched_lock();
- priv->rl_nwaiters++;
- sem_post(&priv->rl_exclsem);
-
- /* We may now be pre-empted! But that should be okay because we
- * have already incremented nwaiters. Pre-emptions is disabled
- * but will be re-enabled while we are waiting.
- */
-
- ret = sem_wait(&priv->rl_waitsem);
-
- /* Interrupts will be disabled when we return. So the decrementing
- * rl_nwaiters here is safe.
- */
-
- priv->rl_nwaiters--;
- sched_unlock();
-
- /* Did we successfully get the rl_waitsem? */
-
- if (ret >= 0)
- {
- /* Yes... then retake the mutual exclusion semaphore */
-
- ret = sem_wait(&priv->rl_exclsem);
- }
-
- /* Was the semaphore wait successful? Did we successful re-take the
- * mutual exclusion semaphore?
- */
-
- if (ret < 0)
- {
- /* No.. One of the two sem_wait's failed. */
-
- int errval = errno;
-
- /* Were we awakened by a signal? Did we read anything before
- * we received the signal?
- */
-
- if (errval != EINTR || nread >= 0)
- {
- /* Yes.. return the error. */
-
- nread = -errval;
- }
-
- /* Break out to return what we have. Note, we can't exactly
- * "break" out because whichever error occurred, we do not hold
- * the exclusion semaphore.
- */
-
- goto errout_without_sem;
- }
-#endif /* CONFIG_RAMLOG_NONBLOCKING */
- }
- else
- {
- /* The circular buffer is not empty, get the next byte from the
- * tail index.
- */
-
- ch = priv->rl_buffer[priv->rl_tail];
-
- /* Increment the tail index and re-enable interrupts */
-
- if (++priv->rl_tail >= priv->rl_bufsize)
- {
- priv->rl_tail = 0;
- }
-
- /* Add the character to the user buffer */
-
- buffer[nread] = ch;
- nread++;
- }
- }
-
- /* Relinquish the mutual exclusion semaphore */
-
- sem_post(&priv->rl_exclsem);
-
- /* Notify all poll/select waiters that they can write to the FIFO */
-
-#ifndef CONFIG_RAMLOG_NONBLOCKING
-errout_without_sem:
-#endif
-
-#ifndef CONFIG_DISABLE_POLL
- if (nread > 0)
- {
- ramlog_pollnotify(priv, POLLOUT);
- }
-#endif
-
- /* Return the number of characters actually read */
-
- return nread;
-}
-
-/****************************************************************************
- * Name: ramlog_write
- ****************************************************************************/
-
-static ssize_t ramlog_write(FAR struct file *filep, FAR const char *buffer, size_t len)
-{
- struct inode *inode = filep->f_inode;
- struct ramlog_dev_s *priv;
- ssize_t nwritten;
- char ch;
- int ret;
-
- /* Some sanity checking */
-
- DEBUGASSERT(inode && inode->i_private);
- priv = inode->i_private;
-
- /* Loop until all of the bytes have been written. This function may be
- * called from an interrupt handler! Semaphores cannot be used!
- *
- * The write logic only needs to modify the rl_head index. Therefore,
- * there is a difference in the way that rl_head and rl_tail are protected:
- * rl_tail is protected with a semaphore; rl_tail is protected by disabling
- * interrupts.
- */
-
- for (nwritten = 0; nwritten < len; nwritten++)
- {
- /* Get the next character to output */
-
- ch = buffer[nwritten];
-
- /* Ignore carriage returns */
-
-#ifdef CONFIG_RAMLOG_CRLF
- if (ch == '\r')
- {
- continue;
- }
-
- /* Pre-pend a carriage before a linefeed */
-
- if (ch == '\n')
- {
- ret = ramlog_addchar(priv, '\r');
- if (ret < 0)
- {
- /* The buffer is full and nothing was saved. Break out of the
- * loop to return the number of bytes written up to this point.
- * The data to be written is dropped on the floor.
- */
-
- break;
- }
- }
-#endif
-
- /* Then output the character */
-
- ret = ramlog_addchar(priv,ch);
- if (ret < 0)
- {
- /* The buffer is full and nothing was saved. Break out of the
- * loop to return the number of bytes written up to this point.
- * The data to be written is dropped on the floor.
- */
-
- break;
- }
- }
-
- /* Was anything written? */
-
-#if !defined(CONFIG_RAMLOG_NONBLOCKING) || !defined(CONFIG_DISABLE_POLL)
- if (nwritten > 0)
- {
- irqstate_t flags;
-#ifndef CONFIG_RAMLOG_NONBLOCKING
- int i;
-#endif
-
- /* Are there threads waiting for read data? */
-
- flags = irqsave();
-#ifndef CONFIG_RAMLOG_NONBLOCKING
- for (i = 0; i < priv->rl_nwaiters; i++)
- {
- /* Yes.. Notify all of the waiting readers that more data is available */
-
- sem_post(&priv->rl_waitsem);
- }
-#endif
-
- /* Notify all poll/select waiters that they can write to the FIFO */
-
- ramlog_pollnotify(priv, POLLIN);
- irqrestore(flags);
- }
-#endif
-
- /* We always have to return the number of bytes requested and NOT the
- * number of bytes that were actually written. Otherwise, callers
- * will think that this is a short write and probably retry (causing
- */
-
- return len;
-}
-
-/****************************************************************************
- * Name: ramlog_poll
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-int ramlog_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct ramlog_dev_s *priv;
- pollevent_t eventset;
- int ndx;
- int ret;
- int i;
-
- /* Some sanity checking */
-
- DEBUGASSERT(inode && inode->i_private);
- priv = inode->i_private;
-
- /* Get exclusive access to the poll structures */
-
- ret = sem_wait(&priv->rl_exclsem);
- if (ret < 0)
- {
- int errval = errno;
- return -errval;
- }
-
- /* Are we setting up the poll? Or tearing it down? */
-
- if (setup)
- {
- /* This is a request to set up the poll. Find an available
- * slot for the poll structure reference
- */
-
- for (i = 0; i < CONFIG_RAMLOG_NPOLLWAITERS; i++)
- {
- /* Find an available slot */
-
- if (!priv->rl_fds[i])
- {
- /* Bind the poll structure and this slot */
-
- priv->rl_fds[i] = fds;
- fds->priv = &priv->rl_fds[i];
- break;
- }
- }
-
- if (i >= CONFIG_RAMLOG_NPOLLWAITERS)
- {
- fds->priv = NULL;
- ret = -EBUSY;
- goto errout;
- }
-
- /* Should immediately notify on any of the requested events?
- * First, check if the xmit buffer is full.
- */
-
- eventset = 0;
-
- ndx = priv->rl_head + 1;
- if (ndx >= priv->rl_bufsize)
- {
- ndx = 0;
- }
-
- if (ndx != priv->rl_tail)
- {
- eventset |= POLLOUT;
- }
-
- /* Check if the receive buffer is empty */
-
- if (priv->rl_head != priv->rl_tail)
- {
- eventset |= POLLIN;
- }
-
- if (eventset)
- {
- ramlog_pollnotify(priv, eventset);
- }
-
- }
- else if (fds->priv)
- {
- /* This is a request to tear down the poll. */
-
- struct pollfd **slot = (struct pollfd **)fds->priv;
-
-#ifdef CONFIG_DEBUG
- if (!slot)
- {
- ret = -EIO;
- goto errout;
- }
-#endif
-
- /* Remove all memory of the poll setup */
-
- *slot = NULL;
- fds->priv = NULL;
- }
-
-errout:
- sem_post(&priv->rl_exclsem);
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: ramlog_register
- *
- * Description:
- * Create the RAM logging device and register it at the specified path.
- * Mostly likely this path will be /dev/console
- *
- ****************************************************************************/
-
-#if !defined(CONFIG_RAMLOG_CONSOLE) && !defined(CONFIG_RAMLOG_SYSLOG)
-int ramlog_register(FAR const char *devpath, FAR char *buffer, size_t buflen)
-{
- FAR struct ramlog_dev_s *priv;
- int ret = -ENOMEM;
-
- /* Sanity checking */
-
- DEBUGASSERT(devpath && buffer && buflen > 1);
-
- /* Allocate a RAM logging device structure */
-
- priv = (struct ramlog_dev_s *)kzalloc(sizeof(struct ramlog_dev_s));
- if (priv)
- {
- /* Initialize the non-zero values in the RAM logging device structure */
-
- sem_init(&priv->rl_exclsem, 0, 1);
-#ifndef CONFIG_RAMLOG_NONBLOCKING
- sem_init(&priv->rl_waitsem, 0, 0);
-#endif
- priv->rl_bufsize = buflen;
- priv->rl_buffer = buffer;
-
- /* Register the character driver */
-
- ret = register_driver(devpath, &g_ramlogfops, 0666, priv);
- if (ret < 0)
- {
- kfree(priv);
- }
- }
-
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Name: ramlog_consoleinit
- *
- * Description:
- * Create the RAM logging device and register it at the specified path.
- * Mostly likely this path will be /dev/console
- *
- ****************************************************************************/
-
-#ifdef CONFIG_RAMLOG_CONSOLE
-int ramlog_consoleinit(void)
-{
- FAR struct ramlog_dev_s *priv = &g_sysdev;
- int ret;
-
- /* Register the console character driver */
-
- ret = register_driver("/dev/console", &g_ramlogfops, 0666, priv);
-}
-#endif
-
-/****************************************************************************
- * Name: ramlog_sysloginit
- *
- * Description:
- * Create the RAM logging device and register it at the specified path.
- * Mostly likely this path will be CONFIG_RAMLOG_SYSLOG
- *
- * If CONFIG_RAMLOG_CONSOLE is also defined, then this functionality is
- * performed when ramlog_consoleinit() is called.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_RAMLOG_SYSLOG
-int ramlog_sysloginit(void)
-{
- /* Register the syslog character driver */
-
- return register_driver(CONFIG_SYSLOG_DEVPATH, &g_ramlogfops, 0666, &g_sysdev);
-}
-#endif
-
-/****************************************************************************
- * Name: syslog_putc
- *
- * Description:
- * This is the low-level system logging interface. The debugging/syslogging
- * interfaces are syslog() and lowsyslog(). The difference is that
- * the syslog() internface writes to fd=1 (stdout) whereas lowsyslog() uses
- * a lower level interface that works from interrupt handlers. This
- * function is a a low-level interface used to implement lowsyslog()
- * when CONFIG_RAMLOG_SYSLOG=y and CONFIG_SYSLOG=y
- *
- ****************************************************************************/
-
-#if defined(CONFIG_RAMLOG_CONSOLE) || defined(CONFIG_RAMLOG_SYSLOG)
-int syslog_putc(int ch)
-{
- FAR struct ramlog_dev_s *priv = &g_sysdev;
- int ret;
-
- /* Ignore carriage returns */
-
-#ifdef CONFIG_RAMLOG_CRLF
- if (ch == '\r')
- {
- return ch;
- }
-
- /* Pre-pend a newline with a carriage return */
-
- if (ch == '\n')
- {
- ret = ramlog_addchar(priv, '\r');
- if (ret < 0)
- {
- /* The buffer is full and nothing was saved. */
-
- return ch;
- }
- }
-#endif
-
- (void)ramlog_addchar(priv, ch);
- return ch;
-}
-#endif
-
-#endif /* CONFIG_RAMLOG */
diff --git a/nuttx/drivers/usbdev/Kconfig b/nuttx/drivers/usbdev/Kconfig
deleted file mode 100644
index 0752bb791..000000000
--- a/nuttx/drivers/usbdev/Kconfig
+++ /dev/null
@@ -1,513 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-menu "Device Controller Driver Options"
-
-config USBDEV_ISOCHRONOUS
- bool "Enable isochronous"
- default n
- ---help---
- Build in extra support for isochronous endpoints
-
-config USBDEV_DUALSPEED
- bool "Enable high and full speed"
- default n
- ---help---
- Hardware handles high and full speed operation (USB 2.0)
-
-choice USBDEV_POWERED
- prompt "Select USB device powered"
- default USBDEV_SELFPOWERED
-
-config USBDEV_SELFPOWERED
- bool "Self powered"
- ---help---
- Will cause USB features to indicate that the device is self-powered
-
-config USBDEV_BUSPOWERED
- bool "Bus powered"
- ---help---
- Will cause USB features to indicate that the device is self-powered
-
-endchoice
-
-config USBDEV_MAXPOWER
- int "Maximum power consumption in mA"
- default 100
- depends on USBDEV_BUSPOWERED
- ---help---
- Maximum power consumption in mA
-
-config USBDEV_DMA
- bool "Enable DMA methods"
- default n
- ---help---
- Select this enable DMA-related methods in USB device controller driver
- interface. These methods include the DMA buffer allocation methods:
- allobuffer() and freebuffer().
-
- The USB class driver allocates packet I/O buffers for data transfer by
- calling the driver allocbuffer() and freebuffer() methods. Those methods
- are only available if USBDEV_DMA is defined in the system configuration.
-
-config USBDEV_DMAMEMORY
-bool "Board DMA Allocation Hooks"
- default n
- depends on USBDEV_DMA
- ---help---
- The USB class driver allocates packet I/O buffers for data transfer by
- calling the driver allocbuffer() and freebuffer() methods. Those methods
- are only available if USBDEV_DMA is defined in the system configuration.
-
- If USBDEV_DMAMEMORY is also defined in the NuttX configuration, then
- the driver implementations of the allocbuffer() and freebuffer()
- methods may use board-specific usbdev_dma_alloc() and usbdev_dma_free().
- If USBDEV_DMA and USBDEV_DMAMEMORY are both defined, then the board-
- specific logic must provide the functions usbdev_dma_alloc() and
- usbdev_dma_free(): usbdev_dma_alloc() will allocate DMA-capable
- memory of the specified size; usbdev_dma_free() is the corresponding
- function that will be called to free the DMA-capable memory.
-
-config USBDEV_TRACE
- bool "Enable USB tracing for debug"
- default n
- ---help---
- Enables USB tracing for debug
-
-config USBDEV_TRACE_NRECORDS
- int "Number of trace entries to remember"
- default 32
- depends on USBDEV_TRACE
- ---help---
- Number of trace entries to remember
-
-endmenu
-
-menuconfig USBDEV_COMPOSITE
- bool "USB composite device support"
- default n
- ---help---
- Enables USB composite device support
-
-if USBDEV_COMPOSITE
-
-#config COMPOSITE_IAD
-# bool ""
-# default n
-# ---help---
-# If one of the members of the composite has multiple interfaces
-# (such as CDC/ACM), then an Interface Association Descriptor (IAD)
-# will be necessary. Default: IAD will be used automatically if
-# needed. It should not be necessary to set this.
-
-config COMPOSITE_EP0MAXPACKET
- int "Max packet size for endpoint 0"
- default 64
- ---help---
- Max packet size for endpoint 0
-
-config COMPOSITE_VENDORID
- hex "Composite vendor ID"
- default 0
-
-config COMPOSITE_VENDORSTR
- string "Composite vendor ID"
- default "Nuttx"
- ---help---
- The vendor ID code/string
-
-config COMPOSITE_PRODUCTID
- hex "Composite product id"
- default 0
-
-config COMPOSITE_PRODUCTSTR
- string "Composite product string"
- default "Composite device"
- ---help---
- The product ID code/string
-
-config COMPOSITE_SERIALSTR
- string "Composite serial string"
- default "001"
- ---help---
- Device serial number string
-
-config COMPOSITE_CONFIGSTR
- string "Configuration string"
- default "Nuttx COMPOSITE config"
- ---help---
- Configuration string
-
-config COMPOSITE_VERSIONNO
- string "Composite version number"
- default ""
- ---help---
- Interface version number.
-endif
-
-menuconfig PL2303
- bool "Prolific PL2303 serial/USB converter emulation"
- default n
- select SERIAL_REMOVABLE
- ---help---
- This logic emulates the Prolific PL2303 serial/USB converter
-
-if PL2303
-
-config PL2303_CONSOLE
- bool "PL2303 console device"
- default n
- ---help---
- Register the USB device as /dev/console so that is will be used
- as the console device.
-
-config PL2303_EPINTIN
- int "Logical endpoint numbers"
- default 1
-
-config PL2303_EPBULKOUT
- int "Endpoint Bulkout"
- default 2
-
-config PL2303_EPBULKIN
- int "Endpoint Bulkin"
- default 3
-
-config PL2303_EP0MAXPACKET
- int "Packet and request buffer sizes"
- default 64
-
-config PL2303_NWRREQS
- int "Number of read requests that can be in flight"
- default 4
- ---help---
- The number of read requests that can be in flight
-
-config PL2303_NRDREQS
- int "Number of write requests that can be in flight"
- default 4
- ---help---
- The number of write/read requests that can be in flight
-
-config PL2303_RXBUFSIZE
- int "Receive buffer size"
- default 256
- ---help---
- Size of the serial receive/transmit buffers
-
-config PL2303_TXBUFSIZE
- int "Transmit buffer size"
- default 256
- ---help---
- Size of the serial receive/transmit buffers
-
-config PL2303_VENDORID
- hex "Vendor ID"
- default 0x067b
-
-config PL2303_PRODUCTID
- hex "Product ID"
- default 0x2303
-
-config PL2303_VENDORSTR
- string "Vendor string"
- default "NuttX"
-
-config PL2303_PRODUCTSTR
- string "Product string"
- default "PL2303 Emulation"
-endif
-
-menuconfig CDCACM
- bool "USB Modem (CDC ACM) support"
- default n
- select SERIAL_REMOVABLE
- ---help---
- Enables USB Modem (CDC ACM) support
-
-if CDCACM
-
-config CDCACM_CONSOLE
- bool "CDC/ACM console device"
- default n
- ---help---
- Register the USB device as /dev/console so that is will be used
- as the console device.
-
-config CDCACM_COMPOSITE
- bool "CDC/ACM composite support"
- default n
- depends on USBDEV_COMPOSITE
- ---help---
- Configure the CDC serial driver as part of a composite driver
- (only if CONFIG_USBDEV_COMPOSITE is also defined)
-
-config CDCACM_IFNOBASE
- int "Offset the CDC/ACM interface numbers"
- default 0
- depends on CDCACM_COMPOSITE
- ---help---
- If the CDC driver is part of a composite device, then this may need to
- be defined to offset the CDC/ACM interface numbers so that they are
- unique and contiguous. When used with the Mass Storage driver, the
- correct value for this offset is zero.
-
-config CDCACM_STRBASE
- int "Offset the CDC/ACM string numbers"
- default 0
- depends on CDCACM_COMPOSITE
- ---help---
- If the CDC driver is part of a composite device, then this may need to
- be defined to offset the CDC/ACM string numbers so that they are
- unique and contiguous. When used with the Mass Storage driver, the
- correct value for this offset is four (this value actuallly only needs
- to be defined if names are provided for the Notification interface,
- config CDCACM_NOTIFSTR, or the data interface, CONFIG_CDCACM_DATAIFSTR).
-
-config CDCACM_EP0MAXPACKET
- int "Endpoint 0 max packet size"
- default 64
- ---help---
- Endpoint 0 max packet size. Default 64.
-
-config CDCACM_EPINTIN
- int "Hardware endpoint that supports interrupt IN operation"
- default 1
- ---help---
- The logical 7-bit address of a hardware endpoint that supports
- interrupt IN operation. Default 1.
-
-config CDCACM_EPINTIN_FSSIZE
- int "Endpoint in full speed size"
- default 64
- ---help---
- Max package size for the interrupt IN endpoint if full speed mode.
- Default 64.
-
-config CDCACM_EPINTIN_HSSIZE
- int "Endpoint in high speed size"
- default 64
- ---help---
- Max package size for the interrupt IN endpoint if high speed mode.
- Default 64.
-
-config CDCACM_EPBULKOUT
- int "Endpoint bulk out"
- default 3
- ---help---
- The logical 7-bit address of a hardware endpoint that supports
- bulk OUT operation. Default: 3
-
-config CDCACM_EPBULKOUT_FSSIZE
- int "Endpoint bulk out full speed size"
- default 64
- ---help---
- Max package size for the bulk OUT endpoint if full speed mode.
- Default 64.
-
-config CDCACM_EPBULKOUT_HSSIZE
- int "Endpoint bulk out high speed size"
- default 512
- ---help---
- Max package size for the bulk OUT endpoint if high speed mode.
- Default 512.
-
-config CDCACM_EPBULKIN
- int "Endpoint bulk in"
- default 2
- ---help---
- The logical 7-bit address of a hardware endpoint that supports
- bulk IN operation. Default: 2
-
-config CDCACM_EPBULKIN_FSSIZE
- int "Endpoint bulk in full speed size"
- default 64
- ---help---
- Max package size for the bulk IN endpoint if full speed mode.
- Default 64.
-
-config CDCACM_EPBULKIN_HSSIZE
- int "Endpoint bulk in high speed size"
- default 512
- ---help---
- Max package size for the bulk IN endpoint if high speed mode.
- Default 512.
-
-config CDCACM_NWRREQS
- int "Number of read requests that can be in flight"
- default 4
- ---help---
- The number of read requests that can be in flight
-
-config CDCACM_NRDREQS
- int "Number of write requests that can be in flight"
- default 4
- ---help---
- The number of write/read requests that can be in flight
-
-config CDCACM_RXBUFSIZE
- int "Receive buffer size"
- default 256
- ---help---
- Size of the serial receive/transmit buffers
-
-config CDCACM_TXBUFSIZE
- int "Transmit buffer size"
- default 256
- ---help---
- Size of the serial receive/transmit buffers
-
-config CDCACM_VENDORID
- hex "Vendor ID"
- default 0x0525
- ---help---
- The vendor ID code/string. Default 0x0525 and "NuttX"
- 0x0525 is the Netchip vendor and should not be used in any
- products. This default VID was selected for compatibility with
- the Linux CDC ACM default VID.
-
-config CDCACM_PRODUCTID
- hex "Product ID"
- default 0xa4a7
- ---help---
- The product ID code/string. Default 0xa4a7 and "CDC/ACM Serial"
- 0xa4a7 was selected for compatibility with the Linux CDC ACM
- default PID.
-
-config CDCACM_VENDORSTR
- string "Vendor string"
- default "NuttX"
-
-config CDCACM_PRODUCTSTR
- string "Product string"
- default "CDC/ACM Serial"
-endif
-
-menuconfig USBMSC
- bool "USB Mass storage class device"
- default n
- ---help---
- References:
- "Universal Serial Bus Mass Storage Class, Specification Overview,"
- Revision 1.2, USB Implementer's Forum, June 23, 2003.
-
- "Universal Serial Bus Mass Storage Class, Bulk-Only Transport,"
- Revision 1.0, USB Implementer's Forum, September 31, 1999.
-
- "SCSI Primary Commands - 3 (SPC-3)," American National Standard
- for Information Technology, May 4, 2005
-
- "SCSI Primary Commands - 4 (SPC-4)," American National Standard
- for Information Technology, July 19, 2008
-
- "SCSI Block Commands -2 (SBC-2)," American National Standard
- for Information Technology, November 13, 2004
-
- "SCSI Multimedia Commands - 3 (MMC-3)," American National Standard
- for Information Technology, November 12, 2001
-
-if USBMSC
-config USBMSC_COMPOSITE
- bool "Mass storage composite support"
- default n
- depends on USBDEV_COMPOSITE
- ---help---
- Configure the mass storage driver as part of a composite driver
- (only if CONFIG_USBDEV_COMPOSITE is also defined)
-
-config USBMSC_IFNOBASE
- int "Offset the mass storage interface number"
- default 2
- depends on USBMSC_COMPOSITE
- ---help---
- If the CDC driver is part of a composite device, then this may need to
- be defined to offset the mass storage interface number so that it is
- unique and contiguous. When used with the CDC/ACM driver, the
- correct value for this offset is two (because of the two CDC/ACM
- interfaces that will precede it).
-
-config USBMSC_STRBASE
- int "Offset the mass storage string numbers"
- default 2
- depends on USBMSC_COMPOSITE
- ---help---
- If the CDC driver is part of a composite device, then this may need to
- be defined to offset the mass storage string numbers so that they are
- unique and contiguous. When used with the CDC/ACM driver, the
- correct value for this offset is four (or perhaps 5 or 6, depending
- on if CONFIG_CDCACM_NOTIFSTR or CONFIG_CDCACM_DATAIFSTR are defined).
-
-config USBMSC_EP0MAXPACKET
- int "Max packet size for endpoint 0"
- default 64
- ---help---
- Max packet size for endpoint 0
-
-config USBMSC_EPBULKOUT
- int "Endpoint bulk out"
- default 0
- ---help---
- The logical 7-bit address of a hardware endpoints that support
- bulk OUT and IN operations
-
-config USBMSC_EPBULKIN
- int "Endpoint bulk in"
- default 0
- ---help---
- The logical 7-bit address of a hardware endpoints that support
- bulk OUT and IN operations
-
-config USBMSC_NWRREQS
- int "The number of write requests that can be in flight"
- default 4
- ---help---
- The number of write/read requests that can be in flight
-config USBMSC_NRDREQS
- int "The number of read requests that can be in flight"
- default 4
- ---help---
- The number of write/read requests that can be in flight
-
-config USBMSC_BULKINREQLEN
- int "Bulk in request size"
- default 512
-
-config USBMSC_BULKOUTREQLEN
- int "Bulk out request size"
- default 512
- ---help---
- The size of the buffer in each write/read request. This
- value needs to be at least as large as the endpoint
- maxpacket and ideally as large as a block device sector.
-
-config USBMSC_VENDORID
- hex "Mass stroage Vendor ID"
- default 0x00
-
-config USBMSC_VENDORSTR
- string "Mass stroage vendor string"
- default "Nuttx"
- ---help---
- The vendor ID code/string
-
-config USBMSC_PRODUCTID
- hex "Mass stroage Product ID"
- default 0x00
-
-config USBMSC_PRODUCTSTR
- string "Mass storage product string"
- default "Mass Storage"
-
-config USBMSC_VERSIONNO
- hex "USB MSC Version Number"
- default "0x399"
-
-config USBMSC_REMOVABLE
- bool "Mass stroage remove able"
- default n
- ---help---
- Select if the media is removable
- USB Composite Device Configuration
-endif
diff --git a/nuttx/drivers/usbdev/Make.defs b/nuttx/drivers/usbdev/Make.defs
deleted file mode 100644
index e43693b29..000000000
--- a/nuttx/drivers/usbdev/Make.defs
+++ /dev/null
@@ -1,63 +0,0 @@
-############################################################################
-# drivers/usbdev/Make.defs
-#
-# Copyright (C) 2008, 2010-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-ifeq ($(CONFIG_USBDEV),y)
-
-# Include USB device drivers
-
-ifeq ($(CONFIG_PL2303),y)
- CSRCS += pl2303.c
-endif
-
-ifeq ($(CONFIG_CDCACM),y)
- CSRCS += cdcacm.c cdcacm_desc.c
-endif
-
-ifeq ($(CONFIG_USBMSC),y)
- CSRCS += usbmsc.c usbmsc_desc.c usbmsc_scsi.c
-endif
-
-ifeq ($(CONFIG_USBDEV_COMPOSITE),y)
- CSRCS += composite.c composite_desc.c
-endif
-
-CSRCS += usbdev_trace.c usbdev_trprintf.c
-
-# Include USB device build support
-
-DEPPATH += --dep-path usbdev
-VPATH += :usbdev
-CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)usbdev}
-endif
diff --git a/nuttx/drivers/usbdev/cdcacm.c b/nuttx/drivers/usbdev/cdcacm.c
deleted file mode 100644
index cb8679976..000000000
--- a/nuttx/drivers/usbdev/cdcacm.c
+++ /dev/null
@@ -1,2329 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/cdcacm.c
- *
- * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <semaphore.h>
-#include <string.h>
-#include <errno.h>
-#include <queue.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/arch.h>
-#include <nuttx/serial/serial.h>
-
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/cdc.h>
-#include <nuttx/usb/usbdev.h>
-#include <nuttx/usb/cdcacm.h>
-#include <nuttx/usb/usbdev_trace.h>
-
-#include "cdcacm.h"
-
-#ifdef CONFIG_USBMSC_COMPOSITE
-# include <nuttx/usb/composite.h>
-# include "composite.h"
-#endif
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* Container to support a list of requests */
-
-struct cdcacm_req_s
-{
- FAR struct cdcacm_req_s *flink; /* Implements a singly linked list */
- FAR struct usbdev_req_s *req; /* The contained request */
-};
-
-/* This structure describes the internal state of the driver */
-
-struct cdcacm_dev_s
-{
- FAR struct uart_dev_s serdev; /* Serial device structure */
- FAR struct usbdev_s *usbdev; /* usbdev driver pointer */
-
- uint8_t config; /* Configuration number */
- uint8_t nwrq; /* Number of queue write requests (in reqlist)*/
- uint8_t nrdq; /* Number of queue read requests (in epbulkout) */
- uint8_t minor; /* The device minor number */
- bool rxenabled; /* true: UART RX "interrupts" enabled */
- int16_t rxhead; /* Working head; used when rx int disabled */
-
- uint8_t ctrlline; /* Buffered control line state */
- struct cdc_linecoding_s linecoding; /* Buffered line status */
- cdcacm_callback_t callback; /* Serial event callback function */
-
- FAR struct usbdev_ep_s *epintin; /* Interrupt IN endpoint structure */
- FAR struct usbdev_ep_s *epbulkin; /* Bulk IN endpoint structure */
- FAR struct usbdev_ep_s *epbulkout; /* Bulk OUT endpoint structure */
- FAR struct usbdev_req_s *ctrlreq; /* Allocoated control request */
- struct sq_queue_s reqlist; /* List of write request containers */
-
- /* Pre-allocated write request containers. The write requests will
- * be linked in a free list (reqlist), and used to send requests to
- * EPBULKIN; Read requests will be queued in the EBULKOUT.
- */
-
- struct cdcacm_req_s wrreqs[CONFIG_CDCACM_NWRREQS];
- struct cdcacm_req_s rdreqs[CONFIG_CDCACM_NWRREQS];
-
- /* Serial I/O buffers */
-
- char rxbuffer[CONFIG_CDCACM_RXBUFSIZE];
- char txbuffer[CONFIG_CDCACM_TXBUFSIZE];
-};
-
-/* The internal version of the class driver */
-
-struct cdcacm_driver_s
-{
- struct usbdevclass_driver_s drvr;
- FAR struct cdcacm_dev_s *dev;
-};
-
-/* This is what is allocated */
-
-struct cdcacm_alloc_s
-{
- struct cdcacm_dev_s dev;
- struct cdcacm_driver_s drvr;
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Transfer helpers *********************************************************/
-
-static uint16_t cdcacm_fillrequest(FAR struct cdcacm_dev_s *priv,
- uint8_t *reqbuf, uint16_t reqlen);
-static int cdcacm_sndpacket(FAR struct cdcacm_dev_s *priv);
-static inline int cdcacm_recvpacket(FAR struct cdcacm_dev_s *priv,
- uint8_t *reqbuf, uint16_t reqlen);
-
-/* Request helpers *********************************************************/
-
-static struct usbdev_req_s *cdcacm_allocreq(FAR struct usbdev_ep_s *ep,
- uint16_t len);
-static void cdcacm_freereq(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-
-/* Configuration ***********************************************************/
-
-static void cdcacm_resetconfig(FAR struct cdcacm_dev_s *priv);
-#ifdef CONFIG_USBDEV_DUALSPEED
-static int cdcacm_epconfigure(FAR struct usbdev_ep_s *ep,
- enum cdcacm_epdesc_e epid, uint16_t mxpacket, bool last);
-#endif
-static int cdcacm_setconfig(FAR struct cdcacm_dev_s *priv,
- uint8_t config);
-
-/* Completion event handlers ***********************************************/
-
-static void cdcacm_ep0incomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-static void cdcacm_rdcomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-static void cdcacm_wrcomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-
-/* USB class device ********************************************************/
-
-static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void cdcacm_unbind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
- size_t outlen);
-static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-#ifdef CONFIG_SERIAL_REMOVABLE
-static void cdcacm_suspend(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void cdcacm_resume(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-#endif
-
-/* UART Operations **********************************************************/
-
-static int cdcuart_setup(FAR struct uart_dev_s *dev);
-static void cdcuart_shutdown(FAR struct uart_dev_s *dev);
-static int cdcuart_attach(FAR struct uart_dev_s *dev);
-static void cdcuart_detach(FAR struct uart_dev_s *dev);
-static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg);
-static void cdcuart_rxint(FAR struct uart_dev_s *dev, bool enable);
-static void cdcuart_txint(FAR struct uart_dev_s *dev, bool enable);
-static bool cdcuart_txempty(FAR struct uart_dev_s *dev);
-
-/****************************************************************************
- * Private Variables
- ****************************************************************************/
-/* USB class device *********************************************************/
-
-static const struct usbdevclass_driverops_s g_driverops =
-{
- cdcacm_bind, /* bind */
- cdcacm_unbind, /* unbind */
- cdcacm_setup, /* setup */
- cdcacm_disconnect, /* disconnect */
-#ifdef CONFIG_SERIAL_REMOVABLE
- cdcacm_suspend, /* suspend */
- cdcacm_resume, /* resume */
-#else
- NULL, /* suspend */
- NULL, /* resume */
-#endif
-};
-
-/* Serial port **************************************************************/
-
-static const struct uart_ops_s g_uartops =
-{
- cdcuart_setup, /* setup */
- cdcuart_shutdown, /* shutdown */
- cdcuart_attach, /* attach */
- cdcuart_detach, /* detach */
- cdcuart_ioctl, /* ioctl */
- NULL, /* receive */
- cdcuart_rxint, /* rxinit */
- NULL, /* rxavailable */
- NULL, /* send */
- cdcuart_txint, /* txinit */
- NULL, /* txready */
- cdcuart_txempty /* txempty */
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: cdcacm_fillrequest
- *
- * Description:
- * If there is data to send it is copied to the given buffer. Called
- * either to initiate the first write operation, or from the completion
- * interrupt handler service consecutive write operations.
- *
- * NOTE: The USB serial driver does not use the serial drivers
- * uart_xmitchars() API. That logic is essentially duplicated here because
- * unlike UART hardware, we need to be able to handle writes not byte-by-byte,
- * but packet-by-packet. Unfortunately, that decision also exposes some
- * internals of the serial driver in the following.
- *
- ****************************************************************************/
-
-static uint16_t cdcacm_fillrequest(FAR struct cdcacm_dev_s *priv, uint8_t *reqbuf,
- uint16_t reqlen)
-{
- FAR uart_dev_t *serdev = &priv->serdev;
- FAR struct uart_buffer_s *xmit = &serdev->xmit;
- irqstate_t flags;
- uint16_t nbytes = 0;
-
- /* Disable interrupts */
-
- flags = irqsave();
-
- /* Transfer bytes while we have bytes available and there is room in the request */
-
- while (xmit->head != xmit->tail && nbytes < reqlen)
- {
- *reqbuf++ = xmit->buffer[xmit->tail];
- nbytes++;
-
- /* Increment the tail pointer */
-
- if (++(xmit->tail) >= xmit->size)
- {
- xmit->tail = 0;
- }
- }
-
- /* When all of the characters have been sent from the buffer
- * disable the "TX interrupt".
- */
-
- if (xmit->head == xmit->tail)
- {
- uart_disabletxint(serdev);
- }
-
- /* If any bytes were removed from the buffer, inform any waiters
- * there there is space available.
- */
-
- if (nbytes)
- {
- uart_datasent(serdev);
- }
-
- irqrestore(flags);
- return nbytes;
-}
-
-/****************************************************************************
- * Name: cdcacm_sndpacket
- *
- * Description:
- * This function obtains write requests, transfers the TX data into the
- * request, and submits the requests to the USB controller. This continues
- * untils either (1) there are no further packets available, or (2) thre is
- * no further data to send.
- *
- ****************************************************************************/
-
-static int cdcacm_sndpacket(FAR struct cdcacm_dev_s *priv)
-{
- FAR struct usbdev_ep_s *ep;
- FAR struct usbdev_req_s *req;
- FAR struct cdcacm_req_s *reqcontainer;
- uint16_t reqlen;
- irqstate_t flags;
- int len;
- int ret = OK;
-
-#ifdef CONFIG_DEBUG
- if (priv == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return -ENODEV;
- }
-#endif
-
- flags = irqsave();
-
- /* Use our IN endpoint for the transfer */
-
- ep = priv->epbulkin;
-
- /* Loop until either (1) we run out or write requests, or (2) cdcacm_fillrequest()
- * is unable to fill the request with data (i.e., until there is no more data
- * to be sent).
- */
-
- uvdbg("head=%d tail=%d nwrq=%d empty=%d\n",
- priv->serdev.xmit.head, priv->serdev.xmit.tail,
- priv->nwrq, sq_empty(&priv->reqlist));
-
- /* Get the maximum number of bytes that will fit into one bulk IN request */
-
-#ifdef CONFIG_CDCACM_BULKREQLEN
- reqlen = MAX(CONFIG_CDCACM_BULKREQLEN, ep->maxpacket);
-#else
- reqlen = ep->maxpacket;
-#endif
-
- while (!sq_empty(&priv->reqlist))
- {
- /* Peek at the request in the container at the head of the list */
-
- reqcontainer = (struct cdcacm_req_s *)sq_peek(&priv->reqlist);
- req = reqcontainer->req;
-
- /* Fill the request with serial TX data */
-
- len = cdcacm_fillrequest(priv, req->buf, reqlen);
- if (len > 0)
- {
- /* Remove the empty container from the request list */
-
- (void)sq_remfirst(&priv->reqlist);
- priv->nwrq--;
-
- /* Then submit the request to the endpoint */
-
- req->len = len;
- req->priv = reqcontainer;
- req->flags = USBDEV_REQFLAGS_NULLPKT;
- ret = EP_SUBMIT(ep, req);
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_SUBMITFAIL), (uint16_t)-ret);
- break;
- }
- }
- else
- {
- break;
- }
- }
-
- irqrestore(flags);
- return ret;
-}
-
-/****************************************************************************
- * Name: cdcacm_recvpacket
- *
- * Description:
- * A normal completion event was received by the read completion handler
- * at the interrupt level (with interrupts disabled). This function handles
- * the USB packet and provides the received data to the uart RX buffer.
- *
- * Assumptions:
- * Called from the USB interrupt handler with interrupts disabled.
- *
- ****************************************************************************/
-
-static inline int cdcacm_recvpacket(FAR struct cdcacm_dev_s *priv,
- uint8_t *reqbuf, uint16_t reqlen)
-{
- FAR uart_dev_t *serdev = &priv->serdev;
- FAR struct uart_buffer_s *recv = &serdev->recv;
- uint16_t currhead;
- uint16_t nexthead;
- uint16_t nbytes = 0;
-
- uvdbg("head=%d tail=%d nrdq=%d reqlen=%d\n",
- priv->serdev.recv.head, priv->serdev.recv.tail, priv->nrdq, reqlen);
-
- /* Get the next head index. During the time that RX interrupts are disabled, the
- * the serial driver will be extracting data from the circular buffer and modifying
- * recv.tail. During this time, we should avoid modifying recv.head; Instead we will
- * use a shadow copy of the index. When interrupts are restored, the real recv.head
- * will be updated with this indes.
- */
-
- if (priv->rxenabled)
- {
- currhead = recv->head;
- }
- else
- {
- currhead = priv->rxhead;
- }
-
- /* Pre-calculate the head index and check for wrap around. We need to do this
- * so that we can determine if the circular buffer will overrun BEFORE we
- * overrun the buffer!
- */
-
- nexthead = currhead + 1;
- if (nexthead >= recv->size)
- {
- nexthead = 0;
- }
-
- /* Then copy data into the RX buffer until either: (1) all of the data has been
- * copied, or (2) the RX buffer is full. NOTE: If the RX buffer becomes full,
- * then we have overrun the serial driver and data will be lost.
- */
-
- while (nexthead != recv->tail && nbytes < reqlen)
- {
- /* Copy one byte to the head of the circular RX buffer */
-
- recv->buffer[currhead] = *reqbuf++;
-
- /* Update counts and indices */
-
- currhead = nexthead;
- nbytes++;
-
- /* Increment the head index and check for wrap around */
-
- nexthead = currhead + 1;
- if (nexthead >= recv->size)
- {
- nexthead = 0;
- }
- }
-
- /* Write back the head pointer using the shadow index if RX "interrupts"
- * are disabled.
- */
-
- if (priv->rxenabled)
- {
- recv->head = currhead;
- }
- else
- {
- priv->rxhead = currhead;
- }
-
- /* If data was added to the incoming serial buffer, then wake up any
- * threads is waiting for incoming data. If we are running in an interrupt
- * handler, then the serial driver will not run until the interrupt handler
- * returns.
- */
-
- if (priv->rxenabled && nbytes > 0)
- {
- uart_datareceived(serdev);
- }
-
- /* Return an error if the entire packet could not be transferred */
-
- if (nbytes < reqlen)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RXOVERRUN), 0);
- return -ENOSPC;
- }
- return OK;
-}
-
-/****************************************************************************
- * Name: cdcacm_allocreq
- *
- * Description:
- * Allocate a request instance along with its buffer
- *
- ****************************************************************************/
-
-static struct usbdev_req_s *cdcacm_allocreq(FAR struct usbdev_ep_s *ep,
- uint16_t len)
-{
- FAR struct usbdev_req_s *req;
-
- req = EP_ALLOCREQ(ep);
- if (req != NULL)
- {
- req->len = len;
- req->buf = EP_ALLOCBUFFER(ep, len);
- if (!req->buf)
- {
- EP_FREEREQ(ep, req);
- req = NULL;
- }
- }
- return req;
-}
-
-/****************************************************************************
- * Name: cdcacm_freereq
- *
- * Description:
- * Free a request instance along with its buffer
- *
- ****************************************************************************/
-
-static void cdcacm_freereq(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- if (ep != NULL && req != NULL)
- {
- if (req->buf != NULL)
- {
- EP_FREEBUFFER(ep, req->buf);
- }
- EP_FREEREQ(ep, req);
- }
-}
-
-/****************************************************************************
- * Name: cdcacm_resetconfig
- *
- * Description:
- * Mark the device as not configured and disable all endpoints.
- *
- ****************************************************************************/
-
-static void cdcacm_resetconfig(FAR struct cdcacm_dev_s *priv)
-{
- /* Are we configured? */
-
- if (priv->config != CDCACM_CONFIGIDNONE)
- {
- /* Yes.. but not anymore */
-
- priv->config = CDCACM_CONFIGIDNONE;
-
- /* Inform the "upper half" driver that there is no (functional) USB
- * connection.
- */
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- uart_connected(&priv->serdev, false);
-#endif
-
- /* Disable endpoints. This should force completion of all pending
- * transfers.
- */
-
- EP_DISABLE(priv->epintin);
- EP_DISABLE(priv->epbulkin);
- EP_DISABLE(priv->epbulkout);
- }
-}
-
-/****************************************************************************
- * Name: cdcacm_epconfigure
- *
- * Description:
- * Configure one endpoint.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-static int cdcacm_epconfigure(FAR struct usbdev_ep_s *ep,
- enum cdcacm_epdesc_e epid, uint16_t mxpacket,
- bool last)
-{
- struct usb_epdesc_s epdesc;
- cdcacm_mkepdesc(epid, mxpacket, &epdesc);
- return EP_CONFIGURE(ep, &epdesc, last);
-}
-#endif
-
-/****************************************************************************
- * Name: cdcacm_setconfig
- *
- * Description:
- * Set the device configuration by allocating and configuring endpoints and
- * by allocating and queue read and write requests.
- *
- ****************************************************************************/
-
-static int cdcacm_setconfig(FAR struct cdcacm_dev_s *priv, uint8_t config)
-{
- FAR struct usbdev_req_s *req;
- int i;
- int ret = 0;
-
-#if CONFIG_DEBUG
- if (priv == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return -EIO;
- }
-#endif
-
- if (config == priv->config)
- {
- /* Already configured -- Do nothing */
-
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALREADYCONFIGURED), 0);
- return 0;
- }
-
- /* Discard the previous configuration data */
-
- cdcacm_resetconfig(priv);
-
- /* Was this a request to simply discard the current configuration? */
-
- if (config == CDCACM_CONFIGIDNONE)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_CONFIGNONE), 0);
- return 0;
- }
-
- /* We only accept one configuration */
-
- if (config != CDCACM_CONFIGID)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_CONFIGIDBAD), 0);
- return -EINVAL;
- }
-
- /* Configure the IN interrupt endpoint */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- if (priv->usbdev->speed == USB_SPEED_HIGH)
- {
- ret = cdcacm_epconfigure(priv->epintin, CDCACM_EPINTIN,
- CONFIG_CDCACM_EPINTIN_HSSIZE, false);
- }
- else
-#endif
- {
- ret = EP_CONFIGURE(priv->epintin,
- cdcacm_getepdesc(CDCACM_EPINTIN), false);
- }
-
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINCONFIGFAIL), 0);
- goto errout;
- }
- priv->epintin->priv = priv;
-
- /* Configure the IN bulk endpoint */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- if (priv->usbdev->speed == USB_SPEED_HIGH)
- {
- ret = cdcacm_epconfigure(priv->epbulkin, CDCACM_EPBULKIN,
- CONFIG_CDCACM_EPBULKIN_HSSIZE, false);
- }
- else
-#endif
- {
- ret = EP_CONFIGURE(priv->epbulkin,
- cdcacm_getepdesc(CDCACM_EPBULKIN), false);
- }
-
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINCONFIGFAIL), 0);
- goto errout;
- }
-
- priv->epbulkin->priv = priv;
-
- /* Configure the OUT bulk endpoint */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- if (priv->usbdev->speed == USB_SPEED_HIGH)
- {
- ret = cdcacm_epconfigure(priv->epbulkout, CDCACM_EPBULKOUT,
- CONFIG_CDCACM_EPBULKOUT_HSSIZE, true);
- }
- else
-#endif
- {
- ret = EP_CONFIGURE(priv->epbulkout,
- cdcacm_getepdesc(CDCACM_EPBULKOUT), true);
- }
-
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTCONFIGFAIL), 0);
- goto errout;
- }
-
- priv->epbulkout->priv = priv;
-
- /* Queue read requests in the bulk OUT endpoint */
-
- DEBUGASSERT(priv->nrdq == 0);
- for (i = 0; i < CONFIG_CDCACM_NRDREQS; i++)
- {
- req = priv->rdreqs[i].req;
- req->callback = cdcacm_rdcomplete;
- ret = EP_SUBMIT(priv->epbulkout, req);
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-ret);
- goto errout;
- }
-
- priv->nrdq++;
- }
-
- /* We are successfully configured */
-
- priv->config = config;
-
- /* Inform the "upper half" driver that we are "open for business" */
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- uart_connected(&priv->serdev, true);
-#endif
-
- return OK;
-
-errout:
- cdcacm_resetconfig(priv);
- return ret;
-}
-
-/****************************************************************************
- * Name: cdcacm_ep0incomplete
- *
- * Description:
- * Handle completion of EP0 control operations
- *
- ****************************************************************************/
-
-static void cdcacm_ep0incomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- if (req->result || req->xfrd != req->len)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_REQRESULT), (uint16_t)-req->result);
- }
-}
-
-/****************************************************************************
- * Name: cdcacm_rdcomplete
- *
- * Description:
- * Handle completion of read request on the bulk OUT endpoint. This
- * is handled like the receipt of serial data on the "UART"
- *
- ****************************************************************************/
-
-static void cdcacm_rdcomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- FAR struct cdcacm_dev_s *priv;
- irqstate_t flags;
- int ret;
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (!ep || !ep->priv || !req)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract references to private data */
-
- priv = (FAR struct cdcacm_dev_s*)ep->priv;
-
- /* Process the received data unless this is some unusual condition */
-
- flags = irqsave();
- switch (req->result)
- {
- case 0: /* Normal completion */
- usbtrace(TRACE_CLASSRDCOMPLETE, priv->nrdq);
- cdcacm_recvpacket(priv, req->buf, req->xfrd);
- break;
-
- case -ESHUTDOWN: /* Disconnection */
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSHUTDOWN), 0);
- priv->nrdq--;
- irqrestore(flags);
- return;
-
- default: /* Some other error occurred */
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDUNEXPECTED), (uint16_t)-req->result);
- break;
- };
-
- /* Requeue the read request */
-
-#ifdef CONFIG_CDCACM_BULKREQLEN
- req->len = MAX(CONFIG_CDCACM_BULKREQLEN, ep->maxpacket);
-#else
- req->len = ep->maxpacket;
-#endif
-
- ret = EP_SUBMIT(ep, req);
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-req->result);
- }
-
- irqrestore(flags);
-}
-
-/****************************************************************************
- * Name: cdcacm_wrcomplete
- *
- * Description:
- * Handle completion of write request. This function probably executes
- * in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-static void cdcacm_wrcomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- FAR struct cdcacm_dev_s *priv;
- FAR struct cdcacm_req_s *reqcontainer;
- irqstate_t flags;
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (!ep || !ep->priv || !req || !req->priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract references to our private data */
-
- priv = (FAR struct cdcacm_dev_s *)ep->priv;
- reqcontainer = (FAR struct cdcacm_req_s *)req->priv;
-
- /* Return the write request to the free list */
-
- flags = irqsave();
- sq_addlast((sq_entry_t*)reqcontainer, &priv->reqlist);
- priv->nwrq++;
- irqrestore(flags);
-
- /* Send the next packet unless this was some unusual termination
- * condition
- */
-
- switch (req->result)
- {
- case OK: /* Normal completion */
- usbtrace(TRACE_CLASSWRCOMPLETE, priv->nwrq);
- cdcacm_sndpacket(priv);
- break;
-
- case -ESHUTDOWN: /* Disconnection */
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRSHUTDOWN), priv->nwrq);
- break;
-
- default: /* Some other error occurred */
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRUNEXPECTED), (uint16_t)-req->result);
- break;
- }
-}
-
-/****************************************************************************
- * USB Class Driver Methods
- ****************************************************************************/
-
-/****************************************************************************
- * Name: cdcacm_bind
- *
- * Description:
- * Invoked when the driver is bound to a USB device driver
- *
- ****************************************************************************/
-
-static int cdcacm_bind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct cdcacm_dev_s *priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
- FAR struct cdcacm_req_s *reqcontainer;
- irqstate_t flags;
- uint16_t reqlen;
- int ret;
- int i;
-
- usbtrace(TRACE_CLASSBIND, 0);
-
- /* Bind the structures */
-
- priv->usbdev = dev;
-
- /* Save the reference to our private data structure in EP0 so that it
- * can be recovered in ep0 completion events (Unless we are part of
- * a composite device and, in that case, the composite device owns
- * EP0).
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- dev->ep0->priv = priv;
-#endif
-
- /* Preallocate control request */
-
- priv->ctrlreq = cdcacm_allocreq(dev->ep0, CDCACM_MXDESCLEN);
- if (priv->ctrlreq == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCCTRLREQ), 0);
- ret = -ENOMEM;
- goto errout;
- }
-
- priv->ctrlreq->callback = cdcacm_ep0incomplete;
-
- /* Pre-allocate all endpoints... the endpoints will not be functional
- * until the SET CONFIGURATION request is processed in cdcacm_setconfig.
- * This is done here because there may be calls to kmalloc and the SET
- * CONFIGURATION processing probably occurrs within interrupt handling
- * logic where kmalloc calls will fail.
- */
-
- /* Pre-allocate the IN interrupt endpoint */
-
- priv->epintin = DEV_ALLOCEP(dev, CDCACM_EPINTIN_ADDR, true, USB_EP_ATTR_XFER_INT);
- if (!priv->epintin)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINALLOCFAIL), 0);
- ret = -ENODEV;
- goto errout;
- }
- priv->epintin->priv = priv;
-
- /* Pre-allocate the IN bulk endpoint */
-
- priv->epbulkin = DEV_ALLOCEP(dev, CDCACM_EPINBULK_ADDR, true, USB_EP_ATTR_XFER_BULK);
- if (!priv->epbulkin)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINALLOCFAIL), 0);
- ret = -ENODEV;
- goto errout;
- }
- priv->epbulkin->priv = priv;
-
- /* Pre-allocate the OUT bulk endpoint */
-
- priv->epbulkout = DEV_ALLOCEP(dev, CDCACM_EPOUTBULK_ADDR, false, USB_EP_ATTR_XFER_BULK);
- if (!priv->epbulkout)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTALLOCFAIL), 0);
- ret = -ENODEV;
- goto errout;
- }
- priv->epbulkout->priv = priv;
-
- /* Pre-allocate read requests */
-
-#ifdef CONFIG_CDCACM_BULKREQLEN
- reqlen = MAX(CONFIG_CDCACM_BULKREQLEN, priv->epbulkout->maxpacket);
-#else
- reqlen = priv->epbulkout->maxpacket;
-#endif
-
- for (i = 0; i < CONFIG_CDCACM_NRDREQS; i++)
- {
- reqcontainer = &priv->rdreqs[i];
- reqcontainer->req = cdcacm_allocreq(priv->epbulkout, reqlen);
- if (reqcontainer->req == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDALLOCREQ), -ENOMEM);
- ret = -ENOMEM;
- goto errout;
- }
- reqcontainer->req->priv = reqcontainer;
- reqcontainer->req->callback = cdcacm_rdcomplete;
- }
-
- /* Pre-allocate write request containers and put in a free list */
-
-#ifdef CONFIG_CDCACM_BULKREQLEN
- reqlen = MAX(CONFIG_CDCACM_BULKREQLEN, priv->epbulkin->maxpacket);
-#else
- reqlen = priv->epbulkin->maxpacket;
-#endif
-
- for (i = 0; i < CONFIG_CDCACM_NWRREQS; i++)
- {
- reqcontainer = &priv->wrreqs[i];
- reqcontainer->req = cdcacm_allocreq(priv->epbulkin, reqlen);
- if (reqcontainer->req == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRALLOCREQ), -ENOMEM);
- ret = -ENOMEM;
- goto errout;
- }
- reqcontainer->req->priv = reqcontainer;
- reqcontainer->req->callback = cdcacm_wrcomplete;
-
- flags = irqsave();
- sq_addlast((sq_entry_t*)reqcontainer, &priv->reqlist);
- priv->nwrq++; /* Count of write requests available */
- irqrestore(flags);
- }
-
- /* Report if we are selfpowered (unless we are part of a composite device) */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
-#ifdef CONFIG_USBDEV_SELFPOWERED
- DEV_SETSELFPOWERED(dev);
-#endif
-
- /* And pull-up the data line for the soft connect function (unless we are
- * part of a composite device)
- */
-
- DEV_CONNECT(dev);
-#endif
- return OK;
-
-errout:
- cdcacm_unbind(driver, dev);
- return ret;
-}
-
-/****************************************************************************
- * Name: cdcacm_unbind
- *
- * Description:
- * Invoked when the driver is unbound from a USB device driver
- *
- ****************************************************************************/
-
-static void cdcacm_unbind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct cdcacm_dev_s *priv;
- FAR struct cdcacm_req_s *reqcontainer;
- irqstate_t flags;
- int i;
-
- usbtrace(TRACE_CLASSUNBIND, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Make sure that we are not already unbound */
-
- if (priv != NULL)
- {
- /* Make sure that the endpoints have been unconfigured. If
- * we were terminated gracefully, then the configuration should
- * already have been reset. If not, then calling cdcacm_resetconfig
- * should cause the endpoints to immediately terminate all
- * transfers and return the requests to us (with result == -ESHUTDOWN)
- */
-
- cdcacm_resetconfig(priv);
- up_mdelay(50);
-
- /* Free the interrupt IN endpoint */
-
- if (priv->epintin)
- {
- DEV_FREEEP(dev, priv->epintin);
- priv->epintin = NULL;
- }
-
- /* Free the bulk IN endpoint */
-
- if (priv->epbulkin)
- {
- DEV_FREEEP(dev, priv->epbulkin);
- priv->epbulkin = NULL;
- }
-
- /* Free the pre-allocated control request */
-
- if (priv->ctrlreq != NULL)
- {
- cdcacm_freereq(dev->ep0, priv->ctrlreq);
- priv->ctrlreq = NULL;
- }
-
- /* Free pre-allocated read requests (which should all have
- * been returned to the free list at this time -- we don't check)
- */
-
- DEBUGASSERT(priv->nrdq == 0);
- for (i = 0; i < CONFIG_CDCACM_NRDREQS; i++)
- {
- reqcontainer = &priv->rdreqs[i];
- if (reqcontainer->req)
- {
- cdcacm_freereq(priv->epbulkout, reqcontainer->req);
- reqcontainer->req = NULL;
- }
- }
-
- /* Free the bulk OUT endpoint */
-
- if (priv->epbulkout)
- {
- DEV_FREEEP(dev, priv->epbulkout);
- priv->epbulkout = NULL;
- }
-
- /* Free write requests that are not in use (which should be all
- * of them)
- */
-
- flags = irqsave();
- DEBUGASSERT(priv->nwrq == CONFIG_CDCACM_NWRREQS);
- while (!sq_empty(&priv->reqlist))
- {
- reqcontainer = (struct cdcacm_req_s *)sq_remfirst(&priv->reqlist);
- if (reqcontainer->req != NULL)
- {
- cdcacm_freereq(priv->epbulkin, reqcontainer->req);
- priv->nwrq--; /* Number of write requests queued */
- }
- }
- DEBUGASSERT(priv->nwrq == 0);
- irqrestore(flags);
- }
-
- /* Clear out all data in the circular buffer */
-
- priv->serdev.xmit.head = 0;
- priv->serdev.xmit.tail = 0;
-}
-
-/****************************************************************************
- * Name: cdcacm_setup
- *
- * Description:
- * Invoked for ep0 control requests. This function probably executes
- * in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl,
- FAR uint8_t *dataout, size_t outlen)
-{
- FAR struct cdcacm_dev_s *priv;
- FAR struct usbdev_req_s *ctrlreq;
- uint16_t value;
- uint16_t index;
- uint16_t len;
- int ret = -EOPNOTSUPP;
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !ctrl)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return -EIO;
- }
-#endif
-
- /* Extract reference to private data */
-
- usbtrace(TRACE_CLASSSETUP, ctrl->req);
- priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv || !priv->ctrlreq)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
- return -ENODEV;
- }
-#endif
- ctrlreq = priv->ctrlreq;
-
- /* Extract the little-endian 16-bit values to host order */
-
- value = GETUINT16(ctrl->value);
- index = GETUINT16(ctrl->index);
- len = GETUINT16(ctrl->len);
-
- uvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n",
- ctrl->type, ctrl->req, value, index, len);
-
- if ((ctrl->type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
- {
- /***********************************************************************
- * Standard Requests
- ***********************************************************************/
-
- switch (ctrl->req)
- {
- case USB_REQ_GETDESCRIPTOR:
- {
- /* The value field specifies the descriptor type in the MS byte and the
- * descriptor index in the LS byte (order is little endian)
- */
-
- switch (ctrl->value[1])
- {
- /* If the serial device is used in as part of a composite device,
- * then the device descriptor is provided by logic in the composite
- * device implementation.
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
- case USB_DESC_TYPE_DEVICE:
- {
- ret = USB_SIZEOF_DEVDESC;
- memcpy(ctrlreq->buf, cdcacm_getdevdesc(), ret);
- }
- break;
-#endif
-
- /* If the serial device is used in as part of a composite device,
- * then the device qualifier descriptor is provided by logic in the
- * composite device implementation.
- */
-
-#if !defined(CONFIG_CDCACM_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
- case USB_DESC_TYPE_DEVICEQUALIFIER:
- {
- ret = USB_SIZEOF_QUALDESC;
- memcpy(ctrlreq->buf, cdcacm_getqualdesc(), ret);
- }
- break;
-
- case USB_DESC_TYPE_OTHERSPEEDCONFIG:
-#endif
-
- /* If the serial device is used in as part of a composite device,
- * then the configuration descriptor is provided by logic in the
- * composite device implementation.
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
- case USB_DESC_TYPE_CONFIG:
- {
-#ifdef CONFIG_USBDEV_DUALSPEED
- ret = cdcacm_mkcfgdesc(ctrlreq->buf, dev->speed, ctrl->req);
-#else
- ret = cdcacm_mkcfgdesc(ctrlreq->buf);
-#endif
- }
- break;
-#endif
-
- /* If the serial device is used in as part of a composite device,
- * then the language string descriptor is provided by logic in the
- * composite device implementation.
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
- case USB_DESC_TYPE_STRING:
- {
- /* index == language code. */
-
- ret = cdcacm_mkstrdesc(ctrl->value[0], (struct usb_strdesc_s *)ctrlreq->buf);
- }
- break;
-#endif
-
- default:
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_GETUNKNOWNDESC), value);
- }
- break;
- }
- }
- break;
-
- case USB_REQ_SETCONFIGURATION:
- {
- if (ctrl->type == 0)
- {
- ret = cdcacm_setconfig(priv, value);
- }
- }
- break;
-
- /* If the serial device is used in as part of a composite device,
- * then the overall composite class configuration is managed by logic
- * in the composite device implementation.
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
- case USB_REQ_GETCONFIGURATION:
- {
- if (ctrl->type == USB_DIR_IN)
- {
- *(uint8_t*)ctrlreq->buf = priv->config;
- ret = 1;
- }
- }
- break;
-#endif
-
- case USB_REQ_SETINTERFACE:
- {
- if (ctrl->type == USB_REQ_RECIPIENT_INTERFACE &&
- priv->config == CDCACM_CONFIGID)
- {
- if ((index == CDCACM_NOTIFID && value == CDCACM_NOTALTIFID) ||
- (index == CDCACM_DATAIFID && value == CDCACM_DATAALTIFID))
- {
- cdcacm_resetconfig(priv);
- cdcacm_setconfig(priv, priv->config);
- ret = 0;
- }
- }
- }
- break;
-
- case USB_REQ_GETINTERFACE:
- {
- if (ctrl->type == (USB_DIR_IN|USB_REQ_RECIPIENT_INTERFACE) &&
- priv->config == CDCACM_CONFIGIDNONE)
- {
- if ((index == CDCACM_NOTIFID && value == CDCACM_NOTALTIFID) ||
- (index == CDCACM_DATAIFID && value == CDCACM_DATAALTIFID))
- {
- *(uint8_t*) ctrlreq->buf = value;
- ret = 1;
- }
- else
- {
- ret = -EDOM;
- }
- }
- }
- break;
-
- default:
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDSTDREQ), ctrl->req);
- break;
- }
- }
-
- else if ((ctrl->type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_CLASS)
- {
- /***********************************************************************
- * CDC ACM-Specific Requests
- ***********************************************************************/
-
- switch (ctrl->req)
- {
- /* ACM_GET_LINE_CODING requests current DTE rate, stop-bits, parity, and
- * number-of-character bits. (Optional)
- */
-
- case ACM_GET_LINE_CODING:
- {
- if (ctrl->type == (USB_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE) &&
- index == CDCACM_NOTIFID)
- {
- /* Return the current line status from the private data structure */
-
- memcpy(ctrlreq->buf, &priv->linecoding, SIZEOF_CDC_LINECODING);
- ret = SIZEOF_CDC_LINECODING;
- }
- else
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDCLASSREQ), ctrl->type);
- }
- }
- break;
-
- /* ACM_SET_LINE_CODING configures DTE rate, stop-bits, parity, and
- * number-of-character bits. (Optional)
- */
-
- case ACM_SET_LINE_CODING:
- {
- if (ctrl->type == (USB_DIR_OUT|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE) &&
- len == SIZEOF_CDC_LINECODING && /* dataout && len == outlen && */
- index == CDCACM_NOTIFID)
- {
- /* Save the new line coding in the private data structure. NOTE:
- * that this is conditional now because not all device controller
- * drivers supported provisioni of EP0 OUT data with the setup
- * command.
- */
-
- if (dataout && len <= SIZEOF_CDC_LINECODING) /* REVISIT */
- {
- memcpy(&priv->linecoding, dataout, SIZEOF_CDC_LINECODING);
- }
- ret = 0;
-
- /* If there is a registered callback to receive line status info, then
- * callout now.
- */
-
- if (priv->callback)
- {
- priv->callback(CDCACM_EVENT_LINECODING);
- }
- }
- else
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDCLASSREQ), ctrl->type);
- }
- }
- break;
-
- /* ACM_SET_CTRL_LINE_STATE: RS-232 signal used to tell the DCE device the
- * DTE device is now present. (Optional)
- */
-
- case ACM_SET_CTRL_LINE_STATE:
- {
- if (ctrl->type == (USB_DIR_OUT|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE) &&
- index == CDCACM_NOTIFID)
- {
- /* Save the control line state in the private data structure. Only bits
- * 0 and 1 have meaning.
- */
-
- priv->ctrlline = value & 3;
- ret = 0;
-
- /* If there is a registered callback to receive control line status info,
- * then callout now.
- */
-
- if (priv->callback)
- {
- priv->callback(CDCACM_EVENT_CTRLLINE);
- }
- }
- else
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDCLASSREQ), ctrl->type);
- }
- }
- break;
-
- /* Sends special carrier*/
-
- case ACM_SEND_BREAK:
- {
- if (ctrl->type == (USB_DIR_OUT|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE) &&
- index == CDCACM_NOTIFID)
- {
- /* If there is a registered callback to handle the SendBreak request,
- * then callout now.
- */
-
- ret = 0;
- if (priv->callback)
- {
- priv->callback(CDCACM_EVENT_SENDBREAK);
- }
- }
- else
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDCLASSREQ), ctrl->type);
- }
- }
- break;
-
- default:
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDCLASSREQ), ctrl->req);
- break;
- }
- }
- else
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDTYPE), ctrl->type);
- }
-
- /* Respond to the setup command if data was returned. On an error return
- * value (ret < 0), the USB driver will stall.
- */
-
- if (ret >= 0)
- {
- /* Configure the response */
-
- ctrlreq->len = MIN(len, ret);
- ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;
-
- /* Send the response -- either directly to the USB controller or
- * indirectly in the case where this class is a member of a composite
- * device.
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
- ret = EP_SUBMIT(dev->ep0, ctrlreq);
-#else
- ret = composite_ep0submit(driver, dev, ctrlreq);
-#endif
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPRESPQ), (uint16_t)-ret);
- ctrlreq->result = OK;
- cdcacm_ep0incomplete(dev->ep0, ctrlreq);
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: cdcacm_disconnect
- *
- * Description:
- * Invoked after all transfers have been stopped, when the host is
- * disconnected. This function is probably called from the context of an
- * interrupt handler.
- *
- ****************************************************************************/
-
-static void cdcacm_disconnect(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct cdcacm_dev_s *priv;
- irqstate_t flags;
-
- usbtrace(TRACE_CLASSDISCONNECT, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Inform the "upper half serial driver that we have lost the USB serial
- * connection.
- */
-
- flags = irqsave();
-#ifdef CONFIG_SERIAL_REMOVABLE
- uart_connected(&priv->serdev, false);
-#endif
-
- /* Reset the configuration */
-
- cdcacm_resetconfig(priv);
-
- /* Clear out all outgoing data in the circular buffer */
-
- priv->serdev.xmit.head = 0;
- priv->serdev.xmit.tail = 0;
- irqrestore(flags);
-
- /* Perform the soft connect function so that we will we can be
- * re-enumerated (unless we are part of a composite device)
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
- DEV_CONNECT(dev);
-#endif
-}
-
-/****************************************************************************
- * Name: cdcacm_suspend
- *
- * Description:
- * Handle the USB suspend event.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_SERIAL_REMOVABLE
-static void cdcacm_suspend(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct cdcacm_dev_s *priv;
-
- usbtrace(TRACE_CLASSSUSPEND, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
-
- /* And let the "upper half" driver now that we are suspended */
-
- uart_connected(&priv->serdev, false);
-}
-#endif
-
-/****************************************************************************
- * Name: cdcacm_resume
- *
- * Description:
- * Handle the USB resume event.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_SERIAL_REMOVABLE
-static void cdcacm_resume(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct cdcacm_dev_s *priv;
-
- usbtrace(TRACE_CLASSRESUME, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
-
- /* Are we still configured? */
-
- if (priv->config != CDCACM_CONFIGIDNONE)
- {
- /* Yes.. let the "upper half" know that have resumed */
-
- uart_connected(&priv->serdev, true);
- }
-}
-#endif
-
-/****************************************************************************
- * Serial Device Methods
- ****************************************************************************/
-
-/****************************************************************************
- * Name: cdcuart_setup
- *
- * Description:
- * This method is called the first time that the serial port is opened.
- *
- ****************************************************************************/
-
-static int cdcuart_setup(FAR struct uart_dev_s *dev)
-{
- FAR struct cdcacm_dev_s *priv;
-
- usbtrace(CDCACM_CLASSAPI_SETUP, 0);
-
- /* Sanity check */
-
-#if CONFIG_DEBUG
- if (!dev || !dev->priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return -EIO;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = (FAR struct cdcacm_dev_s*)dev->priv;
-
- /* Check if we have been configured */
-
- if (priv->config == CDCACM_CONFIGIDNONE)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_SETUPNOTCONNECTED), 0);
- return -ENOTCONN;
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: cdcuart_shutdown
- *
- * Description:
- * This method is called when the serial port is closed. This operation
- * is very simple for the USB serial backend because the serial driver
- * has already assured that the TX data has full drained -- it calls
- * cdcuart_txempty() until that function returns true before calling this
- * function.
- *
- ****************************************************************************/
-
-static void cdcuart_shutdown(FAR struct uart_dev_s *dev)
-{
- usbtrace(CDCACM_CLASSAPI_SHUTDOWN, 0);
-
- /* Sanity check */
-
-#if CONFIG_DEBUG
- if (!dev || !dev->priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- }
-#endif
-}
-
-/****************************************************************************
- * Name: cdcuart_attach
- *
- * Description:
- * Does not apply to the USB serial class device
- *
- ****************************************************************************/
-
-static int cdcuart_attach(FAR struct uart_dev_s *dev)
-{
- usbtrace(CDCACM_CLASSAPI_ATTACH, 0);
- return OK;
-}
-
-/****************************************************************************
- * Name: cdcuart_detach
- *
- * Description:
-* Does not apply to the USB serial class device
- *
- ****************************************************************************/
-
-static void cdcuart_detach(FAR struct uart_dev_s *dev)
-{
- usbtrace(CDCACM_CLASSAPI_DETACH, 0);
-}
-
-/****************************************************************************
- * Name: cdcuart_ioctl
- *
- * Description:
- * All ioctl calls will be routed through this method
- *
- ****************************************************************************/
-
-static int cdcuart_ioctl(FAR struct file *filep,int cmd,unsigned long arg)
-{
- struct inode *inode = filep->f_inode;
- struct cdcacm_dev_s *priv = inode->i_private;
- int ret = OK;
-
- switch (cmd)
- {
- /* CAICO_REGISTERCB
- * Register a callback for serial event notification. Argument:
- * cdcacm_callback_t. See cdcacm_callback_t type definition below.
- * NOTE: The callback will most likely invoked at the interrupt level.
- * The called back function should, therefore, limit its operations to
- * invoking some kind of IPC to handle the serial event in some normal
- * task environment.
- */
-
- case CAIOC_REGISTERCB:
- {
- /* Save the new callback function */
-
- priv->callback = (cdcacm_callback_t)((uintptr_t)arg);
- }
- break;
-
- /* CAIOC_GETLINECODING
- * Get current line coding. Argument: struct cdc_linecoding_s*.
- * See include/nuttx/usb/cdc.h for structure definition. This IOCTL
- * should be called to get the data associated with the
- * CDCACM_EVENT_LINECODING event).
- */
-
- case CAIOC_GETLINECODING:
- {
- FAR struct cdc_linecoding_s *ptr = (FAR struct cdc_linecoding_s *)((uintptr_t)arg);
- if (ptr)
- {
- memcpy(ptr, &priv->linecoding, sizeof(struct cdc_linecoding_s));
- }
- else
- {
- ret = -EINVAL;
- }
- }
- break;
-
- /* CAIOC_GETCTRLLINE
- * Get control line status bits. Argument FAR int*. See
- * include/nuttx/usb/cdc.h for bit definitions. This IOCTL should be
- * called to get the data associated CDCACM_EVENT_CTRLLINE event.
- */
-
- case CAIOC_GETCTRLLINE:
- {
- FAR int *ptr = (FAR int *)((uintptr_t)arg);
- if (ptr)
- {
- *ptr = priv->ctrlline;
- }
- else
- {
- ret = -EINVAL;
- }
- }
- break;
-
- /* CAIOC_NOTIFY
- * Send a serial state to the host via the Interrupt IN endpoint.
- * Argument: int. This includes the current state of the carrier detect,
- * DSR, break, and ring signal. See "Table 69: UART State Bitmap Values"
- * and CDC_UART_definitions in include/nuttx/usb/cdc.h.
- */
-
- case CAIOC_NOTIFY:
- {
- /* Not yet implemented. I probably won't bother to implement until
- * I comr up with a usage model that needs it.
- *
- * Here is what the needs to be done:
- *
- * 1. Format and send a request header with:
- *
- * bmRequestType:
- * USB_REQ_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE
- * bRequest: ACM_SERIAL_STATE
- * wValue: 0
- * wIndex: 0
- * wLength: Length of data
- *
- * 2. Followed by the notification data (in a separate packet)
- */
-
- ret = -ENOSYS;
- }
- break;
-
- default:
- ret = -ENOTTY;
- break;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: cdcuart_rxint
- *
- * Description:
- * Called by the serial driver to enable or disable RX interrupts. We, of
- * course, have no RX interrupts but must behave consistently. This method
- * is called under the conditions:
- *
- * 1. With enable==true when the port is opened (just after cdcuart_setup
- * and cdcuart_attach are called called)
- * 2. With enable==false while transferring data from the RX buffer
- * 2. With enable==true while waiting for more incoming data
- * 3. With enable==false when the port is closed (just before cdcuart_detach
- * and cdcuart_shutdown are called).
- *
- ****************************************************************************/
-
-static void cdcuart_rxint(FAR struct uart_dev_s *dev, bool enable)
-{
- FAR struct cdcacm_dev_s *priv;
- FAR uart_dev_t *serdev;
- irqstate_t flags;
-
- usbtrace(CDCACM_CLASSAPI_RXINT, (uint16_t)enable);
-
- /* Sanity check */
-
-#if CONFIG_DEBUG
- if (!dev || !dev->priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = (FAR struct cdcacm_dev_s*)dev->priv;
- serdev = &priv->serdev;
-
- /* We need exclusive access to the RX buffer and private structure
- * in the following.
- */
-
- flags = irqsave();
- if (enable)
- {
- /* RX "interrupts" are enabled. Is this a transition from disabled
- * to enabled state?
- */
-
- if (!priv->rxenabled)
- {
- /* Yes. During the time that RX interrupts are disabled, the
- * the serial driver will be extracting data from the circular
- * buffer and modifying recv.tail. During this time, we
- * should avoid modifying recv.head; When interrupts are restored,
- * we can update the head pointer for all of the data that we
- * put into cicular buffer while "interrupts" were disabled.
- */
-
- if (priv->rxhead != serdev->recv.head)
- {
- serdev->recv.head = priv->rxhead;
-
- /* Yes... signal the availability of new data */
-
- uart_datareceived(serdev);
- }
-
- /* RX "interrupts are no longer disabled */
-
- priv->rxenabled = true;
- }
- }
-
- /* RX "interrupts" are disabled. Is this a transition from enabled
- * to disabled state?
- */
-
- else if (priv->rxenabled)
- {
- /* Yes. During the time that RX interrupts are disabled, the
- * the serial driver will be extracting data from the circular
- * buffer and modifying recv.tail. During this time, we
- * should avoid modifying recv.head; When interrupts are disabled,
- * we use a shadow index and continue adding data to the circular
- * buffer.
- */
-
- priv->rxhead = serdev->recv.head;
- priv->rxenabled = false;
- }
- irqrestore(flags);
-}
-
-/****************************************************************************
- * Name: cdcuart_txint
- *
- * Description:
- * Called by the serial driver to enable or disable TX interrupts. We, of
- * course, have no TX interrupts but must behave consistently. Initially,
- * TX interrupts are disabled. This method is called under the conditions:
- *
- * 1. With enable==false while transferring data into the TX buffer
- * 2. With enable==true when data may be taken from the buffer.
- * 3. With enable==false when the TX buffer is empty
- *
- ****************************************************************************/
-
-static void cdcuart_txint(FAR struct uart_dev_s *dev, bool enable)
-{
- FAR struct cdcacm_dev_s *priv;
-
- usbtrace(CDCACM_CLASSAPI_TXINT, (uint16_t)enable);
-
- /* Sanity checks */
-
-#if CONFIG_DEBUG
- if (!dev || !dev->priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract references to private data */
-
- priv = (FAR struct cdcacm_dev_s*)dev->priv;
-
- /* If the new state is enabled and if there is data in the XMIT buffer,
- * send the next packet now.
- */
-
- uvdbg("enable=%d head=%d tail=%d\n",
- enable, priv->serdev.xmit.head, priv->serdev.xmit.tail);
-
- if (enable && priv->serdev.xmit.head != priv->serdev.xmit.tail)
- {
- cdcacm_sndpacket(priv);
- }
-}
-
-/****************************************************************************
- * Name: cdcuart_txempty
- *
- * Description:
- * Return true when all data has been sent. This is called from the
- * serial driver when the driver is closed. It will call this API
- * periodically until it reports true. NOTE that the serial driver takes all
- * responsibility for flushing TX data through the hardware so we can be
- * a bit sloppy about that.
- *
- ****************************************************************************/
-
-static bool cdcuart_txempty(FAR struct uart_dev_s *dev)
-{
- FAR struct cdcacm_dev_s *priv = (FAR struct cdcacm_dev_s*)dev->priv;
-
- usbtrace(CDCACM_CLASSAPI_TXEMPTY, 0);
-
-#if CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return true;
- }
-#endif
-
- /* When all of the allocated write requests have been returned to the
- * reqlist, then there is no longer any TX data in flight.
- */
-
- return priv->nwrq >= CONFIG_CDCACM_NWRREQS;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: cdcacm_classobject
- *
- * Description:
- * Register USB serial port (and USB serial console if so configured) and
- * return the class object.
- *
- * Input Parameter:
- * minor - Device minor number. E.g., minor 0 would correspond to
- * /dev/ttyACM0.
- * classdev - The location to return the CDC serial class' device
- * instance.
- *
- * Returned Value:
- * A pointer to the allocated class object (NULL on failure).
- *
- ****************************************************************************/
-
-#ifndef CONFIG_CDCACM_COMPOSITE
-static
-#endif
-int cdcacm_classobject(int minor, FAR struct usbdevclass_driver_s **classdev)
-{
- FAR struct cdcacm_alloc_s *alloc;
- FAR struct cdcacm_dev_s *priv;
- FAR struct cdcacm_driver_s *drvr;
- char devname[CDCACM_DEVNAME_SIZE];
- int ret;
-
- /* Allocate the structures needed */
-
- alloc = (FAR struct cdcacm_alloc_s*)kmalloc(sizeof(struct cdcacm_alloc_s));
- if (!alloc)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCDEVSTRUCT), 0);
- return -ENOMEM;
- }
-
- /* Convenience pointers into the allocated blob */
-
- priv = &alloc->dev;
- drvr = &alloc->drvr;
-
- /* Initialize the USB serial driver structure */
-
- memset(priv, 0, sizeof(struct cdcacm_dev_s));
- sq_init(&priv->reqlist);
-
- priv->minor = minor;
-
- /* Fake line status */
-
- priv->linecoding.baud[0] = (115200) & 0xff; /* Baud=115200 */
- priv->linecoding.baud[1] = (115200 >> 8) & 0xff;
- priv->linecoding.baud[2] = (115200 >> 16) & 0xff;
- priv->linecoding.baud[3] = (115200 >> 24) & 0xff;
- priv->linecoding.stop = CDC_CHFMT_STOP1; /* One stop bit */
- priv->linecoding.parity = CDC_PARITY_NONE; /* No parity */
- priv->linecoding.nbits = 8; /* 8 data bits */
-
- /* Initialize the serial driver sub-structure */
-
- /* The initial state is disconnected */
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- priv->serdev.disconnected = true;
-#endif
- priv->serdev.recv.size = CONFIG_CDCACM_RXBUFSIZE;
- priv->serdev.recv.buffer = priv->rxbuffer;
- priv->serdev.xmit.size = CONFIG_CDCACM_TXBUFSIZE;
- priv->serdev.xmit.buffer = priv->txbuffer;
- priv->serdev.ops = &g_uartops;
- priv->serdev.priv = priv;
-
- /* Initialize the USB class driver structure */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- drvr->drvr.speed = USB_SPEED_HIGH;
-#else
- drvr->drvr.speed = USB_SPEED_FULL;
-#endif
- drvr->drvr.ops = &g_driverops;
- drvr->dev = priv;
-
- /* Register the USB serial console */
-
-#ifdef CONFIG_CDCACM_CONSOLE
- priv->serdev.isconsole = true;
- ret = uart_register("/dev/console", &priv->serdev);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_CONSOLEREGISTER), (uint16_t)-ret);
- goto errout_with_class;
- }
-#endif
-
- /* Register the CDC/ACM TTY device */
-
- sprintf(devname, CDCACM_DEVNAME_FORMAT, minor);
- ret = uart_register(devname, &priv->serdev);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UARTREGISTER), (uint16_t)-ret);
- goto errout_with_class;
- }
-
- *classdev = &drvr->drvr;
- return OK;
-
-errout_with_class:
- kfree(alloc);
- return ret;
-}
-
-/****************************************************************************
- * Name: cdcacm_initialize
- *
- * Description:
- * Register USB serial port (and USB serial console if so configured).
- *
- * Input Parameter:
- * minor - Device minor number. E.g., minor 0 would correspond to
- * /dev/ttyACM0.
- * handle - An optional opaque reference to the CDC/ACM class object that
- * may subsequently be used with cdcacm_uninitialize().
- *
- * Returned Value:
- * Zero (OK) means that the driver was successfully registered. On any
- * failure, a negated errno value is retured.
- *
- ****************************************************************************/
-
-#ifndef CONFIG_CDCACM_COMPOSITE
-int cdcacm_initialize(int minor, FAR void **handle)
-{
- FAR struct usbdevclass_driver_s *drvr = NULL;
- int ret;
-
- /* Get an instance of the serial driver class object */
-
- ret = cdcacm_classobject(minor, &drvr);
- if (ret == OK)
- {
- /* Register the USB serial class driver */
-
- ret = usbdev_register(drvr);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_DEVREGISTER), (uint16_t)-ret);
- }
- }
-
- /* Return the driver instance (if any) if the caller has requested it
- * by provided a pointer to the location to return it.
- */
-
- if (handle)
- {
- *handle = (FAR void*)drvr;
- }
-
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Name: cdcacm_uninitialize
- *
- * Description:
- * Un-initialize the USB storage class driver. This function is used
- * internally by the USB composite driver to unitialize the CDC/ACM
- * driver. This same interface is available (with an untyped input
- * parameter) when the CDC/ACM driver is used standalone.
- *
- * Input Parameters:
- * There is one parameter, it differs in typing depending upon whether the
- * CDC/ACM driver is an internal part of a composite device, or a standalone
- * USB driver:
- *
- * classdev - The class object returned by board_cdcclassobject() or
- * cdcacm_classobject()
- * handle - The opaque handle represetning the class object returned by
- * a previous call to cdcacm_initialize().
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-#ifdef CONFIG_CDCACM_COMPOSITE
-void cdcacm_uninitialize(FAR struct usbdevclass_driver_s *classdev)
-#else
-void cdcacm_uninitialize(FAR void *handle)
-#endif
-{
-#ifdef CONFIG_CDCACM_COMPOSITE
- FAR struct cdcacm_driver_s *drvr = (FAR struct cdcacm_driver_s *)classdev;
-#else
- FAR struct cdcacm_driver_s *drvr = (FAR struct cdcacm_driver_s *)handle;
-#endif
- FAR struct cdcacm_dev_s *priv = drvr->dev;
- char devname[CDCACM_DEVNAME_SIZE];
- int ret;
-
- /* Un-register the CDC/ACM TTY device */
-
- sprintf(devname, CDCACM_DEVNAME_FORMAT, priv->minor);
- ret = unregister_driver(devname);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UARTUNREGISTER), (uint16_t)-ret);
- }
-
- /* Unregister the driver (unless we are a part of a composite device). The
- * device unregister logic will (1) return all of the requests to us then
- * (2) all the unbind method.
- *
- * The same thing will happen in the composite case except that: (1) the
- * composite driver will call usbdev_unregister() which will (2) return the
- * requests for all members of the composite, and (3) call the unbind
- * method in the composite device which will (4) call the unbind method
- * for this device.
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
- usbdev_unregister(&drvr->drvr);
-#endif
-
- /* And free the driver structure */
-
- kfree(priv);
-}
diff --git a/nuttx/drivers/usbdev/cdcacm.h b/nuttx/drivers/usbdev/cdcacm.h
deleted file mode 100644
index 8b06ca9f3..000000000
--- a/nuttx/drivers/usbdev/cdcacm.h
+++ /dev/null
@@ -1,350 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/cdcacm.h
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_USBDEV_CDCACM_H
-#define __DRIVERS_USBDEV_CDCACM_H 1
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdint.h>
-
-#include <nuttx/usb/usbdev.h>
-#include <nuttx/usb/cdc.h>
-#include <nuttx/usb/usbdev_trace.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Configuration ************************************************************/
-/* If the serial device is configured as part of a composite device than both
- * CONFIG_USBDEV_COMPOSITE and CONFIG_CDCACM_COMPOSITE must be defined.
- */
-
-#ifndef CONFIG_USBDEV_COMPOSITE
-# undef CONFIG_CDCACM_COMPOSITE
-#endif
-
-#if defined(CONFIG_CDCACM_COMPOSITE) && !defined(CONFIG_CDCACM_STRBASE)
-# define CONFIG_CDCACM_STRBASE (4)
-#endif
-
-#if defined(CONFIG_CDCACM_COMPOSITE) && !defined(CONFIG_COMPOSITE_IAD)
-# warning "CONFIG_COMPOSITE_IAD may be needed"
-#endif
-
-/* Packet and request buffer sizes */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
-# ifndef CONFIG_CDCACM_EP0MAXPACKET
-# define CONFIG_CDCACM_EP0MAXPACKET 64
-# endif
-#endif
-
-/* Interface IDs. If the serial driver is built as a component of a composite
- * device, then the interface IDs may need to be offset.
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
-# undef CONFIG_CDCACM_IFNOBASE
-# define CONFIG_CDCACM_IFNOBASE 0
-#endif
-
-#ifndef CONFIG_CDCACM_IFNOBASE
-# define CONFIG_CDCACM_IFNOBASE 0
-#endif
-
-/* Descriptors **************************************************************/
-/* These settings are not modifiable via the NuttX configuration */
-
-#define CDC_VERSIONNO 0x0110 /* CDC version number 1.10 (BCD) */
-#define CDCACM_CONFIGIDNONE (0) /* Config ID means to return to address mode */
-
-/* Interface IDs:
- *
- * CDCACM_NINTERFACES Two interfaces
- * CDCACM_NOTIFID ID of the notifier interface
- * CDCACM_NOTALTIFID No alternate for the notifier interface
- * CDCACM_DATAIFID ID of the data interface
- * CDCACM_DATAALTIFID No alternate for the data interface
- */
-
-#define CDCACM_NINTERFACES (2) /* Number of interfaces in the configuration */
-#define CDCACM_NOTIFID (CONFIG_CDCACM_IFNOBASE+0)
-#define CDCACM_NOTALTIFID (0)
-#define CDCACM_DATAIFID (CONFIG_CDCACM_IFNOBASE+1)
-#define CDCACM_DATAALTIFID (0)
-
-/* Configuration descriptor values */
-
-#define CDCACM_CONFIGID (1) /* The only supported configuration ID */
-
-/* Buffer big enough for any of our descriptors (the config descriptor is the
- * biggest).
- */
-
-#define CDCACM_MXDESCLEN (64)
-
-/* Device descriptor values */
-
-#define CDCACM_VERSIONNO (0x0101) /* Device version number 1.1 (BCD) */
-#define CDCACM_NCONFIGS (1) /* Number of configurations supported */
-
-/* String language */
-
-#define CDCACM_STR_LANGUAGE (0x0409) /* en-us */
-
-/* Descriptor strings. If there serial device is part of a composite device
- * then the manufacturer, product, and serial number strings will be provided
- * by the composite logic.
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
-# define CDCACM_MANUFACTURERSTRID (1)
-# define CDCACM_PRODUCTSTRID (2)
-# define CDCACM_SERIALSTRID (3)
-# define CDCACM_CONFIGSTRID (4)
-
-# define CDCACM_LASTBASESTRID (4)
-# undef CONFIG_CDCACM_STRBASE
-# define CONFIG_CDCACM_STRBASE (0)
-#else
-# define CDCACM_LASTBASESTRID CONFIG_CDCACM_STRBASE
-#endif
-
-/* These string IDs only exist if a user-defined string is provided */
-
-#ifdef CONFIG_CDCACM_NOTIFSTR
-# define CDCACM_NOTIFSTRID (CDCACM_LASTBASESTRID+1)
-#else
-# define CDCACM_NOTIFSTRID CDCACM_LASTBASESTRID
-#endif
-
-#ifdef CONFIG_CDCACM_DATAIFSTR
-# define CDCACM_DATAIFSTRID (CDCACM_NOTIFSTRID+1)
-#else
-# define CDCACM_DATAIFSTRID CDCACM_NOTIFSTRID
-#endif
-
-#define CDCACM_LASTSTRID CDCACM_DATAIFSTRID
-#define CDCACM_NSTRIDS (CDCACM_LASTSTRID - CONFIG_CDCACM_STRBASE)
-
-/* Configuration descriptor size */
-
-#if !defined(CONFIG_CDCACM_COMPOSITE)
-
-/* Number of individual descriptors in the configuration descriptor:
- * Configuration descriptor + (2) interface descriptors + (3) endpoint
- * descriptors + (3) ACM descriptors.
- */
-
-# define CDCACM_CFGGROUP_SIZE (9)
-
-/* The size of the config descriptor: (9 + 2*9 + 3*7 + 4 + 5 + 5) = 62 */
-
-# define SIZEOF_CDCACM_CFGDESC \
- (USB_SIZEOF_CFGDESC + 2*USB_SIZEOF_IFDESC + 3*USB_SIZEOF_EPDESC + \
- SIZEOF_ACM_FUNCDESC + SIZEOF_HDR_FUNCDESC + SIZEOF_UNION_FUNCDESC(1))
-
-#elif defined(CONFIG_COMPOSITE_IAD)
-
-/* Number of individual descriptors in the configuration descriptor:
- * (1) interface association descriptor + (2) interface descriptors +
- * (3) endpoint descriptors + (3) ACM descriptors.
- */
-
-# define CDCACM_CFGGROUP_SIZE (9)
-
-/* The size of the config descriptor: (8 + 2*9 + 3*7 + 4 + 5 + 5) = 61 */
-
-# define SIZEOF_CDCACM_CFGDESC \
- (USB_SIZEOF_IADDESC +2*USB_SIZEOF_IFDESC + 3*USB_SIZEOF_EPDESC + \
- SIZEOF_ACM_FUNCDESC + SIZEOF_HDR_FUNCDESC + SIZEOF_UNION_FUNCDESC(1))
-
-#else
-
-/* Number of individual descriptors in the configuration descriptor:
- * (2) interface descriptors + (3) endpoint descriptors + (3) ACM descriptors.
- */
-
-# define CDCACM_CFGGROUP_SIZE (8)
-
-/* The size of the config descriptor: (2*9 + 3*7 + 4 + 5 + 5) = 53 */
-
-# define SIZEOF_CDCACM_CFGDESC \
- (2*USB_SIZEOF_IFDESC + 3*USB_SIZEOF_EPDESC + SIZEOF_ACM_FUNCDESC + \
- SIZEOF_HDR_FUNCDESC + SIZEOF_UNION_FUNCDESC(1))
-#endif
-
-/* Endpoint configuration ****************************************************/
-
-#define CDCACM_EPINTIN_ADDR (USB_DIR_IN|CONFIG_CDCACM_EPINTIN)
-#define CDCACM_EPINTIN_ATTR (USB_EP_ATTR_XFER_INT)
-
-#define CDCACM_EPOUTBULK_ADDR (CONFIG_CDCACM_EPBULKOUT)
-#define CDCACM_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK)
-
-#define CDCACM_EPINBULK_ADDR (USB_DIR_IN|CONFIG_CDCACM_EPBULKIN)
-#define CDCACM_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK)
-
-/* Device driver definitions ************************************************/
-/* A CDC/ACM device is specific by a minor number in the range of 0-255.
- * This maps to a character device at /dev/ttyACMx, x=0..255.
- */
-
-#define CDCACM_DEVNAME_FORMAT "/dev/ttyACM%d"
-#define CDCACM_DEVNAME_SIZE 16
-
-/* Misc Macros **************************************************************/
-/* MIN/MAX macros */
-
-#ifndef MIN
-# define MIN(a,b) ((a)<(b)?(a):(b))
-#endif
-
-#ifndef MAX
-# define MAX(a,b) ((a)>(b)?(a):(b))
-#endif
-
-/* Trace values *************************************************************/
-
-#define CDCACM_CLASSAPI_SETUP TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SETUP)
-#define CDCACM_CLASSAPI_SHUTDOWN TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SHUTDOWN)
-#define CDCACM_CLASSAPI_ATTACH TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_ATTACH)
-#define CDCACM_CLASSAPI_DETACH TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_DETACH)
-#define CDCACM_CLASSAPI_IOCTL TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_IOCTL)
-#define CDCACM_CLASSAPI_RECEIVE TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RECEIVE)
-#define CDCACM_CLASSAPI_RXINT TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RXINT)
-#define CDCACM_CLASSAPI_RXAVAILABLE TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RXAVAILABLE)
-#define CDCACM_CLASSAPI_SEND TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SEND)
-#define CDCACM_CLASSAPI_TXINT TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXINT)
-#define CDCACM_CLASSAPI_TXREADY TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXREADY)
-#define CDCACM_CLASSAPI_TXEMPTY TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXEMPTY)
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-enum cdcacm_epdesc_e
-{
- CDCACM_EPINTIN = 0, /* Interrupt IN endpoint descriptor */
- CDCACM_EPBULKOUT, /* Bulk OUT endpoint descriptor */
- CDCACM_EPBULKIN /* Bulk IN endpoint descriptor */
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Name: cdcacm_mkstrdesc
- *
- * Description:
- * Construct a string descriptor
- *
- ****************************************************************************/
-
-int cdcacm_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
-
-/****************************************************************************
- * Name: cdcacm_getepdesc
- *
- * Description:
- * Return a pointer to the raw device descriptor
- *
- ****************************************************************************/
-
-#ifndef CONFIG_CDCACM_COMPOSITE
-FAR const struct usb_devdesc_s *cdcacm_getdevdesc(void);
-#endif
-
-/****************************************************************************
- * Name: cdcacm_getepdesc
- *
- * Description:
- * Return a pointer to the raw endpoint descriptor (used for configuring
- * endpoints)
- *
- ****************************************************************************/
-
-FAR const struct usb_epdesc_s *cdcacm_getepdesc(enum cdcacm_epdesc_e epid);
-
-/****************************************************************************
- * Name: cdcacm_mkepdesc
- *
- * Description:
- * Construct the endpoint descriptor using the correct max packet size.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-void cdcacm_mkepdesc(enum cdcacm_epdesc_e epid,
- uint16_t mxpacket, FAR struct usb_epdesc_s *outdesc);
-#endif
-
-/****************************************************************************
- * Name: cdcacm_mkcfgdesc
- *
- * Description:
- * Construct the configuration descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type);
-#else
-int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf);
-#endif
-
-/****************************************************************************
- * Name: cdcacm_getqualdesc
- *
- * Description:
- * Return a pointer to the raw qual descriptor
- *
- ****************************************************************************/
-
-#if !defined(CONFIG_CDCACM_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
-FAR const struct usb_qualdesc_s *cdcacm_getqualdesc(void);
-#endif
-
-#endif /* __DRIVERS_USBDEV_CDCACM_H */
diff --git a/nuttx/drivers/usbdev/cdcacm_desc.c b/nuttx/drivers/usbdev/cdcacm_desc.c
deleted file mode 100644
index fde13bfd3..000000000
--- a/nuttx/drivers/usbdev/cdcacm_desc.c
+++ /dev/null
@@ -1,613 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/cdcacm_desc.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/cdc.h>
-#include <nuttx/usb/cdcacm.h>
-#include <nuttx/usb/usbdev_trace.h>
-
-#include "cdcacm.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* Describes one description in the group of descriptors forming the
- * total configuration descriptor.
- */
-
-struct cfgdecsc_group_s
-{
- uint16_t descsize; /* Size of the descriptor in bytes */
- uint16_t hsepsize; /* High speed max packet size */
- FAR void *desc; /* A pointer to the descriptor */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* USB descriptor templates these will be copied and modified **************/
-/* Device Descriptor. If the USB serial device is configured as part of
- * composite device, then the device descriptor will be provided by the
- * composite device logic.
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
-static const struct usb_devdesc_s g_devdesc =
-{
- USB_SIZEOF_DEVDESC, /* len */
- USB_DESC_TYPE_DEVICE, /* type */
- { /* usb */
- LSBYTE(0x0200),
- MSBYTE(0x0200)
- },
- USB_CLASS_CDC, /* class */
- CDC_SUBCLASS_NONE, /* subclass */
- CDC_PROTO_NONE, /* protocol */
- CONFIG_CDCACM_EP0MAXPACKET, /* maxpacketsize */
- {
- LSBYTE(CONFIG_CDCACM_VENDORID), /* vendor */
- MSBYTE(CONFIG_CDCACM_VENDORID)
- },
- {
- LSBYTE(CONFIG_CDCACM_PRODUCTID), /* product */
- MSBYTE(CONFIG_CDCACM_PRODUCTID)
- },
- {
- LSBYTE(CDCACM_VERSIONNO), /* device */
- MSBYTE(CDCACM_VERSIONNO)
- },
- CDCACM_MANUFACTURERSTRID, /* imfgr */
- CDCACM_PRODUCTSTRID, /* iproduct */
- CDCACM_SERIALSTRID, /* serno */
- CDCACM_NCONFIGS /* nconfigs */
-};
-#endif
-
-/* Configuration descriptor. If the USB serial device is configured as part of
- * composite device, then the configuration descriptor will be provided by the
- * composite device logic.
- */
-
-#ifndef CONFIG_CDCACM_COMPOSITE
-static const struct usb_cfgdesc_s g_cfgdesc =
-{
- USB_SIZEOF_CFGDESC, /* len */
- USB_DESC_TYPE_CONFIG, /* type */
- {
- LSBYTE(SIZEOF_CDCACM_CFGDESC), /* LS totallen */
- MSBYTE(SIZEOF_CDCACM_CFGDESC) /* MS totallen */
- },
- CDCACM_NINTERFACES, /* ninterfaces */
- CDCACM_CONFIGID, /* cfgvalue */
- CDCACM_CONFIGSTRID, /* icfg */
- USB_CONFIG_ATTR_ONE|SELFPOWERED|REMOTEWAKEUP, /* attr */
- (CONFIG_USBDEV_MAXPOWER + 1) / 2 /* mxpower */
-};
-#endif
-
-/* Interface association descriptor */
-
-#if defined(CONFIG_CDCACM_COMPOSITE) && defined(CONFIG_COMPOSITE_IAD)
-static const struct usb_iaddesc_s g_iaddesc =
-{
- USB_SIZEOF_IADDESC, /* len */
- USB_DESC_TYPE_INTERFACEASSOCIATION, /* type */
- CONFIG_CDCACM_IFNOBASE, /* firstif */
- CDCACM_NINTERFACES, /* nifs */
- USB_CLASS_CDC, /* class */
- CDC_SUBCLASS_ACM, /* subclass */
- CDC_PROTO_NONE, /* protocol */
- 0 /* ifunction */
-};
-#endif
-
-/* Notification interface */
-
-static const struct usb_ifdesc_s g_notifdesc =
-{
- USB_SIZEOF_IFDESC, /* len */
- USB_DESC_TYPE_INTERFACE, /* type */
- CDCACM_NOTIFID, /* ifno */
- CDCACM_NOTALTIFID, /* alt */
- 1, /* neps */
- USB_CLASS_CDC, /* class */
- CDC_SUBCLASS_ACM, /* subclass */
- CDC_PROTO_ATM, /* proto */
-#ifdef CONFIG_CDCACM_NOTIFSTR
- CDCACM_NOTIFSTRID /* iif */
-#else
- 0 /* iif */
-#endif
-};
-
-/* Header functional descriptor */
-
-static const struct cdc_hdr_funcdesc_s g_funchdr =
-{
- SIZEOF_HDR_FUNCDESC, /* size */
- USB_DESC_TYPE_CSINTERFACE, /* type */
- CDC_DSUBTYPE_HDR, /* subtype */
- {
- LSBYTE(CDC_VERSIONNO), /* LS cdc */
- MSBYTE(CDC_VERSIONNO) /* MS cdc */
- }
-};
-
-/* ACM functional descriptor */
-
-static const struct cdc_acm_funcdesc_s g_acmfunc =
-{
- SIZEOF_ACM_FUNCDESC, /* size */
- USB_DESC_TYPE_CSINTERFACE, /* type */
- CDC_DSUBTYPE_ACM, /* subtype */
- 0x06 /* caps */
-};
-
-/* Union functional descriptor */
-
-static const struct cdc_union_funcdesc_s g_unionfunc =
-{
- SIZEOF_UNION_FUNCDESC(1), /* size */
- USB_DESC_TYPE_CSINTERFACE, /* type */
- CDC_DSUBTYPE_UNION, /* subtype */
- 0, /* master */
- {1} /* slave[0] */
-};
-
-/* Interrupt IN endpoint descriptor */
-
-static const struct usb_epdesc_s g_epintindesc =
-{
- USB_SIZEOF_EPDESC, /* len */
- USB_DESC_TYPE_ENDPOINT, /* type */
- CDCACM_EPINTIN_ADDR, /* addr */
- CDCACM_EPINTIN_ATTR, /* attr */
- {
- LSBYTE(CONFIG_CDCACM_EPINTIN_FSSIZE), /* maxpacket (full speed) */
- MSBYTE(CONFIG_CDCACM_EPINTIN_FSSIZE)
- },
- 0xff /* interval */
-};
-
-/* Data interface descriptor */
-
-static const struct usb_ifdesc_s g_dataifdesc =
-{
- USB_SIZEOF_IFDESC, /* len */
- USB_DESC_TYPE_INTERFACE, /* type */
- CDCACM_DATAIFID, /* ifno */
- CDCACM_DATAALTIFID, /* alt */
- 2, /* neps */
- USB_CLASS_CDC_DATA, /* class */
- CDC_DATA_SUBCLASS_NONE, /* subclass */
- CDC_DATA_PROTO_NONE, /* proto */
-#ifdef CONFIG_CDCACM_DATAIFSTR
- CDCACM_DATAIFSTRID /* iif */
-#else
- 0 /* iif */
-#endif
-};
-
-/* Bulk OUT endpoint descriptor */
-
-static const struct usb_epdesc_s g_epbulkoutdesc =
-{
- USB_SIZEOF_EPDESC, /* len */
- USB_DESC_TYPE_ENDPOINT, /* type */
- CDCACM_EPOUTBULK_ADDR, /* addr */
- CDCACM_EPOUTBULK_ATTR, /* attr */
- {
- LSBYTE(CONFIG_CDCACM_EPBULKOUT_FSSIZE), /* maxpacket (full speed) */
- MSBYTE(CONFIG_CDCACM_EPBULKOUT_FSSIZE)
- },
- 1 /* interval */
-};
-
-/* Bulk IN endpoint descriptor */
-
-static const struct usb_epdesc_s g_epbulkindesc =
-{
- USB_SIZEOF_EPDESC, /* len */
- USB_DESC_TYPE_ENDPOINT, /* type */
- CDCACM_EPINBULK_ADDR, /* addr */
- CDCACM_EPINBULK_ATTR, /* attr */
- {
- LSBYTE(CONFIG_CDCACM_EPBULKIN_FSSIZE), /* maxpacket (full speed) */
- MSBYTE(CONFIG_CDCACM_EPBULKIN_FSSIZE)
- },
- 1 /* interval */
-};
-
-/* The components of the the configuration descriptor are maintained as
- * a collection of separate descriptor structure coordinated by the
- * following array. These descriptors could have been combined into
- * one larger "super" configuration descriptor structure. However, I
- * have concerns about compiler-dependent alignment and packing. Since
- * the individual structures consist only of byte types, alignment and
- * packing is not an issue. And since the are concatentated at run time
- * instead of compile time, there should no issues there either.
- */
-
-static const struct cfgdecsc_group_s g_cfggroup[CDCACM_CFGGROUP_SIZE] =
-{
- /* Configuration Descriptor. If the serial device is used in as part
- * or a composite device, then the configuration descriptor is
- * provided by the composite device logic.
- */
-
-#if !defined(CONFIG_CDCACM_COMPOSITE)
- {
- USB_SIZEOF_CFGDESC, /* 1. Configuration descriptor */
- 0,
- (FAR void *)&g_cfgdesc
- },
-
- /* If the serial device is part of a composite device, then it should
- * begin with an interface association descriptor (IAD) because the
- * CDC/ACM device consists of more than one interface. The IAD associates
- * the two CDC/ACM interfaces with the same CDC/ACM device.
- */
-
-#elif defined(CONFIG_COMPOSITE_IAD)
- {
- USB_SIZEOF_IADDESC, /* 1. Interface association descriptor */
- 0,
- (FAR void *)&g_iaddesc
- },
-#endif
- {
- USB_SIZEOF_IFDESC, /* 2. Notification interface */
- 0,
- (FAR void *)&g_notifdesc
- },
- {
- SIZEOF_HDR_FUNCDESC, /* 3. Header functional descriptor */
- 0,
- (FAR void *)&g_funchdr
- },
- {
- SIZEOF_ACM_FUNCDESC, /* 4. ACM functional descriptor */
- 0,
- (FAR void *)&g_acmfunc
- },
- {
- SIZEOF_UNION_FUNCDESC(1), /* 5. Union functional descriptor */
- 0,
- (FAR void *)&g_unionfunc
- },
- {
- USB_SIZEOF_EPDESC, /* 6. Interrupt IN endpoint descriptor */
- CONFIG_CDCACM_EPINTIN_HSSIZE,
- (FAR void *)&g_epintindesc
- },
- {
- USB_SIZEOF_IFDESC, /* 7. Data interface descriptor */
- 0,
- (FAR void *)&g_dataifdesc
- },
- {
- USB_SIZEOF_EPDESC, /* 8. Bulk OUT endpoint descriptor */
- CONFIG_CDCACM_EPBULKOUT_HSSIZE,
- (FAR void *)&g_epbulkoutdesc
- },
- {
- USB_SIZEOF_EPDESC, /* 9. Bulk OUT endpoint descriptor */
- CONFIG_CDCACM_EPBULKIN_HSSIZE,
- (FAR void *)&g_epbulkindesc
- }
-};
-
-#if !defined(CONFIG_CDCACM_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
-static const struct usb_qualdesc_s g_qualdesc =
-{
- USB_SIZEOF_QUALDESC, /* len */
- USB_DESC_TYPE_DEVICEQUALIFIER, /* type */
- { /* usb */
- LSBYTE(0x0200),
- MSBYTE(0x0200)
- },
- USB_CLASS_VENDOR_SPEC, /* class */
- 0, /* subclass */
- 0, /* protocol */
- CONFIG_CDCACM_EP0MAXPACKET, /* mxpacketsize */
- CDCACM_NCONFIGS, /* nconfigs */
- 0, /* reserved */
-};
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: cdcacm_mkstrdesc
- *
- * Description:
- * Construct a string descriptor
- *
- ****************************************************************************/
-
-int cdcacm_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc)
-{
-#if !defined(CONFIG_CDCACM_COMPOSITE) || defined(CONFIG_CDCACM_NOTIFSTR) || \
- defined(CONFIG_CDCACM_DATAIFSTR)
-
- const char *str;
- int len;
- int ndata;
- int i;
-
- switch (id)
- {
-#ifndef CONFIG_CDCACM_COMPOSITE
- case 0:
- {
- /* Descriptor 0 is the language id */
-
- strdesc->len = 4;
- strdesc->type = USB_DESC_TYPE_STRING;
- strdesc->data[0] = LSBYTE(CDCACM_STR_LANGUAGE);
- strdesc->data[1] = MSBYTE(CDCACM_STR_LANGUAGE);
- return 4;
- }
-
- case CDCACM_MANUFACTURERSTRID:
- str = CONFIG_CDCACM_VENDORSTR;
- break;
-
- case CDCACM_PRODUCTSTRID:
- str = CONFIG_CDCACM_PRODUCTSTR;
- break;
-
- case CDCACM_SERIALSTRID:
- str = CONFIG_CDCACM_SERIALSTR;
- break;
-
- case CDCACM_CONFIGSTRID:
- str = CONFIG_CDCACM_CONFIGSTR;
- break;
-#endif
-
-#ifdef CONFIG_CDCACM_NOTIFSTR
- case CDCACM_NOTIFSTRID:
- str = CONFIG_CDCACM_NOTIFSTR;
- break;
-#endif
-
-#ifdef CONFIG_CDCACM_DATAIFSTR
- case CDCACM_DATAIFSTRID:
- str = CONFIG_CDCACM_DATAIFSTR;
- break;
-#endif
-
- default:
- return -EINVAL;
- }
-
- /* The string is utf16-le. The poor man's utf-8 to utf16-le
- * conversion below will only handle 7-bit en-us ascii
- */
-
- len = strlen(str);
- for (i = 0, ndata = 0; i < len; i++, ndata += 2)
- {
- strdesc->data[ndata] = str[i];
- strdesc->data[ndata+1] = 0;
- }
-
- strdesc->len = ndata+2;
- strdesc->type = USB_DESC_TYPE_STRING;
- return strdesc->len;
-#else
- return -EINVAL;
-#endif
-}
-
-/****************************************************************************
- * Name: cdcacm_getepdesc
- *
- * Description:
- * Return a pointer to the raw device descriptor
- *
- ****************************************************************************/
-
-#ifndef CONFIG_CDCACM_COMPOSITE
-FAR const struct usb_devdesc_s *cdcacm_getdevdesc(void)
-{
- return &g_devdesc;
-}
-#endif
-
-/****************************************************************************
- * Name: cdcacm_getepdesc
- *
- * Description:
- * Return a pointer to the raw endpoint struct (used for configuring
- * endpoints)
- *
- ****************************************************************************/
-
-FAR const struct usb_epdesc_s *cdcacm_getepdesc(enum cdcacm_epdesc_e epid)
-{
- switch (epid)
- {
- case CDCACM_EPINTIN: /* Interrupt IN endpoint */
- return &g_epintindesc;
-
- case CDCACM_EPBULKOUT: /* Bulk OUT endpoint */
- return &g_epbulkoutdesc;
-
- case CDCACM_EPBULKIN: /* Bulk IN endpoint */
- return &g_epbulkindesc;
-
- default:
- return NULL;
- }
-}
-
-/****************************************************************************
- * Name: cdcacm_mkepdesc
- *
- * Description:
- * Construct the endpoint descriptor using the correct max packet size.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-void cdcacm_mkepdesc(num cdcacm_epdesc_e epid, uint16_t mxpacket,
- FAR struct usb_epdesc_s *outdesc)
-{
- FAR const struct usb_epdesc_s *indesc;
-
- /* Copy the "canned" descriptor */
-
- indesc = cdcacm_getepdesc(epid)
- memcpy(outdesc, indesc, USB_SIZEOF_EPDESC);
-
- /* Then add the correct max packet size */
-
- outdesc->mxpacketsize[0] = LSBYTE(mxpacket);
- outdesc->mxpacketsize[1] = MSBYTE(mxpacket);
-}
-#endif
-
-/****************************************************************************
- * Name: cdcacm_mkcfgdesc
- *
- * Description:
- * Construct the configuration descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type)
-#else
-int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf)
-#endif
-{
- FAR const struct cfgdecsc_group_s *group;
- FAR uint8_t *dest = buf;
- int i;
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- bool hispeed = (speed == USB_SPEED_HIGH);
-
- /* Check for switches between high and full speed */
-
- if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
- {
- hispeed = !hispeed;
- }
-#endif
-
- /* Copy all of the descriptors in the group */
-
- for (i = 0, dest = buf; i < CDCACM_CFGGROUP_SIZE; i++)
- {
- group = &g_cfggroup[i];
-
- /* The "canned" descriptors all have full speed endpoint maxpacket
- * sizes. If high speed is selected, we will have to change the
- * endpoint maxpacket size.
- *
- * Is there a alternative high speed maxpacket size in the table?
- * If so, that is sufficient proof that the descriptor that we
- * just copied is an endpoint descriptor and needs the fixup
- */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- if (highspeed && group->hsepsize != 0)
- {
- cdcacm_mkepdesc(group->desc, group->hsepsize,
- (FAR struct usb_epdesc_s*)dest);
- }
- else
-#endif
- /* Copy the "canned" descriptor with the full speed max packet
- * size
- */
-
- {
- memcpy(dest, group->desc, group->descsize);
- }
-
- /* Advance to the destination location for the next descriptor */
-
- dest += group->descsize;
- }
-
- return SIZEOF_CDCACM_CFGDESC;
-}
-
-/****************************************************************************
- * Name: cdcacm_getqualdesc
- *
- * Description:
- * Return a pointer to the raw qual descriptor
- *
- ****************************************************************************/
-
-#if !defined(CONFIG_CDCACM_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
-FAR const struct usb_qualdesc_s *cdcacm_getqualdesc(void)
-{
- return &g_qualdesc;
-}
-#endif
diff --git a/nuttx/drivers/usbdev/composite.c b/nuttx/drivers/usbdev/composite.c
deleted file mode 100644
index 530d64416..000000000
--- a/nuttx/drivers/usbdev/composite.c
+++ /dev/null
@@ -1,933 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/composite.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/kmalloc.h>
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/usbdev.h>
-#include <nuttx/usb/usbdev_trace.h>
-
-#include "composite.h"
-
-#ifdef CONFIG_USBDEV_COMPOSITE
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This structure describes the internal state of the driver */
-
-struct composite_dev_s
-{
- FAR struct usbdev_s *usbdev; /* usbdev driver pointer */
- uint8_t config; /* Configuration number */
- FAR struct usbdev_req_s *ctrlreq; /* Allocated control request */
- struct usbdevclass_driver_s *dev1; /* Device 1 class object */
- struct usbdevclass_driver_s *dev2; /* Device 2 class object */
-};
-
-/* The internal version of the class driver */
-
-struct composite_driver_s
-{
- struct usbdevclass_driver_s drvr;
- FAR struct composite_dev_s *dev;
-};
-
-/* This is what is allocated */
-
-struct composite_alloc_s
-{
- struct composite_dev_s dev;
- struct composite_driver_s drvr;
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-/* USB helps ****************************************************************/
-
-static void composite_ep0incomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-static int composite_classsetup(FAR struct composite_dev_s *priv,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
- size_t outlen);
-static struct usbdev_req_s *composite_allocreq(FAR struct usbdev_ep_s *ep,
- uint16_t len);
-static void composite_freereq(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-
-/* USB class device ********************************************************/
-
-static int composite_bind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void composite_unbind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static int composite_setup(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
- size_t outlen);
-static void composite_disconnect(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void composite_suspend(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void composite_resume(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-/* USB class device *********************************************************/
-
-static const struct usbdevclass_driverops_s g_driverops =
-{
- composite_bind, /* bind */
- composite_unbind, /* unbind */
- composite_setup, /* setup */
- composite_disconnect, /* disconnect */
- composite_suspend, /* suspend */
- composite_resume, /* resume */
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-const char g_compvendorstr[] = CONFIG_COMPOSITE_VENDORSTR;
-const char g_compproductstr[] = CONFIG_COMPOSITE_PRODUCTSTR;
-const char g_compserialstr[] = CONFIG_COMPOSITE_SERIALSTR;
-
- /****************************************************************************
- * Private Functions
- ****************************************************************************/
-/****************************************************************************
- * Helpers
- ****************************************************************************/
-
-/****************************************************************************
- * Name: composite_ep0incomplete
- *
- * Description:
- * Handle completion of the composite driver's EP0 control operations
- *
- ****************************************************************************/
-
-static void composite_ep0incomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- /* Just check the result of the transfer */
-
- if (req->result || req->xfrd != req->len)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_REQRESULT), (uint16_t)-req->result);
- }
-}
-
-/****************************************************************************
- * Name: composite_classsetup
- *
- * Description:
- * Forward a setup command to the appropriate component device
- *
- ****************************************************************************/
-
-static int composite_classsetup(FAR struct composite_dev_s *priv,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl,
- FAR uint8_t *dataout, size_t outlen)
-{
- uint16_t index;
- uint8_t interface;
- int ret = -EOPNOTSUPP;
-
- index = GETUINT16(ctrl->index);
- interface = (uint8_t)(index & 0xff);
-
- if (interface >= DEV1_FIRSTINTERFACE && interface < (DEV1_FIRSTINTERFACE + DEV1_NINTERFACES))
- {
- ret = CLASS_SETUP(priv->dev1, dev, ctrl, dataout, outlen);
- }
- else if (interface >= DEV2_FIRSTINTERFACE && interface < (DEV2_FIRSTINTERFACE + DEV2_NINTERFACES))
- {
- ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen);
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: composite_allocreq
- *
- * Description:
- * Allocate a request instance along with its buffer
- *
- ****************************************************************************/
-
-static struct usbdev_req_s *composite_allocreq(FAR struct usbdev_ep_s *ep,
- uint16_t len)
-{
- FAR struct usbdev_req_s *req;
-
- req = EP_ALLOCREQ(ep);
- if (req != NULL)
- {
- req->len = len;
- req->buf = EP_ALLOCBUFFER(ep, len);
- if (!req->buf)
- {
- EP_FREEREQ(ep, req);
- req = NULL;
- }
- }
- return req;
-}
-
-/****************************************************************************
- * Name: composite_freereq
- *
- * Description:
- * Free a request instance along with its buffer
- *
- ****************************************************************************/
-
-static void composite_freereq(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- if (ep != NULL && req != NULL)
- {
- if (req->buf != NULL)
- {
- EP_FREEBUFFER(ep, req->buf);
- }
- EP_FREEREQ(ep, req);
- }
-}
-
-/****************************************************************************
- * USB Class Driver Methods
- ****************************************************************************/
-
-/****************************************************************************
- * Name: composite_bind
- *
- * Description:
- * Invoked when the driver is bound to a USB device driver
- *
- ****************************************************************************/
-
-static int composite_bind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct composite_dev_s *priv = ((FAR struct composite_driver_s*)driver)->dev;
- int ret;
-
- usbtrace(TRACE_CLASSBIND, 0);
-
- /* Bind the structures */
-
- priv->usbdev = dev;
-
- /* Save the reference to our private data structure in EP0 so that it
- * can be recovered in ep0 completion events.
- */
-
- dev->ep0->priv = priv;
-
- /* Preallocate one control request */
-
- priv->ctrlreq = composite_allocreq(dev->ep0, COMPOSITE_CFGDESCSIZE);
- if (priv->ctrlreq == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_ALLOCCTRLREQ), 0);
- ret = -ENOMEM;
- goto errout;
- }
-
- /* Initialize the pre-allocated control request */
-
- priv->ctrlreq->callback = composite_ep0incomplete;
-
- /* Then bind each of the constituent class drivers */
-
- ret = CLASS_BIND(priv->dev1, dev);
- if (ret < 0)
- {
- goto errout;
- }
-
- ret = CLASS_BIND(priv->dev2, dev);
- if (ret < 0)
- {
- goto errout;
- }
-
- /* Report if we are selfpowered */
-
-#ifdef CONFIG_USBDEV_SELFPOWERED
- DEV_SETSELFPOWERED(dev);
-#endif
-
- /* And pull-up the data line for the soft connect function */
-
- DEV_CONNECT(dev);
- return OK;
-
-errout:
- composite_unbind(driver, dev);
- return ret;
-}
-
-/****************************************************************************
- * Name: composite_unbind
- *
- * Description:
- * Invoked when the driver is unbound from a USB device driver
- *
- ****************************************************************************/
-
-static void composite_unbind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct composite_dev_s *priv;
- irqstate_t flags;
-
- usbtrace(TRACE_CLASSUNBIND, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct composite_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Make sure that we are not already unbound */
-
- if (priv != NULL)
- {
- /* Unbind the constituent class drivers */
-
- flags = irqsave();
- CLASS_UNBIND(priv->dev1, dev);
- CLASS_UNBIND(priv->dev2, dev);
-
- /* Free the pre-allocated control request */
-
- priv->config = COMPOSITE_CONFIGIDNONE;
- if (priv->ctrlreq != NULL)
- {
- composite_freereq(dev->ep0, priv->ctrlreq);
- priv->ctrlreq = NULL;
- }
- irqrestore(flags);
- }
-}
-
-/****************************************************************************
- * Name: composite_setup
- *
- * Description:
- * Invoked for ep0 control requests. This function probably executes
- * in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-static int composite_setup(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl,
- FAR uint8_t *dataout, size_t outlen)
-{
- FAR struct composite_dev_s *priv;
- FAR struct usbdev_req_s *ctrlreq;
- uint16_t value;
- uint16_t index;
- uint16_t len;
- bool dispatched = false;
- int ret = -EOPNOTSUPP;
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0 || !ctrl)
- {
- usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_SETUPINVALIDARGS), 0);
- return -EIO;
- }
-#endif
-
- /* Extract a reference to private data */
-
- usbtrace(TRACE_CLASSSETUP, ctrl->req);
- priv = ((FAR struct composite_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_EP0NOTBOUND2), 0);
- return -ENODEV;
- }
-#endif
- ctrlreq = priv->ctrlreq;
-
- /* Extract the little-endian 16-bit values to host order */
-
- value = GETUINT16(ctrl->value);
- index = GETUINT16(ctrl->index);
- len = GETUINT16(ctrl->len);
-
- uvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n",
- ctrl->type, ctrl->req, value, index, len);
-
- if ((ctrl->type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
- {
- /**********************************************************************
- * Standard Requests
- **********************************************************************/
-
- switch (ctrl->req)
- {
- case USB_REQ_GETDESCRIPTOR:
- {
- /* The value field specifies the descriptor type in the MS byte and the
- * descriptor index in the LS byte (order is little endian)
- */
-
- switch (ctrl->value[1])
- {
- case USB_DESC_TYPE_DEVICE:
- {
- ret = USB_SIZEOF_DEVDESC;
- memcpy(ctrlreq->buf, composite_getdevdesc(), ret);
- }
- break;
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- case USB_DESC_TYPE_DEVICEQUALIFIER:
- {
- ret = USB_SIZEOF_QUALDESC;
- memcpy(ctrlreq->buf, composite_getqualdesc(), ret);
- }
- break;
-
- case USB_DESC_TYPE_OTHERSPEEDCONFIG:
-#endif
-
- case USB_DESC_TYPE_CONFIG:
- {
-#ifdef CONFIG_USBDEV_DUALSPEED
- ret = composite_mkcfgdesc(ctrlreq->buf, dev->speed,
- ctrl->value[1]);
-#else
- ret = composite_mkcfgdesc(ctrlreq->buf);
-#endif
- }
- break;
-
- case USB_DESC_TYPE_STRING:
- {
- /* value == string index. Zero is the language ID. */
-
- uint8_t strid = ctrl->value[0];
- FAR struct usb_strdesc_s *buf = (FAR struct usb_strdesc_s *)ctrlreq->buf;
-
- if (strid <= COMPOSITE_NSTRIDS)
- {
- ret = composite_mkstrdesc(strid, buf);
- }
-#if DEV1_NSTRIDS > 0
- else if (strid <= DEV1_STRIDBASE + DEV1_NSTRIDS)
- {
- ret = DEV1_MKSTRDESC(strid, buf);
- }
-#endif
-#if DEV2_NSTRIDS > 0
- else if (strid <= DEV2_STRIDBASE + DEV2_NSTRIDS)
- {
- ret = DEV2_MKSTRDESC(strid, buf);
- }
-#endif
- }
- break;
-
- default:
- {
- usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_GETUNKNOWNDESC), value);
- }
- break;
- }
- }
- break;
-
- case USB_REQ_SETCONFIGURATION:
- {
- if (ctrl->type == 0)
- {
- /* Save the configuration and inform the constituent classes */
-
- ret = CLASS_SETUP(priv->dev1, dev, ctrl, dataout, outlen);
- dispatched = true;
-
- if (ret >= 0)
- {
- ret = CLASS_SETUP(priv->dev2, dev, ctrl, dataout, outlen);
- if (ret >= 0)
- {
- priv->config = value;
- }
- }
- }
- }
- break;
-
- case USB_REQ_GETCONFIGURATION:
- {
- if (ctrl->type == USB_DIR_IN)
- {
- ctrlreq->buf[0] = priv->config;
- ret = 1;
- }
- }
- break;
-
- case USB_REQ_SETINTERFACE:
- {
- if (ctrl->type == USB_REQ_RECIPIENT_INTERFACE &&
- priv->config == COMPOSITE_CONFIGID)
- {
- ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
- dispatched = true;
- }
- }
- break;
-
- case USB_REQ_GETINTERFACE:
- {
- if (ctrl->type == (USB_DIR_IN|USB_REQ_RECIPIENT_INTERFACE) &&
- priv->config == COMPOSITE_CONFIGIDNONE)
- {
- ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
- dispatched = true;
- }
- }
- break;
-
- default:
- usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_UNSUPPORTEDSTDREQ), ctrl->req);
- break;
- }
- }
- else
- {
- uint8_t recipient;
-
- /**********************************************************************
- * Non-Standard Class Requests
- **********************************************************************/
-
- /* Class implementations should handle there own interface and endpoint
- * requests.
- */
-
- recipient = ctrl->type & USB_REQ_RECIPIENT_MASK;
- if (recipient == USB_REQ_RECIPIENT_INTERFACE || recipient == USB_REQ_RECIPIENT_ENDPOINT)
- {
- ret = composite_classsetup(priv, dev, ctrl, dataout, outlen);
- dispatched = true;
- }
- }
-
-
- /* Respond to the setup command if (1) data was returned, and (2) the request was
- * NOT successfully dispatched to the component class driver. On an error return
- * value (ret < 0), the USB driver will stall EP0.
- */
-
- if (ret >= 0 && !dispatched)
- {
- /* Setup the request */
-
- ctrlreq->len = MIN(len, ret);
- ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;
-
- /* And submit the request to the USB controller driver */
-
- ret = EP_SUBMIT(dev->ep0, ctrlreq);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(COMPOSITE_TRACEERR_EPRESPQ), (uint16_t)-ret);
- ctrlreq->result = OK;
- composite_ep0incomplete(dev->ep0, ctrlreq);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: composite_disconnect
- *
- * Description:
- * Invoked after all transfers have been stopped, when the host is
- * disconnected. This function is probably called from the context of an
- * interrupt handler.
- *
- ****************************************************************************/
-
-static void composite_disconnect(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct composite_dev_s *priv;
- irqstate_t flags;
-
- usbtrace(TRACE_CLASSDISCONNECT, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct composite_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Reset the configuration and inform the constituent class drivers of
- * the disconnection.
- */
-
- flags = irqsave();
- priv->config = COMPOSITE_CONFIGIDNONE;
- CLASS_DISCONNECT(priv->dev1, dev);
- CLASS_DISCONNECT(priv->dev2, dev);
- irqrestore(flags);
-
- /* Perform the soft connect function so that we will we can be
- * re-enumerated.
- */
-
- DEV_CONNECT(dev);
-}
-
-/****************************************************************************
- * Name: composite_suspend
- *
- * Description:
- * Invoked on a USB suspend event.
- *
- ****************************************************************************/
-
-static void composite_suspend(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct composite_dev_s *priv;
- irqstate_t flags;
-
- usbtrace(TRACE_CLASSSUSPEND, 0);
-
-#ifdef CONFIG_DEBUG
- if (!dev)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct composite_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Forward the suspend event to the constituent devices */
-
- flags = irqsave();
- CLASS_SUSPEND(priv->dev1, priv->usbdev);
- CLASS_SUSPEND(priv->dev2, priv->usbdev);
- irqrestore(flags);
-}
-
-/****************************************************************************
- * Name: composite_resume
- *
- * Description:
- * Invoked on a USB resume event.
- *
- ****************************************************************************/
-
-static void composite_resume(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct composite_dev_s *priv = NULL;
- irqstate_t flags;
-
-#ifdef CONFIG_DEBUG
- if (!dev)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct composite_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Forward the resume event to the constituent devices */
-
- flags = irqsave();
- CLASS_RESUME(priv->dev1, priv->usbdev);
- CLASS_RESUME(priv->dev2, priv->usbdev);
- irqrestore(flags);
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-/****************************************************************************
- * Name: composite_initialize
- *
- * Description:
- * Register USB composite device as configured. This function will call
- * board-specific implementations in order to obtain the class objects for
- * each of the members of the composite (see board_mscclassobject(),
- * board_cdcclassobjec(), ...)
- *
- * Input Parameter:
- * None
- *
- * Returned Value:
- * A non-NULL "handle" is returned on success. This handle may be used
- * later with composite_uninitialize() in order to removed the composite
- * device. This handle is the (untyped) internal representation of the
- * the class driver instance.
- *
- * NULL is returned on any failure.
- *
- ****************************************************************************/
-
-FAR void *composite_initialize(void)
-{
- FAR struct composite_alloc_s *alloc;
- FAR struct composite_dev_s *priv;
- FAR struct composite_driver_s *drvr;
- int ret;
-
- /* Allocate the structures needed */
-
- alloc = (FAR struct composite_alloc_s*)kmalloc(sizeof(struct composite_alloc_s));
- if (!alloc)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_ALLOCDEVSTRUCT), 0);
- return NULL;
- }
-
- /* Convenience pointers into the allocated blob */
-
- priv = &alloc->dev;
- drvr = &alloc->drvr;
-
- /* Initialize the USB composite driver structure */
-
- memset(priv, 0, sizeof(struct composite_dev_s));
-
- /* Get the constitueat class driver objects */
-
- ret = DEV1_CLASSOBJECT(&priv->dev1);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT), (uint16_t)-ret);
- goto errout_with_alloc;
- }
-
- ret = DEV2_CLASSOBJECT(&priv->dev2);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_CLASSOBJECT), (uint16_t)-ret);
- goto errout_with_alloc;
- }
-
- /* Initialize the USB class driver structure */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- drvr->drvr.speed = USB_SPEED_HIGH;
-#else
- drvr->drvr.speed = USB_SPEED_FULL;
-#endif
- drvr->drvr.ops = &g_driverops;
- drvr->dev = priv;
-
- /* Register the USB composite class driver */
-
- ret = usbdev_register(&drvr->drvr);
- if (ret)
- {
- usbtrace(TRACE_CLSERROR(USBCOMPOSITE_TRACEERR_DEVREGISTER), (uint16_t)-ret);
- goto errout_with_alloc;
- }
-
- return (FAR void *)alloc;
-
-errout_with_alloc:
- kfree(alloc);
- return NULL;
-}
-
-/****************************************************************************
- * Name: composite_uninitialize
- *
- * Description:
- * Un-initialize the USB composite driver. The handle is the USB composite
- * class' device object as was returned by composite_initialize(). This
- * function will call board-specific implementations in order to free the
- * class objects for each of the members of the composite (see
- * board_mscuninitialize(), board_cdcuninitialize(), ...)
- *
- * Input Parameters:
- * handle - The handle returned by a previous call to composite_initialize().
- *
- * Returned Value:
- * None
- *
- ***************************************************************************/
-
-void composite_uninitialize(FAR void *handle)
-{
- FAR struct composite_alloc_s *alloc = (FAR struct composite_alloc_s *)handle;
- FAR struct composite_dev_s *priv;
-
- DEBUGASSERT(alloc != NULL);
-
- /* Uninitialize each of the member classes */
-
- priv = &alloc->dev;
- if (priv->dev1)
- {
- DEV1_UNINITIALIZE(priv->dev1);
- priv->dev1 = NULL;
- }
-
- if (priv->dev2)
- {
- DEV1_UNINITIALIZE(priv->dev2);
- priv->dev2 = NULL;
- }
-
- /* Then unregister and destroy the composite class */
-
- usbdev_unregister(&alloc->drvr.drvr);
-
- /* Free any resources used by the composite driver */
- /* None */
-
- /* Then free the composite driver state structure itself */
-
- kfree(priv);
-}
-
-/****************************************************************************
- * Name: composite_ep0submit
- *
- * Description:
- * Members of the composite cannot send on EP0 directly because EP0 is
- * is "owned" by the composite device. Instead, when configured as members
- * of a composite device, those classes should call this method so that
- * the composite device can send on EP0 onbehalf of the class.
- *
- ****************************************************************************/
-
-int composite_ep0submit(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR struct usbdev_req_s *ctrlreq)
-{
- /* This function is not really necessary in the current design. However,
- * keeping this will provide us a little flexibility in the future if
- * it becomes necessary to manage the completion callbacks.
- */
-
- return EP_SUBMIT(dev->ep0, ctrlreq);
-}
-
-#endif /* CONFIG_USBDEV_COMPOSITE */
diff --git a/nuttx/drivers/usbdev/composite.h b/nuttx/drivers/usbdev/composite.h
deleted file mode 100644
index 0c022427c..000000000
--- a/nuttx/drivers/usbdev/composite.h
+++ /dev/null
@@ -1,326 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/composite.h
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_USBDEV_COMPOSITE_H
-#define __DRIVERS_USBDEV_COMPOSITE_H 1
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/usbdev_trace.h>
-
-#ifdef CONFIG_USBDEV_COMPOSITE
-
-#ifdef CONFIG_CDCACM_COMPOSITE
-# include <nuttx/usb/cdcacm.h>
-# include "cdcacm.h"
-#endif
-
-#ifdef CONFIG_USBMSC_COMPOSITE
-# include "usbmsc.h"
-#endif
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Configuration ************************************************************/
-/* Packet sizes */
-
-#ifndef CONFIG_COMPOSITE_EP0MAXPACKET
-# define CONFIG_COMPOSITE_EP0MAXPACKET 64
-#endif
-
-/* Vendor and product IDs and strings */
-
-#ifndef CONFIG_COMPOSITE_COMPOSITE
-# ifndef CONFIG_COMPOSITE_VENDORID
-# warning "CONFIG_COMPOSITE_VENDORID not defined"
-# define CONFIG_COMPOSITE_VENDORID 0x03eb
-# endif
-
-# ifndef CONFIG_COMPOSITE_PRODUCTID
-# warning "CONFIG_COMPOSITE_PRODUCTID not defined"
-# define CONFIG_COMPOSITE_PRODUCTID 0x2022
-# endif
-
-# ifndef CONFIG_COMPOSITE_VERSIONNO
-# define CONFIG_COMPOSITE_VERSIONNO (0x0101)
-# endif
-
-# ifndef CONFIG_COMPOSITE_VENDORSTR
-# warning "No Vendor string specified"
-# define CONFIG_COMPOSITE_VENDORSTR "NuttX"
-# endif
-
-# ifndef CONFIG_COMPOSITE_PRODUCTSTR
-# warning "No Product string specified"
-# define CONFIG_COMPOSITE_PRODUCTSTR "Composite Device"
-# endif
-
-# undef CONFIG_COMPOSITE_SERIALSTR
-# define CONFIG_COMPOSITE_SERIALSTR "0101"
-#endif
-
-#undef CONFIG_COMPOSITE_CONFIGSTR
-#define CONFIG_COMPOSITE_CONFIGSTR "Composite"
-
-/* Constituent devices ******************************************************/
-
-#undef DEV1_IS_CDCACM
-#undef DEV1_IS_USBMSC
-
-#undef DEV2_IS_CDCACM
-#undef DEV2_IS_USBMSC
-
-/* Pick the first device in the composite. At present, this may only be
- * the CDC serial device or the mass storage device.
- */
-
-#if defined(CONFIG_CDCACM_COMPOSITE)
-# define DEV1_IS_CDCACM 1
-# define DEV1_MKCFGDESC cdcacm_mkcfgdesc
-# define DEV1_MKSTRDESC cdcacm_mkstrdesc
-# define DEV1_CLASSOBJECT board_cdcclassobject
-# define DEV1_UNINITIALIZE board_cdcuninitialize
-# define DEV1_NCONFIGS CDCACM_NCONFIGS
-# define DEV1_CONFIGID CDCACM_CONFIGID
-# define DEV1_FIRSTINTERFACE CONFIG_CDCACM_IFNOBASE
-# define DEV1_NINTERFACES CDCACM_NINTERFACES
-# define DEV1_STRIDBASE CONFIG_CDCACM_STRBASE
-# define DEV1_NSTRIDS CDCACM_NSTRIDS
-# define DEV1_CFGDESCSIZE SIZEOF_CDCACM_CFGDESC
-#elif defined(CONFIG_CDCACM_COMPOSITE)
-# define DEV1_IS_USBMSC 1
-# define DEV1_MKCFGDESC usbmsc_mkcfgdesc
-# define DEV1_MKSTRDESC usbmsc_mkstrdesc
-# define DEV1_CLASSOBJECT board_mscclassobject
-# define DEV1_UNINITIALIZE board_mscuninitialize
-# define DEV1_NCONFIGS USBMSC_NCONFIGS
-# define DEV1_CONFIGID USBMSC_CONFIGID
-# define DEV1_FIRSTINTERFACE CONFIG_USBMSC_IFNOBASE
-# define DEV1_NINTERFACES USBMSC_NINTERFACES
-# define DEV1_STRIDBASE CONFIG_USBMSC_IFNOBASE
-# define DEV1_NSTRIDS USBMSC_NSTRIDS
-# define DEV1_CFGDESCSIZE SIZEOF_USBMSC_CFGDESC
-#else
-# error "No members of the composite defined"
-#endif
-
-/* Pick the second device in the composite. At present, this may only be
- * the CDC serial device or the mass storage device.
- */
-
-#if defined(CONFIG_CDCACM_COMPOSITE) && !defined(DEV1_IS_CDCACM)
-# define DEV2_IS_CDCACM 1
-# define DEV2_MKCFGDESC cdcacm_mkcfgdesc
-# define DEV2_MKSTRDESC cdcacm_mkstrdesc
-# define DEV2_CLASSOBJECT board_cdcclassobject
-# define DEV2_UNINITIALIZE board_cdcuninitialize
-# define DEV2_NCONFIGS CDCACM_NCONFIGS
-# define DEV2_CONFIGID CDCACM_CONFIGID
-# define DEV2_FIRSTINTERFACE CONFIG_CDCACM_IFNOBASE
-# define DEV2_NINTERFACES CDCACM_NINTERFACES
-# define DEV2_STRIDBASE CONFIG_CDCACM_STRBASE
-# define DEV2_NSTRIDS CDCACM_NSTRIDS
-# define DEV2_CFGDESCSIZE SIZEOF_CDCACM_CFGDESC
-#elif defined(CONFIG_CDCACM_COMPOSITE) && !defined(DEV1_IS_USBMSC)
-# define DEV2_IS_USBMSC 1
-# define DEV2_MKCFGDESC usbmsc_mkcfgdesc
-# define DEV2_MKSTRDESC usbmsc_mkstrdesc
-# define DEV2_UNINITIALIZE board_mscuninitialize
-# define DEV2_CLASSOBJECT board_mscclassobject
-# define DEV2_NCONFIGS USBMSC_NCONFIGS
-# define DEV2_CONFIGID USBMSC_CONFIGID
-# define DEV2_FIRSTINTERFACE CONFIG_USBMSC_IFNOBASE
-# define DEV2_NINTERFACES USBMSC_NINTERFACES
-# define DEV2_STRIDBASE CONFIG_USBMSC_STRBASE
-# define DEV2_NSTRIDS USBMSC_NSTRIDS
-# define DEV2_CFGDESCSIZE SIZEOF_USBMSC_CFGDESC
-#else
-# error "Insufficient members of the composite defined"
-#endif
-
-/* Verify interface configuration */
-
-#if DEV1_FIRSTINTERFACE != 0
-# warning "The first interface number should be zero"
-#endif
-
-#if (DEV1_FIRSTINTERFACE + DEV1_NINTERFACES) != DEV2_FIRSTINTERFACE
-# warning "Interface numbers are not contiguous"
-#endif
-
-/* Check if an IAD is needed */
-
-#ifdef CONFIG_COMPOSITE_IAD
-# if DEV1_NINTERFACES == 1 && DEV2_NINTERFACES == 1
-# warning "CONFIG_COMPOSITE_IAD not needed"
-# endif
-#endif
-
-#if !defined(CONFIG_COMPOSITE_IAD) && DEV1_NINTERFACES > 1 && DEV2_NINTERFACES > 1
-# warning "CONFIG_COMPOSITE_IAD may be needed"
-#endif
-
-/* Total size of the configuration descriptor: */
-
-#define COMPOSITE_CFGDESCSIZE (USB_SIZEOF_CFGDESC + DEV1_CFGDESCSIZE + DEV2_CFGDESCSIZE)
-
-/* The total number of interfaces */
-
-#define COMPOSITE_NINTERFACES (DEV1_NINTERFACES + DEV2_NINTERFACES)
-
-/* Composite configuration ID value */
-
-#if DEV1_NCONFIGS != 1 || DEV1_CONFIGID != 1
-# error "DEV1: Only a single configuration is supported"
-#endif
-
-#if DEV2_NCONFIGS != 1 || DEV2_CONFIGID != 1
-# error "DEV2: Only a single configuration is supported"
-#endif
-
-/* Descriptors **************************************************************/
-/* These settings are not modifiable via the NuttX configuration */
-
-#define COMPOSITE_CONFIGIDNONE (0) /* Config ID = 0 means to return to address mode */
-#define COMPOSITE_NCONFIGS (1) /* The number of configurations supported */
-#define COMPOSITE_CONFIGID (1) /* The only supported configuration ID */
-
-/* String language */
-
-#define COMPOSITE_STR_LANGUAGE (0x0409) /* en-us */
-
-/* Descriptor strings */
-
-#define COMPOSITE_MANUFACTURERSTRID (1)
-#define COMPOSITE_PRODUCTSTRID (2)
-#define COMPOSITE_SERIALSTRID (3)
-#define COMPOSITE_CONFIGSTRID (4)
-#define COMPOSITE_NSTRIDS (4)
-
-/* Verify string configuration */
-
-#if COMPOSITE_NSTRIDS != DEV1_STRIDBASE
-# warning "The DEV1 string base should be COMPOSITE_NSTRIDS"
-#endif
-
-#if (DEV1_STRIDBASE + DEV1_NSTRIDS) != DEV2_STRIDBASE
-# warning "String IDs are not contiguous"
-#endif
-
-/* Everpresent MIN/MAX macros ***********************************************/
-
-#ifndef MIN
-# define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
-#ifndef MAX
-# define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-extern const char g_compvendorstr[];
-extern const char g_compproductstr[];
-extern const char g_compserialstr[];
-
-/****************************************************************************
- * Public Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Name: composite_mkstrdesc
- *
- * Description:
- * Construct a string descriptor
- *
- ****************************************************************************/
-
-int composite_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
-
-/****************************************************************************
- * Name: composite_getepdesc
- *
- * Description:
- * Return a pointer to the composite device descriptor
- *
- ****************************************************************************/
-
-#ifndef CONFIG_COMPOSITE_COMPOSITE
-FAR const struct usb_devdesc_s *composite_getdevdesc(void);
-#endif
-
-/****************************************************************************
- * Name: composite_mkcfgdesc
- *
- * Description:
- * Construct the composite configuration descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-int16_t composite_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type);
-#else
-int16_t composite_mkcfgdesc(uint8_t *buf);
-#endif
-
-/****************************************************************************
- * Name: composite_getqualdesc
- *
- * Description:
- * Return a pointer to the composite qual descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-FAR const struct usb_qualdesc_s *composite_getqualdesc(void);
-#endif
-
-#endif /* CONFIG_USBDEV_COMPOSITE */
-#endif /* __DRIVERS_USBDEV_COMPOSITE_H */
diff --git a/nuttx/drivers/usbdev/composite_desc.c b/nuttx/drivers/usbdev/composite_desc.c
deleted file mode 100644
index 0a0cd4a6a..000000000
--- a/nuttx/drivers/usbdev/composite_desc.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/composite_desc.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/usb/usbdev_trace.h>
-
-#include "composite.h"
-
-#ifdef CONFIG_USBDEV_COMPOSITE
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-typedef int16_t (*mkcfgdesc)(FAR uint8_t *buf, uint8_t speed, uint8_t type);
-#else
-typedef int16_t (*mkcfgdesc)(FAR uint8_t *buf);
-#endif
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-/* Device Descriptor */
-
-static const struct usb_devdesc_s g_devdesc =
-{
- USB_SIZEOF_DEVDESC, /* len */
- USB_DESC_TYPE_DEVICE, /* type */
- { /* usb */
- LSBYTE(0x0200),
- MSBYTE(0x0200)
- },
-#ifdef CONFIG_COMPOSITE_IAD
- USB_CLASS_MISC, /* classid */
- 2, /* subclass */
- 1, /* protocol */
-#else
- USB_CLASS_PER_INTERFACE, /* classid */
- 0, /* subclass */
- 0, /* protocol */
-#endif
- CONFIG_COMPOSITE_EP0MAXPACKET, /* maxpacketsize */
- {
- LSBYTE(CONFIG_COMPOSITE_VENDORID), /* vendor */
- MSBYTE(CONFIG_COMPOSITE_VENDORID)
- },
- {
- LSBYTE(CONFIG_COMPOSITE_PRODUCTID), /* product */
- MSBYTE(CONFIG_COMPOSITE_PRODUCTID)
- },
- {
- LSBYTE(CONFIG_COMPOSITE_VERSIONNO), /* device */
- MSBYTE(CONFIG_COMPOSITE_VERSIONNO)
- },
- COMPOSITE_MANUFACTURERSTRID, /* imfgr */
- COMPOSITE_PRODUCTSTRID, /* iproduct */
- COMPOSITE_SERIALSTRID, /* serno */
- COMPOSITE_NCONFIGS /* nconfigs */
-};
-
-/* Configuration descriptor for the composite device */
-
-static const struct usb_cfgdesc_s g_cfgdesc =
-{
- USB_SIZEOF_CFGDESC, /* len */
- USB_DESC_TYPE_CONFIG, /* type */
- {
- LSBYTE(COMPOSITE_CFGDESCSIZE), /* LS totallen */
- MSBYTE(COMPOSITE_CFGDESCSIZE) /* MS totallen */
- },
- COMPOSITE_NINTERFACES, /* ninterfaces */
- COMPOSITE_CONFIGID, /* cfgvalue */
- COMPOSITE_CONFIGSTRID, /* icfg */
- USB_CONFIG_ATTR_ONE|SELFPOWERED|REMOTEWAKEUP, /* attr */
- (CONFIG_USBDEV_MAXPOWER + 1) / 2 /* mxpower */
-};
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-static const struct usb_qualdesc_s g_qualdesc =
-{
- USB_SIZEOF_QUALDESC, /* len */
- USB_DESC_TYPE_DEVICEQUALIFIER, /* type */
- { /* usb */
- LSBYTE(0x0200),
- MSBYTE(0x0200)
- },
- USB_CLASS_VENDOR_SPEC, /* classid */
- 0, /* subclass */
- 0, /* protocol */
- CONFIG_COMPOSITE_EP0MAXPACKET, /* mxpacketsize */
- COMPOSITE_NCONFIGS, /* nconfigs */
- 0, /* reserved */
-};
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: composite_mkstrdesc
- *
- * Description:
- * Construct a string descriptor
- *
- ****************************************************************************/
-
-int composite_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc)
-{
- const char *str;
- int len;
- int ndata;
- int i;
-
- switch (id)
- {
- case 0:
- {
- /* Descriptor 0 is the language id */
-
- strdesc->len = 4;
- strdesc->type = USB_DESC_TYPE_STRING;
- strdesc->data[0] = LSBYTE(COMPOSITE_STR_LANGUAGE);
- strdesc->data[1] = MSBYTE(COMPOSITE_STR_LANGUAGE);
- return 4;
- }
-
- case COMPOSITE_MANUFACTURERSTRID:
- str = g_compvendorstr;
- break;
-
- case COMPOSITE_PRODUCTSTRID:
- str = g_compproductstr;
- break;
-
- case COMPOSITE_SERIALSTRID:
- str = g_compserialstr;
- break;
-
- case COMPOSITE_CONFIGSTRID:
- str = CONFIG_COMPOSITE_CONFIGSTR;
- break;
-
- default:
- return -EINVAL;
- }
-
- /* The string is utf16-le. The poor man's utf-8 to utf16-le
- * conversion below will only handle 7-bit en-us ascii
- */
-
- len = strlen(str);
- for (i = 0, ndata = 0; i < len; i++, ndata += 2)
- {
- strdesc->data[ndata] = str[i];
- strdesc->data[ndata+1] = 0;
- }
-
- strdesc->len = ndata+2;
- strdesc->type = USB_DESC_TYPE_STRING;
- return strdesc->len;
-}
-
-/****************************************************************************
- * Name: composite_getepdesc
- *
- * Description:
- * Return a pointer to the raw device descriptor
- *
- ****************************************************************************/
-
-FAR const struct usb_devdesc_s *composite_getdevdesc(void)
-{
- return &g_devdesc;
-}
-
-/****************************************************************************
- * Name: composite_mkcfgdesc
- *
- * Description:
- * Construct the configuration descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-int16_t composite_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type)
-#else
-int16_t composite_mkcfgdesc(uint8_t *buf)
-#endif
-{
- int16_t len;
- int16_t total;
-
- /* Configuration descriptor -- Copy the canned configuration descriptor. */
-
- memcpy(buf, &g_cfgdesc, USB_SIZEOF_CFGDESC);
- total = USB_SIZEOF_CFGDESC;
- buf += USB_SIZEOF_CFGDESC;
-
- /* Copy DEV1/DEV2 interface descriptors */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- len = DEV1_MKCFGDESC(buf, speed, type);
- total += len;
- buf += len;
- total += DEV2_MKCFGDESC(buf, speed, type);
-#else
- len = DEV1_MKCFGDESC(buf);
- total += len;
- buf += len;
- total += DEV2_MKCFGDESC(buf);
-#endif
-
- DEBUGASSERT(total == COMPOSITE_CFGDESCSIZE);
- return total;
-}
-
-/****************************************************************************
- * Name: composite_getqualdesc
- *
- * Description:
- * Return a pointer to the raw qual descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-FAR const struct usb_qualdesc_s *composite_getqualdesc(void)
-{
- return &g_qualdesc;
-}
-#endif
-
-#endif /* CONFIG_USBDEV_COMPOSITE */
diff --git a/nuttx/drivers/usbdev/pl2303.c b/nuttx/drivers/usbdev/pl2303.c
deleted file mode 100644
index 7b07a9cba..000000000
--- a/nuttx/drivers/usbdev/pl2303.c
+++ /dev/null
@@ -1,2355 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/pl2303.c
- *
- * Copyright (C) 2008-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * This logic emulates the Prolific PL2303 serial/USB converter
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <semaphore.h>
-#include <string.h>
-#include <errno.h>
-#include <queue.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/arch.h>
-#include <nuttx/serial/serial.h>
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/usbdev.h>
-#include <nuttx/usb/usbdev_trace.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Configuration ************************************************************/
-
-/* Number of requests in the write queue */
-
-#ifndef CONFIG_PL2303_NWRREQS
-# define CONFIG_PL2303_NWRREQS 4
-#endif
-
-/* Number of requests in the read queue */
-
-#ifndef CONFIG_PL2303_NRDREQS
-# define CONFIG_PL2303_NRDREQS 4
-#endif
-
-/* Logical endpoint numbers / max packet sizes */
-
-#ifndef CONFIG_PL2303_EPINTIN
-# warning "EPINTIN not defined in the configuration"
-# define CONFIG_PL2303_EPINTIN 1
-#endif
-
-#ifndef CONFIG_PL2303_EPBULKOUT
-# warning "EPBULKOUT not defined in the configuration"
-# define CONFIG_PL2303_EPBULKOUT 2
-#endif
-
-#ifndef CONFIG_PL2303_EPBULKIN
-# warning "EPBULKIN not defined in the configuration"
-# define CONFIG_PL2303_EPBULKIN 3
-#endif
-
-/* Packet and request buffer sizes */
-
-#ifndef CONFIG_PL2303_EP0MAXPACKET
-# define CONFIG_PL2303_EP0MAXPACKET 64
-#endif
-
-#undef CONFIG_PL2303_BULKREQLEN
-
-/* Vendor and product IDs and strings */
-
-#ifndef CONFIG_PL2303_VENDORID
-# define CONFIG_PL2303_VENDORID 0x067b
-#endif
-
-#ifndef CONFIG_PL2303_PRODUCTID
-# define CONFIG_PL2303_PRODUCTID 0x2303
-#endif
-
-#ifndef CONFIG_PL2303_VENDORSTR
-# warning "No Vendor string specified"
-# define CONFIG_PL2303_VENDORSTR "NuttX"
-#endif
-
-#ifndef CONFIG_PL2303_PRODUCTSTR
-# warning "No Product string specified"
-# define CONFIG_PL2303_PRODUCTSTR "USBdev Serial"
-#endif
-
-#undef CONFIG_PL2303_SERIALSTR
-#define CONFIG_PL2303_SERIALSTR "0"
-
-#undef CONFIG_PL2303_CONFIGSTR
-#define CONFIG_PL2303_CONFIGSTR "Bulk"
-
-/* USB Controller */
-
-#ifndef CONFIG_USBDEV_SELFPOWERED
-# define SELFPOWERED USB_CONFIG_ATTR_SELFPOWER
-#else
-# define SELFPOWERED (0)
-#endif
-
-#ifndef CONFIG_USBDEV_REMOTEWAKEUP
-# define REMOTEWAKEUP USB_CONFIG_ATTR_WAKEUP
-#else
-# define REMOTEWAKEUP (0)
-#endif
-
-#ifndef CONFIG_USBDEV_MAXPOWER
-# define CONFIG_USBDEV_MAXPOWER 100
-#endif
-
-/* Descriptors ****************************************************************/
-
-/* These settings are not modifiable via the NuttX configuration */
-
-#define PL2303_VERSIONNO (0x0202) /* Device version number */
-#define PL2303_CONFIGIDNONE (0) /* Config ID means to return to address mode */
-#define PL2303_CONFIGID (1) /* The only supported configuration ID */
-#define PL2303_NCONFIGS (1) /* Number of configurations supported */
-#define PL2303_INTERFACEID (0)
-#define PL2303_ALTINTERFACEID (0)
-#define PL2303_NINTERFACES (1) /* Number of interfaces in the configuration */
-#define PL2303_NENDPOINTS (3) /* Number of endpoints in the interface */
-
-/* Endpoint configuration */
-
-#define PL2303_EPINTIN_ADDR (USB_DIR_IN|CONFIG_PL2303_EPINTIN)
-#define PL2303_EPINTIN_ATTR (USB_EP_ATTR_XFER_INT)
-#define PL2303_EPINTIN_MXPACKET (10)
-
-#define PL2303_EPOUTBULK_ADDR (CONFIG_PL2303_EPBULKOUT)
-#define PL2303_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK)
-
-#define PL2303_EPINBULK_ADDR (USB_DIR_IN|CONFIG_PL2303_EPBULKIN)
-#define PL2303_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK)
-
-/* String language */
-
-#define PL2303_STR_LANGUAGE (0x0409) /* en-us */
-
-/* Descriptor strings */
-
-#define PL2303_MANUFACTURERSTRID (1)
-#define PL2303_PRODUCTSTRID (2)
-#define PL2303_SERIALSTRID (3)
-#define PL2303_CONFIGSTRID (4)
-
-/* Buffer big enough for any of our descriptors */
-
-#define PL2303_MXDESCLEN (64)
-
-/* Vender specific control requests *******************************************/
-
-#define PL2303_CONTROL_TYPE (0x20)
-#define PL2303_SETLINEREQUEST (0x20) /* OUT, Recipient interface */
-#define PL2303_GETLINEREQUEST (0x21) /* IN, Recipient interface */
-#define PL2303_SETCONTROLREQUEST (0x22) /* OUT, Recipient interface */
-#define PL2303_BREAKREQUEST (0x23) /* OUT, Recipient interface */
-
-/* Vendor read/write */
-
-#define PL2303_RWREQUEST_TYPE (0x40)
-#define PL2303_RWREQUEST (0x01) /* IN/OUT, Recipient device */
-
-/* Misc Macros ****************************************************************/
-
-/* min/max macros */
-
-#ifndef min
-# define min(a,b) ((a)<(b)?(a):(b))
-#endif
-
-#ifndef max
-# define max(a,b) ((a)>(b)?(a):(b))
-#endif
-
-/* Trace values *************************************************************/
-
-#define PL2303_CLASSAPI_SETUP TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SETUP)
-#define PL2303_CLASSAPI_SHUTDOWN TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SHUTDOWN)
-#define PL2303_CLASSAPI_ATTACH TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_ATTACH)
-#define PL2303_CLASSAPI_DETACH TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_DETACH)
-#define PL2303_CLASSAPI_IOCTL TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_IOCTL)
-#define PL2303_CLASSAPI_RECEIVE TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RECEIVE)
-#define PL2303_CLASSAPI_RXINT TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RXINT)
-#define PL2303_CLASSAPI_RXAVAILABLE TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_RXAVAILABLE)
-#define PL2303_CLASSAPI_SEND TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_SEND)
-#define PL2303_CLASSAPI_TXINT TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXINT)
-#define PL2303_CLASSAPI_TXREADY TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXREADY)
-#define PL2303_CLASSAPI_TXEMPTY TRACE_EVENT(TRACE_CLASSAPI_ID, USBSER_TRACECLASSAPI_TXEMPTY)
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* Container to support a list of requests */
-
-struct pl2303_req_s
-{
- FAR struct pl2303_req_s *flink; /* Implements a singly linked list */
- FAR struct usbdev_req_s *req; /* The contained request */
-};
-
-/* This structure describes the internal state of the driver */
-
-struct pl2303_dev_s
-{
- FAR struct uart_dev_s serdev; /* Serial device structure */
- FAR struct usbdev_s *usbdev; /* usbdev driver pointer */
-
- uint8_t config; /* Configuration number */
- uint8_t nwrq; /* Number of queue write requests (in reqlist)*/
- uint8_t nrdq; /* Number of queue read requests (in epbulkout) */
- bool rxenabled; /* true: UART RX "interrupts" enabled */
- uint8_t linest[7]; /* Fake line status */
- int16_t rxhead; /* Working head; used when rx int disabled */
-
- FAR struct usbdev_ep_s *epintin; /* Interrupt IN endpoint structure */
- FAR struct usbdev_ep_s *epbulkin; /* Bulk IN endpoint structure */
- FAR struct usbdev_ep_s *epbulkout; /* Bulk OUT endpoint structure */
- FAR struct usbdev_req_s *ctrlreq; /* Control request */
- struct sq_queue_s reqlist; /* List of write request containers */
-
- /* Pre-allocated write request containers. The write requests will
- * be linked in a free list (reqlist), and used to send requests to
- * EPBULKIN; Read requests will be queued in the EBULKOUT.
- */
-
- struct pl2303_req_s wrreqs[CONFIG_PL2303_NWRREQS];
- struct pl2303_req_s rdreqs[CONFIG_PL2303_NWRREQS];
-
- /* Serial I/O buffers */
-
- char rxbuffer[CONFIG_PL2303_RXBUFSIZE];
- char txbuffer[CONFIG_PL2303_TXBUFSIZE];
-};
-
-/* The internal version of the class driver */
-
-struct pl2303_driver_s
-{
- struct usbdevclass_driver_s drvr;
- FAR struct pl2303_dev_s *dev;
-};
-
-/* This is what is allocated */
-
-struct pl2303_alloc_s
-{
- struct pl2303_dev_s dev;
- struct pl2303_driver_s drvr;
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Transfer helpers *********************************************************/
-
-static uint16_t usbclass_fillrequest(FAR struct pl2303_dev_s *priv,
- uint8_t *reqbuf, uint16_t reqlen);
-static int usbclass_sndpacket(FAR struct pl2303_dev_s *priv);
-static inline int usbclass_recvpacket(FAR struct pl2303_dev_s *priv,
- uint8_t *reqbuf, uint16_t reqlen);
-
-/* Request helpers *********************************************************/
-
-static struct usbdev_req_s *usbclass_allocreq(FAR struct usbdev_ep_s *ep,
- uint16_t len);
-static void usbclass_freereq(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-
-/* Configuration ***********************************************************/
-
-static int usbclass_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
-#ifdef CONFIG_USBDEV_DUALSPEED
-static void usbclass_mkepbulkdesc(const struct usb_epdesc_s *indesc,
- uint16_t mxpacket, struct usb_epdesc_s *outdesc);
-static int16_t usbclass_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type);
-#else
-static int16_t usbclass_mkcfgdesc(uint8_t *buf);
-#endif
-static void usbclass_resetconfig(FAR struct pl2303_dev_s *priv);
-static int usbclass_setconfig(FAR struct pl2303_dev_s *priv,
- uint8_t config);
-
-/* Completion event handlers ***********************************************/
-
-static void usbclass_ep0incomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-static void usbclass_rdcomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-
-/* USB class device ********************************************************/
-
-static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
- size_t outlen);
-static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-#ifdef CONFIG_SERIAL_REMOVABLE
-static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void usbclass_resume(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-#endif
-
-/* Serial port *************************************************************/
-
-static int usbser_setup(FAR struct uart_dev_s *dev);
-static void usbser_shutdown(FAR struct uart_dev_s *dev);
-static int usbser_attach(FAR struct uart_dev_s *dev);
-static void usbser_detach(FAR struct uart_dev_s *dev);
-static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable);
-static void usbser_txint(FAR struct uart_dev_s *dev, bool enable);
-static bool usbser_txempty(FAR struct uart_dev_s *dev);
-
-/****************************************************************************
- * Private Variables
- ****************************************************************************/
-
-/* USB class device ********************************************************/
-
-static const struct usbdevclass_driverops_s g_driverops =
-{
- usbclass_bind, /* bind */
- usbclass_unbind, /* unbind */
- usbclass_setup, /* setup */
- usbclass_disconnect, /* disconnect */
-#ifdef CONFIG_SERIAL_REMOVABLE
- usbclass_suspend, /* suspend */
- usbclass_resume, /* resume */
-#else
- NULL, /* suspend */
- NULL, /* resume */
-#endif
-};
-
-/* Serial port *************************************************************/
-
-static const struct uart_ops_s g_uartops =
-{
- usbser_setup, /* setup */
- usbser_shutdown, /* shutdown */
- usbser_attach, /* attach */
- usbser_detach, /* detach */
- NULL, /* ioctl */
- NULL, /* receive */
- usbser_rxint, /* rxinit */
- NULL, /* rxavailable */
- NULL, /* send */
- usbser_txint, /* txinit */
- NULL, /* txready */
- usbser_txempty /* txempty */
-};
-
-/* USB descriptor templates these will be copied and modified **************/
-
-static const struct usb_devdesc_s g_devdesc =
-{
- USB_SIZEOF_DEVDESC, /* len */
- USB_DESC_TYPE_DEVICE, /* type */
- {LSBYTE(0x0200), MSBYTE(0x0200)}, /* usb */
- USB_CLASS_PER_INTERFACE, /* classid */
- 0, /* subclass */
- 0, /* protocol */
- CONFIG_PL2303_EP0MAXPACKET, /* maxpacketsize */
- { LSBYTE(CONFIG_PL2303_VENDORID), /* vendor */
- MSBYTE(CONFIG_PL2303_VENDORID) },
- { LSBYTE(CONFIG_PL2303_PRODUCTID), /* product */
- MSBYTE(CONFIG_PL2303_PRODUCTID) },
- { LSBYTE(PL2303_VERSIONNO), /* device */
- MSBYTE(PL2303_VERSIONNO) },
- PL2303_MANUFACTURERSTRID, /* imfgr */
- PL2303_PRODUCTSTRID, /* iproduct */
- PL2303_SERIALSTRID, /* serno */
- PL2303_NCONFIGS /* nconfigs */
-};
-
-static const struct usb_cfgdesc_s g_cfgdesc =
-{
- USB_SIZEOF_CFGDESC, /* len */
- USB_DESC_TYPE_CONFIG, /* type */
- {0, 0}, /* totallen -- to be provided */
- PL2303_NINTERFACES, /* ninterfaces */
- PL2303_CONFIGID, /* cfgvalue */
- PL2303_CONFIGSTRID, /* icfg */
- USB_CONFIG_ATTR_ONE|SELFPOWERED|REMOTEWAKEUP, /* attr */
- (CONFIG_USBDEV_MAXPOWER + 1) / 2 /* mxpower */
-};
-
-static const struct usb_ifdesc_s g_ifdesc =
-{
- USB_SIZEOF_IFDESC, /* len */
- USB_DESC_TYPE_INTERFACE, /* type */
- 0, /* ifno */
- 0, /* alt */
- PL2303_NENDPOINTS, /* neps */
- USB_CLASS_VENDOR_SPEC, /* classid */
- 0, /* subclass */
- 0, /* protocol */
- PL2303_CONFIGSTRID /* iif */
-};
-
-static const struct usb_epdesc_s g_epintindesc =
-{
- USB_SIZEOF_EPDESC, /* len */
- USB_DESC_TYPE_ENDPOINT, /* type */
- PL2303_EPINTIN_ADDR, /* addr */
- PL2303_EPINTIN_ATTR, /* attr */
- { LSBYTE(PL2303_EPINTIN_MXPACKET), /* maxpacket */
- MSBYTE(PL2303_EPINTIN_MXPACKET) },
- 1 /* interval */
-};
-
-static const struct usb_epdesc_s g_epbulkoutdesc =
-{
- USB_SIZEOF_EPDESC, /* len */
- USB_DESC_TYPE_ENDPOINT, /* type */
- PL2303_EPOUTBULK_ADDR, /* addr */
- PL2303_EPOUTBULK_ATTR, /* attr */
- { LSBYTE(64), MSBYTE(64) }, /* maxpacket -- might change to 512*/
- 0 /* interval */
-};
-
-static const struct usb_epdesc_s g_epbulkindesc =
-{
- USB_SIZEOF_EPDESC, /* len */
- USB_DESC_TYPE_ENDPOINT, /* type */
- PL2303_EPINBULK_ADDR, /* addr */
- PL2303_EPINBULK_ATTR, /* attr */
- { LSBYTE(64), MSBYTE(64) }, /* maxpacket -- might change to 512*/
- 0 /* interval */
-};
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-static const struct usb_qualdesc_s g_qualdesc =
-{
- USB_SIZEOF_QUALDESC, /* len */
- USB_DESC_TYPE_DEVICEQUALIFIER, /* type */
- {LSBYTE(0x0200), MSBYTE(0x0200) }, /* USB */
- USB_CLASS_VENDOR_SPEC, /* classid */
- 0, /* subclass */
- 0, /* protocol */
- CONFIG_PL2303_EP0MAXPACKET, /* mxpacketsize */
- PL2303_NCONFIGS, /* nconfigs */
- 0, /* reserved */
-};
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/************************************************************************************
- * Name: usbclass_fillrequest
- *
- * Description:
- * If there is data to send it is copied to the given buffer. Called either
- * to initiate the first write operation, or from the completion interrupt handler
- * service consecutive write operations.
- *
- * NOTE: The USB serial driver does not use the serial drivers uart_xmitchars()
- * API. That logic is essentially duplicated here because unlike UART hardware,
- * we need to be able to handle writes not byte-by-byte, but packet-by-packet.
- * Unfortunately, that decision also exposes some internals of the serial driver
- * in the following.
- *
- ************************************************************************************/
-
-static uint16_t usbclass_fillrequest(FAR struct pl2303_dev_s *priv, uint8_t *reqbuf,
- uint16_t reqlen)
-{
- FAR uart_dev_t *serdev = &priv->serdev;
- FAR struct uart_buffer_s *xmit = &serdev->xmit;
- irqstate_t flags;
- uint16_t nbytes = 0;
-
- /* Disable interrupts */
-
- flags = irqsave();
-
- /* Transfer bytes while we have bytes available and there is room in the request */
-
- while (xmit->head != xmit->tail && nbytes < reqlen)
- {
- *reqbuf++ = xmit->buffer[xmit->tail];
- nbytes++;
-
- /* Increment the tail pointer */
-
- if (++(xmit->tail) >= xmit->size)
- {
- xmit->tail = 0;
- }
- }
-
- /* When all of the characters have been sent from the buffer
- * disable the "TX interrupt".
- */
-
- if (xmit->head == xmit->tail)
- {
- uart_disabletxint(serdev);
- }
-
- /* If any bytes were removed from the buffer, inform any waiters
- * there there is space available.
- */
-
- if (nbytes)
- {
- uart_datasent(serdev);
- }
-
- irqrestore(flags);
- return nbytes;
-}
-
-/************************************************************************************
- * Name: usbclass_sndpacket
- *
- * Description:
- * This function obtains write requests, transfers the TX data into the request,
- * and submits the requests to the USB controller. This continues untils either
- * (1) there are no further packets available, or (2) thre is not further data
- * to send.
- *
- ************************************************************************************/
-
-static int usbclass_sndpacket(FAR struct pl2303_dev_s *priv)
-{
- FAR struct usbdev_ep_s *ep;
- FAR struct usbdev_req_s *req;
- FAR struct pl2303_req_s *reqcontainer;
- uint16_t reqlen;
- irqstate_t flags;
- int len;
- int ret = OK;
-
-#ifdef CONFIG_DEBUG
- if (priv == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return -ENODEV;
- }
-#endif
-
- flags = irqsave();
-
- /* Use our IN endpoint for the transfer */
-
- ep = priv->epbulkin;
-
- /* Loop until either (1) we run out or write requests, or (2) usbclass_fillrequest()
- * is unable to fill the request with data (i.e., until there is no more data
- * to be sent).
- */
-
- uvdbg("head=%d tail=%d nwrq=%d empty=%d\n",
- priv->serdev.xmit.head, priv->serdev.xmit.tail,
- priv->nwrq, sq_empty(&priv->reqlist));
-
- /* Get the maximum number of bytes that will fit into one bulk IN request */
-
-#ifdef CONFIG_PL2303_BULKREQLEN
- reqlen = MAX(CONFIG_PL2303_BULKREQLEN, ep->maxpacket);
-#else
- reqlen = ep->maxpacket;
-#endif
-
- while (!sq_empty(&priv->reqlist))
- {
- /* Peek at the request in the container at the head of the list */
-
- reqcontainer = (struct pl2303_req_s *)sq_peek(&priv->reqlist);
- req = reqcontainer->req;
-
- /* Fill the request with serial TX data */
-
- len = usbclass_fillrequest(priv, req->buf, reqlen);
- if (len > 0)
- {
- /* Remove the empty container from the request list */
-
- (void)sq_remfirst(&priv->reqlist);
- priv->nwrq--;
-
- /* Then submit the request to the endpoint */
-
- req->len = len;
- req->priv = reqcontainer;
- req->flags = USBDEV_REQFLAGS_NULLPKT;
- ret = EP_SUBMIT(ep, req);
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_SUBMITFAIL), (uint16_t)-ret);
- break;
- }
- }
- else
- {
- break;
- }
- }
-
- irqrestore(flags);
- return ret;
-}
-
-/************************************************************************************
- * Name: usbclass_recvpacket
- *
- * Description:
- * A normal completion event was received by the read completion handler at the
- * interrupt level (with interrupts disabled). This function handles the USB packet
- * and provides the received data to the uart RX buffer.
- *
- * Assumptions:
- * Called from the USB interrupt handler with interrupts disabled.
- *
- ************************************************************************************/
-
-static inline int usbclass_recvpacket(FAR struct pl2303_dev_s *priv,
- uint8_t *reqbuf, uint16_t reqlen)
-{
- FAR uart_dev_t *serdev = &priv->serdev;
- FAR struct uart_buffer_s *recv = &serdev->recv;
- uint16_t currhead;
- uint16_t nexthead;
- uint16_t nbytes = 0;
-
- /* Get the next head index. During the time that RX interrupts are disabled, the
- * the serial driver will be extracting data from the circular buffer and modifying
- * recv.tail. During this time, we should avoid modifying recv.head; Instead we will
- * use a shadow copy of the index. When interrupts are restored, the real recv.head
- * will be updated with this indes.
- */
-
- if (priv->rxenabled)
- {
- currhead = recv->head;
- }
- else
- {
- currhead = priv->rxhead;
- }
-
- /* Pre-calculate the head index and check for wrap around. We need to do this
- * so that we can determine if the circular buffer will overrun BEFORE we
- * overrun the buffer!
- */
-
- nexthead = currhead + 1;
- if (nexthead >= recv->size)
- {
- nexthead = 0;
- }
-
- /* Then copy data into the RX buffer until either: (1) all of the data has been
- * copied, or (2) the RX buffer is full. NOTE: If the RX buffer becomes full,
- * then we have overrun the serial driver and data will be lost.
- */
-
- while (nexthead != recv->tail && nbytes < reqlen)
- {
- /* Copy one byte to the head of the circular RX buffer */
-
- recv->buffer[currhead] = *reqbuf++;
-
- /* Update counts and indices */
-
- currhead = nexthead;
- nbytes++;
-
- /* Increment the head index and check for wrap around */
-
- nexthead = currhead + 1;
- if (nexthead >= recv->size)
- {
- nexthead = 0;
- }
- }
-
- /* Write back the head pointer using the shadow index if RX "interrupts"
- * are disabled.
- */
-
- if (priv->rxenabled)
- {
- recv->head = currhead;
- }
- else
- {
- priv->rxhead = currhead;
- }
-
- /* If data was added to the incoming serial buffer, then wake up any
- * threads is waiting for incoming data. If we are running in an interrupt
- * handler, then the serial driver will not run until the interrupt handler
- * returns.
- */
-
- if (priv->rxenabled && nbytes > 0)
- {
- uart_datareceived(serdev);
- }
-
- /* Return an error if the entire packet could not be transferred */
-
- if (nbytes < reqlen)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RXOVERRUN), 0);
- return -ENOSPC;
- }
- return OK;
-}
-
-/****************************************************************************
- * Name: usbclass_allocreq
- *
- * Description:
- * Allocate a request instance along with its buffer
- *
- ****************************************************************************/
-
-static struct usbdev_req_s *usbclass_allocreq(FAR struct usbdev_ep_s *ep,
- uint16_t len)
-{
- FAR struct usbdev_req_s *req;
-
- req = EP_ALLOCREQ(ep);
- if (req != NULL)
- {
- req->len = len;
- req->buf = EP_ALLOCBUFFER(ep, len);
- if (!req->buf)
- {
- EP_FREEREQ(ep, req);
- req = NULL;
- }
- }
- return req;
-}
-
-/****************************************************************************
- * Name: usbclass_freereq
- *
- * Description:
- * Free a request instance along with its buffer
- *
- ****************************************************************************/
-
-static void usbclass_freereq(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- if (ep != NULL && req != NULL)
- {
- if (req->buf != NULL)
- {
- EP_FREEBUFFER(ep, req->buf);
- }
- EP_FREEREQ(ep, req);
- }
-}
-
-/****************************************************************************
- * Name: usbclass_mkstrdesc
- *
- * Description:
- * Construct a string descriptor
- *
- ****************************************************************************/
-
-static int usbclass_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc)
-{
- const char *str;
- int len;
- int ndata;
- int i;
-
- switch (id)
- {
- case 0:
- {
- /* Descriptor 0 is the language id */
-
- strdesc->len = 4;
- strdesc->type = USB_DESC_TYPE_STRING;
- strdesc->data[0] = LSBYTE(PL2303_STR_LANGUAGE);
- strdesc->data[1] = MSBYTE(PL2303_STR_LANGUAGE);
- return 4;
- }
-
- case PL2303_MANUFACTURERSTRID:
- str = CONFIG_PL2303_VENDORSTR;
- break;
-
- case PL2303_PRODUCTSTRID:
- str = CONFIG_PL2303_PRODUCTSTR;
- break;
-
- case PL2303_SERIALSTRID:
- str = CONFIG_PL2303_SERIALSTR;
- break;
-
- case PL2303_CONFIGSTRID:
- str = CONFIG_PL2303_CONFIGSTR;
- break;
-
- default:
- return -EINVAL;
- }
-
- /* The string is utf16-le. The poor man's utf-8 to utf16-le
- * conversion below will only handle 7-bit en-us ascii
- */
-
- len = strlen(str);
- for (i = 0, ndata = 0; i < len; i++, ndata += 2)
- {
- strdesc->data[ndata] = str[i];
- strdesc->data[ndata+1] = 0;
- }
-
- strdesc->len = ndata+2;
- strdesc->type = USB_DESC_TYPE_STRING;
- return strdesc->len;
-}
-
-/****************************************************************************
- * Name: usbclass_mkepbulkdesc
- *
- * Description:
- * Construct the endpoint descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-static inline void usbclass_mkepbulkdesc(const FAR struct usb_epdesc_s *indesc,
- uint16_t mxpacket,
- FAR struct usb_epdesc_s *outdesc)
-{
- /* Copy the canned descriptor */
-
- memcpy(outdesc, indesc, USB_SIZEOF_EPDESC);
-
- /* Then add the correct max packet size */
-
- outdesc->mxpacketsize[0] = LSBYTE(mxpacket);
- outdesc->mxpacketsize[1] = MSBYTE(mxpacket);
-}
-#endif
-
-/****************************************************************************
- * Name: usbclass_mkcfgdesc
- *
- * Description:
- * Construct the configuration descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-static int16_t usbclass_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type)
-#else
-static int16_t usbclass_mkcfgdesc(uint8_t *buf)
-#endif
-{
- FAR struct usb_cfgdesc_s *cfgdesc = (struct usb_cfgdesc_s*)buf;
-#ifdef CONFIG_USBDEV_DUALSPEED
- bool hispeed = (speed == USB_SPEED_HIGH);
- uint16_t bulkmxpacket;
-#endif
- uint16_t totallen;
-
- /* This is the total length of the configuration (not necessarily the
- * size that we will be sending now.
- */
-
- totallen = USB_SIZEOF_CFGDESC + USB_SIZEOF_IFDESC + PL2303_NENDPOINTS * USB_SIZEOF_EPDESC;
-
- /* Configuration descriptor -- Copy the canned descriptor and fill in the
- * type (we'll also need to update the size below
- */
-
- memcpy(cfgdesc, &g_cfgdesc, USB_SIZEOF_CFGDESC);
- buf += USB_SIZEOF_CFGDESC;
-
- /* Copy the canned interface descriptor */
-
- memcpy(buf, &g_ifdesc, USB_SIZEOF_IFDESC);
- buf += USB_SIZEOF_IFDESC;
-
- /* Make the three endpoint configurations. First, check for switches
- * between high and full speed
- */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
- {
- hispeed = !hispeed;
- }
-#endif
-
- memcpy(buf, &g_epintindesc, USB_SIZEOF_EPDESC);
- buf += USB_SIZEOF_EPDESC;
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- if (hispeed)
- {
- bulkmxpacket = 512;
- }
- else
- {
- bulkmxpacket = 64;
- }
-
- usbclass_mkepbulkdesc(&g_epbulkoutdesc, bulkmxpacket, (struct usb_epdesc_s*)buf);
- buf += USB_SIZEOF_EPDESC;
- usbclass_mkepbulkdesc(&g_epbulkindesc, bulkmxpacket, (struct usb_epdesc_s*)buf);
-#else
- memcpy(buf, &g_epbulkoutdesc, USB_SIZEOF_EPDESC);
- buf += USB_SIZEOF_EPDESC;
- memcpy(buf, &g_epbulkindesc, USB_SIZEOF_EPDESC);
-#endif
-
- /* Finally, fill in the total size of the configuration descriptor */
-
- cfgdesc->totallen[0] = LSBYTE(totallen);
- cfgdesc->totallen[1] = MSBYTE(totallen);
- return totallen;
-}
-
-/****************************************************************************
- * Name: usbclass_resetconfig
- *
- * Description:
- * Mark the device as not configured and disable all endpoints.
- *
- ****************************************************************************/
-
-static void usbclass_resetconfig(FAR struct pl2303_dev_s *priv)
-{
- /* Are we configured? */
-
- if (priv->config != PL2303_CONFIGIDNONE)
- {
- /* Yes.. but not anymore */
-
- priv->config = PL2303_CONFIGIDNONE;
-
- /* Inform the "upper half" driver that there is no (functional) USB
- * connection.
- */
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- uart_connected(&priv->serdev, false);
-#endif
-
- /* Disable endpoints. This should force completion of all pending
- * transfers.
- */
-
- EP_DISABLE(priv->epintin);
- EP_DISABLE(priv->epbulkin);
- EP_DISABLE(priv->epbulkout);
- }
-}
-
-/****************************************************************************
- * Name: usbclass_setconfig
- *
- * Description:
- * Set the device configuration by allocating and configuring endpoints and
- * by allocating and queue read and write requests.
- *
- ****************************************************************************/
-
-static int usbclass_setconfig(FAR struct pl2303_dev_s *priv, uint8_t config)
-{
- FAR struct usbdev_req_s *req;
-#ifdef CONFIG_USBDEV_DUALSPEED
- struct usb_epdesc_s epdesc;
- uint16_t bulkmxpacket;
-#endif
- int i;
- int ret = 0;
-
-#if CONFIG_DEBUG
- if (priv == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return -EIO;
- }
-#endif
-
- if (config == priv->config)
- {
- /* Already configured -- Do nothing */
-
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALREADYCONFIGURED), 0);
- return 0;
- }
-
- /* Discard the previous configuration data */
-
- usbclass_resetconfig(priv);
-
- /* Was this a request to simply discard the current configuration? */
-
- if (config == PL2303_CONFIGIDNONE)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_CONFIGNONE), 0);
- return 0;
- }
-
- /* We only accept one configuration */
-
- if (config != PL2303_CONFIGID)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_CONFIGIDBAD), 0);
- return -EINVAL;
- }
-
- /* Configure the IN interrupt endpoint */
-
- ret = EP_CONFIGURE(priv->epintin, &g_epintindesc, false);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINCONFIGFAIL), 0);
- goto errout;
- }
- priv->epintin->priv = priv;
-
- /* Configure the IN bulk endpoint */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- if (priv->usbdev->speed == USB_SPEED_HIGH)
- {
- bulkmxpacket = 512;
- }
- else
- {
- bulkmxpacket = 64;
- }
-
- usbclass_mkepbulkdesc(&g_epbulkindesc, bulkmxpacket, &epdesc);
- ret = EP_CONFIGURE(priv->epbulkin, &epdesc, false);
-#else
- ret = EP_CONFIGURE(priv->epbulkin, &g_epbulkindesc, false);
-#endif
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINCONFIGFAIL), 0);
- goto errout;
- }
-
- priv->epbulkin->priv = priv;
-
- /* Configure the OUT bulk endpoint */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- usbclass_mkepbulkdesc(&g_epbulkoutdesc, bulkmxpacket, &epdesc);
- ret = EP_CONFIGURE(priv->epbulkout, &epdesc, true);
-#else
- ret = EP_CONFIGURE(priv->epbulkout, &g_epbulkoutdesc, true);
-#endif
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTCONFIGFAIL), 0);
- goto errout;
- }
-
- priv->epbulkout->priv = priv;
-
- /* Queue read requests in the bulk OUT endpoint */
-
- DEBUGASSERT(priv->nrdq == 0);
- for (i = 0; i < CONFIG_PL2303_NRDREQS; i++)
- {
- req = priv->rdreqs[i].req;
- req->callback = usbclass_rdcomplete;
- ret = EP_SUBMIT(priv->epbulkout, req);
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-ret);
- goto errout;
- }
-
- priv->nrdq++;
- }
-
- /* We are successfully configured */
-
- priv->config = config;
-
- /* Inform the "upper half" driver that we are "open for business" */
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- uart_connected(&priv->serdev, true);
-#endif
-
- return OK;
-
-errout:
- usbclass_resetconfig(priv);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbclass_ep0incomplete
- *
- * Description:
- * Handle completion of EP0 control operations
- *
- ****************************************************************************/
-
-static void usbclass_ep0incomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- if (req->result || req->xfrd != req->len)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_REQRESULT), (uint16_t)-req->result);
- }
-}
-
-/****************************************************************************
- * Name: usbclass_rdcomplete
- *
- * Description:
- * Handle completion of read request on the bulk OUT endpoint. This
- * is handled like the receipt of serial data on the "UART"
- *
- ****************************************************************************/
-
-static void usbclass_rdcomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- FAR struct pl2303_dev_s *priv;
- irqstate_t flags;
- int ret;
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (!ep || !ep->priv || !req)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract references to private data */
-
- priv = (FAR struct pl2303_dev_s*)ep->priv;
-
- /* Process the received data unless this is some unusual condition */
-
- flags = irqsave();
- switch (req->result)
- {
- case 0: /* Normal completion */
- usbtrace(TRACE_CLASSRDCOMPLETE, priv->nrdq);
- usbclass_recvpacket(priv, req->buf, req->xfrd);
- break;
-
- case -ESHUTDOWN: /* Disconnection */
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSHUTDOWN), 0);
- priv->nrdq--;
- irqrestore(flags);
- return;
-
- default: /* Some other error occurred */
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDUNEXPECTED), (uint16_t)-req->result);
- break;
- };
-
- /* Requeue the read request */
-
-#ifdef CONFIG_PL2303_BULKREQLEN
- req->len = max(CONFIG_PL2303_BULKREQLEN, ep->maxpacket);
-#else
- req->len = ep->maxpacket;
-#endif
-
- ret = EP_SUBMIT(ep, req);
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDSUBMIT), (uint16_t)-req->result);
- }
- irqrestore(flags);
-}
-
-/****************************************************************************
- * Name: usbclass_wrcomplete
- *
- * Description:
- * Handle completion of write request. This function probably executes
- * in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-static void usbclass_wrcomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- FAR struct pl2303_dev_s *priv;
- FAR struct pl2303_req_s *reqcontainer;
- irqstate_t flags;
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (!ep || !ep->priv || !req || !req->priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract references to our private data */
-
- priv = (FAR struct pl2303_dev_s *)ep->priv;
- reqcontainer = (FAR struct pl2303_req_s *)req->priv;
-
- /* Return the write request to the free list */
-
- flags = irqsave();
- sq_addlast((sq_entry_t*)reqcontainer, &priv->reqlist);
- priv->nwrq++;
- irqrestore(flags);
-
- /* Send the next packet unless this was some unusual termination
- * condition
- */
-
- switch (req->result)
- {
- case OK: /* Normal completion */
- usbtrace(TRACE_CLASSWRCOMPLETE, priv->nwrq);
- usbclass_sndpacket(priv);
- break;
-
- case -ESHUTDOWN: /* Disconnection */
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRSHUTDOWN), priv->nwrq);
- break;
-
- default: /* Some other error occurred */
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRUNEXPECTED), (uint16_t)-req->result);
- break;
- }
-}
-
-/****************************************************************************
- * USB Class Driver Methods
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbclass_bind
- *
- * Description:
- * Invoked when the driver is bound to a USB device driver
- *
- ****************************************************************************/
-
-static int usbclass_bind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct pl2303_dev_s *priv = ((FAR struct pl2303_driver_s*)driver)->dev;
- FAR struct pl2303_req_s *reqcontainer;
- irqstate_t flags;
- uint16_t reqlen;
- int ret;
- int i;
-
- usbtrace(TRACE_CLASSBIND, 0);
-
- /* Bind the structures */
-
- priv->usbdev = dev;
-
- /* Save the reference to our private data structure in EP0 so that it
- * can be recovered in ep0 completion events (Unless we are part of
- * a composite device and, in that case, the composite device owns
- * EP0).
- */
-
- dev->ep0->priv = priv;
-
- /* Preallocate control request */
-
- priv->ctrlreq = usbclass_allocreq(dev->ep0, PL2303_MXDESCLEN);
- if (priv->ctrlreq == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCCTRLREQ), 0);
- ret = -ENOMEM;
- goto errout;
- }
- priv->ctrlreq->callback = usbclass_ep0incomplete;
-
- /* Pre-allocate all endpoints... the endpoints will not be functional
- * until the SET CONFIGURATION request is processed in usbclass_setconfig.
- * This is done here because there may be calls to kmalloc and the SET
- * CONFIGURATION processing probably occurrs within interrupt handling
- * logic where kmalloc calls will fail.
- */
-
- /* Pre-allocate the IN interrupt endpoint */
-
- priv->epintin = DEV_ALLOCEP(dev, PL2303_EPINTIN_ADDR, true, USB_EP_ATTR_XFER_INT);
- if (!priv->epintin)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPINTINALLOCFAIL), 0);
- ret = -ENODEV;
- goto errout;
- }
- priv->epintin->priv = priv;
-
- /* Pre-allocate the IN bulk endpoint */
-
- priv->epbulkin = DEV_ALLOCEP(dev, PL2303_EPINBULK_ADDR, true, USB_EP_ATTR_XFER_BULK);
- if (!priv->epbulkin)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKINALLOCFAIL), 0);
- ret = -ENODEV;
- goto errout;
- }
- priv->epbulkin->priv = priv;
-
- /* Pre-allocate the OUT bulk endpoint */
-
- priv->epbulkout = DEV_ALLOCEP(dev, PL2303_EPOUTBULK_ADDR, false, USB_EP_ATTR_XFER_BULK);
- if (!priv->epbulkout)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPBULKOUTALLOCFAIL), 0);
- ret = -ENODEV;
- goto errout;
- }
- priv->epbulkout->priv = priv;
-
- /* Pre-allocate read requests */
-
-#ifdef CONFIG_PL2303_BULKREQLEN
- reqlen = max(CONFIG_PL2303_BULKREQLEN, priv->epbulkout->maxpacket);
-#else
- reqlen = priv->epbulkout->maxpacket;
-#endif
-
- for (i = 0; i < CONFIG_PL2303_NRDREQS; i++)
- {
- reqcontainer = &priv->rdreqs[i];
- reqcontainer->req = usbclass_allocreq(priv->epbulkout, reqlen);
- if (reqcontainer->req == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_RDALLOCREQ), -ENOMEM);
- ret = -ENOMEM;
- goto errout;
- }
- reqcontainer->req->priv = reqcontainer;
- reqcontainer->req->callback = usbclass_rdcomplete;
- }
-
- /* Pre-allocate write request containers and put in a free list */
-
-#ifdef CONFIG_PL2303_BULKREQLEN
- reqlen = max(CONFIG_PL2303_BULKREQLEN, priv->epbulkin->maxpacket);
-#else
- reqlen = priv->epbulkin->maxpacket;
-#endif
-
- for (i = 0; i < CONFIG_PL2303_NWRREQS; i++)
- {
- reqcontainer = &priv->wrreqs[i];
- reqcontainer->req = usbclass_allocreq(priv->epbulkin, reqlen);
- if (reqcontainer->req == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_WRALLOCREQ), -ENOMEM);
- ret = -ENOMEM;
- goto errout;
- }
- reqcontainer->req->priv = reqcontainer;
- reqcontainer->req->callback = usbclass_wrcomplete;
-
- flags = irqsave();
- sq_addlast((sq_entry_t*)reqcontainer, &priv->reqlist);
- priv->nwrq++; /* Count of write requests available */
- irqrestore(flags);
- }
-
- /* Report if we are selfpowered */
-
-#ifdef CONFIG_USBDEV_SELFPOWERED
- DEV_SETSELFPOWERED(dev);
-#endif
-
- /* And pull-up the data line for the soft connect function */
-
- DEV_CONNECT(dev);
- return OK;
-
-errout:
- usbclass_unbind(driver, dev);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbclass_unbind
- *
- * Description:
- * Invoked when the driver is unbound from a USB device driver
- *
- ****************************************************************************/
-
-static void usbclass_unbind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct pl2303_dev_s *priv;
- FAR struct pl2303_req_s *reqcontainer;
- irqstate_t flags;
- int i;
-
- usbtrace(TRACE_CLASSUNBIND, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct pl2303_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Make sure that we are not already unbound */
-
- if (priv != NULL)
- {
- /* Make sure that the endpoints have been unconfigured. If
- * we were terminated gracefully, then the configuration should
- * already have been reset. If not, then calling usbclass_resetconfig
- * should cause the endpoints to immediately terminate all
- * transfers and return the requests to us (with result == -ESHUTDOWN)
- */
-
- usbclass_resetconfig(priv);
- up_mdelay(50);
-
- /* Free the interrupt IN endpoint */
-
- if (priv->epintin)
- {
- DEV_FREEEP(dev, priv->epintin);
- priv->epintin = NULL;
- }
-
- /* Free the bulk IN endpoint */
-
- if (priv->epbulkin)
- {
- DEV_FREEEP(dev, priv->epbulkin);
- priv->epbulkin = NULL;
- }
-
- /* Free the pre-allocated control request */
-
- if (priv->ctrlreq != NULL)
- {
- usbclass_freereq(dev->ep0, priv->ctrlreq);
- priv->ctrlreq = NULL;
- }
-
- /* Free pre-allocated read requests (which should all have
- * been returned to the free list at this time -- we don't check)
- */
-
- DEBUGASSERT(priv->nrdq == 0);
- for (i = 0; i < CONFIG_PL2303_NRDREQS; i++)
- {
- reqcontainer = &priv->rdreqs[i];
- if (reqcontainer->req)
- {
- usbclass_freereq(priv->epbulkout, reqcontainer->req);
- reqcontainer->req = NULL;
- }
- }
-
- /* Free the bulk OUT endpoint */
-
- if (priv->epbulkout)
- {
- DEV_FREEEP(dev, priv->epbulkout);
- priv->epbulkout = NULL;
- }
-
- /* Free write requests that are not in use (which should be all
- * of them
- */
-
- flags = irqsave();
- DEBUGASSERT(priv->nwrq == CONFIG_PL2303_NWRREQS);
- while (!sq_empty(&priv->reqlist))
- {
- reqcontainer = (struct pl2303_req_s *)sq_remfirst(&priv->reqlist);
- if (reqcontainer->req != NULL)
- {
- usbclass_freereq(priv->epbulkin, reqcontainer->req);
- priv->nwrq--; /* Number of write requests queued */
- }
- }
- DEBUGASSERT(priv->nwrq == 0);
- irqrestore(flags);
- }
-
- /* Clear out all data in the circular buffer */
-
- priv->serdev.xmit.head = 0;
- priv->serdev.xmit.tail = 0;
-}
-
-/****************************************************************************
- * Name: usbclass_setup
- *
- * Description:
- * Invoked for ep0 control requests. This function probably executes
- * in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-static int usbclass_setup(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl,
- FAR uint8_t *dataout, size_t outlen)
-{
- FAR struct pl2303_dev_s *priv;
- FAR struct usbdev_req_s *ctrlreq;
- uint16_t value;
- uint16_t index;
- uint16_t len;
- int ret = -EOPNOTSUPP;
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0 || !ctrl)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return -EIO;
- }
-#endif
-
- /* Extract reference to private data */
-
- usbtrace(TRACE_CLASSSETUP, ctrl->req);
- priv = ((FAR struct pl2303_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv || !priv->ctrlreq)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
- return -ENODEV;
- }
-#endif
- ctrlreq = priv->ctrlreq;
-
- /* Extract the little-endian 16-bit values to host order */
-
- value = GETUINT16(ctrl->value);
- index = GETUINT16(ctrl->index);
- len = GETUINT16(ctrl->len);
-
- uvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n",
- ctrl->type, ctrl->req, value, index, len);
-
- switch (ctrl->type & USB_REQ_TYPE_MASK)
- {
- /***********************************************************************
- * Standard Requests
- ***********************************************************************/
-
- case USB_REQ_TYPE_STANDARD:
- {
- switch (ctrl->req)
- {
- case USB_REQ_GETDESCRIPTOR:
- {
- /* The value field specifies the descriptor type in the MS byte and the
- * descriptor index in the LS byte (order is little endian)
- */
-
- switch (ctrl->value[1])
- {
- case USB_DESC_TYPE_DEVICE:
- {
- ret = USB_SIZEOF_DEVDESC;
- memcpy(ctrlreq->buf, &g_devdesc, ret);
- }
- break;
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- case USB_DESC_TYPE_DEVICEQUALIFIER:
- {
- ret = USB_SIZEOF_QUALDESC;
- memcpy(ctrlreq->buf, &g_qualdesc, ret);
- }
- break;
-
- case USB_DESC_TYPE_OTHERSPEEDCONFIG:
-#endif /* CONFIG_USBDEV_DUALSPEED */
-
- case USB_DESC_TYPE_CONFIG:
- {
-#ifdef CONFIG_USBDEV_DUALSPEED
- ret = usbclass_mkcfgdesc(ctrlreq->buf, dev->speed, ctrl->req);
-#else
- ret = usbclass_mkcfgdesc(ctrlreq->buf);
-#endif
- }
- break;
-
- case USB_DESC_TYPE_STRING:
- {
- /* index == language code. */
-
- ret = usbclass_mkstrdesc(ctrl->value[0], (struct usb_strdesc_s *)ctrlreq->buf);
- }
- break;
-
- default:
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_GETUNKNOWNDESC), value);
- }
- break;
- }
- }
- break;
-
- case USB_REQ_SETCONFIGURATION:
- {
- if (ctrl->type == 0)
- {
- ret = usbclass_setconfig(priv, value);
- }
- }
- break;
-
- case USB_REQ_GETCONFIGURATION:
- {
- if (ctrl->type == USB_DIR_IN)
- {
- *(uint8_t*)ctrlreq->buf = priv->config;
- ret = 1;
- }
- }
- break;
-
- case USB_REQ_SETINTERFACE:
- {
- if (ctrl->type == USB_REQ_RECIPIENT_INTERFACE)
- {
- if (priv->config == PL2303_CONFIGID &&
- index == PL2303_INTERFACEID &&
- value == PL2303_ALTINTERFACEID)
- {
- usbclass_resetconfig(priv);
- usbclass_setconfig(priv, priv->config);
- ret = 0;
- }
- }
- }
- break;
-
- case USB_REQ_GETINTERFACE:
- {
- if (ctrl->type == (USB_DIR_IN|USB_REQ_RECIPIENT_INTERFACE) &&
- priv->config == PL2303_CONFIGIDNONE)
- {
- if (index != PL2303_INTERFACEID)
- {
- ret = -EDOM;
- }
- else
- {
- *(uint8_t*) ctrlreq->buf = PL2303_ALTINTERFACEID;
- ret = 1;
- }
- }
- }
- break;
-
- default:
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDSTDREQ), ctrl->req);
- break;
- }
- }
- break;
-
- /***********************************************************************
- * PL2303 Vendor-Specific Requests
- ***********************************************************************/
-
- case PL2303_CONTROL_TYPE:
- {
- if ((ctrl->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE)
- {
- switch (ctrl->req)
- {
- case PL2303_SETLINEREQUEST:
- {
- memcpy(priv->linest, ctrlreq->buf, min(len, 7));
- ret = 0;
- }
- break;
-
-
- case PL2303_GETLINEREQUEST:
- {
- memcpy(ctrlreq->buf, priv->linest, 7);
- ret = 7;
- }
- break;
-
- case PL2303_SETCONTROLREQUEST:
- case PL2303_BREAKREQUEST:
- {
- ret = 0;
- }
- break;
-
- default:
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDCLASSREQ), ctrl->type);
- break;
- }
- }
- }
- break;
-
- case PL2303_RWREQUEST_TYPE:
- {
- if ((ctrl->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE)
- {
- if (ctrl->req == PL2303_RWREQUEST)
- {
- if ((ctrl->type & USB_DIR_IN) != 0)
- {
- *(uint32_t*)ctrlreq->buf = 0xdeadbeef;
- ret = 4;
- }
- else
- {
- ret = 0;
- }
- }
- else
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDCLASSREQ), ctrl->type);
- }
- }
- }
- break;
-
- default:
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UNSUPPORTEDTYPE), ctrl->type);
- break;
- }
-
- /* Respond to the setup command if data was returned. On an error return
- * value (ret < 0), the USB driver will stall.
- */
-
- if (ret >= 0)
- {
- ctrlreq->len = min(len, ret);
- ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;
- ret = EP_SUBMIT(dev->ep0, ctrlreq);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EPRESPQ), (uint16_t)-ret);
- ctrlreq->result = OK;
- usbclass_ep0incomplete(dev->ep0, ctrlreq);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbclass_disconnect
- *
- * Description:
- * Invoked after all transfers have been stopped, when the host is
- * disconnected. This function is probably called from the context of an
- * interrupt handler.
- *
- ****************************************************************************/
-
-static void usbclass_disconnect(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct pl2303_dev_s *priv;
- irqstate_t flags;
-
- usbtrace(TRACE_CLASSDISCONNECT, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct pl2303_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_EP0NOTBOUND), 0);
- return;
- }
-#endif
-
- /* Inform the "upper half serial driver that we have lost the USB serial
- * connection.
- */
-
- flags = irqsave();
-#ifdef CONFIG_SERIAL_REMOVABLE
- uart_connected(&priv->serdev, false);
-#endif
-
- /* Reset the configuration */
-
- usbclass_resetconfig(priv);
-
- /* Clear out all outgoing data in the circular buffer */
-
- priv->serdev.xmit.head = 0;
- priv->serdev.xmit.tail = 0;
- irqrestore(flags);
-
- /* Perform the soft connect function so that we will we can be
- * re-enumerated.
- */
-
- DEV_CONNECT(dev);
-}
-
-/****************************************************************************
- * Name: usbclass_suspend
- *
- * Description:
- * Handle the USB suspend event.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_SERIAL_REMOVABLE
-static void usbclass_suspend(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct cdcacm_dev_s *priv;
-
- usbtrace(TRACE_CLASSSUSPEND, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
-
- /* And let the "upper half" driver now that we are suspended */
-
- uart_connected(&priv->serdev, false);
-}
-#endif
-
-/****************************************************************************
- * Name: usbclass_resume
- *
- * Description:
- * Handle the USB resume event.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_SERIAL_REMOVABLE
-static void usbclass_resume(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct cdcacm_dev_s *priv;
-
- usbtrace(TRACE_CLASSRESUME, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct cdcacm_driver_s*)driver)->dev;
-
- /* Are we still configured? */
-
- if (priv->config != PL2303_CONFIGIDNONE)
- {
- /* Yes.. let the "upper half" know that have resumed */
-
- uart_connected(&priv->serdev, true);
- }
-}
-#endif
-
-/****************************************************************************
- * Serial Device Methods
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbser_setup
- *
- * Description:
- * This method is called the first time that the serial port is opened.
- *
- ****************************************************************************/
-
-static int usbser_setup(FAR struct uart_dev_s *dev)
-{
- FAR struct pl2303_dev_s *priv;
-
- usbtrace(PL2303_CLASSAPI_SETUP, 0);
-
- /* Sanity check */
-
-#if CONFIG_DEBUG
- if (!dev || !dev->priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return -EIO;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = (FAR struct pl2303_dev_s*)dev->priv;
-
- /* Check if we have been configured */
-
- if (priv->config == PL2303_CONFIGIDNONE)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_SETUPNOTCONNECTED), 0);
- return -ENOTCONN;
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: usbser_shutdown
- *
- * Description:
- * This method is called when the serial port is closed. This operation
- * is very simple for the USB serial backend because the serial driver
- * has already assured that the TX data has full drained -- it calls
- * usbser_txempty() until that function returns true before calling this
- * function.
- *
- ****************************************************************************/
-
-static void usbser_shutdown(FAR struct uart_dev_s *dev)
-{
- usbtrace(PL2303_CLASSAPI_SHUTDOWN, 0);
-
- /* Sanity check */
-
-#if CONFIG_DEBUG
- if (!dev || !dev->priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- }
-#endif
-}
-
-/****************************************************************************
- * Name: usbser_attach
- *
- * Description:
- * Does not apply to the USB serial class device
- *
- ****************************************************************************/
-
-static int usbser_attach(FAR struct uart_dev_s *dev)
-{
- usbtrace(PL2303_CLASSAPI_ATTACH, 0);
- return OK;
-}
-
-/****************************************************************************
- * Name: usbser_detach
- *
- * Description:
-* Does not apply to the USB serial class device
- *
- ****************************************************************************/
-
-static void usbser_detach(FAR struct uart_dev_s *dev)
-{
- usbtrace(PL2303_CLASSAPI_DETACH, 0);
-}
-
-/****************************************************************************
- * Name: usbser_rxint
- *
- * Description:
- * Called by the serial driver to enable or disable RX interrupts. We, of
- * course, have no RX interrupts but must behave consistently. This method
- * is called under the conditions:
- *
- * 1. With enable==true when the port is opened (just after usbser_setup
- * and usbser_attach are called called)
- * 2. With enable==false while transferring data from the RX buffer
- * 2. With enable==true while waiting for more incoming data
- * 3. With enable==false when the port is closed (just before usbser_detach
- * and usbser_shutdown are called).
- *
- ****************************************************************************/
-
-static void usbser_rxint(FAR struct uart_dev_s *dev, bool enable)
-{
- FAR struct pl2303_dev_s *priv;
- FAR uart_dev_t *serdev;
- irqstate_t flags;
-
- usbtrace(PL2303_CLASSAPI_RXINT, (uint16_t)enable);
-
- /* Sanity check */
-
-#if CONFIG_DEBUG
- if (!dev || !dev->priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = (FAR struct pl2303_dev_s*)dev->priv;
- serdev = &priv->serdev;
-
- /* We need exclusive access to the RX buffer and private structure
- * in the following.
- */
-
- flags = irqsave();
- if (enable)
- {
- /* RX "interrupts" are enabled. Is this a transition from disabled
- * to enabled state?
- */
-
- if (!priv->rxenabled)
- {
- /* Yes. During the time that RX interrupts are disabled, the
- * the serial driver will be extracting data from the circular
- * buffer and modifying recv.tail. During this time, we
- * should avoid modifying recv.head; When interrupts are restored,
- * we can update the head pointer for all of the data that we
- * put into cicular buffer while "interrupts" were disabled.
- */
-
- if (priv->rxhead != serdev->recv.head)
- {
- serdev->recv.head = priv->rxhead;
-
- /* Yes... signal the availability of new data */
-
- uart_datareceived(serdev);
- }
-
- /* RX "interrupts are no longer disabled */
-
- priv->rxenabled = true;
- }
- }
-
- /* RX "interrupts" are disabled. Is this a transition from enabled
- * to disabled state?
- */
-
- else if (priv->rxenabled)
- {
- /* Yes. During the time that RX interrupts are disabled, the
- * the serial driver will be extracting data from the circular
- * buffer and modifying recv.tail. During this time, we
- * should avoid modifying recv.head; When interrupts are disabled,
- * we use a shadow index and continue adding data to the circular
- * buffer.
- */
-
- priv->rxhead = serdev->recv.head;
- priv->rxenabled = false;
- }
- irqrestore(flags);
-}
-
-/****************************************************************************
- * Name: usbser_txint
- *
- * Description:
- * Called by the serial driver to enable or disable TX interrupts. We, of
- * course, have no TX interrupts but must behave consistently. Initially,
- * TX interrupts are disabled. This method is called under the conditions:
- *
- * 1. With enable==false while transferring data into the TX buffer
- * 2. With enable==true when data may be taken from the buffer.
- * 3. With enable==false when the TX buffer is empty
- *
- ****************************************************************************/
-
-static void usbser_txint(FAR struct uart_dev_s *dev, bool enable)
-{
- FAR struct pl2303_dev_s *priv;
-
- usbtrace(PL2303_CLASSAPI_TXINT, (uint16_t)enable);
-
- /* Sanity checks */
-
-#if CONFIG_DEBUG
- if (!dev || !dev->priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return;
- }
-#endif
-
- /* Extract references to private data */
-
- priv = (FAR struct pl2303_dev_s*)dev->priv;
-
- /* If the new state is enabled and if there is data in the XMIT buffer,
- * send the next packet now.
- */
-
- uvdbg("enable=%d head=%d tail=%d\n",
- enable, priv->serdev.xmit.head, priv->serdev.xmit.tail);
-
- if (enable && priv->serdev.xmit.head != priv->serdev.xmit.tail)
- {
- usbclass_sndpacket(priv);
- }
-}
-
-/****************************************************************************
- * Name: usbser_txempty
- *
- * Description:
- * Return true when all data has been sent. This is called from the
- * serial driver when the driver is closed. It will call this API
- * periodically until it reports true. NOTE that the serial driver takes all
- * responsibility for flushing TX data through the hardware so we can be
- * a bit sloppy about that.
- *
- ****************************************************************************/
-
-static bool usbser_txempty(FAR struct uart_dev_s *dev)
-{
- FAR struct pl2303_dev_s *priv = (FAR struct pl2303_dev_s*)dev->priv;
-
- usbtrace(PL2303_CLASSAPI_TXEMPTY, 0);
-
-#if CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_INVALIDARG), 0);
- return true;
- }
-#endif
-
- /* When all of the allocated write requests have been returned to the
- * reqlist, then there is no longer any TX data in flight.
- */
-
- return priv->nwrq >= CONFIG_PL2303_NWRREQS;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbdev_serialinitialize
- *
- * Description:
- * Register USB serial port (and USB serial console if so configured).
- *
- ****************************************************************************/
-
-int usbdev_serialinitialize(int minor)
-{
- FAR struct pl2303_alloc_s *alloc;
- FAR struct pl2303_dev_s *priv;
- FAR struct pl2303_driver_s *drvr;
- char devname[16];
- int ret;
-
- /* Allocate the structures needed */
-
- alloc = (FAR struct pl2303_alloc_s*)kmalloc(sizeof(struct pl2303_alloc_s));
- if (!alloc)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_ALLOCDEVSTRUCT), 0);
- return -ENOMEM;
- }
-
- /* Convenience pointers into the allocated blob */
-
- priv = &alloc->dev;
- drvr = &alloc->drvr;
-
- /* Initialize the USB serial driver structure */
-
- memset(priv, 0, sizeof(struct pl2303_dev_s));
- sq_init(&priv->reqlist);
-
- /* Fake line status */
-
- priv->linest[0] = (115200) & 0xff; /* Baud=115200 */
- priv->linest[1] = (115200 >> 8) & 0xff;
- priv->linest[2] = (115200 >> 16) & 0xff;
- priv->linest[3] = (115200 >> 24) & 0xff;
- priv->linest[4] = 0; /* One stop bit */
- priv->linest[5] = 0; /* No parity */
- priv->linest[6] = 8; /*8 data bits */
-
- /* Initialize the serial driver sub-structure */
-
-#ifdef CONFIG_SERIAL_REMOVABLE
- priv->serdev.disconnected = true;
-#endif
- priv->serdev.recv.size = CONFIG_PL2303_RXBUFSIZE;
- priv->serdev.recv.buffer = priv->rxbuffer;
- priv->serdev.xmit.size = CONFIG_PL2303_TXBUFSIZE;
- priv->serdev.xmit.buffer = priv->txbuffer;
- priv->serdev.ops = &g_uartops;
- priv->serdev.priv = priv;
-
- /* Initialize the USB class driver structure */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- drvr->drvr.speed = USB_SPEED_HIGH;
-#else
- drvr->drvr.speed = USB_SPEED_FULL;
-#endif
- drvr->drvr.ops = &g_driverops;
- drvr->dev = priv;
-
- /* Register the USB serial class driver */
-
- ret = usbdev_register(&drvr->drvr);
- if (ret)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_DEVREGISTER), (uint16_t)-ret);
- goto errout_with_alloc;
- }
-
- /* Register the USB serial console */
-
-#ifdef CONFIG_PL2303_CONSOLE
- priv->serdev.isconsole = true;
- ret = uart_register("/dev/console", &priv->serdev);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_CONSOLEREGISTER), (uint16_t)-ret);
- goto errout_with_class;
- }
-#endif
-
- /* Register the single port supported by this implementation */
-
- sprintf(devname, "/dev/ttyUSB%d", minor);
- ret = uart_register(devname, &priv->serdev);
- if (ret)
- {
- usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_UARTREGISTER), (uint16_t)-ret);
- goto errout_with_class;
- }
- return OK;
-
-errout_with_class:
- usbdev_unregister(&drvr->drvr);
-errout_with_alloc:
- kfree(alloc);
- return ret;
-}
diff --git a/nuttx/drivers/usbdev/usbdev_trace.c b/nuttx/drivers/usbdev/usbdev_trace.c
deleted file mode 100644
index c332c1358..000000000
--- a/nuttx/drivers/usbdev/usbdev_trace.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/usbdev_trace.c
- *
- * Copyright (C) 2008-2010, 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <arch/irq.h>
-#include <nuttx/usb/usbdev_trace.h>
-#undef usbtrace
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-/* Configuration ************************************************************/
-
-#ifndef CONFIG_USBDEV_TRACE_NRECORDS
-# define CONFIG_USBDEV_TRACE_NRECORDS 128
-#endif
-
-#ifndef CONFIG_USBDEV_TRACE_INITIALIDSET
-# define CONFIG_USBDEV_TRACE_INITIALIDSET 0
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_TRACE
-static struct usbtrace_s g_trace[CONFIG_USBDEV_TRACE_NRECORDS];
-static uint16_t g_head = 0;
-static uint16_t g_tail = 0;
-#endif
-
-#if defined(CONFIG_USBDEV_TRACE) || (defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_USB))
-static usbtrace_idset_t g_maskedidset = CONFIG_USBDEV_TRACE_INITIALIDSET;
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/*******************************************************************************
- * Name: usbtrace_enable
- *
- * Description:
- * Enable/disable tracing per trace ID. The initial state is all IDs enabled.
- *
- * Input Parameters:
- * idset - The bitset of IDs to be masked. TRACE_ALLIDS enables all IDS; zero
- * masks all IDs.
- *
- * Returned Value:
- * The previous idset value.
- *
- * Assumptions:
- * - May be called from an interrupt handler
- *
- *******************************************************************************/
-
-#if defined(CONFIG_USBDEV_TRACE) || (defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_USB))
-usbtrace_idset_t usbtrace_enable(usbtrace_idset_t idset)
-{
- irqstate_t flags;
- usbtrace_idset_t ret;
-
- /* The following read and write must be atomic */
-
- flags = irqsave();
- ret = g_maskedidset;
- g_maskedidset = idset;
- irqrestore(flags);
- return ret;
-}
-#endif /* CONFIG_USBDEV_TRACE || CONFIG_DEBUG && CONFIG_DEBUG_USB */
-
-/*******************************************************************************
- * Name: usbtrace
- *
- * Description:
- * Record a USB event (tracing must be enabled)
- *
- * Assumptions:
- * May be called from an interrupt handler
- *
- *******************************************************************************/
-
-#if defined(CONFIG_USBDEV_TRACE) || (defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_USB))
-void usbtrace(uint16_t event, uint16_t value)
-{
- irqstate_t flags;
-
- /* Check if tracing is enabled for this ID */
-
- flags = irqsave();
- if ((g_maskedidset & TRACE_ID2BIT(event)) != 0)
- {
-#ifdef CONFIG_USBDEV_TRACE
- /* Yes... save the new trace data at the head */
-
- g_trace[g_head].event = event;
- g_trace[g_head].value = value;
-
- /* Increment the head and (probably) the tail index */
-
- if (++g_head >= CONFIG_USBDEV_TRACE_NRECORDS)
- {
- g_head = 0;
- }
-
- if (g_head == g_tail)
- {
- if (++g_tail >= CONFIG_USBDEV_TRACE_NRECORDS)
- {
- g_tail = 0;
- }
- }
-#else
- /* Just print the data using lowsyslog */
-
- usbtrace_trprintf((trprintf_t)lowsyslog, event, value);
-#endif
- }
- irqrestore(flags);
-}
-#endif /* CONFIG_USBDEV_TRACE || CONFIG_DEBUG && CONFIG_DEBUG_USB */
-
-/*******************************************************************************
- * Name: usbtrace_enumerate
- *
- * Description:
- * Enumerate all buffer trace data (will temporarily disable tracing)
- *
- * Assumptions:
- * NEVER called from an interrupt handler
- *
- *******************************************************************************/
-
-#ifdef CONFIG_USBDEV_TRACE
-int usbtrace_enumerate(trace_callback_t callback, void *arg)
-{
- uint16_t ndx;
- uint32_t idset;
- int ret = OK;
-
- /* Temporarily disable tracing */
-
- idset = usbtrace_enable(0);
-
- /* Visit every entry, starting with the tail */
-
- for (ndx = g_tail; ndx != g_head; )
- {
- /* Call the user provided callback */
-
- ret = callback(&g_trace[ndx], arg);
- if (ret != OK)
- {
- /* Abort the enumeration */
-
- break;
- }
-
- /* Increment the index */
-
- if (++ndx >= CONFIG_USBDEV_TRACE_NRECORDS)
- {
- ndx = 0;
- }
- }
-
- /* Discard the trace data after it has been reported */
-
- g_tail = g_head;
-
- /* Restore tracing state */
-
- (void)usbtrace_enable(idset);
- return ret;
-}
-#endif /* CONFIG_USBDEV_TRACE */
diff --git a/nuttx/drivers/usbdev/usbdev_trprintf.c b/nuttx/drivers/usbdev/usbdev_trprintf.c
deleted file mode 100644
index 2a9921f98..000000000
--- a/nuttx/drivers/usbdev/usbdev_trprintf.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/usbdev_trprintf.c
- *
- * Copyright (C) 2008-2010, 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <debug.h>
-
-#include <nuttx/usb/usbdev_trace.h>
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/*******************************************************************************
- * Name: usbtrace_trprintf
- *
- * Description:
- * Print the trace record using the supplied printing function
- *
- *******************************************************************************/
-
-void usbtrace_trprintf(trprintf_t trprintf, uint16_t event, uint16_t value)
-{
- switch (event)
- {
- case TRACE_DEVINIT:
- trprintf("USB controller initialization: %04x\n", value);
- break;
-
- case TRACE_DEVUNINIT:
- trprintf("USB controller un-initialization: %04x\n", value);
- break;
-
- case TRACE_DEVREGISTER:
- trprintf("usbdev_register(): %04x\n", value);
- break;
-
- case TRACE_DEVUNREGISTER:
- trprintf("usbdev_unregister(): %04x\n", value);
- break;
-
- case TRACE_EPCONFIGURE:
- trprintf("Endpoint configure(): %04x\n", value);
- break;
-
- case TRACE_EPDISABLE:
- trprintf("Endpoint disable(): %04x\n", value);
- break;
-
- case TRACE_EPALLOCREQ:
- trprintf("Endpoint allocreq(): %04x\n", value);
- break;
-
- case TRACE_EPFREEREQ:
- trprintf("Endpoint freereq(): %04x\n", value);
- break;
-
- case TRACE_EPALLOCBUFFER:
- trprintf("Endpoint allocbuffer(): %04x\n", value);
- break;
-
- case TRACE_EPFREEBUFFER:
- trprintf("Endpoint freebuffer(): %04x\n", value);
- break;
-
- case TRACE_EPSUBMIT:
- trprintf("Endpoint submit(): %04x\n", value);
- break;
-
- case TRACE_EPCANCEL:
- trprintf("Endpoint cancel(): %04x\n", value);
- break;
-
- case TRACE_EPSTALL:
- trprintf("Endpoint stall(true): %04x\n", value);
- break;
-
- case TRACE_EPRESUME:
- trprintf("Endpoint stall(false): %04x\n", value);
- break;
-
- case TRACE_DEVALLOCEP:
- trprintf("Device allocep(): %04x\n", value);
- break;
-
- case TRACE_DEVFREEEP:
- trprintf("Device freeep(): %04x\n", value);
- break;
-
- case TRACE_DEVGETFRAME:
- trprintf("Device getframe(): %04x\n", value);
- break;
-
- case TRACE_DEVWAKEUP:
- trprintf("Device wakeup(): %04x\n", value);
- break;
-
- case TRACE_DEVSELFPOWERED:
- trprintf("Device selfpowered(): %04x\n", value);
- break;
-
- case TRACE_DEVPULLUP:
- trprintf("Device pullup(): %04x\n", value);
- break;
-
- case TRACE_CLASSBIND:
- trprintf("Class bind(): %04x\n", value);
- break;
-
- case TRACE_CLASSUNBIND:
- trprintf("Class unbind(): %04x\n", value);
- break;
-
- case TRACE_CLASSDISCONNECT:
- trprintf("Class disconnect(): %04x\n", value);
- break;
-
- case TRACE_CLASSSETUP:
- trprintf("Class setup(): %04x\n", value);
- break;
-
- case TRACE_CLASSSUSPEND:
- trprintf("Class suspend(): %04x\n", value);
- break;
-
- case TRACE_CLASSRESUME:
- trprintf("Class resume(): %04x\n", value);
- break;
-
- case TRACE_CLASSRDCOMPLETE:
- trprintf("Class RD request complete: %04x\n", value);
- break;
-
- case TRACE_CLASSWRCOMPLETE:
- trprintf("Class WR request complete: %04x\n", value);
- break;
-
- default:
- switch (TRACE_ID(event))
- {
- case TRACE_CLASSAPI_ID: /* Other class driver system API calls */
- trprintf("Class API call %d: %04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_CLASSSTATE_ID: /* Track class driver state changes */
- trprintf("Class state %d: %04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_INTENTRY_ID: /* Interrupt handler entry */
- trprintf("Interrupt %d entry: %04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_INTDECODE_ID: /* Decoded interrupt event */
- trprintf("Interrupt decode %d: %04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_INTEXIT_ID: /* Interrupt handler exit */
- trprintf("Interrupt %d exit: %04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_OUTREQQUEUED_ID: /* Request queued for OUT endpoint */
- trprintf("EP%d OUT request queued: %04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_INREQQUEUED_ID: /* Request queued for IN endpoint */
- trprintf("EP%d IN request queued: %04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_READ_ID: /* Read (OUT) action */
- trprintf("EP%d OUT read: %04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_WRITE_ID: /* Write (IN) action */
- trprintf("EP%d IN write: %04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_COMPLETE_ID: /* Request completed */
- trprintf("EP%d request complete: %04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_DEVERROR_ID: /* USB controller driver error event */
- trprintf("Controller error: %02x:%04x\n", TRACE_DATA(event), value);
- break;
-
- case TRACE_CLSERROR_ID: /* USB class driver error event */
- trprintf("Class error: %02x:%04x\n", TRACE_DATA(event), value);
- break;
-
- default:
- trprintf("Unrecognized event: %02x:%02x:%04x\n",
- TRACE_ID(event) >> 8, TRACE_DATA(event), value);
- break;
- }
- }
-}
diff --git a/nuttx/drivers/usbdev/usbmsc.c b/nuttx/drivers/usbdev/usbmsc.c
deleted file mode 100644
index 68b61814a..000000000
--- a/nuttx/drivers/usbdev/usbmsc.c
+++ /dev/null
@@ -1,1778 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/usbmsc.c
- *
- * Copyright (C) 2008-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Mass storage class device. Bulk-only with SCSI subclass.
- *
- * References:
- * "Universal Serial Bus Mass Storage Class, Specification Overview,"
- * Revision 1.2, USB Implementer's Forum, June 23, 2003.
- *
- * "Universal Serial Bus Mass Storage Class, Bulk-Only Transport,"
- * Revision 1.0, USB Implementer's Forum, September 31, 1999.
- *
- * "SCSI Primary Commands - 3 (SPC-3)," American National Standard
- * for Information Technology, May 4, 2005
- *
- * "SCSI Primary Commands - 4 (SPC-4)," American National Standard
- * for Information Technology, July 19, 2008
- *
- * "SCSI Block Commands -2 (SBC-2)," American National Standard
- * for Information Technology, November 13, 2004
- *
- * "SCSI Multimedia Commands - 3 (MMC-3)," American National Standard
- * for Information Technology, November 12, 2001
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <string.h>
-#include <errno.h>
-#include <queue.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/arch.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/storage.h>
-#include <nuttx/usb/usbdev.h>
-#include <nuttx/usb/usbdev_trace.h>
-
-#include "usbmsc.h"
-
-#ifdef CONFIG_USBMSC_COMPOSITE
-# include <nuttx/usb/composite.h>
-# include "composite.h"
-#endif
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* The internal version of the class driver */
-
-struct usbmsc_driver_s
-{
- struct usbdevclass_driver_s drvr;
- FAR struct usbmsc_dev_s *dev;
-};
-
-/* This is what is allocated */
-
-struct usbmsc_alloc_s
-{
- struct usbmsc_dev_s dev;
- struct usbmsc_driver_s drvr;
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Class Driver Support *****************************************************/
-
-static void usbmsc_ep0incomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-static struct usbdev_req_s *usbmsc_allocreq(FAR struct usbdev_ep_s *ep,
- uint16_t len);
-static void usbmsc_freereq(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-
-/* Class Driver Operations (most at interrupt level) ************************/
-
-static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl, FAR uint8_t *dataout,
- size_t outlen);
-static void usbmsc_disconnect(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev);
-
-/* Initialization/Uninitialization ******************************************/
-
-static void usbmsc_lununinitialize(struct usbmsc_lun_s *lun);
-#ifdef CONFIG_USBMSC_COMPOSITE
-static int usbmsc_exportluns(FAR void *handle);
-#endif
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* Driver operations ********************************************************/
-
-static struct usbdevclass_driverops_s g_driverops =
-{
- usbmsc_bind, /* bind */
- usbmsc_unbind, /* unbind */
- usbmsc_setup, /* setup */
- usbmsc_disconnect, /* disconnect */
- NULL, /* suspend */
- NULL /* resume */
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Class Driver Support
- ****************************************************************************/
-/****************************************************************************
- * Name: usbmsc_ep0incomplete
- *
- * Description:
- * Handle completion of EP0 control operations
- *
- ****************************************************************************/
-
-static void usbmsc_ep0incomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req)
-{
- if (req->result || req->xfrd != req->len)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_REQRESULT),
- (uint16_t)-req->result);
- }
-}
-
-/****************************************************************************
- * Name: usbmsc_allocreq
- *
- * Description:
- * Allocate a request instance along with its buffer
- *
- ****************************************************************************/
-
-static struct usbdev_req_s *usbmsc_allocreq(FAR struct usbdev_ep_s *ep,
- uint16_t len)
-{
- FAR struct usbdev_req_s *req;
-
- req = EP_ALLOCREQ(ep);
- if (req != NULL)
- {
- req->len = len;
- req->buf = EP_ALLOCBUFFER(ep, len);
- if (!req->buf)
- {
- EP_FREEREQ(ep, req);
- req = NULL;
- }
- }
- return req;
-}
-
-/****************************************************************************
- * Name: usbmsc_freereq
- *
- * Description:
- * Free a request instance along with its buffer
- *
- ****************************************************************************/
-
-static void usbmsc_freereq(FAR struct usbdev_ep_s *ep, struct usbdev_req_s *req)
-{
- if (ep != NULL && req != NULL)
- {
- if (req->buf != NULL)
- {
- EP_FREEBUFFER(ep, req->buf);
- }
- EP_FREEREQ(ep, req);
- }
-}
-
-/****************************************************************************
- * Class Driver Interfaces
- ****************************************************************************/
-/****************************************************************************
- * Name: usbmsc_bind
- *
- * Description:
- * Invoked when the driver is bound to a USB device driver
- *
- ****************************************************************************/
-
-static int usbmsc_bind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct usbmsc_dev_s *priv = ((FAR struct usbmsc_driver_s*)driver)->dev;
- FAR struct usbmsc_req_s *reqcontainer;
- irqstate_t flags;
- int ret = OK;
- int i;
-
- usbtrace(TRACE_CLASSBIND, 0);
-
- /* Bind the structures */
-
- priv->usbdev = dev;
-
- /* Save the reference to our private data structure in EP0 so that it
- * can be recovered in ep0 completion events (Unless we are part of
- * a composite device and, in that case, the composite device owns
- * EP0).
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- dev->ep0->priv = priv;
-#endif
-
- /* The configured EP0 size should match the reported EP0 size. We could
- * easily adapt to the reported EP0 size, but then we could not use the
- * const, canned descriptors.
- */
-
- DEBUGASSERT(CONFIG_USBMSC_EP0MAXPACKET == dev->ep0->maxpacket);
-
- /* Preallocate control request */
-
- priv->ctrlreq = usbmsc_allocreq(dev->ep0, USBMSC_MXDESCLEN);
- if (priv->ctrlreq == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCCTRLREQ), 0);
- ret = -ENOMEM;
- goto errout;
- }
- priv->ctrlreq->callback = usbmsc_ep0incomplete;
-
- /* Pre-allocate all endpoints... the endpoints will not be functional
- * until the SET CONFIGURATION request is processed in usbmsc_setconfig.
- * This is done here because there may be calls to kmalloc and the SET
- * CONFIGURATION processing probably occurrs within interrupt handling
- * logic where kmalloc calls will fail.
- */
-
- /* Pre-allocate the IN bulk endpoint */
-
- priv->epbulkin = DEV_ALLOCEP(dev, USBMSC_EPINBULK_ADDR, true, USB_EP_ATTR_XFER_BULK);
- if (!priv->epbulkin)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKINALLOCFAIL), 0);
- ret = -ENODEV;
- goto errout;
- }
- priv->epbulkin->priv = priv;
-
- /* Pre-allocate the OUT bulk endpoint */
-
- priv->epbulkout = DEV_ALLOCEP(dev, USBMSC_EPOUTBULK_ADDR, false, USB_EP_ATTR_XFER_BULK);
- if (!priv->epbulkout)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKOUTALLOCFAIL), 0);
- ret = -ENODEV;
- goto errout;
- }
- priv->epbulkout->priv = priv;
-
- /* Pre-allocate read requests */
-
- for (i = 0; i < CONFIG_USBMSC_NRDREQS; i++)
- {
- reqcontainer = &priv->rdreqs[i];
- reqcontainer->req = usbmsc_allocreq(priv->epbulkout, CONFIG_USBMSC_BULKOUTREQLEN);
- if (reqcontainer->req == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDALLOCREQ),
- (uint16_t)-ret);
- ret = -ENOMEM;
- goto errout;
- }
- reqcontainer->req->priv = reqcontainer;
- reqcontainer->req->callback = usbmsc_rdcomplete;
- }
-
- /* Pre-allocate write request containers and put in a free list */
-
- for (i = 0; i < CONFIG_USBMSC_NWRREQS; i++)
- {
- reqcontainer = &priv->wrreqs[i];
- reqcontainer->req = usbmsc_allocreq(priv->epbulkin, CONFIG_USBMSC_BULKINREQLEN);
- if (reqcontainer->req == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRALLOCREQ),
- (uint16_t)-ret);
- ret = -ENOMEM;
- goto errout;
- }
- reqcontainer->req->priv = reqcontainer;
- reqcontainer->req->callback = usbmsc_wrcomplete;
-
- flags = irqsave();
- sq_addlast((sq_entry_t*)reqcontainer, &priv->wrreqlist);
- irqrestore(flags);
- }
-
- /* Report if we are selfpowered (unless we are part of a composite device) */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-#ifdef CONFIG_USBDEV_SELFPOWERED
- DEV_SETSELFPOWERED(dev);
-#endif
-
- /* And pull-up the data line for the soft connect function (unless we are
- * part of a composite device)
- */
-
- DEV_CONNECT(dev);
-#endif
- return OK;
-
-errout:
- usbmsc_unbind(driver, dev);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_unbind
- *
- * Description:
- * Invoked when the driver is unbound from a USB device driver
- *
- ****************************************************************************/
-
-static void usbmsc_unbind(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- FAR struct usbmsc_dev_s *priv;
- FAR struct usbmsc_req_s *reqcontainer;
- irqstate_t flags;
- int i;
-
- usbtrace(TRACE_CLASSUNBIND, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNBINDINVALIDARGS), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct usbmsc_driver_s*)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EP0NOTBOUND1), 0);
- return;
- }
-#endif
-
- /* The worker thread should have already been stopped by the
- * driver un-initialize logic.
- */
-
- DEBUGASSERT(priv->thstate == USBMSC_STATE_TERMINATED);
-
- /* Make sure that we are not already unbound */
-
- if (priv != NULL)
- {
- /* Make sure that the endpoints have been unconfigured. If
- * we were terminated gracefully, then the configuration should
- * already have been reset. If not, then calling usbmsc_resetconfig
- * should cause the endpoints to immediately terminate all
- * transfers and return the requests to us (with result == -ESHUTDOWN)
- */
-
- usbmsc_resetconfig(priv);
- up_mdelay(50);
-
- /* Free the pre-allocated control request */
-
- if (priv->ctrlreq != NULL)
- {
- usbmsc_freereq(dev->ep0, priv->ctrlreq);
- priv->ctrlreq = NULL;
- }
-
- /* Free pre-allocated read requests (which should all have
- * been returned to the free list at this time -- we don't check)
- */
-
- for (i = 0; i < CONFIG_USBMSC_NRDREQS; i++)
- {
- reqcontainer = &priv->rdreqs[i];
- if (reqcontainer->req)
- {
- usbmsc_freereq(priv->epbulkout, reqcontainer->req);
- reqcontainer->req = NULL;
- }
- }
-
- /* Free the bulk OUT endpoint */
-
- if (priv->epbulkout)
- {
- DEV_FREEEP(dev, priv->epbulkout);
- priv->epbulkout = NULL;
- }
-
- /* Free write requests that are not in use (which should be all
- * of them
- */
-
- flags = irqsave();
- while (!sq_empty(&priv->wrreqlist))
- {
- reqcontainer = (struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist);
- if (reqcontainer->req != NULL)
- {
- usbmsc_freereq(priv->epbulkin, reqcontainer->req);
- }
- }
-
- /* Free the bulk IN endpoint */
-
- if (priv->epbulkin)
- {
- DEV_FREEEP(dev, priv->epbulkin);
- priv->epbulkin = NULL;
- }
-
- irqrestore(flags);
- }
-}
-
-/****************************************************************************
- * Name: usbmsc_setup
- *
- * Description:
- * Invoked for ep0 control requests. This function probably executes
- * in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-static int usbmsc_setup(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev,
- FAR const struct usb_ctrlreq_s *ctrl,
- FAR uint8_t *dataout, size_t outlen)
-{
- FAR struct usbmsc_dev_s *priv;
- FAR struct usbdev_req_s *ctrlreq;
- uint16_t value;
- uint16_t index;
- uint16_t len;
- int ret = -EOPNOTSUPP;
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0 || !ctrl)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SETUPINVALIDARGS), 0);
- return -EIO;
- }
-#endif
-
- /* Extract reference to private data */
-
- usbtrace(TRACE_CLASSSETUP, ctrl->req);
- priv = ((FAR struct usbmsc_driver_s *)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv || !priv->ctrlreq)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EP0NOTBOUND2), 0);
- return -ENODEV;
- }
-#endif
- ctrlreq = priv->ctrlreq;
-
- /* Extract the little-endian 16-bit values to host order */
-
- value = GETUINT16(ctrl->value);
- index = GETUINT16(ctrl->index);
- len = GETUINT16(ctrl->len);
-
- uvdbg("type=%02x req=%02x value=%04x index=%04x len=%04x\n",
- ctrl->type, ctrl->req, value, index, len);
-
- if ((ctrl->type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
- {
- /**********************************************************************
- * Standard Requests
- **********************************************************************/
-
- switch (ctrl->req)
- {
- case USB_REQ_GETDESCRIPTOR:
- {
- /* The value field specifies the descriptor type in the MS byte and the
- * descriptor index in the LS byte (order is little endian)
- */
-
- switch (ctrl->value[1])
- {
- /* If the mass storage device is used in as part of a composite
- * device, then the device descriptor is is provided by logic
- * in the composite device implementation.
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- case USB_DESC_TYPE_DEVICE:
- {
- ret = USB_SIZEOF_DEVDESC;
- memcpy(ctrlreq->buf, usbmsc_getdevdesc(), ret);
- }
- break;
-#endif
-
- /* If the mass storage device is used in as part of a composite device,
- * then the device qualifier descriptor is provided by logic in the
- * composite device implementation.
- */
-
-#if !defined(CONFIG_USBMSC_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
- case USB_DESC_TYPE_DEVICEQUALIFIER:
- {
- ret = USB_SIZEOF_QUALDESC;
- memcpy(ctrlreq->buf, usbmsc_getqualdesc(), ret);
- }
- break;
-
- case USB_DESC_TYPE_OTHERSPEEDCONFIG:
-#endif
-
- /* If the mass storage device is used in as part of a composite device,
- * then the configuration descriptor is provided by logic in the
- * composite device implementation.
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- case USB_DESC_TYPE_CONFIG:
- {
-#ifdef CONFIG_USBDEV_DUALSPEED
- ret = usbmsc_mkcfgdesc(ctrlreq->buf, dev->speed, ctrl->value[1]);
-#else
- ret = usbmsc_mkcfgdesc(ctrlreq->buf);
-#endif
- }
- break;
-#endif
-
- /* If the mass storage device is used in as part of a composite device,
- * then the language string descriptor is provided by logic in the
- * composite device implementation.
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- case USB_DESC_TYPE_STRING:
- {
- /* index == language code. */
-
- ret = usbmsc_mkstrdesc(ctrl->value[0], (struct usb_strdesc_s *)ctrlreq->buf);
- }
- break;
-#endif
-
- default:
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETUNKNOWNDESC), value);
- }
- break;
- }
- }
- break;
-
- case USB_REQ_SETCONFIGURATION:
- {
- if (ctrl->type == 0)
- {
- /* Signal the worker thread to instantiate the new configuration */
-
- priv->theventset |= USBMSC_EVENT_CFGCHANGE;
- priv->thvalue = value;
- pthread_cond_signal(&priv->cond);
-
- /* Return here... the response will be provided later by the
- * worker thread.
- */
-
- return OK;
- }
- }
- break;
-
- /* If the mass storage device is used in as part of a composite device,
- * then the overall composite class configuration is managed by logic
- * in the composite device implementation.
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- case USB_REQ_GETCONFIGURATION:
- {
- if (ctrl->type == USB_DIR_IN)
- {
- ctrlreq->buf[0] = priv->config;
- ret = 1;
- }
- }
- break;
-#endif
-
- case USB_REQ_SETINTERFACE:
- {
- if (ctrl->type == USB_REQ_RECIPIENT_INTERFACE)
- {
- if (priv->config == USBMSC_CONFIGID &&
- index == USBMSC_INTERFACEID &&
- value == USBMSC_ALTINTERFACEID)
- {
- /* Signal to instantiate the interface change */
-
- priv->theventset |= USBMSC_EVENT_IFCHANGE;
- pthread_cond_signal(&priv->cond);
-
- /* Return here... the response will be provided later by the
- * worker thread.
- */
-
- return OK;
- }
- }
- }
- break;
-
- case USB_REQ_GETINTERFACE:
- {
- if (ctrl->type == (USB_DIR_IN|USB_REQ_RECIPIENT_INTERFACE) &&
- priv->config == USBMSC_CONFIGIDNONE)
- {
- if (index != USBMSC_INTERFACEID)
- {
- ret = -EDOM;
- }
- else
- {
- ctrlreq->buf[0] = USBMSC_ALTINTERFACEID;
- ret = 1;
- }
- }
- }
- break;
-
- default:
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNSUPPORTEDSTDREQ), ctrl->req);
- break;
- }
- }
- else if ((ctrl->type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_CLASS)
- {
- /**********************************************************************
- * Bulk-Only Mass Storage Class Requests
- **********************************************************************/
-
- /* Verify that we are configured */
-
- if (!priv->config)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_NOTCONFIGURED), 0);
- return ret;
- }
-
- switch (ctrl->req)
- {
- case USBMSC_REQ_MSRESET: /* Reset mass storage device and interface */
- {
- if (ctrl->type == USBMSC_TYPE_SETUPOUT && value == 0 && len == 0)
- {
- /* Only one interface is supported */
-
- if (index != USBMSC_INTERFACEID)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_MSRESETNDX), index);
- ret = -EDOM;
- }
- else
- {
- /* Signal to stop the current operation and reinitialize state */
-
- priv->theventset |= USBMSC_EVENT_RESET;
- pthread_cond_signal(&priv->cond);
-
- /* Return here... the response will be provided later by the
- * worker thread.
- */
-
- return OK;
- }
- }
- }
- break;
-
- case USBMSC_REQ_GETMAXLUN: /* Return number LUNs supported */
- {
- if (ctrl->type == USBMSC_TYPE_SETUPIN && value == 0 && len == 1)
- {
- /* Only one interface is supported */
-
- if (index != USBMSC_INTERFACEID)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_GETMAXLUNNDX), index);
- ret = -EDOM;
- }
- else
- {
- ctrlreq->buf[0] = priv->nluns - 1;
- ret = 1;
- }
- }
- }
- break;
-
- default:
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BADREQUEST), ctrl->req);
- break;
- }
- }
- else
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNSUPPORTEDTYPE), ctrl->type);
- }
-
- /* Respond to the setup command if data was returned. On an error return
- * value (ret < 0), the USB driver will stall EP0.
- */
-
- if (ret >= 0)
- {
- /* Configure the response */
-
- ctrlreq->len = MIN(len, ret);
- ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;
-
- /* Send the response -- either directly to the USB controller or
- * indirectly in the case where this class is a member of a composite
- * device.
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- ret = EP_SUBMIT(dev->ep0, ctrlreq);
-#else
- ret = composite_ep0submit(driver, dev, ctrlreq);
-#endif
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPRESPQ), (uint16_t)-ret);
-#if 0 /* Not necessary */
- ctrlreq->result = OK;
- usbmsc_ep0incomplete(dev->ep0, ctrlreq);
-#endif
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_disconnect
- *
- * Description:
- * Invoked after all transfers have been stopped, when the host is
- * disconnected. This function is probably called from the context of an
- * interrupt handler.
- *
- ****************************************************************************/
-
-static void usbmsc_disconnect(FAR struct usbdevclass_driver_s *driver,
- FAR struct usbdev_s *dev)
-{
- struct usbmsc_dev_s *priv;
- irqstate_t flags;
-
- usbtrace(TRACE_CLASSDISCONNECT, 0);
-
-#ifdef CONFIG_DEBUG
- if (!driver || !dev || !dev->ep0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_DISCONNECTINVALIDARGS), 0);
- return;
- }
-#endif
-
- /* Extract reference to private data */
-
- priv = ((FAR struct usbmsc_driver_s *)driver)->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EP0NOTBOUND3), 0);
- return;
- }
-#endif
-
- /* Reset the configuration */
-
- flags = irqsave();
- usbmsc_resetconfig(priv);
-
- /* Signal the worker thread */
-
- priv->theventset |= USBMSC_EVENT_DISCONNECT;
- pthread_cond_signal(&priv->cond);
- irqrestore(flags);
-
- /* Perform the soft connect function so that we will we can be
- * re-enumerated (unless we are part of a composite device)
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- DEV_CONNECT(dev);
-#endif
-}
-
-/****************************************************************************
- * Initialization/Un-Initialization
- ****************************************************************************/
-/****************************************************************************
- * Name: usbmsc_lununinitialize
- ****************************************************************************/
-
-static void usbmsc_lununinitialize(struct usbmsc_lun_s *lun)
-{
- /* Has a block driver has been bound to the LUN? */
-
- if (lun->inode)
- {
- /* Close the block driver */
-
- (void)close_blockdriver(lun->inode);
- }
-
- memset(lun, 0, sizeof(struct usbmsc_lun_s *));
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-/****************************************************************************
- * Internal Interfaces
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbmsc_setconfig
- *
- * Description:
- * Set the device configuration by allocating and configuring endpoints and
- * by allocating and queuing read and write requests.
- *
- ****************************************************************************/
-
-int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config)
-{
- FAR struct usbmsc_req_s *privreq;
- FAR struct usbdev_req_s *req;
-#ifdef CONFIG_USBDEV_DUALSPEED
- FAR const struct usb_epdesc_s *epdesc;
- bool hispeed = (priv->usbdev->speed == USB_SPEED_HIGH);
- uint16_t bulkmxpacket;
-#endif
- int i;
- int ret = 0;
-
-#if CONFIG_DEBUG
- if (priv == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SETCONFIGINVALIDARGS), 0);
- return -EIO;
- }
-#endif
-
- if (config == priv->config)
- {
- /* Already configured -- Do nothing */
-
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALREADYCONFIGURED), 0);
- return OK;
- }
-
- /* Discard the previous configuration data */
-
- usbmsc_resetconfig(priv);
-
- /* Was this a request to simply discard the current configuration? */
-
- if (config == USBMSC_CONFIGIDNONE)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CONFIGNONE), 0);
- return OK;
- }
-
- /* We only accept one configuration */
-
- if (config != USBMSC_CONFIGID)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CONFIGIDBAD), 0);
- return -EINVAL;
- }
-
- /* Configure the IN bulk endpoint */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- bulkmxpacket = USBMSC_BULKMAXPACKET(hispeed);
- epdesc = USBMSC_EPBULKINDESC(hispeed);
- ret = EP_CONFIGURE(priv->epbulkin, epdesc, false);
-#else
- ret = EP_CONFIGURE(priv->epbulkin,
- usbmsc_getepdesc(USBMSC_EPFSBULKIN), false);
-#endif
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKINCONFIGFAIL), 0);
- goto errout;
- }
-
- priv->epbulkin->priv = priv;
-
- /* Configure the OUT bulk endpoint */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- epdesc = USBMSC_EPBULKOUTDESC(hispeed);
- ret = EP_CONFIGURE(priv->epbulkout, epdesc, true);
-#else
- ret = EP_CONFIGURE(priv->epbulkout,
- usbmsc_getepdesc(USBMSC_EPFSBULKOUT), true);
-#endif
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EPBULKOUTCONFIGFAIL), 0);
- goto errout;
- }
-
- priv->epbulkout->priv = priv;
-
- /* Queue read requests in the bulk OUT endpoint */
-
- for (i = 0; i < CONFIG_USBMSC_NRDREQS; i++)
- {
- privreq = &priv->rdreqs[i];
- req = privreq->req;
- req->len = CONFIG_USBMSC_BULKOUTREQLEN;
- req->priv = privreq;
- req->callback = usbmsc_rdcomplete;
- ret = EP_SUBMIT(priv->epbulkout, req);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDSUBMIT), (uint16_t)-ret);
- goto errout;
- }
- }
-
- priv->config = config;
- return OK;
-
-errout:
- usbmsc_resetconfig(priv);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_resetconfig
- *
- * Description:
- * Mark the device as not configured and disable all endpoints.
- *
- ****************************************************************************/
-
-void usbmsc_resetconfig(FAR struct usbmsc_dev_s *priv)
-{
- /* Are we configured? */
-
- if (priv->config != USBMSC_CONFIGIDNONE)
- {
- /* Yes.. but not anymore */
-
- priv->config = USBMSC_CONFIGIDNONE;
-
- /* Disable endpoints. This should force completion of all pending
- * transfers.
- */
-
- EP_DISABLE(priv->epbulkin);
- EP_DISABLE(priv->epbulkout);
- }
-}
-
-/****************************************************************************
- * Name: usbmsc_wrcomplete
- *
- * Description:
- * Handle completion of write request. This function probably executes
- * in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-void usbmsc_wrcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req)
-{
- FAR struct usbmsc_dev_s *priv;
- FAR struct usbmsc_req_s *privreq;
- irqstate_t flags;
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (!ep || !ep->priv || !req || !req->priv)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRCOMPLETEINVALIDARGS), 0);
- return;
- }
-#endif
-
- /* Extract references to private data */
-
- priv = (FAR struct usbmsc_dev_s*)ep->priv;
- privreq = (FAR struct usbmsc_req_s *)req->priv;
-
- /* Return the write request to the free list */
-
- flags = irqsave();
- sq_addlast((sq_entry_t*)privreq, &priv->wrreqlist);
- irqrestore(flags);
-
- /* Process the received data unless this is some unusual condition */
-
- switch (req->result)
- {
- case OK: /* Normal completion */
- usbtrace(TRACE_CLASSWRCOMPLETE, req->xfrd);
- break;
-
- case -ESHUTDOWN: /* Disconnection */
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRSHUTDOWN), 0);
- break;
-
- default: /* Some other error occurred */
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRUNEXPECTED),
- (uint16_t)-req->result);
- break;
- };
-
- /* Inform the worker thread that a write request has been returned */
-
- priv->theventset |= USBMSC_EVENT_WRCOMPLETE;
- pthread_cond_signal(&priv->cond);
-}
-
-/****************************************************************************
- * Name: usbmsc_rdcomplete
- *
- * Description:
- * Handle completion of read request on the bulk OUT endpoint. This
- * is handled like the receipt of serial data on the "UART"
- *
- ****************************************************************************/
-
-void usbmsc_rdcomplete(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req)
-{
- FAR struct usbmsc_dev_s *priv;
- FAR struct usbmsc_req_s *privreq;
- irqstate_t flags;
- int ret;
-
- /* Sanity check */
-
-#ifdef CONFIG_DEBUG
- if (!ep || !ep->priv || !req || !req->priv)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDCOMPLETEINVALIDARGS), 0);
- return;
- }
-#endif
-
- /* Extract references to private data */
-
- priv = (FAR struct usbmsc_dev_s*)ep->priv;
- privreq = (FAR struct usbmsc_req_s *)req->priv;
-
- /* Process the received data unless this is some unusual condition */
-
- switch (req->result)
- {
- case 0: /* Normal completion */
- {
- usbtrace(TRACE_CLASSRDCOMPLETE, req->xfrd);
-
- /* Add the filled read request from the rdreqlist */
-
- flags = irqsave();
- sq_addlast((sq_entry_t*)privreq, &priv->rdreqlist);
- irqrestore(flags);
-
- /* Signal the worker thread that there is received data to be processed */
-
- priv->theventset |= USBMSC_EVENT_RDCOMPLETE;
- pthread_cond_signal(&priv->cond);
- }
- break;
-
- case -ESHUTDOWN: /* Disconnection */
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDSHUTDOWN), 0);
-
- /* Drop the read request... it will be cleaned up later */
- }
- break;
-
- default: /* Some other error occurred */
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDUNEXPECTED),
- (uint16_t)-req->result);
-
- /* Return the read request to the bulk out endpoint for re-filling */
-
- req = privreq->req;
- req->priv = privreq;
- req->callback = usbmsc_rdcomplete;
-
- ret = EP_SUBMIT(priv->epbulkout, req);
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_RDCOMPLETERDSUBMIT),
- (uint16_t)-ret);
- }
- }
- break;
- }
-}
-
-/****************************************************************************
- * Name: usbmsc_deferredresponse
- *
- * Description:
- * Some EP0 setup request cannot be responded to immediately becuase they
- * require some asynchronous action from the SCSI worker thread. This
- * function is provided for the SCSI thread to make that deferred response.
- * The specific requests that require this deferred response are:
- *
- * 1. USB_REQ_SETCONFIGURATION,
- * 2. USB_REQ_SETINTERFACE, or
- * 3. USBMSC_REQ_MSRESET
- *
- * In all cases, the success reponse is a zero-length packet; the failure
- * response is an EP0 stall.
- *
- * Input parameters:
- * priv - Private state structure for this USB storage instance
- * stall - true is the action failed and a stall is required
- *
- ****************************************************************************/
-
-void usbmsc_deferredresponse(FAR struct usbmsc_dev_s *priv, bool failed)
-{
- FAR struct usbdev_s *dev;
- FAR struct usbdev_req_s *ctrlreq;
- int ret;
-
-#ifdef CONFIG_DEBUG
- if (!priv || !priv->usbdev || !priv->ctrlreq)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_DEFERREDRESPINVALIDARGS), 0);
- return;
- }
-#endif
-
- dev = priv->usbdev;
- ctrlreq = priv->ctrlreq;
-
- /* If no error occurs, respond to the deferred setup command with a null
- * packet.
- */
-
- if (!failed)
- {
- ctrlreq->len = 0;
- ctrlreq->flags = USBDEV_REQFLAGS_NULLPKT;
- ret = EP_SUBMIT(dev->ep0, ctrlreq);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_DEFERREDRESPSUBMIT),
- (uint16_t)-ret);
-#if 0 /* Not necessary */
- ctrlreq->result = OK;
- usbmsc_ep0incomplete(dev->ep0, ctrlreq);
-#endif
- }
- }
- else
- {
- /* On a failure, the USB driver will stall. */
-
- usbtrace(TRACE_DEVERROR(USBMSC_TRACEERR_DEFERREDRESPSTALLED), 0);
- EP_STALL(dev->ep0);
- }
-}
-
-/****************************************************************************
- * User Interfaces
- ****************************************************************************/
-/****************************************************************************
- * Name: usbmsc_configure
- *
- * Description:
- * One-time initialization of the USB storage driver. The initialization
- * sequence is as follows:
- *
- * 1. Call usbmsc_configure to perform one-time initialization specifying
- * the number of luns.
- * 2. Call usbmsc_bindlun to configure each supported LUN
- * 3. Call usbmsc_exportluns when all LUNs are configured
- *
- * Input Parameters:
- * nluns - the number of LUNs that will be registered
- * handle - Location to return a handle that is used in other API calls.
- *
- * Returned Value:
- * 0 on success; a negated errno on failure
- *
- ****************************************************************************/
-
-int usbmsc_configure(unsigned int nluns, void **handle)
-{
- FAR struct usbmsc_alloc_s *alloc;
- FAR struct usbmsc_dev_s *priv;
- FAR struct usbmsc_driver_s *drvr;
- int ret;
-
-#ifdef CONFIG_DEBUG
- if (nluns > 15)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_TOOMANYLUNS), 0);
- return -EDOM;
- }
-#endif
-
- /* Allocate the structures needed */
-
- alloc = (FAR struct usbmsc_alloc_s*)kmalloc(sizeof(struct usbmsc_alloc_s));
- if (!alloc)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCDEVSTRUCT), 0);
- return -ENOMEM;
- }
-
- /* Initialize the USB storage driver structure */
-
- priv = &alloc->dev;
- memset(priv, 0, sizeof(struct usbmsc_dev_s));
-
- pthread_mutex_init(&priv->mutex, NULL);
- pthread_cond_init(&priv->cond, NULL);
- sq_init(&priv->wrreqlist);
-
- priv->nluns = nluns;
-
- /* Allocate the LUN table */
-
- priv->luntab = (struct usbmsc_lun_s*)kmalloc(priv->nluns*sizeof(struct usbmsc_lun_s));
- if (!priv->luntab)
- {
- ret = -ENOMEM;
- goto errout;
- }
- memset(priv->luntab, 0, priv->nluns * sizeof(struct usbmsc_lun_s));
-
- /* Initialize the USB class driver structure */
-
- drvr = &alloc->drvr;
-#ifdef CONFIG_USBDEV_DUALSPEED
- drvr->drvr.speed = USB_SPEED_HIGH;
-#else
- drvr->drvr.speed = USB_SPEED_FULL;
-#endif
- drvr->drvr.ops = &g_driverops;
- drvr->dev = priv;
-
- /* Return the handle and success */
-
- *handle = (FAR void*)alloc;
- return OK;
-
-errout:
- usbmsc_uninitialize(alloc);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_bindlun
- *
- * Description:
- * Bind the block driver specified by drvrpath to a USB storage LUN.
- *
- * Input Parameters:
- * handle - The handle returned by a previous call to usbmsc_configure().
- * drvrpath - the full path to the block driver
- * startsector - A sector offset into the block driver to the start of the
- * partition on drvrpath (0 if no partitions)
- * nsectors - The number of sectors in the partition (if 0, all sectors
- * to the end of the media will be exported).
- * lunno - the LUN to bind to
- *
- * Returned Value:
- * 0 on success; a negated errno on failure.
- *
- ****************************************************************************/
-
-int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath,
- unsigned int lunno, off_t startsector, size_t nsectors,
- bool readonly)
-{
- FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
- FAR struct usbmsc_dev_s *priv;
- FAR struct usbmsc_lun_s *lun;
- FAR struct inode *inode;
- struct geometry geo;
- int ret;
-
-#ifdef CONFIG_DEBUG
- if (!alloc || !drvrpath || startsector < 0 || nsectors < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINLUNINVALIDARGS1), 0);
- return -EINVAL;
- }
-#endif
-
- priv = &alloc->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv->luntab)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INTERNALCONFUSION1), 0);
- return -EIO;
- }
-
- if (lunno > priv->nluns)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINDLUNINVALIDARGS2), 0);
- return -EINVAL;
- }
-#endif
-
- lun = &priv->luntab[lunno];
-
-#ifdef CONFIG_DEBUG
- if (lun->inode != NULL)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_LUNALREADYBOUND), 0);
- return -EBUSY;
- }
-#endif
-
- /* Open the block driver */
-
- ret = open_blockdriver(drvrpath, 0, &inode);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BLKDRVEOPEN), 0);
- return ret;
- }
-
- /* Get the drive geometry */
-
- if (!inode || !inode->u.i_bops || !inode->u.i_bops->geometry ||
- inode->u.i_bops->geometry(inode, &geo) != OK || !geo.geo_available)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_NOGEOMETRY), 0);
- return -ENODEV;
- }
-
- /* Verify that the partition parameters are valid */
-
- if (startsector >= geo.geo_nsectors)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINDLUNINVALIDARGS3), 0);
- return -EDOM;
- }
- else if (nsectors == 0)
- {
- nsectors = geo.geo_nsectors - startsector;
- }
- else if (startsector + nsectors >= geo.geo_nsectors)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINDLUNINVALIDARGS4), 0);
- return -EDOM;
- }
-
- /* Initialize the LUN structure */
-
- memset(lun, 0, sizeof(struct usbmsc_lun_s *));
-
- /* Allocate an I/O buffer big enough to hold one hardware sector. SCSI commands
- * are processed one at a time so all LUNs may share a single I/O buffer. The
- * I/O buffer will be allocated so that is it as large as the largest block
- * device sector size
- */
-
- if (!priv->iobuffer)
- {
- priv->iobuffer = (uint8_t*)kmalloc(geo.geo_sectorsize);
- if (!priv->iobuffer)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCIOBUFFER), geo.geo_sectorsize);
- return -ENOMEM;
- }
- priv->iosize = geo.geo_sectorsize;
- }
- else if (priv->iosize < geo.geo_sectorsize)
- {
- void *tmp;
- tmp = (uint8_t*)realloc(priv->iobuffer, geo.geo_sectorsize);
- if (!tmp)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_REALLOCIOBUFFER), geo.geo_sectorsize);
- return -ENOMEM;
- }
-
- priv->iobuffer = (uint8_t*)tmp;
- priv->iosize = geo.geo_sectorsize;
- }
-
- lun->inode = inode;
- lun->startsector = startsector;
- lun->nsectors = nsectors;
- lun->sectorsize = geo.geo_sectorsize;
-
- /* If the driver does not support the write method, then this is read-only */
-
- if (!inode->u.i_bops->write)
- {
- lun->readonly = true;
- }
- return OK;
-}
-
-/****************************************************************************
- * Name: usbmsc_unbindlun
- *
- * Description:
- * Un-bind the block driver for the specified LUN
- *
- * Input Parameters:
- * handle - The handle returned by a previous call to usbmsc_configure().
- * lun - the LUN to unbind from
- *
- * Returned Value:
- * 0 on success; a negated errno on failure.
- *
- ****************************************************************************/
-
-int usbmsc_unbindlun(FAR void *handle, unsigned int lunno)
-{
- FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
- FAR struct usbmsc_dev_s *priv;
- FAR struct usbmsc_lun_s *lun;
- int ret;
-
-#ifdef CONFIG_DEBUG
- if (!alloc)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNBINDLUNINVALIDARGS1), 0);
- return -EINVAL;
- }
-#endif
-
- priv = &alloc->dev;
-
-#ifdef CONFIG_DEBUG
- if (!priv->luntab)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INTERNALCONFUSION2), 0);
- return -EIO;
- }
-
- if (lunno > priv->nluns)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNBINDLUNINVALIDARGS2), 0);
- return -EINVAL;
- }
-#endif
-
- lun = &priv->luntab[lunno];
- pthread_mutex_lock(&priv->mutex);
-
-#ifdef CONFIG_DEBUG
- if (lun->inode == NULL)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_LUNNOTBOUND), 0);
- ret = -EBUSY;
- }
- else
-#endif
- {
- /* Close the block driver */
-
- usbmsc_lununinitialize(lun);
- ret = OK;
- }
-
- pthread_mutex_unlock(&priv->mutex);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_exportluns
- *
- * Description:
- * After all of the LUNs have been bound, this function may be called
- * in order to export those LUNs in the USB storage device.
- *
- * Input Parameters:
- * handle - The handle returned by a previous call to usbmsc_configure().
- *
- * Returned Value:
- * 0 on success; a negated errno on failure
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBMSC_COMPOSITE
-static
-#endif
-int usbmsc_exportluns(FAR void *handle)
-{
- FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
- FAR struct usbmsc_dev_s *priv;
- FAR struct usbmsc_driver_s *drvr;
- irqstate_t flags;
-#ifdef SDCC
- pthread_attr_t attr;
-#endif
- int ret;
-
-#ifdef CONFIG_DEBUG
- if (!alloc)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_EXPORTLUNSINVALIDARGS), 0);
- return -ENXIO;
- }
-#endif
-
- priv = &alloc->dev;
- drvr = &alloc->drvr;
-
- /* Start the worker thread */
-
- pthread_mutex_lock(&priv->mutex);
- priv->thstate = USBMSC_STATE_NOTSTARTED;
- priv->theventset = USBMSC_EVENT_NOEVENTS;
-
-#ifdef SDCC
- (void)pthread_attr_init(&attr);
- ret = pthread_create(&priv->thread, &attr, usbmsc_workerthread, (pthread_addr_t)priv);
-#else
- ret = pthread_create(&priv->thread, NULL, usbmsc_workerthread, (pthread_addr_t)priv);
-#endif
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_THREADCREATE), (uint16_t)-ret);
- goto errout_with_mutex;
- }
-
- /* Register the USB storage class driver (unless we are part of a composite device) */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- ret = usbdev_register(&drvr->drvr);
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_DEVREGISTER), (uint16_t)-ret);
- goto errout_with_mutex;
- }
-#endif
-
- /* Signal to start the thread */
-
- flags = irqsave();
- priv->theventset |= USBMSC_EVENT_READY;
- pthread_cond_signal(&priv->cond);
- irqrestore(flags);
-
-errout_with_mutex:
- pthread_mutex_unlock(&priv->mutex);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_classobject
- *
- * Description:
- * Register USB mass storage device and return the class object.
- *
- * Input Parameters:
- * classdev - The location to return the CDC serial class' device
- * instance.
- *
- * Returned Value:
- * 0 on success; a negated errno on failure
-
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBMSC_COMPOSITE
-int usbmsc_classobject(FAR void *handle,
- FAR struct usbdevclass_driver_s **classdev)
-{
- FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
- int ret;
-
- DEBUGASSERT(handle && classdev);
-
- /* Export the LUNs as with the "standalone" USB mass storage driver, but
- * don't register the class instance with the USB device infrastructure.
- */
-
- ret = usbmsc_exportluns(handle);
- if (ret == OK)
- {
- /* On sucess, return an (typed) instance of the class instance */
-
- *classdev = &alloc->drvr.drvr;
- }
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Name: usbmsc_uninitialize
- *
- * Description:
- * Un-initialize the USB storage class driver
- *
- * Input Parameters:
- * handle - The handle returned by a previous call to usbmsc_configure().
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-void usbmsc_uninitialize(FAR void *handle)
-{
- FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
- FAR struct usbmsc_dev_s *priv;
- irqstate_t flags;
-#ifdef SDCC
- pthread_addr_t result1, result2;
- pthread_attr_t attr;
-#endif
- void *value;
- int i;
-
-#ifdef CONFIG_DEBUG
- if (!handle)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_UNINITIALIZEINVALIDARGS), 0);
- return;
- }
-#endif
- priv = &alloc->dev;
-
- /* If the thread hasn't already exitted, tell it to exit now */
-
- if (priv->thstate != USBMSC_STATE_NOTSTARTED)
- {
- /* The thread was started.. Is it still running? */
-
- pthread_mutex_lock(&priv->mutex);
- if (priv->thstate != USBMSC_STATE_TERMINATED)
- {
- /* Yes.. Ask the thread to stop */
-
- flags = irqsave();
- priv->theventset |= USBMSC_EVENT_TERMINATEREQUEST;
- pthread_cond_signal(&priv->cond);
- irqrestore(flags);
- }
- pthread_mutex_unlock(&priv->mutex);
-
- /* Wait for the thread to exit. This is necessary even if the
- * thread has already exitted in order to collect the join
- * garbage
- */
-
- (void)pthread_join(priv->thread, &value);
- }
- priv->thread = 0;
-
- /* Unregister the driver (unless we are a part of a composite device */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- usbdev_unregister(&alloc->drvr.drvr);
-#endif
-
- /* Uninitialize and release the LUNs */
-
- for (i = 0; i < priv->nluns; ++i)
- {
- usbmsc_lununinitialize(&priv->luntab[i]);
- }
- kfree(priv->luntab);
-
- /* Release the I/O buffer */
-
- if (priv->iobuffer)
- {
- kfree(priv->iobuffer);
- }
-
- /* Uninitialize and release the driver structure */
-
- pthread_mutex_destroy(&priv->mutex);
- pthread_cond_destroy(&priv->cond);
-
- kfree(priv);
-}
diff --git a/nuttx/drivers/usbdev/usbmsc.h b/nuttx/drivers/usbdev/usbmsc.h
deleted file mode 100644
index da35ae923..000000000
--- a/nuttx/drivers/usbdev/usbmsc.h
+++ /dev/null
@@ -1,694 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/usbmsc.h
- *
- * Copyright (C) 2008-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Mass storage class device. Bulk-only with SCSI subclass.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_USBDEV_USBMSC_H
-#define __DRIVERS_USBDEV_USBMSC_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <pthread.h>
-#include <queue.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/usb/storage.h>
-#include <nuttx/usb/usbdev.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Configuration ************************************************************/
-/* If the USB mass storage device is configured as part of a composite device
- * then both CONFIG_USBDEV_COMPOSITE and CONFIG_USBMSC_COMPOSITE must be
- * defined.
- */
-
-#ifndef CONFIG_USBDEV_COMPOSITE
-# undef CONFIG_USBMSC_COMPOSITE
-#endif
-
-#if defined(CONFIG_USBMSC_COMPOSITE) && !defined(CONFIG_USBMSC_STRBASE)
-# define CONFIG_USBMSC_STRBASE (4)
-#endif
-
-/* Interface IDs. If the mass storage driver is built as a component of a
- * composite device, then the interface IDs may need to be offset.
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-# undef CONFIG_USBMSC_IFNOBASE
-# define CONFIG_USBMSC_IFNOBASE 0
-#endif
-
-#ifndef CONFIG_USBMSC_IFNOBASE
-# define CONFIG_USBMSC_IFNOBASE 0
-#endif
-
-/* Number of requests in the write queue */
-
-#ifndef CONFIG_USBMSC_NWRREQS
-# define CONFIG_USBMSC_NWRREQS 4
-#endif
-
-/* Number of requests in the read queue */
-
-#ifndef CONFIG_USBMSC_NRDREQS
-# define CONFIG_USBMSC_NRDREQS 4
-#endif
-
-/* Logical endpoint numbers / max packet sizes */
-
-#ifndef CONFIG_USBMSC_EPBULKOUT
-# warning "EPBULKOUT not defined in the configuration"
-# define CONFIG_USBMSC_EPBULKOUT 2
-#endif
-
-#ifndef CONFIG_USBMSC_EPBULKIN
-# warning "EPBULKIN not defined in the configuration"
-# define CONFIG_USBMSC_EPBULKIN 3
-#endif
-
-/* Packet and request buffer sizes */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-# ifndef CONFIG_USBMSC_EP0MAXPACKET
-# define CONFIG_USBMSC_EP0MAXPACKET 64
-# endif
-#endif
-
-#ifndef CONFIG_USBMSC_BULKINREQLEN
-# ifdef CONFIG_USBDEV_DUALSPEED
-# define CONFIG_USBMSC_BULKINREQLEN 512
-# else
-# define CONFIG_USBMSC_BULKINREQLEN 64
-# endif
-#else
-# ifdef CONFIG_USBDEV_DUALSPEED
-# if CONFIG_USBMSC_BULKINREQLEN < 512
-# warning "Bulk in buffer size smaller than max packet"
-# undef CONFIG_USBMSC_BULKINREQLEN
-# define CONFIG_USBMSC_BULKINREQLEN 512
-# endif
-# else
-# if CONFIG_USBMSC_BULKINREQLEN < 64
-# warning "Bulk in buffer size smaller than max packet"
-# undef CONFIG_USBMSC_BULKINREQLEN
-# define CONFIG_USBMSC_BULKINREQLEN 64
-# endif
-# endif
-#endif
-
-#ifndef CONFIG_USBMSC_BULKOUTREQLEN
-# ifdef CONFIG_USBDEV_DUALSPEED
-# define CONFIG_USBMSC_BULKOUTREQLEN 512
-# else
-# define CONFIG_USBMSC_BULKOUTREQLEN 64
-# endif
-#else
-# ifdef CONFIG_USBDEV_DUALSPEED
-# if CONFIG_USBMSC_BULKOUTREQLEN < 512
-# warning "Bulk in buffer size smaller than max packet"
-# undef CONFIG_USBMSC_BULKOUTREQLEN
-# define CONFIG_USBMSC_BULKOUTREQLEN 512
-# endif
-# else
-# if CONFIG_USBMSC_BULKOUTREQLEN < 64
-# warning "Bulk in buffer size smaller than max packet"
-# undef CONFIG_USBMSC_BULKOUTREQLEN
-# define CONFIG_USBMSC_BULKOUTREQLEN 64
-# endif
-# endif
-#endif
-
-/* Vendor and product IDs and strings */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-# ifndef CONFIG_USBMSC_VENDORID
-# warning "CONFIG_USBMSC_VENDORID not defined"
-# define CONFIG_USBMSC_VENDORID 0x584e
-# endif
-
-# ifndef CONFIG_USBMSC_PRODUCTID
-# warning "CONFIG_USBMSC_PRODUCTID not defined"
-# define CONFIG_USBMSC_PRODUCTID 0x5342
-# endif
-
-# ifndef CONFIG_USBMSC_VERSIONNO
-# define CONFIG_USBMSC_VERSIONNO (0x0399)
-# endif
-
-# ifndef CONFIG_USBMSC_VENDORSTR
-# warning "No Vendor string specified"
-# define CONFIG_USBMSC_VENDORSTR "NuttX"
-# endif
-
-# ifndef CONFIG_USBMSC_PRODUCTSTR
-# warning "No Product string specified"
-# define CONFIG_USBMSC_PRODUCTSTR "USBdev Storage"
-# endif
-
-# undef CONFIG_USBMSC_SERIALSTR
-# define CONFIG_USBMSC_SERIALSTR "0101"
-#endif
-
-#undef CONFIG_USBMSC_CONFIGSTR
-#define CONFIG_USBMSC_CONFIGSTR "Bulk"
-
-/* Debug -- must be consistent with include/debug.h */
-
-#ifdef CONFIG_CPP_HAVE_VARARGS
-# ifdef CONFIG_DEBUG
-# ifdef CONFIG_ARCH_LOWPUTC
-# define dbgprintf(format, arg...) lowsyslog(format, ##arg)
-# else
-# define dbgprintf(format, arg...) syslog(format, ##arg)
-# endif
-# else
-# define dbgprintf(x...)
-# endif
-#else
-# ifdef CONFIG_DEBUG
-# ifdef CONFIG_ARCH_LOWPUTC
-# define dbgprintf lowsyslog
-# else
-# define dbgprintf syslog
-# endif
-# else
-# define dbgprintf (void)
-# endif
-#endif
-
-/* Packet and request buffer sizes */
-
-#ifndef CONFIG_USBMSC_EP0MAXPACKET
-# define CONFIG_USBMSC_EP0MAXPACKET 64
-#endif
-
-/* USB Controller */
-
-#ifndef CONFIG_USBDEV_SELFPOWERED
-# define SELFPOWERED USB_CONFIG_ATTR_SELFPOWER
-#else
-# define SELFPOWERED (0)
-#endif
-
-#ifndef CONFIG_USBDEV_REMOTEWAKEUP
-# define REMOTEWAKEUP USB_CONFIG_ATTR_WAKEUP
-#else
-# define REMOTEWAKEUP (0)
-#endif
-
-#ifndef CONFIG_USBDEV_MAXPOWER
-# define CONFIG_USBDEV_MAXPOWER 100
-#endif
-
-/* Current state of the worker thread */
-
-#define USBMSC_STATE_NOTSTARTED (0) /* Thread has not yet been started */
-#define USBMSC_STATE_STARTED (1) /* Started, but is not yet initialized */
-#define USBMSC_STATE_IDLE (2) /* Started and waiting for commands */
-#define USBMSC_STATE_CMDPARSE (3) /* Processing a received command */
-#define USBMSC_STATE_CMDREAD (4) /* Processing a SCSI read command */
-#define USBMSC_STATE_CMDWRITE (5) /* Processing a SCSI write command */
-#define USBMSC_STATE_CMDFINISH (6) /* Finish command processing */
-#define USBMSC_STATE_CMDSTATUS (7) /* Processing the final status of the command */
-#define USBMSC_STATE_TERMINATED (8) /* Thread has exitted */
-
-/* Event communicated to worker thread */
-
-#define USBMSC_EVENT_NOEVENTS (0) /* There are no outstanding events */
-#define USBMSC_EVENT_READY (1 << 0) /* Initialization is complete */
-#define USBMSC_EVENT_RDCOMPLETE (1 << 1) /* A read has completed there is data to be processed */
-#define USBMSC_EVENT_WRCOMPLETE (1 << 2) /* A write has completed and a request is available */
-#define USBMSC_EVENT_TERMINATEREQUEST (1 << 3) /* Shutdown requested */
-#define USBMSC_EVENT_DISCONNECT (1 << 4) /* USB disconnect received */
-#define USBMSC_EVENT_RESET (1 << 5) /* USB storage setup reset received */
-#define USBMSC_EVENT_CFGCHANGE (1 << 6) /* USB setup configuration change received */
-#define USBMSC_EVENT_IFCHANGE (1 << 7) /* USB setup interface change received */
-#define USBMSC_EVENT_ABORTBULKOUT (1 << 8) /* SCSI receive failure */
-
-/* SCSI command flags (passed to usbmsc_setupcmd()) */
-
-#define USBMSC_FLAGS_DIRMASK (0x03) /* Bits 0-1: Data direction */
-#define USBMSC_FLAGS_DIRNONE (0x00) /* No data to send */
-#define USBMSC_FLAGS_DIRHOST2DEVICE (0x01) /* Host-to-device */
-#define USBMSC_FLAGS_DIRDEVICE2HOST (0x02) /* Device-to-host */
-#define USBMSC_FLAGS_BLOCKXFR (0x04) /* Bit 2: Command is a block transfer request */
-#define USBMSC_FLAGS_LUNNOTNEEDED (0x08) /* Bit 3: Command does not require a valid LUN */
-#define USBMSC_FLAGS_UACOKAY (0x10) /* Bit 4: Command OK if unit attention condition */
-#define USBMSC_FLAGS_RETAINSENSEDATA (0x20) /* Bit 5: Do not clear sense data */
-
-/* Descriptors **************************************************************/
-
-/* Big enough to hold our biggest descriptor */
-
-#define USBMSC_MXDESCLEN (64)
-
-/* String language */
-
-#define USBMSC_STR_LANGUAGE (0x0409) /* en-us */
-
-/* Descriptor strings */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-# define USBMSC_MANUFACTURERSTRID (1)
-# define USBMSC_PRODUCTSTRID (2)
-# define USBMSC_SERIALSTRID (3)
-# define USBMSC_CONFIGSTRID (4)
-# define USBMSC_INTERFACESTRID USBMSC_CONFIGSTRID
-
-# undef CONFIG_USBMSC_STRBASE
-# define CONFIG_USBMSC_STRBASE (0)
-#else
-# define USBMSC_INTERFACESTRID (CONFIG_USBMSC_STRBASE+1)
-#endif
-
-#define USBMSC_LASTSTRID USBMSC_INTERFACESTRID
-#define USBMSC_NSTRIDS (USBMSC_LASTSTRID - CONFIG_USBMSC_STRBASE)
-
-#define USBMSC_NCONFIGS (1) /* Number of configurations supported */
-
-/* Configuration Descriptor */
-
-#define USBMSC_NINTERFACES (1) /* Number of interfaces in the configuration */
-#define USBMSC_INTERFACEID (CONFIG_USBMSC_IFNOBASE+0)
-#define USBMSC_ALTINTERFACEID (0)
-
-#define USBMSC_CONFIGIDNONE (0) /* Config ID means to return to address mode */
-#define USBMSC_CONFIGID (1) /* The only supported configuration ID */
-
-/* Interface description */
-
-#define USBMSC_NENDPOINTS (2) /* Number of endpoints in the interface */
-
-/* Endpoint configuration */
-
-#define USBMSC_EPOUTBULK_ADDR (CONFIG_USBMSC_EPBULKOUT)
-#define USBMSC_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK)
-
-#define USBMSC_EPINBULK_ADDR (USB_DIR_IN|CONFIG_USBMSC_EPBULKIN)
-#define USBMSC_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK)
-
-#define USBMSC_HSBULKMAXPACKET (512)
-#define USBMSC_HSBULKMXPKTSHIFT (9)
-#define USBMSC_HSBULKMXPKTMASK (0x000001ff)
-#define USBMSC_FSBULKMAXPACKET (64)
-#define USBMSC_FSBULKMXPKTSHIFT (6)
-#define USBMSC_FSBULKMXPKTMASK (0x0000003f)
-
-/* Macros for dual speed vs. full speed only operation */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-# define USBMSC_EPBULKINDESC(hs) \
- usbmsc_getepdesc((hs) ? USBMSC_EPHSBULKIN : USBMSC_EPFSBULKIN)
-# define USBMSC_EPBULKOUTDESC(hs) \
- usbmsc_getepdesc((hs) ? USBMSC_EPHSBULKOUT : USBMSC_EPFSBULKOUT)
-# define USBMSC_BULKMAXPACKET(hs) \
- ((hs) ? USBMSC_HSBULKMAXPACKET : USBMSC_FSBULKMAXPACKET)
-# define USBMSC_BULKMXPKTSHIFT(d) \
- (((d)->speed==USB_SPEED_HIGH) ? USBMSC_HSBULKMXPKTSHIFT : USBMSC_FSBULKMXPKTSHIFT)
-# define USBMSC_BULKMXPKTMASK(d) \
- (((d)->speed==USB_SPEED_HIGH) ? USBMSC_HSBULKMXPKTMASK : USBMSC_FSBULKMXPKTMASK)
-#else
-# define USBMSC_EPBULKINDESC(d) usbmsc_getepdesc(USBMSC_EPFSBULKIN)
-# define USBMSC_EPBULKOUTDESC(d) usbmsc_getepdesc(USBMSC_EPFSBULKOUT)
-# define USBMSC_BULKMAXPACKET(hs) USBMSC_FSBULKMAXPACKET
-# define USBMSC_BULKMXPKTSHIFT(d) USBMSC_FSBULKMXPKTSHIFT
-# define USBMSC_BULKMXPKTMASK(d) USBMSC_FSBULKMXPKTMASK
-#endif
-
-/* Configuration descriptor size */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-
-/* Number of individual descriptors in the configuration descriptor:
- * (1) Configuration descriptor + (1) interface descriptor + (2) interface
- * descriptors.
- */
-
-# define USBMSC_CFGGROUP_SIZE (4)
-
-/* The size of the config descriptor: (9 + 9 + 2*7) = 32 */
-
-# define SIZEOF_USBMSC_CFGDESC \
- (USB_SIZEOF_CFGDESC + USB_SIZEOF_IFDESC + USBMSC_NENDPOINTS * USB_SIZEOF_EPDESC)
-
-#else
-
-/* Number of individual descriptors in the configuration descriptor:
- * (1) interface descriptor + (2) interface descriptors.
- */
-
-# define USBMSC_CFGGROUP_SIZE (3)
-
-/* The size of the config descriptor: (9 + 2*7) = 23 */
-
-# define SIZEOF_USBMSC_CFGDESC \
- (USB_SIZEOF_IFDESC + USBMSC_NENDPOINTS * USB_SIZEOF_EPDESC)
-
-#endif
-
-/* Block driver helpers *****************************************************/
-
-#define USBMSC_DRVR_READ(l,b,s,n) ((l)->inode->u.i_bops->read((l)->inode,b,s,n))
-#define USBMSC_DRVR_WRITE(l,b,s,n) ((l)->inode->u.i_bops->write((l)->inode,b,s,n))
-#define USBMSC_DRVR_GEOMETRY(l,g) ((l)->inode->u.i_bops->geometry((l)->inode,g))
-
-/* Everpresent MIN/MAX macros ***********************************************/
-
-#ifndef MIN
-# define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
-#ifndef MAX
-# define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-/* Endpoint descriptors */
-
-enum usbmsc_epdesc_e
-{
- USBMSC_EPFSBULKOUT = 0, /* Full speed bulk OUT endpoint descriptor */
- USBMSC_EPFSBULKIN /* Full speed bulk IN endpoint descriptor */
-#ifdef CONFIG_USBDEV_DUALSPEED
- ,
- USBMSC_EPHSBULKOUT, /* High speed bulk OUT endpoint descriptor */
- USBMSC_EPHSBULKIN /* High speed bulk IN endpoint descriptor */
-#endif
-};
-
-/* Container to support a list of requests */
-
-struct usbmsc_req_s
-{
- FAR struct usbmsc_req_s *flink; /* Implements a singly linked list */
- FAR struct usbdev_req_s *req; /* The contained request */
-};
-
-/* This structure describes one LUN: */
-
-struct usbmsc_lun_s
-{
- struct inode *inode; /* Inode structure of open'ed block driver */
- uint8_t readonly:1; /* Media is read-only */
- uint8_t locked:1; /* Media removal is prevented */
- uint16_t sectorsize; /* The size of one sector */
- uint32_t sd; /* Sense data */
- uint32_t sdinfo; /* Sense data information */
- uint32_t uad; /* Unit needs attention data */
- off_t startsector; /* Sector offset to start of partition */
- size_t nsectors; /* Number of sectors in the partition */
-};
-
-/* Describes the overall state of the driver */
-
-struct usbmsc_dev_s
-{
- FAR struct usbdev_s *usbdev; /* usbdev driver pointer (Non-null if registered) */
-
- /* Worker thread interface */
-
- pthread_t thread; /* The worker thread */
- pthread_mutex_t mutex; /* Mutually exclusive access to resources*/
- pthread_cond_t cond; /* Used to signal worker thread */
- volatile uint8_t thstate; /* State of the worker thread */
- volatile uint16_t theventset; /* Set of pending events signaled to worker thread */
- volatile uint8_t thvalue; /* Value passed with the event (must persist) */
-
- /* Storage class configuration and state */
-
- uint8_t nluns:4; /* Number of LUNs */
- uint8_t config; /* Configuration number */
-
- /* Endpoints */
-
- FAR struct usbdev_ep_s *epbulkin; /* Bulk IN endpoint structure */
- FAR struct usbdev_ep_s *epbulkout; /* Bulk OUT endpoint structure */
- FAR struct usbdev_req_s *ctrlreq; /* Control request (for ep0 setup responses) */
-
- /* SCSI command processing */
-
- struct usbmsc_lun_s *lun; /* Currently selected LUN */
- struct usbmsc_lun_s *luntab; /* Allocated table of all LUNs */
- uint8_t cdb[USBMSC_MAXCDBLEN]; /* Command data (cdb[]) from CBW */
- uint8_t phaseerror:1; /* Need to send phase sensing status */
- uint8_t shortpacket:1; /* Host transmission stopped unexpectedly */
- uint8_t cbwdir:2; /* Direction from CBW. See USBMSC_FLAGS_DIR* definitions */
- uint8_t cdblen; /* Length of cdb[] from CBW */
- uint8_t cbwlun; /* LUN from the CBW */
- uint16_t nsectbytes; /* Bytes buffered in iobuffer[] */
- uint16_t nreqbytes; /* Bytes buffered in head write requests */
- uint16_t iosize; /* Size of iobuffer[] */
- uint32_t cbwlen; /* Length of data from CBW */
- uint32_t cbwtag; /* Tag from the CBW */
- union
- {
- uint32_t xfrlen; /* Read/Write: Sectors remaining to be transferred */
- uint32_t alloclen; /* Other device-to-host: Host allocation length */
- } u;
- uint32_t sector; /* Current sector (relative to lun->startsector) */
- uint32_t residue; /* Untransferred amount reported in the CSW */
- uint8_t *iobuffer; /* Buffer for data transfers */
-
- /* Write request list */
-
- struct sq_queue_s wrreqlist; /* List of empty write request containers */
- struct sq_queue_s rdreqlist; /* List of filled read request containers */
-
- /* Pre-allocated write request containers. The write requests will
- * be linked in a free list (wrreqlist), and used to send requests to
- * EPBULKIN; Read requests will be queued in the EBULKOUT.
- */
-
- struct usbmsc_req_s wrreqs[CONFIG_USBMSC_NWRREQS];
- struct usbmsc_req_s rdreqs[CONFIG_USBMSC_NRDREQS];
-};
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-# define EXTERN extern "C"
-extern "C"
-{
-#else
-# define EXTERN extern
-#endif
-
-/* String *******************************************************************/
-
-/* Mass storage class vendor/product/serial number strings */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-EXTERN const char g_mscvendorstr[];
-EXTERN const char g_mscproductstr[];
-EXTERN const char g_mscserialstr[];
-
-/* If we are using a composite device, then vendor/product/serial number strings
- * are provided by the composite device logic.
- */
-
-#else
-EXTERN const char g_compvendorstr[];
-EXTERN const char g_compproductstr[];
-EXTERN const char g_compserialstr[];
-
-#define g_mscvendorstr g_compvendorstr
-#define g_mscproductstr g_compproductstr
-#define g_mscserialstr g_compserialstr
-#endif
-/************************************************************************************
- * Public Function Prototypes
- ************************************************************************************/
-
-/************************************************************************************
- * Name: usbmsc_mkstrdesc
- *
- * Description:
- * Construct a string descriptor
- *
- ************************************************************************************/
-
-struct usb_strdesc_s;
-int usbmsc_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc);
-
-/************************************************************************************
- * Name: usbmsc_getepdesc
- *
- * Description:
- * Return a pointer to the raw device descriptor
- *
- ************************************************************************************/
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-FAR const struct usb_devdesc_s *usbmsc_getdevdesc(void);
-#endif
-
-/************************************************************************************
- * Name: usbmsc_getepdesc
- *
- * Description:
- * Return a pointer to the raw endpoint descriptor (used for configuring endpoints)
- *
- ************************************************************************************/
-
-struct usb_epdesc_s;
-FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid);
-
-/************************************************************************************
- * Name: usbmsc_mkcfgdesc
- *
- * Description:
- * Construct the configuration descriptor
- *
- ************************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type);
-#else
-int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf);
-#endif
-
-/************************************************************************************
- * Name: usbmsc_getqualdesc
- *
- * Description:
- * Return a pointer to the raw qual descriptor
- *
- ************************************************************************************/
-
-#if !defined(CONFIG_USBMSC_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
-FAR const struct usb_qualdesc_s *usbmsc_getqualdesc(void);
-#endif
-
-/****************************************************************************
- * Name: usbmsc_workerthread
- *
- * Description:
- * This is the main function of the USB storage worker thread. It loops
- * until USB-related events occur, then processes those events accordingly
- *
- ****************************************************************************/
-
-EXTERN void *usbmsc_workerthread(void *arg);
-
-/****************************************************************************
- * Name: usbmsc_setconfig
- *
- * Description:
- * Set the device configuration by allocating and configuring endpoints and
- * by allocating and queue read and write requests.
- *
- ****************************************************************************/
-
-EXTERN int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config);
-
-/****************************************************************************
- * Name: usbmsc_resetconfig
- *
- * Description:
- * Mark the device as not configured and disable all endpoints.
- *
- ****************************************************************************/
-
-EXTERN void usbmsc_resetconfig(FAR struct usbmsc_dev_s *priv);
-
-/****************************************************************************
- * Name: usbmsc_wrcomplete
- *
- * Description:
- * Handle completion of write request. This function probably executes
- * in the context of an interrupt handler.
- *
- ****************************************************************************/
-
-EXTERN void usbmsc_wrcomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-
-/****************************************************************************
- * Name: usbmsc_rdcomplete
- *
- * Description:
- * Handle completion of read request on the bulk OUT endpoint. This
- * is handled like the receipt of serial data on the "UART"
- *
- ****************************************************************************/
-
-EXTERN void usbmsc_rdcomplete(FAR struct usbdev_ep_s *ep,
- FAR struct usbdev_req_s *req);
-
-/****************************************************************************
- * Name: usbmsc_deferredresponse
- *
- * Description:
- * Some EP0 setup request cannot be responded to immediately becuase they
- * require some asynchronous action from the SCSI worker thread. This
- * function is provided for the SCSI thread to make that deferred response.
- * The specific requests that require this deferred response are:
- *
- * 1. USB_REQ_SETCONFIGURATION,
- * 2. USB_REQ_SETINTERFACE, or
- * 3. USBMSC_REQ_MSRESET
- *
- * In all cases, the success reponse is a zero-length packet; the failure
- * response is an EP0 stall.
- *
- * Input parameters:
- * priv - Private state structure for this USB storage instance
- * stall - true is the action failed and a stall is required
- *
- ****************************************************************************/
-
-EXTERN void usbmsc_deferredresponse(FAR struct usbmsc_dev_s *priv, bool failed);
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* #define __DRIVERS_USBDEV_USBMSC_H */
diff --git a/nuttx/drivers/usbdev/usbmsc_desc.c b/nuttx/drivers/usbdev/usbmsc_desc.c
deleted file mode 100644
index 6d7561b3f..000000000
--- a/nuttx/drivers/usbdev/usbmsc_desc.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/usbmsc_desc.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/usbdev_trace.h>
-
-#include "usbmsc.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-/* Descriptors **************************************************************/
-/* Device descriptor. If the USB mass storage device is configured as part
- * of a composite device, then the device descriptor will be provided by the
- * composite device logic.
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-static const struct usb_devdesc_s g_devdesc =
-{
- USB_SIZEOF_DEVDESC, /* len */
- USB_DESC_TYPE_DEVICE, /* type */
- {LSBYTE(0x0200), MSBYTE(0x0200)}, /* usb */
- USB_CLASS_PER_INTERFACE, /* classid */
- 0, /* subclass */
- 0, /* protocol */
- CONFIG_USBMSC_EP0MAXPACKET, /* maxpacketsize */
- { /* vendor */
- LSBYTE(CONFIG_USBMSC_VENDORID),
- MSBYTE(CONFIG_USBMSC_VENDORID)
- },
- { /* product */
- LSBYTE(CONFIG_USBMSC_PRODUCTID),
- MSBYTE(CONFIG_USBMSC_PRODUCTID) },
- { /* device */
- LSBYTE(CONFIG_USBMSC_VERSIONNO),
- MSBYTE(CONFIG_USBMSC_VERSIONNO)
- },
- USBMSC_MANUFACTURERSTRID, /* imfgr */
- USBMSC_PRODUCTSTRID, /* iproduct */
- USBMSC_SERIALSTRID, /* serno */
- USBMSC_NCONFIGS /* nconfigs */
-};
-#endif
-
-/* Configuration descriptor If the USB mass storage device is configured as part
- * of a composite device, then the configuration descriptor will be provided by the
- * composite device logic.
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-static const struct usb_cfgdesc_s g_cfgdesc =
-{
- USB_SIZEOF_CFGDESC, /* len */
- USB_DESC_TYPE_CONFIG, /* type */
- { /* totallen */
- LSBYTE(SIZEOF_USBMSC_CFGDESC),
- MSBYTE(SIZEOF_USBMSC_CFGDESC)
- },
- USBMSC_NINTERFACES, /* ninterfaces */
- USBMSC_CONFIGID, /* cfgvalue */
- USBMSC_CONFIGSTRID, /* icfg */
- USB_CONFIG_ATTR_ONE|SELFPOWERED|REMOTEWAKEUP, /* attr */
- (CONFIG_USBDEV_MAXPOWER + 1) / 2 /* mxpower */
-};
-#endif
-
-/* Single interface descriptor */
-
-static const struct usb_ifdesc_s g_ifdesc =
-{
- USB_SIZEOF_IFDESC, /* len */
- USB_DESC_TYPE_INTERFACE, /* type */
- USBMSC_INTERFACEID, /* ifno */
- USBMSC_ALTINTERFACEID, /* alt */
- USBMSC_NENDPOINTS, /* neps */
- USB_CLASS_MASS_STORAGE, /* classid */
- USBMSC_SUBCLASS_SCSI, /* subclass */
- USBMSC_PROTO_BULKONLY, /* protocol */
- USBMSC_INTERFACESTRID /* iif */
-};
-
-/* Endpoint descriptors */
-
-static const struct usb_epdesc_s g_fsepbulkoutdesc =
-{
- USB_SIZEOF_EPDESC, /* len */
- USB_DESC_TYPE_ENDPOINT, /* type */
- USBMSC_EPOUTBULK_ADDR, /* addr */
- USBMSC_EPOUTBULK_ATTR, /* attr */
- { /* maxpacket */
- LSBYTE(USBMSC_FSBULKMAXPACKET),
- MSBYTE(USBMSC_FSBULKMAXPACKET)
- },
- 0 /* interval */
-};
-
-static const struct usb_epdesc_s g_fsepbulkindesc =
-{
- USB_SIZEOF_EPDESC, /* len */
- USB_DESC_TYPE_ENDPOINT, /* type */
- USBMSC_EPINBULK_ADDR, /* addr */
- USBMSC_EPINBULK_ATTR, /* attr */
- { /* maxpacket */
- LSBYTE(USBMSC_FSBULKMAXPACKET),
- MSBYTE(USBMSC_FSBULKMAXPACKET)
- },
- 0 /* interval */
-};
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-#ifndef CONFIG_USBMSC_COMPOSITE
-static const struct usb_qualdesc_s g_qualdesc =
-{
- USB_SIZEOF_QUALDESC, /* len */
- USB_DESC_TYPE_DEVICEQUALIFIER, /* type */
- { /* usb */
- LSBYTE(0x0200),
- MSBYTE(0x0200)
- },
- USB_CLASS_PER_INTERFACE, /* classid */
- 0, /* subclass */
- 0, /* protocol */
- CONFIG_USBMSC_EP0MAXPACKET, /* mxpacketsize */
- USBMSC_NCONFIGS, /* nconfigs */
- 0, /* reserved */
-};
-#endif
-
-static const struct usb_epdesc_s g_hsepbulkoutdesc =
-{
- USB_SIZEOF_EPDESC, /* len */
- USB_DESC_TYPE_ENDPOINT, /* type */
- USBMSC_EPOUTBULK_ADDR, /* addr */
- USBMSC_EPOUTBULK_ATTR, /* attr */
- { /* maxpacket */
- LSBYTE(USBMSC_HSBULKMAXPACKET),
- MSBYTE(USBMSC_HSBULKMAXPACKET)
- },
- 0 /* interval */
-};
-
-static const struct usb_epdesc_s g_hsepbulkindesc =
-{
- USB_SIZEOF_EPDESC, /* len */
- USB_DESC_TYPE_ENDPOINT, /* type */
- USBMSC_EPINBULK_ADDR, /* addr */
- USBMSC_EPINBULK_ATTR, /* attr */
- { /* maxpacket */
- LSBYTE(USBMSC_HSBULKMAXPACKET),
- MSBYTE(USBMSC_HSBULKMAXPACKET)
- },
- 0 /* interval */
-};
-#endif
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-/* Strings ******************************************************************/
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-const char g_mscvendorstr[] = CONFIG_USBMSC_VENDORSTR;
-const char g_mscproductstr[] = CONFIG_USBMSC_PRODUCTSTR;
-const char g_mscserialstr[] = CONFIG_USBMSC_SERIALSTR;
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbmsc_mkstrdesc
- *
- * Description:
- * Construct a string descriptor
- *
- ****************************************************************************/
-
-int usbmsc_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc)
-{
- const char *str;
- int len;
- int ndata;
- int i;
-
- switch (id)
- {
-#ifndef CONFIG_USBMSC_COMPOSITE
- case 0:
- {
- /* Descriptor 0 is the language id */
-
- strdesc->len = 4;
- strdesc->type = USB_DESC_TYPE_STRING;
- strdesc->data[0] = LSBYTE(USBMSC_STR_LANGUAGE);
- strdesc->data[1] = MSBYTE(USBMSC_STR_LANGUAGE);
- return 4;
- }
-
- case USBMSC_MANUFACTURERSTRID:
- str = g_mscvendorstr;
- break;
-
- case USBMSC_PRODUCTSTRID:
- str = g_mscproductstr;
- break;
-
- case USBMSC_SERIALSTRID:
- str = g_mscserialstr;
- break;
-#endif
-
- /* case USBMSC_CONFIGSTRID: */
- case USBMSC_INTERFACESTRID:
- str = CONFIG_USBMSC_CONFIGSTR;
- break;
-
- default:
- return -EINVAL;
- }
-
- /* The string is utf16-le. The poor man's utf-8 to utf16-le
- * conversion below will only handle 7-bit en-us ascii
- */
-
- len = strlen(str);
- for (i = 0, ndata = 0; i < len; i++, ndata += 2)
- {
- strdesc->data[ndata] = str[i];
- strdesc->data[ndata+1] = 0;
- }
-
- strdesc->len = ndata+2;
- strdesc->type = USB_DESC_TYPE_STRING;
- return strdesc->len;
-}
-
-/****************************************************************************
- * Name: usbmsc_getepdesc
- *
- * Description:
- * Return a pointer to the raw device descriptor
- *
- ****************************************************************************/
-
-#ifndef CONFIG_USBMSC_COMPOSITE
-FAR const struct usb_devdesc_s *usbmsc_getdevdesc(void)
-{
- return &g_devdesc;
-}
-#endif
-
-/****************************************************************************
- * Name: usbmsc_getepdesc
- *
- * Description:
- * Return a pointer to the raw endpoint descriptor (used for configuring
- * endpoints)
- *
- ****************************************************************************/
-
-FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid)
-{
- switch (epid)
- {
- case USBMSC_EPFSBULKOUT: /* Full speed bulk OUT endpoint descriptor */
- return &g_fsepbulkoutdesc;
-
- case USBMSC_EPFSBULKIN: /* Full speed bulk IN endpoint descriptor */
- return &g_fsepbulkindesc;
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- case USBMSC_EPHSBULKOUT: /* High speed bulk OUT endpoint descriptor */
- return &g_hsepbulkoutdesc;
-
- case USBMSC_EPHSBULKIN: /* High speed bulk IN endpoint descriptor */
- return &g_hsepbulkindesc;
-#endif
- default:
- return NULL;
- }
-};
-
-/****************************************************************************
- * Name: usbmsc_mkcfgdesc
- *
- * Description:
- * Construct the configuration descriptor
- *
- ****************************************************************************/
-
-#ifdef CONFIG_USBDEV_DUALSPEED
-int16_t usbmsc_mkcfgdesc(uint8_t *buf, uint8_t speed, uint8_t type)
-#else
-int16_t usbmsc_mkcfgdesc(uint8_t *buf)
-#endif
-{
-#ifdef CONFIG_USBDEV_DUALSPEED
- FAR const struct usb_epdesc_s *epdesc;
- bool hispeed = (speed == USB_SPEED_HIGH);
- uint16_t bulkmxpacket;
-#endif
-
- /* Configuration descriptor. If the USB mass storage device is
- * configured as part of a composite device, then the configuration
- * descriptor will be provided by the composite device logic.
- */
-
-#ifndef CONFIG_USBMSC_COMPOSITE
- memcpy(buf, &g_cfgdesc, USB_SIZEOF_CFGDESC);
- buf += USB_SIZEOF_CFGDESC;
-#endif
-
- /* Copy the canned interface descriptor */
-
- memcpy(buf, &g_ifdesc, USB_SIZEOF_IFDESC);
- buf += USB_SIZEOF_IFDESC;
-
- /* Make the two endpoint configurations */
-
-#ifdef CONFIG_USBDEV_DUALSPEED
- /* Check for switches between high and full speed */
-
- hispeed = (speed == USB_SPEED_HIGH);
- if (type == USB_DESC_TYPE_OTHERSPEEDCONFIG)
- {
- hispeed = !hispeed;
- }
-
- bulkmxpacket = USBMSC_BULKMAXPACKET(hispeed);
- epdesc = USBMSC_EPBULKINDESC(hispeed);
- memcpy(buf, epdesc, USB_SIZEOF_EPDESC);
- buf += USB_SIZEOF_EPDESC;
-
- epdesc = USBMSC_EPBULKOUTDESC(hispeed);
- memcpy(buf, epdesc, USB_SIZEOF_EPDESC);
-#else
- memcpy(buf, &g_fsepbulkoutdesc, USB_SIZEOF_EPDESC);
- buf += USB_SIZEOF_EPDESC;
- memcpy(buf, &g_fsepbulkindesc, USB_SIZEOF_EPDESC);
-#endif
-
- return SIZEOF_USBMSC_CFGDESC;
-}
-
-/****************************************************************************
- * Name: usbmsc_getqualdesc
- *
- * Description:
- * Return a pointer to the raw qual descriptor
- *
- ****************************************************************************/
-
-#if !defined(CONFIG_USBMSC_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
-FAR const struct usb_qualdesc_s *usbmsc_getqualdesc(void)
-{
- return &g_qualdesc;
-}
-#endif
-
diff --git a/nuttx/drivers/usbdev/usbmsc_scsi.c b/nuttx/drivers/usbdev/usbmsc_scsi.c
deleted file mode 100644
index ccc967618..000000000
--- a/nuttx/drivers/usbdev/usbmsc_scsi.c
+++ /dev/null
@@ -1,2667 +0,0 @@
-/****************************************************************************
- * drivers/usbdev/usbmsc_scsi.c
- *
- * Copyright (C) 2008-2010, 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Mass storage class device. Bulk-only with SCSI subclass.
- *
- * References:
- * "Universal Serial Bus Mass Storage Class, Specification Overview,"
- * Revision 1.2, USB Implementer's Forum, June 23, 2003.
- *
- * "Universal Serial Bus Mass Storage Class, Bulk-Only Transport,"
- * Revision 1.0, USB Implementer's Forum, September 31, 1999.
- *
- * "SCSI Primary Commands - 3 (SPC-3)," American National Standard
- * for Information Technology, May 4, 2005
- *
- * "SCSI Primary Commands - 4 (SPC-4)," American National Standard
- * for Information Technology, July 19, 2008
- *
- * "SCSI Block Commands -2 (SBC-2)," American National Standard
- * for Information Technology, November 13, 2004
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <pthread.h>
-#include <string.h>
-#include <errno.h>
-#include <queue.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/scsi.h>
-#include <nuttx/usb/storage.h>
-#include <nuttx/usb/usbdev.h>
-#include <nuttx/usb/usbdev_trace.h>
-
-#include "usbmsc.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Configuration ************************************************************/
-
-/* Race condition workaround found by David Hewson. This race condition
- * "seems to relate to stalling the endpoint when a short response is
- * generated which causes a residue to exist when the CSW would be returned.
- * I think there's two issues here. The first being if the transfer which
- * had just been queued before the stall had not completed then it wouldn’t
- * then complete once the endpoint was stalled? The second is that the
- * subsequent transfer for the CSW would be dropped on the floor (by the
- * epsubmit() function) if the end point was still stalled as the control
- * transfer to resume it hadn't occurred."
- */
-
-#define CONFIG_USBMSC_RACEWAR 1
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Debug ********************************************************************/
-
-#if defined(CONFIG_DEBUG_VERBOSE) && defined (CONFIG_DEBUG_USB)
-static void usbmsc_dumpdata(const char *msg, const uint8_t *buf,
- int buflen);
-#else
-# define usbmsc_dumpdata(msg, buf, len)
-#endif
-
-/* Utility Support Functions ************************************************/
-
-static uint16_t usbmsc_getbe16(uint8_t *buf);
-static uint32_t usbmsc_getbe32(uint8_t *buf);
-static void usbmsc_putbe16(uint8_t * buf, uint16_t val);
-static void usbmsc_putbe24(uint8_t *buf, uint32_t val);
-static void usbmsc_putbe32(uint8_t *buf, uint32_t val);
-#if 0 /* not used */
-static uint16_t usbmsc_getle16(uint8_t *buf);
-#endif
-static uint32_t usbmsc_getle32(uint8_t *buf);
-#if 0 /* not used */
-static void usbmsc_putle16(uint8_t * buf, uint16_t val);
-#endif
-static void usbmsc_putle32(uint8_t *buf, uint32_t val);
-
-/* SCSI Command Processing **************************************************/
-
-static inline int usbmsc_cmdtestunitready(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdrequestsense(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf);
-static inline int usbmsc_cmdread6(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdwrite6(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdinquiry(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf);
-static inline int usbmsc_cmdmodeselect6(FAR struct usbmsc_dev_s *priv);
-static int usbmsc_modepage(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf, uint8_t pcpgcode, int *mdlen);
-static inline int usbmsc_cmdmodesense6(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf);
-static inline int usbmsc_cmdstartstopunit(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdpreventmediumremoval(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdreadformatcapacity(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf);
-static inline int usbmsc_cmdreadcapacity10(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf);
-static inline int usbmsc_cmdread10(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdwrite10(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdverify10(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdsynchronizecache10(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdmodeselect10(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdmodesense10(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf);
-static inline int usbmsc_cmdread12(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_cmdwrite12(FAR struct usbmsc_dev_s *priv);
-static inline int usbmsc_setupcmd(FAR struct usbmsc_dev_s *priv,
- uint8_t cdblen, uint8_t flags);
-
-/* SCSI Worker Thread *******************************************************/
-
-static int usbmsc_idlestate(FAR struct usbmsc_dev_s *priv);
-static int usbmsc_cmdparsestate(FAR struct usbmsc_dev_s *priv);
-static int usbmsc_cmdreadstate(FAR struct usbmsc_dev_s *priv);
-static int usbmsc_cmdwritestate(FAR struct usbmsc_dev_s *priv);
-static int usbmsc_cmdfinishstate(FAR struct usbmsc_dev_s *priv);
-static int usbmsc_cmdstatusstate(FAR struct usbmsc_dev_s *priv);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Debug
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbmsc_dumpdata
- ****************************************************************************/
-
-#if defined(CONFIG_DEBUG_VERBOSE) && defined (CONFIG_DEBUG_USB)
-static void usbmsc_dumpdata(const char *msg, const uint8_t *buf, int buflen)
-{
- int i;
-
- dbgprintf("%s:", msg);
- for (i = 0; i < buflen; i++)
- {
- dbgprintf(" %02x", buf[i]);
- }
- dbgprintf("\n");
-}
-#endif
-
-/****************************************************************************
- * Utility Support Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbmsc_getbe16
- *
- * Description:
- * Get a 16-bit big-endian value reference by the byte pointer
- *
- ****************************************************************************/
-
-static uint16_t usbmsc_getbe16(uint8_t *buf)
-{
- return ((uint16_t)buf[0] << 8) | ((uint16_t)buf[1]);
-}
-
-/****************************************************************************
- * Name: usbmsc_getbe32
- *
- * Description:
- * Get a 32-bit big-endian value reference by the byte pointer
- *
- ****************************************************************************/
-
-static uint32_t usbmsc_getbe32(uint8_t *buf)
-{
- return ((uint32_t)buf[0] << 24) | ((uint32_t)buf[1] << 16) |
- ((uint32_t)buf[2] << 8) | ((uint32_t)buf[3]);
-}
-
-/****************************************************************************
- * Name: usbmsc_putbe16
- *
- * Description:
- * Store a 16-bit value in big-endian order to the location specified by
- * a byte pointer
- *
- ****************************************************************************/
-
-static void usbmsc_putbe16(uint8_t * buf, uint16_t val)
-{
- buf[0] = val >> 8;
- buf[1] = val;
-}
-
-/****************************************************************************
- * Name: usbmsc_putbe24
- *
- * Description:
- * Store a 32-bit value in big-endian order to the location specified by
- * a byte pointer
- *
- ****************************************************************************/
-
-static void usbmsc_putbe24(uint8_t *buf, uint32_t val)
-{
- buf[0] = val >> 16;
- buf[1] = val >> 8;
- buf[2] = val;
-}
-
-/****************************************************************************
- * Name: usbmsc_putbe32
- *
- * Description:
- * Store a 32-bit value in big-endian order to the location specified by
- * a byte pointer
- *
- ****************************************************************************/
-
-static void usbmsc_putbe32(uint8_t *buf, uint32_t val)
-{
- buf[0] = val >> 24;
- buf[1] = val >> 16;
- buf[2] = val >> 8;
- buf[3] = val;
-}
-
-/****************************************************************************
- * Name: usbmsc_getle16
- *
- * Description:
- * Get a 16-bit little-endian value reference by the byte pointer
- *
- ****************************************************************************/
-
-#if 0 /* not used */
-static uint16_t usbmsc_getle16(uint8_t *buf)
-{
- return ((uint16_t)buf[1] << 8) | ((uint16_t)buf[0]);
-}
-#endif
-
-/****************************************************************************
- * Name: usbmsc_getle32
- *
- * Description:
- * Get a 32-bit little-endian value reference by the byte pointer
- *
- ****************************************************************************/
-
-static uint32_t usbmsc_getle32(uint8_t *buf)
-{
- return ((uint32_t)buf[3] << 24) | ((uint32_t)buf[2] << 16) |
- ((uint32_t)buf[1] << 8) | ((uint32_t)buf[0]);
-}
-
-/****************************************************************************
- * Name: usbmsc_putle16
- *
- * Description:
- * Store a 16-bit value in little-endian order to the location specified by
- * a byte pointer
- *
- ****************************************************************************/
-
-#if 0 /* not used */
-static void usbmsc_putle16(uint8_t * buf, uint16_t val)
-{
- buf[0] = val;
- buf[1] = val >> 8;
-}
-#endif
-
-/****************************************************************************
- * Name: usbmsc_putle32
- *
- * Description:
- * Store a 32-bit value in little-endian order to the location specified by
- * a byte pointer
- *
- ****************************************************************************/
-
-static void usbmsc_putle32(uint8_t *buf, uint32_t val)
-{
- buf[0] = val;
- buf[1] = val >> 8;
- buf[2] = val >> 16;
- buf[3] = val >> 24;
-}
-
-/****************************************************************************
- * SCSI Worker Thread
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbmsc_cmdtestunitready
- *
- * Description:
- * Handle the SCSI_CMD_TESTUNITREADY command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdtestunitready(FAR struct usbmsc_dev_s *priv)
-{
- int ret;
-
- priv->u.alloclen = 0;
- ret = usbmsc_setupcmd(priv, 6, USBMSC_FLAGS_DIRNONE);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdrequestsense
- *
- * Description:
- * Handle the SCSI_CMD_REQUESTSENSE command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdrequestsense(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf)
-{
- FAR struct scsicmd_requestsense_s *request = (FAR struct scsicmd_requestsense_s *)priv->cdb;
- FAR struct scsiresp_fixedsensedata_s *response = (FAR struct scsiresp_fixedsensedata_s *)buf;
- FAR struct usbmsc_lun_s *lun;
- uint32_t sd;
- uint32_t sdinfo;
- uint8_t cdblen;
- int ret;
-
- /* Extract the host allocation length */
-
- priv->u.alloclen = request->alloclen;
-
- /* Get the expected length of the command (with hack for MS-Windows 12-byte
- * REQUEST SENSE command.
- */
-
- cdblen = SCSICMD_REQUESTSENSE_SIZEOF;
- if (cdblen != priv->cdblen)
- {
- /* Try MS-Windows REQUEST SENSE with cbw->cdblen == 12 */
-
- cdblen = SCSICMD_REQUESTSENSE_MSSIZEOF;
- }
-
- ret = usbmsc_setupcmd(priv, cdblen,
- USBMSC_FLAGS_DIRDEVICE2HOST|USBMSC_FLAGS_LUNNOTNEEDED|
- USBMSC_FLAGS_UACOKAY|USBMSC_FLAGS_RETAINSENSEDATA);
- if (ret == OK)
- {
- lun = priv->lun;
- if (!lun)
- {
- sd = SCSI_KCQIR_INVALIDLUN;
- sdinfo = 0;
- }
- else
- {
- /* Get the saved sense data from the LUN structure */
-
- sd = lun->sd;
- sdinfo = lun->sdinfo;
-
- /* Discard the sense data */
-
- lun->sd = SCSI_KCQ_NOSENSE;
- lun->sdinfo = 0;
- }
-
- /* Create the fixed sense data response */
-
- memset(response, 0, SCSIRESP_FIXEDSENSEDATA_SIZEOF);
-
- response->code = SCSIRESP_SENSEDATA_RESPVALID|SCSIRESP_SENSEDATA_CURRENTFIXED;
- response->flags = (uint8_t)(sd >> 16);
- usbmsc_putbe32(response->info, sdinfo);
- response->len = SCSIRESP_FIXEDSENSEDATA_SIZEOF - 7;
- response->code2 = (uint8_t)(sd >> 8);
- response->qual2 = (uint8_t)sd;
-
- priv->nreqbytes = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
- ret = OK;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdread6
- *
- * Description:
- * Handle the SCSI_CMD_READ6 command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdread6(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct scsicmd_read6_s *read6 = (FAR struct scsicmd_read6_s*)priv->cdb;
- FAR struct usbmsc_lun_s *lun = priv->lun;
- int ret;
-
- priv->u.xfrlen = (uint16_t)read6->xfrlen;
- if (priv->u.xfrlen == 0)
- {
- priv->u.xfrlen = 256;
- }
-
- ret = usbmsc_setupcmd(priv, SCSICMD_READ6_SIZEOF, USBMSC_FLAGS_DIRDEVICE2HOST|USBMSC_FLAGS_BLOCKXFR);
- if (ret == OK)
- {
- /* Get the Logical Block Address (LBA) from cdb[] as the starting sector */
-
- priv->sector = (uint32_t)(read6->mslba & SCSICMD_READ6_MSLBAMASK) << 16 | (uint32_t)usbmsc_getbe16(read6->lslba);
-
- /* Verify that a block driver has been bound to the LUN */
-
- if (!lun->inode)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ6MEDIANOTPRESENT), 0);
- lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
- ret = -EINVAL;
- }
-
- /* Verify that sector lies in the range supported by the block driver */
-
- else if (priv->sector >= lun->nsectors)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ6LBARANGE), 0);
- lun->sd = SCSI_KCQIR_LBAOUTOFRANGE;
- ret = -EINVAL;
- }
-
- /* Looks like we are good to go */
-
- else
- {
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDPARSECMDREAD6), priv->cdb[0]);
- priv->thstate = USBMSC_STATE_CMDREAD;
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdwrite6
- *
- * Description:
- * Handle the SCSI_CMD_WRITE6 command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdwrite6(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct scsicmd_write6_s *write6 = (FAR struct scsicmd_write6_s *)priv->cdb;
- FAR struct usbmsc_lun_s *lun = priv->lun;
- int ret;
-
- priv->u.xfrlen = (uint16_t)write6->xfrlen;
- if (priv->u.xfrlen == 0)
- {
- priv->u.xfrlen = 256;
- }
-
- ret = usbmsc_setupcmd(priv, SCSICMD_WRITE6_SIZEOF, USBMSC_FLAGS_DIRHOST2DEVICE|USBMSC_FLAGS_BLOCKXFR);
- if (ret == OK)
- {
- /* Get the Logical Block Address (LBA) from cdb[] as the starting sector */
-
- priv->sector = (uint32_t)(write6->mslba & SCSICMD_WRITE6_MSLBAMASK) << 16 | (uint32_t)usbmsc_getbe16(write6->lslba);
-
- /* Verify that a block driver has been bound to the LUN */
-
- if (!lun->inode)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE6MEDIANOTPRESENT), 0);
- lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
- ret = -EINVAL;
- }
-
- /* Check for attempts to write to a read-only device */
-
- else if (lun->readonly)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE6READONLY), 0);
- lun->sd = SCSI_KCQWP_COMMANDNOTALLOWED;
- ret = -EINVAL;
- }
-
- /* Verify that sector lies in the range supported by the block driver */
-
- else if (priv->sector >= lun->nsectors)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE6LBARANGE), 0);
- lun->sd = SCSI_KCQIR_LBAOUTOFRANGE;
- ret = -EINVAL;
- }
-
- /* Looks like we are good to go */
-
- else
- {
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDPARSECMDWRITE6), priv->cdb[0]);
- priv->thstate = USBMSC_STATE_CMDWRITE;
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdinquiry
- *
- * Description:
- * Handle SCSI_CMD_INQUIRY command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdinquiry(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf)
-{
- FAR struct scscicmd_inquiry_s *inquiry = (FAR struct scscicmd_inquiry_s *)priv->cdb;
- FAR struct scsiresp_inquiry_s *response = (FAR struct scsiresp_inquiry_s *)buf;
- int len;
- int ret;
-
- priv->u.alloclen = usbmsc_getbe16(inquiry->alloclen);
- ret = usbmsc_setupcmd(priv, SCSICMD_INQUIRY_SIZEOF,
- USBMSC_FLAGS_DIRDEVICE2HOST|USBMSC_FLAGS_LUNNOTNEEDED|USBMSC_FLAGS_UACOKAY);
- if (ret == OK)
- {
- if (!priv->lun)
- {
- response->qualtype = SCSIRESP_INQUIRYPQ_NOTCAPABLE|SCSIRESP_INQUIRYPD_UNKNOWN;
- }
- else if ((inquiry->flags != 0) || (inquiry->pagecode != 0))
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INQUIRYFLAGS), 0);
- priv->lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- ret = -EINVAL;
- }
- else
- {
- memset(response, 0, SCSIRESP_INQUIRY_SIZEOF);
- priv->nreqbytes = SCSIRESP_INQUIRY_SIZEOF;
-
-#ifdef CONFIG_USBMSC_REMOVABLE
- response->flags1 = SCSIRESP_INQUIRYFLAGS1_RMB;
-#endif
- response->version = 2; /* SCSI-2 */
- response->flags2 = 2; /* SCSI-2 INQUIRY response data format */
- response->len = SCSIRESP_INQUIRY_SIZEOF - 5;
-
- /* Strings */
-
- memset(response->vendorid, ' ', 8+16+4);
-
- len = strlen(g_mscvendorstr);
- DEBUGASSERT(len <= 8);
- memcpy(response->vendorid, g_mscvendorstr, len);
-
- len = strlen(g_mscproductstr);
- DEBUGASSERT(len <= 16);
- memcpy(response->productid, g_mscproductstr, len);
-
- len = strlen(g_mscserialstr);
- DEBUGASSERT(len <= 4);
- memcpy(response->revision, g_mscserialstr, len);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdmodeselect6
- *
- * Description:
- * Handle SCSI_CMD_MODESELECT6 command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdmodeselect6(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct scsicmd_modeselect6_s *modeselect = (FAR struct scsicmd_modeselect6_s *)priv->cdb;
-
- priv->u.alloclen = modeselect->plen;
- (void)usbmsc_setupcmd(priv, SCSICMD_MODESELECT6_SIZEOF, USBMSC_FLAGS_DIRHOST2DEVICE);
-
- /* Not supported */
-
- priv->lun->sd = SCSI_KCQIR_INVALIDCOMMAND;
- return -EINVAL;
-}
-
-/****************************************************************************
- * Name: usbmsc_modepage
- *
- * Description:
- * Common logic for usbmsc_cmdmodesense6() and usbmsc_cmdmodesense10()
- *
- ****************************************************************************/
-
-static int usbmsc_modepage(FAR struct usbmsc_dev_s *priv, FAR uint8_t *buf,
- uint8_t pcpgcode, int *mdlen)
-{
- FAR struct scsiresp_cachingmodepage_s *cmp = (FAR struct scsiresp_cachingmodepage_s *)buf;
-
- /* Saving parms not supported */
-
- if ((pcpgcode & SCSICMD_MODESENSE_PCMASK) == SCSICMD_MODESENSE_PCSAVED)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_PCSAVED), 0);
- priv->lun->sd = SCSI_KCQIR_SAVINGPARMSNOTSUPPORTED;
- return -EINVAL;
- }
-
- /* Only the caching mode page is supported: */
-
- if ((pcpgcode & SCSICMD_MODESENSE_PGCODEMASK) == SCSIRESP_MODESENSE_PGCCODE_CACHING ||
- (pcpgcode & SCSICMD_MODESENSE_PGCODEMASK) == SCSIRESP_MODESENSE_PGCCODE_RETURNALL)
- {
- memset(cmp, 0, 12);
- cmp->pgcode = SCSIRESP_MODESENSE_PGCCODE_CACHING;
- cmp->len = 10; /* n-2 */
-
- /* None of the fields are changeable */
-
- if (((pcpgcode & SCSICMD_MODESENSE_PCMASK) != SCSICMD_MODESENSE_PCCHANGEABLE))
- {
- cmp->flags1 = SCSIRESP_CACHINGMODEPG_WCE; /* Write cache enable */
- cmp->dpflen[0] = 0xff; /* Disable prefetch transfer length = 0xffffffff */
- cmp->dpflen[1] = 0xff;
- cmp->maxpf[0] = 0xff; /* Maximum pre-fetch = 0xffffffff */
- cmp->maxpf[1] = 0xff;
- cmp->maxpfc[0] = 0xff; /* Maximum pref-fetch ceiling = 0xffffffff */
- cmp->maxpfc[1] = 0xff;
- }
-
- /* Return the mode data length */
-
- *mdlen = 12; /* Only the first 12-bytes of caching mode page sent */
- return OK;
- }
- else
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_MODEPAGEFLAGS), pcpgcode);
- priv->lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- return -EINVAL;
- }
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdmodesense6
- *
- * Description:
- * Handle SCSI_CMD_MODESENSE6 command
- *
- ****************************************************************************/
-
-static int inline usbmsc_cmdmodesense6(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf)
-{
- FAR struct scsicmd_modesense6_s *modesense = (FAR struct scsicmd_modesense6_s *)priv->cdb;
- FAR struct scsiresp_modeparameterhdr6_s *mph = (FAR struct scsiresp_modeparameterhdr6_s *)buf;
- int mdlen;
- int ret;
-
- priv->u.alloclen = modesense->alloclen;
- ret = usbmsc_setupcmd(priv, SCSICMD_MODESENSE6_SIZEOF, USBMSC_FLAGS_DIRDEVICE2HOST);
- if (ret == OK)
- {
- if ((modesense->flags & ~SCSICMD_MODESENSE6_DBD) != 0 || modesense->subpgcode != 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_MODESENSE6FLAGS), 0);
- priv->lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- ret = -EINVAL;
- }
- else
- {
- /* The response consists of:
- *
- * (1) A MODESENSE6-specific mode parameter header,
- * (2) A variable length list of block descriptors, and
- * (3) A variable length list of mode page formats
- */
-
- mph->type = 0; /* Medium type */
- mph->param = (priv->lun->readonly ? SCSIRESP_MODEPARMHDR_DAPARM_WP : 0x00);
- mph->bdlen = 0; /* Block descriptor length */
-
- /* There are no block descriptors, only the following mode page: */
-
- ret = usbmsc_modepage(priv, &buf[SCSIRESP_MODEPARAMETERHDR6_SIZEOF], modesense->pcpgcode, &mdlen);
- if (ret == OK)
- {
- /* Store the mode data length and return the total message size */
-
- mph->mdlen = mdlen - 1;
- priv->nreqbytes = mdlen + SCSIRESP_MODEPARAMETERHDR6_SIZEOF;
- }
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdstartstopunit
- *
- * Description:
- * Handle SCSI_CMD_STARTSTOPUNIT command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdstartstopunit(FAR struct usbmsc_dev_s *priv)
-{
- int ret;
-
- priv->u.alloclen = 0;
- ret = usbmsc_setupcmd(priv, SCSICMD_STARTSTOPUNIT_SIZEOF, USBMSC_FLAGS_DIRNONE);
- if (ret == OK)
- {
-#ifndef CONFIG_USBMSC_REMOVABLE
- /* This command is not valid if the media is not removable */
-
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_NOTREMOVABLE), 0);
- lun->sd = SCSI_KCQIR_INVALIDCOMMAND;
- ret = -EINVAL;
-#endif
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdpreventmediumremoval
- *
- * Description:
- * Handle SCSI_CMD_PREVENTMEDIAREMOVAL command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdpreventmediumremoval(FAR struct usbmsc_dev_s *priv)
-{
-#ifdef CONFIG_USBMSC_REMOVABLE
- FAR struct scsicmd_preventmediumremoval_s *pmr = (FAR struct scsicmd_preventmediumremoval_s *)priv->cdb;
- FAR struct usbmsc_lun_s *lun = priv->lun;
-#endif
- int ret;
-
- priv->u.alloclen = 0;
- ret = usbmsc_setupcmd(priv, SCSICMD_PREVENTMEDIUMREMOVAL_SIZEOF, USBMSC_FLAGS_DIRNONE);
- if (ret == OK)
- {
-#ifndef CONFIG_USBMSC_REMOVABLE
- lun->sd = SCSI_KCQIR_INVALIDCOMMAND;
- ret = -EINVAL;
-#else
- if ((pmr->prevent & ~SCSICMD_PREVENTMEDIUMREMOVAL_TRANSPORT) != 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_PREVENTMEDIUMREMOVALPREVENT), 0);
- lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- ret = -EINVAL;
- }
-
- lun->locked = pmr->prevent & SCSICMD_PREVENTMEDIUMREMOVAL_TRANSPORT;
-#endif
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdreadformatcapacity
- *
- * Description:
- * Handle SCSI_CMD_READFORMATCAPACITIES command (MMC)
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdreadformatcapacity(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf)
-{
- FAR struct scsicmd_readformatcapcacities_s *rfc = (FAR struct scsicmd_readformatcapcacities_s *)priv->cdb;
- FAR struct scsiresp_readformatcapacities_s *hdr;
- FAR struct usbmsc_lun_s *lun = priv->lun;
- int ret;
-
- priv->u.alloclen = usbmsc_getbe16(rfc->alloclen);
- ret = usbmsc_setupcmd(priv, SCSICMD_READFORMATCAPACITIES_SIZEOF, USBMSC_FLAGS_DIRDEVICE2HOST);
- if (ret == OK)
- {
- hdr = (FAR struct scsiresp_readformatcapacities_s *)buf;
- memset(hdr, 0, SCSIRESP_READFORMATCAPACITIES_SIZEOF);
- hdr->listlen = SCSIRESP_CURRCAPACITYDESC_SIZEOF;
-
- /* Only the Current/Maximum Capacity Descriptor follows the header */
-
- usbmsc_putbe32(hdr->nblocks, lun->nsectors);
- hdr->type = SCIRESP_RDFMTCAPACITIES_FORMATED;
- usbmsc_putbe24(hdr->blocklen, lun->sectorsize);
- priv->nreqbytes = SCSIRESP_READFORMATCAPACITIES_SIZEOF;
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdreadcapacity10
- *
- * Description:
- * Handle SCSI_CMD_READCAPACITY10 command
- *
- ****************************************************************************/
-
-static int inline usbmsc_cmdreadcapacity10(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf)
-{
- FAR struct scsicmd_readcapacity10_s *rcc = (FAR struct scsicmd_readcapacity10_s *)priv->cdb;
- FAR struct scsiresp_readcapacity10_s *rcr = (FAR struct scsiresp_readcapacity10_s *)buf;
- FAR struct usbmsc_lun_s *lun = priv->lun;
- uint32_t lba;
- int ret;
-
- priv->u.alloclen = SCSIRESP_READCAPACITY10_SIZEOF; /* Fake the allocation length */
- ret = usbmsc_setupcmd(priv, SCSICMD_READCAPACITY10_SIZEOF, USBMSC_FLAGS_DIRDEVICE2HOST);
- if (ret == OK)
- {
- /* Check the PMI and LBA fields */
-
- lba = usbmsc_getbe32(rcc->lba);
-
- if (rcc->pmi > 1 || (rcc->pmi == 0 && lba != 0))
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READCAPACITYFLAGS), 0);
- lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- ret = -EINVAL;
- }
- else
- {
- usbmsc_putbe32(rcr->lba, lun->nsectors - 1);
- usbmsc_putbe32(&buf[4], lun->sectorsize);
- priv->nreqbytes = SCSIRESP_READCAPACITY10_SIZEOF;
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdread10
- *
- * Description:
- * Handle SCSI_CMD_READ10 command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdread10(FAR struct usbmsc_dev_s *priv)
-{
- struct scsicmd_read10_s *read10 = (struct scsicmd_read10_s*)priv->cdb;
- FAR struct usbmsc_lun_s *lun = priv->lun;
- int ret;
-
- priv->u.xfrlen = usbmsc_getbe16(read10->xfrlen);
- ret = usbmsc_setupcmd(priv, SCSICMD_READ10_SIZEOF, USBMSC_FLAGS_DIRDEVICE2HOST|USBMSC_FLAGS_BLOCKXFR);
- if (ret == OK)
- {
- /* Get the Logical Block Address (LBA) from cdb[] as the starting sector */
-
- priv->sector = usbmsc_getbe32(read10->lba);
-
- /* Verify that we can support this read command */
-
- if ((read10->flags & ~(SCSICMD_READ10FLAGS_DPO|SCSICMD_READ10FLAGS_FUA)) != 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ10FLAGS), 0);
- lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- ret = -EINVAL;
- }
-
- /* Verify that a block driver has been bound to the LUN */
-
- else if (!lun->inode)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ10MEDIANOTPRESENT), 0);
- lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
- ret = -EINVAL;
- }
-
- /* Verify that LBA lies in the range supported by the block driver */
-
- else if (priv->sector >= lun->nsectors)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ10LBARANGE), 0);
- lun->sd = SCSI_KCQIR_LBAOUTOFRANGE;
- ret = -EINVAL;
- }
-
- /* Looks like we are good to go */
-
- else
- {
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDPARSECMDREAD10), priv->cdb[0]);
- priv->thstate = USBMSC_STATE_CMDREAD;
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdwrite10
- *
- * Description:
- * Handle SCSI_CMD_WRITE10 command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdwrite10(FAR struct usbmsc_dev_s *priv)
-{
- struct scsicmd_write10_s *write10 = (struct scsicmd_write10_s *)priv->cdb;
- FAR struct usbmsc_lun_s *lun = priv->lun;
- int ret;
-
- priv->u.xfrlen = usbmsc_getbe16(write10->xfrlen);
- ret = usbmsc_setupcmd(priv, SCSICMD_WRITE10_SIZEOF, USBMSC_FLAGS_DIRHOST2DEVICE|USBMSC_FLAGS_BLOCKXFR);
- if (ret == OK)
- {
- /* Get the Logical Block Address (LBA) from cdb[] as the starting sector */
-
- priv->sector = usbmsc_getbe32(write10->lba);
-
- /* Verify that we can support this write command */
-
- if ((write10->flags & ~(SCSICMD_WRITE10FLAGS_DPO|SCSICMD_WRITE10FLAGS_FUA)) != 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE10FLAGS), 0);
- lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- ret = -EINVAL;
- }
-
- /* Verify that a block driver has been bound to the LUN */
-
- else if (!lun->inode)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE10MEDIANOTPRESENT), 0);
- lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
- ret = -EINVAL;
- }
-
- /* Check for attempts to write to a read-only device */
-
- else if (lun->readonly)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE10READONLY), 0);
- lun->sd = SCSI_KCQWP_COMMANDNOTALLOWED;
- ret = -EINVAL;
- }
-
- /* Verify that LBA lies in the range supported by the block driver */
-
- else if (priv->sector >= lun->nsectors)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE10LBARANGE), 0);
- lun->sd = SCSI_KCQIR_LBAOUTOFRANGE;
- ret = -EINVAL;
- }
-
- /* Looks like we are good to go */
-
- else
- {
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDPARSECMDWRITE10), priv->cdb[0]);
- priv->thstate = USBMSC_STATE_CMDWRITE;
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdverify10
- *
- * Description:
- * Handle SCSI_CMD_VERIFY10 command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdverify10(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct scsicmd_verify10_s *verf = (FAR struct scsicmd_verify10_s *)priv->cdb;
- FAR struct usbmsc_lun_s *lun = priv->lun;
- uint32_t lba;
- uint16_t blocks;
- size_t sector;
- ssize_t nread;
- int ret;
- int i;
-
- priv->u.alloclen = 0;
- ret = usbmsc_setupcmd(priv, SCSICMD_VERIFY10_SIZEOF, USBMSC_FLAGS_DIRNONE);
- if (ret == OK)
- {
- /* Verify the starting and ending LBA */
-
- lba = usbmsc_getbe32(verf->lba);
- blocks = usbmsc_getbe16(verf->len);
-
- if ((verf->flags & ~SCSICMD_VERIFY10_DPO) != 0 || verf->groupno != 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_VERIFY10FLAGS), 0);
- lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- ret = -EINVAL;
- }
- else if (blocks == 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_VERIFY10NOBLOCKS), 0);
- ret = -EIO; /* No reply */
- }
-
- /* Verify that a block driver has been bound to the LUN */
-
- else if (!lun->inode)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_VERIFY10MEDIANOTPRESENT), 0);
- lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
- ret = -EINVAL;
- }
-
- /* Verify that LBA lies in the range supported by the block driver */
-
- else if (lba >= lun->nsectors || lba + blocks > lun->nsectors)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_VERIFY10LBARANGE), 0);
- lun->sd = SCSI_KCQIR_LBAOUTOFRANGE;
- ret = -EINVAL;
- }
- else
- {
- /* Try to read the requested blocks */
-
- for (i = 0, sector = lba + lun->startsector; i < blocks; i++, sector++)
- {
- nread = USBMSC_DRVR_READ(lun, priv->iobuffer, sector, 1);
- if (nread < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_VERIFY10READFAIL), i);
- lun->sd = SCSI_KCQME_UNRRE1;
- lun->sdinfo = sector;
- ret = -EIO;
- break;
- }
- }
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdsynchronizecache10
- *
- * Description:
- * Handle SCSI_CMD_SYNCHCACHE10 command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdsynchronizecache10(FAR struct usbmsc_dev_s *priv)
-{
- int ret;
-
- priv->u.alloclen = 0;
-
- /* Verify that we have the LUN structure and the block driver has been bound */
-
- if (!priv->lun->inode)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SYNCCACHEMEDIANOTPRESENT), 0);
- priv->lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
- ret = -EINVAL;
- }
- else
- {
- ret = usbmsc_setupcmd(priv, SCSICMD_SYNCHRONIZECACHE10_SIZEOF, USBMSC_FLAGS_DIRNONE);
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdmodeselect10
- *
- * Description:
- * Handle SCSI_CMD_MODESELECT10 command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdmodeselect10(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct scsicmd_modeselect10_s *modeselect = (FAR struct scsicmd_modeselect10_s *)priv->cdb;
-
- priv->u.alloclen = usbmsc_getbe16(modeselect->parmlen);
- (void)usbmsc_setupcmd(priv, SCSICMD_MODESELECT10_SIZEOF, USBMSC_FLAGS_DIRHOST2DEVICE);
-
- /* Not supported */
-
- priv->lun->sd = SCSI_KCQIR_INVALIDCOMMAND;
- return -EINVAL;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdmodesense10
- *
- * Description:
- * Handle SCSI_CMD_MODESENSE10 command
- *
- ****************************************************************************/
-
-static int inline usbmsc_cmdmodesense10(FAR struct usbmsc_dev_s *priv,
- FAR uint8_t *buf)
-{
- FAR struct scsicmd_modesense10_s *modesense = (FAR struct scsicmd_modesense10_s *)priv->cdb;
- FAR struct scsiresp_modeparameterhdr10_s *mph = (FAR struct scsiresp_modeparameterhdr10_s *)buf;
- int mdlen;
- int ret;
-
- priv->u.alloclen = usbmsc_getbe16(modesense->alloclen);
- ret = usbmsc_setupcmd(priv, SCSICMD_MODESENSE10_SIZEOF, USBMSC_FLAGS_DIRDEVICE2HOST);
- if (ret == OK)
- {
- if ((modesense->flags & ~SCSICMD_MODESENSE10_DBD) != 0 || modesense->subpgcode != 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_MODESENSE10FLAGS), 0);
- priv->lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- ret = -EINVAL;
- }
- else
- {
- /* The response consists of:
- *
- * (1) A MODESENSE6-specific mode parameter header,
- * (2) A variable length list of block descriptors, and
- * (3) A variable lengtth list of mode page formats
- */
-
- memset(mph, 0, SCSIRESP_MODEPARAMETERHDR10_SIZEOF);
- mph->param = (priv->lun->readonly ? SCSIRESP_MODEPARMHDR_DAPARM_WP : 0x00);
-
- /* There are no block descriptors, only the following mode page: */
-
- ret = usbmsc_modepage(priv, &buf[SCSIRESP_MODEPARAMETERHDR10_SIZEOF], modesense->pcpgcode, &mdlen);
- if (ret == OK)
- {
- /* Store the mode data length and return the total message size */
-
- usbmsc_putbe16(mph->mdlen, mdlen - 2);
- priv->nreqbytes = mdlen + SCSIRESP_MODEPARAMETERHDR10_SIZEOF;
- }
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdread12
- *
- * Description:
- * Handle SCSI_CMD_READ12 command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdread12(FAR struct usbmsc_dev_s *priv)
-{
- struct scsicmd_read12_s *read12 = (struct scsicmd_read12_s*)priv->cdb;
- FAR struct usbmsc_lun_s *lun = priv->lun;
- int ret;
-
- priv->u.xfrlen = usbmsc_getbe32(read12->xfrlen);
- ret = usbmsc_setupcmd(priv, SCSICMD_READ12_SIZEOF, USBMSC_FLAGS_DIRDEVICE2HOST|USBMSC_FLAGS_BLOCKXFR);
- if (ret == OK)
- {
- /* Get the Logical Block Address (LBA) from cdb[] as the starting sector */
-
- priv->sector = usbmsc_getbe32(read12->lba);
-
- /* Verify that we can support this read command */
-
- if ((read12->flags & ~(SCSICMD_READ12FLAGS_DPO|SCSICMD_READ12FLAGS_FUA)) != 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ12FLAGS), 0);
- lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- ret = -EINVAL;
- }
-
- /* Verify that a block driver has been bound to the LUN */
-
- else if (!lun->inode)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ12MEDIANOTPRESENT), 0);
- lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
- ret = -EINVAL;
- }
-
- /* Verify that LBA lies in the range supported by the block driver */
-
- else if (priv->sector >= lun->nsectors)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_READ12LBARANGE), 0);
- lun->sd = SCSI_KCQIR_LBAOUTOFRANGE;
- ret = -EINVAL;
- }
-
- /* Looks like we are good to go */
-
- else
- {
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDPARSECMDREAD12), priv->cdb[0]);
- priv->thstate = USBMSC_STATE_CMDREAD;
- }
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdwrite12
- *
- * Description:
- * Handle SCSI_CMD_WRITE12 command
- *
- ****************************************************************************/
-
-static inline int usbmsc_cmdwrite12(FAR struct usbmsc_dev_s *priv)
-{
- struct scsicmd_write12_s *write12 = (struct scsicmd_write12_s *)priv->cdb;
- FAR struct usbmsc_lun_s *lun = priv->lun;
- int ret;
-
- priv->u.xfrlen = usbmsc_getbe32(write12->xfrlen);
- ret = usbmsc_setupcmd(priv, SCSICMD_WRITE12_SIZEOF, USBMSC_FLAGS_DIRHOST2DEVICE|USBMSC_FLAGS_BLOCKXFR);
- if (ret == OK)
- {
- /* Get the Logical Block Address (LBA) from cdb[] as the starting sector */
-
- priv->sector = usbmsc_getbe32(write12->lba);
-
- /* Verify that we can support this write command */
-
- if ((write12->flags & ~(SCSICMD_WRITE12FLAGS_DPO|SCSICMD_WRITE12FLAGS_FUA)) != 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE12FLAGS), 0);
- lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- }
-
- /* Verify that a block driver has been bound to the LUN */
-
- else if (!lun->inode)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE12MEDIANOTPRESENT), 0);
- lun->sd = SCSI_KCQNR_MEDIANOTPRESENT;
- ret = -EINVAL;
- }
-
- /* Check for attempts to write to a read-only device */
-
- else if (lun->readonly)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE12READONLY), 0);
- lun->sd = SCSI_KCQWP_COMMANDNOTALLOWED;
- }
-
- /* Verify that LBA lies in the range supported by the block driver */
-
- else if (priv->sector >= lun->nsectors)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_WRITE12LBARANGE), 0);
- lun->sd = SCSI_KCQIR_LBAOUTOFRANGE;
- }
-
- /* Looks like we are good to go */
-
- else
- {
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDPARSECMDWRITE12), priv->cdb[0]);
- priv->thstate = USBMSC_STATE_CMDWRITE;
- return OK;
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_setupcmd
- *
- * Description:
- * Called after each SCSI command is identified in order to perform setup
- * and verification operations that are common to all SCSI commands. This
- * function performs the following common setup operations:
- *
- * 1. Determine the direction of the response
- * 2. Verify lengths
- * 3. Setup and verify the LUN
- *
- * Includes special logic for INQUIRY and REQUESTSENSE commands
- *
- ****************************************************************************/
-
-static int inline usbmsc_setupcmd(FAR struct usbmsc_dev_s *priv, uint8_t cdblen, uint8_t flags)
-{
- FAR struct usbmsc_lun_s *lun = NULL;
- uint32_t datlen;
- uint8_t dir = flags & USBMSC_FLAGS_DIRMASK;
- int ret = OK;
-
- /* Verify the LUN and set up the current LUN reference in the
- * device structure
- */
-
- if (priv->cbwlun < priv->nluns)
- {
- /* LUN number is valid in a valid range, but the LUN is not necessarily
- * bound to a block driver. That will be checked as necessary in each
- * individual command.
- */
-
- lun = &priv->luntab[priv->cbwlun];
- priv->lun = lun;
- }
-
- /* Only a few commands may specify unsupported LUNs */
-
- else if ((flags & USBMSC_FLAGS_LUNNOTNEEDED) == 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDBADLUN), priv->cbwlun);
- ret = -EINVAL;
- }
-
- /* Extract the direction and data transfer length */
-
- dir = flags & USBMSC_FLAGS_DIRMASK; /* Expected data direction */
- datlen = 0;
- if ((flags & USBMSC_FLAGS_BLOCKXFR) == 0)
- {
- /* Non-block transfer. Data length: Host allocation to receive data
- * (only for device-to-host transfers. At present, alloclen is set
- * to zero for all host-to-device, non-block transfers.
- */
-
- datlen = priv->u.alloclen;
- }
- else if (lun)
- {
- /* Block transfer: Calculate the total size of all sectors to be transferred */
-
- datlen = priv->u.alloclen * lun->sectorsize;
- }
-
- /* Check the data direction. This was set up at the end of the
- * IDLE state when the CBW was parsed, but if there is no data,
- * then the direction is none.
- */
-
- if (datlen == 0)
- {
- /* No data.. then direction is none */
-
- dir = USBMSC_FLAGS_DIRNONE;
- }
-
- /* Compare the expected data length in the command to the data length
- * in the CBW.
- */
-
- else if (priv->cbwlen < datlen)
- {
- /* Clip to the length in the CBW and declare a phase error */
-
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_PHASEERROR1), priv->cdb[0]);
- if ((flags & USBMSC_FLAGS_BLOCKXFR) != 0)
- {
- priv->u.alloclen = priv->cbwlen;
- }
- else
- {
- priv->u.xfrlen = priv->cbwlen / lun->sectorsize;
- }
-
- priv->phaseerror = 1;
- }
-
- /* Initialize the residue */
-
- priv->residue = priv->cbwlen;
-
- /* Conflicting data directions is a phase error */
-
- if (priv->cbwdir != dir && datlen > 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_PHASEERROR2), priv->cdb[0]);
- priv->phaseerror = 1;
- ret = -EINVAL;
- }
-
- /* Compare the length of data in the cdb[] with the expected length
- * of the command.
- */
-
- if (cdblen != priv->cdblen)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_PHASEERROR3), priv->cdb[0]);
- priv->phaseerror = 1;
- ret = -EINVAL;
- }
-
- if (lun)
- {
- /* Retain the sense data for the REQUEST SENSE command */
-
- if ((flags & USBMSC_FLAGS_RETAINSENSEDATA) == 0)
- {
- /* Discard the sense data */
-
- lun->sd = SCSI_KCQ_NOSENSE;
- lun->sdinfo = 0;
- }
-
- /* If a unit attention condition exists, then only a restricted set of
- * commands is permitted.
- */
-
- if (lun->uad != SCSI_KCQ_NOSENSE && (flags & USBMSC_FLAGS_UACOKAY) != 0)
- {
- /* Command not permitted */
-
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDUNEVIOLATION), priv->cbwlun);
- lun->sd = lun->uad;
- lun->uad = SCSI_KCQ_NOSENSE;
- ret = -EINVAL;
- }
- }
-
- /* The final, 1-byte field of every SCSI command is the Control field which
- * must be zero
- */
-
- if (priv->cdb[cdblen-1] != 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SCSICMDCONTROL), 0);
- if (lun)
- {
- lun->sd = SCSI_KCQIR_INVALIDFIELDINCBA;
- }
- ret = -EINVAL;
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_idlestate
- *
- * Description:
- * Called from the worker thread in the USBMSC_STATE_IDLE state. Checks
- * for the receipt of a bulk CBW.
- *
- * Returned value:
- * If no new, valid CBW is available, this function returns a negated errno.
- * Otherwise, when a new CBW is successfully parsed, this function sets
- * priv->thstate to USBMSC_STATE_CMDPARSE and returns OK.
- *
- ****************************************************************************/
-
-static int usbmsc_idlestate(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct usbmsc_req_s *privreq;
- FAR struct usbdev_req_s *req;
- FAR struct usbmsc_cbw_s *cbw;
- irqstate_t flags;
- int ret = -EINVAL;
-
- /* Take a request from the rdreqlist */
-
- flags = irqsave();
- privreq = (FAR struct usbmsc_req_s *)sq_remfirst(&priv->rdreqlist);
- irqrestore(flags);
-
- /* Has anything been received? If not, just return an error.
- * This will cause us to remain in the IDLE state. When a USB request is
- * received, the worker thread will be awakened in the USBMSC_STATE_IDLE
- * and we will be called again.
- */
-
- if (!privreq)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_IDLERDREQLISTEMPTY), 0);
- return -ENOMEM;
- }
-
- req = privreq->req;
- cbw = (FAR struct usbmsc_cbw_s *)req->buf;
-
- /* Handle the CBW */
-
- usbmsc_dumpdata("SCSCI CBW", (uint8_t*)cbw, USBMSC_CBW_SIZEOF - USBMSC_MAXCDBLEN);
- usbmsc_dumpdata(" CDB", cbw->cdb, MIN(cbw->cdblen, USBMSC_MAXCDBLEN));
-
- /* Check for properly formatted CBW? */
-
- if (req->xfrd != USBMSC_CBW_SIZEOF ||
- cbw->signature[0] != 'U' ||
- cbw->signature[1] != 'S' ||
- cbw->signature[2] != 'B' ||
- cbw->signature[3] != 'C')
- {
- /* CBS BAD: Stall the bulk endpoints. If the CBW is bad we must stall the
- * bulk IN endpoint and either (1) stall the bulk OUT endpoint, or
- * (2) discard data from the endpoint.
- */
-
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INVALIDCBWSIGNATURE), 0);
- EP_STALL(priv->epbulkout);
- EP_STALL(priv->epbulkin);
- }
-
- /* Is the CBW meaningful? */
-
- else if (cbw->lun >= priv->nluns || (cbw->flags & ~USBMSC_CBWFLAG_IN) != 0 ||
- cbw->cdblen < 6 || cbw->cdblen > USBMSC_MAXCDBLEN)
- {
- /* CBS BAD: Stall the bulk endpoints. If the CBW is bad we must stall the
- * bulk IN endpoint and either (1) stall the bulk OUT endpoint, or
- * (2) discard data from the endpoint.
- */
-
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INVALIDCBWCONTENT), 0);
- EP_STALL(priv->epbulkout);
- EP_STALL(priv->epbulkin);
- }
-
- /* Save the information from the CBW */
-
- else
- {
- /* Extract the CDB and copy the whole CBD[] for later use */
-
- priv->cdblen = cbw->cdblen;
- memcpy(priv->cdb, cbw->cdb, priv->cdblen);
-
- /* Extract the data direction */
-
- if ((cbw->flags & USBMSC_CBWFLAG_IN) != 0)
- {
- /* IN: Device-to-host */
-
- priv->cbwdir = USBMSC_FLAGS_DIRDEVICE2HOST;
- }
- else
- {
- /* OUT: Host-to-device */
-
- priv->cbwdir = USBMSC_FLAGS_DIRHOST2DEVICE;
- }
-
- /* Get the max size of the data response */
-
- priv->cbwlen = usbmsc_getle32(cbw->datlen);
- if (priv->cbwlen == 0)
- {
- /* No length? Then no direction either */
-
- priv->cbwdir = USBMSC_FLAGS_DIRNONE;
- }
-
- /* Extract and save the LUN index and TAG value */
-
- priv->cbwlun = cbw->lun;
- priv->cbwtag = usbmsc_getle32(cbw->tag);
-
- /* Return the read request to the bulk out endpoint for re-filling */
-
- req = privreq->req;
- req->len = CONFIG_USBMSC_BULKOUTREQLEN;
- req->priv = privreq;
- req->callback = usbmsc_rdcomplete;
-
- /* Change to the CMDPARSE state and return success */
-
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_IDLECMDPARSE), priv->cdb[0]);
- priv->thstate = USBMSC_STATE_CMDPARSE;
- ret = OK;
- }
-
- /* In any event, return the request to be refilled */
-
- if (EP_SUBMIT(priv->epbulkout, req) != OK)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_IDLERDSUBMIT), (uint16_t)-ret);
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdparsestate
- *
- * Description:
- * Called from the worker thread in the USBMSC_STATE_CMDPARSE state.
- * This state is entered when usbmsc_idlestate obtains a valid CBW
- * containing SCSI commands. This function processes those SCSI commands.
- *
- * Returned value:
- * If no write request is available or certain other errors occur, this
- * function returns a negated errno and stays in the USBMSC_STATE_CMDPARSE
- * state. Otherwise, when the new CBW is successfully process, this
- * function sets priv->thstate to one of USBMSC_STATE_CMDREAD,
- * USBMSC_STATE_CMDWRITE, or USBMSC_STATE_CMDFINISH and returns OK.
- *
- ****************************************************************************/
-
-static int usbmsc_cmdparsestate(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct usbmsc_req_s *privreq;
- FAR uint8_t *buf;
- int ret = -EINVAL;
-
- usbmsc_dumpdata("SCSCI CDB", priv->cdb, priv->cdblen);
-
- /* Check if there is a request in the wrreqlist that we will be able to
- * use for data or status.
- */
-
- privreq = (FAR struct usbmsc_req_s *)sq_peek(&priv->wrreqlist);
-
- /* If there no request structures available, then just return an error.
- * This will cause us to remain in the CMDPARSE state. When a request is
- * returned, the worker thread will be awakened in the USBMSC_STATE_CMDPARSE
- * and we will be called again.
- */
-
- if (!privreq)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDPARSEWRREQLISTEMPTY), 0);
- return -ENOMEM;
- }
-
- DEBUGASSERT(privreq->req && privreq->req->buf);
- buf = privreq->req->buf;
-
- /* Assume that no errors will be encountered */
-
- priv->phaseerror = 0;
- priv->shortpacket = 0;
-
- /* No data is buffered */
-
- priv->nsectbytes = 0;
- priv->nreqbytes = 0;
-
- /* Get exclusive access to the block driver */
-
- pthread_mutex_lock(&priv->mutex);
- switch (priv->cdb[0])
- {
- case SCSI_CMD_TESTUNITREADY: /* 0x00 Mandatory */
- ret = usbmsc_cmdtestunitready(priv);
- break;
-
- /* case SCSI_CMD_REZEROUNIT: * 0x01 Obsolete
- * * 0x02 Vendor-specific */
-
- case SCSI_CMD_REQUESTSENSE: /* 0x03 Mandatory */
- ret = usbmsc_cmdrequestsense(priv, buf);
- break;
-
- /* case SCSI_CMD_FORMAT_UNIT: * 0x04 Mandatory, but not implemented
- * * 0x05 Vendor specific
- * * 0x06 Vendor specific
- * case SCSI_CMD_REASSIGNBLOCKS: * 0x07 Optional */
-
- case SCSI_CMD_READ6: /* 0x08 Mandatory */
- ret = usbmsc_cmdread6(priv);
- break;
-
- /* * 0x09 Vendor specific */
-
- case SCSI_CMD_WRITE6: /* 0x0a Optional */
- ret = usbmsc_cmdwrite6(priv);
- break;
-
- /* case SCSI_CMD_SEEK6: * 0x0b Obsolete
- * * 0x0c-0x10 Vendor specific
- * case SCSI_CMD_SPACE6: * 0x11 Vendor specific */
-
- case SCSI_CMD_INQUIRY: /* 0x12 Mandatory */
- ret = usbmsc_cmdinquiry(priv, buf);
- break;
-
- /* * 0x13-0x14 Vendor specific */
-
- case SCSI_CMD_MODESELECT6: /* 0x15 Optional */
- ret = usbmsc_cmdmodeselect6(priv);
- break;
-
- /* case SCSI_CMD_RESERVE6: * 0x16 Obsolete
- * case SCSI_CMD_RELEASE6: * 0x17 Obsolete
- * case SCSI_CMD_COPY: * 0x18 Obsolete
- * * 0x19 Vendor specific */
-
- case SCSI_CMD_MODESENSE6: /* 0x1a Optional */
- ret = usbmsc_cmdmodesense6(priv, buf);
- break;
-
- case SCSI_CMD_STARTSTOPUNIT: /* 0x1b Optional */
- ret = usbmsc_cmdstartstopunit(priv);
- break;
-
- /* case SCSI_CMD_RECEIVEDIAGNOSTICRESULTS: * 0x1c Optional
- * case SCSI_CMD_SENDDIAGNOSTIC: * 0x1d Mandatory, but not implemented */
-
- case SCSI_CMD_PREVENTMEDIAREMOVAL: /* 0x1e Optional */
- ret = usbmsc_cmdpreventmediumremoval(priv);
- break;
-
- /* * 0x20-22 Vendor specific */
- case SCSI_CMD_READFORMATCAPACITIES: /* 0x23 Vendor-specific (defined in MMC spec) */
- ret = usbmsc_cmdreadformatcapacity(priv, buf);
- break;
- /* * 0x24 Vendor specific */
-
- case SCSI_CMD_READCAPACITY10: /* 0x25 Mandatory */
- ret = usbmsc_cmdreadcapacity10(priv, buf);
- break;
-
- /* * 0x26-27 Vendor specific */
- case SCSI_CMD_READ10: /* 0x28 Mandatory */
- ret = usbmsc_cmdread10(priv);
- break;
-
- /* * 0x29 Vendor specific */
-
- case SCSI_CMD_WRITE10: /* 0x2a Optional */
- ret = usbmsc_cmdwrite10(priv);
- break;
-
- /* case SCSI_CMD_SEEK10: * 0x2b Obsolete
- * * 0x2c-2d Vendor specific
- * case SCSI_CMD_WRITEANDVERIFY: * 0x2e Optional */
-
- case SCSI_CMD_VERIFY10: /* 0x2f Optional, but needed my MS Windows */
- ret = usbmsc_cmdverify10(priv);
- break;
-
- /* case SCSI_CMD_SEARCHDATAHIGH: * 0x30 Obsolete
- * case SCSI_CMD_SEARCHDATAEQUAL: * 0x31 Obsolete
- * case SCSI_CMD_SEARCHDATALOW: * 0x32 Obsolete
- * case SCSI_CMD_SETLIMITS10: * 0x33 Obsolete
- * case SCSI_CMD_PREFETCH10: * 0x34 Optional */
-
- case SCSI_CMD_SYNCHCACHE10: /* 0x35 Optional */
- ret = usbmsc_cmdsynchronizecache10(priv);
- break;
-
- /* case SCSI_CMD_LOCKCACHE: * 0x36 Obsolete
- * case SCSI_CMD_READDEFECTDATA10: * 0x37 Optional
- * case SCSI_CMD_COMPARE: * 0x39 Obsolete
- * case SCSI_CMD_COPYANDVERIFY: * 0x3a Obsolete
- * case SCSI_CMD_WRITEBUFFER: * 0x3b Optional
- * case SCSI_CMD_READBUFFER: * 0x3c Optional
- * case SCSI_CMD_READLONG10: * 0x3e Optional
- * case SCSI_CMD_WRITELONG10: * 0x3f Optional
- * case SCSI_CMD_CHANGEDEFINITION: * 0x40 Obsolete
- * case SCSI_CMD_WRITESAME10: * 0x41 Optional
- * case SCSI_CMD_LOGSELECT: * 0x4c Optional
- * case SCSI_CMD_LOGSENSE: * 0x4d Optional
- * case SCSI_CMD_XDWRITE10: * 0x50 Optional
- * case SCSI_CMD_XPWRITE10: * 0x51 Optional
- * case SCSI_CMD_XDREAD10: * 0x52 Optional */
-
- case SCSI_CMD_MODESELECT10: /* 0x55 Optional */
- ret = usbmsc_cmdmodeselect10(priv);
- break;
-
- /* case SCSI_CMD_RESERVE10: * 0x56 Obsolete
- * case SCSI_CMD_RELEASE10: * 0x57 Obsolete */
-
- case SCSI_CMD_MODESENSE10: /* 0x5a Optional */
- ret = usbmsc_cmdmodesense10(priv, buf);
- break;
-
- /* case SCSI_CMD_PERSISTENTRESERVEIN: * 0x5e Optional
- * case SCSI_CMD_PERSISTENTRESERVEOUT: * 0x5f Optional
- * case SCSI_CMD_32: * 0x7f Optional
- * case SCSI_CMD_XDWRITEEXTENDED: * 0x80 Obsolete
- * case SCSI_CMD_REBUILD: * 0x81 Obsolete
- * case SCSI_CMD_REGENERATE: * 0x82 Obsolete
- * case SCSI_CMD_EXTENDEDCOPY: * 0x83 Optional
- * case SCSI_CMD_COPYRESULTS: * 0x84 Optional
- * case SCSI_CMD_ACCESSCONTROLIN: * 0x86 Optional
- * case SCSI_CMD_ACCESSCONTROLOUT: * 0x87 Optional
- * case SCSI_CMD_READ16: * 0x88 Optional
- * case SCSI_CMD_WRITE16: * 0x8a Optional
- * case SCSI_CMD_READATTRIBUTE: * 0x8c Optional
- * case SCSI_CMD_WRITEATTRIBUTE: * 0x8d Optional
- * case SCSI_CMD_WRITEANDVERIFY16: * 0x8e Optional
- * case SCSI_CMD_SYNCHCACHE16: * 0x91 Optional
- * case SCSI_CMD_LOCKUNLOCKACACHE: * 0x92 Optional
- * case SCSI_CMD_WRITESAME16: * 0x93 Optional
- * case SCSI_CMD_READCAPACITY16: * 0x9e Optional
- * case SCSI_CMD_READLONG16: * 0x9e Optional
- * case SCSI_CMD_WRITELONG16 * 0x9f Optional
- * case SCSI_CMD_REPORTLUNS: * 0xa0 Mandatory, but not implemented
- * case SCSI_CMD_MAINTENANCEIN: * 0xa3 Optional (SCCS==0)
- * case SCSI_CMD_MAINTENANCEOUT: * 0xa4 Optional (SCCS==0)
- * case SCSI_CMD_MOVEMEDIUM: * 0xa5 ?
- * case SCSI_CMD_MOVEMEDIUMATTACHED: * 0xa7 Optional (MCHNGR==0) */
-
- case SCSI_CMD_READ12: /* 0xa8 Optional */
- ret = usbmsc_cmdread12(priv);
- break;
-
- case SCSI_CMD_WRITE12: /* 0xaa Optional */
- ret = usbmsc_cmdwrite12(priv);
- break;
-
- /* case SCSI_CMD_READMEDIASERIALNUMBER: * 0xab Optional
- * case SCSI_CMD_WRITEANDVERIFY12: * 0xae Optional
- * case SCSI_CMD_VERIFY12: * 0xaf Optional
- * case SCSI_CMD_SETLIMITS12 * 0xb3 Obsolete
- * case SCSI_CMD_READELEMENTSTATUS: * 0xb4 Optional (MCHNGR==0)
- * case SCSI_CMD_READDEFECTDATA12: * 0xb7 Optional
- * case SCSI_CMD_REDUNDANCYGROUPIN: * 0xba Optional
- * case SCSI_CMD_REDUNDANCYGROUPOUT: * 0xbb Optional
- * case SCSI_CMD_SPAREIN: * 0xbc Optional (SCCS==0)
- * case SCSI_CMD_SPAREOUT: * 0xbd Optional (SCCS==0)
- * case SCSI_CMD_VOLUMESETIN: * 0xbe Optional (SCCS==0)
- * case SCSI_CMD_VOLUMESETOUT: * 0xbe Optional (SCCS==0)
- * * 0xc0-0xff Vendor specific */
-
- default:
- priv->u.alloclen = 0;
- if (ret == OK)
- {
- priv->lun->sd = SCSI_KCQIR_INVALIDCOMMAND;
- ret = -EINVAL;
- }
- break;
- }
- pthread_mutex_unlock(&priv->mutex);
-
- /* Is a response required? (Not for read6/10/12 and write6/10/12). */
-
- if (priv->thstate == USBMSC_STATE_CMDPARSE)
- {
- /* All commands come through this path (EXCEPT read6/10/12 and write6/10/12).
- * For all other commands, the following setup is expected for the response
- * based on data direction:
- *
- * For direction NONE:
- * 1. priv->u.alloclen == 0
- * 2. priv->nreqbytes == 0
- *
- * For direction = device-to-host:
- * 1. priv->u.alloclen == allocation length; space set aside by the
- * host to receive the device data. The size of the response
- * cannot exceed this value.
- * 2. response data is in the request currently at the head of
- * the priv->wrreqlist queue. priv->nreqbytes is set to the length
- * of data in the response.
- *
- * For direction host-to-device
- * At present, there are no supported commands that should have host-to-device
- * transfers (except write6/10/12 and that command logic does not take this
- * path. The 'residue' is left at the full host-to-device data size.
- *
- * For all:
- * ret set to <0 if an error occurred in parsing the commands.
- */
-
- /* For from device-to-hose operations, the residue is the expected size
- * (the initial value of 'residue') minus the amount actually returned
- * in the response:
- */
-
- if (priv->cbwdir == USBMSC_FLAGS_DIRDEVICE2HOST)
- {
- /* The number of bytes in the response cannot exceed the host
- * 'allocation length' in the command.
- */
-
- if (priv->nreqbytes > priv->u.alloclen)
- {
- priv->nreqbytes = priv->u.alloclen;
- }
-
- /* The residue is then the number of bytes that were not sent */
-
- priv->residue -= priv->nreqbytes;
- }
-
- /* On return, we need the following:
- *
- * 1. Setup for CMDFINISH state if appropriate
- * 2. priv->thstate set to either CMDPARSE if no buffer was available or
- * CMDFINISH to send the response
- * 3. Return OK to continue; <0 to wait for the next event
- */
-
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDPARSECMDFINISH), priv->cdb[0]);
- priv->thstate = USBMSC_STATE_CMDFINISH;
- ret = OK;
- }
- return ret;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdreadstate
- *
- * Description:
- * Called from the worker thread in the USBMSC_STATE_CMDREAD state.
- * The USBMSC_STATE_CMDREAD state is entered when usbmsc_cmdparsestate
- * obtains a valid SCSI read command. This state is really a continuation
- * of the USBMSC_STATE_CMDPARSE state that handles extended SCSI read
- * command handling.
- *
- * Returned value:
- * If no USBDEV write request is available or certain other errors occur, this
- * function returns a negated errno and stays in the USBMSC_STATE_CMDREAD
- * state. Otherwise, when the new SCSI read command is fully processed,
- * this function sets priv->thstate to USBMSC_STATE_CMDFINISH and returns OK.
- *
- * State variables:
- * xfrlen - holds the number of sectors read to be read.
- * sector - holds the sector number of the next sector to be read
- * nsectbytes - holds the number of bytes buffered for the current sector
- * nreqbytes - holds the number of bytes currently buffered in the request
- * at the head of the wrreqlist.
- *
- ****************************************************************************/
-
-static int usbmsc_cmdreadstate(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct usbmsc_lun_s *lun = priv->lun;
- FAR struct usbmsc_req_s *privreq;
- FAR struct usbdev_req_s *req;
- irqstate_t flags;
- ssize_t nread;
- uint8_t *src;
- uint8_t *dest;
- int nbytes;
- int ret;
-
- /* Loop transferring data until either (1) all of the data has been
- * transferred, or (2) we have used up all of the write requests that we have
- * available.
- */
-
- while (priv->u.xfrlen > 0 || priv->nsectbytes > 0)
- {
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDREAD), priv->u.xfrlen);
-
- /* Is the I/O buffer empty? */
-
- if (priv->nsectbytes <= 0)
- {
- /* Yes.. read the next sector */
-
- nread = USBMSC_DRVR_READ(lun, priv->iobuffer, priv->sector, 1);
- if (nread < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDREADREADFAIL), -nread);
- lun->sd = SCSI_KCQME_UNRRE1;
- lun->sdinfo = priv->sector;
- break;
- }
-
- priv->nsectbytes = lun->sectorsize;
- priv->u.xfrlen--;
- priv->sector++;
- }
-
- /* Check if there is a request in the wrreqlist that we will be able to
- * use for data transfer.
- */
-
- privreq = (FAR struct usbmsc_req_s *)sq_peek(&priv->wrreqlist);
-
- /* If there no request structures available, then just return an error.
- * This will cause us to remain in the CMDREAD state. When a request is
- * returned, the worker thread will be awakened in the USBMSC_STATE_CMDREAD
- * and we will be called again.
- */
-
- if (!privreq)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDREADWRRQEMPTY), 0);
- priv->nreqbytes = 0;
- return -ENOMEM;
- }
- req = privreq->req;
-
- /* Transfer all of the data that will (1) fit into the request buffer, OR (2)
- * all of the data available in the sector buffer.
- */
-
- src = &priv->iobuffer[lun->sectorsize - priv->nsectbytes];
- dest = &req->buf[priv->nreqbytes];
-
- nbytes = MIN(CONFIG_USBMSC_BULKINREQLEN - priv->nreqbytes, priv->nsectbytes);
-
- /* Copy the data from the sector buffer to the USB request and update counts */
-
- memcpy(dest, src, nbytes);
- priv->nreqbytes += nbytes;
- priv->nsectbytes -= nbytes;
-
- /* If (1) the request buffer is full OR (2) this is the final request full of data,
- * then submit the request
- */
-
- if (priv->nreqbytes >= CONFIG_USBMSC_BULKINREQLEN ||
- (priv->u.xfrlen <= 0 && priv->nsectbytes <= 0))
- {
- /* Remove the request that we just filled from wrreqlist (we've already checked
- * that is it not NULL
- */
-
- flags = irqsave();
- privreq = (FAR struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist);
- irqrestore(flags);
-
- /* And submit the request to the bulk IN endpoint */
-
- req->len = priv->nreqbytes;
- req->priv = privreq;
- req->callback = usbmsc_wrcomplete;
- req->flags = 0;
-
- ret = EP_SUBMIT(priv->epbulkin, req);
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDREADSUBMIT), (uint16_t)-ret);
- lun->sd = SCSI_KCQME_UNRRE1;
- lun->sdinfo = priv->sector;
- break;
- }
-
- /* Assume success... residue should probably really be decremented in
- * wrcomplete when we know that the transfer completed successfully.
- */
-
- priv->residue -= priv->nreqbytes;
- priv->nreqbytes = 0;
- }
- }
-
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDREADCMDFINISH), priv->u.xfrlen);
- priv->thstate = USBMSC_STATE_CMDFINISH;
- return OK;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdwritestate
- *
- * Description:
- * Called from the worker thread in the USBMSC_STATE_CMDWRITE state.
- * The USBMSC_STATE_CMDWRITE state is entered when usbmsc_cmdparsestate
- * obtains a valid SCSI write command. This state is really a continuation
- * of the USBMSC_STATE_CMDPARSE state that handles extended SCSI write
- * command handling.
- *
- * Returned value:
- * If no USBDEV write request is available or certain other errors occur, this
- * function returns a negated errno and stays in the USBMSC_STATE_CMDWRITE
- * state. Otherwise, when the new SCSI write command is fully processed,
- * this function sets priv->thstate to USBMSC_STATE_CMDFINISH and returns OK.
- *
- * State variables:
- * xfrlen - holds the number of sectors read to be written.
- * sector - holds the sector number of the next sector to write
- * nsectbytes - holds the number of bytes buffered for the current sector
- * nreqbytes - holds the number of untransferred bytes currently in the
- * request at the head of the rdreqlist.
- *
- ****************************************************************************/
-
-static int usbmsc_cmdwritestate(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct usbmsc_lun_s *lun = priv->lun;
- FAR struct usbmsc_req_s *privreq;
- FAR struct usbdev_req_s *req;
- ssize_t nwritten;
- uint16_t xfrd;
- uint8_t *src;
- uint8_t *dest;
- int nbytes;
- int ret;
-
- /* Loop transferring data until either (1) all of the data has been
- * transferred, or (2) we have written all of the data in the available
- * read requests.
- */
-
- while (priv->u.xfrlen > 0)
- {
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDWRITE), priv->u.xfrlen);
-
- /* Check if there is a request in the rdreqlist containing additional
- * data to be written.
- */
-
- privreq = (FAR struct usbmsc_req_s *)sq_remfirst(&priv->rdreqlist);
-
- /* If there no request data available, then just return an error.
- * This will cause us to remain in the CMDWRITE state. When a filled request is
- * received, the worker thread will be awakened in the USBMSC_STATE_CMDWRITE
- * and we will be called again.
- */
-
- if (!privreq)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDWRITERDRQEMPTY), 0);
- priv->nreqbytes = 0;
- return -ENOMEM;
- }
-
- req = privreq->req;
- xfrd = req->xfrd;
- priv->nreqbytes = xfrd;
-
- /* Now loop until all of the data in the read request has been tranferred
- * to the block driver OR all of the request data has been transferred.
- */
-
- while (priv->nreqbytes > 0 && priv->u.xfrlen > 0)
- {
- /* Copy the data received in the read request into the sector I/O buffer */
-
- src = &req->buf[xfrd - priv->nreqbytes];
- dest = &priv->iobuffer[priv->nsectbytes];
-
- nbytes = MIN(lun->sectorsize - priv->nsectbytes, priv->nreqbytes);
-
- /* Copy the data from the sector buffer to the USB request and update counts */
-
- memcpy(dest, src, nbytes);
- priv->nsectbytes += nbytes;
- priv->nreqbytes -= nbytes;
-
- /* Is the I/O buffer full? */
-
- if (priv->nsectbytes >= lun->sectorsize)
- {
- /* Yes.. Write the next sector */
-
- nwritten = USBMSC_DRVR_WRITE(lun, priv->iobuffer, priv->sector, 1);
- if (nwritten < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDWRITEWRITEFAIL), -nwritten);
- lun->sd = SCSI_KCQME_WRITEFAULTAUTOREALLOCFAILED;
- lun->sdinfo = priv->sector;
- goto errout;
- }
-
- priv->nsectbytes = 0;
- priv->residue -= lun->sectorsize;
- priv->u.xfrlen--;
- priv->sector++;
- }
- }
-
- /* In either case, we are finished with this read request and can return it
- * to the endpoint. Then we will go back to the top of the top and attempt
- * to get the next read request.
- */
-
- req->len = CONFIG_USBMSC_BULKOUTREQLEN;
- req->priv = privreq;
- req->callback = usbmsc_rdcomplete;
-
- ret = EP_SUBMIT(priv->epbulkout, req);
- if (ret != OK)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDWRITERDSUBMIT), (uint16_t)-ret);
- }
-
- /* Did the host decide to stop early? */
-
- if (xfrd != CONFIG_USBMSC_BULKOUTREQLEN)
- {
- priv->shortpacket = 1;
- goto errout;
- }
- }
-
-errout:
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDWRITECMDFINISH), priv->u.xfrlen);
- priv->thstate = USBMSC_STATE_CMDFINISH;
- return OK;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdfinishstate
- *
- * Description:
- * Called from the worker thread in the USBMSC_STATE_CMDFINISH state.
- * The USBMSC_STATE_CMDFINISH state is entered when processing of a
- * command has finished but before status has been returned.
- *
- * Returned value:
- * If no USBDEV write request is available or certain other errors occur, this
- * function returns a negated errno and stays in the USBMSC_STATE_CMDFINISH
- * state. Otherwise, when the command is fully processed, this function
- * sets priv->thstate to USBMSC_STATE_CMDSTATUS and returns OK.
- *
- ****************************************************************************/
-
-static int usbmsc_cmdfinishstate(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct usbmsc_req_s *privreq;
- irqstate_t flags;
- int ret = OK;
-
- /* Check if there is a request in the wrreqlist that we will be able to
- * use for data transfer.
- */
-
- privreq = (FAR struct usbmsc_req_s *)sq_peek(&priv->wrreqlist);
-
- /* If there no request structures available, then just return an error.
- * This will cause us to remain in the CMDREAD state. When a request is
- * returned, the worker thread will be awakened in the USBMSC_STATE_CMDREAD
- * and we will be called again.
- */
-
- if (!privreq)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDFINISHRQEMPTY), 0);
- return -ENOMEM;
- }
-
- /* Finish the final stages of the reply */
-
- switch (priv->cbwdir)
- {
- /* Device-to-host: All but the last data buffer has been sent */
-
- case USBMSC_FLAGS_DIRDEVICE2HOST:
- if (priv->cbwlen > 0)
- {
- /* On most commands (the exception is outgoing, write commands),
- * the data has not not yet been sent.
- */
-
- if (priv->nreqbytes > 0)
- {
- struct usbdev_req_s *req;
-
- /* Take a request from the wrreqlist (we've already checked
- * that is it not NULL)
- */
-
- flags = irqsave();
- privreq = (FAR struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist);
- irqrestore(flags);
-
- /* Send the write request */
-
- req = privreq->req;
- req->len = priv->nreqbytes;
- req->callback = usbmsc_wrcomplete;
- req->priv = privreq;
- req->flags = USBDEV_REQFLAGS_NULLPKT;
-
- ret = EP_SUBMIT(priv->epbulkin, privreq->req);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDFINISHSUBMIT), (uint16_t)-ret);
- }
- }
-
- /* Stall the BULK In endpoint if there is a residue */
-
- if (priv->residue > 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDFINISHRESIDUE), (uint16_t)priv->residue);
-
-#ifdef CONFIG_USBMSC_RACEWAR
- /* (See description of the workaround at the top of the file).
- * First, wait for the transfer to complete, then stall the endpoint
- */
-
- usleep (100000);
- (void)EP_STALL(priv->epbulkin);
-
- /* now wait for stall to go away .... */
-
- usleep (100000);
-#else
- (void)EP_STALL(priv->epbulkin);
-#endif
- }
- }
- break;
-
- /* Host-to-device: We have processed all we want of the host data. */
-
- case USBMSC_FLAGS_DIRHOST2DEVICE:
- if (priv->residue > 0)
- {
- /* Did the host stop sending unexpectedly early? */
-
- flags = irqsave();
- if (priv->shortpacket)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDFINISHSHORTPKT), (uint16_t)priv->residue);
- }
-
- /* Unprocessed incoming data: STALL and cancel requests. */
-
- else
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDFINSHSUBMIT), (uint16_t)priv->residue);
- EP_STALL(priv->epbulkout);
- }
-
- priv->theventset |= USBMSC_EVENT_ABORTBULKOUT;
- irqrestore(flags);
- }
- break;
-
- default:
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDFINSHDIR), priv->cbwdir);
- case USBMSC_FLAGS_DIRNONE: /* Nothing to send */
- break;
- }
-
- /* Return to the IDLE state */
-
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDFINISHCMDSTATUS), 0);
- priv->thstate = USBMSC_STATE_CMDSTATUS;
- return OK;
-}
-
-/****************************************************************************
- * Name: usbmsc_cmdstatusstate
- *
- * Description:
- * Called from the worker thread in the USBMSC_STATE_CMDSTATUS state.
- * That state is after a CBW has been fully processed. This function sends
- * the concluding CSW.
- *
- * Returned value:
- * If no write request is available or certain other errors occur, this
- * function returns a negated errno and stays in the USBMSC_STATE_CMDSTATUS
- * state. Otherwise, when the SCSI statis is successfully returned, this
- * function sets priv->thstate to USBMSC_STATE_IDLE and returns OK.
- *
- ****************************************************************************/
-
-static int usbmsc_cmdstatusstate(FAR struct usbmsc_dev_s *priv)
-{
- FAR struct usbmsc_lun_s *lun = priv->lun;
- FAR struct usbmsc_req_s *privreq;
- FAR struct usbdev_req_s *req;
- FAR struct usbmsc_csw_s *csw;
- irqstate_t flags;
- uint32_t sd;
- uint8_t status = USBMSC_CSWSTATUS_PASS;
- int ret;
-
- /* Take a request from the wrreqlist */
-
- flags = irqsave();
- privreq = (FAR struct usbmsc_req_s *)sq_remfirst(&priv->wrreqlist);
- irqrestore(flags);
-
- /* If there no request structures available, then just return an error.
- * This will cause us to remain in the CMDSTATUS status. When a request is
- * returned, the worker thread will be awakened in the USBMSC_STATE_CMDSTATUS
- * and we will be called again.
- */
-
- if (!privreq)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_CMDSTATUSRDREQLISTEMPTY), 0);
- return -ENOMEM;
- }
-
- req = privreq->req;
- csw = (struct usbmsc_csw_s*)req->buf;
-
- /* Extract the sense data from the LUN structure */
-
- if (lun)
- {
- sd = lun->sd;
- }
- else
- {
- sd = SCSI_KCQIR_INVALIDLUN;
- }
-
- /* Determine the CSW status: PASS, PHASEERROR, or FAIL */
-
- if (priv->phaseerror)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SNDPHERROR), 0);
- status = USBMSC_CSWSTATUS_PHASEERROR;
- sd = SCSI_KCQIR_INVALIDCOMMAND;
- }
- else if (sd != SCSI_KCQ_NOSENSE)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SNDCSWFAIL), 0);
- status = USBMSC_CSWSTATUS_FAIL;
- }
-
- /* Format and submit the CSW */
-
- csw->signature[0] = 'U';
- csw->signature[1] = 'S';
- csw->signature[2] = 'B';
- csw->signature[3] = 'S';
- usbmsc_putle32(csw->tag, priv->cbwtag);
- usbmsc_putle32(csw->residue, priv->residue);
- csw->status = status;
-
- usbmsc_dumpdata("SCSCI CSW", (uint8_t*)csw, USBMSC_CSW_SIZEOF);
-
- req->len = USBMSC_CSW_SIZEOF;
- req->callback = usbmsc_wrcomplete;
- req->priv = privreq;
- req->flags = USBDEV_REQFLAGS_NULLPKT;
-
- ret = EP_SUBMIT(priv->epbulkin, req);
- if (ret < 0)
- {
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_SNDSTATUSSUBMIT), (uint16_t)-ret);
- flags = irqsave();
- (void)sq_addlast((sq_entry_t*)privreq, &priv->wrreqlist);
- irqrestore(flags);
- }
-
- /* Return to the IDLE state */
-
- usbtrace(TRACE_CLASSSTATE(USBMSC_CLASSSTATE_CMDSTATUSIDLE), 0);
- priv->thstate = USBMSC_STATE_IDLE;
- return OK;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbmsc_workerthread
- *
- * Description:
- * This is the main function of the USB storage worker thread. It loops
- * until USB-related events occur, then processes those events accordingly
- *
- ****************************************************************************/
-
-void *usbmsc_workerthread(void *arg)
-{
- struct usbmsc_dev_s *priv = (struct usbmsc_dev_s *)arg;
- irqstate_t flags;
- uint16_t eventset;
- int ret;
-
- /* This thread is started before the USB storage class is fully initialized.
- * wait here until we are told to begin. Start in the NOTINITIALIZED state
- */
-
- pthread_mutex_lock(&priv->mutex);
- priv->thstate = USBMSC_STATE_STARTED;
- while ((priv->theventset & USBMSC_EVENT_READY) != 0 &&
- (priv->theventset & USBMSC_EVENT_TERMINATEREQUEST) != 0)
- {
- pthread_cond_wait(&priv->cond, &priv->mutex);
- }
-
- /* Transition to the INITIALIZED/IDLE state */
-
- priv->thstate = USBMSC_STATE_IDLE;
- eventset = priv->theventset;
- priv->theventset = USBMSC_EVENT_NOEVENTS;
- pthread_mutex_unlock(&priv->mutex);
-
- /* Then loop until we are asked to terminate */
-
- while ((eventset & USBMSC_EVENT_TERMINATEREQUEST) == 0)
- {
- /* Wait for some interesting event. Note that we must both take the
- * lock (to eliminate race conditions with other threads) and disable
- * interrupts (to eliminate race conditions with USB interrupt handling.
- */
-
- pthread_mutex_lock(&priv->mutex);
- flags = irqsave();
- if (priv->theventset == USBMSC_EVENT_NOEVENTS)
- {
- pthread_cond_wait(&priv->cond, &priv->mutex);
- }
-
- /* Sample any events before re-enabling interrupts. Any events that
- * occur after re-enabling interrupts will have to be handled in the
- * next time through the loop.
- */
-
- eventset = priv->theventset;
- priv->theventset = USBMSC_EVENT_NOEVENTS;
- pthread_mutex_unlock(&priv->mutex);
-
- /* Were we awakened by some event that requires immediate action?
- *
- * - The USBMSC_EVENT_DISCONNECT is signalled from the disconnect method
- * after all transfers have been stopped, when the host is disconnected.
- *
- * - The CUSBMSC_EVENT_RESET is signalled when the bulk-storage-specific
- * USBMSC_REQ_MSRESET EP0 setup received. We must stop the current
- * operation and reinialize state.
- *
- * - The USBMSC_EVENT_CFGCHANGE is signaled when the EP0 setup logic
- * receives a valid USB_REQ_SETCONFIGURATION request
- *
- * - The USBMSC_EVENT_IFCHANGE is signaled when the EP0 setup logic
- * receives a valid USB_REQ_SETINTERFACE request
- *
- * - The USBMSC_EVENT_ABORTBULKOUT event is signalled by the CMDFINISH
- * logic when there is a residue after processing a host-to-device
- * transfer. We need to discard all incoming request.
- *
- * All other events are just wakeup calls and are intended only
- * drive the state machine.
- */
-
- if ((eventset & (USBMSC_EVENT_DISCONNECT|USBMSC_EVENT_RESET|USBMSC_EVENT_CFGCHANGE|
- USBMSC_EVENT_IFCHANGE|USBMSC_EVENT_ABORTBULKOUT)) != 0)
- {
- /* These events require that the current configuration be reset */
-
- if ((eventset & USBMSC_EVENT_IFCHANGE) != 0)
- {
- usbmsc_resetconfig(priv);
- }
-
- /* These events require that a new configuration be established */
-
- if ((eventset & (USBMSC_EVENT_CFGCHANGE|USBMSC_EVENT_IFCHANGE)) != 0)
- {
- usbmsc_setconfig(priv, priv->thvalue);
- }
-
- /* These events required that we send a deferred EP0 setup response */
-
- if ((eventset & (USBMSC_EVENT_RESET|USBMSC_EVENT_CFGCHANGE|USBMSC_EVENT_IFCHANGE)) != 0)
- {
- usbmsc_deferredresponse(priv, false);
- }
-
- /* For all of these events... terminate any transactions in progress */
-
- priv->thstate = USBMSC_STATE_IDLE;
- }
- irqrestore(flags);
-
- /* Loop processing each SCSI command state. Each state handling
- * function will do the following:
- *
- * - If it must block for an event, it will return a negated errno value
- * - If it completes the processing for that state, it will (1) set
- * the next appropriate state value and (2) return OK.
- *
- * So the following will loop until we must block for an event in
- * a particular state. When we are awakened by an event (above) we
- * will resume processing in the same state.
- */
-
- do
- {
- switch (priv->thstate)
- {
- case USBMSC_STATE_IDLE: /* Started and waiting for commands */
- ret = usbmsc_idlestate(priv);
- break;
-
- case USBMSC_STATE_CMDPARSE: /* Parsing the received a command */
- ret = usbmsc_cmdparsestate(priv);
- break;
-
- case USBMSC_STATE_CMDREAD: /* Continuing to process a SCSI read command */
- ret = usbmsc_cmdreadstate(priv);
- break;
-
- case USBMSC_STATE_CMDWRITE: /* Continuing to process a SCSI write command */
- ret = usbmsc_cmdwritestate(priv);
- break;
-
- case USBMSC_STATE_CMDFINISH: /* Finish command processing */
- ret = usbmsc_cmdfinishstate(priv);
- break;
-
- case USBMSC_STATE_CMDSTATUS: /* Processing the status phase of a command */
- ret = usbmsc_cmdstatusstate(priv);
- break;
-
- case USBMSC_STATE_NOTSTARTED: /* Thread has not yet been started */
- case USBMSC_STATE_STARTED: /* Started, but is not yet initialized */
- case USBMSC_STATE_TERMINATED: /* Thread has exitted */
- default:
- usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INVALIDSTATE), priv->thstate);
- priv->thstate = USBMSC_STATE_IDLE;
- ret = OK;
- break;
- }
- }
- while (ret == OK);
- }
-
- /* Transition to the TERMINATED state and exit */
-
- priv->thstate = USBMSC_STATE_TERMINATED;
- return NULL;
-}
diff --git a/nuttx/drivers/usbhost/Kconfig b/nuttx/drivers/usbhost/Kconfig
deleted file mode 100644
index 531e94442..000000000
--- a/nuttx/drivers/usbhost/Kconfig
+++ /dev/null
@@ -1,114 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
-
-config USBHOST_NPREALLOC
- int "Number of pre-allocated class instances"
- default 4
- ---help---
- Number of pre-allocated class instances
-
-config USBHOST_BULK_DISABLE
- bool "Disable bulk endpoint support"
- default n
- ---help---
- On some architectures, selecting this setting will reduce driver size
- by disabling bulk endpoint support
-
-config USBHOST_INT_DISABLE
- bool "Disable interrupt endpoint support"
- default n
- ---help---
- On some architectures, selecting this setting will reduce driver size
- by disabling interrupt endpoint support
-
-config USBHOST_ISOC_DISABLE
- bool "Disable isochronous endpoint support"
- default n
- ---help---
- On some architectures, selecting this setting will reduce driver size
- by disabling isochronous endpoint support
-
-config USBHOST_MSC
- bool "Mass Storage Class Support"
- default n
- depends on !BULK_DISABLE
- ---help---
- Enable support for the keyboard class driver. This also depends on
- NFILE_DESCRIPTORS > 0 && SCHED_WORKQUEUE=y
-
-config USBHOST_HIDKBD
- bool "HID Keyboard Class Support"
- default n
- depends on !INT_DISABLE
- ---help---
- Enable support for the keyboard class driver. This also depends on
- SCHED_WORKQUEUE && !DISABLE_SIGNALS
-
-if USBHOST_HIDKBD
-config HIDKBD_POLLUSEC
- int "Keyboard Poll Rate (MSEC)"
- default 100000
- ---help---
- Device poll rate in microseconds. Default: 100,000 microseconds.
-
-config HIDKBD_DEFPRIO
- int "Polling Thread Priority"
- default 50
- ---help---
- Priority of the polling thread. Default: 50.
-
-config HIDKBD_STACKSIZE
- int "Polling thread stack size"
- default 1024
- ---help---
- Stack size for polling thread. Default: 1024
-
-config HIDKBD_BUFSIZE
- int "Scancode Buffer Size"
- default 64
- ---help---
- Scancode buffer size. Default: 64.
-
-config HIDKBD_NPOLLWAITERS
- int "Max Number of Waiters for Poll Event"
- default 2
- depends on !DISABLE_POLL
- ---help---
- If the poll() method is enabled, this defines the maximum number
- of threads that can be waiting for keyboard events. Default: 2.
-
-config HIDKBD_RAWSCANCODES
- bool "Use Raw Scan Codes"
- default n
- ---help---
- If set to y no conversions will be made on the raw keyboard scan
- codes. This option is useful during testing. Default: ASCII conversion.
-
-config HIDKBD_ENCODED
- bool "Enocode Special Keys"
- default n
- depends on !HIDKBD_RAWSCANCODES && LIB_KBDCODEC
- ---help---
- Encode special key press events in the user buffer. In this case,
- the user end must decode the encoded special key values using the
- interfaces defined in include/nuttx/input/kbd_codec.h. These
- special keys include such things as up/down arrows, home and end
- keys, etc. If this not defined, only 7-bit print-able and control
- ASCII characters will be provided to the user.
-
-config HIDKBD_ALLSCANCODES
- bool "Use All Scancodes"
- default n
- ---help---
- If set to y all 231 possible scancodes will be converted to
- something. Default: 104 key US keyboard.
-
-config HIDKBD_NODEBOUNCE
- bool "Disable Debounce"
- default n
- ---help---
- If set to y normal debouncing is disabled. Default:
- Debounce enabled (No repeat keys).
-endif
diff --git a/nuttx/drivers/usbhost/Make.defs b/nuttx/drivers/usbhost/Make.defs
deleted file mode 100644
index ebb522695..000000000
--- a/nuttx/drivers/usbhost/Make.defs
+++ /dev/null
@@ -1,57 +0,0 @@
-############################################################################
-# drivers/usbhost/Make.defs
-#
-# Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-CSRCS += hid_parser.c
-
-ifeq ($(CONFIG_USBHOST),y)
-
-# Include built-in USB host driver logic
-
-CSRCS += usbhost_registry.c usbhost_registerclass.c usbhost_findclass.c
-CSRCS += usbhost_enumerate.c usbhost_storage.c usbhost_hidkbd.c
-
-# Include add-on USB host driver logic (see misc/drivers)
-
-ifeq ($(CONFIG_NET),y)
- RTL8187_CSRC := ${shell if [ -f usbhost$(DELIM)rtl8187x.c ]; then echo "rtl8187x.c"; fi}
- CSRCS += $(RTL8187_CSRC)
-endif
-endif
-
-# Include USB host driver build logic
-
-DEPPATH += --dep-path usbhost
-VPATH += :usbhost
-CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)usbhost}
diff --git a/nuttx/drivers/usbhost/hid_parser.c b/nuttx/drivers/usbhost/hid_parser.c
deleted file mode 100644
index a0ca6066b..000000000
--- a/nuttx/drivers/usbhost/hid_parser.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/****************************************************************************
- * drivers/usbhost/hid_parser.c
- *
- * Copyright (C) 2011 Gregory Nutt. All rights reserved.
- *
- * Adapted from the LUFA Library:
- *
- * Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com)
- * dean [at] fourwalledcubicle [dot] com, www.lufa-lib.org
- *
- * Permission to use, copy, modify, distribute, and sell this
- * software and its documentation for any purpose is hereby granted
- * without fee, provided that the above copyright notice appear in
- * all copies and that both that the copyright notice and this
- * permission notice and warranty disclaimer appear in supporting
- * documentation, and that the name of the author not be used in
- * advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- *
- * The author disclaim all warranties with regard to this
- * software, including all implied warranties of merchantability
- * and fitness. In no event shall the author be liable for any
- * special, indirect or consequential damages or any damages
- * whatsoever resulting from loss of use, data or profits, whether
- * in an action of contract, negligence or other tortious action,
- * arising out of or in connection with the use or performance of
- * this software.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/usb/hid.h>
-#include <nuttx/usb/hid_parser.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-struct hid_state_s
-{
- struct hid_rptitem_attributes_s attrib;
- uint8_t rptcount;
- uint8_t id;
-};
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: hid_parsereport
- *
- * Description:
- * Function to process a given HID report returned from an attached device,
- * and store it into a given struct hid_rptinfo_s structure.
- *
- * Input Parameters:
- * report Buffer containing the device's HID report table.
- * rptlen Size in bytes of the HID report table.
- * filter Callback function to decide if an item should be retained
- * rptinfo Pointer to a struct hid_rptinfo_s instance for the parser output.
- *
- * Returned Value:
- * Zero on success, otherwise a negated errno value.
- ****************************************************************************/
-
-int hid_parsereport(FAR const uint8_t *report, int rptlen,
- hid_rptfilter_t filter, FAR struct hid_rptinfo_s *rptinfo)
-{
- struct hid_state_s state[CONFIG_HID_STATEDEPTH];
- struct hid_state_s *currstate = &state[0];
- struct hid_collectionpath_s *collectionpath = NULL;
- struct hid_rptsizeinfo_s *rptidinfo = &rptinfo->rptsize[0];
- uint16_t usage[CONFIG_HID_USAGEDEPTH];
- uint8_t nusage = 0;
- struct hid_range_s usage_range = { 0, 0 };
- int i;
-
- DEBUGASSERT(report && filter && rptinfo);
-
- memset(rptinfo, 0x00, sizeof(struct hid_rptinfo_s));
- memset(currstate, 0x00, sizeof(struct hid_state_s));
- memset(rptidinfo, 0x00, sizeof(struct hid_rptsizeinfo_s));
-
- rptinfo->nreports = 1;
-
- while (rptlen > 0)
- {
- uint8_t item = *report;
- uint32_t data = 0;
-
- report++;
- rptlen--;
-
- switch (item & USBHID_RPTITEM_SIZE_MASK)
- {
- case USBHID_RPTITEM_SIZE_4: /* 4 bytes of little endian data follow */
- data = (uint32_t)(*report++);
- data |= (uint32_t)(*report++) << 8;
- data |= (uint32_t)(*report++) << 16;
- data |= (uint32_t)(*report++) << 24;
- rptlen -= 4;
- break;
-
- case USBHID_RPTITEM_SIZE_2: /* 2 bytes of little endian data follow */
- data = (uint32_t)(*report++);
- data |= (uint32_t)(*report++) << 8;
- rptlen -= 2;
- break;
-
- case USBHID_RPTITEM_SIZE_1: /* 1 byte of data follows */
- data = (uint32_t)(*report++);
- rptlen -= 1;
- break;
-
- case USBHID_RPTITEM_SIZE_0: /* No data follows */
- default:
- break;
- }
-
- switch (item & ~USBHID_RPTITEM_SIZE_MASK)
- {
- case USBHID_GLOBAL_PUSH_PREFIX:
- if (currstate == &state[CONFIG_HID_STATEDEPTH - 1])
- {
- return -E2BIG;
- }
-
- memcpy((currstate + 1),
- currstate, sizeof(struct hid_rptitem_s));
-
- currstate++;
- break;
-
- case USBHID_GLOBAL_POP_PREFIX:
- if (currstate == &state[0])
- {
- return -EINVAL; /* Pop without push? */
- }
-
- currstate--;
- break;
-
- case USBHID_GLOBAL_USAGEPAGE_PREFIX:
- if ((item & USBHID_RPTITEM_SIZE_MASK) == USBHID_RPTITEM_SIZE_4)
- {
- currstate->attrib.usage.page = (data >> 16);
- }
-
- currstate->attrib.usage.page = data;
- break;
-
- case USBHID_GLOBAL_LOGICALMIN_PREFIX:
- currstate->attrib.logical.min = data;
- break;
-
- case USBHID_GLOBAL_LOGICALMAX_PREFIX:
- currstate->attrib.logical.max = data;
- break;
-
- case USBHID_GLOBAL_PHYSICALMIN_PREFIX:
- currstate->attrib.physical.min = data;
- break;
-
- case USBHID_GLOBAL_PHYSMICALAX_PREFIX:
- currstate->attrib.physical.max = data;
- break;
-
- case USBHID_GLOBAL_UNITEXP_PREFIX:
- currstate->attrib.unit.exponent = data;
- break;
-
- case USBHID_GLOBAL_UNIT_PREFIX:
- currstate->attrib.unit.type = data;
- break;
-
- case USBHID_GLOBAL_REPORTSIZE_PREFIX:
- currstate->attrib.bitsize = data;
- break;
-
- case USBHID_GLOBAL_REPORTCOUNT_PREFIX:
- currstate->rptcount = data;
- break;
-
- case USBHID_GLOBAL_REPORTID_PREFIX:
- currstate->id = data;
-
- if (rptinfo->haverptid)
- {
- rptidinfo = NULL;
-
- for (i = 0; i < rptinfo->nreports; i++)
- {
- if (rptinfo->rptsize[i].id == currstate->id)
- {
- rptidinfo = &rptinfo->rptsize[i];
- break;
- }
- }
-
- if (rptidinfo == NULL)
- {
- if (rptinfo->nreports == CONFIG_HID_MAXIDS)
- {
- return -EINVAL;
- }
-
- rptidinfo = &rptinfo->rptsize[rptinfo->nreports++];
- memset(rptidinfo, 0x00, sizeof(struct hid_rptsizeinfo_s));
- }
- }
-
- rptinfo->haverptid = true;
-
- rptidinfo->id = currstate->id;
- break;
-
- case USBHID_LOCAL_USAGE_PREFIX:
- if (nusage == CONFIG_HID_USAGEDEPTH)
- {
- return -E2BIG;
- }
-
- usage[nusage++] = data;
- break;
-
- case USBHID_LOCAL_USAGEMIN_PREFIX:
- usage_range.min = data;
- break;
-
- case USBHID_LOCAL_USAGEMAX_PREFIX:
- usage_range.max = data;
- break;
-
- case USBHID_MAIN_COLLECTION_PREFIX:
- if (collectionpath == NULL)
- {
- collectionpath = &rptinfo->collectionpaths[0];
- }
- else
- {
- struct hid_collectionpath_s *ParentCollectionPath = collectionpath;
-
- collectionpath = &rptinfo->collectionpaths[1];
-
- while (collectionpath->parent != NULL)
- {
- if (collectionpath == &rptinfo->collectionpaths[CONFIG_HID_MAXCOLLECTIONS - 1])
- {
- return -EINVAL;
- }
-
- collectionpath++;
- }
-
- collectionpath->parent = ParentCollectionPath;
- }
-
- collectionpath->type = data;
- collectionpath->usage.page = currstate->attrib.usage.page;
-
- if (nusage)
- {
- collectionpath->usage.usage = usage[0];
-
- for (i = 0; i < nusage; i++)
- usage[i] = usage[i + 1];
-
- nusage--;
- }
- else if (usage_range.min <= usage_range.max)
- {
- collectionpath->usage.usage = usage_range.min++;
- }
-
- break;
-
- case USBHID_MAIN_ENDCOLLECTION_PREFIX:
- if (collectionpath == NULL)
- {
- return -EINVAL;
- }
-
- collectionpath = collectionpath->parent;
- break;
-
- case USBHID_MAIN_INPUT_PREFIX:
- case USBHID_MAIN_OUTPUT_PREFIX:
- case USBHID_MAIN_FEATURE_PREFIX:
- {
- int itemno;
- for (itemno = 0; itemno < currstate->rptcount; itemno++)
- {
- struct hid_rptitem_s newitem;
- uint8_t tag;
-
- memcpy(&newitem.attrib, &currstate->attrib,
- sizeof(struct hid_rptitem_attributes_s));
-
- newitem.flags = data;
- newitem.collectionpath = collectionpath;
- newitem.id = currstate->id;
-
- if (nusage)
- {
- newitem.attrib.usage.usage = usage[0];
-
- for (i = 0; i < nusage; i++)
- {
- usage[i] = usage[i + 1];
- }
- nusage--;
- }
- else if (usage_range.min <= usage_range.max)
- {
- newitem.attrib.usage.usage = usage_range.min++;
- }
-
- tag = (item & ~USBHID_RPTITEM_SIZE_MASK);
- if (tag == USBHID_MAIN_INPUT_PREFIX)
- {
- newitem.type = HID_REPORT_ITEM_IN;
- }
- else if (tag == USBHID_MAIN_OUTPUT_PREFIX)
- {
- newitem.type = HID_REPORT_ITEM_OUT;
- }
- else
- {
- newitem.type = HID_REPORT_ITEM_FEATURE;
- }
-
- newitem.bitoffset = rptidinfo->size[newitem.type];
- rptidinfo->size[newitem.type] += currstate->attrib.bitsize;
-
- /* Accumulate the maximum report size */
-
- if (rptinfo->maxrptsize < newitem.bitoffset)
- {
- rptinfo->maxrptsize = newitem.bitoffset;
- }
-
- if ((data & USBHID_MAIN_CONSTANT) == 0 && filter(&newitem))
- {
- if (rptinfo->nitems == CONFIG_HID_MAXITEMS)
- {
- return -EINVAL;
- }
-
- memcpy(&rptinfo->items[rptinfo->nitems],
- &newitem, sizeof(struct hid_rptitem_s));
-
- rptinfo->nitems++;
- }
- }
- }
- break;
- }
-
- if ((item & USBHID_RPTITEM_TYPE_MASK) == USBHID_RPTITEM_TYPE_MAIN)
- {
- usage_range.min = 0;
- usage_range.max = 0;
- nusage = 0;
- }
- }
-
- if (!(rptinfo->nitems))
- {
- return -ENOENT;
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: hid_getitem
- *
- * Description:
- * Extracts the given report item's value out of the given HID report and
- * places it into the value member of the report item's struct hid_rptitem_s
- * structure.
- *
- * When called on a report with an item that exists in that report, this
- * copies the report item's Value to it's previous element for easy
- * checking to see if an item's value has changed before processing a
- * report. If the given item does not exist in the report, the function
- * does not modify the report item's data.
- *
- * Input Parameters
- * report Buffer containing an IN or FEATURE report from an attached
- * device.
- * item Pointer to the report item of interest in a struct hid_rptinfo_s
- * item array.
- *
- * Returned Value:
- * Zero on success, otherwise a negated errno value.
- *
- ****************************************************************************/
-
-int hid_getitem(FAR const uint8_t *report, FAR struct hid_rptitem_s *item)
-{
- uint16_t remaining = item->attrib.bitsize;
- uint16_t offset = item->bitoffset;
- uint32_t mask = (1 << 0);
-
- if (item->id)
- {
- if (item->id != report[0])
- {
- return -ENOENT;
- }
-
- report++;
- }
-
- item->previous = item->value;
- item->value = 0;
-
- while (remaining--)
- {
- if (report[offset >> 3] & (1 << (offset & 7)))
- {
- item->value |= mask;
- }
-
- offset++;
- mask <<= 1;
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Name: hid_putitem
- *
- * Desription:
- * Retrieves the given report item's value out of the Value member of the
- * report item's struct hid_rptitem_s structure and places it into the correct
- * position in the HID report buffer. The report buffer is assumed to have
- * the appropriate bits cleared before calling this function (i.e., the
- * buffer should be explicitly cleared before report values are added).
- *
- * When called, this copies the report item's Value element to it's
- * previous element for easy checking to see if an item's value has
- * changed before sending a report.
- *
- * If the device has multiple HID reports, the first byte in the report is
- * set to the report ID of the given item.
- *
- * Input Parameters:
- * report Buffer holding the current OUT or FEATURE report data.
- * item Pointer to the report item of interest in a struct hid_rptinfo_s
- * item array.
- *
- ****************************************************************************/
-
-#if 0 /* Not needed by host */
-void hid_putitem(FAR uint8_t *report, struct hid_rptitem_s *item)
-{
- uint16_t remaining = item->attrib.bitsize;
- uint16_t offset = item->bitoffset;
- uint32_t mask = (1 << 0);
-
- if (item->id)
- {
- report[0] = item->id;
- report++;
- }
-
- item->previous = item->value;
-
- while (remaining--)
- {
- if (item->value & (1 << (offset & 7)))
- {
- report[offset >> 3] |= mask;
- }
-
- offset++;
- mask <<= 1;
- }
-}
-#endif
-
-/****************************************************************************
- * Name: hid_reportsize
- *
- * Description:
- * Retrieves the size of a given HID report in bytes from it's Report ID.
- *
- * InputParameters:
- * rptinfo Pointer to a struct hid_rptinfo_s instance containing the parser output.
- * id Report ID of the report whose size is to be retrieved.
- * rpttype Type of the report whose size is to be determined, a valued from the
- * HID_ReportItemTypes_t enum.
- *
- * Size of the report in bytes, or 0 if the report does not exist.
- *
- ****************************************************************************/
-
-size_t hid_reportsize(FAR struct hid_rptinfo_s *rptinfo, uint8_t id, uint8_t rpttype)
-{
- int i;
- for (i = 0; i < CONFIG_HID_MAXIDS; i++)
- {
- size_t size = rptinfo->rptsize[i].size[rpttype];
-
- if (rptinfo->rptsize[i].id == id)
- {
- return ((size >> 3) + ((size & 0x07) ? 1 : 0));
- }
- }
-
- return 0;
-}
diff --git a/nuttx/drivers/usbhost/usbhost_enumerate.c b/nuttx/drivers/usbhost/usbhost_enumerate.c
deleted file mode 100644
index 26b93bf36..000000000
--- a/nuttx/drivers/usbhost/usbhost_enumerate.c
+++ /dev/null
@@ -1,518 +0,0 @@
-/*******************************************************************************
- * drivers/usbhost/usbhost_enumerate.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Authors: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/usbhost.h>
-
-/*******************************************************************************
- * Definitions
- *******************************************************************************/
-
-/*******************************************************************************
- * Private Types
- *******************************************************************************/
-
-/*******************************************************************************
- * Private Function Prototypes
- *******************************************************************************/
-
-static inline uint16_t usbhost_getle16(const uint8_t *val);
-static void usbhost_putle16(uint8_t *dest, uint16_t val);
-
-static inline int usbhost_devdesc(const struct usb_devdesc_s *devdesc,
- struct usbhost_id_s *id);
-static inline int usbhost_configdesc(const uint8_t *configdesc, int desclen,
- struct usbhost_id_s *id);
-static inline int usbhost_classbind(FAR struct usbhost_driver_s *drvr,
- const uint8_t *configdesc, int desclen,
- struct usbhost_id_s *id, uint8_t funcaddr,
- FAR struct usbhost_class_s **class);
-
-/*******************************************************************************
- * Private Data
- *******************************************************************************/
-
-/*******************************************************************************
- * Public Data
- *******************************************************************************/
-
-/*******************************************************************************
- * Private Functions
- *******************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_getle16
- *
- * Description:
- * Get a (possibly unaligned) 16-bit little endian value.
- *
- *******************************************************************************/
-
-static inline uint16_t usbhost_getle16(const uint8_t *val)
-{
- return (uint16_t)val[1] << 8 | (uint16_t)val[0];
-}
-
-/****************************************************************************
- * Name: usbhost_putle16
- *
- * Description:
- * Put a (possibly unaligned) 16-bit little endian value.
- *
- *******************************************************************************/
-
-static void usbhost_putle16(uint8_t *dest, uint16_t val)
-{
- dest[0] = val & 0xff; /* Little endian means LS byte first in byte stream */
- dest[1] = val >> 8;
-}
-
-/*******************************************************************************
- * Name: usbhost_devdesc
- *
- * Description:
- * A configuration descriptor has been obtained from the device. Find the
- * ID information for the class that supports this device.
- *
- *******************************************************************************/
-
-static inline int usbhost_devdesc(FAR const struct usb_devdesc_s *devdesc,
- FAR struct usbhost_id_s *id)
-{
- /* Clear the ID info */
-
- memset(id, 0, sizeof(struct usbhost_id_s));
-
- /* Pick off the class ID info */
-
- id->base = devdesc->classid;
- id->subclass = devdesc->subclass;
- id->proto = devdesc->protocol;
-
- /* Pick off the VID and PID as well (for vendor specfic devices) */
-
- id->vid = usbhost_getle16(devdesc->vendor);
- id->pid = usbhost_getle16(devdesc->product);
-
- uvdbg("class:%d subclass:%04x protocol:%04x vid:%d pid:%d\n",
- id->base, id->subclass, id->proto, id->vid, id->pid);
- return OK;
-}
-
-/*******************************************************************************
- * Name: usbhost_configdesc
- *
- * Description:
- * A configuration descriptor has been obtained from the device. Find the
- * ID information for the class that supports this device.
- *
- *******************************************************************************/
-
-static inline int usbhost_configdesc(const uint8_t *configdesc, int cfglen,
- struct usbhost_id_s *id)
-{
- struct usb_cfgdesc_s *cfgdesc;
- struct usb_ifdesc_s *ifdesc;
- int remaining;
-
- DEBUGASSERT(configdesc != NULL && cfglen >= USB_SIZEOF_CFGDESC);
-
- /* Verify that we were passed a configuration descriptor */
-
- cfgdesc = (struct usb_cfgdesc_s *)configdesc;
- uvdbg("cfg len:%d total len:%d\n", cfgdesc->len, cfglen);
-
- if (cfgdesc->type != USB_DESC_TYPE_CONFIG)
- {
- return -EINVAL;
- }
-
- /* Skip to the next entry descriptor */
-
- configdesc += cfgdesc->len;
- remaining = cfglen - cfgdesc->len;
-
- /* Loop where there are more dscriptors to examine */
-
- memset(id, 0, sizeof(FAR struct usb_desc_s));
- while (remaining >= sizeof(struct usb_desc_s))
- {
- /* What is the next descriptor? Is it an interface descriptor? */
-
- ifdesc = (struct usb_ifdesc_s *)configdesc;
- if (ifdesc->type == USB_DESC_TYPE_INTERFACE)
- {
- /* Yes, extract the class information from the interface descriptor.
- * Typically these values are zero meaning that the "real" ID
- * information resides in the device descriptor.
- */
-
- DEBUGASSERT(remaining >= sizeof(struct usb_ifdesc_s));
- id->base = ifdesc->classid;
- id->subclass = ifdesc->subclass;
- id->proto = ifdesc->protocol;
- uvdbg("class:%d subclass:%d protocol:%d\n",
- id->base, id->subclass, id->proto);
- return OK;
- }
-
- /* Increment the address of the next descriptor */
-
- configdesc += ifdesc->len;
- remaining -= ifdesc->len;
- }
-
- return -ENOENT;
-}
-
-/*******************************************************************************
- * Name: usbhost_classbind
- *
- * Description:
- * A configuration descriptor has been obtained from the device. Try to
- * bind this configuration descriptor with a supported class.
- *
- *******************************************************************************/
-
-static inline int usbhost_classbind(FAR struct usbhost_driver_s *drvr,
- const uint8_t *configdesc, int desclen,
- struct usbhost_id_s *id, uint8_t funcaddr,
- FAR struct usbhost_class_s **class)
-{
- FAR struct usbhost_class_s *devclass;
- const struct usbhost_registry_s *reg;
- int ret = -EINVAL;
-
- /* Is there is a class implementation registered to support this device. */
-
- reg = usbhost_findclass(id);
- uvdbg("usbhost_findclass: %p\n", reg);
- if (reg)
- {
- /* Yes.. there is a class for this device. Get an instance of
- * its interface.
- */
-
- ret = -ENOMEM;
- devclass = CLASS_CREATE(reg, drvr, id);
- uvdbg("CLASS_CREATE: %p\n", devclass);
- if (devclass)
- {
- /* Then bind the newly instantiated class instance */
-
- ret = CLASS_CONNECT(devclass, configdesc, desclen, funcaddr);
- if (ret != OK)
- {
- /* On failures, call the class disconnect method which
- * should then free the allocated devclass instance.
- */
-
- udbg("CLASS_CONNECT failed: %d\n", ret);
- CLASS_DISCONNECTED(devclass);
- }
- else
- {
- *class = devclass;
- }
- }
- }
-
- uvdbg("Returning: %d\n", ret);
- return ret;
-}
-
-/*******************************************************************************
- * Public Functions
- *******************************************************************************/
-
-/*******************************************************************************
- * Name: usbhost_enumerate
- *
- * Description:
- * Enumerate the connected device. As part of this enumeration process,
- * the driver will (1) get the device's configuration descriptor, (2)
- * extract the class ID info from the configuration descriptor, (3) call
- * usbhost_findclass() to find the class that supports this device, (4)
- * call the create() method on the struct usbhost_registry_s interface
- * to get a class instance, and finally (5) call the configdesc() method
- * of the struct usbhost_class_s interface. After that, the class is in
- * charge of the sequence of operations.
- *
- * Input Parameters:
- * drvr - The USB host driver instance obtained as a parameter from the call to
- * the class create() method.
- * funcaddr - The USB address of the function containing the endpoint that EP0
- * controls
- * class - If the class driver for the device is successful located
- * and bound to the driver, the allocated class instance is returned into
- * this caller-provided memory location.
- *
- * Returned Values:
- * On success, zero (OK) is returned. On a failure, a negated errno value is
- * returned indicating the nature of the failure
- *
- * Assumptions:
- * - Only a single class bound to a single device is supported.
- * - Called from a single thread so no mutual exclusion is required.
- * - Never called from an interrupt handler.
- *
- *******************************************************************************/
-
-int usbhost_enumerate(FAR struct usbhost_driver_s *drvr, uint8_t funcaddr,
- FAR struct usbhost_class_s **class)
-{
- struct usb_ctrlreq_s *ctrlreq;
- struct usbhost_id_s id;
- size_t maxlen;
- unsigned int cfglen;
- uint8_t maxpacketsize;
- uint8_t *buffer;
- int ret;
-
- DEBUGASSERT(drvr && class);
-
- /* Allocate descriptor buffers for use in this function. We will need two:
- * One for the request and one for the data buffer.
- */
-
- ret = DRVR_ALLOC(drvr, (FAR uint8_t **)&ctrlreq, &maxlen);
- if (ret != OK)
- {
- udbg("DRVR_ALLOC failed: %d\n", ret);
- return ret;
- }
-
- ret = DRVR_ALLOC(drvr, &buffer, &maxlen);
- if (ret != OK)
- {
- udbg("DRVR_ALLOC failed: %d\n", ret);
- goto errout;
- }
-
- /* Set max pkt size = 8 */
-
- DRVR_EP0CONFIGURE(drvr, 0, 8);
-
- /* Read first 8 bytes of the device descriptor */
-
- ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_RECIPIENT_DEVICE;
- ctrlreq->req = USB_REQ_GETDESCRIPTOR;
- usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_DEVICE << 8));
- usbhost_putle16(ctrlreq->index, 0);
- usbhost_putle16(ctrlreq->len, 8);
-
- ret = DRVR_CTRLIN(drvr, ctrlreq, buffer);
- if (ret != OK)
- {
- udbg("ERROR: GETDESCRIPTOR/DEVICE, DRVR_CTRLIN returned %d\n", ret);
- goto errout;
- }
-
- /* Extract the correct max packetsize from the device descriptor */
-
- maxpacketsize = ((struct usb_devdesc_s *)buffer)->mxpacketsize;
- uvdbg("maxpacksetsize: %d\n", maxpacketsize);
-
- /* And reconfigure EP0 */
-
- DRVR_EP0CONFIGURE(drvr, 0, maxpacketsize);
-
- /* Now read the full device descriptor */
-
- ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_RECIPIENT_DEVICE;
- ctrlreq->req = USB_REQ_GETDESCRIPTOR;
- usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_DEVICE << 8));
- usbhost_putle16(ctrlreq->index, 0);
- usbhost_putle16(ctrlreq->len, USB_SIZEOF_DEVDESC);
-
- ret = DRVR_CTRLIN(drvr, ctrlreq, buffer);
- if (ret != OK)
- {
- udbg("ERROR: GETDESCRIPTOR/DEVICE, DRVR_CTRLIN returned %d\n", ret);
- goto errout;
- }
-
- /* Get class identification information from the device descriptor. Most
- * devices set this to USB_CLASS_PER_INTERFACE (zero) and provide the
- * identification informatino in the interface descriptor(s). That allows
- * a device to support multiple, different classes.
- */
-
- (void)usbhost_devdesc((struct usb_devdesc_s *)buffer, &id);
-
- /* Set the USB device address to the value in the 'funcaddr' input */
-
- ctrlreq->type = USB_REQ_DIR_OUT|USB_REQ_RECIPIENT_DEVICE;
- ctrlreq->req = USB_REQ_SETADDRESS;
- usbhost_putle16(ctrlreq->value, (uint16_t)funcaddr);
- usbhost_putle16(ctrlreq->index, 0);
- usbhost_putle16(ctrlreq->len, 0);
-
- ret = DRVR_CTRLOUT(drvr, ctrlreq, NULL);
- if (ret != OK)
- {
- udbg("ERROR: SETADDRESS DRVR_CTRLOUT returned %d\n", ret);
- goto errout;
- }
- usleep(2*1000);
-
- /* Modify control pipe with the provided USB device address */
-
- DRVR_EP0CONFIGURE(drvr, funcaddr, maxpacketsize);
-
- /* Get the configuration descriptor (only), index == 0. Should not be
- * hard-coded! More logic is needed in order to handle devices with
- * multiple configurations.
- */
-
- ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_RECIPIENT_DEVICE;
- ctrlreq->req = USB_REQ_GETDESCRIPTOR;
- usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_CONFIG << 8));
- usbhost_putle16(ctrlreq->index, 0);
- usbhost_putle16(ctrlreq->len, USB_SIZEOF_CFGDESC);
-
- ret = DRVR_CTRLIN(drvr, ctrlreq, buffer);
- if (ret != OK)
- {
- udbg("ERROR: GETDESCRIPTOR/CONFIG, DRVR_CTRLIN returned %d\n", ret);
- goto errout;
- }
-
- /* Extract the full size of the configuration data */
-
- cfglen = (unsigned int)usbhost_getle16(((struct usb_cfgdesc_s *)buffer)->totallen);
- uvdbg("sizeof config data: %d\n", cfglen);
-
- /* Get all of the configuration descriptor data, index == 0 (Should not be
- * hard-coded!)
- */
-
- ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_RECIPIENT_DEVICE;
- ctrlreq->req = USB_REQ_GETDESCRIPTOR;
- usbhost_putle16(ctrlreq->value, (USB_DESC_TYPE_CONFIG << 8));
- usbhost_putle16(ctrlreq->index, 0);
- usbhost_putle16(ctrlreq->len, cfglen);
-
- ret = DRVR_CTRLIN(drvr, ctrlreq, buffer);
- if (ret != OK)
- {
- udbg("ERROR: GETDESCRIPTOR/CONFIG, DRVR_CTRLIN returned %d\n", ret);
- goto errout;
- }
-
- /* Select device configuration 1 (Should not be hard-coded!) */
-
- ctrlreq->type = USB_REQ_DIR_OUT|USB_REQ_RECIPIENT_DEVICE;
- ctrlreq->req = USB_REQ_SETCONFIGURATION;
- usbhost_putle16(ctrlreq->value, 1);
- usbhost_putle16(ctrlreq->index, 0);
- usbhost_putle16(ctrlreq->len, 0);
-
- ret = DRVR_CTRLOUT(drvr, ctrlreq, NULL);
- if (ret != OK)
- {
- udbg("ERROR: SETCONFIGURATION, DRVR_CTRLOUT returned %d\n", ret);
- goto errout;
- }
-
- /* Free the descriptor buffer that we were using for the request buffer.
- * It is not needed further here but it may be needed by the class driver
- * during its connection operations.
- */
-
- DRVR_FREE(drvr, (uint8_t*)ctrlreq);
- ctrlreq = NULL;
-
- /* Was the class identification information provided in the device descriptor?
- * Or do we need to find it in the interface descriptor(s)?
- */
-
- if (id.base == USB_CLASS_PER_INTERFACE)
- {
- /* Get the class identification information for this device from the
- * interface descriptor(s). Hmmm.. More logic is need to handle the
- * case of multiple interface descriptors.
- */
-
- ret = usbhost_configdesc(buffer, cfglen, &id);
- if (ret != OK)
- {
- udbg("ERROR: usbhost_configdesc returned %d\n", ret);
- goto errout;
- }
- }
-
- /* Some devices may require some delay before initialization */
-
- usleep(100*1000);
-
- /* Parse the configuration descriptor and bind to the class instance for the
- * device. This needs to be the last thing done because the class driver
- * will begin configuring the device.
- */
-
- ret = usbhost_classbind(drvr, buffer, cfglen, &id, funcaddr, class);
- if (ret != OK)
- {
- udbg("ERROR: usbhost_classbind returned %d\n", ret);
- }
-
-errout:
- if (buffer)
- {
- DRVR_FREE(drvr, buffer);
- }
-
- if (ctrlreq)
- {
- DRVR_FREE(drvr, (uint8_t*)ctrlreq);
- }
- return ret;
-}
diff --git a/nuttx/drivers/usbhost/usbhost_findclass.c b/nuttx/drivers/usbhost/usbhost_findclass.c
deleted file mode 100644
index 3e38670cf..000000000
--- a/nuttx/drivers/usbhost/usbhost_findclass.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/****************************************************************************
- * drivers/usbhost/usbhost_findclass.c
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdbool.h>
-#include <debug.h>
-
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/usbhost.h>
-#include <arch/irq.h>
-
-#include "usbhost_registry.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_idmatch
- *
- * Description:
- * Check if the class ID matches what the host controller found.
- *
- * Input Parameters:
- * classid - ID info for the class under consideration.
- * devid - ID info reported by the device.
- *
- * Returned Values:
- * TRUE - the class will support this device.
- *
- ****************************************************************************/
-
-static bool usbhost_idmatch(const struct usbhost_id_s *classid,
- const struct usbhost_id_s *devid)
-{
- uvdbg("Compare to class:%d subclass:%d protocol:%d vid:%04x pid:%04x\n",
- classid->base, classid->subclass, classid->proto,
- classid->vid, classid->pid);
-
- /* The base class ID, subclass and protocol have to match up in any event */
-
- if (devid->base == classid->base &&
- devid->subclass == classid->subclass &&
- devid->proto == classid->proto)
- {
- /* If this is a vendor-specific class ID, then the VID and PID have to
- * match as well.
- */
-
- if (devid->base == USB_CLASS_VENDOR_SPEC)
- {
- /* Vendor specific... do the VID and PID also match? */
-
- if (devid->vid == classid->vid && devid->pid == classid->pid)
- {
- /* Yes.. then we have a match */
-
- return true;
- }
- }
- else
- {
- /* Not vendor specific? Then we have a match */
-
- return true;
- }
- }
-
- /* No match.. not supported */
-
- return false;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_findclass
- *
- * Description:
- * Find a USB host class implementation previously registered by
- * usbhost_registerclass(). On success, an instance of struct
- * usbhost_registry_s will be returned. That instance will contain all of
- * the information that will be needed to obtain and bind a struct
- * usbhost_class_s instance for the device.
- *
- * Input Parameters:
- * id - Identifies the USB device class that has connect to the USB host.
- *
- * Returned Values:
- * On success this function will return a non-NULL instance of struct
- * usbhost_registry_s. NULL will be returned on failure. This function
- * can only fail if (1) id is NULL, or (2) no USB host class is registered
- * that matches the device class ID.
- *
- ****************************************************************************/
-
-const struct usbhost_registry_s *usbhost_findclass(const struct usbhost_id_s *id)
-{
- struct usbhost_registry_s *class;
- irqstate_t flags;
- int ndx;
-
- DEBUGASSERT(id);
- uvdbg("Looking for class:%d subclass:%d protocol:%d vid:%04x pid:%04x\n",
- id->base, id->subclass, id->proto, id->vid, id->pid);
-
- /* g_classregistry is a singly-linkedlist of class ID information added by
- * calls to usbhost_registerclass(). Since this list is accessed from USB
- * host controller interrupt handling logic, accesses to this list must be
- * protected by disabling interrupts.
- */
-
- flags = irqsave();
-
- /* Examine each register class in the linked list */
-
- for (class = g_classregistry; class; class = class->flink)
- {
- /* If the registered class supports more than one ID, subclass, or
- * protocol, then try each.
- */
-
- uvdbg("Checking class:%p nids:%d\n", class, class->nids);
- for (ndx = 0; ndx < class->nids; ndx++)
- {
- /* Did we find a matching ID? */
-
- if (usbhost_idmatch(&class->id[ndx], id))
- {
- /* Yes.. restore interrupts and return the class info */
-
- irqrestore(flags);
- return class;
- }
- }
- }
-
- /* Not found... restore interrupts and return NULL */
-
- irqrestore(flags);
- return NULL;
-}
-
diff --git a/nuttx/drivers/usbhost/usbhost_hidkbd.c b/nuttx/drivers/usbhost/usbhost_hidkbd.c
deleted file mode 100644
index d6a9ceda3..000000000
--- a/nuttx/drivers/usbhost/usbhost_hidkbd.c
+++ /dev/null
@@ -1,2353 +0,0 @@
-/****************************************************************************
- * drivers/usbhost/usbhost_hidkbd.c
- *
- * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <poll.h>
-#include <semaphore.h>
-#include <time.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/arch.h>
-#include <nuttx/wqueue.h>
-
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/usbhost.h>
-#include <nuttx/usb/hid.h>
-
-#ifdef CONFIG_HIDKBD_ENCODED
-# include <nuttx/streams.h>
-# include <nuttx/input/kbd_codec.h>
-#endif
-
-/* Don't compile if prerequisites are not met */
-
-#if defined(CONFIG_USBHOST) && !defined(CONFIG_USBHOST_INT_DISABLE) && CONFIG_NFILE_DESCRIPTORS > 0
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Configuration ************************************************************/
-/* This determines how often the USB keyboard will be polled in units of
- * of microseconds. The default is 100MS.
- */
-
-#ifndef CONFIG_HIDKBD_POLLUSEC
-# define CONFIG_HIDKBD_POLLUSEC (100*1000)
-#endif
-
-/* Worker thread is needed, unfortunately, to handle some cornercase failure
- * conditions. This is kind of wasteful and begs for a re-design.
- */
-
-#ifndef CONFIG_SCHED_WORKQUEUE
-# warning "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)"
-#endif
-
-/* Signals must not be disabled as they are needed by usleep. Need to have
- * CONFIG_DISABLE_SIGNALS=n
- */
-
-#ifdef CONFIG_DISABLE_SIGNALS
-# warning "Signal support is required (CONFIG_DISABLE_SIGNALS)"
-#endif
-
-/* Provide some default values for other configuration settings */
-
-#ifndef CONFIG_HIDKBD_DEFPRIO
-# define CONFIG_HIDKBD_DEFPRIO 50
-#endif
-
-#ifndef CONFIG_HIDKBD_STACKSIZE
-# define CONFIG_HIDKBD_STACKSIZE 1024
-#endif
-
-#ifndef CONFIG_HIDKBD_BUFSIZE
-# define CONFIG_HIDKBD_BUFSIZE 64
-#endif
-
-#ifndef CONFIG_HIDKBD_NPOLLWAITERS
-# define CONFIG_HIDKBD_NPOLLWAITERS 2
-#endif
-
-/* The default is to support scancode mapping for the standard 104 key
- * keyboard. Setting CONFIG_HIDKBD_RAWSCANCODES will disable all scancode
- * mapping; Setting CONFIG_HIDKBD_ALLSCANCODES will enable mapping of all
- * scancodes;
- */
-
-#ifndef CONFIG_HIDKBD_RAWSCANCODES
-# ifdef CONFIG_HIDKBD_ALLSCANCODES
-# define USBHID_NUMSCANCODES (USBHID_KBDUSE_MAX+1)
-# else
-# define USBHID_NUMSCANCODES 104
-# endif
-#endif
-
-/* We cant support encoding of special characters of unless the Keyboard
- * CODEC is enabled.
- */
-
-#ifndef CONFIG_LIB_KBDCODEC
-# undef CONFIG_HIDKBD_ENCODED
-#endif
-
-/* If we are using raw scancodes, then we cannot support encoding of
- * special characters either.
- */
-
-#ifdef CONFIG_HIDKBD_RAWSCANCODES
-# undef CONFIG_HIDKBD_ENCODED
-#endif
-
-/* Driver support ***********************************************************/
-/* This format is used to construct the /dev/kbd[n] device driver path. It
- * defined here so that it will be used consistently in all places.
- */
-
-#define DEV_FORMAT "/dev/kbd%c"
-#define DEV_NAMELEN 11
-
-/* Used in usbhost_cfgdesc() */
-
-#define USBHOST_IFFOUND 0x01 /* Required I/F descriptor found */
-#define USBHOST_EPINFOUND 0x02 /* Required interrupt IN EP descriptor found */
-#define USBHOST_EPOUTFOUND 0x04 /* Optional interrupt OUT EP descriptor found */
-#define USBHOST_RQDFOUND (USBHOST_IFFOUND|USBHOST_EPINFOUND)
-#define USBHOST_ALLFOUND (USBHOST_RQDFOUND|USBHOST_EPOUTFOUND)
-
-#define USBHOST_MAX_CREFS 0x7fff
-
-/* Debug ********************************************************************/
-/* Both CONFIG_DEBUG_INPUT and CONFIG_DEBUG_USB could apply to this file.
- * We assume here that CONFIG_DEBUG_INPUT might be enabled separately, but
- * CONFIG_DEBUG_USB implies both.
- */
-
-#ifndef CONFIG_DEBUG_INPUT
-# undef idbg
-# define idbg udbg
-# undef illdbg
-# define illdbg ulldbg
-# undef ivdbg
-# define ivdbg uvdbg
-# undef illvdbg
-# define illvdbg ullvdbg
-#endif
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This structure contains the internal, private state of the USB host
- * keyboard storage class.
- */
-
-struct usbhost_state_s
-{
- /* This is the externally visible portion of the state */
-
- struct usbhost_class_s class;
-
- /* This is an instance of the USB host driver bound to this class instance */
-
- struct usbhost_driver_s *drvr;
-
- /* The remainder of the fields are provide o the keyboard class driver */
-
- char devchar; /* Character identifying the /dev/kbd[n] device */
- volatile bool disconnected; /* TRUE: Device has been disconnected */
- volatile bool polling; /* TRUE: Poll thread is running */
- volatile bool open; /* TRUE: The keyboard device is open */
- volatile bool waiting; /* TRUE: waiting for keyboard data */
- uint8_t ifno; /* Interface number */
- int16_t crefs; /* Reference count on the driver instance */
- sem_t exclsem; /* Used to maintain mutual exclusive access */
- sem_t waitsem; /* Used to wait for keyboard data */
- FAR uint8_t *tbuffer; /* The allocated transfer buffer */
- size_t tbuflen; /* Size of the allocated transfer buffer */
- pid_t pollpid; /* PID of the poll task */
- struct work_s work; /* For cornercase error handling by the worker thread */
-
- /* Endpoints:
- * EP0 (Control):
- * - Receiving and responding to requests for USB control and class data.
- * - IN data when polled by the HID class driver (Get_Report)
- * - OUT data from the host.
- * EP Interrupt IN:
- * - Receiving asynchronous (unrequested) IN data from the device.
- * EP Interrrupt OUT (optional):
- * - Transmitting low latency OUT data to the device.
- * - If not present, EP0 used.
- */
-
- usbhost_ep_t epin; /* Interrupt IN endpoint */
- usbhost_ep_t epout; /* Optional interrupt OUT endpoint */
-
- /* The following is a list if poll structures of threads waiting for
- * driver events. The 'struct pollfd' reference for each open is also
- * retained in the f_priv field of the 'struct file'.
- */
-
-#ifndef CONFIG_DISABLE_POLL
- struct pollfd *fds[CONFIG_HIDKBD_NPOLLWAITERS];
-#endif
-
- /* Buffer used to collect and buffer incoming keyboard characters */
-
- volatile uint16_t headndx; /* Buffer head index */
- volatile uint16_t tailndx; /* Buffer tail index */
- uint8_t kbdbuffer[CONFIG_HIDKBD_BUFSIZE];
-};
-
-/* This type is used for encoding special characters */
-
-#ifdef CONFIG_HIDKBD_ENCODED
-struct usbhost_outstream_s
-{
- struct lib_outstream_s stream;
- FAR struct usbhost_state_s *priv;
-};
-#endif
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Semaphores */
-
-static void usbhost_takesem(sem_t *sem);
-#define usbhost_givesem(s) sem_post(s);
-
-/* Polling support */
-
-#ifndef CONFIG_DISABLE_POLL
-static void usbhost_pollnotify(FAR struct usbhost_state_s *dev);
-#else
-# define usbhost_pollnotify(dev)
-#endif
-
-/* Memory allocation services */
-
-static inline FAR struct usbhost_state_s *usbhost_allocclass(void);
-static inline void usbhost_freeclass(FAR struct usbhost_state_s *class);
-
-/* Device name management */
-
-static int usbhost_allocdevno(FAR struct usbhost_state_s *priv);
-static void usbhost_freedevno(FAR struct usbhost_state_s *priv);
-static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *devname);
-
-/* Keyboard polling thread */
-
-static void usbhost_destroy(FAR void *arg);
-static void usbhost_putbuffer(FAR struct usbhost_state_s *priv, uint8_t keycode);
-#ifdef CONFIG_HIDKBD_ENCODED
-static void usbhost_putstream(FAR struct lib_outstream_s *this, int ch);
-#endif
-static inline uint8_t usbhost_mapscancode(uint8_t scancode, uint8_t modifier);
-#ifdef CONFIG_HIDKBD_ENCODED
-static inline void usbhost_encodescancode(FAR struct usbhost_state_s *priv,
- uint8_t scancode, uint8_t modifier);
-#endif
-static int usbhost_kbdpoll(int argc, char *argv[]);
-
-/* Helpers for usbhost_connect() */
-
-static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr);
-static inline int usbhost_devinit(FAR struct usbhost_state_s *priv);
-
-/* (Little Endian) Data helpers */
-
-static inline uint16_t usbhost_getle16(const uint8_t *val);
-static inline void usbhost_putle16(uint8_t *dest, uint16_t val);
-static inline uint32_t usbhost_getle32(const uint8_t *val);
-#if 0 /* Not used */
-static void usbhost_putle32(uint8_t *dest, uint32_t val);
-#endif
-
-/* Transfer descriptor memory management */
-
-static inline int usbhost_tdalloc(FAR struct usbhost_state_s *priv);
-static inline int usbhost_tdfree(FAR struct usbhost_state_s *priv);
-
-/* struct usbhost_registry_s methods */
-
-static struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *drvr,
- FAR const struct usbhost_id_s *id);
-
-/* struct usbhost_class_s methods */
-
-static int usbhost_connect(FAR struct usbhost_class_s *class,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr);
-static int usbhost_disconnected(FAR struct usbhost_class_s *class);
-
-/* Driver methods. We export the keyboard as a standard character driver */
-
-static int usbhost_open(FAR struct file *filep);
-static int usbhost_close(FAR struct file *filep);
-static ssize_t usbhost_read(FAR struct file *filep,
- FAR char *buffer, size_t len);
-static ssize_t usbhost_write(FAR struct file *filep,
- FAR const char *buffer, size_t len);
-#ifndef CONFIG_DISABLE_POLL
-static int usbhost_poll(FAR struct file *filep, FAR struct pollfd *fds,
- bool setup);
-#endif
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* This structure provides the registry entry ID informatino that will be
- * used to associate the USB host keyboard class driver to a connected USB
- * device.
- */
-
-static const const struct usbhost_id_s g_id =
-{
- USB_CLASS_HID, /* base */
- USBHID_SUBCLASS_BOOTIF, /* subclass */
- USBHID_PROTOCOL_KEYBOARD, /* proto */
- 0, /* vid */
- 0 /* pid */
-};
-
-/* This is the USB host storage class's registry entry */
-
-static struct usbhost_registry_s g_skeleton =
-{
- NULL, /* flink */
- usbhost_create, /* create */
- 1, /* nids */
- &g_id /* id[] */
-};
-
-static const struct file_operations usbhost_fops =
-{
- usbhost_open, /* open */
- usbhost_close, /* close */
- usbhost_read, /* read */
- usbhost_write, /* write */
- 0, /* seek */
- 0 /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , usbhost_poll /* poll */
-#endif
-};
-
-/* This is a bitmap that is used to allocate device names /dev/kbda-z. */
-
-static uint32_t g_devinuse;
-
-/* The following are used to managed the class creation operation */
-
-static sem_t g_exclsem; /* For mutually exclusive thread creation */
-static sem_t g_syncsem; /* Thread data passing interlock */
-static struct usbhost_state_s *g_priv; /* Data passed to thread */
-
-/* The following tables map keyboard scan codes to printable ASIC
- * characters. There is no support here for function keys or cursor
- * controls.
- */
-
-#ifndef CONFIG_HIDKBD_RAWSCANCODES
-#ifdef CONFIG_HIDKBD_ENCODED
-
-/* The first and last scancode values with encode-able values */
-
-#define FIRST_ENCODING USBHID_KBDUSE_ENTER /* 0x28 Keyboard Return (ENTER) */
-#ifndef CONFIG_HIDKBD_ALLSCANCODES
-# define LAST_ENCODING USBHID_KBDUSE_POWER /* 0x66 Keyboard Power */
-#else
-# define LAST_ENCODING USBHID_KBDUSE_KPDHEXADECIMAL /* 0xdd Keypad Hexadecimal */
-#endif
-
-#define USBHID_NUMENCODINGS (LAST_ENCODING - FIRST_ENCODING + 1)
-
-static const uint8_t encoding[USBHID_NUMENCODINGS] =
-{
- /* 0x28-0x2f: Enter,escape,del,back-tab,space,_,+,{ */
-
- KEYCODE_ENTER, 0, KEYCODE_FWDDEL, KEYCODE_BACKDEL, 0, 0, 0, 0,
-
- /* 0x30-0x37: },|,Non-US tilde,:,",grave tilde,<,> */
-
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* 0x38-0x3f: /,CapsLock,F1,F2,F3,F4,F5,F6 */
-
- 0, KEYCODE_CAPSLOCK, KEYCODE_F1, KEYCODE_F2, KEYCODE_F3, KEYCODE_F4, KEYCODE_F5, KEYCODE_F6,
-
- /* 0x40-0x47: F7,F8,F9,F10,F11,F12,PrtScn,ScrollLock */
-
- KEYCODE_F7, KEYCODE_F8, KEYCODE_F9, KEYCODE_F10, KEYCODE_F11, KEYCODE_F12, KEYCODE_PRTSCRN, KEYCODE_SCROLLLOCK,
-
- /* 0x48-0x4f: Pause,Insert,Home,PageUp,DeleteForward,End,PageDown,RightArrow */
-
- KEYCODE_PAUSE, KEYCODE_INSERT, KEYCODE_HOME, KEYCODE_PAGEUP, KEYCODE_FWDDEL, KEYCODE_END, KEYCODE_PAGEDOWN, KEYCODE_RIGHT,
-
- /* 0x50-0x57: LeftArrow,DownArrow,UpArrow,Num Lock,/,*,-,+ */
-
- KEYCODE_LEFT, KEYCODE_DOWN, KEYCODE_UP, KEYCODE_NUMLOCK, 0, 0, 0, 0,
-
- /* 0x58-0x5f: Enter,1-7 */
-
- KEYCODE_ENTER, 0, 0, 0, 0, 0, 0, 0,
-
- /* 0x60-0x66: 8-9,0,.,Non-US \,Application,Power */
-
- 0, 0, 0, 0, 0, 0, KEYCODE_POWER,
-
-#ifdef CONFIG_HIDKBD_ALLSCANCODES
-
- 0, /* 0x67 = */
-
- /* 0x68-0x6f: F13,F14,F15,F16,F17,F18,F19,F20 */
-
- KEYCODE_F13, KEYCODE_F14, KEYCODE_F15, KEYCODE_F16, KEYCODE_F17, KEYCODE_F18, KEYCODE_F19, KEYCODE_F20,
-
- /* 0x70-0x77: F21,F22,F23,F24,Execute,Help,Menu,Select */
-
- KEYCODE_F21, KEYCODE_F22, KEYCODE_F23, KEYCODE_F24, KEYCODE_EXECUTE, KEYCODE_HELP, KEYCODE_MENU, KEYCODE_SELECT,
-
- /* 0x78-0x7f: Stop,Again,Undo,Cut,Copy,Paste,Find,Mute */
-
- KEYCODE_STOP, KEYCODE_AGAIN, KEYCODE_UNDO, KEYCODE_CUT, KEYCODE_COPY, KEYCODE_PASTE, KEYCODE_FIND, KEYCODE_MUTE,
-
- /* 0x80-0x87: VolUp,VolDown,LCapsLock,lNumLock,LScrollLock,,,=,International1 */
-
- KEYCODE_VOLUP, KEYCODE_VOLDOWN, KEYCODE_LCAPSLOCK, KEYCODE_LNUMLOCK, KEYCODE_LSCROLLLOCK, 0, 0, 0,
-
- /* 0x88-0x8f: International 2-9 */
-
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* 0x90-0x97: LAN 1-8 */
-
- KEYCODE_LANG1, KEYCODE_LANG2, KEYCODE_LANG3, KEYCODE_LANG4, KEYCODE_LANG5, KEYCODE_LANG6, KEYCODE_LANG7, KEYCODE_LANG8,
-
- /* 0x98-0x9f: LAN 9,Erase,SysReq,Cancel,Clear,Prior,Return,Separator */
-
- 0, 0, KEYCODE_SYSREQ, KEYCODE_CANCEL, KEYCODE_CLEAR, 0, KEYCODE_ENTER, 0,
-
- /* 0xa0-0xa7: Out,Oper,Clear,CrSel,Excel,(reserved) */
-
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* 0xa8-0xaf: (reserved) */
-
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* 0xb0-0xb7: 00,000,ThouSeparator,DecSeparator,CurrencyUnit,SubUnit,(,) */
-
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* 0xb8-0xbf: {,},tab,backspace,A-D */
-
- 0, 0, 0, KEYCODE_BACKDEL, 0, 0, 0, 0,
-
- /* 0xc0-0xc7: E-F,XOR,^,%,<,>,& */
-
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* 0xc8-0xcf: &&,|,||,:,#, ,@,! */
-
- 0, 0, 0, 0, 0, 0, 0, 0,
-
- /* 0xd0-0xd7: Memory Store,Recall,Clear,Add,Subtract,Muliply,Divide,+/- */
-
- KEYCODE_MEMSTORE, KEYCODE_MEMRECALL, KEYCODE_MEMCLEAR, KEYCODE_MEMADD, KEYCODE_MEMSUB, KEYCODE_MEMMUL, KEYCODE_MEMDIV, KEYCODE_NEGATE,
-
- /* 0xd8-0xdd: Clear,ClearEntry,Binary,Octal,Decimal,Hexadecimal */
-
- KEYCODE_CLEAR, KEYCODE_CLEARENTRY, KEYCODE_BINARY, KEYCODE_OCTAL, KEYCODE_DECIMAL, KEYCODE_HEXADECIMAL
-#endif
-};
-
-#endif
-
-static const uint8_t ucmap[USBHID_NUMSCANCODES] =
-{
- 0, 0, 0, 0, 'A', 'B', 'C', 'D', /* 0x00-0x07: Reserved, errors, A-D */
- 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', /* 0x08-0x0f: E-L */
- 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 0x10-0x17: M-T */
- 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', /* 0x18-0x1f: U-Z,!,@ */
- '#', '$', '%', '^', '&', '*', '(', ')', /* 0x20-0x27: #,$,%,^,&,*,(,) */
- '\n', '\033', '\177', 0, ' ', '_', '+', '{', /* 0x28-0x2f: Enter,escape,del,back-tab,space,_,+,{ */
- '}', '|', 0, ':', '"', '~', '<', '>', /* 0x30-0x37: },|,Non-US tilde,:,",grave tilde,<,> */
- '?', 0, 0, 0, 0, 0, 0, 0, /* 0x38-0x3f: /,CapsLock,F1,F2,F3,F4,F5,F6 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x47: F7,F8,F9,F10,F11,F12,PrtScn,ScrollLock */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x48-0x4f: Pause,Insert,Home,PageUp,DeleteForward,End,PageDown,RightArrow */
- 0, 0, 0, 0, '/', '*', '-', '+', /* 0x50-0x57: LeftArrow,DownArrow,UpArrow,Num Lock,/,*,-,+ */
- '\n', '1', '2', '3', '4', '5', '6', '7', /* 0x58-0x5f: Enter,1-7 */
- '8', '9', '0', '.', 0, 0, 0, '=', /* 0x60-0x67: 8-9,0,.,Non-US \,Application,Power,= */
-#ifdef CONFIG_HIDKBD_ALLSCANCODES
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x68-0x6f: F13,F14,F15,F16,F17,F18,F19,F20 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77: F21,F22,F23,F24,Execute,Help,Menu,Select */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x78-0x7f: Stop,Again,Undo,Cut,Copy,Paste,Find,Mute */
- 0, 0, 0, 0, 0, ',', 0, 0, /* 0x80-0x87: VolUp,VolDown,LCapsLock,lNumLock,LScrollLock,,,=,International1 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x88-0x8f: International 2-9 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x97: LAN 1-8 */
- 0, 0, 0, 0, 0, 0, '\n', 0, /* 0x98-0x9f: LAN 9,Erase,SysReq,Cancel,Clear,Prior,Return,Separator */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xa7: Out,Oper,Clear,CrSel,Excel,(reserved) */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa8-0xaf: (reserved) */
- 0, 0, 0, 0, 0, 0, '(', ')', /* 0xb0-0xb7: 00,000,ThouSeparator,DecSeparator,CurrencyUnit,SubUnit,(,) */
- '{', '}', '\t', \177, 'A', 'B', 'C', 'D', /* 0xb8-0xbf: {,},tab,backspace,A-D */
- 'F', 'F', 0, '^', '%', '<', '>', '&', /* 0xc0-0xc7: E-F,XOR,^,%,<,>,& */
- 0, '|', 0, ':', '%', ' ', '@', '!', /* 0xc8-0xcf: &&,|,||,:,#, ,@,! */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xd7: Memory Store,Recall,Clear,Add,Subtract,Muliply,Divide,+/- */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd8-0xdf: Clear,ClearEntry,Binary,Octal,Decimal,Hexadecimal */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xe7: Left Ctrl,Shift,Alt,GUI, Right Ctrl,Shift,Alt,GUI */
-#endif
-};
-
-static const uint8_t lcmap[USBHID_NUMSCANCODES] =
-{
- 0, 0, 0, 0, 'a', 'b', 'c', 'd', /* 0x00-0x07: Reserved, errors, a-d */
- 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', /* 0x08-0x0f: e-l */
- 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', /* 0x10-0x17: m-t */
- 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', /* 0x18-0x1f: u-z,1-2 */
- '3', '4', '5', '6', '7', '8', '9', '0', /* 0x20-0x27: 3-9,0 */
- '\n', '\033', '\177', '\t', ' ', '-', '=', '[', /* 0x28-0x2f: Enter,escape,del,tab,space,-,=,[ */
- ']', '\\', '\234', ';', '\'', '`', ',', '.', /* 0x30-0x37: ],\,Non-US pound,;,',grave accent,,,. */
- '/', 0, 0, 0, 0, 0, 0, 0, /* 0x38-0x3f: /,CapsLock,F1,F2,F3,F4,F5,F6 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40-0x47: F7,F8,F9,F10,F11,F12,PrtScn,ScrollLock */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x48-0x4f: Pause,Insert,Home,PageUp,DeleteForward,End,PageDown,RightArrow */
- 0, 0, 0, 0, '/', '*', '-', '+', /* 0x50-0x57: LeftArrow,DownArrow,UpArrow,Num Lock,/,*,-,+ */
- '\n', '1', '2', '3', '4', '5', '6', '7', /* 0x58-0x5f: Enter,1-7 */
- '8', '9', '0', '.', 0, 0, 0, '=', /* 0x60-0x67: 8-9,0,.,Non-US \,Application,Power,= */
-#ifdef CONFIG_HIDKBD_ALLSCANCODES
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x68-0x6f: F13,F14,F15,F16,F17,F18,F19,F20 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77: F21,F22,F23,F24,Execute,Help,Menu,Select */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x78-0x7f: Stop,Again,Undo,Cut,Copy,Paste,Find,Mute */
- 0, 0, 0, 0, 0, ',', 0, 0, /* 0x80-0x87: VolUp,VolDown,LCapsLock,lNumLock,LScrollLock,,,=,International1 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x88-0x8f: International 2-9 */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x97: LAN 1-8 */
- 0, 0, 0, 0, 0, 0, '\n', 0, /* 0x98-0x9f: LAN 9,Erase,SysReq,Cancel,Clear,Prior,Return,Separator */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0-0xa7: Out,Oper,Clear,CrSel,Excel,(reserved) */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa8-0xaf: (reserved) */
- 0, 0, 0, 0, 0, 0, '(', ')', /* 0xb0-0xb7: 00,000,ThouSeparator,DecSeparator,CurrencyUnit,SubUnit,(,) */
- '{', '}', '\t', '\177', 'A', 'B', 'C', 'D', /* 0xb8-0xbf: {,},tab,backspace,A-D */
- 'F', 'F', 0, '^', '%', '<', '>', '&', /* 0xc0-0xc7: E-F,XOR,^,%,<,>,& */
- 0, '|', 0, ':', '%', ' ', '@', '!', /* 0xc8-0xcf: &&,|,||,:,#, ,@,! */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0-0xd7: Memory Store,Recall,Clear,Add,Subtract,Muliply,Divide,+/- */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd8-0xdf: Clear,ClearEntry,Binary,Octal,Decimal,Hexadecimal */
- 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0-0xe7: Left Ctrl,Shift,Alt,GUI, Right Ctrl,Shift,Alt,GUI */
-#endif
-};
-#endif /* CONFIG_HIDKBD_RAWSCANCODES */
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_takesem
- *
- * Description:
- * This is just a wrapper to handle the annoying behavior of semaphore
- * waits that return due to the receipt of a signal.
- *
- ****************************************************************************/
-
-static void usbhost_takesem(sem_t *sem)
-{
- /* Take the semaphore (perhaps waiting) */
-
- while (sem_wait(sem) != 0)
- {
- /* The only case that an error should occr here is if the wait was
- * awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-}
-
-/****************************************************************************
- * Name: usbhost_pollnotify
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static void usbhost_pollnotify(FAR struct usbhost_state_s *priv)
-{
- int i;
-
- for (i = 0; i < CONFIG_HIDKBD_NPOLLWAITERS; i++)
- {
- struct pollfd *fds = priv->fds[i];
- if (fds)
- {
- fds->revents |= (fds->events & POLLIN);
- if (fds->revents != 0)
- {
- uvdbg("Report events: %02x\n", fds->revents);
- sem_post(fds->sem);
- }
- }
- }
-}
-#endif
-
-/****************************************************************************
- * Name: usbhost_allocclass
- *
- * Description:
- * This is really part of the logic that implements the create() method
- * of struct usbhost_registry_s. This function allocates memory for one
- * new class instance.
- *
- * Input Parameters:
- * None
- *
- * Returned Values:
- * On success, this function will return a non-NULL instance of struct
- * usbhost_class_s. NULL is returned on failure; this function will
- * will fail only if there are insufficient resources to create another
- * USB host class instance.
- *
- ****************************************************************************/
-
-static inline FAR struct usbhost_state_s *usbhost_allocclass(void)
-{
- FAR struct usbhost_state_s *priv;
-
- DEBUGASSERT(!up_interrupt_context());
- priv = (FAR struct usbhost_state_s *)kmalloc(sizeof(struct usbhost_state_s));
- uvdbg("Allocated: %p\n", priv);;
- return priv;
-}
-
-/****************************************************************************
- * Name: usbhost_freeclass
- *
- * Description:
- * Free a class instance previously allocated by usbhost_allocclass().
- *
- * Input Parameters:
- * class - A reference to the class instance to be freed.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline void usbhost_freeclass(FAR struct usbhost_state_s *class)
-{
- DEBUGASSERT(class != NULL);
-
- /* Free the class instance. */
-
- uvdbg("Freeing: %p\n", class);;
- kfree(class);
-}
-
-/****************************************************************************
- * Name: Device name management
- *
- * Description:
- * Some tiny functions to coordinate management of device names.
- *
- ****************************************************************************/
-
-static int usbhost_allocdevno(FAR struct usbhost_state_s *priv)
-{
- irqstate_t flags;
- int devno;
-
- flags = irqsave();
- for (devno = 0; devno < 26; devno++)
- {
- uint32_t bitno = 1 << devno;
- if ((g_devinuse & bitno) == 0)
- {
- g_devinuse |= bitno;
- priv->devchar = 'a' + devno;
- irqrestore(flags);
- return OK;
- }
- }
-
- irqrestore(flags);
- return -EMFILE;
-}
-
-static void usbhost_freedevno(FAR struct usbhost_state_s *priv)
-{
- int devno = 'a' - priv->devchar;
-
- if (devno >= 0 && devno < 26)
- {
- irqstate_t flags = irqsave();
- g_devinuse &= ~(1 << devno);
- irqrestore(flags);
- }
-}
-
-static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *devname)
-{
- (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->devchar);
-}
-
-/****************************************************************************
- * Name: usbhost_destroy
- *
- * Description:
- * The USB device has been disconnected and the refernce count on the USB
- * host class instance has gone to 1.. Time to destroy the USB host class
- * instance.
- *
- * Input Parameters:
- * arg - A reference to the class instance to be destroyed.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_destroy(FAR void *arg)
-{
- FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)arg;
- char devname[DEV_NAMELEN];
-
- DEBUGASSERT(priv != NULL);
- uvdbg("crefs: %d\n", priv->crefs);
-
- /* Unregister the driver */
-
- uvdbg("Unregister driver\n");
- usbhost_mkdevname(priv, devname);
- (void)unregister_driver(devname);
-
- /* Release the device name used by this connection */
-
- usbhost_freedevno(priv);
-
- /* Free the interrupt endpoints */
-
- if (priv->epin)
- {
- DRVR_EPFREE(priv->drvr, priv->epin);
- }
-
- if (priv->epout)
- {
- DRVR_EPFREE(priv->drvr, priv->epout);
- }
-
- /* Free any transfer buffers */
-
- usbhost_tdfree(priv);
-
- /* Destroy the semaphores */
-
- sem_destroy(&priv->exclsem);
- sem_destroy(&priv->waitsem);
-
- /* Disconnect the USB host device */
-
- DRVR_DISCONNECT(priv->drvr);
-
- /* And free the class instance. Hmmm.. this may execute on the worker
- * thread and the work structure is part of what is getting freed. That
- * should be okay because once the work contained is removed from the
- * queue, it should not longer be accessed by the worker thread.
- */
-
- usbhost_freeclass(priv);
-}
-
-/****************************************************************************
- * Name: usbhost_putbuffer
- *
- * Description:
- * Add one character to the user buffer.
- *
- * Input Parameters:
- * priv - Driver internal state
- * keycode - The value to add to the user buffer
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_putbuffer(FAR struct usbhost_state_s *priv,
- uint8_t keycode)
-{
- register unsigned int head;
- register unsigned int tail;
-
- /* Copy the next keyboard character into the user buffer. */
-
- head = priv->headndx;
- priv->kbdbuffer[head] = keycode;
-
- /* Increment the head index */
-
- if (++head >= CONFIG_HIDKBD_BUFSIZE)
- {
- head = 0;
- }
-
- /* If the buffer is full, then increment the tail index to make space. Is
- * it better to lose old keystrokes or new?
- */
-
- tail = priv->tailndx;
- if (tail == head)
- {
- if (++tail >= CONFIG_HIDKBD_BUFSIZE)
- {
- tail = 0;
- }
-
- /* Save the updated tail index */
-
- priv->tailndx = tail;
- }
-
- /* Save the updated head index */
-
- priv->headndx = head;
-}
-
-/****************************************************************************
- * Name: usbhost_putstream
- *
- * Description:
- * A wrapper for usbhost_putc that is compatibile with the lib_outstream_s
- * putc methos.
- *
- * Input Parameters:
- * stream - The struct lib_outstream_s reference
- * ch - The character to add to the user buffer
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-#ifdef CONFIG_HIDKBD_ENCODED
-static void usbhost_putstream(FAR struct lib_outstream_s *stream, int ch)
-{
- FAR struct usbhost_outstream_s *privstream = (FAR struct usbhost_outstream_s *)stream;
-
- DEBUGASSERT(privstream && privstream->priv);
- usbhost_putbuffer(privstream->priv, (uint8_t)ch);
- stream->nput++;
-}
-#endif
-
-/****************************************************************************
- * Name: usbhost_mapscancode
- *
- * Description:
- * Map a keyboard scancode to a printable ASCII character. There is no
- * support here for function keys or cursor controls in this version of
- * the driver.
- *
- * Input Parameters:
- * scancode - Scan code to be mapped.
- * modifier - Ctrl,Alt,Shift,GUI modifier bits
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline uint8_t usbhost_mapscancode(uint8_t scancode, uint8_t modifier)
-{
-#ifndef CONFIG_HIDKBD_RAWSCANCODES
- /* Range check */
-
- if (scancode >= USBHID_NUMSCANCODES)
- {
- return 0;
- }
-
- /* Is either shift key pressed? */
-
- if ((modifier & (USBHID_MODIFER_LSHIFT|USBHID_MODIFER_RSHIFT)) != 0)
- {
- return ucmap[scancode];
- }
- else
- {
- return lcmap[scancode];
- }
-#else
- return scancode;
-#endif
-}
-
-/****************************************************************************
- * Name: usbhost_encodescancode
- *
- * Description:
- * Check if the key has a special function encoding and, if it does, add
- * the encoded value to the user buffer.
- *
- * Input Parameters:
- * priv - Driver internal state
- * scancode - Scan code to be mapped.
- * modifier - Ctrl,Alt,Shift,GUI modifier bits
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-#ifdef CONFIG_HIDKBD_ENCODED
-static inline void usbhost_encodescancode(FAR struct usbhost_state_s *priv,
- uint8_t scancode, uint8_t modifier)
-{
- uint8_t encoded;
-
- /* Check if the raw scancode is in a valid range */
-
- if (scancode >= FIRST_ENCODING && scancode <= LAST_ENCODING)
- {
- /* Yes the value is within range */
-
- encoded = encoding[scancode - FIRST_ENCODING];
- ivdbg(" scancode: %02x modifier: %02x encoded: %d\n",
- scancode, modifier, encoded);
-
- if (encoded)
- {
- struct usbhost_outstream_s usbstream;
-
- /* And it does correspond to a special function key */
-
- usbstream.stream.put = usbhost_putstream;
- usbstream.stream.nput = 0;
- usbstream.priv = priv;
-
- /* Add the special function value to the user buffer */
-
- kbd_specpress((enum kbd_keycode_e)encoded,
- (FAR struct lib_outstream_s *)&usbstream);
- }
- }
-}
-#endif
-
-/****************************************************************************
- * Name: usbhost_kbdpoll
- *
- * Description:
- * Periodically check for new keyboard data.
- *
- * Input Parameters:
- * arg - A reference to the class instance to be destroyed.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static int usbhost_kbdpoll(int argc, char *argv[])
-{
- FAR struct usbhost_state_s *priv;
- FAR struct usb_ctrlreq_s *ctrlreq;
-#ifndef CONFIG_HIDKBD_NODEBOUNCE
- uint8_t lastkey[6] = {0, 0, 0, 0, 0, 0};
-#endif
-#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE)
- unsigned int npolls = 0;
-#endif
- unsigned int nerrors = 0;
- bool empty = true;
- bool newstate;
- int ret;
-
- uvdbg("Started\n");
-
- /* Synchronize with the start-up logic. Get the private instance, re-start
- * the start-up logic, and wait a bit to make sure that all of the class
- * creation logic has a chance to run to completion.
- *
- * NOTE: that the reference count is incremented here. Therefore, we know
- * that the driver data structure will remain stable while this thread is
- * running.
- */
-
- priv = g_priv;
- DEBUGASSERT(priv != NULL);
-
- priv->polling = true;
- priv->crefs++;
- usbhost_givesem(&g_syncsem);
- sleep(1);
-
- /* Loop here until the device is disconnected */
-
- uvdbg("Entering poll loop\n");
-
- while (!priv->disconnected)
- {
- /* Make sure that we have exclusive access to the private data
- * structure. There may now be other tasks with the character driver
- * open and actively trying to interact with the class driver.
- */
-
- usbhost_takesem(&priv->exclsem);
-
- /* Format the HID report request:
- *
- * bmRequestType 10100001
- * bRequest GET_REPORT (0x01)
- * wValue Report Type and Report Index
- * wIndex Interface Number
- * wLength Descriptor Length
- * Data Descriptor Data
- */
-
- ctrlreq = (struct usb_ctrlreq_s *)priv->tbuffer;
- ctrlreq->type = USB_REQ_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE;
- ctrlreq->req = USBHID_REQUEST_GETREPORT;
-
- usbhost_putle16(ctrlreq->value, (USBHID_REPORTTYPE_INPUT << 8));
- usbhost_putle16(ctrlreq->index, priv->ifno);
- usbhost_putle16(ctrlreq->len, sizeof(struct usbhid_kbdreport_s));
-
- /* Send HID report request */
-
- ret = DRVR_CTRLIN(priv->drvr, ctrlreq, priv->tbuffer);
- usbhost_givesem(&priv->exclsem);
-
- /* Check for errors -- Bail if an excessive number of errors
- * are encountered.
- */
-
- if (ret != OK)
- {
- nerrors++;
- udbg("ERROR: GETREPORT/INPUT, DRVR_CTRLIN returned: %d/%d\n",
- ret, nerrors);
-
- if (nerrors > 200)
- {
- udbg("Too many errors... aborting: %d\n", nerrors);
- break;
- }
- }
-
- /* The report was received correctly. But ignore the keystrokes if no
- * task has opened the driver.
- */
-
- else if (priv->open)
- {
- struct usbhid_kbdreport_s *rpt = (struct usbhid_kbdreport_s *)priv->tbuffer;
- uint8_t keycode;
- int i;
-
- /* Add the newly received keystrokes to our internal buffer */
-
- usbhost_takesem(&priv->exclsem);
- for (i = 0; i < 6; i++)
- {
- /* Is this key pressed? But not pressed last time?
- * HID spec: "The order of keycodes in array fields has no
- * significance. Order determination is done by the host
- * software comparing the contents of the previous report to
- * the current report. If two or more keys are reported in
- * one report, their order is indeterminate. Keyboards may
- * buffer events that would have otherwise resulted in
- * multiple event in a single report.
- *
- * "'Repeat Rate' and 'Delay Before First Repeat' are
- * implemented by the host and not in the keyboard (this
- * means the BIOS in legacy mode). The host may use the
- * device report rate and the number of reports to determine
- * how long a key is being held down. Alternatively, the host
- * may use its own clock or the idle request for the timing
- * of these features."
- */
-
- if (rpt->key[i] != USBHID_KBDUSE_NONE
-#ifndef CONFIG_HIDKBD_NODEBOUNCE
- && rpt->key[i] != lastkey[i]
-#endif
- )
- {
- /* Yes.. Add it to the buffer. */
-
- /* Map the keyboard scancode to a printable ASCII
- * character. There is no support here for function keys
- * or cursor controls in this version of the driver.
- */
-
- keycode = usbhost_mapscancode(rpt->key[i], rpt->modifier);
- ivdbg("Key %d: %02x keycode:%c modifier: %02x\n",
- i, rpt->key[i], keycode ? keycode : ' ', rpt->modifier);
-
- /* Zero at this point means that the key does not map to a
- * printable character.
- */
-
- if (keycode != 0)
- {
- /* Handle control characters. Zero after this means
- * a valid, NUL character.
- */
-
- if ((rpt->modifier & (USBHID_MODIFER_LCTRL|USBHID_MODIFER_RCTRL)) != 0)
- {
- keycode &= 0x1f;
- }
-
- /* Copy the next keyboard character into the user
- * buffer.
- */
-
- usbhost_putbuffer(priv, keycode);
- }
-
- /* The zero might, however, map to a special keyboard action (such as a
- * cursor movement or function key). Attempt to encode the special key.
- */
-
-#ifdef CONFIG_HIDKBD_ENCODED
- else
- {
- usbhost_encodescancode(priv, rpt->key[i], rpt->modifier);
- }
-#endif
- }
-
- /* Save the scancode (or lack thereof) for key debouncing on
- * next keyboard report.
- */
-
-#ifndef CONFIG_HIDKBD_NODEBOUNCE
- lastkey[i] = rpt->key[i];
-#endif
- }
-
- /* Is there data available? */
-
- newstate = (priv->headndx == priv->tailndx);
- if (!newstate)
- {
- /* Yes.. Is there a thread waiting for keyboard data now? */
-
- if (priv->waiting)
- {
- /* Yes.. wake it up */
-
- usbhost_givesem(&priv->waitsem);
- priv->waiting = false;
- }
-
- /* Did we just transition from no data available to data
- * available? If so, wake up any threads waiting for the
- * POLLIN event.
- */
-
- if (empty)
- {
- usbhost_pollnotify(priv);
- }
- }
-
- empty = newstate;
- usbhost_givesem(&priv->exclsem);
- }
-
- /* If USB debug is on, then provide some periodic indication that
- * polling is still happening.
- */
-
-#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE)
- npolls++;
- if ((npolls & 31) == 0)
- {
- udbg("Still polling: %d\n", npolls);
- }
-#endif
- /* Wait for the required amount (or until a signal is received). We
- * will wake up when either the delay elapses or we are signalled that
- * the device has been disconnected.
- */
-
- usleep(CONFIG_HIDKBD_POLLUSEC);
- }
-
- /* We get here when the driver is removed.. or when too many errors have
- * been encountered.
- *
- * Make sure that we have exclusive access to the private data structure.
- * There may now be other tasks with the character driver open and actively
- * trying to interact with the class driver.
- */
-
- usbhost_takesem(&priv->exclsem);
-
- /* Indicate that we are no longer running and decrement the reference
- * count help by this thread. If there are no other users of the class,
- * we can destroy it now. Otherwise, we have to wait until the all
- * of the file descriptors are closed.
- */
-
- udbg("Keyboard removed, polling halted\n");
- priv->polling = false;
- if (--priv->crefs < 2)
- {
- /* Destroy the instance (while we hold the semaphore!) */
-
- usbhost_destroy(priv);
- }
- else
- {
- /* No, we will destroy the driver instance when it is finally closed */
-
- usbhost_givesem(&priv->exclsem);
- }
-
- return 0;
-}
-
-/****************************************************************************
- * Name: usbhost_cfgdesc
- *
- * Description:
- * This function implements the connect() method of struct
- * usbhost_class_s. This method is a callback into the class
- * implementation. It is used to provide the device's configuration
- * descriptor to the class so that the class may initialize properly
- *
- * Input Parameters:
- * priv - The USB host class instance.
- * configdesc - A pointer to a uint8_t buffer container the configuration descripor.
- * desclen - The length in bytes of the configuration descriptor.
- * funcaddr - The USB address of the function containing the endpoint that EP0
- * controls
- *
- * Returned Values:
- * On success, zero (OK) is returned. On a failure, a negated errno value is
- * returned indicating the nature of the failure
- *
- * Assumptions:
- * This function will *not* be called from an interrupt handler.
- *
- ****************************************************************************/
-
-static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr)
-{
- FAR struct usb_cfgdesc_s *cfgdesc;
- FAR struct usb_desc_s *desc;
- FAR struct usbhost_epdesc_s epindesc;
- FAR struct usbhost_epdesc_s epoutdesc;
- int remaining;
- uint8_t found = 0;
- bool done = false;
- int ret;
-
- DEBUGASSERT(priv != NULL &&
- configdesc != NULL &&
- desclen >= sizeof(struct usb_cfgdesc_s));
-
- /* Verify that we were passed a configuration descriptor */
-
- cfgdesc = (FAR struct usb_cfgdesc_s *)configdesc;
- if (cfgdesc->type != USB_DESC_TYPE_CONFIG)
- {
- return -EINVAL;
- }
-
- /* Get the total length of the configuration descriptor (little endian).
- * It might be a good check to get the number of interfaces here too.
- */
-
- remaining = (int)usbhost_getle16(cfgdesc->totallen);
-
- /* Skip to the next entry descriptor */
-
- configdesc += cfgdesc->len;
- remaining -= cfgdesc->len;
-
- /* Loop where there are more dscriptors to examine */
-
- while (remaining >= sizeof(struct usb_desc_s) && !done)
- {
- /* What is the next descriptor? */
-
- desc = (FAR struct usb_desc_s *)configdesc;
- switch (desc->type)
- {
- /* Interface descriptor. We really should get the number of endpoints
- * from this descriptor too.
- */
-
- case USB_DESC_TYPE_INTERFACE:
- {
- FAR struct usb_ifdesc_s *ifdesc = (FAR struct usb_ifdesc_s *)configdesc;
-
- uvdbg("Interface descriptor\n");
- DEBUGASSERT(remaining >= USB_SIZEOF_IFDESC);
-
- /* Did we already find what we needed from a preceding interface? */
-
- if ((found & USBHOST_RQDFOUND) == USBHOST_RQDFOUND)
- {
- /* Yes.. then break out of the loop and use the preceding
- * interface.
- */
-
- done = true;
- }
- else
- {
- /* Otherwise, save the interface number and discard any
- * endpoints previously found
- */
-
- priv->ifno = ifdesc->ifno;
- found = USBHOST_IFFOUND;
- }
- }
- break;
-
- /* HID descriptor */
-
- case USBHID_DESCTYPE_HID:
- uvdbg("HID descriptor\n");
- break;
-
- /* Endpoint descriptor. We expect one or two interrupt endpoints,
- * a required IN endpoint and an optional OUT endpoint.
- */
-
- case USB_DESC_TYPE_ENDPOINT:
- {
- FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)configdesc;
-
- uvdbg("Endpoint descriptor\n");
- DEBUGASSERT(remaining >= USB_SIZEOF_EPDESC);
-
- /* Check for an interrupt endpoint. */
-
- if ((epdesc->attr & USB_EP_ATTR_XFERTYPE_MASK) == USB_EP_ATTR_XFER_INT)
- {
- /* Yes.. it is a interrupt endpoint. IN or OUT? */
-
- if (USB_ISEPOUT(epdesc->addr))
- {
- /* It is an interrupt OUT endpoint. There not be more than one
- * interrupt OUT endpoint.
- */
-
- if ((found & USBHOST_EPOUTFOUND) != 0)
- {
- /* Oops.. more than one endpoint. We don't know what to do with this. */
-
- return -EINVAL;
- }
- found |= USBHOST_EPOUTFOUND;
-
- /* Save the interrupt OUT endpoint information */
-
- epoutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
- epoutdesc.in = false;
- epoutdesc.funcaddr = funcaddr;
- epoutdesc.xfrtype = USB_EP_ATTR_XFER_INT;
- epoutdesc.interval = epdesc->interval;
- epoutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
- uvdbg("Interrupt OUT EP addr:%d mxpacketsize:%d\n",
- epoutdesc.addr, epoutdesc.mxpacketsize);
- }
- else
- {
- /* It is an interrupt IN endpoint. There should be only
- * one interrupt IN endpoint.
- */
-
- if ((found & USBHOST_EPINFOUND) != 0)
- {
- /* Oops.. more than one endpint. We don't know what
- * to do with this.
- */
-
- return -EINVAL;
- }
- found |= USBHOST_EPINFOUND;
-
- /* Save the interrupt IN endpoint information */
-
- epindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
- epindesc.in = 1;
- epindesc.funcaddr = funcaddr;
- epindesc.xfrtype = USB_EP_ATTR_XFER_INT;
- epindesc.interval = epdesc->interval;
- epindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
- uvdbg("Interrupt IN EP addr:%d mxpacketsize:%d\n",
- epindesc.addr, epindesc.mxpacketsize);
- }
- }
- }
- break;
-
- /* Other descriptors are just ignored for now */
-
- default:
- uvdbg("Other descriptor: %d\n", desc->type);
- break;
- }
-
- /* What we found everything that we are going to find? */
-
- if (found == USBHOST_ALLFOUND)
- {
- /* Yes.. then break out of the loop and use the preceding interface */
-
- done = true;
- }
-
- /* Increment the address of the next descriptor */
-
- configdesc += desc->len;
- remaining -= desc->len;
- }
-
- /* Sanity checking... did we find all of things that we need? */
-
- if ((found & USBHOST_RQDFOUND) != USBHOST_RQDFOUND)
- {
- ulldbg("ERROR: Found IF:%s EPIN:%s\n",
- (found & USBHOST_IFFOUND) != 0 ? "YES" : "NO",
- (found & USBHOST_EPINFOUND) != 0 ? "YES" : "NO");
- return -EINVAL;
- }
-
- /* We are good... Allocate the endpoints. First, the required interrupt
- * IN endpoint.
- */
-
- ret = DRVR_EPALLOC(priv->drvr, &epindesc, &priv->epin);
- if (ret != OK)
- {
- udbg("ERROR: Failed to allocate interrupt IN endpoint\n");
- return ret;
- }
-
- /* Then the optional interrupt OUT endpoint */
-
- ullvdbg("Found EPOOUT:%s\n",
- (found & USBHOST_EPOUTFOUND) != 0 ? "YES" : "NO");
-
- if ((found & USBHOST_EPOUTFOUND) != 0)
- {
- ret = DRVR_EPALLOC(priv->drvr, &epoutdesc, &priv->epout);
- if (ret != OK)
- {
- udbg("ERROR: Failed to allocate interrupt OUT endpoint\n");
- (void)DRVR_EPFREE(priv->drvr, priv->epin);
- return ret;
- }
- }
-
- ullvdbg("Endpoints allocated\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: usbhost_devinit
- *
- * Description:
- * The USB device has been successfully connected. This completes the
- * initialization operations. It is first called after the
- * configuration descriptor has been received.
- *
- * This function is called from the connect() method. This function always
- * executes on the thread of the caller of connect().
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline int usbhost_devinit(FAR struct usbhost_state_s *priv)
-{
- char devname[DEV_NAMELEN];
- int ret;
-
- /* Set aside a transfer buffer for exclusive use by the keyboard class driver */
-
- ret = usbhost_tdalloc(priv);
- if (ret != OK)
- {
- udbg("ERROR: Failed to allocate transfer buffer\n");
- return ret;
- }
-
- /* Increment the reference count. This will prevent usbhost_destroy() from
- * being called asynchronously if the device is removed.
- */
-
- priv->crefs++;
- DEBUGASSERT(priv->crefs == 2);
-
- /* Start a worker task to poll the USB device. It would be nice to used the
- * the NuttX worker thread to do this, but this task needs to wait for events
- * and activities on the worker thread should not involve significant waiting.
- * Having a dedicated thread is more efficient in this sense, but requires more
- * memory resources, primarily for the dedicated stack (CONFIG_HIDKBD_STACKSIZE).
- */
-
- uvdbg("user_start: Start poll task\n");
-
- /* The inputs to a task started by task_create() are very awkard for this
- * purpose. They are really designed for command line tasks (argc/argv). So
- * the following is kludge pass binary data when the keyboard poll task
- * is started.
- *
- * First, make sure we have exclusive access to g_priv (what is the likelihood
- * of this being used? About zero, but we protect it anyway).
- */
-
- usbhost_takesem(&g_exclsem);
- g_priv = priv;
-
-#ifndef CONFIG_CUSTOM_STACK
- priv->pollpid = task_create("usbhost", CONFIG_HIDKBD_DEFPRIO,
- CONFIG_HIDKBD_STACKSIZE,
- (main_t)usbhost_kbdpoll, (const char **)NULL);
-#else
- priv->pollpid = task_create("usbhost", CONFIG_HIDKBD_DEFPRIO,
- (main_t)usbhost_kbdpoll, (const char **)NULL);
-#endif
- if (priv->pollpid == ERROR)
- {
- /* Failed to started the poll thread... probably due to memory resources */
-
- usbhost_givesem(&g_exclsem);
- ret = -ENOMEM;
- goto errout;
- }
-
- /* Now wait for the poll task to get properly initialized */
-
- usbhost_takesem(&g_syncsem);
- usbhost_givesem(&g_exclsem);
-
- /* Register the driver */
-
- uvdbg("Register driver\n");
- usbhost_mkdevname(priv, devname);
- ret = register_driver(devname, &usbhost_fops, 0666, priv);
-
- /* We now have to be concerned about asynchronous modification of crefs
- * because the driver has been registerd.
- */
-
-errout:
- usbhost_takesem(&priv->exclsem);
- priv->crefs--;
- usbhost_givesem(&priv->exclsem);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbhost_getle16
- *
- * Description:
- * Get a (possibly unaligned) 16-bit little endian value.
- *
- * Input Parameters:
- * val - A pointer to the first byte of the little endian value.
- *
- * Returned Values:
- * A uint16_t representing the whole 16-bit integer value
- *
- ****************************************************************************/
-
-static inline uint16_t usbhost_getle16(const uint8_t *val)
-{
- return (uint16_t)val[1] << 8 | (uint16_t)val[0];
-}
-
-/****************************************************************************
- * Name: usbhost_putle16
- *
- * Description:
- * Put a (possibly unaligned) 16-bit little endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the little endian value.
- * val - The 16-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_putle16(uint8_t *dest, uint16_t val)
-{
- dest[0] = val & 0xff; /* Little endian means LS byte first in byte stream */
- dest[1] = val >> 8;
-}
-
-/****************************************************************************
- * Name: usbhost_getle32
- *
- * Description:
- * Get a (possibly unaligned) 32-bit little endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the big endian value.
- * val - The 32-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline uint32_t usbhost_getle32(const uint8_t *val)
-{
- /* Little endian means LS halfword first in byte stream */
-
- return (uint32_t)usbhost_getle16(&val[2]) << 16 | (uint32_t)usbhost_getle16(val);
-}
-
-/****************************************************************************
- * Name: usbhost_putle32
- *
- * Description:
- * Put a (possibly unaligned) 32-bit little endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the little endian value.
- * val - The 32-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-#if 0 /* Not used */
-static void usbhost_putle32(uint8_t *dest, uint32_t val)
-{
- /* Little endian means LS halfword first in byte stream */
-
- usbhost_putle16(dest, (uint16_t)(val & 0xffff));
- usbhost_putle16(dest+2, (uint16_t)(val >> 16));
-}
-#endif
-
-/****************************************************************************
- * Name: usbhost_tdalloc
- *
- * Description:
- * Allocate transfer buffer memory.
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * On sucess, zero (OK) is returned. On failure, an negated errno value
- * is returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-static inline int usbhost_tdalloc(FAR struct usbhost_state_s *priv)
-{
- DEBUGASSERT(priv && priv->tbuffer == NULL);
- return DRVR_ALLOC(priv->drvr, &priv->tbuffer, &priv->tbuflen);
-}
-
-/****************************************************************************
- * Name: usbhost_tdfree
- *
- * Description:
- * Free transfer buffer memory.
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * On sucess, zero (OK) is returned. On failure, an negated errno value
- * is returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-static inline int usbhost_tdfree(FAR struct usbhost_state_s *priv)
-{
- int result = OK;
- DEBUGASSERT(priv);
-
- if (priv->tbuffer)
- {
- DEBUGASSERT(priv->drvr);
- result = DRVR_FREE(priv->drvr, priv->tbuffer);
- priv->tbuffer = NULL;
- priv->tbuflen = 0;
- }
- return result;
-}
-
-/****************************************************************************
- * struct usbhost_registry_s methods
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_create
- *
- * Description:
- * This function implements the create() method of struct usbhost_registry_s.
- * The create() method is a callback into the class implementation. It is
- * used to (1) create a new instance of the USB host class state and to (2)
- * bind a USB host driver "session" to the class instance. Use of this
- * create() method will support environments where there may be multiple
- * USB ports and multiple USB devices simultaneously connected.
- *
- * Input Parameters:
- * drvr - An instance of struct usbhost_driver_s that the class
- * implementation will "bind" to its state structure and will
- * subsequently use to communicate with the USB host driver.
- * id - In the case where the device supports multiple base classes,
- * subclasses, or protocols, this specifies which to configure for.
- *
- * Returned Values:
- * On success, this function will return a non-NULL instance of struct
- * usbhost_class_s that can be used by the USB host driver to communicate
- * with the USB host class. NULL is returned on failure; this function
- * will fail only if the drvr input parameter is NULL or if there are
- * insufficient resources to create another USB host class instance.
- *
- ****************************************************************************/
-
-static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *drvr,
- FAR const struct usbhost_id_s *id)
-{
- FAR struct usbhost_state_s *priv;
-
- /* Allocate a USB host class instance */
-
- priv = usbhost_allocclass();
- if (priv)
- {
- /* Initialize the allocated storage class instance */
-
- memset(priv, 0, sizeof(struct usbhost_state_s));
-
- /* Assign a device number to this class instance */
-
- if (usbhost_allocdevno(priv) == OK)
- {
- /* Initialize class method function pointers */
-
- priv->class.connect = usbhost_connect;
- priv->class.disconnected = usbhost_disconnected;
-
- /* The initial reference count is 1... One reference is held by the driver */
-
- priv->crefs = 1;
-
- /* Initialize semaphores */
-
- sem_init(&priv->exclsem, 0, 1);
- sem_init(&priv->waitsem, 0, 0);
-
- /* Bind the driver to the storage class instance */
-
- priv->drvr = drvr;
-
- /* Return the instance of the USB keyboard class driver */
-
- return &priv->class;
- }
- }
-
- /* An error occurred. Free the allocation and return NULL on all failures */
-
- if (priv)
- {
- usbhost_freeclass(priv);
- }
- return NULL;
-}
-
-/****************************************************************************
- * struct usbhost_class_s methods
- ****************************************************************************/
-/****************************************************************************
- * Name: usbhost_connect
- *
- * Description:
- * This function implements the connect() method of struct
- * usbhost_class_s. This method is a callback into the class
- * implementation. It is used to provide the device's configuration
- * descriptor to the class so that the class may initialize properly
- *
- * Input Parameters:
- * class - The USB host class entry previously obtained from a call to create().
- * configdesc - A pointer to a uint8_t buffer container the configuration descripor.
- * desclen - The length in bytes of the configuration descriptor.
- * funcaddr - The USB address of the function containing the endpoint that EP0
- * controls
- *
- * Returned Values:
- * On success, zero (OK) is returned. On a failure, a negated errno value is
- * returned indicating the nature of the failure
- *
- * NOTE that the class instance remains valid upon return with a failure. It is
- * the responsibility of the higher level enumeration logic to call
- * CLASS_DISCONNECTED to free up the class driver resources.
- *
- * Assumptions:
- * - This function will *not* be called from an interrupt handler.
- * - If this function returns an error, the USB host controller driver
- * must call to DISCONNECTED method to recover from the error
- *
- ****************************************************************************/
-
-static int usbhost_connect(FAR struct usbhost_class_s *class,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr)
-{
- FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)class;
- int ret;
-
- DEBUGASSERT(priv != NULL &&
- configdesc != NULL &&
- desclen >= sizeof(struct usb_cfgdesc_s));
-
- /* Parse the configuration descriptor to get the endpoints */
-
- ret = usbhost_cfgdesc(priv, configdesc, desclen, funcaddr);
- if (ret != OK)
- {
- udbg("usbhost_cfgdesc() failed: %d\n", ret);
- }
- else
- {
- /* Now configure the device and register the NuttX driver */
-
- ret = usbhost_devinit(priv);
- if (ret != OK)
- {
- udbg("usbhost_devinit() failed: %d\n", ret);
- }
- }
-
- /* ERROR handling: Do nothing. If we return and error during connection,
- * the driver is required to call the DISCONNECT method. Possibilities:
- *
- * - Failure occurred before the kbdpoll task was started successfully.
- * In this case, the disconnection will have to be handled on the worker
- * task.
- * - Failure occured after the kbdpoll task was started succesffuly. In
- * this case, the disconnetion can be performed on the kbdpoll thread.
- */
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbhost_disconnected
- *
- * Description:
- * This function implements the disconnected() method of struct
- * usbhost_class_s. This method is a callback into the class
- * implementation. It is used to inform the class that the USB device has
- * been disconnected.
- *
- * Input Parameters:
- * class - The USB host class entry previously obtained from a call to
- * create().
- *
- * Returned Values:
- * On success, zero (OK) is returned. On a failure, a negated errno value
- * is returned indicating the nature of the failure
- *
- * Assumptions:
- * This function may be called from an interrupt handler.
- *
- ****************************************************************************/
-
-static int usbhost_disconnected(struct usbhost_class_s *class)
-{
- FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)class;
-
- DEBUGASSERT(priv != NULL);
-
- /* Set an indication to any users of the keyboard device that the device
- * is no longer available.
- */
-
- priv->disconnected = true;
- ullvdbg("Disconnected\n");
-
- /* Is there a thread waiting for keyboard data that will never come? */
-
- if (priv->waiting)
- {
- /* Yes.. wake it up */
-
- usbhost_givesem(&priv->waitsem);
- priv->waiting = false;
- }
-
- /* Possibilities:
- *
- * - Failure occurred before the kbdpoll task was started successfully.
- * In this case, the disconnection will have to be handled on the worker
- * task.
- * - Failure occured after the kbdpoll task was started succesffuly. In
- * this case, the disconnetion can be performed on the kbdpoll thread.
- */
-
- if (priv->polling)
- {
- /* The polling task is still alive. Signal the keyboard polling task.
- * When that task wakes up, it will decrement the reference count and,
- * perhaps, destroy the class instance. Then it will exit.
- */
-
- (void)kill(priv->pollpid, SIGALRM);
- }
- else
- {
- /* In the case where the failure occurs before the polling task was
- * started. Now what? We are probably executing from an interrupt
- * handler here. We will use the worker thread. This is kind of
- * wasteful and begs for a re-design.
- */
-
- DEBUGASSERT(priv->work.worker == NULL);
- (void)work_queue(HPWORK, &priv->work, usbhost_destroy, priv, 0);
- }
-
- return OK;
-}
-
-/****************************************************************************
- * Character driver methods
- ****************************************************************************/
-/****************************************************************************
- * Name: usbhost_open
- *
- * Description:
- * Standard character driver open method.
- *
- ****************************************************************************/
-
-static int usbhost_open(FAR struct file *filep)
-{
- FAR struct inode *inode;
- FAR struct usbhost_state_s *priv;
- irqstate_t flags;
- int ret;
-
- uvdbg("Entry\n");
- DEBUGASSERT(filep && filep->f_inode);
- inode = filep->f_inode;
- priv = inode->i_private;
-
- /* Make sure that we have exclusive access to the private data structure */
-
- DEBUGASSERT(priv && priv->crefs > 0 && priv->crefs < USBHOST_MAX_CREFS);
- usbhost_takesem(&priv->exclsem);
-
- /* Check if the keyboard device is still connected. We need to disable
- * interrupts momentarily to assure that there are no asynchronous disconnect
- * events.
- */
-
- flags = irqsave();
- if (priv->disconnected)
- {
- /* No... the driver is no longer bound to the class. That means that
- * the USB storage device is no longer connected. Refuse any further
- * attempts to open the driver.
- */
-
- ret = -ENODEV;
- }
- else
- {
- /* Otherwise, just increment the reference count on the driver */
-
- priv->crefs++;
- priv->open = true;
- ret = OK;
- }
- irqrestore(flags);
-
- usbhost_givesem(&priv->exclsem);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbhost_close
- *
- * Description:
- * Standard character driver close method.
- *
- ****************************************************************************/
-
-static int usbhost_close(FAR struct file *filep)
-{
- FAR struct inode *inode;
- FAR struct usbhost_state_s *priv;
-
- uvdbg("Entry\n");
- DEBUGASSERT(filep && filep->f_inode);
- inode = filep->f_inode;
- priv = inode->i_private;
-
- /* Decrement the reference count on the driver */
-
- DEBUGASSERT(priv->crefs > 1);
- usbhost_takesem(&priv->exclsem);
- priv->crefs--;
-
- /* Is this the last reference (other than the one held by the USB host
- * controller driver)
- */
-
- if (priv->crefs <= 1)
- {
- irqstate_t flags;
-
- /* Yes.. then the driver is no longer open */
-
- priv->open = false;
- priv->headndx = 0;
- priv->tailndx = 0;
-
- /* We need to disable interrupts momentarily to assure that there are
- * no asynchronous disconnect events.
- */
-
- flags = irqsave();
-
- /* Check if the USB keyboard device is still connected. If the device is
- * no longer connected, then unregister the driver and free the driver
- * class instance.
- */
-
- if (priv->disconnected)
- {
- /* Destroy the class instance (we can't use priv after this; we can't
- * 'give' the semapore)
- */
-
- usbhost_destroy(priv);
- irqrestore(flags);
- return OK;
- }
- irqrestore(flags);
- }
-
- usbhost_givesem(&priv->exclsem);
- return OK;
-}
-
-/****************************************************************************
- * Name: usbhost_read
- *
- * Description:
- * Standard character driver read method.
- *
- ****************************************************************************/
-
-static ssize_t usbhost_read(FAR struct file *filep, FAR char *buffer, size_t len)
-{
- FAR struct inode *inode;
- FAR struct usbhost_state_s *priv;
- size_t nbytes;
- unsigned int tail;
- int ret;
-
- uvdbg("Entry\n");
- DEBUGASSERT(filep && filep->f_inode && buffer);
- inode = filep->f_inode;
- priv = inode->i_private;
-
- /* Make sure that we have exclusive access to the private data structure */
-
- DEBUGASSERT(priv && priv->crefs > 0 && priv->crefs < USBHOST_MAX_CREFS);
- usbhost_takesem(&priv->exclsem);
-
- /* Check if the keyboard is still connected. We need to disable interrupts
- * momentarily to assure that there are no asynchronous disconnect events.
- */
-
- if (priv->disconnected)
- {
- /* No... the driver is no longer bound to the class. That means that
- * the USB keybaord is no longer connected. Refuse any further attempts
- * to access the driver.
- */
-
- ret = -ENODEV;
- }
- else
- {
- /* Is there keyboard data now? */
-
- while (priv->tailndx == priv->headndx)
- {
- /* No.. were we open non-blocking? */
-
- if (filep->f_oflags & O_NONBLOCK)
- {
- /* Yes.. then return a failure */
-
- ret = -EAGAIN;
- goto errout;
- }
-
- /* Wait for data to be available */
-
- uvdbg("Waiting...\n");
-
- priv->waiting = true;
- usbhost_givesem(&priv->exclsem);
- usbhost_takesem(&priv->waitsem);
- usbhost_takesem(&priv->exclsem);
-
- /* Did the keyboard become disconnected while we were waiting */
-
- if (priv->disconnected)
- {
- ret = -ENODEV;
- goto errout;
- }
- }
-
- /* Read data from our internal buffer of received characters */
-
- for (tail = priv->tailndx, nbytes = 0;
- tail != priv->headndx && nbytes < len;
- nbytes++)
- {
- /* Copy the next keyboard character into the user buffer */
-
- *buffer++ = priv->kbdbuffer[tail];
-
- /* Handle wrap-around of the tail index */
-
- if (++tail >= CONFIG_HIDKBD_BUFSIZE)
- {
- tail = 0;
- }
- }
- ret = nbytes;
-
- /* Update the tail index (pehaps marking the buffer empty) */
-
- priv->tailndx = tail;
- }
-
-errout:
- usbhost_givesem(&priv->exclsem);
- return (ssize_t)ret;
-}
-
-/****************************************************************************
- * Name: usbhost_write
- *
- * Description:
- * Standard character driver write method.
- *
- ****************************************************************************/
-
-static ssize_t usbhost_write(FAR struct file *filep, FAR const char *buffer, size_t len)
-{
- /* We won't try to write to the keyboard */
-
- return -ENOSYS;
-}
-
-/****************************************************************************
- * Name: usbhost_poll
- *
- * Description:
- * Standard character driver poll method.
- *
- ****************************************************************************/
-
-#ifndef CONFIG_DISABLE_POLL
-static int usbhost_poll(FAR struct file *filep, FAR struct pollfd *fds,
- bool setup)
-{
- FAR struct inode *inode;
- FAR struct usbhost_state_s *priv;
- int ret = OK;
- int i;
-
- uvdbg("Entry\n");
- DEBUGASSERT(filep && filep->f_inode && fds);
- inode = filep->f_inode;
- priv = inode->i_private;
-
- /* Make sure that we have exclusive access to the private data structure */
-
- DEBUGASSERT(priv);
- usbhost_takesem(&priv->exclsem);
-
- /* Check if the keyboard is still connected. We need to disable interrupts
- * momentarily to assure that there are no asynchronous disconnect events.
- */
-
- if (priv->disconnected)
- {
- /* No... the driver is no longer bound to the class. That means that
- * the USB keybaord is no longer connected. Refuse any further attempts
- * to access the driver.
- */
-
- ret = -ENODEV;
- }
- else if (setup)
- {
- /* This is a request to set up the poll. Find an availableslot for
- * the poll structure reference
- */
-
- for (i = 0; i < CONFIG_HIDKBD_NPOLLWAITERS; i++)
- {
- /* Find an available slot */
-
- if (!priv->fds[i])
- {
- /* Bind the poll structure and this slot */
-
- priv->fds[i] = fds;
- fds->priv = &priv->fds[i];
- break;
- }
- }
-
- if (i >= CONFIG_HIDKBD_NPOLLWAITERS)
- {
- fds->priv = NULL;
- ret = -EBUSY;
- goto errout;
- }
-
- /* Should we immediately notify on any of the requested events? Notify
- * the POLLIN event if there is buffered keyboard data.
- */
-
- if (priv->headndx != priv->tailndx)
- {
- usbhost_pollnotify(priv);
- }
- }
- else
- {
- /* This is a request to tear down the poll. */
-
- struct pollfd **slot = (struct pollfd **)fds->priv;
- DEBUGASSERT(slot);
-
- /* Remove all memory of the poll setup */
-
- *slot = NULL;
- fds->priv = NULL;
- }
-
-errout:
- sem_post(&priv->exclsem);
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_kbdinit
- *
- * Description:
- * Initialize the USB storage HID keyboard class driver. This function
- * should be called be platform-specific code in order to initialize and
- * register support for the USB host HID keyboard class device.
- *
- * Input Parameters:
- * None
- *
- * Returned Values:
- * On success this function will return zero (OK); A negated errno value
- * will be returned on failure.
- *
- ****************************************************************************/
-
-int usbhost_kbdinit(void)
-{
- /* Perform any one-time initialization of the class implementation */
-
- sem_init(&g_exclsem, 0, 1);
- sem_init(&g_syncsem, 0, 0);
-
- /* Advertise our availability to support (certain) devices */
-
- return usbhost_registerclass(&g_skeleton);
-}
-
-#endif /* CONFIG_USBHOST)&& !CONFIG_USBHOST_INT_DISABLE && CONFIG_NFILE_DESCRIPTORS */
-
-
diff --git a/nuttx/drivers/usbhost/usbhost_registerclass.c b/nuttx/drivers/usbhost/usbhost_registerclass.c
deleted file mode 100644
index f4d1b64af..000000000
--- a/nuttx/drivers/usbhost/usbhost_registerclass.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/****************************************************************************
- * drivers/usbhost/usbhost_registerclass.c
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <arch/irq.h>
-#include <nuttx/usb/usbhost.h>
-
-#include "usbhost_registry.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_registerclass
- *
- * Description:
- * Register a USB host class implementation. The caller provides an
- * instance of struct usbhost_registry_s that contains all of the
- * information that will be needed later to (1) associate the USB host
- * class implementation with a connected USB device, and (2) to obtain and
- * bind a struct usbhost_class_s instance for the device.
- *
- * Input Parameters:
- * class - An write-able instance of struct usbhost_registry_s that will be
- * maintained in a registry.
- *
- * Returned Values:
- * On success, this function will return zero (OK). Otherwise, a negated
- * errno value is returned.
- *
- ****************************************************************************/
-
-int usbhost_registerclass(struct usbhost_registry_s *class)
-{
- irqstate_t flags;
-
- uvdbg("Registering class:%p nids:%d\n", class, class->nids);
-
- /* g_classregistry is a singly-linkedlist of class ID information added by
- * calls to usbhost_registerclass(). Since this list is accessed from USB
- * host controller interrupt handling logic, accesses to this list must be
- * protected by disabling interrupts.
- */
-
- flags = irqsave();
-
- /* Add the new class ID info to the head of the list */
-
- class->flink = g_classregistry;
- g_classregistry = class;
-
- irqrestore(flags);
- return OK;
-}
-
diff --git a/nuttx/drivers/usbhost/usbhost_registry.c b/nuttx/drivers/usbhost/usbhost_registry.c
deleted file mode 100644
index fb2e900e2..000000000
--- a/nuttx/drivers/usbhost/usbhost_registry.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
- * drivers/usbhost/usbhost_registry.c
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <nuttx/usb/usbhost.h>
-
-#include "usbhost_registry.h"
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/* g_classregistry is a singly-linkedlist of class ID information added by
- * calls to usbhost_registerclass(). Since this list is accessed from USB
- * host controller interrupt handling logic, accesses to this list must be
- * protected by disabling interrupts.
- */
-
-struct usbhost_registry_s *g_classregistry;
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
diff --git a/nuttx/drivers/usbhost/usbhost_registry.h b/nuttx/drivers/usbhost/usbhost_registry.h
deleted file mode 100644
index 759a1c66e..000000000
--- a/nuttx/drivers/usbhost/usbhost_registry.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/****************************************************************************
- * drivers/usbhost/usbdev_registry.h
- *
- * Copyright (C) 2010 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#ifndef __DRIVERS_USBHOST_USBHOST_REGISTRY_H
-#define __DRIVERS_USBHOST_USBHOST_REGISTRY_H
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <nuttx/usb/usbhost.h>
-
-/****************************************************************************
- * Definitions
- ****************************************************************************/
-
-/* Configuration ************************************************************/
-
-/****************************************************************************
- * Public Types
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-# define EXTERN extern "C"
-extern "C"
-{
-#else
-# define EXTERN extern
-#endif
-
-/* g_classregistry is a singly-linkedlist of class ID information added by
- * calls to usbhost_registerclass(). Since this list is accessed from USB
- * host controller interrupt handling logic, accesses to this list must be
- * protected by disabling interrupts.
- */
-
-EXTERN struct usbhost_registry_s *g_classregistry;
-
-/************************************************************************************
- * Public Function Prototypes
- ************************************************************************************/
-
-#undef EXTERN
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* #define __DRIVERS_USBHOST_USBHOST_REGISTRY_H */
diff --git a/nuttx/drivers/usbhost/usbhost_skeleton.c b/nuttx/drivers/usbhost/usbhost_skeleton.c
deleted file mode 100644
index c44a265e8..000000000
--- a/nuttx/drivers/usbhost/usbhost_skeleton.c
+++ /dev/null
@@ -1,1060 +0,0 @@
-/****************************************************************************
- * drivers/usbhost/usbhost_skeleton.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <semaphore.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/arch.h>
-#include <nuttx/wqueue.h>
-
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/usbhost.h>
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Configuration ************************************************************/
-
-#ifndef CONFIG_SCHED_WORKQUEUE
-# warning "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)"
-#endif
-
-/* Driver support ***********************************************************/
-/* This format is used to construct the /dev/skel[n] device driver path. It
- * defined here so that it will be used consistently in all places.
- */
-
-#define DEV_FORMAT "/dev/skel%c"
-#define DEV_NAMELEN 12
-
-/* Used in usbhost_cfgdesc() */
-
-#define USBHOST_IFFOUND 0x01
-#define USBHOST_BINFOUND 0x02
-#define USBHOST_BOUTFOUND 0x04
-#define USBHOST_ALLFOUND 0x07
-
-#define USBHOST_MAX_CREFS 0x7fff
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This structure contains the internal, private state of the USB host class
- * driver.
- */
-
-struct usbhost_state_s
-{
- /* This is the externally visible portion of the state */
-
- struct usbhost_class_s class;
-
- /* This is an instance of the USB host driver bound to this class instance */
-
- struct usbhost_driver_s *drvr;
-
- /* The remainder of the fields are provide to the class driver */
-
- char devchar; /* Character identifying the /dev/skel[n] device */
- volatile bool disconnected; /* TRUE: Device has been disconnected */
- uint8_t ifno; /* Interface number */
- int16_t crefs; /* Reference count on the driver instance */
- sem_t exclsem; /* Used to maintain mutual exclusive access */
- struct work_s work; /* For interacting with the worker thread */
- FAR uint8_t *tbuffer; /* The allocated transfer buffer */
- size_t tbuflen; /* Size of the allocated transfer buffer */
- usbhost_ep_t epin; /* IN endpoint */
- usbhost_ep_t epout; /* OUT endpoint */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Semaphores */
-
-static void usbhost_takesem(sem_t *sem);
-#define usbhost_givesem(s) sem_post(s);
-
-/* Memory allocation services */
-
-static inline FAR struct usbhost_state_s *usbhost_allocclass(void);
-static inline void usbhost_freeclass(FAR struct usbhost_state_s *class);
-
-/* Device name management */
-
-static int usbhost_allocdevno(FAR struct usbhost_state_s *priv);
-static void usbhost_freedevno(FAR struct usbhost_state_s *priv);
-static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *devname);
-
-/* Worker thread actions */
-
-static void usbhost_destroy(FAR void *arg);
-
-/* Helpers for usbhost_connect() */
-
-static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr);
-static inline int usbhost_devinit(FAR struct usbhost_state_s *priv);
-
-/* (Little Endian) Data helpers */
-
-static inline uint16_t usbhost_getle16(const uint8_t *val);
-static inline void usbhost_putle16(uint8_t *dest, uint16_t val);
-static inline uint32_t usbhost_getle32(const uint8_t *val);
-static void usbhost_putle32(uint8_t *dest, uint32_t val);
-
-/* Transfer descriptor memory management */
-
-static inline int usbhost_talloc(FAR struct usbhost_state_s *priv);
-static inline int usbhost_tfree(FAR struct usbhost_state_s *priv);
-
-/* struct usbhost_registry_s methods */
-
-static struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *drvr,
- FAR const struct usbhost_id_s *id);
-
-/* struct usbhost_class_s methods */
-
-static int usbhost_connect(FAR struct usbhost_class_s *class,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr);
-static int usbhost_disconnected(FAR struct usbhost_class_s *class);
-
-/* Driver methods -- depend upon the type of NuttX driver interface exported */
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* This structure provides the registry entry ID informatino that will be
- * used to associate the USB class driver to a connected USB device.
- */
-
-static const const struct usbhost_id_s g_id =
-{
- 0, /* base -- Must be one of the USB_CLASS_* definitions in usb.h */
- 0, /* subclass -- depends on the device */
- 0, /* proto -- depends on the device */
- 0, /* vid */
- 0 /* pid */
-};
-
-/* This is the USB host storage class's registry entry */
-
-static struct usbhost_registry_s g_skeleton =
-{
- NULL, /* flink */
- usbhost_create, /* create */
- 1, /* nids */
- &g_id /* id[] */
-};
-
-/* This is a bitmap that is used to allocate device names /dev/skela-z. */
-
-static uint32_t g_devinuse;
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_takesem
- *
- * Description:
- * This is just a wrapper to handle the annoying behavior of semaphore
- * waits that return due to the receipt of a signal.
- *
- ****************************************************************************/
-
-static void usbhost_takesem(sem_t *sem)
-{
- /* Take the semaphore (perhaps waiting) */
-
- while (sem_wait(sem) != 0)
- {
- /* The only case that an error should occr here is if the wait was
- * awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-}
-
-/****************************************************************************
- * Name: usbhost_allocclass
- *
- * Description:
- * This is really part of the logic that implements the create() method
- * of struct usbhost_registry_s. This function allocates memory for one
- * new class instance.
- *
- * Input Parameters:
- * None
- *
- * Returned Values:
- * On success, this function will return a non-NULL instance of struct
- * usbhost_class_s. NULL is returned on failure; this function will
- * will fail only if there are insufficient resources to create another
- * USB host class instance.
- *
- ****************************************************************************/
-
-static inline FAR struct usbhost_state_s *usbhost_allocclass(void)
-{
- FAR struct usbhost_state_s *priv;
-
- DEBUGASSERT(!up_interrupt_context());
- priv = (FAR struct usbhost_state_s *)kmalloc(sizeof(struct usbhost_state_s));
- uvdbg("Allocated: %p\n", priv);;
- return priv;
-}
-
-/****************************************************************************
- * Name: usbhost_freeclass
- *
- * Description:
- * Free a class instance previously allocated by usbhost_allocclass().
- *
- * Input Parameters:
- * class - A reference to the class instance to be freed.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline void usbhost_freeclass(FAR struct usbhost_state_s *class)
-{
- DEBUGASSERT(class != NULL);
-
- /* Free the class instance (perhaps calling sched_free() in case we are
- * executing from an interrupt handler.
- */
-
- uvdbg("Freeing: %p\n", class);;
- kfree(class);
-}
-
-/****************************************************************************
- * Name: Device name management
- *
- * Description:
- * Some tiny functions to coordinate management of device names.
- *
- ****************************************************************************/
-
-static int usbhost_allocdevno(FAR struct usbhost_state_s *priv)
-{
- irqstate_t flags;
- int devno;
-
- flags = irqsave();
- for (devno = 0; devno < 26; devno++)
- {
- uint32_t bitno = 1 << devno;
- if ((g_devinuse & bitno) == 0)
- {
- g_devinuse |= bitno;
- priv->devchar = 'a' + devno;
- irqrestore(flags);
- return OK;
- }
- }
-
- irqrestore(flags);
- return -EMFILE;
-}
-
-static void usbhost_freedevno(FAR struct usbhost_state_s *priv)
-{
- int devno = 'a' - priv->devchar;
-
- if (devno >= 0 && devno < 26)
- {
- irqstate_t flags = irqsave();
- g_devinuse &= ~(1 << devno);
- irqrestore(flags);
- }
-}
-
-static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *devname)
-{
- (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->devchar);
-}
-
-/****************************************************************************
- * Name: usbhost_destroy
- *
- * Description:
- * The USB device has been disconnected and the refernce count on the USB
- * host class instance has gone to 1.. Time to destroy the USB host class
- * instance.
- *
- * Input Parameters:
- * arg - A reference to the class instance to be destroyed.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_destroy(FAR void *arg)
-{
- FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)arg;
-
- DEBUGASSERT(priv != NULL);
- uvdbg("crefs: %d\n", priv->crefs);
-
- /* Unregister the driver */
-
- /* Release the device name used by this connection */
-
- usbhost_freedevno(priv);
-
- /* Free the endpoints */
-
- /* Free any transfer buffers */
-
- /* Destroy the semaphores */
-
- /* Disconnect the USB host device */
-
- DRVR_DISCONNECT(priv->drvr);
-
- /* And free the class instance. Hmmm.. this may execute on the worker
- * thread and the work structure is part of what is getting freed. That
- * should be okay because once the work contained is removed from the
- * queue, it should not longer be accessed by the worker thread.
- */
-
- usbhost_freeclass(priv);
-}
-
-/****************************************************************************
- * Name: usbhost_cfgdesc
- *
- * Description:
- * This function implements the connect() method of struct
- * usbhost_class_s. This method is a callback into the class
- * implementation. It is used to provide the device's configuration
- * descriptor to the class so that the class may initialize properly
- *
- * Input Parameters:
- * priv - The USB host class instance.
- * configdesc - A pointer to a uint8_t buffer container the configuration descripor.
- * desclen - The length in bytes of the configuration descriptor.
- * funcaddr - The USB address of the function containing the endpoint that EP0
- * controls
- *
- * Returned Values:
- * On success, zero (OK) is returned. On a failure, a negated errno value is
- * returned indicating the nature of the failure
- *
- * Assumptions:
- * This function will *not* be called from an interrupt handler.
- *
- ****************************************************************************/
-
-static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr)
-{
- FAR struct usb_cfgdesc_s *cfgdesc;
- FAR struct usb_desc_s *desc;
- FAR struct usbhost_epdesc_s bindesc;
- FAR struct usbhost_epdesc_s boutdesc;
- int remaining;
- uint8_t found = 0;
- int ret;
-
- DEBUGASSERT(priv != NULL &&
- configdesc != NULL &&
- desclen >= sizeof(struct usb_cfgdesc_s));
-
- /* Verify that we were passed a configuration descriptor */
-
- cfgdesc = (FAR struct usb_cfgdesc_s *)configdesc;
- if (cfgdesc->type != USB_DESC_TYPE_CONFIG)
- {
- return -EINVAL;
- }
-
- /* Get the total length of the configuration descriptor (little endian).
- * It might be a good check to get the number of interfaces here too.
- */
-
- remaining = (int)usbhost_getle16(cfgdesc->totallen);
-
- /* Skip to the next entry descriptor */
-
- configdesc += cfgdesc->len;
- remaining -= cfgdesc->len;
-
- /* Loop where there are more dscriptors to examine */
-
- while (remaining >= sizeof(struct usb_desc_s))
- {
- /* What is the next descriptor? */
-
- desc = (FAR struct usb_desc_s *)configdesc;
- switch (desc->type)
- {
- /* Interface descriptor. We really should get the number of endpoints
- * from this descriptor too.
- */
-
- case USB_DESC_TYPE_INTERFACE:
- {
- FAR struct usb_ifdesc_s *ifdesc = (FAR struct usb_ifdesc_s *)configdesc;
-
- uvdbg("Interface descriptor\n");
- DEBUGASSERT(remaining >= USB_SIZEOF_IFDESC);
-
- /* Save the interface number and mark ONLY the interface found */
-
- priv->ifno = ifdesc->ifno;
- found = USBHOST_IFFOUND;
- }
- break;
-
- /* Endpoint descriptor. Here, we expect two bulk endpoints, an IN
- * and an OUT.
- */
-
- case USB_DESC_TYPE_ENDPOINT:
- {
- FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)configdesc;
-
- uvdbg("Endpoint descriptor\n");
- DEBUGASSERT(remaining >= USB_SIZEOF_EPDESC);
-
- /* Check for a bulk endpoint. */
-
- if ((epdesc->attr & USB_EP_ATTR_XFERTYPE_MASK) == USB_EP_ATTR_XFER_BULK)
- {
- /* Yes.. it is a bulk endpoint. IN or OUT? */
-
- if (USB_ISEPOUT(epdesc->addr))
- {
- /* It is an OUT bulk endpoint. There should be only one
- * bulk OUT endpoint.
- */
-
- if ((found & USBHOST_BOUTFOUND) != 0)
- {
- /* Oops.. more than one endpoint. We don't know
- * what to do with this.
- */
-
- return -EINVAL;
- }
- found |= USBHOST_BOUTFOUND;
-
- /* Save the bulk OUT endpoint information */
-
- boutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
- boutdesc.in = false;
- boutdesc.funcaddr = funcaddr;
- boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK;
- boutdesc.interval = epdesc->interval;
- boutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
- uvdbg("Bulk OUT EP addr:%d mxpacketsize:%d\n",
- boutdesc.addr, boutdesc.mxpacketsize);
- }
- else
- {
- /* It is an IN bulk endpoint. There should be only one
- * bulk IN endpoint.
- */
-
- if ((found & USBHOST_BINFOUND) != 0)
- {
- /* Oops.. more than one endpoint. We don't know
- * what to do with this.
- */
-
- return -EINVAL;
- }
- found |= USBHOST_BINFOUND;
-
- /* Save the bulk IN endpoint information */
-
- bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
- bindesc.in = 1;
- bindesc.funcaddr = funcaddr;
- bindesc.xfrtype = USB_EP_ATTR_XFER_BULK;
- bindesc.interval = epdesc->interval;
- bindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
- uvdbg("Bulk IN EP addr:%d mxpacketsize:%d\n",
- bindesc.addr, bindesc.mxpacketsize);
- }
- }
- }
- break;
-
- /* Other descriptors are just ignored for now */
-
- default:
- break;
- }
-
- /* If we found everything we need with this interface, then break out
- * of the loop early.
- */
-
- if (found == USBHOST_ALLFOUND)
- {
- break;
- }
-
- /* Increment the address of the next descriptor */
-
- configdesc += desc->len;
- remaining -= desc->len;
- }
-
- /* Sanity checking... did we find all of things that we need? */
-
- if (found != USBHOST_ALLFOUND)
- {
- ulldbg("ERROR: Found IF:%s BIN:%s BOUT:%s\n",
- (found & USBHOST_IFFOUND) != 0 ? "YES" : "NO",
- (found & USBHOST_BINFOUND) != 0 ? "YES" : "NO",
- (found & USBHOST_BOUTFOUND) != 0 ? "YES" : "NO");
- return -EINVAL;
- }
-
- /* We are good... Allocate the endpoints */
-
- ret = DRVR_EPALLOC(priv->drvr, &boutdesc, &priv->epout);
- if (ret != OK)
- {
- udbg("ERROR: Failed to allocate Bulk OUT endpoint\n");
- return ret;
- }
-
- ret = DRVR_EPALLOC(priv->drvr, &bindesc, &priv->epin);
- if (ret != OK)
- {
- udbg("ERROR: Failed to allocate Bulk IN endpoint\n");
- (void)DRVR_EPFREE(priv->drvr, priv->epout);
- return ret;
- }
-
- ullvdbg("Endpoints allocated\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: usbhost_devinit
- *
- * Description:
- * The USB device has been successfully connected. This completes the
- * initialization operations. It is first called after the
- * configuration descriptor has been received.
- *
- * This function is called from the connect() method. This function always
- * executes on the thread of the caller of connect().
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline int usbhost_devinit(FAR struct usbhost_state_s *priv)
-{
- int ret = OK;
-
- /* Set aside a transfer buffer for exclusive use by the class driver */
-
- /* Increment the reference count. This will prevent usbhost_destroy() from
- * being called asynchronously if the device is removed.
- */
-
- priv->crefs++;
- DEBUGASSERT(priv->crefs == 2);
-
- /* Configure the device */
-
- /* Register the driver */
-
- if (ret == OK)
- {
- char devname[DEV_NAMELEN];
-
- uvdbg("Register block driver\n");
- usbhost_mkdevname(priv, devname);
- // ret = register_blockdriver(devname, &g_bops, 0, priv);
- }
-
- /* Check if we successfully initialized. We now have to be concerned
- * about asynchronous modification of crefs because the block
- * driver has been registerd.
- */
-
- if (ret == OK)
- {
- usbhost_takesem(&priv->exclsem);
- DEBUGASSERT(priv->crefs >= 2);
-
- /* Handle a corner case where (1) open() has been called so the
- * reference count is > 2, but the device has been disconnected.
- * In this case, the class instance needs to persist until close()
- * is called.
- */
-
- if (priv->crefs <= 2 && priv->disconnected)
- {
- /* We don't have to give the semaphore because it will be
- * destroyed when usb_destroy is called.
- */
-
- ret = -ENODEV;
- }
- else
- {
- /* Ready for normal operation as a block device driver */
-
- uvdbg("Successfully initialized\n");
- priv->crefs--;
- usbhost_givesem(&priv->exclsem);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbhost_getle16
- *
- * Description:
- * Get a (possibly unaligned) 16-bit little endian value.
- *
- * Input Parameters:
- * val - A pointer to the first byte of the little endian value.
- *
- * Returned Values:
- * A uint16_t representing the whole 16-bit integer value
- *
- ****************************************************************************/
-
-static inline uint16_t usbhost_getle16(const uint8_t *val)
-{
- return (uint16_t)val[1] << 8 | (uint16_t)val[0];
-}
-
-/****************************************************************************
- * Name: usbhost_putle16
- *
- * Description:
- * Put a (possibly unaligned) 16-bit little endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the little endian value.
- * val - The 16-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_putle16(uint8_t *dest, uint16_t val)
-{
- dest[0] = val & 0xff; /* Little endian means LS byte first in byte stream */
- dest[1] = val >> 8;
-}
-
-/****************************************************************************
- * Name: usbhost_getle32
- *
- * Description:
- * Get a (possibly unaligned) 32-bit little endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the big endian value.
- * val - The 32-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline uint32_t usbhost_getle32(const uint8_t *val)
-{
- /* Little endian means LS halfword first in byte stream */
-
- return (uint32_t)usbhost_getle16(&val[2]) << 16 | (uint32_t)usbhost_getle16(val);
-}
-
-/****************************************************************************
- * Name: usbhost_putle32
- *
- * Description:
- * Put a (possibly unaligned) 32-bit little endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the little endian value.
- * val - The 32-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_putle32(uint8_t *dest, uint32_t val)
-{
- /* Little endian means LS halfword first in byte stream */
-
- usbhost_putle16(dest, (uint16_t)(val & 0xffff));
- usbhost_putle16(dest+2, (uint16_t)(val >> 16));
-}
-
-/****************************************************************************
- * Name: usbhost_talloc
- *
- * Description:
- * Allocate transfer buffer memory.
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * On sucess, zero (OK) is returned. On failure, an negated errno value
- * is returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-static inline int usbhost_talloc(FAR struct usbhost_state_s *priv)
-{
- DEBUGASSERT(priv && priv->tbuffer == NULL);
- return DRVR_ALLOC(priv->drvr, &priv->tbuffer, &priv->tbuflen);
-}
-
-/****************************************************************************
- * Name: usbhost_tfree
- *
- * Description:
- * Free transfer buffer memory.
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * On sucess, zero (OK) is returned. On failure, an negated errno value
- * is returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-static inline int usbhost_tfree(FAR struct usbhost_state_s *priv)
-{
- int result = OK;
- DEBUGASSERT(priv);
-
- if (priv->tbuffer)
- {
- DEBUGASSERT(priv->drvr);
- result = DRVR_FREE(priv->drvr, priv->tbuffer);
- priv->tbuffer = NULL;
- priv->tbuflen = 0;
- }
- return result;
-}
-
-/****************************************************************************
- * struct usbhost_registry_s methods
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_create
- *
- * Description:
- * This function implements the create() method of struct usbhost_registry_s.
- * The create() method is a callback into the class implementation. It is
- * used to (1) create a new instance of the USB host class state and to (2)
- * bind a USB host driver "session" to the class instance. Use of this
- * create() method will support environments where there may be multiple
- * USB ports and multiple USB devices simultaneously connected.
- *
- * Input Parameters:
- * drvr - An instance of struct usbhost_driver_s that the class
- * implementation will "bind" to its state structure and will
- * subsequently use to communicate with the USB host driver.
- * id - In the case where the device supports multiple base classes,
- * subclasses, or protocols, this specifies which to configure for.
- *
- * Returned Values:
- * On success, this function will return a non-NULL instance of struct
- * usbhost_class_s that can be used by the USB host driver to communicate
- * with the USB host class. NULL is returned on failure; this function
- * will fail only if the drvr input parameter is NULL or if there are
- * insufficient resources to create another USB host class instance.
- *
- ****************************************************************************/
-
-static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *drvr,
- FAR const struct usbhost_id_s *id)
-{
- FAR struct usbhost_state_s *priv;
-
- /* Allocate a USB host class instance */
-
- priv = usbhost_allocclass();
- if (priv)
- {
- /* Initialize the allocated storage class instance */
-
- memset(priv, 0, sizeof(struct usbhost_state_s));
-
- /* Assign a device number to this class instance */
-
- if (usbhost_allocdevno(priv) == OK)
- {
- /* Initialize class method function pointers */
-
- priv->class.connect = usbhost_connect;
- priv->class.disconnected = usbhost_disconnected;
-
- /* The initial reference count is 1... One reference is held by the driver */
-
- priv->crefs = 1;
-
- /* Initialize semphores (this works okay in the interrupt context) */
-
- sem_init(&priv->exclsem, 0, 1);
-
- /* Bind the driver to the storage class instance */
-
- priv->drvr = drvr;
-
- /* Return the instance of the USB class driver */
-
- return &priv->class;
- }
- }
-
- /* An error occurred. Free the allocation and return NULL on all failures */
-
- if (priv)
- {
- usbhost_freeclass(priv);
- }
- return NULL;
-}
-
-/****************************************************************************
- * struct usbhost_class_s methods
- ****************************************************************************/
-/****************************************************************************
- * Name: usbhost_connect
- *
- * Description:
- * This function implements the connect() method of struct
- * usbhost_class_s. This method is a callback into the class
- * implementation. It is used to provide the device's configuration
- * descriptor to the class so that the class may initialize properly
- *
- * Input Parameters:
- * class - The USB host class entry previously obtained from a call to create().
- * configdesc - A pointer to a uint8_t buffer container the configuration descripor.
- * desclen - The length in bytes of the configuration descriptor.
- * funcaddr - The USB address of the function containing the endpoint that EP0
- * controls
- *
- * Returned Values:
- * On success, zero (OK) is returned. On a failure, a negated errno value is
- * returned indicating the nature of the failure
- *
- * NOTE that the class instance remains valid upon return with a failure. It is
- * the responsibility of the higher level enumeration logic to call
- * CLASS_DISCONNECTED to free up the class driver resources.
- *
- * Assumptions:
- * - This function will *not* be called from an interrupt handler.
- * - If this function returns an error, the USB host controller driver
- * must call to DISCONNECTED method to recover from the error
- *
- ****************************************************************************/
-
-static int usbhost_connect(FAR struct usbhost_class_s *class,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr)
-{
- FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)class;
- int ret;
-
- DEBUGASSERT(priv != NULL &&
- configdesc != NULL &&
- desclen >= sizeof(struct usb_cfgdesc_s));
-
- /* Parse the configuration descriptor to get the endpoints */
-
- ret = usbhost_cfgdesc(priv, configdesc, desclen, funcaddr);
- if (ret != OK)
- {
- udbg("usbhost_cfgdesc() failed: %d\n", ret);
- }
- else
- {
- /* Now configure the device and register the NuttX driver */
-
- ret = usbhost_devinit(priv);
- if (ret != OK)
- {
- udbg("usbhost_devinit() failed: %d\n", ret);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbhost_disconnected
- *
- * Description:
- * This function implements the disconnected() method of struct
- * usbhost_class_s. This method is a callback into the class
- * implementation. It is used to inform the class that the USB device has
- * been disconnected.
- *
- * Input Parameters:
- * class - The USB host class entry previously obtained from a call to
- * create().
- *
- * Returned Values:
- * On success, zero (OK) is returned. On a failure, a negated errno value
- * is returned indicating the nature of the failure
- *
- * Assumptions:
- * This function may be called from an interrupt handler.
- *
- ****************************************************************************/
-
-static int usbhost_disconnected(struct usbhost_class_s *class)
-{
- FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)class;
- irqstate_t flags;
-
- DEBUGASSERT(priv != NULL);
-
- /* Set an indication to any users of the device that the device is no
- * longer available.
- */
-
- flags = irqsave();
- priv->disconnected = true;
-
- /* Now check the number of references on the class instance. If it is one,
- * then we can free the class instance now. Otherwise, we will have to
- * wait until the holders of the references free them by closing the
- * block driver.
- */
-
- ullvdbg("crefs: %d\n", priv->crefs);
- if (priv->crefs == 1)
- {
- /* Destroy the class instance. If we are executing from an interrupt
- * handler, then defer the destruction to the worker thread.
- * Otherwise, destroy the instance now.
- */
-
- if (up_interrupt_context())
- {
- /* Destroy the instance on the worker thread. */
-
- uvdbg("Queuing destruction: worker %p->%p\n", priv->work.worker, usbhost_destroy);
- DEBUGASSERT(priv->work.worker == NULL);
- (void)work_queue(HPWORK, &priv->work, usbhost_destroy, priv, 0);
- }
- else
- {
- /* Do the work now */
-
- usbhost_destroy(priv);
- }
- }
-
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_skelinit
- *
- * Description:
- * Initialize the USB class driver. This function should be called
- * be platform-specific code in order to initialize and register support
- * for the USB host class device.
- *
- * Input Parameters:
- * None
- *
- * Returned Values:
- * On success this function will return zero (OK); A negated errno value
- * will be returned on failure.
- *
- ****************************************************************************/
-
-int usbhost_skelinit(void)
-{
- /* Perform any one-time initialization of the class implementation */
-
- /* Advertise our availability to support (certain) devices */
-
- return usbhost_registerclass(&g_skeleton);
-}
diff --git a/nuttx/drivers/usbhost/usbhost_storage.c b/nuttx/drivers/usbhost/usbhost_storage.c
deleted file mode 100644
index 2b14676d7..000000000
--- a/nuttx/drivers/usbhost/usbhost_storage.c
+++ /dev/null
@@ -1,2244 +0,0 @@
-/****************************************************************************
- * drivers/usbhost/usbhost_storage.c
- *
- * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <semaphore.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/fs/fs.h>
-#include <nuttx/arch.h>
-#include <nuttx/wqueue.h>
-#include <nuttx/scsi.h>
-
-#include <nuttx/usb/usb.h>
-#include <nuttx/usb/usbhost.h>
-#include <nuttx/usb/storage.h>
-
-/* Don't compile if prerequisites are not met */
-
-#if defined(CONFIG_USBHOST) && !defined(CONFIG_USBHOST_BULK_DISABLE) && \
- !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* Configuration ************************************************************/
-
-#ifndef CONFIG_SCHED_WORKQUEUE
-# warning "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)"
-#endif
-
-/* If the create() method is called by the USB host device driver from an
- * interrupt handler, then it will be unable to call kmalloc() in order to
- * allocate a new class instance. If the create() method is called from the
- * interrupt level, then class instances must be pre-allocated.
- */
-
-#ifndef CONFIG_USBHOST_NPREALLOC
-# define CONFIG_USBHOST_NPREALLOC 0
-#endif
-
-#if CONFIG_USBHOST_NPREALLOC > 26
-# error "Currently limited to 26 devices /dev/sda-z"
-#endif
-
-/* Driver support ***********************************************************/
-/* This format is used to construct the /dev/sd[n] device driver path. It
- * defined here so that it will be used consistently in all places.
- */
-
-#define DEV_FORMAT "/dev/sd%c"
-#define DEV_NAMELEN 10
-
-/* Used in usbhost_connect() */
-
-#define USBHOST_IFFOUND 0x01
-#define USBHOST_BINFOUND 0x02
-#define USBHOST_BOUTFOUND 0x04
-#define USBHOST_ALLFOUND 0x07
-
-#define USBHOST_MAX_RETRIES 100
-#define USBHOST_MAX_CREFS 0x7fff
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* This structure contains the internal, private state of the USB host mass
- * storage class.
- */
-
-struct usbhost_state_s
-{
- /* This is the externally visible portion of the state */
-
- struct usbhost_class_s class;
-
- /* This is an instance of the USB host driver bound to this class instance */
-
- struct usbhost_driver_s *drvr;
-
- /* The remainder of the fields are provide to the mass storage class */
-
- char sdchar; /* Character identifying the /dev/sd[n] device */
- volatile bool disconnected; /* TRUE: Device has been disconnected */
- uint8_t ifno; /* Interface number */
- int16_t crefs; /* Reference count on the driver instance */
- uint16_t blocksize; /* Block size of USB mass storage device */
- uint32_t nblocks; /* Number of blocks on the USB mass storage device */
- sem_t exclsem; /* Used to maintain mutual exclusive access */
- struct work_s work; /* For interacting with the worker thread */
- FAR uint8_t *tbuffer; /* The allocated transfer buffer */
- size_t tbuflen; /* Size of the allocated transfer buffer */
- usbhost_ep_t bulkin; /* Bulk IN endpoint */
- usbhost_ep_t bulkout; /* Bulk OUT endpoint */
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/* Semaphores */
-
-static void usbhost_takesem(sem_t *sem);
-#define usbhost_givesem(s) sem_post(s);
-
-/* Memory allocation services */
-
-static inline FAR struct usbhost_state_s *usbhost_allocclass(void);
-static inline void usbhost_freeclass(FAR struct usbhost_state_s *class);
-
-/* Device name management */
-
-static int usbhost_allocdevno(FAR struct usbhost_state_s *priv);
-static void usbhost_freedevno(FAR struct usbhost_state_s *priv);
-static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *devname);
-
-/* CBW/CSW debug helpers */
-
-#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE)
-static void usbhost_dumpcbw(FAR struct usbmsc_cbw_s *cbw);
-static void usbhost_dumpcsw(FAR struct usbmsc_csw_s *csw);
-#else
-# define usbhost_dumpcbw(cbw);
-# define usbhost_dumpcsw(csw);
-#endif
-
-/* CBW helpers */
-
-static inline void usbhost_requestsensecbw(FAR struct usbmsc_cbw_s *cbw);
-static inline void usbhost_testunitreadycbw(FAR struct usbmsc_cbw_s *cbw);
-static inline void usbhost_readcapacitycbw(FAR struct usbmsc_cbw_s *cbw);
-static inline void usbhost_inquirycbw (FAR struct usbmsc_cbw_s *cbw);
-static inline void usbhost_readcbw (size_t startsector, uint16_t blocksize,
- unsigned int nsectors,
- FAR struct usbmsc_cbw_s *cbw);
-static inline void usbhost_writecbw(size_t startsector, uint16_t blocksize,
- unsigned int nsectors,
- FAR struct usbmsc_cbw_s *cbw);
-/* Command helpers */
-
-static inline int usbhost_maxlunreq(FAR struct usbhost_state_s *priv);
-static inline int usbhost_testunitready(FAR struct usbhost_state_s *priv);
-static inline int usbhost_requestsense(FAR struct usbhost_state_s *priv);
-static inline int usbhost_readcapacity(FAR struct usbhost_state_s *priv);
-static inline int usbhost_inquiry(FAR struct usbhost_state_s *priv);
-
-/* Worker thread actions */
-
-static void usbhost_destroy(FAR void *arg);
-
-/* Helpers for usbhost_connect() */
-
-static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr);
-static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv);
-
-/* (Little Endian) Data helpers */
-
-static inline uint16_t usbhost_getle16(const uint8_t *val);
-static inline uint16_t usbhost_getbe16(const uint8_t *val);
-static inline void usbhost_putle16(uint8_t *dest, uint16_t val);
-static inline void usbhost_putbe16(uint8_t *dest, uint16_t val);
-static inline uint32_t usbhost_getle32(const uint8_t *val);
-static inline uint32_t usbhost_getbe32(const uint8_t *val);
-static void usbhost_putle32(uint8_t *dest, uint32_t val);
-static void usbhost_putbe32(uint8_t *dest, uint32_t val);
-
-/* Transfer descriptor memory management */
-
-static inline int usbhost_talloc(FAR struct usbhost_state_s *priv);
-static inline int usbhost_tfree(FAR struct usbhost_state_s *priv);
-static FAR struct usbmsc_cbw_s *usbhost_cbwalloc(FAR struct usbhost_state_s *priv);
-
-/* struct usbhost_registry_s methods */
-
-static struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *drvr,
- FAR const struct usbhost_id_s *id);
-
-/* struct usbhost_class_s methods */
-
-static int usbhost_connect(FAR struct usbhost_class_s *class,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr);
-static int usbhost_disconnected(FAR struct usbhost_class_s *class);
-
-/* struct block_operations methods */
-
-static int usbhost_open(FAR struct inode *inode);
-static int usbhost_close(FAR struct inode *inode);
-static ssize_t usbhost_read(FAR struct inode *inode, FAR unsigned char *buffer,
- size_t startsector, unsigned int nsectors);
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t usbhost_write(FAR struct inode *inode,
- FAR const unsigned char *buffer, size_t startsector,
- unsigned int nsectors);
-#endif
-static int usbhost_geometry(FAR struct inode *inode,
- FAR struct geometry *geometry);
-static int usbhost_ioctl(FAR struct inode *inode, int cmd,
- unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* This structure provides the registry entry ID informatino that will be
- * used to associate the USB host mass storage class to a connected USB
- * device.
- */
-
-static const const struct usbhost_id_s g_id =
-{
- USB_CLASS_MASS_STORAGE, /* base */
- USBMSC_SUBCLASS_SCSI, /* subclass */
- USBMSC_PROTO_BULKONLY, /* proto */
- 0, /* vid */
- 0 /* pid */
-};
-
-/* This is the USB host storage class's registry entry */
-
-static struct usbhost_registry_s g_storage =
-{
- NULL, /* flink */
- usbhost_create, /* create */
- 1, /* nids */
- &g_id /* id[] */
-};
-
-/* Block driver operations. This is the interface exposed to NuttX by the
- * class that permits it to behave like a block driver.
- */
-
-static const struct block_operations g_bops =
-{
- usbhost_open, /* open */
- usbhost_close, /* close */
- usbhost_read, /* read */
-#ifdef CONFIG_FS_WRITABLE
- usbhost_write, /* write */
-#else
- NULL, /* write */
-#endif
- usbhost_geometry, /* geometry */
- usbhost_ioctl /* ioctl */
-};
-
-/* This is an array of pre-allocated USB host storage class instances */
-
-#if CONFIG_USBHOST_NPREALLOC > 0
-static struct usbhost_state_s g_prealloc[CONFIG_USBHOST_NPREALLOC];
-#endif
-
-/* This is a list of free, pre-allocated USB host storage class instances */
-
-#if CONFIG_USBHOST_NPREALLOC > 0
-static struct usbhost_state_s *g_freelist;
-#endif
-
-/* This is a bitmap that is used to allocate device names /dev/sda-z. */
-
-static uint32_t g_devinuse;
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_takesem
- *
- * Description:
- * This is just a wrapper to handle the annoying behavior of semaphore
- * waits that return due to the receipt of a signal.
- *
- ****************************************************************************/
-
-static void usbhost_takesem(sem_t *sem)
-{
- /* Take the semaphore (perhaps waiting) */
-
- while (sem_wait(sem) != 0)
- {
- /* The only case that an error should occr here is if the wait was
- * awakened by a signal.
- */
-
- ASSERT(errno == EINTR);
- }
-}
-
-/****************************************************************************
- * Name: usbhost_allocclass
- *
- * Description:
- * This is really part of the logic that implements the create() method
- * of struct usbhost_registry_s. This function allocates memory for one
- * new class instance.
- *
- * Input Parameters:
- * None
- *
- * Returned Values:
- * On success, this function will return a non-NULL instance of struct
- * usbhost_class_s. NULL is returned on failure; this function will
- * will fail only if there are insufficient resources to create another
- * USB host class instance.
- *
- ****************************************************************************/
-
-#if CONFIG_USBHOST_NPREALLOC > 0
-static inline FAR struct usbhost_state_s *usbhost_allocclass(void)
-{
- struct usbhost_state_s *priv;
- irqstate_t flags;
-
- /* We may be executing from an interrupt handler so we need to take one of
- * our pre-allocated class instances from the free list.
- */
-
- flags = irqsave();
- priv = g_freelist;
- if (priv)
- {
- g_freelist = priv->class.flink;
- priv->class.flink = NULL;
- }
- irqrestore(flags);
- ullvdbg("Allocated: %p\n", priv);;
- return priv;
-}
-#else
-static inline FAR struct usbhost_state_s *usbhost_allocclass(void)
-{
- FAR struct usbhost_state_s *priv;
-
- /* We are not executing from an interrupt handler so we can just call
- * kmalloc() to get memory for the class instance.
- */
-
- DEBUGASSERT(!up_interrupt_context());
- priv = (FAR struct usbhost_state_s *)kmalloc(sizeof(struct usbhost_state_s));
- uvdbg("Allocated: %p\n", priv);;
- return priv;
-}
-#endif
-
-/****************************************************************************
- * Name: usbhost_freeclass
- *
- * Description:
- * Free a class instance previously allocated by usbhost_allocclass().
- *
- * Input Parameters:
- * class - A reference to the class instance to be freed.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-#if CONFIG_USBHOST_NPREALLOC > 0
-static inline void usbhost_freeclass(FAR struct usbhost_state_s *class)
-{
- irqstate_t flags;
- DEBUGASSERT(class != NULL);
-
- ullvdbg("Freeing: %p\n", class);;
-
- /* Just put the pre-allocated class structure back on the freelist */
-
- flags = irqsave();
- class->class.flink = g_freelist;
- g_freelist = class;
- irqrestore(flags);
-}
-#else
-static inline void usbhost_freeclass(FAR struct usbhost_state_s *class)
-{
- DEBUGASSERT(class != NULL);
-
- /* Free the class instance (calling sched_free() in case we are executing
- * from an interrupt handler.
- */
-
- uvdbg("Freeing: %p\n", class);;
- kfree(class);
-}
-#endif
-
-/****************************************************************************
- * Name: Device name management
- *
- * Description:
- * Some tiny functions to coordinate management of mass storage device names.
- *
- ****************************************************************************/
-
-static int usbhost_allocdevno(FAR struct usbhost_state_s *priv)
-{
- irqstate_t flags;
- int devno;
-
- flags = irqsave();
- for (devno = 0; devno < 26; devno++)
- {
- uint32_t bitno = 1 << devno;
- if ((g_devinuse & bitno) == 0)
- {
- g_devinuse |= bitno;
- priv->sdchar = 'a' + devno;
- irqrestore(flags);
- return OK;
- }
- }
-
- irqrestore(flags);
- return -EMFILE;
-}
-
-static void usbhost_freedevno(FAR struct usbhost_state_s *priv)
-{
- int devno = 'a' - priv->sdchar;
-
- if (devno >= 0 && devno < 26)
- {
- irqstate_t flags = irqsave();
- g_devinuse &= ~(1 << devno);
- irqrestore(flags);
- }
-}
-
-static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *devname)
-{
- (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->sdchar);
-}
-
-/****************************************************************************
- * Name: CBW/CSW debug helpers
- *
- * Description:
- * The following functions are helper functions used to dump CBWs and CSWs.
- *
- * Input Parameters:
- * cbw/csw - A reference to the CBW/CSW to dump.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-#if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_VERBOSE)
-static void usbhost_dumpcbw(FAR struct usbmsc_cbw_s *cbw)
-{
- int i;
-
- uvdbg("CBW:\n");
- uvdbg(" signature: %08x\n", usbhost_getle32(cbw->signature));
- uvdbg(" tag: %08x\n", usbhost_getle32(cbw->tag));
- uvdbg(" datlen: %08x\n", usbhost_getle32(cbw->datlen));
- uvdbg(" flags: %02x\n", cbw->flags);
- uvdbg(" lun: %02x\n", cbw->lun);
- uvdbg(" cdblen: %02x\n", cbw->cdblen);
-
- uvdbg("CDB:\n");
- for (i = 0; i < cbw->cdblen; i += 8)
- {
- uvdbg(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
- cbw->cdb[i], cbw->cdb[i+1], cbw->cdb[i+2], cbw->cdb[i+3],
- cbw->cdb[i+4], cbw->cdb[i+5], cbw->cdb[i+6], cbw->cdb[i+7]);
- }
-}
-
-static void usbhost_dumpcsw(FAR struct usbmsc_csw_s *csw)
-{
- uvdbg("CSW:\n");
- uvdbg(" signature: %08x\n", usbhost_getle32(csw->signature));
- uvdbg(" tag: %08x\n", usbhost_getle32(csw->tag));
- uvdbg(" residue: %08x\n", usbhost_getle32(csw->residue));
- uvdbg(" status: %02x\n", csw->status);
-}
-#endif
-
-/****************************************************************************
- * Name: CBW helpers
- *
- * Description:
- * The following functions are helper functions used to format CBWs.
- *
- * Input Parameters:
- * cbw - A reference to allocated and initialized CBW to be built.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline void usbhost_requestsensecbw(FAR struct usbmsc_cbw_s *cbw)
-{
- FAR struct scsicmd_requestsense_s *reqsense;
-
- /* Format the CBW */
-
- usbhost_putle32(cbw->datlen, SCSIRESP_FIXEDSENSEDATA_SIZEOF);
- cbw->flags = USBMSC_CBWFLAG_IN;
- cbw->cdblen = SCSICMD_REQUESTSENSE_SIZEOF;
-
- /* Format the CDB */
-
- reqsense = (FAR struct scsicmd_requestsense_s *)cbw->cdb;
- reqsense->opcode = SCSI_CMD_REQUESTSENSE;
- reqsense->alloclen = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
-
- usbhost_dumpcbw(cbw);
-}
-
-static inline void usbhost_testunitreadycbw(FAR struct usbmsc_cbw_s *cbw)
-{
- /* Format the CBW */
-
- cbw->cdblen = SCSICMD_TESTUNITREADY_SIZEOF;
-
- /* Format the CDB */
-
- cbw->cdb[0] = SCSI_CMD_TESTUNITREADY;
-
- usbhost_dumpcbw(cbw);
-}
-
-static inline void usbhost_readcapacitycbw(FAR struct usbmsc_cbw_s *cbw)
-{
- FAR struct scsicmd_readcapacity10_s *rcap10;
-
- /* Format the CBW */
-
- usbhost_putle32(cbw->datlen, SCSIRESP_READCAPACITY10_SIZEOF);
- cbw->flags = USBMSC_CBWFLAG_IN;
- cbw->cdblen = SCSICMD_READCAPACITY10_SIZEOF;
-
- /* Format the CDB */
-
- rcap10 = (FAR struct scsicmd_readcapacity10_s *)cbw->cdb;
- rcap10->opcode = SCSI_CMD_READCAPACITY10;
-
- usbhost_dumpcbw(cbw);
-}
-
-static inline void usbhost_inquirycbw (FAR struct usbmsc_cbw_s *cbw)
-{
- FAR struct scscicmd_inquiry_s *inq;
-
- /* Format the CBW */
-
- usbhost_putle32(cbw->datlen, SCSIRESP_INQUIRY_SIZEOF);
- cbw->flags = USBMSC_CBWFLAG_IN;
- cbw->cdblen = SCSICMD_INQUIRY_SIZEOF;
-
- /* Format the CDB */
-
- inq = (FAR struct scscicmd_inquiry_s *)cbw->cdb;
- inq->opcode = SCSI_CMD_INQUIRY;
- usbhost_putbe16(inq->alloclen, SCSIRESP_INQUIRY_SIZEOF);
-
- usbhost_dumpcbw(cbw);
-}
-
-static inline void
-usbhost_readcbw (size_t startsector, uint16_t blocksize,
- unsigned int nsectors, FAR struct usbmsc_cbw_s *cbw)
-{
- FAR struct scsicmd_read10_s *rd10;
-
- /* Format the CBW */
-
- usbhost_putle32(cbw->datlen, blocksize * nsectors);
- cbw->flags = USBMSC_CBWFLAG_IN;
- cbw->cdblen = SCSICMD_READ10_SIZEOF;
-
- /* Format the CDB */
-
- rd10 = (FAR struct scsicmd_read10_s *)cbw->cdb;
- rd10->opcode = SCSI_CMD_READ10;
- usbhost_putbe32(rd10->lba, startsector);
- usbhost_putbe16(rd10->xfrlen, nsectors);
-
- usbhost_dumpcbw(cbw);
-}
-
-static inline void
-usbhost_writecbw(size_t startsector, uint16_t blocksize,
- unsigned int nsectors, FAR struct usbmsc_cbw_s *cbw)
-{
- FAR struct scsicmd_write10_s *wr10;
-
- /* Format the CBW */
-
- usbhost_putle32(cbw->datlen, blocksize * nsectors);
- cbw->cdblen = SCSICMD_WRITE10_SIZEOF;
-
- /* Format the CDB */
-
- wr10 = (FAR struct scsicmd_write10_s *)cbw->cdb;
- wr10->opcode = SCSI_CMD_WRITE10;
- usbhost_putbe32(wr10->lba, startsector);
- usbhost_putbe16(wr10->xfrlen, nsectors);
-
- usbhost_dumpcbw(cbw);
-}
-
-/****************************************************************************
- * Name: Command helpers
- *
- * Description:
- * The following functions are helper functions used to send commands.
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline int usbhost_maxlunreq(FAR struct usbhost_state_s *priv)
-{
- FAR struct usb_ctrlreq_s *req = (FAR struct usb_ctrlreq_s *)priv->tbuffer;
- DEBUGASSERT(priv && priv->tbuffer);
- int ret;
-
- /* Request maximum logical unit number. NOTE: On an IN transaction, The
- * req and buffer pointers passed to DRVR_CTRLIN may refer to the same
- * allocated memory.
- */
-
- uvdbg("Request maximum logical unit number\n");
- memset(req, 0, sizeof(struct usb_ctrlreq_s));
- req->type = USB_DIR_IN|USB_REQ_TYPE_CLASS|USB_REQ_RECIPIENT_INTERFACE;
- req->req = USBMSC_REQ_GETMAXLUN;
- usbhost_putle16(req->len, 1);
-
- ret = DRVR_CTRLIN(priv->drvr, req, priv->tbuffer);
- if (ret != OK)
- {
- /* Devices that do not support multiple LUNs may stall this command.
- * On a failure, a single LUN is assumed.
- */
-
- *(priv->tbuffer) = 0;
- }
- return OK;
-}
-
-static inline int usbhost_testunitready(FAR struct usbhost_state_s *priv)
-{
- FAR struct usbmsc_cbw_s *cbw;
- int result;
-
- /* Initialize a CBW (re-using the allocated transfer buffer) */
-
- cbw = usbhost_cbwalloc(priv);
- if (!cbw)
- {
- udbg("ERROR: Failed to create CBW\n");
- return -ENOMEM;
- }
-
- /* Construct and send the CBW */
-
- usbhost_testunitreadycbw(cbw);
- result = DRVR_TRANSFER(priv->drvr, priv->bulkout,
- (uint8_t*)cbw, USBMSC_CBW_SIZEOF);
- if (result == OK)
- {
- /* Receive the CSW */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
- priv->tbuffer, USBMSC_CSW_SIZEOF);
- if (result == OK)
- {
- usbhost_dumpcsw((FAR struct usbmsc_csw_s *)priv->tbuffer);
- }
- }
-
- return result;
-}
-
-static inline int usbhost_requestsense(FAR struct usbhost_state_s *priv)
-{
- FAR struct usbmsc_cbw_s *cbw;
- int result;
-
- /* Initialize a CBW (re-using the allocated transfer buffer) */
-
- cbw = usbhost_cbwalloc(priv);
- if (!cbw)
- {
- udbg("ERROR: Failed to create CBW\n");
- return -ENOMEM;
- }
-
- /* Construct and send the CBW */
-
- usbhost_requestsensecbw(cbw);
- result = DRVR_TRANSFER(priv->drvr, priv->bulkout,
- (uint8_t*)cbw, USBMSC_CBW_SIZEOF);
- if (result == OK)
- {
- /* Receive the sense data response */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
- priv->tbuffer, SCSIRESP_FIXEDSENSEDATA_SIZEOF);
- if (result == OK)
- {
- /* Receive the CSW */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
- priv->tbuffer, USBMSC_CSW_SIZEOF);
- if (result == OK)
- {
- usbhost_dumpcsw((FAR struct usbmsc_csw_s *)priv->tbuffer);
- }
- }
- }
-
- return result;
-}
-
-static inline int usbhost_readcapacity(FAR struct usbhost_state_s *priv)
-{
- FAR struct usbmsc_cbw_s *cbw;
- FAR struct scsiresp_readcapacity10_s *resp;
- int result;
-
- /* Initialize a CBW (re-using the allocated transfer buffer) */
-
- cbw = usbhost_cbwalloc(priv);
- if (!cbw)
- {
- udbg("ERROR: Failed to create CBW\n");
- return -ENOMEM;
- }
-
- /* Construct and send the CBW */
-
- usbhost_readcapacitycbw(cbw);
- result = DRVR_TRANSFER(priv->drvr, priv->bulkout,
- (uint8_t*)cbw, USBMSC_CBW_SIZEOF);
- if (result == OK)
- {
- /* Receive the read capacity CBW IN response */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
- priv->tbuffer, SCSIRESP_READCAPACITY10_SIZEOF);
- if (result == OK)
- {
- /* Save the capacity information */
-
- resp = (FAR struct scsiresp_readcapacity10_s *)priv->tbuffer;
- priv->nblocks = usbhost_getbe32(resp->lba) + 1;
- priv->blocksize = usbhost_getbe32(resp->blklen);
-
- /* Receive the CSW */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
- priv->tbuffer, USBMSC_CSW_SIZEOF);
- if (result == OK)
- {
- usbhost_dumpcsw((FAR struct usbmsc_csw_s *)priv->tbuffer);
- }
- }
- }
-
- return result;
-}
-
-static inline int usbhost_inquiry(FAR struct usbhost_state_s *priv)
-{
- FAR struct usbmsc_cbw_s *cbw;
- FAR struct scsiresp_inquiry_s *resp;
- int result;
-
- /* Initialize a CBW (re-using the allocated transfer buffer) */
-
- cbw = usbhost_cbwalloc(priv);
- if (!cbw)
- {
- udbg("ERROR: Failed to create CBW\n");
- return -ENOMEM;
- }
-
- /* Construct and send the CBW */
-
- usbhost_inquirycbw(cbw);
- result = DRVR_TRANSFER(priv->drvr, priv->bulkout,
- (uint8_t*)cbw, USBMSC_CBW_SIZEOF);
- if (result == OK)
- {
- /* Receive the CBW IN response */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
- priv->tbuffer, SCSIRESP_INQUIRY_SIZEOF);
- if (result == OK)
- {
- /* TODO: If USB debug is enabled, dump the response data here */
-
- resp = (FAR struct scsiresp_inquiry_s *)priv->tbuffer;
-
- /* Receive the CSW */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
- priv->tbuffer, USBMSC_CSW_SIZEOF);
- if (result == OK)
- {
- usbhost_dumpcsw((FAR struct usbmsc_csw_s *)priv->tbuffer);
- }
- }
- }
-
- return result;
-}
-
-/****************************************************************************
- * Name: usbhost_destroy
- *
- * Description:
- * The USB mass storage device has been disconnected and the refernce count
- * on the USB host class instance has gone to 1.. Time to destroy the USB
- * host class instance.
- *
- * Input Parameters:
- * arg - A reference to the class instance to be destroyed.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_destroy(FAR void *arg)
-{
- FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)arg;
- char devname[DEV_NAMELEN];
-
- DEBUGASSERT(priv != NULL);
- uvdbg("crefs: %d\n", priv->crefs);
-
- /* Unregister the block driver */
-
- usbhost_mkdevname(priv, devname);
- (void)unregister_blockdriver(devname);
-
- /* Release the device name used by this connection */
-
- usbhost_freedevno(priv);
-
- /* Free the bulk endpoints */
-
- if (priv->bulkout)
- {
- DRVR_EPFREE(priv->drvr, priv->bulkout);
- }
-
- if (priv->bulkin)
- {
- DRVR_EPFREE(priv->drvr, priv->bulkin);
- }
-
- /* Free any transfer buffers */
-
- usbhost_tfree(priv);
-
- /* Destroy the semaphores */
-
- sem_destroy(&priv->exclsem);
-
- /* Disconnect the USB host device */
-
- DRVR_DISCONNECT(priv->drvr);
-
- /* And free the class instance. Hmmm.. this may execute on the worker
- * thread and the work structure is part of what is getting freed. That
- * should be okay because once the work contained is removed from the
- * queue, it should not longer be accessed by the worker thread.
- */
-
- usbhost_freeclass(priv);
-}
-
-/****************************************************************************
- * Name: usbhost_cfgdesc
- *
- * Description:
- * This function implements the connect() method of struct
- * usbhost_class_s. This method is a callback into the class
- * implementation. It is used to provide the device's configuration
- * descriptor to the class so that the class may initialize properly
- *
- * Input Parameters:
- * priv - The USB host class instance.
- * configdesc - A pointer to a uint8_t buffer container the configuration descripor.
- * desclen - The length in bytes of the configuration descriptor.
- * funcaddr - The USB address of the function containing the endpoint that EP0
- * controls
- *
- * Returned Values:
- * On success, zero (OK) is returned. On a failure, a negated errno value is
- * returned indicating the nature of the failure
- *
- * Assumptions:
- * This function will *not* be called from an interrupt handler.
- *
- ****************************************************************************/
-
-static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr)
-{
- FAR struct usb_cfgdesc_s *cfgdesc;
- FAR struct usb_desc_s *desc;
- FAR struct usbhost_epdesc_s bindesc;
- FAR struct usbhost_epdesc_s boutdesc;
- int remaining;
- uint8_t found = 0;
- int ret;
-
- DEBUGASSERT(priv != NULL &&
- configdesc != NULL &&
- desclen >= sizeof(struct usb_cfgdesc_s));
-
- /* Verify that we were passed a configuration descriptor */
-
- cfgdesc = (FAR struct usb_cfgdesc_s *)configdesc;
- if (cfgdesc->type != USB_DESC_TYPE_CONFIG)
- {
- return -EINVAL;
- }
-
- /* Get the total length of the configuration descriptor (little endian).
- * It might be a good check to get the number of interfaces here too.
- */
-
- remaining = (int)usbhost_getle16(cfgdesc->totallen);
-
- /* Skip to the next entry descriptor */
-
- configdesc += cfgdesc->len;
- remaining -= cfgdesc->len;
-
- /* Loop where there are more dscriptors to examine */
-
- while (remaining >= sizeof(struct usb_desc_s))
- {
- /* What is the next descriptor? */
-
- desc = (FAR struct usb_desc_s *)configdesc;
- switch (desc->type)
- {
- /* Interface descriptor. We really should get the number of endpoints
- * from this descriptor too.
- */
-
- case USB_DESC_TYPE_INTERFACE:
- {
- FAR struct usb_ifdesc_s *ifdesc = (FAR struct usb_ifdesc_s *)configdesc;
-
- uvdbg("Interface descriptor\n");
- DEBUGASSERT(remaining >= USB_SIZEOF_IFDESC);
-
- /* Save the interface number and mark ONLY the interface found */
-
- priv->ifno = ifdesc->ifno;
- found = USBHOST_IFFOUND;
- }
- break;
-
- /* Endpoint descriptor. We expect two bulk endpoints, an IN and an
- * OUT.
- */
-
- case USB_DESC_TYPE_ENDPOINT:
- {
- FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)configdesc;
-
- uvdbg("Endpoint descriptor\n");
- DEBUGASSERT(remaining >= USB_SIZEOF_EPDESC);
-
- /* Check for a bulk endpoint. We only support the bulk-only
- * protocol so I suppose anything else should really be an error.
- */
-
- if ((epdesc->attr & USB_EP_ATTR_XFERTYPE_MASK) == USB_EP_ATTR_XFER_BULK)
- {
- /* Yes.. it is a bulk endpoint. IN or OUT? */
-
- if (USB_ISEPOUT(epdesc->addr))
- {
- /* It is an OUT bulk endpoint. There should be only one
- * bulk OUT endpoint.
- */
-
- if ((found & USBHOST_BOUTFOUND) != 0)
- {
- /* Oops.. more than one endpoint. We don't know
- * what to do with this.
- */
-
- return -EINVAL;
- }
- found |= USBHOST_BOUTFOUND;
-
- /* Save the bulk OUT endpoint information */
-
- boutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
- boutdesc.in = false;
- boutdesc.funcaddr = funcaddr;
- boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK;
- boutdesc.interval = epdesc->interval;
- boutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
- uvdbg("Bulk OUT EP addr:%d mxpacketsize:%d\n",
- boutdesc.addr, boutdesc.mxpacketsize);
- }
- else
- {
- /* It is an IN bulk endpoint. There should be only one
- * bulk IN endpoint.
- */
-
- if ((found & USBHOST_BINFOUND) != 0)
- {
- /* Oops.. more than one endpoint. We don't know
- * what to do with this.
- */
-
- return -EINVAL;
- }
- found |= USBHOST_BINFOUND;
-
- /* Save the bulk IN endpoint information */
-
- bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
- bindesc.in = 1;
- bindesc.funcaddr = funcaddr;
- bindesc.xfrtype = USB_EP_ATTR_XFER_BULK;
- bindesc.interval = epdesc->interval;
- bindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
- uvdbg("Bulk IN EP addr:%d mxpacketsize:%d\n",
- bindesc.addr, bindesc.mxpacketsize);
- }
- }
- }
- break;
-
- /* Other descriptors are just ignored for now */
-
- default:
- break;
- }
-
- /* If we found everything we need with this interface, then break out
- * of the loop early.
- */
-
- if (found == USBHOST_ALLFOUND)
- {
- break;
- }
-
- /* Increment the address of the next descriptor */
-
- configdesc += desc->len;
- remaining -= desc->len;
- }
-
- /* Sanity checking... did we find all of things that we need? Hmmm.. I wonder..
- * can we work read-only or write-only if only one bulk endpoint found?
- */
-
- if (found != USBHOST_ALLFOUND)
- {
- ulldbg("ERROR: Found IF:%s BIN:%s BOUT:%s\n",
- (found & USBHOST_IFFOUND) != 0 ? "YES" : "NO",
- (found & USBHOST_BINFOUND) != 0 ? "YES" : "NO",
- (found & USBHOST_BOUTFOUND) != 0 ? "YES" : "NO");
- return -EINVAL;
- }
-
- /* We are good... Allocate the endpoints */
-
- ret = DRVR_EPALLOC(priv->drvr, &boutdesc, &priv->bulkout);
- if (ret != OK)
- {
- udbg("ERROR: Failed to allocate Bulk OUT endpoint\n");
- return ret;
- }
-
- ret = DRVR_EPALLOC(priv->drvr, &bindesc, &priv->bulkin);
- if (ret != OK)
- {
- udbg("ERROR: Failed to allocate Bulk IN endpoint\n");
- (void)DRVR_EPFREE(priv->drvr, priv->bulkout);
- return ret;
- }
-
- ullvdbg("Endpoints allocated\n");
- return OK;
-}
-
-/****************************************************************************
- * Name: usbhost_initvolume
- *
- * Description:
- * The USB mass storage device has been successfully connected. This
- * completes the initialization operations. It is first called after the
- * configuration descriptor has been received.
- *
- * This function is called from the connect() method. This function always
- * executes on the thread of the caller of connect().
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv)
-{
- FAR struct usbmsc_csw_s *csw;
- unsigned int retries;
- int ret = OK;
-
- DEBUGASSERT(priv != NULL);
-
- /* Set aside a transfer buffer for exclusive use by the mass storage driver */
-
- ret = usbhost_talloc(priv);
- if (ret != OK)
- {
- udbg("ERROR: Failed to allocate transfer buffer\n");
- return ret;
- }
-
- /* Increment the reference count. This will prevent usbhost_destroy() from
- * being called asynchronously if the device is removed.
- */
-
- priv->crefs++;
- DEBUGASSERT(priv->crefs == 2);
-
- /* Request the maximum logical unit number */
-
- uvdbg("Get max LUN\n");
- ret = usbhost_maxlunreq(priv);
-
- for (retries = 0; retries < USBHOST_MAX_RETRIES /* && ret == OK */; retries++)
- {
- uvdbg("Test unit ready, retries=%d\n", retries);
-
- /* Wait just a bit */
-
- usleep(50*1000);
-
- /* Send TESTUNITREADY to see if the unit is ready */
-
- ret = usbhost_testunitready(priv);
- if (ret == OK)
- {
- /* Is the unit is ready */
-
- csw = (FAR struct usbmsc_csw_s *)priv->tbuffer;
- if (csw->status == 0)
- {
- /* Yes... break out of the loop */
-
- break;
- }
-
- /* No.. Request mode sense information. The REQUEST SENSE command
- * is sent only "to clear interlocked unit attention conditions."
- * The returned status is ignored here.
- */
-
- uvdbg("Request sense\n");
- ret = usbhost_requestsense(priv);
- }
- }
-
- /* Did the unit become ready? Did an error occur? Or did we time out? */
-
- if (retries >= USBHOST_MAX_RETRIES)
- {
- udbg("ERROR: Timeout!\n");
- ret = -ETIMEDOUT;
- }
-
- if (ret == OK)
- {
- /* Get the capacity of the volume */
-
- uvdbg("Read capacity\n");
- ret = usbhost_readcapacity(priv);
- if (ret == OK)
- {
- /* Check the CSW for errors */
-
- csw = (FAR struct usbmsc_csw_s *)priv->tbuffer;
- if (csw->status != 0)
- {
- udbg("ERROR: CSW status error: %d\n", csw->status);
- ret = -ENODEV;
- }
- }
- }
-
- /* Get information about the volume */
-
- if (ret == OK)
- {
- /* Inquiry */
-
- uvdbg("Inquiry\n");
- ret = usbhost_inquiry(priv);
- if (ret == OK)
- {
- /* Check the CSW for errors */
-
- csw = (FAR struct usbmsc_csw_s *)priv->tbuffer;
- if (csw->status != 0)
- {
- udbg("ERROR: CSW status error: %d\n", csw->status);
- ret = -ENODEV;
- }
- }
- }
-
- /* Register the block driver */
-
- if (ret == OK)
- {
- char devname[DEV_NAMELEN];
-
- uvdbg("Register block driver\n");
- usbhost_mkdevname(priv, devname);
- ret = register_blockdriver(devname, &g_bops, 0, priv);
- }
-
- /* Check if we successfully initialized. We now have to be concerned
- * about asynchronous modification of crefs because the block
- * driver has been registerd.
- */
-
- if (ret == OK)
- {
- usbhost_takesem(&priv->exclsem);
- DEBUGASSERT(priv->crefs >= 2);
-
- /* Decrement the reference count */
-
- priv->crefs--;
-
- /* Handle a corner case where (1) open() has been called so the
- * reference count was > 2, but the device has been disconnected.
- * In this case, the class instance needs to persist until close()
- * is called.
- */
-
- if (priv->crefs <= 1 && priv->disconnected)
- {
- /* The will cause the enumeration logic to disconnect
- * the class driver.
- */
-
- ret = -ENODEV;
- }
-
- /* Release the semaphore... there is a race condition here.
- * Decrementing the reference count and releasing the semaphore
- * allows usbhost_destroy() to execute (on the worker thread);
- * the class driver instance could get destoryed before we are
- * ready to handle it!
- */
-
- usbhost_givesem(&priv->exclsem);
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbhost_getle16
- *
- * Description:
- * Get a (possibly unaligned) 16-bit little endian value.
- *
- * Input Parameters:
- * val - A pointer to the first byte of the little endian value.
- *
- * Returned Values:
- * A uint16_t representing the whole 16-bit integer value
- *
- ****************************************************************************/
-
-static inline uint16_t usbhost_getle16(const uint8_t *val)
-{
- return (uint16_t)val[1] << 8 | (uint16_t)val[0];
-}
-
-/****************************************************************************
- * Name: usbhost_getbe16
- *
- * Description:
- * Get a (possibly unaligned) 16-bit big endian value.
- *
- * Input Parameters:
- * val - A pointer to the first byte of the big endian value.
- *
- * Returned Values:
- * A uint16_t representing the whole 16-bit integer value
- *
- ****************************************************************************/
-
-static inline uint16_t usbhost_getbe16(const uint8_t *val)
-{
- return (uint16_t)val[0] << 8 | (uint16_t)val[1];
-}
-
-/****************************************************************************
- * Name: usbhost_putle16
- *
- * Description:
- * Put a (possibly unaligned) 16-bit little endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the little endian value.
- * val - The 16-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_putle16(uint8_t *dest, uint16_t val)
-{
- dest[0] = val & 0xff; /* Little endian means LS byte first in byte stream */
- dest[1] = val >> 8;
-}
-
-/****************************************************************************
- * Name: usbhost_putbe16
- *
- * Description:
- * Put a (possibly unaligned) 16-bit big endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the big endian value.
- * val - The 16-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_putbe16(uint8_t *dest, uint16_t val)
-{
- dest[0] = val >> 8; /* Big endian means MS byte first in byte stream */
- dest[1] = val & 0xff;
-}
-
-/****************************************************************************
- * Name: usbhost_getle32
- *
- * Description:
- * Get a (possibly unaligned) 32-bit little endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the big endian value.
- * val - The 32-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline uint32_t usbhost_getle32(const uint8_t *val)
-{
- /* Little endian means LS halfword first in byte stream */
-
- return (uint32_t)usbhost_getle16(&val[2]) << 16 | (uint32_t)usbhost_getle16(val);
-}
-
-/****************************************************************************
- * Name: usbhost_getbe32
- *
- * Description:
- * Get a (possibly unaligned) 32-bit big endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the big endian value.
- * val - The 32-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static inline uint32_t usbhost_getbe32(const uint8_t *val)
-{
- /* Big endian means MS halfword first in byte stream */
-
- return (uint32_t)usbhost_getbe16(val) << 16 | (uint32_t)usbhost_getbe16(&val[2]);
-}
-
-/****************************************************************************
- * Name: usbhost_putle32
- *
- * Description:
- * Put a (possibly unaligned) 32-bit little endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the little endian value.
- * val - The 32-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_putle32(uint8_t *dest, uint32_t val)
-{
- /* Little endian means LS halfword first in byte stream */
-
- usbhost_putle16(dest, (uint16_t)(val & 0xffff));
- usbhost_putle16(dest+2, (uint16_t)(val >> 16));
-}
-
-/****************************************************************************
- * Name: usbhost_putbe32
- *
- * Description:
- * Put a (possibly unaligned) 32-bit big endian value.
- *
- * Input Parameters:
- * dest - A pointer to the first byte to save the big endian value.
- * val - The 32-bit value to be saved.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static void usbhost_putbe32(uint8_t *dest, uint32_t val)
-{
- /* Big endian means MS halfword first in byte stream */
-
- usbhost_putbe16(dest, (uint16_t)(val >> 16));
- usbhost_putbe16(dest+2, (uint16_t)(val & 0xffff));
-}
-
-/****************************************************************************
- * Name: usbhost_talloc
- *
- * Description:
- * Allocate transfer buffer memory.
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * On sucess, zero (OK) is returned. On failure, an negated errno value
- * is returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-static inline int usbhost_talloc(FAR struct usbhost_state_s *priv)
-{
- DEBUGASSERT(priv && priv->tbuffer == NULL);
- return DRVR_ALLOC(priv->drvr, &priv->tbuffer, &priv->tbuflen);
-}
-
-/****************************************************************************
- * Name: usbhost_tfree
- *
- * Description:
- * Free transfer buffer memory.
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * On sucess, zero (OK) is returned. On failure, an negated errno value
- * is returned to indicate the nature of the failure.
- *
- ****************************************************************************/
-
-static inline int usbhost_tfree(FAR struct usbhost_state_s *priv)
-{
- int result = OK;
- DEBUGASSERT(priv);
-
- if (priv->tbuffer)
- {
- DEBUGASSERT(priv->drvr);
- result = DRVR_FREE(priv->drvr, priv->tbuffer);
- priv->tbuffer = NULL;
- priv->tbuflen = 0;
- }
- return result;
-}
-
-/****************************************************************************
- * Name: usbhost_cbwalloc
- *
- * Description:
- * Initialize a CBW (re-using the allocated transfer buffer). Upon
- * successful return, the CBW is cleared and has the CBW signature in place.
- *
- * Input Parameters:
- * priv - A reference to the class instance.
- *
- * Returned Values:
- * None
- *
- ****************************************************************************/
-
-static FAR struct usbmsc_cbw_s *usbhost_cbwalloc(FAR struct usbhost_state_s *priv)
-{
- FAR struct usbmsc_cbw_s *cbw = NULL;
-
- DEBUGASSERT(priv->tbuffer && priv->tbuflen >= sizeof(struct usbmsc_cbw_s))
-
- /* Intialize the CBW sructure */
-
- cbw = (FAR struct usbmsc_cbw_s *)priv->tbuffer;
- memset(cbw, 0, sizeof(struct usbmsc_cbw_s));
- usbhost_putle32(cbw->signature, USBMSC_CBW_SIGNATURE);
- return cbw;
-}
-
-/****************************************************************************
- * struct usbhost_registry_s methods
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_create
- *
- * Description:
- * This function implements the create() method of struct usbhost_registry_s.
- * The create() method is a callback into the class implementation. It is
- * used to (1) create a new instance of the USB host class state and to (2)
- * bind a USB host driver "session" to the class instance. Use of this
- * create() method will support environments where there may be multiple
- * USB ports and multiple USB devices simultaneously connected.
- *
- * Input Parameters:
- * drvr - An instance of struct usbhost_driver_s that the class
- * implementation will "bind" to its state structure and will
- * subsequently use to communicate with the USB host driver.
- * id - In the case where the device supports multiple base classes,
- * subclasses, or protocols, this specifies which to configure for.
- *
- * Returned Values:
- * On success, this function will return a non-NULL instance of struct
- * usbhost_class_s that can be used by the USB host driver to communicate
- * with the USB host class. NULL is returned on failure; this function
- * will fail only if the drvr input parameter is NULL or if there are
- * insufficient resources to create another USB host class instance.
- *
- ****************************************************************************/
-
-static FAR struct usbhost_class_s *usbhost_create(FAR struct usbhost_driver_s *drvr,
- FAR const struct usbhost_id_s *id)
-{
- FAR struct usbhost_state_s *priv;
-
- /* Allocate a USB host mass storage class instance */
-
- priv = usbhost_allocclass();
- if (priv)
- {
- /* Initialize the allocated storage class instance */
-
- memset(priv, 0, sizeof(struct usbhost_state_s));
-
- /* Assign a device number to this class instance */
-
- if (usbhost_allocdevno(priv) == OK)
- {
- /* Initialize class method function pointers */
-
- priv->class.connect = usbhost_connect;
- priv->class.disconnected = usbhost_disconnected;
-
- /* The initial reference count is 1... One reference is held by the driver */
-
- priv->crefs = 1;
-
- /* Initialize semphores (this works okay in the interrupt context) */
-
- sem_init(&priv->exclsem, 0, 1);
-
- /* Bind the driver to the storage class instance */
-
- priv->drvr = drvr;
-
- /* NOTE: We do not yet know the geometry of the USB mass storage device */
-
- /* Return the instance of the USB mass storage class */
-
- return &priv->class;
- }
- }
-
- /* An error occurred. Free the allocation and return NULL on all failures */
-
- if (priv)
- {
- usbhost_freeclass(priv);
- }
- return NULL;
-}
-
-/****************************************************************************
- * struct usbhost_class_s methods
- ****************************************************************************/
-/****************************************************************************
- * Name: usbhost_connect
- *
- * Description:
- * This function implements the connect() method of struct
- * usbhost_class_s. This method is a callback into the class
- * implementation. It is used to provide the device's configuration
- * descriptor to the class so that the class may initialize properly
- *
- * Input Parameters:
- * class - The USB host class entry previously obtained from a call to create().
- * configdesc - A pointer to a uint8_t buffer container the configuration descripor.
- * desclen - The length in bytes of the configuration descriptor.
- * funcaddr - The USB address of the function containing the endpoint that EP0
- * controls
- *
- * Returned Values:
- * On success, zero (OK) is returned. On a failure, a negated errno value is
- * returned indicating the nature of the failure
- *
- * NOTE that the class instance remains valid upon return with a failure. It is
- * the responsibility of the higher level enumeration logic to call
- * CLASS_DISCONNECTED to free up the class driver resources.
- *
- * Assumptions:
- * - This function will *not* be called from an interrupt handler.
- * - If this function returns an error, the USB host controller driver
- * must call to DISCONNECTED method to recover from the error
- *
- ****************************************************************************/
-
-static int usbhost_connect(FAR struct usbhost_class_s *class,
- FAR const uint8_t *configdesc, int desclen,
- uint8_t funcaddr)
-{
- FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)class;
- int ret;
-
- DEBUGASSERT(priv != NULL &&
- configdesc != NULL &&
- desclen >= sizeof(struct usb_cfgdesc_s));
-
- /* Parse the configuration descriptor to get the bulk I/O endpoints */
-
- ret = usbhost_cfgdesc(priv, configdesc, desclen, funcaddr);
- if (ret != OK)
- {
- udbg("usbhost_cfgdesc() failed: %d\n", ret);
- }
- else
- {
- /* Now configure the LUNs and register the block driver(s) */
-
- ret = usbhost_initvolume(priv);
- if (ret != OK)
- {
- udbg("usbhost_initvolume() failed: %d\n", ret);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbhost_disconnected
- *
- * Description:
- * This function implements the disconnected() method of struct
- * usbhost_class_s. This method is a callback into the class
- * implementation. It is used to inform the class that the USB device has
- * been disconnected.
- *
- * Input Parameters:
- * class - The USB host class entry previously obtained from a call to
- * create().
- *
- * Returned Values:
- * On success, zero (OK) is returned. On a failure, a negated errno value
- * is returned indicating the nature of the failure
- *
- * Assumptions:
- * This function may be called from an interrupt handler.
- *
- ****************************************************************************/
-
-static int usbhost_disconnected(struct usbhost_class_s *class)
-{
- FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)class;
- irqstate_t flags;
-
- DEBUGASSERT(priv != NULL);
-
- /* Set an indication to any users of the mass storage device that the device
- * is no longer available.
- */
-
- flags = irqsave();
- priv->disconnected = true;
-
- /* Now check the number of references on the class instance. If it is one,
- * then we can free the class instance now. Otherwise, we will have to
- * wait until the holders of the references free them by closing the
- * block driver.
- */
-
- ullvdbg("crefs: %d\n", priv->crefs);
- if (priv->crefs == 1)
- {
- /* Destroy the class instance. If we are executing from an interrupt
- * handler, then defer the destruction to the worker thread.
- * Otherwise, destroy the instance now.
- */
-
- if (up_interrupt_context())
- {
- /* Destroy the instance on the worker thread. */
-
- uvdbg("Queuing destruction: worker %p->%p\n", priv->work.worker, usbhost_destroy);
- DEBUGASSERT(priv->work.worker == NULL);
- (void)work_queue(HPWORK, &priv->work, usbhost_destroy, priv, 0);
- }
- else
- {
- /* Do the work now */
-
- usbhost_destroy(priv);
- }
- }
-
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * struct block_operations methods
- ****************************************************************************/
-/****************************************************************************
- * Name: usbhost_open
- *
- * Description: Open the block device
- *
- ****************************************************************************/
-
-static int usbhost_open(FAR struct inode *inode)
-{
- FAR struct usbhost_state_s *priv;
- irqstate_t flags;
- int ret;
-
- uvdbg("Entry\n");
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct usbhost_state_s *)inode->i_private;
-
- /* Make sure that we have exclusive access to the private data structure */
-
- DEBUGASSERT(priv->crefs > 0 && priv->crefs < USBHOST_MAX_CREFS);
- usbhost_takesem(&priv->exclsem);
-
- /* Check if the mass storage device is still connected. We need to disable
- * interrupts momentarily to assure that there are no asynchronous disconnect
- * events.
- */
-
- flags = irqsave();
- if (priv->disconnected)
- {
- /* No... the block driver is no longer bound to the class. That means that
- * the USB storage device is no longer connected. Refuse any further
- * attempts to open the driver.
- */
-
- ret = -ENODEV;
- }
- else
- {
- /* Otherwise, just increment the reference count on the driver */
-
- priv->crefs++;
- ret = OK;
- }
- irqrestore(flags);
-
- usbhost_givesem(&priv->exclsem);
- return ret;
-}
-
-/****************************************************************************
- * Name: usbhost_close
- *
- * Description: close the block device
- *
- ****************************************************************************/
-
-static int usbhost_close(FAR struct inode *inode)
-{
- FAR struct usbhost_state_s *priv;
- irqstate_t flags;
-
- uvdbg("Entry\n");
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct usbhost_state_s *)inode->i_private;
-
- /* Decrement the reference count on the block driver */
-
- DEBUGASSERT(priv->crefs > 1);
- usbhost_takesem(&priv->exclsem);
- priv->crefs--;
-
- /* Release the semaphore. The following operations when crefs == 1 are
- * safe because we know that there is no outstanding open references to
- * the block driver.
- */
-
- usbhost_givesem(&priv->exclsem);
-
- /* We need to disable interrupts momentarily to assure that there are
- * no asynchronous disconnect events.
- */
-
- flags = irqsave();
-
- /* Check if the USB mass storage device is still connected. If the
- * storage device is not connected and the reference count just
- * decremented to one, then unregister the block driver and free
- * the class instance.
- */
-
- if (priv->crefs <= 1 && priv->disconnected)
- {
- /* Destroy the class instance */
-
- DEBUGASSERT(priv->crefs == 1);
- usbhost_destroy(priv);
- }
-
- irqrestore(flags);
- return OK;
-}
-
-/****************************************************************************
- * Name: usbhost_read
- *
- * Description:
- * Read the specified numer of sectors from the read-ahead buffer or from
- * the physical device.
- *
- ****************************************************************************/
-
-static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer,
- size_t startsector, unsigned int nsectors)
-{
- FAR struct usbhost_state_s *priv;
- ssize_t ret = 0;
- int result;
-
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct usbhost_state_s *)inode->i_private;
- uvdbg("startsector: %d nsectors: %d sectorsize: %d\n",
- startsector, nsectors, priv->blocksize);
-
- /* Check if the mass storage device is still connected */
-
- if (priv->disconnected)
- {
- /* No... the block driver is no longer bound to the class. That means that
- * the USB storage device is no longer connected. Refuse any attempt to read
- * from the device.
- */
-
- ret = -ENODEV;
- }
- else if (nsectors > 0)
- {
- FAR struct usbmsc_cbw_s *cbw;
-
- usbhost_takesem(&priv->exclsem);
-
- /* Assume allocation failure */
-
- ret = -ENOMEM;
-
- /* Initialize a CBW (re-using the allocated transfer buffer) */
-
- cbw = usbhost_cbwalloc(priv);
- if (cbw)
- {
- /* Loop in the event that EAGAIN is returned (mean that the
- * transaction was NAKed and we should try again.
- */
-
- do
- {
- /* Assume some device failure */
-
- ret = -ENODEV;
-
- /* Construct and send the CBW */
-
- usbhost_readcbw(startsector, priv->blocksize, nsectors, cbw);
- result = DRVR_TRANSFER(priv->drvr, priv->bulkout,
- (uint8_t*)cbw, USBMSC_CBW_SIZEOF);
- if (result == OK)
- {
- /* Receive the user data */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
- buffer, priv->blocksize * nsectors);
- if (result == OK)
- {
- /* Receive the CSW */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
- priv->tbuffer, USBMSC_CSW_SIZEOF);
- if (result == OK)
- {
- FAR struct usbmsc_csw_s *csw;
-
- /* Check the CSW status */
-
- csw = (FAR struct usbmsc_csw_s *)priv->tbuffer;
- if (csw->status == 0)
- {
- ret = nsectors;
- }
- }
- }
- }
- } while (result == -EAGAIN);
- }
-
- usbhost_givesem(&priv->exclsem);
- }
-
- /* On success, return the number of blocks read */
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbhost_write
- *
- * Description:
- * Write the specified number of sectors to the write buffer or to the
- * physical device.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_FS_WRITABLE
-static ssize_t usbhost_write(FAR struct inode *inode, const unsigned char *buffer,
- size_t startsector, unsigned int nsectors)
-{
- FAR struct usbhost_state_s *priv;
- ssize_t ret;
- int result;
-
- uvdbg("sector: %d nsectors: %d sectorsize: %d\n");
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct usbhost_state_s *)inode->i_private;
-
- /* Check if the mass storage device is still connected */
-
- if (priv->disconnected)
- {
- /* No... the block driver is no longer bound to the class. That means that
- * the USB storage device is no longer connected. Refuse any attempt to
- * write to the device.
- */
-
- ret = -ENODEV;
- }
- else
- {
- FAR struct usbmsc_cbw_s *cbw;
-
- usbhost_takesem(&priv->exclsem);
-
- /* Assume allocation failure */
-
- ret = -ENOMEM;
-
- /* Initialize a CBW (re-using the allocated transfer buffer) */
-
- cbw = usbhost_cbwalloc(priv);
- if (cbw)
- {
- /* Assume some device failure */
-
- ret = -ENODEV;
-
- /* Construct and send the CBW */
-
- usbhost_writecbw(startsector, priv->blocksize, nsectors, cbw);
- result = DRVR_TRANSFER(priv->drvr, priv->bulkout,
- (uint8_t*)cbw, USBMSC_CBW_SIZEOF);
- if (result == OK)
- {
- /* Send the user data */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkout,
- (uint8_t*)buffer, priv->blocksize * nsectors);
- if (result == OK)
- {
- /* Receive the CSW */
-
- result = DRVR_TRANSFER(priv->drvr, priv->bulkin,
- priv->tbuffer, USBMSC_CSW_SIZEOF);
- if (result == OK)
- {
- FAR struct usbmsc_csw_s *csw;
-
- /* Check the CSW status */
-
- csw = (FAR struct usbmsc_csw_s *)priv->tbuffer;
- if (csw->status == 0)
- {
- ret = nsectors;
- }
- }
- }
- }
- }
-
- usbhost_givesem(&priv->exclsem);
- }
-
- /* On success, return the number of blocks written */
-
- return ret;
-}
-#endif
-
-/****************************************************************************
- * Name: usbhost_geometry
- *
- * Description: Return device geometry
- *
- ****************************************************************************/
-
-static int usbhost_geometry(FAR struct inode *inode, struct geometry *geometry)
-{
- FAR struct usbhost_state_s *priv;
- int ret = -EINVAL;
-
- uvdbg("Entry\n");
- DEBUGASSERT(inode && inode->i_private);
-
- /* Check if the mass storage device is still connected */
-
- priv = (FAR struct usbhost_state_s *)inode->i_private;
- if (priv->disconnected)
- {
- /* No... the block driver is no longer bound to the class. That means that
- * the USB storage device is no longer connected. Refuse to return any
- * geometry info.
- */
-
- ret = -ENODEV;
- }
- else if (geometry)
- {
- /* Return the geometry of the USB mass storage device */
-
- usbhost_takesem(&priv->exclsem);
-
- geometry->geo_available = true;
- geometry->geo_mediachanged = false;
-#ifdef CONFIG_FS_WRITABLE
- geometry->geo_writeenabled = true;
-#else
- geometry->geo_writeenabled = false;
-#endif
- geometry->geo_nsectors = priv->nblocks;
- geometry->geo_sectorsize = priv->blocksize;
- usbhost_givesem(&priv->exclsem);
-
- uvdbg("nsectors: %ld sectorsize: %d\n",
- (long)geometry->geo_nsectors, geometry->geo_sectorsize);
-
- ret = OK;
- }
-
- return ret;
-}
-
-/****************************************************************************
- * Name: usbhost_ioctl
- *
- * Description: Return device geometry
- *
- ****************************************************************************/
-
-static int usbhost_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
-{
- FAR struct usbhost_state_s *priv;
- int ret;
-
- uvdbg("Entry\n");
- DEBUGASSERT(inode && inode->i_private);
- priv = (FAR struct usbhost_state_s *)inode->i_private;
-
- /* Check if the mass storage device is still connected */
-
- if (priv->disconnected)
- {
- /* No... the block driver is no longer bound to the class. That means that
- * the USB storage device is no longer connected. Refuse to process any
- * ioctl commands.
- */
-
- ret = -ENODEV;
- }
- else
- {
- /* Process the IOCTL by command */
-
- usbhost_takesem(&priv->exclsem);
- switch (cmd)
- {
- /* Add support for ioctl commands here */
-
- default:
- ret = -ENOTTY;
- break;
- }
- usbhost_givesem(&priv->exclsem);
- }
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: usbhost_storageinit
- *
- * Description:
- * Initialize the USB host storage class. This function should be called
- * be platform-specific code in order to initialize and register support
- * for the USB host storage class.
- *
- * Input Parameters:
- * None
- *
- * Returned Values:
- * On success this function will return zero (OK); A negated errno value
- * will be returned on failure.
- *
- ****************************************************************************/
-
-int usbhost_storageinit(void)
-{
- /* If we have been configured to use pre-allocated storage class instances,
- * then place all of the pre-allocated USB host storage class instances
- * into a free list.
- */
-
-#if CONFIG_USBHOST_NPREALLOC > 0
- int i;
-
- g_freelist = NULL;
- for (i = 0; i < CONFIG_USBHOST_NPREALLOC; i++)
- {
- struct usbhost_state_s *class = &g_prealloc[i];
- class->class.flink = g_freelist;
- g_freelist = class;
- }
-#endif
-
- /* Advertise our availability to support (certain) mass storage devices */
-
- return usbhost_registerclass(&g_storage);
-}
-
-#endif /* CONFIG_USBHOST && !CONFIG_USBHOST_BULK_DISABLE && !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 */
diff --git a/nuttx/drivers/watchdog.c b/nuttx/drivers/watchdog.c
deleted file mode 100644
index 4f7357444..000000000
--- a/nuttx/drivers/watchdog.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/****************************************************************************
- * drivers/watchdog.c
- *
- * Copyright (C) 2012 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <gnutt@nuttx.org>
- *
- * 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 <nuttx/config.h>
-
-#include <sys/types.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <semaphore.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <errno.h>
-#include <debug.h>
-
-#include <nuttx/fs/fs.h>
-#include <nuttx/irq.h>
-#include <nuttx/kmalloc.h>
-#include <nuttx/watchdog.h>
-
-#ifdef CONFIG_WATCHDOG
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-/* Debug ********************************************************************/
-/* Non-standard debug that may be enabled just for testing the watchdog driver */
-
-#ifdef CONFIG_DEBUG_WATCHDOG
-# define wddbg dbg
-# define wdvdbg vdbg
-# define wdlldbg lldbg
-# define wdllvdbg llvdbg
-#else
-# define wddbg(x...)
-# define wdvdbg(x...)
-# define wdlldbg(x...)
-# define wdllvdbg(x...)
-#endif
-
-/****************************************************************************
- * Private Type Definitions
- ****************************************************************************/
-
-/* This structure describes the state of the upper half driver */
-
-struct watchdog_upperhalf_s
-{
- uint8_t crefs; /* The number of times the device has been opened */
- sem_t exclsem; /* Supports mutual exclusion */
- FAR char *path; /* Registration path */
-
- /* The contained lower-half driver */
-
- FAR struct watchdog_lowerhalf_s *lower;
-};
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int wdog_open(FAR struct file *filep);
-static int wdog_close(FAR struct file *filep);
-static ssize_t wdog_read(FAR struct file *filep, FAR char *buffer,
- size_t buflen);
-static ssize_t wdog_write(FAR struct file *filep, FAR const char *buffer,
- size_t buflen);
-static int wdog_ioctl(FAR struct file *filep, int cmd,
- unsigned long arg);
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-static const struct file_operations g_wdogops =
-{
- wdog_open, /* open */
- wdog_close, /* close */
- wdog_read, /* read */
- wdog_write, /* write */
- 0, /* seek */
- wdog_ioctl /* ioctl */
-#ifndef CONFIG_DISABLE_POLL
- , 0 /* poll */
-#endif
-};
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/************************************************************************************
- * Name: wdog_open
- *
- * Description:
- * This function is called whenever the watchdog timer device is opened.
- *
- ************************************************************************************/
-
-static int wdog_open(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct watchdog_upperhalf_s *upper = inode->i_private;
- uint8_t tmp;
- int ret;
-
- wdvdbg("crefs: %d\n", upper->crefs);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0)
- {
- ret = -errno;
- goto errout;
- }
-
- /* Increment the count of references to the device. If this the first
- * time that the driver has been opened for this device, then initialize
- * the device.
- */
-
- tmp = upper->crefs + 1;
- if (tmp == 0)
- {
- /* More than 255 opens; uint8_t overflows to zero */
-
- ret = -EMFILE;
- goto errout_with_sem;
- }
-
- /* Save the new open count */
-
- upper->crefs = tmp;
- ret = OK;
-
-errout_with_sem:
- sem_post(&upper->exclsem);
-
-errout:
- return ret;
-}
-
-/************************************************************************************
- * Name: wdog_close
- *
- * Description:
- * This function is called when the watchdog timer device is closed.
- *
- ************************************************************************************/
-
-static int wdog_close(FAR struct file *filep)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct watchdog_upperhalf_s *upper = inode->i_private;
- int ret;
-
- wdvdbg("crefs: %d\n", upper->crefs);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0)
- {
- ret = -errno;
- goto errout;
- }
-
- /* Decrement the references to the driver. If the reference count will
- * decrement to 0, then uninitialize the driver.
- */
-
- if (upper->crefs > 0)
- {
- upper->crefs--;
- }
-
- sem_post(&upper->exclsem);
- ret = OK;
-
-errout:
- return ret;
-}
-
-/************************************************************************************
- * Name: wdog_read
- *
- * Description:
- * A dummy read method. This is provided only to satsify the VFS layer.
- *
- ************************************************************************************/
-
-static ssize_t wdog_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
-{
- /* Return zero -- usually meaning end-of-file */
-
- return 0;
-}
-
-/************************************************************************************
- * Name: wdog_write
- *
- * Description:
- * A dummy write method. This is provided only to satsify the VFS layer.
- *
- ************************************************************************************/
-
-static ssize_t wdog_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
-{
- return 0;
-}
-
-/************************************************************************************
- * Name: wdog_ioctl
- *
- * Description:
- * The standard ioctl method. This is where ALL of the watchdog timer work is
- * done.
- *
- ************************************************************************************/
-
-static int wdog_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
-{
- FAR struct inode *inode = filep->f_inode;
- FAR struct watchdog_upperhalf_s *upper = inode->i_private;
- FAR struct watchdog_lowerhalf_s *lower = upper->lower;
- int ret;
-
- wdvdbg("cmd: %d arg: %ld\n", cmd, arg);
- DEBUGASSERT(upper && lower);
-
- /* Get exclusive access to the device structures */
-
- ret = sem_wait(&upper->exclsem);
- if (ret < 0)
- {
- return ret;
- }
-
- /* Handle built-in ioctl commands */
-
- switch (cmd)
- {
- /* cmd: WDIOC_START
- * Description: Start the watchdog timer
- * Argument: Ignored
- */
-
- case WDIOC_START:
- {
- /* Start the watchdog timer, resetting the time to the current timeout */
-
- DEBUGASSERT(lower->ops->start); /* Required */
- ret = lower->ops->start(lower);
- }
- break;
-
- /* cmd: WDIOC_STOP
- * Description: Stop the watchdog timer
- * Argument: Ignored
- */
-
- case WDIOC_STOP:
- {
- /* Stop the watchdog timer */
-
- DEBUGASSERT(lower->ops->stop); /* Required */
- ret = lower->ops->stop(lower);
- }
- break;
-
- /* cmd: WDIOC_GETSTATUS
- * Description: et the status of the watchdog timer.
- * Argument: A writeable pointer to struct watchdog_status_s.
- */
-
- case WDIOC_GETSTATUS:
- {
- FAR struct watchdog_status_s *status;
-
- /* Get the current watchdog timer status */
-
- if (lower->ops->getstatus) /* Optional */
- {
- status = (FAR struct watchdog_status_s *)((uintptr_t)arg);
- if (status)
- {
- ret = lower->ops->getstatus(lower, status);
- }
- else
- {
- ret = -EINVAL;
- }
- }
- else
- {
- ret = -ENOSYS;
- }
- }
- break;
-
- /* cmd: WDIOC_SETTIMEOUT
- * Description: Reset the watchdog timeout to this value
- * Argument: A 32-bit timeout value in milliseconds.
- */
-
- case WDIOC_SETTIMEOUT:
- {
- /* Set a new timeout value (and reset the watchdog timer) */
-
- if (lower->ops->settimeout) /* Optional */
- {
- ret = lower->ops->settimeout(lower, (uint32_t)arg);
- }
- else
- {
- ret = -ENOSYS;
- }
- }
- break;
-
- /* cmd: WDIOC_CAPTURE
- * Description: Do not reset. Instead, called this handler.
- * Argument: A pointer to struct watchdog_capture_s.
- */
-
- case WDIOC_CAPTURE:
- {
- FAR struct watchdog_capture_s *capture;
-
- /* Don't reset on watchdog timer timeout; instead, call this user
- * provider timeout handler. NOTE: Providing handler==NULL will
- * restore the reset behavior.
- */
-
- if (lower->ops->capture) /* Optional */
- {
- capture = (FAR struct watchdog_capture_s *)((uintptr_t)arg);
- if (capture)
- {
- capture->oldhandler =
- lower->ops->capture(lower, capture->newhandler);
- ret = OK;
- }
- else
- {
- ret = -EINVAL;
- }
- }
- else
- {
- ret = -ENOSYS;
- }
- }
- break;
-
- /* cmd: WDIOC_KEEPALIVE
- * Description: Reset the watchdog timer ("ping", "pet the dog")
- * Argument: Argument: Ignored
- */
-
- case WDIOC_KEEPALIVE:
- {
- /* Reset the watchdog timer to the current timeout value, prevent any
- * imminent watchdog timeouts. This is sometimes referred as
- * "pinging" the watchdog timer or "petting the dog".
- */
-
- if (lower->ops->keepalive) /* Optional */
- {
- ret = lower->ops->keepalive(lower);
- }
- else
- {
- ret = -ENOSYS;
- }
- }
- break;
-
-
- /* Any unrecognized IOCTL commands might be platform-specific ioctl commands */
-
- default:
- {
- wdvdbg("Forwarding unrecognized cmd: %d arg: %ld\n", cmd, arg);
-
- /* An ioctl commands that are not recognized by the "upper-half"
- * driver are forwarded to the lower half driver through this
- * method.
- */
-
- if (lower->ops->ioctl) /* Optional */
- {
- ret = lower->ops->ioctl(lower, cmd, arg);
- }
- else
- {
- ret = -ENOSYS;
- }
- }
- break;
- }
-
- sem_post(&upper->exclsem);
- return ret;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: watchdog_register
- *
- * Description:
- * This function binds an instance of a "lower half" watchdog driver with the
- * "upper half" watchdog device and registers that device so that can be used
- * by application code.
- *
- * When this function is called, the "lower half" driver should be in the
- * disabled state (as if the stop() method had already been called).
- *
- * Input parameters:
- * dev path - The full path to the driver to be registers in the NuttX
- * pseudo-filesystem. The recommended convention is to name all watchdog
- * drivers as "/dev/watchdog0", "/dev/watchdog1", etc. where the driver
- * path differs only in the "minor" number at the end of the device name.
- * lower - A pointer to an instance of lower half watchdog driver. This
- * instance is bound to the watchdog driver and must persists as long as
- * the driver persists.
- *
- * Returned Value:
- * On success, a non-NULL handle is returned to the caller. In the event
- * of any failure, a NULL value is returned.
- *
- ****************************************************************************/
-
-FAR void *watchdog_register(FAR const char *path,
- FAR struct watchdog_lowerhalf_s *lower)
-{
- FAR struct watchdog_upperhalf_s *upper;
- int ret;
-
- DEBUGASSERT(path && lower);
- wdvdbg("Entry: path=%s\n", path);
-
- /* Allocate the upper-half data structure */
-
- upper = (FAR struct watchdog_upperhalf_s *)
- kzalloc(sizeof(struct watchdog_upperhalf_s));
- if (!upper)
- {
- wddbg("Upper half allocation failed\n");
- goto errout;
- }
-
- /* Initialize the watchdog timer device structure (it was already zeroed
- * by kzalloc()).
- */
-
- sem_init(&upper->exclsem, 0, 1);
- upper->lower = lower;
-
- /* Copy the registration path */
-
- upper->path = strdup(path);
- if (!upper->path)
- {
- wddbg("Path allocation failed\n");
- goto errout_with_upper;
- }
-
- /* Register the watchdog timer device */
-
- ret = register_driver(path, &g_wdogops, 0666, upper);
- if (ret < 0)
- {
- wddbg("register_driver failed: %d\n", ret);
- goto errout_with_path;
- }
-
- return (FAR void *)upper;
-
-errout_with_path:
- kfree(upper->path);
-
-errout_with_upper:
- sem_destroy(&upper->exclsem);
- kfree(upper);
-
-errout:
- return NULL;
-}
-
-/****************************************************************************
- * Name: watchdog_unregister
- *
- * Description:
- * This function can be called to disable and unregister the watchdog
- * device driver.
- *
- * Input parameters:
- * handle - This is the handle that was returned by watchdog_register()
- *
- * Returned Value:
- * None
- *
- ****************************************************************************/
-
-void watchdog_unregister(FAR void *handle)
-{
- FAR struct watchdog_upperhalf_s *upper;
- FAR struct watchdog_lowerhalf_s *lower;
-
- /* Recover the pointer to the upper-half driver state */
-
- upper = (FAR struct watchdog_upperhalf_s *)handle;
- lower = upper->lower;
- DEBUGASSERT(upper && lower);
-
- wdvdbg("Unregistering: %s\n", upper->path);
-
- /* Disable the watchdog timer */
-
- DEBUGASSERT(lower->ops->stop); /* Required */
- (void)lower->ops->stop(lower);
-
- /* Unregister the watchdog timer device */
-
- (void)unregister_driver(upper->path);
-
- /* Then free all of the driver resources */
-
- kfree(upper->path);
- sem_destroy(&upper->exclsem);
- kfree(upper);
-}
-
-#endif /* CONFIG_WATCHDOG */
diff --git a/nuttx/drivers/wireless/Kconfig b/nuttx/drivers/wireless/Kconfig
deleted file mode 100644
index ae2bf3130..000000000
--- a/nuttx/drivers/wireless/Kconfig
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
diff --git a/nuttx/drivers/wireless/Make.defs b/nuttx/drivers/wireless/Make.defs
deleted file mode 100644
index fa8e8acb5..000000000
--- a/nuttx/drivers/wireless/Make.defs
+++ /dev/null
@@ -1,47 +0,0 @@
-############################################################################
-# drivers/wireless/Make.defs
-#
-# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved.
-# Author: Gregory Nutt <gnutt@nuttx.org>
-#
-# 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.
-#
-############################################################################
-
-ifeq ($(CONFIG_WIRELESS),y)
-
-# Include wireless drivers
-
-CSRCS += cc1101.c ISM1_868MHzGFSK100kbps.c ISM2_905MHzGFSK250kbps.c
-
-# Include wireless build support
-
-DEPPATH += --dep-path wireless$(DELIM)cc1101
-VPATH += :wireless$(DELIM)cc1101
-CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)drivers$(DELIM)wireless$(DELIM)cc1101}
-endif
diff --git a/nuttx/drivers/wireless/cc1101/ISM1_868MHzGFSK100kbps.c b/nuttx/drivers/wireless/cc1101/ISM1_868MHzGFSK100kbps.c
deleted file mode 100644
index 5c4c58ab2..000000000
--- a/nuttx/drivers/wireless/cc1101/ISM1_868MHzGFSK100kbps.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/****************************************************************************
- * drivers/wireless/cc1101/ISM1_868MHzGFSK100kbps.c
- *
- * Copyright (C) 2011 Uros Platise. All rights reserved.
- * Copyright (C) 2011 Ales Verbic. All rights reserved.
- *
- * Authors: Uros Platise <uros.platise@isotel.eu>
- * Ales Verbic <ales.verbic@isotel.eu>
- *
- * 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.
- *
- ****************************************************************************/
-
-#include <nuttx/wireless/cc1101.h>
-
-/** Settings for 868 MHz, GFSK at 100kbps
- *
- * ISM Region 1 (Europe) only, Band 868–870 MHz
- *
- * Frequency ERP Duty Cycle Bandwidth Remarks
- * 868 – 868.6 MHz +14 dBm < 1% No limits
- * 868.7 – 869.2 MHz +14 dBm < 0.1% No limits
- * 869.3 – 869.4 MHz +10 dBm No limits < 25 kHz Appropriate access protocol required
- * 869.4 – 869.65 MHz +27 dBm < 10% < 25 kHz Channels may be combined to one high speed channel
- * 869.7 -870 MHz +7 dBm No limits No limits
- *
- * Deviation = 46.142578
- * Base frequency = 867.999985
- * Carrier frequency = 867.999985
- * Channel number = 0
- * Carrier frequency = 867.999985
- * Modulated = true
- * Modulation format = GFSK
- * Manchester enable = false
- * Sync word qualifier mode = 30/32 sync word bits detected
- * Preamble count = 4
- * Channel spacing = 199.813843
- * Carrier frequency = 867.999985
- * Data rate = 99.9069
- * RX filter BW = 210.937500
- * Data format = Normal mode
- * Length config = Fixed packet length mode. Length configured in PKTLEN register
- * CRC enable = true
- * Packet length = 62
- * Device address = 00
- * Address config = NO Address check, no broadcast
- * CRC autoflush = true
- * PA ramping = false
- * TX power = 0
- */
-const struct c1101_rfsettings_s cc1101_rfsettings_ISM1_868MHzGFSK100kbps = {
- .FSCTRL1 = 0x08, // FSCTRL1 Frequency Synthesizer Control
- .FSCTRL0 = 0x00, // FSCTRL0 Frequency Synthesizer Control
-
- .FREQ2 = 0x20, // FREQ2 Frequency Control Word, High Byte
- .FREQ1 = 0x25, // FREQ1 Frequency Control Word, Middle Byte
- .FREQ0 = 0xED, // FREQ0 Frequency Control Word, Low Byte
-
- .MDMCFG4 = 0x8B, // MDMCFG4 Modem Configuration
- .MDMCFG3 = 0xE5, // MDMCFG3 Modem Configuration
- .MDMCFG2 = 0x13, // MDMCFG2 Modem Configuration
- .MDMCFG1 = 0x22, // MDMCFG1 Modem Configuration
- .MDMCFG0 = 0xE5, // MDMCFG0 Modem Configuration
-
- .DEVIATN = 0x46, // DEVIATN Modem Deviation Setting
-
- .FOCCFG = 0x1D, // FOCCFG Frequency Offset Compensation Configuration
-
- .BSCFG = 0x1C, // BSCFG Bit Synchronization Configuration
-
- .AGCCTRL2= 0xC7, // AGCCTRL2 AGC Control
- .AGCCTRL1= 0x00, // AGCCTRL1 AGC Control
- .AGCCTRL0= 0xB2, // AGCCTRL0 AGC Control
-
- .FREND1 = 0xB6, // FREND1 Front End RX Configuration
- .FREND0 = 0x10, // FREND0 Front End TX Configuration
-
- .FSCAL3 = 0xEA, // FSCAL3 Frequency Synthesizer Calibration
- .FSCAL2 = 0x2A, // FSCAL2 Frequency Synthesizer Calibration
- .FSCAL1 = 0x00, // FSCAL1 Frequency Synthesizer Calibration
- .FSCAL0 = 0x1F, // FSCAL0 Frequency Synthesizer Calibration
-
- .CHMIN = 0, // Fix at 9th channel: 869.80 MHz +- 100 kHz RF Bandwidth
- .CHMAX = 9, // single channel
-
- .PAMAX = 8, // 0 means power OFF, 8 represents PA[7]
- .PA = {0x03, 0x0F, 0x1E, 0x27, 0x67, 0x50, 0x81, 0xC2}
-};
diff --git a/nuttx/drivers/wireless/cc1101/ISM2_905MHzGFSK250kbps.c b/nuttx/drivers/wireless/cc1101/ISM2_905MHzGFSK250kbps.c
deleted file mode 100644
index e5655bed6..000000000
--- a/nuttx/drivers/wireless/cc1101/ISM2_905MHzGFSK250kbps.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
- * drivers/wireless/cc1101/ISM2_905MHzGFSK250kbps.c
- *
- * Copyright (C) 2011 Uros Platise. All rights reserved.
- * Copyright (C) 2011 Ales Verbic. All rights reserved.
- *
- * Authors: Uros Platise <uros.platise@isotel.eu>
- * Ales Verbic <ales.verbic@isotel.eu>
- *
- * 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.
- *
- ****************************************************************************/
-
-#include <nuttx/wireless/cc1101.h>
-
-/** Settings for 905 MHz, GFSK at 250kbps
- *
- * ISM Region 2 (America) only, Band 902–928 MHz
- *
- * Cordless phones 1 W
- * Microwave ovens 750 W
- * Industrial heaters 100 kW
- * Military radar 1000 kW
- *
- * Deviation = 126.953125
- * Base frequency = 901.999969
- * Carrier frequency = 905.998993
- * Channel number = 20
- * Carrier frequency = 905.998993
- * Modulated = true
- * Modulation format = GFSK
- * Manchester enable = false
- * Sync word qualifier mode = 30/32 sync word bits detected
- * Preamble count = 4
- * Channel spacing = 199.951172
- * Carrier frequency = 905.998993
- * Data rate = 249.939
- * RX filter BW = 541.666667
- * Data format = Normal mode
- * Length config = Variable packet length mode. Packet length configured by the first byte after sync word
- * CRC enable = true
- * Packet length = 61
- * Device address = 0
- * Address config = No address check
- * CRC autoflush = false
- * PA ramping = false
- * TX power = 0
- */
-const struct c1101_rfsettings_s cc1101_rfsettings_ISM2_905MHzGFSK250kbps = {
- .FSCTRL1 = 0x0C, // FSCTRL1 Frequency Synthesizer Control
- .FSCTRL0 = 0x00, // FSCTRL0 Frequency Synthesizer Control
-
- .FREQ2 = 0x22, // FREQ2 Frequency Control Word, High Byte
- .FREQ1 = 0xB1, // FREQ1 Frequency Control Word, Middle Byte
- .FREQ0 = 0x3B, // FREQ0 Frequency Control Word, Low Byte
-
- .MDMCFG4 = 0x2D, // MDMCFG4 Modem Configuration
- .MDMCFG3 = 0x3B, // MDMCFG3 Modem Configuration
- .MDMCFG2 = 0x13, // MDMCFG2 Modem Configuration
- .MDMCFG1 = 0x22, // MDMCFG1 Modem Configuration
- .MDMCFG0 = 0xF8, // MDMCFG0 Modem Configuration
-
- .DEVIATN = 0x62, // DEVIATN Modem Deviation Setting
-
- .FOCCFG = 0x1D, // FOCCFG Frequency Offset Compensation Configuration
-
- .BSCFG = 0x1C, // BSCFG Bit Synchronization Configuration
-
- .AGCCTRL2= 0xC7, // AGCCTRL2 AGC Control
- .AGCCTRL1= 0x00, // AGCCTRL1 AGC Control
- .AGCCTRL0= 0xB0, // AGCCTRL0 AGC Control
-
- .FREND1 = 0xB6, // FREND1 Front End RX Configuration
- .FREND0 = 0x10, // FREND0 Front End TX Configuration
-
- .FSCAL3 = 0xEA, // FSCAL3 Frequency Synthesizer Calibration
- .FSCAL2 = 0x2A, // FSCAL2 Frequency Synthesizer Calibration
- .FSCAL1 = 0x00, // FSCAL1 Frequency Synthesizer Calibration
- .FSCAL0 = 0x1F, // FSCAL0 Frequency Synthesizer Calibration
-
- .CHMIN = 0, // VERIFY REGULATIONS!
- .CHMAX = 0xFF,
-
- .PAMAX = 8, // 0 means power OFF, 8 represents PA[7]
- .PA = {0x03, 0x0E, 0x1E, 0x27, 0x39, 0x8E, 0xCD, 0xC0}
-};
diff --git a/nuttx/drivers/wireless/cc1101/Kconfig b/nuttx/drivers/wireless/cc1101/Kconfig
deleted file mode 100644
index ae2bf3130..000000000
--- a/nuttx/drivers/wireless/cc1101/Kconfig
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# For a description of the syntax of this configuration file,
-# see misc/tools/kconfig-language.txt.
-#
diff --git a/nuttx/drivers/wireless/cc1101/cc1101.c b/nuttx/drivers/wireless/cc1101/cc1101.c
deleted file mode 100644
index 45faaecd2..000000000
--- a/nuttx/drivers/wireless/cc1101/cc1101.c
+++ /dev/null
@@ -1,812 +0,0 @@
-/****************************************************************************
- * drivers/wireless/cc1101/cc1101.c
- *
- * Copyright (C) 2011 Uros Platise. All rights reserved.
- *
- * Authors: Uros Platise <uros.platise@isotel.eu>
- *
- * 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.
- *
- ****************************************************************************/
-
-/** \file
- * \author Uros Platise
- * \brief Chipcon CC1101 Device Driver
- *
- * Features:
- * - Maximum data length: 61 bytes CC1101_PACKET_MAXDATALEN
- * - Packet length includes two additional bytes: CC1101_PACKET_MAXTOTALLEN
- * - Requires one GDO to trigger end-of-packets in RX and TX modes.
- * - Variable packet length with data payload between 1..61 bytes
- * (three bytes are reserved for packet length, and RSSI and LQI
- * appended at the end of RXFIFO after each reception)
- * - Support for General Digital Outputs with overload protection
- * (single XOSC pin is allowed, otherwise error is returned)
- * - Loadable RF settings, one for ISM Region 1 (Europe) and one for
- * ISM Region 2 (Complete America)
- *
- * Todo:
- * - Extend max packet length up to 255 bytes or rather infinite < 4096 bytes
- * - Power up/down modes
- * - Sequencing between states or add protection for correct termination of
- * various different state (so that CC1101 does not block in case of improper use)
- *
- * \par RSSI and LQI value interpretation
- *
- * The LQI can be read from the LQI status register or it can be appended
- * to the received packet in the RX FIFO. LQI is a metric of the current
- * quality of the received signal. The LQI gives an estimate of how easily
- * a received signal can be demodulated by accumulating the magnitude of
- * the error between ideal constellations and the received signal over
- * the 64 symbols immediately following the sync word. LQI is best used
- * as a relative measurement of the link quality (a high value indicates
- * a better link than what a low value does), since the value is dependent
- * on the modulation format.
- *
- * To simplify: If the received modulation is FSK or GFSK, the receiver
- * will measure the frequency of each "bit" and compare it with the
- * expected frequency based on the channel frequency and the deviation
- * and the measured frequency offset. If other modulations are used, the
- * error of the modulated parameter (frequency for FSK/GFSK, phase for
- * MSK, amplitude for ASK etc) will be measured against the expected
- * ideal value
- *
- * RSSI (Received Signal Strength Indicator) is a signal strength
- * indication. It does not care about the "quality" or "correctness" of
- * the signal. LQI does not care about the actual signal strength, but
- * the signal quality often is linked to signal strength. This is because
- * a strong signal is likely to be less affected by noise and thus will
- * be seen as "cleaner" or more "correct" by the receiver.
- *
- * There are four to five "extreme cases" that can be used to illustrate
- * how RSSI and LQI work:
- * 1. A weak signal in the presence of noise may give low RSSI and low LQI.
- * 2. A weak signal in "total" absence of noise may give low RSSI and high LQI.
- * 3. Strong noise (usually coming from an interferer) may give high RSSI and low LQI.
- * 4. A strong signal without much noise may give high RSSI and high LQI.
- * 5. A very strong signal that causes the receiver to saturate may give
- * high RSSI and low LQI.
- *
- * Note that both RSSI and LQI are best used as relative measurements since
- * the values are dependent on the modulation format.
- **/
-
-#include <nuttx/config.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include <nuttx/kmalloc.h>
-#include <nuttx/wireless/cc1101.h>
-
-
-/****************************************************************************
- * Declarations
- ****************************************************************************/
-
-#define CC1101_SPIFREQ_BURST 6500000 /* Hz, no delay */
-#define CC1101_SPIFREQ_SINGLE 9000000 /* Hz, single access only - no delay */
-
-#define CC1101_MCSM0_VALUE 0x1C
-
-/****************************************************************************
- * Chipcon CC1101 Internal Registers
- ****************************************************************************/
-
-/* Configuration Registers */
-
-#define CC1101_IOCFG2 0x00 /* GDO2 output pin configuration */
-#define CC1101_IOCFG1 0x01 /* GDO1 output pin configuration */
-#define CC1101_IOCFG0 0x02 /* GDO0 output pin configuration */
-#define CC1101_FIFOTHR 0x03 /* RX FIFO and TX FIFO thresholds */
-#define CC1101_SYNC1 0x04 /* Sync word, high byte */
-#define CC1101_SYNC0 0x05 /* Sync word, low byte */
-#define CC1101_PKTLEN 0x06 /* Packet length */
-#define CC1101_PKTCTRL1 0x07 /* Packet automation control */
-#define CC1101_PKTCTRL0 0x08 /* Packet automation control */
-#define CC1101_ADDR 0x09 /* Device address */
-#define CC1101_CHANNR 0x0A /* Channel number */
-#define CC1101_FSCTRL1 0x0B /* Frequency synthesizer control */
-#define CC1101_FSCTRL0 0x0C /* Frequency synthesizer control */
-#define CC1101_FREQ2 0x0D /* Frequency control word, high byte */
-#define CC1101_FREQ1 0x0E /* Frequency control word, middle byte */
-#define CC1101_FREQ0 0x0F /* Frequency control word, low byte */
-#define CC1101_MDMCFG4 0x10 /* Modem configuration */
-#define CC1101_MDMCFG3 0x11 /* Modem configuration */
-#define CC1101_MDMCFG2 0x12 /* Modem configuration */
-#define CC1101_MDMCFG1 0x13 /* Modem configuration */
-#define CC1101_MDMCFG0 0x14 /* Modem configuration */
-#define CC1101_DEVIATN 0x15 /* Modem deviation setting */
-#define CC1101_MCSM2 0x16 /* Main Radio Cntrl State Machine config */
-#define CC1101_MCSM1 0x17 /* Main Radio Cntrl State Machine config */
-#define CC1101_MCSM0 0x18 /* Main Radio Cntrl State Machine config */
-#define CC1101_FOCCFG 0x19 /* Frequency Offset Compensation config */
-#define CC1101_BSCFG 0x1A /* Bit Synchronization configuration */
-#define CC1101_AGCCTRL2 0x1B /* AGC control */
-#define CC1101_AGCCTRL1 0x1C /* AGC control */
-#define CC1101_AGCCTRL0 0x1D /* AGC control */
-#define CC1101_WOREVT1 0x1E /* High byte Event 0 timeout */
-#define CC1101_WOREVT0 0x1F /* Low byte Event 0 timeout */
-#define CC1101_WORCTRL 0x20 /* Wake On Radio control */
-#define CC1101_FREND1 0x21 /* Front end RX configuration */
-#define CC1101_FREND0 0x22 /* Front end TX configuration */
-#define CC1101_FSCAL3 0x23 /* Frequency synthesizer calibration */
-#define CC1101_FSCAL2 0x24 /* Frequency synthesizer calibration */
-#define CC1101_FSCAL1 0x25 /* Frequency synthesizer calibration */
-#define CC1101_FSCAL0 0x26 /* Frequency synthesizer calibration */
-#define CC1101_RCCTRL1 0x27 /* RC oscillator configuration */
-#define CC1101_RCCTRL0 0x28 /* RC oscillator configuration */
-#define CC1101_FSTEST 0x29 /* Frequency synthesizer cal control */
-#define CC1101_PTEST 0x2A /* Production test */
-#define CC1101_AGCTEST 0x2B /* AGC test */
-#define CC1101_TEST2 0x2C /* Various test settings */
-#define CC1101_TEST1 0x2D /* Various test settings */
-#define CC1101_TEST0 0x2E /* Various test settings */
-
-/* Status registers */
-
-#define CC1101_PARTNUM (0x30 | 0xc0) /* Part number */
-#define CC1101_VERSION (0x31 | 0xc0) /* Current version number */
-#define CC1101_FREQEST (0x32 | 0xc0) /* Frequency offset estimate */
-#define CC1101_LQI (0x33 | 0xc0) /* Demodulator estimate for link quality */
-#define CC1101_RSSI (0x34 | 0xc0) /* Received signal strength indication */
-#define CC1101_MARCSTATE (0x35 | 0xc0) /* Control state machine state */
-#define CC1101_WORTIME1 (0x36 | 0xc0) /* High byte of WOR timer */
-#define CC1101_WORTIME0 (0x37 | 0xc0) /* Low byte of WOR timer */
-#define CC1101_PKTSTATUS (0x38 | 0xc0) /* Current GDOx status and packet status */
-#define CC1101_VCO_VC_DAC (0x39 | 0xc0) /* Current setting from PLL cal module */
-#define CC1101_TXBYTES (0x3A | 0xc0) /* Underflow and # of bytes in TXFIFO */
-#define CC1101_RXBYTES (0x3B | 0xc0) /* Overflow and # of bytes in RXFIFO */
-#define CC1101_RCCTRL1_STATUS (0x3C | 0xc0) /* Last RC oscilator calibration results */
-#define CC1101_RCCTRL0_STATUS (0x3D | 0xc0) /* Last RC oscilator calibration results */
-
-/* Multi byte memory locations */
-
-#define CC1101_PATABLE 0x3E
-#define CC1101_TXFIFO 0x3F
-#define CC1101_RXFIFO 0x3F
-
-/* Definitions for burst/single access to registers */
-
-#define CC1101_WRITE_BURST 0x40
-#define CC1101_READ_SINGLE 0x80
-#define CC1101_READ_BURST 0xC0
-
-/* Strobe commands */
-
-#define CC1101_SRES 0x30 /* Reset chip. */
-#define CC1101_SFSTXON 0x31 /* Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1). */
-#define CC1101_SXOFF 0x32 /* Turn off crystal oscillator. */
-#define CC1101_SCAL 0x33 /* Calibrate frequency synthesizer and turn it off */
-#define CC1101_SRX 0x34 /* Enable RX. Perform calibration first if switching from IDLE and MCSM0.FS_AUTOCAL=1. */
-#define CC1101_STX 0x35 /* Enable TX. Perform calibration first if IDLE and MCSM0.FS_AUTOCAL=1. */
- /* If switching from RX state and CCA is enabled then go directly to TX if channel is clear. */
-#define CC1101_SIDLE 0x36 /* Exit RX / TX, turn off frequency synthesizer and exit Wake-On-Radio mode if applicable. */
-#define CC1101_SAFC 0x37 /* Perform AFC adjustment of the frequency synthesizer */
-#define CC1101_SWOR 0x38 /* Start automatic RX polling sequence (Wake-on-Radio) */
-#define CC1101_SPWD 0x39 /* Enter power down mode when CSn goes high. */
-#define CC1101_SFRX 0x3A /* Flush the RX FIFO buffer. */
-#define CC1101_SFTX 0x3B /* Flush the TX FIFO buffer. */
-#define CC1101_SWORRST 0x3C /* Reset real time clock. */
-#define CC1101_SNOP 0x3D /* No operation. */
-
-/* Modem Control */
-
-#define CC1101_MCSM0_XOSC_FORCE_ON 0x01
-
-
-/*
- * Chip Status Byte
- */
-
-/* Bit fields in the chip status byte */
-
-#define CC1101_STATUS_CHIP_RDYn_BM 0x80
-#define CC1101_STATUS_STATE_BM 0x70
-#define CC1101_STATUS_FIFO_BYTES_AVAILABLE_BM 0x0F
-
-/* Chip states */
-
-#define CC1101_STATE_MASK 0x70
-#define CC1101_STATE_IDLE 0x00
-#define CC1101_STATE_RX 0x10
-#define CC1101_STATE_TX 0x20
-#define CC1101_STATE_FSTXON 0x30
-#define CC1101_STATE_CALIBRATE 0x40
-#define CC1101_STATE_SETTLING 0x50
-#define CC1101_STATE_RX_OVERFLOW 0x60
-#define CC1101_STATE_TX_UNDERFLOW 0x70
-
-/* Values of the MACRSTATE register */
-
-#define CC1101_MARCSTATE_SLEEP 0x00
-#define CC1101_MARCSTATE_IDLE 0x01
-#define CC1101_MARCSTATE_XOFF 0x02
-#define CC1101_MARCSTATE_VCOON_MC 0x03
-#define CC1101_MARCSTATE_REGON_MC 0x04
-#define CC1101_MARCSTATE_MANCAL 0x05
-#define CC1101_MARCSTATE_VCOON 0x06
-#define CC1101_MARCSTATE_REGON 0x07
-#define CC1101_MARCSTATE_STARTCAL 0x08
-#define CC1101_MARCSTATE_BWBOOST 0x09
-#define CC1101_MARCSTATE_FS_LOCK 0x0A
-#define CC1101_MARCSTATE_IFADCON 0x0B
-#define CC1101_MARCSTATE_ENDCAL 0x0C
-#define CC1101_MARCSTATE_RX 0x0D
-#define CC1101_MARCSTATE_RX_END 0x0E
-#define CC1101_MARCSTATE_RX_RST 0x0F
-#define CC1101_MARCSTATE_TXRX_SWITCH 0x10
-#define CC1101_MARCSTATE_RXFIFO_OVERFLOW 0x11
-#define CC1101_MARCSTATE_FSTXON 0x12
-#define CC1101_MARCSTATE_TX 0x13
-#define CC1101_MARCSTATE_TX_END 0x14
-#define CC1101_MARCSTATE_RXTX_SWITCH 0x15
-#define CC1101_MARCSTATE_TXFIFO_UNDERFLOW 0x16
-
-/* Part number and version */
-
-#define CC1101_PARTNUM_VALUE 0x00
-#define CC1101_VERSION_VALUE 0x04
-
-/*
- * Others ...
- */
-
-#define CC1101_LQI_CRC_OK_BM 0x80
-#define CC1101_LQI_EST_BM 0x7F
-
-
-/****************************************************************************
- * Private Data Types
- ****************************************************************************/
-
-#define FLAGS_RXONLY 1 /* Indicates receive operation only */
-#define FLAGS_XOSCENABLED 2 /* Indicates that one pin is configured as XOSC/n */
-
-struct cc1101_dev_s {
- const struct c1101_rfsettings_s *rfsettings;
-
- struct spi_dev_s * spi;
- uint8_t isrpin; /* CC1101 pin used to trigger interrupts */
- uint32_t pinset; /* GPIO of the MCU */
- uint8_t flags;
- uint8_t channel;
- uint8_t power;
-};
-
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-void cc1101_access_begin(struct cc1101_dev_s * dev)
-{
- (void)SPI_LOCK(dev->spi, true);
- SPI_SELECT(dev->spi, SPIDEV_WIRELESS, true);
- SPI_SETMODE(dev->spi, SPIDEV_MODE0); /* CPOL=0, CPHA=0 */
- SPI_SETBITS(dev->spi, 8);
-}
-
-
-void cc1101_access_end(struct cc1101_dev_s * dev)
-{
- SPI_SELECT(dev->spi, SPIDEV_WIRELESS, false);
- (void)SPI_LOCK(dev->spi, false);
-}
-
-
-/** CC1101 Access with Range Check
- *
- * \param dev CC1101 Private Structure
- * \param addr CC1101 Address
- * \param buf Pointer to buffer, either for read or write access
- * \param length when >0 it denotes read access, when <0 it denotes write
- * access of -length. abs(length) greater of 1 implies burst mode,
- * however
- * \return OK on success or errno is set.
- */
-int cc1101_access(struct cc1101_dev_s * dev, uint8_t addr, uint8_t *buf, int length)
-{
- int stabyte;
-
- /* Address cannot explicitly define READ command while length WRITE.
- * Also access to these cells is only permitted as one byte, eventhough
- * transfer is marked as BURST!
- */
-
- if ( (addr & CC1101_READ_SINGLE) && length != 1 )
- return ERROR;
-
- /* Prepare SPI */
-
- cc1101_access_begin(dev);
-
- if (length>1 || length < -1)
- SPI_SETFREQUENCY(dev->spi, CC1101_SPIFREQ_BURST);
- else SPI_SETFREQUENCY(dev->spi, CC1101_SPIFREQ_SINGLE);
-
- /* Transfer */
-
- if (length <= 0) { /* 0 length are command strobes */
- if (length < -1)
- addr |= CC1101_WRITE_BURST;
-
- stabyte = SPI_SEND(dev->spi, addr);
- if (length) {
- SPI_SNDBLOCK(dev->spi, buf, -length);
- }
- }
- else {
- addr |= CC1101_READ_SINGLE;
- if (length > 1)
- addr |= CC1101_READ_BURST;
-
- stabyte = SPI_SEND(dev->spi, addr);
- SPI_RECVBLOCK(dev->spi, buf, length);
- }
-
- cc1101_access_end(dev);
-
- return stabyte;
-}
-
-
-/** Strobes command and returns chip status byte
- *
- * By default commands are send as Write. To a command,
- * CC1101_READ_SINGLE may be OR'ed to obtain the number of RX bytes
- * pending in RX FIFO.
- */
-inline uint8_t cc1101_strobe(struct cc1101_dev_s * dev, uint8_t command)
-{
- uint8_t status;
-
- cc1101_access_begin(dev);
- SPI_SETFREQUENCY(dev->spi, CC1101_SPIFREQ_SINGLE);
-
- status = SPI_SEND(dev->spi, command);
-
- cc1101_access_end(dev);
-
- return status;
-}
-
-
-int cc1101_reset(struct cc1101_dev_s * dev)
-{
- cc1101_strobe(dev, CC1101_SRES);
- return OK;
-}
-
-
-int cc1101_checkpart(struct cc1101_dev_s * dev)
-{
- uint8_t partnum, version;
-
- if (cc1101_access(dev, CC1101_PARTNUM, &partnum, 1) < 0 ||
- cc1101_access(dev, CC1101_VERSION, &version, 1) < 0)
- return ERROR;
-
- if (partnum == CC1101_PARTNUM_VALUE && version == CC1101_VERSION_VALUE)
- return OK;
-
- return ERROR;
-}
-
-
-void cc1101_dumpregs(struct cc1101_dev_s * dev, uint8_t addr, uint8_t length)
-{
- uint8_t buf[0x30], i;
-
- cc1101_access(dev, addr, buf, length);
-
- printf("CC1101[%2x]: ", addr);
- for (i=0; i<length; i++) printf(" %2x,", buf[i]);
- printf("\n");
-}
-
-
-void cc1101_setpacketctrl(struct cc1101_dev_s * dev)
-{
- uint8_t values[3];
-
- values[0] = 0; /* Rx FIFO threshold = 32, Tx FIFO threshold = 33 */
- cc1101_access(dev, CC1101_FIFOTHR, values, -1);
-
- /* Packet length
- * Limit it to 61 bytes in total: pktlen, data[61], rssi, lqi
- */
-
- values[0] = CC1101_PACKET_MAXDATALEN;
- cc1101_access(dev, CC1101_PKTLEN, values, -1);
-
- /* Packet Control */
-
- values[0] = 0x04; /* Append status: RSSI and LQI at the end of received packet */
- /* TODO: CRC Auto Flash bit 0x08 ??? */
- values[1] = 0x05; /* CRC in Rx and Tx Enabled: Variable Packet mode, defined by first byte */
- /* TODO: Enable data whitening ... */
- cc1101_access(dev, CC1101_PKTCTRL1, values, -2);
-
- /* Main Radio Control State Machine */
-
- values[0] = 0x07; /* No time-out */
- values[1] = 0x00; /* Clear channel if RSSI < thr && !receiving;
- * TX -> RX, RX -> RX: 0x3F */
- values[2] = CC1101_MCSM0_VALUE; /* Calibrate on IDLE -> RX/TX, OSC Timeout = ~500 us
- TODO: has XOSC_FORCE_ON */
- cc1101_access(dev, CC1101_MCSM2, values, -3);
-
- /* Wake-On Radio Control */
-
- // Not used yet.
-
- // WOREVT1:WOREVT0 - 16-bit timeout register
-}
-
-
-/****************************************************************************
- * Callbacks
- ****************************************************************************/
-
-volatile int cc1101_interrupt = 0;
-
-/** External line triggers this callback
- *
- * The concept todo is:
- * - GPIO provides EXTI Interrupt
- * - It should handle EXTI Interrupts in ISR, to which chipcon can
- * register a callback (and others). The ISR then foreach() calls a
- * its callback, and it is up to peripheral to find, whether the cause
- * of EXTI ISR was itself.
- **/
-
-int cc1101_eventcb(int irq, FAR void *context)
-{
- cc1101_interrupt++;
- return OK;
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-struct cc1101_dev_s * cc1101_init(struct spi_dev_s * spi, uint8_t isrpin,
- uint32_t pinset, const struct c1101_rfsettings_s * rfsettings)
-{
- struct cc1101_dev_s * dev;
-
- ASSERT(spi);
-
- if ( (dev = kmalloc( sizeof(struct cc1101_dev_s) )) == NULL) {
- errno = ENOMEM;
- return NULL;
- }
-
- dev->rfsettings = rfsettings;
- dev->spi = spi;
- dev->isrpin = isrpin;
- dev->pinset = pinset;
- dev->flags = 0;
- dev->channel = rfsettings->CHMIN;
- dev->power = rfsettings->PAMAX;
-
- /* Reset chip, check status bytes */
-
- if ( cc1101_reset(dev) < 0 ) {
- kfree(dev);
- errno = EFAULT;
- return NULL;
- }
-
- /* Check part compatibility */
-
- if ( cc1101_checkpart(dev) < 0 ) {
- kfree(dev);
- errno = ENODEV;
- return NULL;
- }
-
- /* Configure CC1101:
- * - disable GDOx for best performance
- * - load RF
- * - and packet control
- */
-
- cc1101_setgdo(dev, CC1101_PIN_GDO0, CC1101_GDO_HIZ);
- cc1101_setgdo(dev, CC1101_PIN_GDO1, CC1101_GDO_HIZ);
- cc1101_setgdo(dev, CC1101_PIN_GDO2, CC1101_GDO_HIZ);
- cc1101_setrf(dev, rfsettings);
- cc1101_setpacketctrl(dev);
-
- /* Set the ISR to be triggerred on falling edge of the:
- *
- * 6 (0x06) Asserts when sync word has been sent / received, and
- * de-asserts at the end of the packet. In RX, the pin will de-assert
- * when the optional address check fails or the RX FIFO overflows.
- * In TX the pin will de-assert if the TX FIFO underflows.
- */
-
- cc1101_setgdo(dev, dev->isrpin, CC1101_GDO_SYNC);
-
- /* Bind to external interrupt line */
-
- // depends on STM32: TODO: Make that config within pinset and
- // provide general gpio interface
- //stm32_gpiosetevent(pinset, false, true, true, cc1101_eventcb);
-
- return dev;
-}
-
-
-int cc1101_deinit(struct cc1101_dev_s * dev)
-{
- ASSERT(dev);
-
- /* Release interrupt */
- //stm32_gpiosetevent(pinset, false, false, false, NULL);
-
- /* Power down chip */
- cc1101_powerdown(dev);
-
- /* Release external interrupt line */
- kfree(dev);
-
- return 0;
-}
-
-
-int cc1101_powerup(struct cc1101_dev_s * dev)
-{
- ASSERT(dev);
- return 0;
-}
-
-
-int cc1101_powerdown(struct cc1101_dev_s * dev)
-{
- ASSERT(dev);
- return 0;
-}
-
-
-int cc1101_setgdo(struct cc1101_dev_s * dev, uint8_t pin, uint8_t function)
-{
- ASSERT(dev);
- ASSERT(pin <= CC1101_IOCFG0);
-
- if (function >= CC1101_GDO_CLK_XOSC1) {
-
- /* Only one pin can be enabled at a time as XOSC/n */
-
- if (dev->flags & FLAGS_XOSCENABLED) return -EPERM;
-
- /* Force XOSC to stay active even in sleep mode */
-
- int value = CC1101_MCSM0_VALUE | CC1101_MCSM0_XOSC_FORCE_ON;
- cc1101_access(dev, CC1101_MCSM0, &value, -1);
-
- dev->flags |= FLAGS_XOSCENABLED;
- }
- else if (dev->flags & FLAGS_XOSCENABLED) {
-
- /* Disable XOSC in sleep mode */
-
- int value = CC1101_MCSM0_VALUE;
- cc1101_access(dev, CC1101_MCSM0, &value, -1);
-
- dev->flags &= ~FLAGS_XOSCENABLED;
- }
-
- return cc1101_access(dev, pin, &function, -1);
-}
-
-
-int cc1101_setrf(struct cc1101_dev_s * dev, const struct c1101_rfsettings_s *settings)
-{
- ASSERT(dev);
- ASSERT(settings);
-
- if (cc1101_access(dev, CC1101_FSCTRL1, &settings->FSCTRL1, -11) < 0) return ERROR;
- if (cc1101_access(dev, CC1101_FOCCFG, &settings->FOCCFG, -5) < 0) return ERROR;
- if (cc1101_access(dev, CC1101_FREND1, &settings->FREND1, -6) < 0) return ERROR;
-
- /* Load Power Table */
-
- if (cc1101_access(dev, CC1101_PATABLE, settings->PA, -8) < 0) return ERROR;
-
- /* If channel is out of valid range, mark that. Limit power.
- * We are not allowed to send any data, but are allowed to listen
- * and receive.
- */
-
- cc1101_setchannel(dev, dev->channel);
- cc1101_setpower(dev, dev->power);
-
- return OK;
-}
-
-
-int cc1101_setchannel(struct cc1101_dev_s * dev, uint8_t channel)
-{
- ASSERT(dev);
-
- /* Store localy in further checks */
-
- dev->channel = channel;
-
- /* If channel is out of valid, we are allowed to listen and receive only */
-
- if (channel < dev->rfsettings->CHMIN || channel > dev->rfsettings->CHMAX)
- dev->flags |= FLAGS_RXONLY;
- else dev->flags &= ~FLAGS_RXONLY;
-
- cc1101_access(dev, CC1101_CHANNR, &dev->channel, -1);
-
- return dev->flags & FLAGS_RXONLY;
-}
-
-
-uint8_t cc1101_setpower(struct cc1101_dev_s * dev, uint8_t power)
-{
- ASSERT(dev);
-
- if (power > dev->rfsettings->PAMAX)
- power = dev->rfsettings->PAMAX;
-
- dev->power = power;
-
- if (power == 0) {
- dev->flags |= FLAGS_RXONLY;
- return 0;
- }
- else dev->flags &= ~FLAGS_RXONLY;
-
- /* Add remaining part from RF table (to get rid of readback) */
-
- power--;
- power |= dev->rfsettings->FREND0;
-
- /* On error, report that as zero power */
-
- if (cc1101_access(dev, CC1101_FREND0, &power, -1) < 0)
- dev->power = 0;
-
- return dev->power;
-}
-
-
-int cc1101_calcRSSIdBm(int rssi)
-{
- if (rssi >= 128) rssi -= 256;
- return (rssi >> 1) - 74;
-}
-
-
-int cc1101_receive(struct cc1101_dev_s * dev)
-{
- ASSERT(dev);
-
- /* \todo Wait for IDLE before going into another state? */
-
- cc1101_interrupt = 0;
-
- cc1101_strobe(dev, CC1101_SRX | CC1101_READ_SINGLE);
-
- return 0;
-}
-
-
-int cc1101_read(struct cc1101_dev_s * dev, uint8_t * buf, size_t size)
-{
- ASSERT(dev);
-
- if (buf==NULL) {
- if (size==0) return 64;
- // else received packet size
- return 0;
- }
-
- if (cc1101_interrupt == 0) return 0;
-
- int status = cc1101_strobe(dev, CC1101_SNOP | CC1101_READ_SINGLE);
-
- if (status & CC1101_STATUS_FIFO_BYTES_AVAILABLE_BM &&
- (status & CC1101_STATE_MASK) == CC1101_STATE_IDLE) {
-
- uint8_t nbytes;
-
- cc1101_access(dev, CC1101_RXFIFO, &nbytes, 1);
-
- nbytes += 2; /* RSSI and LQI */
-
- cc1101_access(dev, CC1101_RXFIFO, buf, (nbytes > size) ? size : nbytes);
-
- /* Flush remaining bytes, if there is no room to receive
- * or if there is a BAD CRC
- */
-
- if (nbytes > size || (nbytes <= size && !(buf[nbytes-1]&0x80)) ) {
- printf("Flushing RX FIFO\n");
- cc1101_strobe(dev, CC1101_SFRX);
- }
-
- return nbytes;
- }
-
- return 0;
-}
-
-
-int cc1101_write(struct cc1101_dev_s * dev, const uint8_t * buf, size_t size)
-{
- uint8_t packetlen;
-
- ASSERT(dev);
- ASSERT(buf);
-
- if (dev->flags & FLAGS_RXONLY) return -EPERM;
-
- /* Present limit */
- if (size > CC1101_PACKET_MAXDATALEN)
- packetlen = CC1101_PACKET_MAXDATALEN;
- else packetlen = size;
-
- cc1101_access(dev, CC1101_TXFIFO, &packetlen, -1);
- cc1101_access(dev, CC1101_TXFIFO, buf, -size);
-
- return 0;
-}
-
-
-int cc1101_send(struct cc1101_dev_s * dev)
-{
- ASSERT(dev);
-
- if (dev->flags & FLAGS_RXONLY) return -EPERM;
-
- cc1101_interrupt = 0;
-
- cc1101_strobe(dev, CC1101_STX);
-
- /* wait until send, going to IDLE */
-
- while( cc1101_interrupt == 0 );
-
- return 0;
-}
-
-
-int cc1101_idle(struct cc1101_dev_s * dev)
-{
- ASSERT(dev);
- cc1101_strobe(dev, CC1101_SIDLE);
- return 0;
-}