summaryrefslogtreecommitdiff
path: root/components/drivers
diff options
context:
space:
mode:
authoryangjie11 <[email protected]>2020-11-18 09:56:35 +0800
committerGitHub <[email protected]>2020-11-18 09:56:35 +0800
commitd4a682e8d97fa131e5a8d795f8c5451d55cdd5b0 (patch)
tree4773b40cb012475c5daf74bfd55707e141477669 /components/drivers
parent2b98f4720c827ae1850df78299f6b273d568c8c7 (diff)
parent2ef3c9d861f55253620996a94831a4be31ca6620 (diff)
Merge pull request #3 from RT-Thread/master
sync
Diffstat (limited to 'components/drivers')
-rwxr-xr-xcomponents/drivers/Kconfig487
-rw-r--r--components/drivers/audio/audio.c641
-rw-r--r--components/drivers/audio/audio_pipe.c44
-rw-r--r--components/drivers/can/can.c167
-rw-r--r--components/drivers/hwcrypto/SConscript34
-rw-r--r--components/drivers/hwcrypto/hw_bignum.c315
-rw-r--r--components/drivers/hwcrypto/hw_bignum.h186
-rw-r--r--components/drivers/hwcrypto/hw_crc.c117
-rw-r--r--components/drivers/hwcrypto/hw_crc.h148
-rw-r--r--components/drivers/hwcrypto/hw_gcm.c218
-rw-r--r--components/drivers/hwcrypto/hw_gcm.h182
-rw-r--r--components/drivers/hwcrypto/hw_hash.c111
-rw-r--r--components/drivers/hwcrypto/hw_hash.h110
-rw-r--r--components/drivers/hwcrypto/hw_rng.c110
-rw-r--r--components/drivers/hwcrypto/hw_rng.h79
-rw-r--r--components/drivers/hwcrypto/hw_symmetric.c276
-rw-r--r--components/drivers/hwcrypto/hw_symmetric.h189
-rw-r--r--components/drivers/hwcrypto/hwcrypto.c255
-rw-r--r--components/drivers/hwcrypto/hwcrypto.h193
-rw-r--r--components/drivers/hwtimer/README_CN.md49
-rw-r--r--components/drivers/hwtimer/hwtimer.c3
-rw-r--r--components/drivers/i2c/fm24clxx.c160
-rw-r--r--components/drivers/i2c/fm24clxx.h26
-rw-r--r--components/drivers/i2c/i2c-bit-ops.c76
-rw-r--r--components/drivers/i2c/i2c_core.c25
-rw-r--r--components/drivers/i2c/i2c_dev.c16
-rw-r--r--components/drivers/include/drivers/alarm.h7
-rw-r--r--components/drivers/include/drivers/audio.h144
-rw-r--r--components/drivers/include/drivers/can.h6
-rw-r--r--components/drivers/include/drivers/crypto.h23
-rw-r--r--components/drivers/include/drivers/dac.h42
-rw-r--r--components/drivers/include/drivers/i2c.h11
-rw-r--r--components/drivers/include/drivers/mtd.h105
-rw-r--r--components/drivers/include/drivers/mtd_nand.h88
-rw-r--r--components/drivers/include/drivers/mtdnand.h101
-rw-r--r--components/drivers/include/drivers/mtdnor.h35
-rw-r--r--components/drivers/include/drivers/phy.h87
-rw-r--r--components/drivers/include/drivers/phy_mdio.h43
-rw-r--r--components/drivers/include/drivers/pin.h3
-rw-r--r--components/drivers/include/drivers/pm.h169
-rw-r--r--components/drivers/include/drivers/pulse_encoder.h58
-rw-r--r--components/drivers/include/drivers/rt_inputcapture.h60
-rw-r--r--components/drivers/include/drivers/spi.h26
-rw-r--r--components/drivers/include/drivers/usb_common.h16
-rw-r--r--components/drivers/include/ipc/dataqueue.h14
-rw-r--r--components/drivers/include/ipc/pipe.h1
-rw-r--r--components/drivers/include/ipc/workqueue.h56
-rw-r--r--components/drivers/include/rtdevice.h21
-rw-r--r--components/drivers/misc/SConscript9
-rw-r--r--components/drivers/misc/adc.c36
-rw-r--r--components/drivers/misc/dac.c231
-rw-r--r--components/drivers/misc/pin.c15
-rw-r--r--components/drivers/misc/pulse_encoder.c136
-rw-r--r--components/drivers/misc/rt_drv_pwm.c2
-rw-r--r--components/drivers/misc/rt_inputcapture.c195
-rw-r--r--components/drivers/mtd/SConscript15
-rw-r--r--components/drivers/mtd/mtd.c236
-rw-r--r--components/drivers/mtd/mtd_nand.c370
-rw-r--r--components/drivers/mtd/mtdnand.c645
-rw-r--r--components/drivers/mtd/mtdnor.c74
-rw-r--r--components/drivers/phy/SConscript8
-rw-r--r--components/drivers/phy/phy.c78
-rw-r--r--components/drivers/pm/pm.c440
-rw-r--r--components/drivers/rtc/alarm.c150
-rw-r--r--components/drivers/rtc/rtc.c4
-rw-r--r--components/drivers/sdio/block_dev.c19
-rw-r--r--components/drivers/sdio/mmc.c44
-rw-r--r--components/drivers/sdio/mmcsd_core.c20
-rw-r--r--components/drivers/sdio/sd.c46
-rw-r--r--components/drivers/sdio/sdio.c18
-rw-r--r--components/drivers/sensors/SConscript9
-rw-r--r--components/drivers/sensors/bmi055_sensor.cpp451
-rw-r--r--components/drivers/sensors/bmi055_sensor.h334
-rw-r--r--components/drivers/sensors/mpu6050_sensor.cpp458
-rw-r--r--components/drivers/sensors/mpu6050_sensor.h189
-rw-r--r--components/drivers/sensors/sensor.c455
-rw-r--r--components/drivers/sensors/sensor.cpp228
-rwxr-xr-x[-rw-r--r--]components/drivers/sensors/sensor.h1230
-rwxr-xr-xcomponents/drivers/sensors/sensor_cmd.c498
-rw-r--r--components/drivers/serial/serial.c84
-rw-r--r--components/drivers/spi/SConscript15
-rw-r--r--components/drivers/spi/device_driver_list.txt10
-rw-r--r--components/drivers/spi/sfud/inc/sfud_cfg.h14
-rw-r--r--components/drivers/spi/sfud/inc/sfud_flash_def.h14
-rw-r--r--components/drivers/spi/sfud/src/sfud.c7
-rw-r--r--components/drivers/spi/spi_flash_at45dbxx.c433
-rw-r--r--components/drivers/spi/spi_flash_at45dbxx.h27
-rw-r--r--components/drivers/spi/spi_flash_gd.c347
-rw-r--r--components/drivers/spi/spi_flash_gd.h18
-rw-r--r--components/drivers/spi/spi_flash_sfud.c313
-rw-r--r--components/drivers/spi/spi_flash_sfud.h24
-rw-r--r--components/drivers/spi/spi_flash_sst25vfxx.c358
-rw-r--r--components/drivers/spi/spi_flash_sst25vfxx.h28
-rw-r--r--components/drivers/spi/spi_flash_w25qxx.c393
-rw-r--r--components/drivers/spi/spi_flash_w25qxx.h20
-rw-r--r--components/drivers/spi/spi_flash_w25qxx_mtd.c336
-rw-r--r--components/drivers/spi/spi_flash_w25qxx_mtd.h20
-rw-r--r--components/drivers/spi/spi_msd.c10
-rw-r--r--components/drivers/src/dataqueue.c131
-rw-r--r--components/drivers/src/pipe.c37
-rw-r--r--components/drivers/src/ringblk_buf.c48
-rw-r--r--components/drivers/src/ringbuffer.c5
-rw-r--r--components/drivers/src/workqueue.c280
-rw-r--r--components/drivers/touch/SConscript11
-rw-r--r--components/drivers/touch/touch.c258
-rw-r--r--components/drivers/touch/touch.h110
-rw-r--r--components/drivers/usb/usbdevice/SConscript8
-rw-r--r--components/drivers/usb/usbdevice/class/audio.h676
-rw-r--r--components/drivers/usb/usbdevice/class/audio_mic.c577
-rw-r--r--components/drivers/usb/usbdevice/class/audio_speaker.c578
-rw-r--r--components/drivers/usb/usbdevice/class/cdc_vcom.c107
-rw-r--r--components/drivers/usb/usbdevice/class/ecm.c53
-rw-r--r--components/drivers/usb/usbdevice/class/hid.c21
-rw-r--r--components/drivers/usb/usbdevice/class/mstorage.c41
-rw-r--r--components/drivers/usb/usbdevice/class/rndis.c236
-rw-r--r--components/drivers/usb/usbdevice/class/rndis.h9
-rw-r--r--components/drivers/usb/usbdevice/class/winusb.c2
-rw-r--r--components/drivers/usb/usbdevice/core/usbdevice_core.c (renamed from components/drivers/usb/usbdevice/core/core.c)86
-rw-r--r--components/drivers/usb/usbhost/SConscript2
-rw-r--r--components/drivers/usb/usbhost/class/adk.h4
-rw-r--r--components/drivers/usb/usbhost/class/udisk.c2
-rw-r--r--components/drivers/usb/usbhost/core/hub.c16
-rw-r--r--components/drivers/usb/usbhost/core/usbhost_core.c (renamed from components/drivers/usb/usbhost/core/core.c)8
-rw-r--r--components/drivers/watchdog/watchdog.c2
-rw-r--r--components/drivers/wlan/SConscript24
-rw-r--r--components/drivers/wlan/wlan_cfg.c19
-rw-r--r--components/drivers/wlan/wlan_cmd.c37
-rw-r--r--components/drivers/wlan/wlan_dev.c209
-rw-r--r--components/drivers/wlan/wlan_dev.h17
-rw-r--r--components/drivers/wlan/wlan_lwip.c152
-rw-r--r--components/drivers/wlan/wlan_mgnt.c390
-rw-r--r--components/drivers/wlan/wlan_mgnt.h10
-rw-r--r--components/drivers/wlan/wlan_prot.c30
-rw-r--r--components/drivers/wlan/wlan_prot.h2
-rw-r--r--components/drivers/wlan/wlan_workqueue.c10
135 files changed, 10570 insertions, 8085 deletions
diff --git a/components/drivers/Kconfig b/components/drivers/Kconfig
index d8dc5e7458..db4455160e 100755
--- a/components/drivers/Kconfig
+++ b/components/drivers/Kconfig
@@ -8,6 +8,20 @@ if RT_USING_DEVICE_IPC
config RT_PIPE_BUFSZ
int "Set pipe buffer size"
default 512
+
+ config RT_USING_SYSTEM_WORKQUEUE
+ bool "Using system default workqueue"
+ default n
+
+ if RT_USING_SYSTEM_WORKQUEUE
+ config RT_SYSTEM_WORKQUEUE_STACKSIZE
+ int "The stack size for system workqueue thread"
+ default 2048
+
+ config RT_SYSTEM_WORKQUEUE_PRIORITY
+ int "The priority level of system workqueue thread"
+ default 23
+ endif
endif
config RT_USING_SERIAL
@@ -20,7 +34,12 @@ if RT_USING_SERIAL
config RT_SERIAL_USING_DMA
bool "Enable serial DMA mode"
default y
-endif
+
+ config RT_SERIAL_RB_BUFSZ
+ int "Set RX buffer size"
+ default 64
+
+endif
config RT_USING_CAN
bool "Using CAN device drivers"
@@ -29,7 +48,7 @@ config RT_USING_CAN
if RT_USING_CAN
config RT_CAN_USING_HDR
bool "Enable CAN hardware filter"
- default y
+ default n
endif
config RT_USING_HWTIMER
@@ -69,11 +88,25 @@ config RT_USING_I2C
default n
if RT_USING_I2C
+ config RT_I2C_DEBUG
+ bool "Use I2C debug message"
+ default n
+
config RT_USING_I2C_BITOPS
bool "Use GPIO to simulate I2C"
default y
+
+ if RT_USING_I2C_BITOPS
+ config RT_I2C_BITOPS_DEBUG
+ bool "Use simulate I2C debug message"
+ default n
+ endif
endif
+config RT_USING_PHY
+ bool "Using ethernet phy device drivers"
+ default n
+
config RT_USING_PIN
bool "Using generic GPIO device drivers"
default y
@@ -82,6 +115,10 @@ config RT_USING_ADC
bool "Using ADC device drivers"
default n
+config RT_USING_DAC
+ bool "Using DAC device drivers"
+ default n
+
config RT_USING_PWM
bool "Using PWM device drivers"
default n
@@ -100,20 +137,6 @@ config RT_USING_MTD_NAND
default n
endif
-config RT_USING_MTD
- bool "Using Memory Technology Device (MTD)"
- default n
-
- if RT_USING_MTD
- config MTD_USING_NOR
- bool "Using MTD Nor Flash device"
- default n
-
- config MTD_USING_NAND
- bool "Using MTD Nand Flash device"
- default n
- endif
-
config RT_USING_PM
bool "Using Power Management device drivers"
default n
@@ -123,22 +146,27 @@ config RT_USING_RTC
default n
if RT_USING_RTC
- config RT_USING_SOFT_RTC
- bool "Using software simulation RTC device"
- default n
- config RTC_SYNC_USING_NTP
- bool "Using NTP auto sync RTC time"
- depends on PKG_NETUTILS_NTP
- default y
+ config RT_USING_ALARM
+ bool "Using RTC alarm"
+ default n
+
+ config RT_USING_SOFT_RTC
+ bool "Using software simulation RTC device"
+ default n
+
+ config RTC_SYNC_USING_NTP
+ bool "Using NTP auto sync RTC time"
+ depends on PKG_NETUTILS_NTP
+ default y
- if RTC_SYNC_USING_NTP
- config RTC_NTP_FIRST_SYNC_DELAY
- int "NTP first sync delay time(second) for network connect"
- default 30
- config RTC_NTP_SYNC_PERIOD
- int "NTP auto sync period(second)"
- default 3600
- endif
+ if RTC_SYNC_USING_NTP
+ config RTC_NTP_FIRST_SYNC_DELAY
+ int "NTP first sync delay time(second) for network connect"
+ default 30
+ config RTC_NTP_SYNC_PERIOD
+ int "NTP auto sync period(second)"
+ default 3600
+ endif
endif
config RT_USING_SDIO
@@ -187,6 +215,9 @@ config RT_USING_SPI
config RT_USING_SFUD
bool "Using Serial Flash Universal Driver"
default n
+ help
+ An using JEDEC's SFDP standard serial (SPI) flash universal driver library
+
if RT_USING_SFUD
config RT_SFUD_USING_SFDP
bool "Using auto probe flash JEDEC SFDP parameter"
@@ -201,19 +232,18 @@ config RT_USING_SPI
select RT_USING_QSPI
default n
+ config RT_SFUD_SPI_MAX_HZ
+ int "Default spi maximum speed(HZ)"
+ range 0 50000000
+ default 50000000
+ help
+ Read the JEDEC SFDP command must run at 50 MHz or less,and you also can use rt_spi_configure(); to config spi speed.
+
config RT_DEBUG_SFUD
bool "Show more SFUD debug information"
default n
endif
- config RT_USING_W25QXX
- bool "Using W25QXX SPI NorFlash"
- default n
-
- config RT_USING_GD
- bool "Using GD SPI NorFlash"
- default n
-
config RT_USING_ENC28J60
bool "Using ENC28J60 SPI Ethernet network interface"
select RT_USING_LWIP
@@ -232,68 +262,335 @@ config RT_USING_WDT
config RT_USING_AUDIO
bool "Using Audio device drivers"
default n
+
+ if RT_USING_AUDIO
+ config RT_AUDIO_REPLAY_MP_BLOCK_SIZE
+ int "Replay memory pool block size"
+ default 4096
+
+ config RT_AUDIO_REPLAY_MP_BLOCK_COUNT
+ int "Replay memory pool block count"
+ default 2
+
+ config RT_AUDIO_RECORD_PIPE_SIZE
+ int "Record pipe size"
+ default 2048
+ endif
+
+config RT_USING_SENSOR
+ bool "Using Sensor device drivers"
+ select RT_USING_PIN
+ default n
+
+if RT_USING_SENSOR
+ config RT_USING_SENSOR_CMD
+ bool "Using Sensor cmd"
+ default y
+endif
+
+config RT_USING_TOUCH
+ bool "Using Touch device drivers"
+ default n
+
+menuconfig RT_USING_HWCRYPTO
+ bool "Using Hardware Crypto drivers"
+ default n
+
+ if RT_USING_HWCRYPTO
+ config RT_HWCRYPTO_DEFAULT_NAME
+ string "Hardware crypto device name"
+ default "hwcryto"
+
+ config RT_HWCRYPTO_IV_MAX_SIZE
+ int "IV max size"
+ default "16"
+
+ config RT_HWCRYPTO_KEYBIT_MAX_SIZE
+ int "Key max bit length"
+ default 256
+
+ config RT_HWCRYPTO_USING_GCM
+ bool "Using Hardware GCM"
+ default n
+
+ config RT_HWCRYPTO_USING_AES
+ bool "Using Hardware AES"
+ default n
+
+ if RT_HWCRYPTO_USING_AES
+ config RT_HWCRYPTO_USING_AES_ECB
+ bool "Using Hardware AES ECB mode"
+ default y
+
+ config RT_HWCRYPTO_USING_AES_CBC
+ bool "Using Hardware AES CBC mode"
+ default n
+
+ config RT_HWCRYPTO_USING_AES_CFB
+ bool "Using Hardware AES CFB mode"
+ default n
+
+ config RT_HWCRYPTO_USING_AES_CTR
+ bool "Using Hardware AES CTR mode"
+ default n
+
+ config RT_HWCRYPTO_USING_AES_OFB
+ bool "Using Hardware AES OFB mode"
+ default n
+ endif
+
+ config RT_HWCRYPTO_USING_DES
+ bool "Using Hardware DES"
+ default n
+
+ if RT_HWCRYPTO_USING_DES
+ config RT_HWCRYPTO_USING_DES_ECB
+ bool "Using Hardware DES ECB mode"
+ default y
+
+ config RT_HWCRYPTO_USING_DES_CBC
+ bool "Using Hardware DES CBC mode"
+ default n
+ endif
+
+ config RT_HWCRYPTO_USING_3DES
+ bool "Using Hardware 3DES"
+ default n
+
+ if RT_HWCRYPTO_USING_3DES
+ config RT_HWCRYPTO_USING_3DES_ECB
+ bool "Using Hardware 3DES ECB mode"
+ default y
+
+ config RT_HWCRYPTO_USING_3DES_CBC
+ bool "Using Hardware 3DES CBC mode"
+ default n
+ endif
+
+ config RT_HWCRYPTO_USING_RC4
+ bool "Using Hardware RC4"
+ default n
+
+ config RT_HWCRYPTO_USING_MD5
+ bool "Using Hardware MD5"
+ default n
+
+ config RT_HWCRYPTO_USING_SHA1
+ bool "Using Hardware SHA1"
+ default n
+
+ config RT_HWCRYPTO_USING_SHA2
+ bool "Using Hardware SHA2"
+ default n
+
+ if RT_HWCRYPTO_USING_SHA2
+ config RT_HWCRYPTO_USING_SHA2_224
+ bool "Using Hardware SHA2_224 mode"
+ default n
+
+ config RT_HWCRYPTO_USING_SHA2_256
+ bool "Using Hardware SHA2_256 mode"
+ default y
+
+ config RT_HWCRYPTO_USING_SHA2_384
+ bool "Using Hardware SHA2_384 mode"
+ default n
+
+ config RT_HWCRYPTO_USING_SHA2_512
+ bool "Using Hardware SHA2_512 mode"
+ default n
+ endif
+
+ config RT_HWCRYPTO_USING_RNG
+ bool "Using Hardware RNG"
+ default n
+
+ config RT_HWCRYPTO_USING_CRC
+ bool "Using Hardware CRC"
+ default n
+
+ if RT_HWCRYPTO_USING_CRC
+ config RT_HWCRYPTO_USING_CRC_07
+ bool "Using Hardware CRC-8 0x07 polynomial"
+ default n
+
+ config RT_HWCRYPTO_USING_CRC_8005
+ bool "Using Hardware CRC-16 0x8005 polynomial"
+ default n
+
+ config RT_HWCRYPTO_USING_CRC_1021
+ bool "Using Hardware CRC-16 0x1021 polynomial"
+ default n
+
+ config RT_HWCRYPTO_USING_CRC_3D65
+ bool "Using Hardware CRC-16 0x3D65 polynomial"
+ default n
+
+ config RT_HWCRYPTO_USING_CRC_04C11DB7
+ bool "Using Hardware CRC-32 0x04C11DB7 polynomial"
+ default n
+ endif
+
+ config RT_HWCRYPTO_USING_BIGNUM
+ bool "Using Hardware bignum"
+ default n
+
+ if RT_HWCRYPTO_USING_BIGNUM
+ config RT_HWCRYPTO_USING_BIGNUM_EXPTMOD
+ bool "Using Hardware bignum expt_mod operation"
+ default y
+
+ config RT_HWCRYPTO_USING_BIGNUM_MULMOD
+ bool "Using Hardware bignum mul_mod operation"
+ default y
+
+ config RT_HWCRYPTO_USING_BIGNUM_MUL
+ bool "Using Hardware bignum mul operation"
+ default n
+
+ config RT_HWCRYPTO_USING_BIGNUM_ADD
+ bool "Using Hardware bignum add operation"
+ default n
+
+ config RT_HWCRYPTO_USING_BIGNUM_SUB
+ bool "Using Hardware bignum sub operation"
+ default n
+ endif
+ endif
+
+config RT_USING_PULSE_ENCODER
+ bool "Using PULSE ENCODER device drivers"
+ default n
-menu "Using WiFi"
- config RT_USING_WIFI
+config RT_USING_INPUT_CAPTURE
+ bool "Using INPUT CAPTURE device drivers"
+ default n
+
+if RT_USING_INPUT_CAPTURE
+ config RT_INPUT_CAPTURE_RB_SIZE
+ int "Set input capture ringbuffer size"
+ default 100
+endif
+
+menuconfig RT_USING_WIFI
bool "Using Wi-Fi framework"
default n
if RT_USING_WIFI
config RT_WLAN_DEVICE_STA_NAME
- string "The WiFi device name for station"
+ string "The device name for station"
default "wlan0"
config RT_WLAN_DEVICE_AP_NAME
- string "The WiFi device name for ap"
+ string "The device name for ap"
default "wlan1"
- config RT_WLAN_DEFAULT_PROT
- string "Default transport protocol"
- default "lwip"
-
- config RT_WLAN_SCAN_WAIT_MS
- int "Set scan timeout time(ms)"
- default 10000
-
- config RT_WLAN_CONNECT_WAIT_MS
- int "Set connect timeout time(ms)"
- default 10000
-
config RT_WLAN_SSID_MAX_LENGTH
- int "SSID name maximum length"
+ int "SSID maximum length"
default 32
config RT_WLAN_PASSWORD_MAX_LENGTH
- int "Maximum password length"
+ int "Password maximum length"
default 32
- config RT_WLAN_SCAN_SORT
- bool "Automatic sorting of scan results"
+ config RT_WLAN_DEV_EVENT_NUM
+ int "Driver events maxcount"
+ default 2
+
+ config RT_WLAN_MANAGE_ENABLE
+ bool "Connection management Enable"
default y
- config RT_WLAN_CFG_INFO_MAX
- int "Maximum number of WiFi information automatically saved"
- default 3
+ if RT_WLAN_MANAGE_ENABLE
+ config RT_WLAN_SCAN_WAIT_MS
+ int "Set scan timeout time(ms)"
+ default 10000
- config RT_WLAN_WORKQUEUE_THREAD_NAME
- string "WiFi work queue thread name"
- default "wlan_job"
+ config RT_WLAN_CONNECT_WAIT_MS
+ int "Set connect timeout time(ms)"
+ default 10000
- config RT_WLAN_WORKQUEUE_THREAD_SIZE
- int "wifi work queue thread size"
- default 2048
+ config RT_WLAN_SCAN_SORT
+ bool "Automatic sorting of scan results"
+ default y
- config RT_WLAN_WORKQUEUE_THREAD_PRIO
- int "WiFi work queue thread priority"
- default 22
+ config RT_WLAN_MSH_CMD_ENABLE
+ bool "MSH command Enable"
+ default y
- config RT_WLAN_DEV_EVENT_NUM
- int "Maximum number of driver events"
- default 2
+ config RT_WLAN_AUTO_CONNECT_ENABLE
+ bool "Auto connect Enable"
+ select RT_WLAN_CFG_ENABLE
+ select RT_WLAN_WORK_THREAD_ENABLE
+ default y
- config RT_WLAN_PROT_LWIP_PBUF_FORCE
- bool "Forced use of PBUF transmission"
- default n
+ if RT_WLAN_AUTO_CONNECT_ENABLE
+ config AUTO_CONNECTION_PERIOD_MS
+ int "Auto connect period(ms)"
+ default 2000
+ endif
+ endif
+
+ config RT_WLAN_CFG_ENABLE
+ bool "WiFi information automatically saved Enable"
+ default y
+
+ if RT_WLAN_CFG_ENABLE
+ config RT_WLAN_CFG_INFO_MAX
+ int "Maximum number of WiFi information automatically saved"
+ default 3
+ endif
+
+ config RT_WLAN_PROT_ENABLE
+ bool "Transport protocol manage Enable"
+ default y
+
+ if RT_WLAN_PROT_ENABLE
+ config RT_WLAN_PROT_NAME_LEN
+ int "Transport protocol name length"
+ default 8
+
+ config RT_WLAN_PROT_MAX
+ int "Transport protocol maxcount"
+ default 2
+
+ config RT_WLAN_DEFAULT_PROT
+ string "Default transport protocol"
+ default "lwip"
+
+ config RT_WLAN_PROT_LWIP_ENABLE
+ bool "LWIP transport protocol Enable"
+ select RT_USING_LWIP
+ default y
+
+ if RT_WLAN_PROT_LWIP_ENABLE
+ config RT_WLAN_PROT_LWIP_NAME
+ string "LWIP transport protocol name"
+ default "lwip"
+
+ config RT_WLAN_PROT_LWIP_PBUF_FORCE
+ bool "Forced use of PBUF transmission"
+ default n
+ endif
+ endif
+
+ config RT_WLAN_WORK_THREAD_ENABLE
+ bool "WLAN work queue thread Enable"
+ default y
+
+ if RT_WLAN_WORK_THREAD_ENABLE
+ config RT_WLAN_WORKQUEUE_THREAD_NAME
+ string "WLAN work queue thread name"
+ default "wlan"
+
+ config RT_WLAN_WORKQUEUE_THREAD_SIZE
+ int "WLAN work queue thread size"
+ default 2048
+
+ config RT_WLAN_WORKQUEUE_THREAD_PRIO
+ int "WLAN work queue thread priority"
+ default 15
+ endif
menuconfig RT_WLAN_DEBUG
bool "Enable WLAN Debugging Options"
@@ -325,7 +622,6 @@ menu "Using WiFi"
default n
endif
endif
-endmenu
menu "Using USB"
config RT_USING_USB_HOST
@@ -388,6 +684,9 @@ menu "Using USB"
config _RT_USB_DEVICE_WINUSB
bool "Enable to use device as winusb device"
select RT_USB_DEVICE_WINUSB
+ config _RT_USB_DEVICE_AUDIO
+ bool "Enable to use device as audio device"
+ select RT_USB_DEVICE_AUDIO
endchoice
if RT_USB_DEVICE_COMPOSITE
config RT_USB_DEVICE_CDC
@@ -413,11 +712,17 @@ menu "Using USB"
config RT_USB_DEVICE_WINUSB
bool "Enable to use device as winusb device"
default n
+ config RT_USB_DEVICE_AUDIO
+ bool "Enable to use device as audio device"
+ default n
endif
if RT_USB_DEVICE_CDC
config RT_VCOM_TASK_STK_SIZE
int "virtual com thread stack size"
default 512
+ config RT_CDC_RX_BUFSIZE
+ int "virtual com rx buffer size"
+ default 128
config RT_VCOM_TX_USE_DMA
bool "Enable to use dma for vcom tx"
default n
@@ -441,6 +746,14 @@ menu "Using USB"
string "msc class disk name"
default "flash0"
endif
+
+ if RT_USB_DEVICE_RNDIS
+ config RNDIS_DELAY_LINK_UP
+ bool "Delay linkup media connection"
+ select RT_USING_TIMER_SOFT
+ default n
+ endif
+
if RT_USB_DEVICE_HID
config RT_USB_DEVICE_HID_KEYBOARD
bool "Use to HID device as Keyboard"
@@ -472,6 +785,24 @@ menu "Using USB"
bool "Use to HID device as media keyboard"
default y
endif
+ if RT_USB_DEVICE_AUDIO
+ config RT_USB_DEVICE_AUDIO_MIC
+ bool "Use usb mic device as audio device"
+ default n
+ if RT_USB_DEVICE_AUDIO_MIC
+ config RT_USBD_MIC_DEVICE_NAME
+ string "audio mic device name"
+ default "mic0"
+ endif
+ config RT_USB_DEVICE_AUDIO_SPEAKER
+ bool "Use usb speaker device as audio device"
+ default n
+ if RT_USB_DEVICE_AUDIO_SPEAKER
+ config RT_USBD_SPEAKER_DEVICE_NAME
+ string "audio speaker device name"
+ default "sound0"
+ endif
+ endif
endif
endmenu
endmenu
diff --git a/components/drivers/audio/audio.c b/components/drivers/audio/audio.c
index 6a5ebc8741..4cec8a4a9c 100644
--- a/components/drivers/audio/audio.c
+++ b/components/drivers/audio/audio.c
@@ -5,83 +5,208 @@
*
* Change Logs:
* Date Author Notes
- * 2017-05-09 Urey first version
+ * 2017-05-09 Urey first version
+ * 2019-07-09 Zero-Free improve device ops interface and data flows
*/
#include <stdio.h>
+#include <string.h>
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
-#include <drivers/audio.h>
+#define DBG_TAG "audio"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
-#include "audio_pipe.h"
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
-
-#define AUDIO_DEBUG 0
-#if AUDIO_DEBUG
-#define AUDIO_DBG(...) printf("[AUDIO]:"),printf(__VA_ARGS__)
-#else
-#define AUDIO_DBG(...)
-#endif
-
-static struct rt_audio_pipe audio_pipe;
+enum
+{
+ REPLAY_EVT_NONE = 0x00,
+ REPLAY_EVT_START = 0x01,
+ REPLAY_EVT_STOP = 0x02,
+};
static rt_err_t _audio_send_replay_frame(struct rt_audio_device *audio)
{
rt_err_t result = RT_EOK;
- rt_base_t level;
- struct rt_audio_frame frame;
+ rt_uint8_t *data;
+ rt_size_t dst_size, src_size;
+ rt_uint16_t position, remain_bytes = 0, index = 0;
+ struct rt_audio_buf_info *buf_info;
RT_ASSERT(audio != RT_NULL);
- //check repaly queue is empty
- if (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) != RT_EOK)
+ buf_info = &audio->replay->buf_info;
+ /* save current pos */
+ position = audio->replay->pos;
+ dst_size = buf_info->block_size;
+
+ /* check repaly queue is empty */
+ if (rt_data_queue_peak(&audio->replay->queue, (const void **)&data, &src_size) != RT_EOK)
{
- AUDIO_DBG("TX queue is empty\n");
- result = -RT_EEMPTY;
+ /* ack stop event */
+ if (audio->replay->event & REPLAY_EVT_STOP)
+ rt_completion_done(&audio->replay->cmp);
- level = rt_hw_interrupt_disable();
- audio->replay->activated = RT_FALSE;
- rt_hw_interrupt_enable(level);
+ /* send zero frames */
+ memset(&buf_info->buffer[audio->replay->pos], 0, dst_size);
- goto _exit;
+ audio->replay->pos += dst_size;
+ audio->replay->pos %= buf_info->total_size;
}
-
- if (audio->ops->transmit != RT_NULL)
+ else
{
- AUDIO_DBG("audio transmit...\n");
- if (audio->ops->transmit(audio, frame.data_ptr, RT_NULL, frame.data_size) != frame.data_size)
+ memset(&buf_info->buffer[audio->replay->pos], 0, dst_size);
+
+ /* copy data from memory pool to hardware device fifo */
+ while (index < dst_size)
{
- result = -RT_EBUSY;
+ result = rt_data_queue_peak(&audio->replay->queue, (const void **)&data, &src_size);
+ if (result != RT_EOK)
+ {
+ LOG_D("under run %d, remain %d", audio->replay->pos, remain_bytes);
+ audio->replay->pos -= remain_bytes;
+ audio->replay->pos += dst_size;
+ audio->replay->pos %= buf_info->total_size;
+ audio->replay->read_index = 0;
+ result = -RT_EEMPTY;
+ break;
+ }
+
+ remain_bytes = MIN((dst_size - index), (src_size - audio->replay->read_index));
+ memcpy(&buf_info->buffer[audio->replay->pos],
+ &data[audio->replay->read_index], remain_bytes);
+
+ index += remain_bytes;
+ audio->replay->read_index += remain_bytes;
+ audio->replay->pos += remain_bytes;
+ audio->replay->pos %= buf_info->total_size;
+
+ if (audio->replay->read_index == src_size)
+ {
+ /* free memory */
+ audio->replay->read_index = 0;
+ rt_data_queue_pop(&audio->replay->queue, (const void **)&data, &src_size, RT_WAITING_NO);
+ rt_mp_free(data);
- goto _exit;
+ /* notify transmitted complete. */
+ if (audio->parent.tx_complete != RT_NULL)
+ audio->parent.tx_complete(&audio->parent, (void *)data);
+ }
}
}
- //pop the head frame...
- rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER);
+ if (audio->ops->transmit != RT_NULL)
+ {
+ if (audio->ops->transmit(audio, &buf_info->buffer[position], RT_NULL, dst_size) != dst_size)
+ result = -RT_ERROR;
+ }
- _exit: return result;
+ return result;
}
static rt_err_t _audio_flush_replay_frame(struct rt_audio_device *audio)
{
- struct rt_audio_frame frame;
+ rt_err_t result = RT_EOK;
- if (audio->replay == RT_NULL)
- return -RT_EIO;
- while (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) == RT_EOK)
+ if (audio->replay->write_index)
{
- //pop the head frame...
- rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER);
+ result = rt_data_queue_push(&audio->replay->queue,
+ (const void **)audio->replay->write_data,
+ audio->replay->write_index,
+ RT_WAITING_FOREVER);
- /* notify transmitted complete. */
- if (audio->parent.tx_complete != RT_NULL)
- audio->parent.tx_complete(&audio->parent, (void *) frame.data_ptr);
+ audio->replay->write_index = 0;
}
- return RT_EOK;
+ return result;
+}
+
+static rt_err_t _aduio_replay_start(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+
+ if (audio->replay->activated != RT_TRUE)
+ {
+ /* start playback hardware device */
+ if (audio->ops->start)
+ result = audio->ops->start(audio, AUDIO_STREAM_REPLAY);
+
+ audio->replay->activated = RT_TRUE;
+ LOG_D("start audio replay device");
+ }
+
+ return result;
+}
+
+static rt_err_t _aduio_replay_stop(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+
+ if (audio->replay->activated == RT_TRUE)
+ {
+ /* flush replay remian frames */
+ _audio_flush_replay_frame(audio);
+
+ /* notify irq(or thread) to stop the data transmission */
+ audio->replay->event |= REPLAY_EVT_STOP;
+
+ /* waiting for the remaining data transfer to complete */
+ rt_completion_init(&audio->replay->cmp);
+ rt_completion_wait(&audio->replay->cmp, RT_WAITING_FOREVER);
+ audio->replay->event &= ~REPLAY_EVT_STOP;
+
+ /* stop playback hardware device */
+ if (audio->ops->stop)
+ result = audio->ops->stop(audio, AUDIO_STREAM_REPLAY);
+
+ audio->replay->activated = RT_FALSE;
+ LOG_D("stop audio replay device");
+ }
+
+ return result;
+}
+
+static rt_err_t _audio_record_start(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+
+ if (audio->record->activated != RT_TRUE)
+ {
+ /* open audio record pipe */
+ rt_device_open(RT_DEVICE(&audio->record->pipe), RT_DEVICE_OFLAG_RDONLY);
+
+ /* start record hardware device */
+ if (audio->ops->start)
+ result = audio->ops->start(audio, AUDIO_STREAM_RECORD);
+
+ audio->record->activated = RT_TRUE;
+ LOG_D("start audio record device");
+ }
+
+ return result;
+}
+
+static rt_err_t _audio_record_stop(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+
+ if (audio->record->activated == RT_TRUE)
+ {
+ /* stop record hardware device */
+ if (audio->ops->stop)
+ result = audio->ops->stop(audio, AUDIO_STREAM_RECORD);
+
+ /* close audio record pipe */
+ rt_device_close(RT_DEVICE(&audio->record->pipe));
+
+ audio->record->activated = RT_FALSE;
+ LOG_D("stop audio record device");
+ }
+
+ return result;
}
static rt_err_t _audio_dev_init(struct rt_device *dev)
@@ -96,9 +221,68 @@ static rt_err_t _audio_dev_init(struct rt_device *dev)
audio->replay = RT_NULL;
audio->record = RT_NULL;
- /* apply configuration */
+ /* initialize replay */
+ if (dev->flag & RT_DEVICE_FLAG_WRONLY)
+ {
+ struct rt_audio_replay *replay = (struct rt_audio_replay *) rt_malloc(sizeof(struct rt_audio_replay));
+
+ if (replay == RT_NULL)
+ return -RT_ENOMEM;
+ memset(replay, 0, sizeof(struct rt_audio_replay));
+
+ /* init memory pool for replay */
+ replay->mp = rt_mp_create("adu_mp", RT_AUDIO_REPLAY_MP_BLOCK_COUNT, RT_AUDIO_REPLAY_MP_BLOCK_SIZE);
+ if (replay->mp == RT_NULL)
+ {
+ rt_free(replay);
+ LOG_E("create memory pool for repaly failed");
+ return -RT_ENOMEM;
+ }
+
+ /* init queue for audio replay */
+ rt_data_queue_init(&replay->queue, CFG_AUDIO_REPLAY_QUEUE_COUNT, 0, RT_NULL);
+
+ /* init mutex lock for audio replay */
+ rt_mutex_init(&replay->lock, "replay", RT_IPC_FLAG_PRIO);
+
+ replay->activated = RT_FALSE;
+ audio->replay = replay;
+ }
+
+ /* initialize record */
+ if (dev->flag & RT_DEVICE_FLAG_RDONLY)
+ {
+ struct rt_audio_record *record = (struct rt_audio_record *) rt_malloc(sizeof(struct rt_audio_record));
+ rt_uint8_t *buffer;
+
+ if (record == RT_NULL)
+ return -RT_ENOMEM;
+ memset(record, 0, sizeof(struct rt_audio_record));
+
+ /* init pipe for record*/
+ buffer = rt_malloc(RT_AUDIO_RECORD_PIPE_SIZE);
+ if (buffer == RT_NULL)
+ {
+ rt_free(record);
+ LOG_E("malloc memory for for record pipe failed");
+ return -RT_ENOMEM;
+ }
+ rt_audio_pipe_init(&record->pipe, "record",
+ (rt_int32_t)(RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD),
+ buffer,
+ RT_AUDIO_RECORD_PIPE_SIZE);
+
+ record->activated = RT_FALSE;
+ audio->record = record;
+ }
+
+ /* initialize hardware configuration */
if (audio->ops->init)
- result = audio->ops->init(audio);
+ audio->ops->init(audio);
+
+ /* get replay buffer information */
+ if (audio->ops->buffer_info)
+ audio->ops->buffer_info(audio, &audio->replay->buf_info);
return result;
}
@@ -122,65 +306,27 @@ static rt_err_t _audio_dev_open(struct rt_device *dev, rt_uint16_t oflag)
/* initialize the Rx/Tx structure according to open flag */
if (oflag & RT_DEVICE_OFLAG_WRONLY)
{
- AUDIO_DBG("open audio device ,oflag = %x\n",oflag);
- if (audio->replay == RT_NULL)
+ if (audio->replay->activated != RT_TRUE)
{
- struct rt_audio_replay *replay = (struct rt_audio_replay *) rt_malloc(sizeof(struct rt_audio_replay));
-
- if (replay == RT_NULL)
- {
- AUDIO_DBG("request memory for replay error\n");
- return -RT_ENOMEM;
- }
-
- //init queue for audio replay
- rt_data_queue_init(&replay->queue, CFG_AUDIO_REPLAY_QUEUE_COUNT, CFG_AUDIO_REPLAY_QUEUE_COUNT / 2, RT_NULL);
-
- replay->activated = RT_FALSE;
- audio->replay = replay;
+ LOG_D("open audio replay device, oflag = %x\n", oflag);
+ audio->replay->write_index = 0;
+ audio->replay->read_index = 0;
+ audio->replay->pos = 0;
+ audio->replay->event = REPLAY_EVT_NONE;
}
-
dev->open_flag |= RT_DEVICE_OFLAG_WRONLY;
}
if (oflag & RT_DEVICE_OFLAG_RDONLY)
{
- if (audio->record == RT_NULL)
+ /* open record pipe */
+ if (audio->record->activated != RT_TRUE)
{
- struct rt_audio_record *record = (struct rt_audio_record *) rt_malloc(sizeof(struct rt_audio_record));
-
- if (record == RT_NULL)
- {
- AUDIO_DBG("request memory for record error\n");
- return -RT_ENOMEM;
- }
-
- //init pipe for record
- {
- rt_uint8_t *buf = rt_malloc(CFG_AUDIO_RECORD_PIPE_SIZE);
-
- if (buf == RT_NULL)
- {
- rt_free(record);
- AUDIO_DBG("request pipe memory error\n");
+ LOG_D("open audio record device ,oflag = %x\n", oflag);
- return -RT_ENOMEM;
- }
-
- rt_audio_pipe_init(&audio_pipe, "recpipe", (rt_int32_t)(RT_PIPE_FLAG_FORCE_WR | RT_PIPE_FLAG_BLOCK_RD), buf,
- CFG_AUDIO_RECORD_PIPE_SIZE);
- }
-
- record->activated = RT_FALSE;
- audio->record = record;
- }
-
- //open record pipe
- if (audio->record != RT_NULL)
- {
- rt_device_open(RT_DEVICE(&audio_pipe), RT_DEVICE_OFLAG_RDONLY);
+ _audio_record_start(audio);
+ audio->record->activated = RT_TRUE;
}
-
dev->open_flag |= RT_DEVICE_OFLAG_RDONLY;
}
@@ -193,39 +339,17 @@ static rt_err_t _audio_dev_close(struct rt_device *dev)
RT_ASSERT(dev != RT_NULL);
audio = (struct rt_audio_device *) dev;
- //shutdown the lower device
- if (audio->ops->shutdown != RT_NULL)
- audio->ops->shutdown(audio);
-
if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
{
- struct rt_audio_frame frame;
- //stop replay stream
- audio->ops->stop(audio, AUDIO_STREAM_REPLAY);
-
- //flush all frame
- while (rt_data_queue_peak(&audio->replay->queue, &frame.data_ptr, &frame.data_size) == RT_EOK)
- {
- //pop the head frame...
- rt_data_queue_pop(&audio->replay->queue, &frame.data_ptr, &frame.data_size, RT_WAITING_FOREVER);
-
- /* notify transmitted complete. */
- if (audio->parent.tx_complete != RT_NULL)
- audio->parent.tx_complete(&audio->parent, (void *) frame.data_ptr);
- }
-
+ /* stop replay stream */
+ _aduio_replay_stop(audio);
dev->open_flag &= ~RT_DEVICE_OFLAG_WRONLY;
}
if (dev->open_flag & RT_DEVICE_OFLAG_RDONLY)
{
- //stop record stream
- audio->ops->stop(audio, AUDIO_STREAM_RECORD);
-
- //close record pipe
- if (audio->record != RT_NULL)
- rt_device_close(RT_DEVICE(&audio_pipe));
-
+ /* stop record stream */
+ _audio_record_stop(audio);
dev->open_flag &= ~RT_DEVICE_OFLAG_RDONLY;
}
@@ -237,17 +361,19 @@ static rt_size_t _audio_dev_read(struct rt_device *dev, rt_off_t pos, void *buff
struct rt_audio_device *audio;
RT_ASSERT(dev != RT_NULL);
audio = (struct rt_audio_device *) dev;
+
if (!(dev->open_flag & RT_DEVICE_OFLAG_RDONLY) || (audio->record == RT_NULL))
return 0;
- return rt_device_read(RT_DEVICE(&audio_pipe), pos, buffer, size);
+ return rt_device_read(RT_DEVICE(&audio->record->pipe), pos, buffer, size);
}
static rt_size_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
- rt_err_t result = RT_EOK;
- rt_base_t level;
+
struct rt_audio_device *audio;
+ rt_uint8_t *ptr;
+ rt_uint16_t block_size, remain_bytes, index = 0;
RT_ASSERT(dev != RT_NULL);
audio = (struct rt_audio_device *) dev;
@@ -255,34 +381,46 @@ static rt_size_t _audio_dev_write(struct rt_device *dev, rt_off_t pos, const voi
if (!(dev->open_flag & RT_DEVICE_OFLAG_WRONLY) || (audio->replay == RT_NULL))
return 0;
- AUDIO_DBG("audio write : pos = %d,buffer = %x,size = %d\n",pos,(rt_uint32_t)buffer,size);
- //push a new frame to tx queue
+ /* push a new frame to replay data queue */
+ ptr = (rt_uint8_t *)buffer;
+ block_size = RT_AUDIO_REPLAY_MP_BLOCK_SIZE;
+
+ rt_mutex_take(&audio->replay->lock, RT_WAITING_FOREVER);
+ while (index < size)
{
- result = rt_data_queue_push(&audio->replay->queue, buffer, size,
- RT_WAITING_FOREVER);
- if (result != RT_EOK)
+ /* request buffer from replay memory pool */
+ if (audio->replay->write_index % block_size == 0)
{
- AUDIO_DBG("TX frame queue push error\n");
- rt_set_errno(-RT_EFULL);
- return 0;
+ audio->replay->write_data = rt_mp_alloc(audio->replay->mp, RT_WAITING_FOREVER);
+ memset(audio->replay->write_data, 0, block_size);
+ }
+
+ /* copy data to replay memory pool */
+ remain_bytes = MIN((block_size - audio->replay->write_index), (size - index));
+ memcpy(&audio->replay->write_data[audio->replay->write_index], &ptr[index], remain_bytes);
+
+ index += remain_bytes;
+ audio->replay->write_index += remain_bytes;
+ audio->replay->write_index %= block_size;
+
+ if (audio->replay->write_index == 0)
+ {
+ rt_data_queue_push(&audio->replay->queue,
+ audio->replay->write_data,
+ block_size,
+ RT_WAITING_FOREVER);
}
}
+ rt_mutex_release(&audio->replay->lock);
- //check tx state...
- level = rt_hw_interrupt_disable();
+ /* check replay state */
if (audio->replay->activated != RT_TRUE)
{
+ _aduio_replay_start(audio);
audio->replay->activated = RT_TRUE;
- rt_hw_interrupt_enable(level);
-
- _audio_send_replay_frame(audio);
- }
- else
- {
- rt_hw_interrupt_enable(level);
}
- return size;
+ return index;
}
static rt_err_t _audio_dev_control(struct rt_device *dev, int cmd, void *args)
@@ -292,112 +430,70 @@ static rt_err_t _audio_dev_control(struct rt_device *dev, int cmd, void *args)
RT_ASSERT(dev != RT_NULL);
audio = (struct rt_audio_device *) dev;
- //dev stat...
+ /* dev stat...*/
switch (cmd)
{
- case AUDIO_CTL_GETCAPS:
- {
- struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
+ case AUDIO_CTL_GETCAPS:
+ {
+ struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
- AUDIO_DBG("AUDIO_CTL_GETCAPS: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type);
- if (audio->ops->getcaps != RT_NULL)
- {
- result = audio->ops->getcaps(audio, caps);
- }
- }
- break;
- case AUDIO_CTL_CONFIGURE:
+ LOG_D("AUDIO_CTL_GETCAPS: main_type = %d,sub_type = %d", caps->main_type, caps->sub_type);
+ if (audio->ops->getcaps != RT_NULL)
{
- struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
-
- AUDIO_DBG("AUDIO_CTL_CONFIGURE: main_type = %d,sub_type = %d\n",caps->main_type,caps->sub_type);
- if (audio->ops->configure != RT_NULL)
- {
- result = audio->ops->configure(audio, caps);
- }
+ result = audio->ops->getcaps(audio, caps);
}
break;
- case AUDIO_CTL_SHUTDOWN:
- {
- AUDIO_DBG("AUDIO_CTL_SHUTDOWN\n");
-
- if (audio->ops->shutdown != RT_NULL)
- result = audio->ops->shutdown(audio);
+ }
- //flush replay frame...
- _audio_flush_replay_frame(audio);
- }
- break;
+ case AUDIO_CTL_CONFIGURE:
+ {
+ struct rt_audio_caps *caps = (struct rt_audio_caps *) args;
- case AUDIO_CTL_START:
+ LOG_D("AUDIO_CTL_CONFIGURE: main_type = %d,sub_type = %d", caps->main_type, caps->sub_type);
+ if (audio->ops->configure != RT_NULL)
{
- int stream = *(int *) args;
-
- AUDIO_DBG("AUDIO_CTL_START: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->start(audio, stream);
+ result = audio->ops->configure(audio, caps);
}
+
break;
- case AUDIO_CTL_STOP:
- {
- int stream = *(int *) args;
+ }
- AUDIO_DBG("AUDIO_CTL_STOP: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->stop(audio, stream);
+ case AUDIO_CTL_START:
+ {
+ int stream = *(int *) args;
- if (stream == AUDIO_STREAM_REPLAY)
- {
- _audio_flush_replay_frame(audio);
- }
- }
- break;
- case AUDIO_CTL_PAUSE:
+ LOG_D("AUDIO_CTL_START: stream = %d", stream);
+ if (stream == AUDIO_STREAM_REPLAY)
{
- int stream = *(int *) args;
-
- AUDIO_DBG("AUDIO_CTL_PAUSE: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->suspend(audio, stream);
+ result = _aduio_replay_start(audio);
}
- break;
- case AUDIO_CTL_RESUME:
+ else
{
- int stream = *(int *) args;
-
- AUDIO_DBG("AUDIO_CTL_RESUME: stream = %d\n",stream);
- if (audio->ops->start != RT_NULL)
- result = audio->ops->resume(audio, stream);
-
- //resume tx frame...
- if (stream == AUDIO_STREAM_REPLAY)
- _audio_send_replay_frame(audio);
+ result = _audio_record_start(audio);
}
+
break;
- case AUDIO_CTL_ALLOCBUFFER:
- {
- struct rt_audio_buf_desc *desc = (struct rt_audio_buf_desc *) args;
+ }
- if (desc)
- {
- desc->data_size = AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2;
- desc->data_ptr = rt_mp_alloc(&audio->mp, RT_WAITING_FOREVER);
+ case AUDIO_CTL_STOP:
+ {
+ int stream = *(int *) args;
- result = RT_EOK;
- }
- else result = -RT_EIO;
+ LOG_D("AUDIO_CTL_STOP: stream = %d", stream);
+ if (stream == AUDIO_STREAM_REPLAY)
+ {
+ result = _aduio_replay_stop(audio);
}
- break;
- case AUDIO_CTL_FREEBUFFER:
+ else
{
- rt_uint8_t *data_ptr = (rt_uint8_t *) args;
- if (data_ptr)
- rt_mp_free(data_ptr);
+ result = _audio_record_stop(audio);
}
+
break;
- default:
- result = audio->ops->control(audio, cmd, args);
+ }
+
+ default:
break;
}
@@ -418,7 +514,9 @@ const static struct rt_device_ops audio_ops =
rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data)
{
+ rt_err_t result = RT_EOK;
struct rt_device *device;
+
RT_ASSERT(audio != RT_NULL);
device = &(audio->parent);
@@ -438,15 +536,14 @@ rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_u
#endif
device->user_data = data;
- //init memory pool for replay
- {
- rt_uint8_t *mempool = rt_malloc(AUDIO_DEVICE_DECODE_MP_SZ);
- rt_mp_init(&audio->mp, "adu_mp", mempool, AUDIO_DEVICE_DECODE_MP_SZ,
- AUDIO_DEVICE_DECODE_MP_BLOCK_SZ * 2);
- }
-
/* register a character device */
- return rt_device_register(device, name, flag | RT_DEVICE_FLAG_REMOVABLE);
+ result = rt_device_register(device, name, flag | RT_DEVICE_FLAG_REMOVABLE);
+
+ /* initialize audio device */
+ if (result == RT_EOK)
+ result = rt_device_init(device);
+
+ return result;
}
int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
@@ -454,43 +551,43 @@ int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
int speed = 0;
switch (bitValue)
{
- case AUDIO_SAMP_RATE_8K:
- speed = 8000;
+ case AUDIO_SAMP_RATE_8K:
+ speed = 8000;
break;
- case AUDIO_SAMP_RATE_11K:
- speed = 11052;
+ case AUDIO_SAMP_RATE_11K:
+ speed = 11052;
break;
- case AUDIO_SAMP_RATE_16K:
- speed = 16000;
+ case AUDIO_SAMP_RATE_16K:
+ speed = 16000;
break;
- case AUDIO_SAMP_RATE_22K:
- speed = 22050;
+ case AUDIO_SAMP_RATE_22K:
+ speed = 22050;
break;
- case AUDIO_SAMP_RATE_32K:
- speed = 32000;
+ case AUDIO_SAMP_RATE_32K:
+ speed = 32000;
break;
- case AUDIO_SAMP_RATE_44K:
- speed = 44100;
+ case AUDIO_SAMP_RATE_44K:
+ speed = 44100;
break;
- case AUDIO_SAMP_RATE_48K:
- speed = 48000;
+ case AUDIO_SAMP_RATE_48K:
+ speed = 48000;
break;
- case AUDIO_SAMP_RATE_96K:
- speed = 96000;
+ case AUDIO_SAMP_RATE_96K:
+ speed = 96000;
break;
- case AUDIO_SAMP_RATE_128K:
- speed = 128000;
+ case AUDIO_SAMP_RATE_128K:
+ speed = 128000;
break;
- case AUDIO_SAMP_RATE_160K:
- speed = 160000;
+ case AUDIO_SAMP_RATE_160K:
+ speed = 160000;
break;
- case AUDIO_SAMP_RATE_172K:
- speed = 176400;
+ case AUDIO_SAMP_RATE_172K:
+ speed = 176400;
break;
- case AUDIO_SAMP_RATE_192K:
- speed = 192000;
+ case AUDIO_SAMP_RATE_192K:
+ speed = 192000;
break;
- default:
+ default:
break;
}
@@ -498,46 +595,18 @@ int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
return speed;
}
-rt_uint32_t rt_audio_format_to_bits(rt_uint32_t format)
+void rt_audio_tx_complete(struct rt_audio_device *audio)
{
- switch (format)
- {
- case AUDIO_FMT_PCM_U8:
- case AUDIO_FMT_PCM_S8:
- return 8;
- case AUDIO_FMT_PCM_S16_LE:
- case AUDIO_FMT_PCM_S16_BE:
- case AUDIO_FMT_PCM_U16_LE:
- case AUDIO_FMT_PCM_U16_BE:
- return 16;
- default:
- return 32;
- };
-}
-
-void rt_audio_tx_complete(struct rt_audio_device *audio, rt_uint8_t *pbuf)
-{
- rt_err_t result;
- AUDIO_DBG("audio tx complete ptr=%x...\n",(rt_uint32_t)pbuf);
-
- //try to send all frame
- do
- {
- result = _audio_send_replay_frame(audio);
- } while (result == RT_EOK);
-
- /* notify transmitted complete. */
- if (audio->parent.tx_complete != RT_NULL)
- audio->parent.tx_complete(&audio->parent, (void *) pbuf);
+ /* try to send next frame */
+ _audio_send_replay_frame(audio);
}
void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len)
{
- //save data to record pipe
- rt_device_write(RT_DEVICE(RT_DEVICE(&audio_pipe)), 0, pbuf, len);
+ /* save data to record pipe */
+ rt_device_write(RT_DEVICE(&audio->record->pipe), 0, pbuf, len);
/* invoke callback */
if (audio->parent.rx_indicate != RT_NULL)
audio->parent.rx_indicate(&audio->parent, len);
}
-
diff --git a/components/drivers/audio/audio_pipe.c b/components/drivers/audio/audio_pipe.c
index 4df9fd8a49..d7c37009b6 100644
--- a/components/drivers/audio/audio_pipe.c
+++ b/components/drivers/audio/audio_pipe.c
@@ -24,8 +24,8 @@ static void _rt_pipe_resume_writer(struct rt_audio_pipe *pipe)
/* get suspended thread */
thread = rt_list_entry(pipe->suspended_write_list.next,
- struct rt_thread,
- tlist);
+ struct rt_thread,
+ tlist);
/* resume the write thread */
rt_thread_resume(thread);
@@ -50,7 +50,7 @@ static rt_size_t rt_pipe_read(rt_device_t dev,
if (!(pipe->flag & RT_PIPE_FLAG_BLOCK_RD))
{
level = rt_hw_interrupt_disable();
- read_nbytes = rt_ringbuffer_get(&(pipe->ringbuffer), buffer, size);
+ read_nbytes = rt_ringbuffer_get(&(pipe->ringbuffer), (rt_uint8_t *)buffer, size);
/* if the ringbuffer is empty, there won't be any writer waiting */
if (read_nbytes)
@@ -66,9 +66,10 @@ static rt_size_t rt_pipe_read(rt_device_t dev,
/* current context checking */
RT_DEBUG_NOT_IN_INTERRUPT;
- do {
+ do
+ {
level = rt_hw_interrupt_disable();
- read_nbytes = rt_ringbuffer_get(&(pipe->ringbuffer), buffer, size);
+ read_nbytes = rt_ringbuffer_get(&(pipe->ringbuffer), (rt_uint8_t *)buffer, size);
if (read_nbytes == 0)
{
rt_thread_suspend(thread);
@@ -85,7 +86,8 @@ static rt_size_t rt_pipe_read(rt_device_t dev,
rt_hw_interrupt_enable(level);
break;
}
- } while (read_nbytes == 0);
+ }
+ while (read_nbytes == 0);
return read_nbytes;
}
@@ -104,8 +106,8 @@ static void _rt_pipe_resume_reader(struct rt_audio_pipe *pipe)
/* get suspended thread */
thread = rt_list_entry(pipe->suspended_read_list.next,
- struct rt_thread,
- tlist);
+ struct rt_thread,
+ tlist);
/* resume the read thread */
rt_thread_resume(thread);
@@ -128,16 +130,16 @@ static rt_size_t rt_pipe_write(rt_device_t dev,
RT_ASSERT(pipe != RT_NULL);
if ((pipe->flag & RT_PIPE_FLAG_FORCE_WR) ||
- !(pipe->flag & RT_PIPE_FLAG_BLOCK_WR))
+ !(pipe->flag & RT_PIPE_FLAG_BLOCK_WR))
{
level = rt_hw_interrupt_disable();
if (pipe->flag & RT_PIPE_FLAG_FORCE_WR)
write_nbytes = rt_ringbuffer_put_force(&(pipe->ringbuffer),
- buffer, size);
+ (const rt_uint8_t *)buffer, size);
else
write_nbytes = rt_ringbuffer_put(&(pipe->ringbuffer),
- buffer, size);
+ (const rt_uint8_t *)buffer, size);
_rt_pipe_resume_reader(pipe);
@@ -151,9 +153,10 @@ static rt_size_t rt_pipe_write(rt_device_t dev,
/* current context checking */
RT_DEBUG_NOT_IN_INTERRUPT;
- do {
+ do
+ {
level = rt_hw_interrupt_disable();
- write_nbytes = rt_ringbuffer_put(&(pipe->ringbuffer), buffer, size);
+ write_nbytes = rt_ringbuffer_put(&(pipe->ringbuffer), (const rt_uint8_t *)buffer, size);
if (write_nbytes == 0)
{
/* pipe full, waiting on suspended write list */
@@ -171,7 +174,8 @@ static rt_size_t rt_pipe_write(rt_device_t dev,
rt_hw_interrupt_enable(level);
break;
}
- } while (write_nbytes == 0);
+ }
+ while (write_nbytes == 0);
return write_nbytes;
}
@@ -183,7 +187,7 @@ static rt_err_t rt_pipe_control(rt_device_t dev, int cmd, void *args)
pipe = (struct rt_audio_pipe *)dev;
if (cmd == PIPE_CTRL_GET_SPACE && args)
- *(rt_size_t*)args = rt_ringbuffer_space_len(&pipe->ringbuffer);
+ *(rt_size_t *)args = rt_ringbuffer_space_len(&pipe->ringbuffer);
return RT_EOK;
}
@@ -212,10 +216,10 @@ const static struct rt_device_ops audio_pipe_ops =
* @return the operation status, RT_EOK on successful
*/
rt_err_t rt_audio_pipe_init(struct rt_audio_pipe *pipe,
- const char *name,
- rt_int32_t flag,
- rt_uint8_t *buf,
- rt_size_t size)
+ const char *name,
+ rt_int32_t flag,
+ rt_uint8_t *buf,
+ rt_size_t size)
{
RT_ASSERT(pipe);
RT_ASSERT(buf);
@@ -270,7 +274,7 @@ rt_err_t rt_audio_pipe_create(const char *name, rt_int32_t flag, rt_size_t size)
return -RT_ENOMEM;
/* create ring buffer of pipe */
- rb_memptr = rt_malloc(size);
+ rb_memptr = (rt_uint8_t *)rt_malloc(size);
if (rb_memptr == RT_NULL)
{
rt_free(pipe);
diff --git a/components/drivers/can/can.c b/components/drivers/can/can.c
index e20fcddcff..9f4612355b 100644
--- a/components/drivers/can/can.c
+++ b/components/drivers/can/can.c
@@ -27,10 +27,15 @@ static rt_err_t rt_can_init(struct rt_device *dev)
/* initialize rx/tx */
can->can_rx = RT_NULL;
can->can_tx = RT_NULL;
+#ifdef RT_CAN_USING_HDR
+ can->hdr = RT_NULL;
+#endif
/* apply configuration */
if (can->ops->configure)
result = can->ops->configure(can, &can->config);
+ else
+ result = -RT_ENOSYS;
return result;
}
@@ -53,7 +58,7 @@ rt_inline int _can_int_rx(struct rt_can_device *can, struct rt_can_msg *data, in
{
rt_base_t level;
#ifdef RT_CAN_USING_HDR
- rt_int32_t hdr;
+ rt_int8_t hdr;
#endif /*RT_CAN_USING_HDR*/
struct rt_can_msg_list *listmsg = RT_NULL;
@@ -293,7 +298,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
can->can_rx = rx_fifo;
dev->open_flag |= RT_DEVICE_FLAG_INT_RX;
- /* configure low level device */
+ /* open can rx interrupt */
can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX);
}
}
@@ -311,7 +316,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
tx_fifo->buffer = (struct rt_can_sndbxinx_list *)(tx_fifo + 1);
rt_memset(tx_fifo->buffer, 0,
- can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list));
+ can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list));
rt_list_init(&tx_fifo->freelist);
for (i = 0; i < can->config.sndboxnumber; i++)
{
@@ -325,7 +330,7 @@ static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag)
can->can_tx = tx_fifo;
dev->open_flag |= RT_DEVICE_FLAG_INT_TX;
- /* configure low level device */
+ /* open can tx interrupt */
can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_TX);
}
}
@@ -405,7 +410,8 @@ static rt_err_t rt_can_close(struct rt_device *dev)
rt_free(rx_fifo);
dev->open_flag &= ~RT_DEVICE_FLAG_INT_RX;
- /* configure low level device */
+ can->can_rx = RT_NULL;
+ /* clear can rx interrupt */
can->ops->control(can, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_RX);
}
@@ -416,9 +422,11 @@ static rt_err_t rt_can_close(struct rt_device *dev)
tx_fifo = (struct rt_can_tx_fifo *)can->can_tx;
RT_ASSERT(tx_fifo != RT_NULL);
+ rt_sem_detach(&(tx_fifo->sem));
rt_free(tx_fifo);
dev->open_flag &= ~RT_DEVICE_FLAG_INT_TX;
- /* configure low level device */
+ can->can_tx = RT_NULL;
+ /* clear can tx interrupt */
can->ops->control(can, RT_DEVICE_CTRL_CLR_INT, (void *)RT_DEVICE_FLAG_INT_TX);
}
@@ -482,6 +490,7 @@ static rt_err_t rt_can_control(struct rt_device *dev,
struct rt_can_device *can;
rt_err_t res;
+ res = RT_EOK;
RT_ASSERT(dev != RT_NULL);
can = (struct rt_can_device *)dev;
@@ -499,8 +508,9 @@ static rt_err_t rt_can_control(struct rt_device *dev,
case RT_DEVICE_CTRL_CONFIG:
/* configure device */
- can->ops->configure(can, (struct can_configure *)args);
+ res = can->ops->configure(can, (struct can_configure *)args);
break;
+
case RT_CAN_CMD_SET_PRIV:
/* configure device */
if ((rt_uint32_t)args != can->config.privmode)
@@ -511,7 +521,6 @@ static rt_err_t rt_can_control(struct rt_device *dev,
res = can->ops->control(can, cmd, args);
if (res != RT_EOK) return res;
-
tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;
if (can->config.privmode)
{
@@ -520,11 +529,11 @@ static rt_err_t rt_can_control(struct rt_device *dev,
level = rt_hw_interrupt_disable();
if(rt_list_isempty(&tx_fifo->buffer[i].list))
{
- rt_sem_release(&(tx_fifo->sem));
+ rt_sem_release(&(tx_fifo->sem));
}
else
{
- rt_list_remove(&tx_fifo->buffer[i].list);
+ rt_list_remove(&tx_fifo->buffer[i].list);
}
rt_hw_interrupt_enable(level);
}
@@ -542,7 +551,6 @@ static rt_err_t rt_can_control(struct rt_device *dev,
rt_hw_interrupt_enable(level);
}
}
- return RT_EOK;
}
break;
@@ -559,74 +567,73 @@ static rt_err_t rt_can_control(struct rt_device *dev,
return res;
}
- {
- struct rt_can_filter_config *pfilter;
- struct rt_can_filter_item *pitem;
- rt_uint32_t count;
- rt_base_t level;
+ struct rt_can_filter_config *pfilter;
+ struct rt_can_filter_item *pitem;
+ rt_uint32_t count;
+ rt_base_t level;
- pfilter = (struct rt_can_filter_config *)args;
- count = pfilter->count;
- pitem = pfilter->items;
- if (pfilter->actived)
+ pfilter = (struct rt_can_filter_config *)args;
+ RT_ASSERT(pfilter);
+ count = pfilter->count;
+ pitem = pfilter->items;
+ if (pfilter->actived)
+ {
+ while (count)
{
- while (count)
+ if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0)
{
- if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0)
- {
- count--;
- pitem++;
- continue;
- }
-
- level = rt_hw_interrupt_disable();
- if (!can->hdr[pitem->hdr].connected)
- {
- rt_hw_interrupt_enable(level);
- rt_memcpy(&can->hdr[pitem->hdr].filter, pitem,
- sizeof(struct rt_can_filter_item));
- level = rt_hw_interrupt_disable();
- can->hdr[pitem->hdr].connected = 1;
- can->hdr[pitem->hdr].msgs = 0;
- rt_list_init(&can->hdr[pitem->hdr].list);
- }
- rt_hw_interrupt_enable(level);
-
count--;
pitem++;
+ continue;
}
+
+ level = rt_hw_interrupt_disable();
+ if (!can->hdr[pitem->hdr].connected)
+ {
+ rt_hw_interrupt_enable(level);
+ rt_memcpy(&can->hdr[pitem->hdr].filter, pitem,
+ sizeof(struct rt_can_filter_item));
+ level = rt_hw_interrupt_disable();
+ can->hdr[pitem->hdr].connected = 1;
+ can->hdr[pitem->hdr].msgs = 0;
+ rt_list_init(&can->hdr[pitem->hdr].list);
+ }
+ rt_hw_interrupt_enable(level);
+
+ count--;
+ pitem++;
}
- else
+ }
+ else
+ {
+ while (count)
{
- while (count)
+ if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0)
{
- if (pitem->hdr >= can->config.maxhdr || pitem->hdr < 0)
- {
- count--;
- pitem++;
- continue;
- }
- level = rt_hw_interrupt_disable();
+ count--;
+ pitem++;
+ continue;
+ }
+ level = rt_hw_interrupt_disable();
- if (can->hdr[pitem->hdr].connected)
+ if (can->hdr[pitem->hdr].connected)
+ {
+ can->hdr[pitem->hdr].connected = 0;
+ can->hdr[pitem->hdr].msgs = 0;
+ if (!rt_list_isempty(&can->hdr[pitem->hdr].list))
{
- can->hdr[pitem->hdr].connected = 0;
- can->hdr[pitem->hdr].msgs = 0;
- if (!rt_list_isempty(&can->hdr[pitem->hdr].list))
- {
- rt_list_remove(can->hdr[pitem->hdr].list.next);
- }
- rt_hw_interrupt_enable(level);
- rt_memset(&can->hdr[pitem->hdr].filter, 0,
- sizeof(struct rt_can_filter_item));
+ rt_list_remove(can->hdr[pitem->hdr].list.next);
}
- else
- {
- rt_hw_interrupt_enable(level);
- }
- count--;
- pitem++;
+ rt_hw_interrupt_enable(level);
+ rt_memset(&can->hdr[pitem->hdr].filter, 0,
+ sizeof(struct rt_can_filter_item));
+ }
+ else
+ {
+ rt_hw_interrupt_enable(level);
}
+ count--;
+ pitem++;
}
}
break;
@@ -640,12 +647,16 @@ static rt_err_t rt_can_control(struct rt_device *dev,
/* control device */
if (can->ops->control != RT_NULL)
{
- can->ops->control(can, cmd, args);
+ res = can->ops->control(can, cmd, args);
+ }
+ else
+ {
+ res = -RT_ENOSYS;
}
break;
}
- return RT_EOK;
+ return res;
}
/*
@@ -653,8 +664,10 @@ static rt_err_t rt_can_control(struct rt_device *dev,
*/
static void cantimeout(void *arg)
{
- rt_can_t can = (rt_can_t)arg;
+ rt_can_t can;
+ can = (rt_can_t)arg;
+ RT_ASSERT(can);
rt_device_control((rt_device_t)can, RT_CAN_CMD_GET_STATUS, (void *)&can->status);
if (can->status_indicate.ind != RT_NULL)
@@ -688,7 +701,7 @@ const static struct rt_device_ops can_device_ops =
/*
* can register
*/
-rt_err_t rt_hw_can_register(struct rt_can_device *can,
+rt_err_t rt_hw_can_register(struct rt_can_device *can,
const char *name,
const struct rt_can_ops *ops,
void *data)
@@ -758,7 +771,7 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
struct rt_can_rx_fifo *rx_fifo;
struct rt_can_msg_list *listmsg = RT_NULL;
#ifdef RT_CAN_USING_HDR
- rt_int32_t hdr;
+ rt_int8_t hdr;
#endif
int ch = -1;
rt_base_t level;
@@ -841,7 +854,10 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
level = rt_hw_interrupt_disable();
rx_length = can->hdr[hdr].msgs * sizeof(struct rt_can_msg);
rt_hw_interrupt_enable(level);
- can->hdr[hdr].filter.ind(&can->parent, can->hdr[hdr].filter.args, hdr, rx_length);
+ if (rx_length)
+ {
+ can->hdr[hdr].filter.ind(&can->parent, can->hdr[hdr].filter.args, hdr, rx_length);
+ }
}
else
#endif
@@ -852,10 +868,13 @@ void rt_hw_can_isr(struct rt_can_device *can, int event)
level = rt_hw_interrupt_disable();
/* get rx length */
- rx_length = rx_fifo->freenumbers * sizeof(struct rt_can_msg);
+ rx_length = rt_list_len(&rx_fifo->uselist)* sizeof(struct rt_can_msg);
rt_hw_interrupt_enable(level);
- can->parent.rx_indicate(&can->parent, rx_length);
+ if (rx_length)
+ {
+ can->parent.rx_indicate(&can->parent, rx_length);
+ }
}
}
break;
diff --git a/components/drivers/hwcrypto/SConscript b/components/drivers/hwcrypto/SConscript
new file mode 100644
index 0000000000..90feff50b3
--- /dev/null
+++ b/components/drivers/hwcrypto/SConscript
@@ -0,0 +1,34 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd = GetCurrentDir()
+CPPPATH = [cwd, str(Dir('#'))]
+
+src = ['hwcrypto.c']
+
+if (GetDepend(['RT_HWCRYPTO_USING_AES']) or
+ GetDepend(['RT_HWCRYPTO_USING_DES']) or
+ GetDepend(['RT_HWCRYPTO_USING_3DES']) or
+ GetDepend(['RT_HWCRYPTO_USING_RC4'])):
+ src += ['hw_symmetric.c']
+ if GetDepend(['RT_HWCRYPTO_USING_GCM']):
+ src += ['hw_gcm.c']
+
+if (GetDepend(['RT_HWCRYPTO_USING_MD5']) or
+ GetDepend(['RT_HWCRYPTO_USING_SHA1']) or
+ GetDepend(['RT_HWCRYPTO_USING_SHA2'])):
+ src += ['hw_hash.c']
+
+if GetDepend(['RT_HWCRYPTO_USING_RNG']):
+ src += ['hw_rng.c']
+
+if GetDepend(['RT_HWCRYPTO_USING_CRC']):
+ src += ['hw_crc.c']
+
+if GetDepend(['RT_HWCRYPTO_USING_BIGNUM']):
+ src += ['hw_bignum.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_HWCRYPTO'], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/components/drivers/hwcrypto/hw_bignum.c b/components/drivers/hwcrypto/hw_bignum.c
new file mode 100644
index 0000000000..88813566b1
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_bignum.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_bignum.h>
+
+static struct rt_hwcrypto_ctx *bignum_default;
+
+rt_inline rt_err_t hwcrypto_bignum_dev_is_init(void)
+{
+ struct rt_hwcrypto_device *dev;
+
+ if (bignum_default)
+ {
+ return RT_EOK;
+ }
+ dev = rt_hwcrypto_dev_default();
+ if (dev == RT_NULL)
+ {
+ return -RT_ERROR;
+ }
+ return rt_hwcrypto_bignum_default(dev);
+}
+
+/**
+ * @brief Setting bignum default devices
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_default(struct rt_hwcrypto_device *device)
+{
+ if (bignum_default)
+ {
+ rt_hwcrypto_ctx_destroy(bignum_default);
+ bignum_default = RT_NULL;
+ }
+ if (device == RT_NULL)
+ {
+ return RT_EOK;
+ }
+ bignum_default = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_BIGNUM, sizeof(struct hwcrypto_bignum));
+ if (bignum_default == RT_NULL)
+ {
+ return -RT_ERROR;
+ }
+ return RT_EOK;
+}
+
+/**
+ * @brief Init bignum obj
+ *
+ * @param n bignum obj
+ */
+void rt_hwcrypto_bignum_init(struct hw_bignum_mpi *n)
+{
+ if(n == RT_NULL)
+ return;
+
+ n->sign = 1;
+ n->total = 0;
+ n->p = RT_NULL;
+}
+
+/**
+ * @brief free a bignum obj
+ *
+ * @param Pointer to bignum obj
+ */
+void rt_hwcrypto_bignum_free(struct hw_bignum_mpi *n)
+{
+ if (n)
+ {
+ rt_free(n->p);
+ n->sign = 0;
+ n->total = 0;
+ n->p = RT_NULL;
+ }
+}
+
+/**
+ * @brief Get length of bignum as an unsigned binary buffer
+ *
+ * @param n bignum obj
+ *
+ * @return binary buffer length
+ */
+int rt_hwcrypto_bignum_get_len(const struct hw_bignum_mpi *n)
+{
+ int tmp_len, total;
+
+ if (n == RT_NULL || n->p == RT_NULL)
+ {
+ return 0;
+ }
+ tmp_len = 0;
+ total = n->total;
+ while ((total > 0) && (n->p[total - 1] == 0))
+ {
+ tmp_len++;
+ total--;
+ }
+ return n->total - tmp_len;
+}
+
+/**
+ * @brief Export n into unsigned binary data, big endian
+ *
+ * @param n bignum obj
+ * @param buf Buffer for the binary number
+ * @param len Length of the buffer
+ *
+ * @return export bin length
+ */
+int rt_hwcrypto_bignum_export_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
+{
+ int cp_len, i, j;
+
+ if (n == RT_NULL || buf == RT_NULL)
+ {
+ return 0;
+ }
+ rt_memset(buf, 0, len);
+ cp_len = n->total > len ? len : n->total;
+ for(i = cp_len, j = 0; i > 0; i--, j++)
+ {
+ buf[i - 1] = n->p[j];
+ }
+
+ return cp_len;
+}
+
+/**
+ * @brief Import n from unsigned binary data, big endian
+ *
+ * @param n bignum obj
+ * @param buf Buffer for the binary number
+ * @param len Length of the buffer
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_import_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len)
+{
+ int cp_len, i, j;
+ void *temp_p;
+
+ if (n == RT_NULL || buf == RT_NULL)
+ {
+ return 0;
+ }
+ if (n->total < len)
+ {
+ temp_p = rt_malloc(len);
+ if (temp_p == RT_NULL)
+ {
+ return 0;
+ }
+ rt_memset(temp_p, 0, len);
+ rt_free(n->p);
+ n->p = temp_p;
+ n->total = len;
+ }
+ cp_len = n->total > len ? len : n->total;
+
+ for(i = cp_len, j = 0; i > 0; i--, j++)
+ {
+ n->p[j] = buf[i - 1];
+ }
+
+ return cp_len;
+}
+
+/**
+ * @brief x = a + b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_add(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b)
+{
+ struct hwcrypto_bignum *bignum_ctx;
+
+ if (hwcrypto_bignum_dev_is_init() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+ if (bignum_ctx->ops->add)
+ {
+ return bignum_ctx->ops->add(bignum_ctx, x, a, b);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief x = a - b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_sub(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b)
+{
+ struct hwcrypto_bignum *bignum_ctx;
+
+ if (hwcrypto_bignum_dev_is_init() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+ if (bignum_ctx->ops->sub)
+ {
+ return bignum_ctx->ops->sub(bignum_ctx, x, a, b);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief x = a * b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mul(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b)
+{
+ struct hwcrypto_bignum *bignum_ctx;
+
+ if (hwcrypto_bignum_dev_is_init() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+ if (bignum_ctx->ops->mul)
+ {
+ return bignum_ctx->ops->mul(bignum_ctx, x, a, b);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief x = a * b (mod c)
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mulmod(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c)
+{
+ struct hwcrypto_bignum *bignum_ctx;
+
+ if (hwcrypto_bignum_dev_is_init() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+ if (bignum_ctx->ops->mulmod)
+ {
+ return bignum_ctx->ops->mulmod(bignum_ctx, x, a, b, c);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief x = a ^ b (mod c)
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_exptmod(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c)
+{
+ struct hwcrypto_bignum *bignum_ctx;
+
+ if (hwcrypto_bignum_dev_is_init() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
+ bignum_ctx = (struct hwcrypto_bignum *)bignum_default;
+ if (bignum_ctx->ops->exptmod)
+ {
+ return bignum_ctx->ops->exptmod(bignum_ctx, x, a, b, c);
+ }
+ return -RT_ERROR;
+}
diff --git a/components/drivers/hwcrypto/hw_bignum.h b/components/drivers/hwcrypto/hw_bignum.h
new file mode 100644
index 0000000000..a1f567e68f
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_bignum.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#ifndef __HW_BIGNUM_H__
+#define __HW_BIGNUM_H__
+
+#include <hwcrypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_bignum;
+
+/* bignum obj */
+struct hw_bignum_mpi
+{
+ int sign; /**< integer sign */
+ rt_size_t total; /**< total of limbs */
+ rt_uint8_t *p; /**< pointer to limbs */
+};
+
+struct hwcrypto_bignum_ops
+{
+ rt_err_t (*add)(struct hwcrypto_bignum *bignum_ctx,
+ struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b); /**< x = a + b */
+ rt_err_t (*sub)(struct hwcrypto_bignum *bignum_ctx,
+ struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b); /**< x = a - b */
+ rt_err_t (*mul)(struct hwcrypto_bignum *bignum_ctx,
+ struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b); /**< x = a * b */
+ rt_err_t (*mulmod)(struct hwcrypto_bignum *bignum_ctx,
+ struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c); /**< x = a * b (mod c) */
+ rt_err_t (*exptmod)(struct hwcrypto_bignum *bignum_ctx,
+ struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c); /**< x = a ^ b (mod c) */
+};
+
+/**
+ * @brief bignum context. Hardware driver usage
+ */
+struct hwcrypto_bignum
+{
+ struct rt_hwcrypto_ctx parent; /**< Inheritance from hardware crypto context */
+ const struct hwcrypto_bignum_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Setting bignum default devices
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_default(struct rt_hwcrypto_device *device);
+
+/**
+ * @brief Init bignum obj
+ */
+void rt_hwcrypto_bignum_init(struct hw_bignum_mpi *n);
+
+/**
+ * @brief free a bignum obj
+ *
+ * @param Pointer to bignum obj
+ */
+void rt_hwcrypto_bignum_free(struct hw_bignum_mpi *n);
+
+/**
+ * @brief Get length of bignum as an unsigned binary buffer
+ *
+ * @param n bignum obj
+ *
+ * @return binary buffer Length
+ */
+int rt_hwcrypto_bignum_get_len(const struct hw_bignum_mpi *n);
+
+/**
+ * @brief Export n into unsigned binary data, big endian
+ *
+ * @param n bignum obj
+ * @param buf Buffer for the binary number
+ * @param len Length of the buffer
+ *
+ * @return export bin length
+ */
+int rt_hwcrypto_bignum_export_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len);
+
+/**
+ * @brief Import n from unsigned binary data, big endian
+ *
+ * @param n bignum obj
+ * @param buf Buffer for the binary number
+ * @param len Length of the buffer
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_import_bin(struct hw_bignum_mpi *n, rt_uint8_t *buf, int len);
+
+/**
+ * @brief x = a + b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_add(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b);
+
+/**
+ * @brief x = a - b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_sub(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b);
+
+/**
+ * @brief x = a * b
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mul(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b);
+
+/**
+ * @brief x = a * b (mod c)
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_mulmod(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c);
+
+/**
+ * @brief x = a ^ b (mod c)
+ *
+ * @param a bignum obj
+ * @param b bignum obj
+ * @param c bignum obj
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_bignum_exptmod(struct hw_bignum_mpi *x,
+ const struct hw_bignum_mpi *a,
+ const struct hw_bignum_mpi *b,
+ const struct hw_bignum_mpi *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hw_crc.c b/components/drivers/hwcrypto/hw_crc.c
new file mode 100644
index 0000000000..20579711e2
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_crc.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_crc.h>
+
+/**
+ * @brief Creating CRC Context
+ *
+ * @param device Hardware crypto device
+ * @param mode Setting default mode or custom mode
+ *
+ * @return CRC context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_crc_create(struct rt_hwcrypto_device *device,
+ hwcrypto_crc_mode mode)
+{
+ struct hwcrypto_crc *crc_ctx;
+
+ crc_ctx = (struct hwcrypto_crc *)rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_CRC, sizeof(struct hwcrypto_crc));
+ if (crc_ctx == RT_NULL)
+ {
+ return RT_NULL;
+ }
+
+ switch (mode)
+ {
+ case HWCRYPTO_CRC_CRC8:
+ {
+ struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC8_CFG;
+ crc_ctx->crc_cfg = temp;
+ break;
+ }
+ case HWCRYPTO_CRC_CRC16:
+ {
+ struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC16_CFG;
+ crc_ctx->crc_cfg = temp;
+ break;
+ }
+ case HWCRYPTO_CRC_CRC32:
+ {
+ struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC32_CFG;
+ crc_ctx->crc_cfg = temp;
+ break;
+ }
+ case HWCRYPTO_CRC_CCITT:
+ {
+ struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC_CCITT_CFG;
+ crc_ctx->crc_cfg = temp;
+ break;
+ }
+ case HWCRYPTO_CRC_DNP:
+ {
+ struct hwcrypto_crc_cfg temp = HWCRYPTO_CRC_DNP_CFG;
+ crc_ctx->crc_cfg = temp;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return &crc_ctx->parent;
+}
+
+/**
+ * @brief Destroy CRC Context
+ *
+ * @param ctx CRC context
+ */
+void rt_hwcrypto_crc_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief Processing a packet of data
+ *
+ * @param ctx CRC context
+ * @param input Data buffer to be Processed
+ * @param length Data Buffer length
+ *
+ * @return RT_EOK on success.
+ */
+rt_uint32_t rt_hwcrypto_crc_update(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *input,
+ rt_size_t length)
+{
+ struct hwcrypto_crc *crc_ctx = (struct hwcrypto_crc *)ctx;
+ if (ctx && crc_ctx->ops->update)
+ {
+ return crc_ctx->ops->update(crc_ctx, input, length);
+ }
+ return 0;
+}
+
+/**
+ * @brief CRC context configuration
+ *
+ * @param ctx CRC context
+ * @param cfg CRC config
+ */
+void rt_hwcrypto_crc_cfg(struct rt_hwcrypto_ctx *ctx,
+ struct hwcrypto_crc_cfg *cfg)
+{
+ if (cfg)
+ {
+ ((struct hwcrypto_crc *)ctx)->crc_cfg = *cfg;
+ }
+}
diff --git a/components/drivers/hwcrypto/hw_crc.h b/components/drivers/hwcrypto/hw_crc.h
new file mode 100644
index 0000000000..a6df92a2ef
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_crc.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#ifndef __HW_CRC_H__
+#define __HW_CRC_H__
+
+#include <hwcrypto.h>
+
+#define CRC_FLAG_REFIN (0x1 << 0)
+#define CRC_FLAG_REFOUT (0x1 << 1)
+
+#define HWCRYPTO_CRC8_CFG \
+{ \
+ .last_val = 0x00, \
+ .poly = 0x07, \
+ .width = 8, \
+ .xorout = 0x00, \
+ .flags = 0, \
+}
+
+#define HWCRYPTO_CRC16_CFG \
+{ \
+ .last_val = 0x0000, \
+ .poly = 0x8005, \
+ .width = 16, \
+ .xorout = 0x0000, \
+ .flags = 0, \
+}
+
+#define HWCRYPTO_CRC32_CFG \
+{ \
+ .last_val = 0x00000000, \
+ .poly = 0x04C11DB7, \
+ .width = 32, \
+ .xorout = 0x00000000, \
+ .flags = 0, \
+}
+
+#define HWCRYPTO_CRC_CCITT_CFG \
+{ \
+ .last_val = 0x0000, \
+ .poly = 0x1021, \
+ .width = 16, \
+ .xorout = 0x0000, \
+ .flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT, \
+}
+
+#define HWCRYPTO_CRC_DNP_CFG \
+{ \
+ .last_val = 0x0000, \
+ .poly = 0x3D65, \
+ .width = 16, \
+ .xorout = 0xffff, \
+ .flags = CRC_FLAG_REFIN | CRC_FLAG_REFOUT, \
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_crc;
+
+typedef enum
+{
+ HWCRYPTO_CRC_CUSTOM, /**< Custom CRC mode */
+ HWCRYPTO_CRC_CRC8, /**< poly : 0x07 */
+ HWCRYPTO_CRC_CRC16, /**< poly : 0x8005 */
+ HWCRYPTO_CRC_CRC32, /**< poly : 0x04C11DB7 */
+ HWCRYPTO_CRC_CCITT, /**< poly : 0x1021 */
+ HWCRYPTO_CRC_DNP, /**< poly : 0x3D65 */
+} hwcrypto_crc_mode;
+
+struct hwcrypto_crc_cfg
+{
+ rt_uint32_t last_val; /**< Last CRC value cache */
+ rt_uint32_t poly; /**< CRC polynomial */
+ rt_uint16_t width; /**< CRC value width */
+ rt_uint32_t xorout; /**< Result XOR Value */
+ rt_uint16_t flags; /**< Input or output data reverse. CRC_FLAG_REFIN or CRC_FLAG_REFOUT */
+};
+
+struct hwcrypto_crc_ops
+{
+ rt_uint32_t (*update)(struct hwcrypto_crc *ctx,
+ const rt_uint8_t *in, rt_size_t length); /**< Perform a CRC calculation. return CRC value */
+};
+
+/**
+ * @brief CRC context. Hardware driver usage
+ */
+struct hwcrypto_crc
+{
+ struct rt_hwcrypto_ctx parent; /**< Inherited from the standard device */
+ struct hwcrypto_crc_cfg crc_cfg; /**< CRC configure */
+ const struct hwcrypto_crc_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Creating CRC Context
+ *
+ * @param device Hardware crypto device
+ * @param mode Setting default mode or custom mode
+ *
+ * @return CRC context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_crc_create(struct rt_hwcrypto_device *device,
+ hwcrypto_crc_mode mode);
+
+/**
+ * @brief Destroy CRC Context
+ *
+ * @param ctx CRC context
+ */
+void rt_hwcrypto_crc_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Processing a packet of data
+ *
+ * @param ctx CRC context
+ * @param input Data buffer to be Processed
+ * @param length Data Buffer length
+ *
+ * @return CRC value
+ */
+rt_uint32_t rt_hwcrypto_crc_update(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *input, rt_size_t length);
+
+/**
+ * @brief CRC context configuration
+ *
+ * @param ctx CRC context
+ * @param cfg CRC config
+ */
+void rt_hwcrypto_crc_cfg(struct rt_hwcrypto_ctx *ctx,
+ struct hwcrypto_crc_cfg *cfg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hw_gcm.c b/components/drivers/hwcrypto/hw_gcm.c
new file mode 100644
index 0000000000..8d0f49149a
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_gcm.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-14 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_gcm.h>
+
+/**
+ * @brief Creating GCM Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of symmetric crypto context
+ *
+ * @return GCM context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_gcm_create(struct rt_hwcrypto_device *device,
+ hwcrypto_type crypt_type)
+{
+ struct rt_hwcrypto_ctx *ctx;
+
+ ctx = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_GCM, sizeof(struct hwcrypto_gcm));
+ if (ctx)
+ {
+ ((struct hwcrypto_gcm *)ctx)->crypt_type = crypt_type;
+ }
+ return ctx;
+}
+
+/**
+ * @brief Destroy GCM Context
+ *
+ * @param ctx GCM context
+ */
+void rt_hwcrypto_gcm_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief This function starts a GCM encryption or decryption operation
+ *
+ * @param ctx GCM context
+ * @param add The buffer holding the additional data
+ * @param add_len The length of the additional data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_start(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *add,
+ rt_size_t add_len)
+{
+ struct hwcrypto_gcm *gcm_ctx = (struct hwcrypto_gcm *)ctx;
+
+ if (gcm_ctx && gcm_ctx->ops->start)
+ {
+ return gcm_ctx->ops->start(gcm_ctx, add, add_len);
+ }
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief This function finishes the GCM operation and generates the authentication tag
+ *
+ * @param ctx GCM context
+ * @param tag The buffer for holding the tag
+ * @param tag_len The length of the tag to generate
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_finish(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *tag,
+ rt_size_t tag_len)
+{
+ struct hwcrypto_gcm *gcm_ctx = (struct hwcrypto_gcm *)ctx;
+
+ if (gcm_ctx && gcm_ctx->ops->finish)
+ {
+ return gcm_ctx->ops->finish(gcm_ctx, tag, tag_len);
+ }
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx GCM context
+ * @param mode Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in The buffer holding the input data
+ * @param out The buffer holding the output data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
+ rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out)
+{
+ return rt_hwcrypto_symmetric_crypt(ctx, mode, length, in, out);
+}
+
+/**
+ * @brief Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx GCM context
+ * @param key The crypto key
+ * @param bitlen The crypto key bit length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setkey(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *key, rt_uint32_t bitlen)
+{
+ return rt_hwcrypto_symmetric_setkey(ctx, key, bitlen);
+}
+
+/**
+ * @brief Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx GCM context
+ * @param key The crypto key buffer
+ * @param bitlen The crypto key bit length
+ *
+ * @return Key length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getkey(struct rt_hwcrypto_ctx *ctx,
+ rt_uint8_t *key, rt_uint32_t bitlen)
+{
+ return rt_hwcrypto_symmetric_getkey(ctx, key, bitlen);
+}
+
+/**
+ * @brief Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv The crypto initialization vector
+ * @param len The crypto initialization vector length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setiv(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *iv, rt_size_t len)
+{
+ return rt_hwcrypto_symmetric_setiv(ctx, iv, len);
+}
+
+/**
+ * @brief Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv The crypto initialization vector buffer
+ * @param len The crypto initialization vector buffer length
+ *
+ * @return IV length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getiv(struct rt_hwcrypto_ctx *ctx,
+ rt_uint8_t *iv, rt_size_t len)
+{
+ return rt_hwcrypto_symmetric_getiv(ctx, iv, len);
+}
+
+/**
+ * @brief Set offset in initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv_off The offset in IV
+ */
+void rt_hwcrypto_gcm_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off)
+{
+ rt_hwcrypto_symmetric_set_ivoff(ctx, iv_off);
+}
+
+/**
+ * @brief Get offset in initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv_off It must point to a valid memory
+ */
+void rt_hwcrypto_gcm_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off)
+{
+ rt_hwcrypto_symmetric_get_ivoff(ctx, iv_off);
+}
+
+/**
+ * @brief This function copy GCM context
+ *
+ * @param des The destination GCM context
+ * @param src The GCM context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_cpy(struct rt_hwcrypto_ctx *des,
+ const struct rt_hwcrypto_ctx *src)
+{
+ struct hwcrypto_gcm *gcm_des = (struct hwcrypto_gcm *)des;
+ struct hwcrypto_gcm *gcm_src = (struct hwcrypto_gcm *)src;
+
+ if (des != RT_NULL && src != RT_NULL)
+ {
+ gcm_des->crypt_type = gcm_src->crypt_type;
+ /* symmetric crypto context copy */
+ return rt_hwcrypto_symmetric_cpy(des, src);
+ }
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief Reset GCM context
+ *
+ * @param ctx GCM context
+ */
+void rt_hwcrypto_gcm_reset(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_symmetric_reset(ctx);
+}
diff --git a/components/drivers/hwcrypto/hw_gcm.h b/components/drivers/hwcrypto/hw_gcm.h
new file mode 100644
index 0000000000..a73b2b0634
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_gcm.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-14 tyx the first version
+ */
+
+#ifndef __HW_GCM_H__
+#define __HW_GCM_H__
+
+#include "hw_symmetric.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_gcm;
+
+struct hwcrypto_gcm_ops
+{
+ rt_err_t (*start)(struct hwcrypto_gcm *gcm_ctx,
+ const unsigned char *add, size_t add_len); /**< Set additional data. start GCM operation */
+ rt_err_t (*finish)(struct hwcrypto_gcm *gcm_ctx,
+ const unsigned char *tag, size_t tag_len); /**< finish GCM operation. get tag */
+};
+
+/**
+ * @brief GCM context. Hardware driver usage
+ */
+struct hwcrypto_gcm
+{
+ struct hwcrypto_symmetric parent; /**< Inheritance from hardware symmetric crypto context */
+ hwcrypto_type crypt_type; /**< symmetric crypto type. eg: AES/DES */
+ const struct hwcrypto_gcm_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Creating GCM Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of symmetric crypto context
+ *
+ * @return GCM context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_gcm_create(struct rt_hwcrypto_device *device,
+ hwcrypto_type crypt_type);
+
+/**
+ * @brief Destroy GCM Context
+ *
+ * @param ctx GCM context
+ */
+void rt_hwcrypto_gcm_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief This function starts a GCM encryption or decryption operation
+ *
+ * @param ctx GCM context
+ * @param add The buffer holding the additional data
+ * @param add_len The length of the additional data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_start(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *add,
+ rt_size_t add_len);
+
+/**
+ * @brief This function finishes the GCM operation and generates the authentication tag
+ *
+ * @param ctx GCM context
+ * @param tag The buffer for holding the tag
+ * @param tag_len The length of the tag to generate
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_finish(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *tag,
+ rt_size_t tag_len);
+
+/**
+ * @brief This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx GCM context
+ * @param mode Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in The buffer holding the input data
+ * @param out The buffer holding the output data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
+ rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out);
+
+/**
+ * @brief Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx GCM context
+ * @param key The crypto key
+ * @param bitlen The crypto key bit length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setkey(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx GCM context
+ * @param key The crypto key buffer
+ * @param bitlen The crypto key bit length
+ *
+ * @return Key length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getkey(struct rt_hwcrypto_ctx *ctx,
+ rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv The crypto initialization vector
+ * @param len The crypto initialization vector length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_setiv(struct rt_hwcrypto_ctx *ctx,
+ const rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv The crypto initialization vector buffer
+ * @param len The crypto initialization vector buffer length
+ *
+ * @return IV length of copy
+ */
+rt_err_t rt_hwcrypto_gcm_getiv(struct rt_hwcrypto_ctx *ctx,
+ rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief Set offset in initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv_off The offset in IV
+ */
+void rt_hwcrypto_gcm_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off);
+
+/**
+ * @brief Get offset in initialization vector
+ *
+ * @param ctx GCM context
+ * @param iv_off It must point to a valid memory
+ */
+void rt_hwcrypto_gcm_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off);
+
+/**
+ * @brief This function copy GCM context
+ *
+ * @param des The destination GCM context
+ * @param src The GCM context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_gcm_cpy(struct rt_hwcrypto_ctx *des,
+ const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief Reset GCM context
+ *
+ * @param ctx GCM context
+ */
+void rt_hwcrypto_gcm_reset(struct rt_hwcrypto_ctx *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hw_hash.c b/components/drivers/hwcrypto/hw_hash.c
new file mode 100644
index 0000000000..b20069ac0e
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_hash.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-23 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_hash.h>
+
+/**
+ * @brief Creating hash Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of hash context
+ *
+ * @return Hash context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_hash_create(struct rt_hwcrypto_device *device, hwcrypto_type type)
+{
+ struct rt_hwcrypto_ctx *ctx;
+
+ ctx = rt_hwcrypto_ctx_create(device, type, sizeof(struct hwcrypto_hash));
+ return ctx;
+}
+
+/**
+ * @brief Destroy hash Context
+ *
+ * @param ctx Hash context
+ */
+void rt_hwcrypto_hash_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief Get the final hash value
+ *
+ * @param ctx Hash context
+ * @param output Hash value buffer
+ * @param length Hash value buffer length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_finish(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *output, rt_size_t length)
+{
+ if (ctx && ((struct hwcrypto_hash *)ctx)->ops->finish)
+ {
+ return ((struct hwcrypto_hash *)ctx)->ops->finish((struct hwcrypto_hash *)ctx, output, length);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief Processing a packet of data
+ *
+ * @param ctx Hash context
+ * @param input Data buffer to be Processed
+ * @param length Data Buffer length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_update(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *input, rt_size_t length)
+{
+ if (ctx && ((struct hwcrypto_hash *)ctx)->ops->update)
+ {
+ return ((struct hwcrypto_hash *)ctx)->ops->update((struct hwcrypto_hash *)ctx, input, length);
+ }
+ return -RT_ERROR;
+}
+
+/**
+ * @brief This function copy hash context
+ *
+ * @param des The destination hash context
+ * @param src The hash context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
+{
+ return rt_hwcrypto_ctx_cpy(des, src);
+}
+
+/**
+ * @brief Reset hash context
+ *
+ * @param ctx Hash context
+ */
+void rt_hwcrypto_hash_reset(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_ctx_reset(ctx);
+}
+
+/**
+ * @brief Setting hash context type
+ *
+ * @param ctx Hash context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
+{
+ return rt_hwcrypto_set_type(ctx, type);
+}
diff --git a/components/drivers/hwcrypto/hw_hash.h b/components/drivers/hwcrypto/hw_hash.h
new file mode 100644
index 0000000000..de0310e84c
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_hash.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-23 tyx the first version
+ */
+
+#ifndef __HW_HASH_H__
+#define __HW_HASH_H__
+
+#include <hwcrypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_hash;
+
+struct hwcrypto_hash_ops
+{
+ rt_err_t (*update)(struct hwcrypto_hash *hash_ctx,
+ const rt_uint8_t *in, rt_size_t length); /**< Processing a packet of data */
+ rt_err_t (*finish)(struct hwcrypto_hash *hash_ctx,
+ rt_uint8_t *out, rt_size_t length); /**< Get the final hash value */
+};
+
+/**
+ * @brief hash context. Hardware driver usage
+ */
+struct hwcrypto_hash
+{
+ struct rt_hwcrypto_ctx parent; /**< Inheritance from hardware crypto context */
+ const struct hwcrypto_hash_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Creating hash Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of hash context
+ *
+ * @return Hash context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_hash_create(struct rt_hwcrypto_device *device,
+ hwcrypto_type type);
+
+/**
+ * @brief Destroy hash Context
+ *
+ * @param ctx Hash context
+ */
+void rt_hwcrypto_hash_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Get the final hash value
+ *
+ * @param ctx Hash context
+ * @param output Hash value buffer
+ * @param length Hash value buffer length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_finish(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *output, rt_size_t length);
+
+/**
+ * @brief Processing a packet of data
+ *
+ * @param ctx Hash context
+ * @param input Data buffer to be Processed
+ * @param length Data Buffer length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_update(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *input, rt_size_t length);
+
+/**
+ * @brief This function copy hash context
+ *
+ * @param des The destination hash context
+ * @param src The hash context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief Reset hash context
+ *
+ * @param ctx Hash context
+ */
+void rt_hwcrypto_hash_reset(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Setting hash context type
+ *
+ * @param ctx Hash context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_hash_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hw_rng.c b/components/drivers/hwcrypto/hw_rng.c
new file mode 100644
index 0000000000..13a17cc6be
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_rng.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_rng.h>
+
+/* Used to save default RNG Context */
+static struct rt_hwcrypto_ctx *ctx_default;
+
+/**
+ * @brief Creating RNG Context
+ *
+ * @param device Hardware crypto device
+ *
+ * @return RNG context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_rng_create(struct rt_hwcrypto_device *device)
+{
+ struct rt_hwcrypto_ctx *ctx;
+
+ ctx = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_RNG, sizeof(struct hwcrypto_rng));
+ return ctx;
+}
+
+/**
+ * @brief Destroy RNG Context
+ *
+ * @param ctx RNG context
+ */
+void rt_hwcrypto_rng_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ /* Destroy the defaule RNG Context ? */
+ if (ctx == ctx_default)
+ {
+ ctx_default = RT_NULL;
+ }
+ rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief Setting RNG default devices
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_rng_default(struct rt_hwcrypto_device *device)
+{
+ struct rt_hwcrypto_ctx *tmp_ctx;
+
+ /* if device is null, destroy default RNG Context */
+ if (device == RT_NULL)
+ {
+ if (ctx_default)
+ {
+ rt_hwcrypto_rng_destroy(ctx_default);
+ ctx_default = RT_NULL;
+ }
+ return RT_EOK;
+ }
+ /* Try create RNG Context */
+ tmp_ctx = rt_hwcrypto_rng_create(device);
+ if (tmp_ctx == RT_NULL)
+ {
+ return -RT_ERROR;
+ }
+ /* create RNG Context success, update default RNG Context */
+ rt_hwcrypto_rng_destroy(ctx_default);
+ ctx_default = tmp_ctx;
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Getting Random Numbers from RNG Context
+ *
+ * @param ctx RNG context
+ *
+ * @return Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update_ctx(struct rt_hwcrypto_ctx *ctx)
+{
+ if (ctx)
+ {
+ return ((struct hwcrypto_rng *)ctx)->ops->update((struct hwcrypto_rng *)ctx);
+ }
+ return 0;
+}
+
+/**
+ * @brief Return a random number
+ *
+ * @return Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update(void)
+{
+ /* Default device does not exist ? */
+ if (ctx_default == RT_NULL)
+ {
+ /* try create Context from default device */
+ rt_hwcrypto_rng_default(rt_hwcrypto_dev_default());
+ }
+ return rt_hwcrypto_rng_update_ctx(ctx_default);
+}
diff --git a/components/drivers/hwcrypto/hw_rng.h b/components/drivers/hwcrypto/hw_rng.h
new file mode 100644
index 0000000000..fc28afdb1e
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_rng.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#ifndef __HW_RNG_H__
+#define __HW_RNG_H__
+
+#include <hwcrypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_rng;
+
+struct hwcrypto_rng_ops
+{
+ rt_uint32_t (*update)(struct hwcrypto_rng *ctx); /**< Return a random number */
+};
+
+/**
+ * @brief random context. Hardware driver usage
+ */
+struct hwcrypto_rng
+{
+ struct rt_hwcrypto_ctx parent; /**< Inheritance from hardware crypto context */
+ const struct hwcrypto_rng_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Creating RNG Context
+ *
+ * @param device Hardware crypto device
+ *
+ * @return RNG context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_rng_create(struct rt_hwcrypto_device *device);
+
+/**
+ * @brief Destroy RNG Context
+ *
+ * @param ctx RNG context
+ */
+void rt_hwcrypto_rng_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Setting RNG default devices
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_rng_default(struct rt_hwcrypto_device *device);
+
+/**
+ * @brief Getting Random Numbers from RNG Context
+ *
+ * @param ctx RNG context
+ *
+ * @return Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update_ctx(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Return a random number
+ *
+ * @return Random number
+ */
+rt_uint32_t rt_hwcrypto_rng_update(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hw_symmetric.c b/components/drivers/hwcrypto/hw_symmetric.c
new file mode 100644
index 0000000000..789c5c1a2c
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_symmetric.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hw_symmetric.h>
+
+/**
+ * @brief Creating Symmetric Encryption and Decryption Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of symmetric crypto context
+ *
+ * @return Symmetric crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_symmetric_create(struct rt_hwcrypto_device *device, hwcrypto_type type)
+{
+ struct rt_hwcrypto_ctx *ctx;
+
+ ctx = rt_hwcrypto_ctx_create(device, type, sizeof(struct hwcrypto_symmetric));
+ return ctx;
+}
+
+/**
+ * @brief Destroy Symmetric Encryption and Decryption Context
+ *
+ * @param ctx Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ rt_hwcrypto_ctx_destroy(ctx);
+}
+
+/**
+ * @brief This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx Symmetric crypto context
+ * @param mode Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in The buffer holding the input data
+ * @param out The buffer holding the output data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode, rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out)
+{
+ struct hwcrypto_symmetric *symmetric_ctx;
+ struct hwcrypto_symmetric_info symmetric_info;
+ rt_err_t err;
+
+ if (ctx == RT_NULL)
+ {
+ return -RT_EINVAL;
+ }
+ symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+ if (symmetric_ctx->ops->crypt == RT_NULL)
+ {
+ return -RT_ERROR;
+ }
+ if (mode != HWCRYPTO_MODE_ENCRYPT && mode != HWCRYPTO_MODE_DECRYPT)
+ {
+ return -EINVAL;
+ }
+
+ /* Input information packaging */
+ symmetric_info.mode = mode;
+ symmetric_info.in = in;
+ symmetric_info.out = out;
+ symmetric_info.length = length;
+
+ /* Calling Hardware Encryption and Decryption Function */
+ err = symmetric_ctx->ops->crypt(symmetric_ctx, &symmetric_info);
+
+ /* clean up flags */
+ symmetric_ctx->flags &= ~(SYMMTRIC_MODIFY_KEY | SYMMTRIC_MODIFY_IV | SYMMTRIC_MODIFY_IVOFF);
+ return err;
+}
+
+/**
+ * @brief Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx Symmetric crypto context
+ * @param key The crypto key
+ * @param bitlen The crypto key bit length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setkey(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *key, rt_uint32_t bitlen)
+{
+ struct hwcrypto_symmetric *symmetric_ctx;
+
+ if (ctx && bitlen <= RT_HWCRYPTO_KEYBIT_MAX_SIZE)
+ {
+ symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+ rt_memcpy(symmetric_ctx->key, key, bitlen >> 3);
+ /* Record key length */
+ symmetric_ctx->key_bitlen = bitlen;
+ /* Key change flag set up */
+ symmetric_ctx->flags |= SYMMTRIC_MODIFY_KEY;
+ return RT_EOK;
+ }
+
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx Symmetric crypto context
+ * @param key The crypto key buffer
+ * @param bitlen The crypto key bit length
+ *
+ * @return Key length of copy
+ */
+int rt_hwcrypto_symmetric_getkey(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *key, rt_uint32_t bitlen)
+{
+ struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+
+ if (ctx && bitlen >= symmetric_ctx->key_bitlen)
+ {
+ rt_memcpy(key, symmetric_ctx->key, symmetric_ctx->key_bitlen >> 3);
+ return symmetric_ctx->key_bitlen;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv The crypto initialization vector
+ * @param len The crypto initialization vector length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setiv(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *iv, rt_size_t len)
+{
+ struct hwcrypto_symmetric *symmetric_ctx;
+
+ if (ctx && len <= RT_HWCRYPTO_IV_MAX_SIZE)
+ {
+ symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+ rt_memcpy(symmetric_ctx->iv, iv, len);
+ symmetric_ctx->iv_len = len;
+ /* IV change flag set up */
+ symmetric_ctx->flags |= SYMMTRIC_MODIFY_IV;
+ return RT_EOK;
+ }
+
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv The crypto initialization vector buffer
+ * @param len The crypto initialization vector buffer length
+ *
+ * @return IV length of copy
+ */
+int rt_hwcrypto_symmetric_getiv(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *iv, rt_size_t len)
+{
+ struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;;
+
+ if (ctx && len >= symmetric_ctx->iv_len)
+ {
+ rt_memcpy(iv, symmetric_ctx->iv, symmetric_ctx->iv_len);
+ return symmetric_ctx->iv_len;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Set offset in initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv_off The offset in IV
+ */
+void rt_hwcrypto_symmetric_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off)
+{
+ if (ctx)
+ {
+ ((struct hwcrypto_symmetric *)ctx)->iv_off = iv_off;
+ /* iv_off change flag set up */
+ ((struct hwcrypto_symmetric *)ctx)->flags |= SYMMTRIC_MODIFY_IVOFF;
+ }
+}
+
+/**
+ * @brief Get offset in initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv_off It must point to a valid memory
+ */
+void rt_hwcrypto_symmetric_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off)
+{
+ if (ctx && iv_off)
+ {
+ *iv_off = ((struct hwcrypto_symmetric *)ctx)->iv_off;
+ }
+}
+
+/**
+ * @brief This function copy symmetric crypto context
+ *
+ * @param des The destination symmetric crypto context
+ * @param src The symmetric crypto context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
+{
+ struct hwcrypto_symmetric *symmetric_des = (struct hwcrypto_symmetric *)des;
+ struct hwcrypto_symmetric *symmetric_src = (struct hwcrypto_symmetric *)src;
+
+ if (des != RT_NULL && src != RT_NULL)
+ {
+ /* Copy Symmetric Encryption and Decryption Context Information */
+ symmetric_des->flags = symmetric_src->flags ;
+ symmetric_des->iv_len = symmetric_src->iv_len ;
+ symmetric_des->iv_off = symmetric_src->iv_off ;
+ symmetric_des->key_bitlen = symmetric_src->key_bitlen;
+ rt_memcpy(symmetric_des->iv, symmetric_src->iv, symmetric_src->iv_len);
+ rt_memcpy(symmetric_des->key, symmetric_src->key, symmetric_src->key_bitlen >> 3);
+
+ /* Hardware context copy */
+ return rt_hwcrypto_ctx_cpy(des, src);
+ }
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief Reset symmetric crypto context
+ *
+ * @param ctx Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_reset(struct rt_hwcrypto_ctx *ctx)
+{
+ struct hwcrypto_symmetric *symmetric_ctx = (struct hwcrypto_symmetric *)ctx;
+ if (ctx != RT_NULL)
+ {
+ /* Copy Symmetric Encryption and Decryption Context Information */
+ symmetric_ctx->flags = 0x00;
+ symmetric_ctx->iv_len = 0x00;
+ symmetric_ctx->iv_off = 0x00;
+ symmetric_ctx->key_bitlen = 0x00;
+ rt_memset(symmetric_ctx->iv, 0, RT_HWCRYPTO_IV_MAX_SIZE);
+ rt_memset(symmetric_ctx->key, 0, RT_HWCRYPTO_KEYBIT_MAX_SIZE >> 3);
+
+ /* Hardware context reset */
+ rt_hwcrypto_ctx_reset(ctx);
+ }
+}
+
+/**
+ * @brief Setting symmetric crypto context type
+ *
+ * @param ctx Symmetric crypto context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
+{
+ return rt_hwcrypto_set_type(ctx, type);
+}
diff --git a/components/drivers/hwcrypto/hw_symmetric.h b/components/drivers/hwcrypto/hw_symmetric.h
new file mode 100644
index 0000000000..12f4dbec30
--- /dev/null
+++ b/components/drivers/hwcrypto/hw_symmetric.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-25 tyx the first version
+ */
+
+#ifndef __HW_SYMMETRIC_H__
+#define __HW_SYMMETRIC_H__
+
+#include <hwcrypto.h>
+
+#ifndef RT_HWCRYPTO_IV_MAX_SIZE
+#define RT_HWCRYPTO_IV_MAX_SIZE (16)
+#endif
+#ifndef RT_HWCRYPTO_KEYBIT_MAX_SIZE
+#define RT_HWCRYPTO_KEYBIT_MAX_SIZE (256)
+#endif
+
+#define SYMMTRIC_MODIFY_KEY (0x1 << 0)
+#define SYMMTRIC_MODIFY_IV (0x1 << 1)
+#define SYMMTRIC_MODIFY_IVOFF (0x1 << 2)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct hwcrypto_symmetric;
+struct hwcrypto_symmetric_info;
+
+struct hwcrypto_symmetric_ops
+{
+ rt_err_t (*crypt)(struct hwcrypto_symmetric *symmetric_ctx,
+ struct hwcrypto_symmetric_info *symmetric_info); /**< Hardware Symmetric Encryption and Decryption Callback */
+};
+
+/**
+ * @brief Hardware driver usage, including input and output information
+ */
+struct hwcrypto_symmetric_info
+{
+ hwcrypto_mode mode; /**< crypto mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT */
+ const rt_uint8_t *in; /**< Input data */
+ rt_uint8_t *out; /**< Output data will be written */
+ rt_size_t length; /**< The length of the input data in Bytes. It's a multiple of block size. */
+};
+
+/**
+ * @brief Symmetric crypto context. Hardware driver usage
+ */
+struct hwcrypto_symmetric
+{
+ struct rt_hwcrypto_ctx parent; /**< Inheritance from hardware crypto context */
+ rt_uint32_t flags; /**< key or iv or ivoff has been changed. The flag will be set up */
+ rt_int32_t iv_len; /**< initialization vector effective length */
+ rt_int32_t iv_off; /**< The offset in IV */
+ rt_uint8_t iv[RT_HWCRYPTO_IV_MAX_SIZE]; /**< The initialization vector */
+ rt_uint8_t key[RT_HWCRYPTO_KEYBIT_MAX_SIZE >> 3]; /**< The crypto key */
+ rt_int32_t key_bitlen; /**< The crypto key bit length */
+ const struct hwcrypto_symmetric_ops *ops; /**< !! Hardware initializes this value when creating context !! */
+};
+
+/**
+ * @brief Creating Symmetric Encryption and Decryption Context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of symmetric crypto context
+ *
+ * @return Symmetric crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_symmetric_create(struct rt_hwcrypto_device *device,
+ hwcrypto_type type);
+
+/**
+ * @brief Destroy Symmetric Encryption and Decryption Context
+ *
+ * @param ctx Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief This function performs a symmetric encryption or decryption operation
+ *
+ * @param ctx Symmetric crypto context
+ * @param mode Operation mode. HWCRYPTO_MODE_ENCRYPT or HWCRYPTO_MODE_DECRYPT
+ * @param length The length of the input data in Bytes. This must be a multiple of the block size
+ * @param in The buffer holding the input data
+ * @param out The buffer holding the output data
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_crypt(struct rt_hwcrypto_ctx *ctx, hwcrypto_mode mode,
+ rt_size_t length, const rt_uint8_t *in, rt_uint8_t *out);
+
+/**
+ * @brief Set Symmetric Encryption and Decryption Key
+ *
+ * @param ctx Symmetric crypto context
+ * @param key The crypto key
+ * @param bitlen The crypto key bit length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setkey(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief Get Symmetric Encryption and Decryption Key
+ *
+ * @param ctx Symmetric crypto context
+ * @param key The crypto key buffer
+ * @param bitlen The crypto key bit length
+ *
+ * @return Key length of copy
+ */
+int rt_hwcrypto_symmetric_getkey(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *key, rt_uint32_t bitlen);
+
+/**
+ * @brief Set Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv The crypto initialization vector
+ * @param len The crypto initialization vector length
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_setiv(struct rt_hwcrypto_ctx *ctx, const rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief Get Symmetric Encryption and Decryption initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv The crypto initialization vector buffer
+ * @param len The crypto initialization vector buffer length
+ *
+ * @return IV length of copy
+ */
+int rt_hwcrypto_symmetric_getiv(struct rt_hwcrypto_ctx *ctx, rt_uint8_t *iv, rt_size_t len);
+
+/**
+ * @brief Set offset in initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv_off The offset in IV
+ */
+void rt_hwcrypto_symmetric_set_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t iv_off);
+
+/**
+ * @brief Get offset in initialization vector
+ *
+ * @param ctx Symmetric crypto context
+ * @param iv_off It must point to a valid memory
+ */
+void rt_hwcrypto_symmetric_get_ivoff(struct rt_hwcrypto_ctx *ctx, rt_int32_t *iv_off);
+
+/**
+ * @brief This function copy symmetric crypto context
+ *
+ * @param des The destination symmetric crypto context
+ * @param src The symmetric crypto context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief Reset symmetric crypto context
+ *
+ * @param ctx Symmetric crypto context
+ */
+void rt_hwcrypto_symmetric_reset(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Setting symmetric crypto context type
+ *
+ * @param ctx Symmetric crypto context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_symmetric_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwcrypto/hwcrypto.c b/components/drivers/hwcrypto/hwcrypto.c
new file mode 100644
index 0000000000..bbe1ff63fb
--- /dev/null
+++ b/components/drivers/hwcrypto/hwcrypto.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-23 tyx the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <hwcrypto.h>
+
+/**
+ * @brief Setting context type (Direct calls are not recommended)
+ *
+ * @param ctx Crypto context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type)
+{
+ if (ctx)
+ {
+ /* Is it the same category? */
+ if ((ctx->type & HWCRYPTO_MAIN_TYPE_MASK) == (type & HWCRYPTO_MAIN_TYPE_MASK))
+ {
+ ctx->type = type;
+ return RT_EOK;
+ }
+ /* Context is empty type */
+ else if (ctx->type == HWCRYPTO_TYPE_NULL)
+ {
+ ctx->type = type;
+ return RT_EOK;
+ }
+ else
+ {
+ return -RT_ERROR;
+ }
+ }
+ return -RT_EINVAL;
+}
+
+/**
+ * @brief Reset context type (Direct calls are not recommended)
+ *
+ * @param ctx Crypto context
+ *
+ */
+void rt_hwcrypto_ctx_reset(struct rt_hwcrypto_ctx *ctx)
+{
+ if (ctx && ctx->device->ops->reset)
+ {
+ ctx->device->ops->reset(ctx);
+ }
+}
+
+/**
+ * @brief Init crypto context
+ *
+ * @param ctx The context to initialize
+ * @param device Hardware crypto device
+ * @param type Type of context
+ * @param obj_size Size of context object
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_init(struct rt_hwcrypto_ctx *ctx, struct rt_hwcrypto_device *device, hwcrypto_type type)
+{
+ rt_err_t err;
+
+ /* Setting context type */
+ rt_hwcrypto_set_type(ctx, type);
+ ctx->device = device;
+ /* Create hardware context */
+ err = ctx->device->ops->create(ctx);
+ if (err != RT_EOK)
+ {
+ return err;
+ }
+ return RT_EOK;
+}
+
+/**
+ * @brief Create crypto context
+ *
+ * @param device Hardware crypto device
+ * @param type Type of context
+ * @param obj_size Size of context object
+ *
+ * @return Crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_ctx_create(struct rt_hwcrypto_device *device, hwcrypto_type type, rt_uint32_t obj_size)
+{
+ struct rt_hwcrypto_ctx *ctx;
+ rt_err_t err;
+
+ /* Parameter checking */
+ if (device == RT_NULL || obj_size < sizeof(struct rt_hwcrypto_ctx))
+ {
+ return RT_NULL;
+ }
+ ctx = rt_malloc(obj_size);
+ if (ctx == RT_NULL)
+ {
+ return ctx;
+ }
+ rt_memset(ctx, 0, obj_size);
+ /* Init context */
+ err = rt_hwcrypto_ctx_init(ctx, device, type);
+ if (err != RT_EOK)
+ {
+ rt_free(ctx);
+ ctx = RT_NULL;
+ }
+ return ctx;
+}
+
+/**
+ * @brief Destroy crypto context
+ *
+ * @param device Crypto context
+ */
+void rt_hwcrypto_ctx_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+ if (ctx == RT_NULL)
+ {
+ return;
+ }
+ /* Destroy hardware context */
+ if (ctx->device->ops->destroy)
+ {
+ ctx->device->ops->destroy(ctx);
+ }
+ /* Free the resources */
+ rt_free(ctx);
+}
+
+/**
+ * @brief Copy crypto context
+ *
+ * @param des The destination context
+ * @param src The context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
+{
+ if (des == RT_NULL || src == RT_NULL)
+ {
+ return -RT_EINVAL;
+ }
+
+ /* The equipment is different or of different types and cannot be copied */
+ if (des->device != src->device ||
+ (des->type & HWCRYPTO_MAIN_TYPE_MASK) != (src->type & HWCRYPTO_MAIN_TYPE_MASK))
+ {
+ return -RT_EINVAL;
+ }
+ des->type = src->type;
+ /* Calling Hardware Context Copy Function */
+ return src->device->ops->copy(des, src);
+}
+
+/**
+ * @brief Get the default hardware crypto device
+ *
+ * @return Hardware crypto device
+ *
+ */
+struct rt_hwcrypto_device *rt_hwcrypto_dev_default(void)
+{
+ static struct rt_hwcrypto_device *hwcrypto_dev;
+
+ /* If there is a default device, return the device */
+ if (hwcrypto_dev)
+ {
+ return hwcrypto_dev;
+ }
+ /* Find by default device name */
+ hwcrypto_dev = (struct rt_hwcrypto_device *)rt_device_find(RT_HWCRYPTO_DEFAULT_NAME);
+ return hwcrypto_dev;
+}
+
+/**
+ * @brief Get the unique ID of the device
+ *
+ * @param device Device object
+ *
+ * @return Device unique ID
+ */
+rt_uint64_t rt_hwcrypto_id(struct rt_hwcrypto_device *device)
+{
+ if (device)
+ {
+ return device->id;
+ }
+ return 0;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops hwcrypto_ops =
+{
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL
+};
+#endif
+
+/**
+ * @brief Register hardware crypto device
+ *
+ * @param device Hardware crypto device
+ * @param name Name of device
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_register(struct rt_hwcrypto_device *device, const char *name)
+{
+ rt_err_t err;
+
+ RT_ASSERT(device != RT_NULL);
+ RT_ASSERT(name != RT_NULL);
+ RT_ASSERT(device->ops != RT_NULL);
+ RT_ASSERT(device->ops->create != RT_NULL);
+ RT_ASSERT(device->ops->destroy != RT_NULL);
+ RT_ASSERT(device->ops->copy != RT_NULL);
+ RT_ASSERT(device->ops->reset != RT_NULL);
+
+ rt_memset(&device->parent, 0, sizeof(struct rt_device));
+#ifdef RT_USING_DEVICE_OPS
+ device->parent.ops = &hwcrypto_ops;
+#else
+ device->parent.init = RT_NULL;
+ device->parent.open = RT_NULL;
+ device->parent.close = RT_NULL;
+ device->parent.read = RT_NULL;
+ device->parent.write = RT_NULL;
+ device->parent.control = RT_NULL;
+#endif
+
+ device->parent.user_data = RT_NULL;
+ device->parent.type = RT_Device_Class_Miscellaneous;
+
+ /* Register device */
+ err = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR);
+
+ return err;
+}
diff --git a/components/drivers/hwcrypto/hwcrypto.h b/components/drivers/hwcrypto/hwcrypto.h
new file mode 100644
index 0000000000..a428f4437d
--- /dev/null
+++ b/components/drivers/hwcrypto/hwcrypto.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-04-23 tyx the first version
+ */
+
+#ifndef __HWCRYPTO_H__
+#define __HWCRYPTO_H__
+
+#include <rtthread.h>
+
+#ifndef RT_HWCRYPTO_DEFAULT_NAME
+#define RT_HWCRYPTO_DEFAULT_NAME ("hwcryto")
+#endif
+
+#define HWCRYPTO_MAIN_TYPE_MASK (0xffffUL << 16)
+#define HWCRYPTO_SUB_TYPE_MASK (0xffUL << 8)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ HWCRYPTO_TYPE_NULL = 0x00000000,
+
+ /* Main Type */
+ /* symmetric Type */
+ HWCRYPTO_TYPE_HEAD = __LINE__,
+ HWCRYPTO_TYPE_AES = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< AES */
+ HWCRYPTO_TYPE_DES = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< DES */
+ HWCRYPTO_TYPE_3DES = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< 3DES */
+ HWCRYPTO_TYPE_RC4 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< RC4 */
+ HWCRYPTO_TYPE_GCM = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< GCM */
+ /* HASH Type */
+ HWCRYPTO_TYPE_MD5 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< MD5 */
+ HWCRYPTO_TYPE_SHA1 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< SHA1 */
+ HWCRYPTO_TYPE_SHA2 = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< SHA2 */
+ /* Other Type */
+ HWCRYPTO_TYPE_RNG = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< RNG */
+ HWCRYPTO_TYPE_CRC = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< CRC */
+ HWCRYPTO_TYPE_BIGNUM = ((__LINE__ - HWCRYPTO_TYPE_HEAD) & 0xffff) << 16, /**< BIGNUM */
+
+ /* AES Subtype */
+ HWCRYPTO_TYPE_AES_ECB = HWCRYPTO_TYPE_AES | (0x01 << 8),
+ HWCRYPTO_TYPE_AES_CBC = HWCRYPTO_TYPE_AES | (0x02 << 8),
+ HWCRYPTO_TYPE_AES_CFB = HWCRYPTO_TYPE_AES | (0x03 << 8),
+ HWCRYPTO_TYPE_AES_CTR = HWCRYPTO_TYPE_AES | (0x04 << 8),
+ HWCRYPTO_TYPE_AES_OFB = HWCRYPTO_TYPE_AES | (0x05 << 8),
+
+ /* DES Subtype */
+ HWCRYPTO_TYPE_DES_ECB = HWCRYPTO_TYPE_DES | (0x01 << 8),
+ HWCRYPTO_TYPE_DES_CBC = HWCRYPTO_TYPE_DES | (0x02 << 8),
+
+ /* 3DES Subtype */
+ HWCRYPTO_TYPE_3DES_ECB = HWCRYPTO_TYPE_3DES | (0x01 << 8),
+ HWCRYPTO_TYPE_3DES_CBC = HWCRYPTO_TYPE_3DES | (0x02 << 8),
+
+ /* SHA2 Subtype */
+ HWCRYPTO_TYPE_SHA224 = HWCRYPTO_TYPE_SHA2 | (0x01 << 8),
+ HWCRYPTO_TYPE_SHA256 = HWCRYPTO_TYPE_SHA2 | (0x02 << 8),
+ HWCRYPTO_TYPE_SHA384 = HWCRYPTO_TYPE_SHA2 | (0x03 << 8),
+ HWCRYPTO_TYPE_SHA512 = HWCRYPTO_TYPE_SHA2 | (0x04 << 8),
+} hwcrypto_type;
+
+typedef enum
+{
+ HWCRYPTO_MODE_ENCRYPT = 0x1, /**< Encryption operations */
+ HWCRYPTO_MODE_DECRYPT = 0x2, /**< Decryption operations */
+ HWCRYPTO_MODE_UNKNOWN = 0x7fffffff, /**< Unknown */
+} hwcrypto_mode;
+
+struct rt_hwcrypto_ctx;
+
+struct rt_hwcrypto_ops
+{
+ rt_err_t (*create)(struct rt_hwcrypto_ctx *ctx); /**< Creating hardware context */
+ void (*destroy)(struct rt_hwcrypto_ctx *ctx); /**< Delete hardware context */
+ rt_err_t (*copy)(struct rt_hwcrypto_ctx *des,
+ const struct rt_hwcrypto_ctx *src); /**< Cpoy hardware context */
+ void (*reset)(struct rt_hwcrypto_ctx *ctx); /**< Reset hardware context */
+};
+
+struct rt_hwcrypto_device
+{
+ struct rt_device parent; /**< Inherited from the standard device */
+ const struct rt_hwcrypto_ops *ops; /**< Hardware crypto ops */
+ rt_uint64_t id; /**< Unique id */
+ void *user_data; /**< Device user data */
+};
+
+struct rt_hwcrypto_ctx
+{
+ struct rt_hwcrypto_device *device; /**< Binding device */
+ hwcrypto_type type; /**< Encryption and decryption types */
+ void *contex; /**< Hardware context */
+};
+
+/**
+ * @brief Setting context type (Direct calls are not recommended)
+ *
+ * @param ctx Crypto context
+ * @param type Types of settings
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_set_type(struct rt_hwcrypto_ctx *ctx, hwcrypto_type type);
+
+/**
+ * @brief Reset context type (Direct calls are not recommended)
+ *
+ * @param ctx Crypto context
+ */
+void rt_hwcrypto_ctx_reset(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Init crypto context (Direct calls are not recommended)
+ *
+ * @param ctx The context to initialize
+ * @param device Hardware crypto device
+ * @param type Type of context
+ * @param obj_size Size of context object
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_init(struct rt_hwcrypto_ctx *ctx,
+ struct rt_hwcrypto_device *device, hwcrypto_type type);
+
+/**
+ * @brief Create crypto context (Direct calls are not recommended)
+ *
+ * @param device Hardware crypto device
+ * @param type Type of context
+ * @param obj_size Size of context object
+ *
+ * @return Crypto context
+ */
+struct rt_hwcrypto_ctx *rt_hwcrypto_ctx_create(struct rt_hwcrypto_device *device,
+ hwcrypto_type type, rt_uint32_t obj_size);
+
+/**
+ * @brief Destroy crypto context (Direct calls are not recommended)
+ *
+ * @param device Crypto context
+ */
+void rt_hwcrypto_ctx_destroy(struct rt_hwcrypto_ctx *ctx);
+
+/**
+ * @brief Copy crypto context (Direct calls are not recommended)
+ *
+ * @param des The destination context
+ * @param src The context to be copy
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_ctx_cpy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src);
+
+/**
+ * @brief Register hardware crypto device
+ *
+ * @param device Hardware crypto device
+ * @param name Name of device
+ *
+ * @return RT_EOK on success.
+ */
+rt_err_t rt_hwcrypto_register(struct rt_hwcrypto_device *device, const char *name);
+
+/**
+ * @brief Get the default hardware crypto device
+ *
+ * @return Hardware crypto device
+ *
+ */
+struct rt_hwcrypto_device *rt_hwcrypto_dev_default(void);
+
+/**
+ * @brief Get the unique ID of the device
+ *
+ * @param device Device object
+ *
+ * @return Device unique ID
+ */
+rt_uint64_t rt_hwcrypto_id(struct rt_hwcrypto_device *device);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/hwtimer/README_CN.md b/components/drivers/hwtimer/README_CN.md
index fb3b4fa60a..810b1b1d80 100644
--- a/components/drivers/hwtimer/README_CN.md
+++ b/components/drivers/hwtimer/README_CN.md
@@ -1,17 +1,16 @@
-定时器设备
-===
-
-##功能
----
+# 定时器设备
+
+## 功能
+
* 时间测量
* 周期或单次执行回调函数
-##编译
----
+## 编译
+
1. 在rtconfig.h添加 `#define RT_USING_HWTIMER`
-
-##使用流程
----
+
+## 使用流程
+
1. 以读写方式打开设备
2. 设置超时回调函数(如果需要)
3. 根据需要设置定时模式(单次/周期)
@@ -19,12 +18,12 @@
5. 写入超时值,定时器随即启动
6. 停止定时器(可选)
7. 关闭设备(如果需要)
-
+
应用参考 [hwtimer_test] (/examples/test/hwtimer\_test.c)
-##驱动编写指南
----
-###操作接口
+## 驱动编写指南
+
+### 操作接口
```
struct rt_hwtimer_ops
@@ -43,8 +42,8 @@ struct rt_hwtimer_ops
* count_get - <读取计数器值>
* control - <设置计数频率 >
-###定时器特征信息
-
+### 定时器特征信息
+
```
struct rt_hwtimer_info
{
@@ -60,7 +59,8 @@ struct rt_hwtimer_info
* maxcnt <计数器最大计数值>
* cntmode <递增计数/递减计数>
-###注册设备
+### 注册设备
+
```
static rt_hwtimer_t _timer0;
int stm32_hwtimer_init(void)
@@ -73,8 +73,9 @@ int stm32_hwtimer_init(void)
return 0;
}
```
-
-###定时器中断
+
+### 定时器中断
+
```
void timer_irq_handler(void)
{
@@ -84,15 +85,13 @@ void timer_irq_handler(void)
}
```
-##注意事项
----
-
-<font color="#FF0000">可能出现定时误差</font>
-
+## 注意事项
+
+**可能出现定时误差**
误差原因:
假设计数器最大值0xFFFF,计数频率1Mhz,定时时间1秒又1微秒。
-
+
由于定时器一次最多只能计时到65535us,对于1000001us的定时要求。
可以50000us定时20次完成,此时将会出现计算误差1us。
diff --git a/components/drivers/hwtimer/hwtimer.c b/components/drivers/hwtimer/hwtimer.c
index cd85b3baef..3953919fae 100644
--- a/components/drivers/hwtimer/hwtimer.c
+++ b/components/drivers/hwtimer/hwtimer.c
@@ -153,7 +153,7 @@ static rt_size_t rt_hwtimer_read(struct rt_device *dev, rt_off_t pos, void *buff
cnt = timer->ops->count_get(timer);
if (timer->info->cntmode == HWTIMER_CNTMODE_DW)
{
- cnt = timer->info->maxcnt - cnt;
+ cnt = (timer->freq * timer->period_sec) - cnt;
}
t = timer->overflow * timer->period_sec + cnt/(float)timer->freq;
@@ -255,6 +255,7 @@ static rt_err_t rt_hwtimer_control(struct rt_device *dev, int cmd, void *args)
*((struct rt_hwtimer_info*)args) = *timer->info;
}
+ break;
case HWTIMER_CTRL_MODE_SET:
{
rt_hwtimer_mode_t *m;
diff --git a/components/drivers/i2c/fm24clxx.c b/components/drivers/i2c/fm24clxx.c
deleted file mode 100644
index eecf3d455a..0000000000
--- a/components/drivers/i2c/fm24clxx.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2017-07-14 aubr.cool 1st version
- */
-#include <rtthread.h>
-#include <rtdevice.h>
-#include "fm24clxx.h"
-
-struct fm24clxx_device
-{
- struct rt_device parent;
- struct rt_i2c_bus_device *bus;
-};
-
-/* RT-Thread device interface */
-
-static rt_err_t fm24clxx_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-static rt_err_t fm24clxx_open(rt_device_t dev, rt_uint16_t oflag)
-{
- return RT_EOK;
-}
-
-static rt_err_t fm24clxx_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t fm24clxx_control(rt_device_t dev, int cmd, void *args)
-{
- return RT_EOK;
-}
-
-static rt_size_t fm24clxx_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
-{
- struct fm24clxx_device *fm24clxx;
- const struct fm24clxx_config *cfg;
- struct rt_i2c_msg msg[2];
- rt_uint8_t mem_addr[2] = {0,};
- rt_size_t ret = 0;
- RT_ASSERT(dev != 0);
-
- fm24clxx = (struct fm24clxx_device *) dev;
-
- RT_ASSERT(fm24clxx->parent.user_data != 0);
- cfg = (const struct fm24clxx_config *) fm24clxx->parent.user_data;
-
- if(pos > cfg->size)
- {
- return 0;
- }
-
- if(pos + size > cfg->size)
- {
- size = cfg->size - pos;
- }
-
- msg[0].addr = cfg->addr;
- msg[0].flags = cfg->flags | RT_I2C_WR;
- mem_addr[0] = (pos >> 8);
- mem_addr[1] = (rt_uint8_t) pos;
- msg[0].buf = (rt_uint8_t *) mem_addr;
- msg[0].len = 2;
-
- msg[1].addr = cfg->addr;
- msg[1].flags = cfg->flags | RT_I2C_RD;
- msg[1].buf = (rt_uint8_t *) buffer;
- msg[1].len = size;
-
- ret = rt_i2c_transfer(fm24clxx->bus, msg, 2);
- return (ret == 2) ? size : 0;
-}
-
-static rt_size_t fm24clxx_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
-{
- struct fm24clxx_device *fm24clxx;
- const struct fm24clxx_config *cfg;
- struct rt_i2c_msg msg[2];
- rt_uint8_t mem_addr[2] = {0,};
- rt_size_t ret = 0;
- RT_ASSERT(dev != 0);
-
- fm24clxx = (struct fm24clxx_device *) dev;
-
- RT_ASSERT(fm24clxx->parent.user_data != 0);
- cfg = (const struct fm24clxx_config *) fm24clxx->parent.user_data;
-
- if(pos > cfg->size)
- {
- return 0;
- }
-
- if(pos + size > cfg->size)
- {
- size = cfg->size - pos;
- }
-
- msg[0].addr = cfg->addr;
- msg[0].flags = cfg->flags | RT_I2C_WR;
- mem_addr[0] = (pos >> 8);
- mem_addr[1] = (rt_uint8_t) pos;
- msg[0].buf = (rt_uint8_t *) mem_addr;
- msg[0].len = 2;
-
- msg[1].addr = cfg->addr;
- msg[1].flags = cfg->flags | RT_I2C_WR | RT_I2C_NO_START;
- msg[1].buf = (rt_uint8_t *) buffer;
- msg[1].len = size;
-
- ret = rt_i2c_transfer(fm24clxx->bus, msg, 2);
- return (ret == 2) ? size : 0;
-}
-
-#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device fm24clxx_ops =
-{
- fm24clxx_init,
- fm24clxx_open,
- fm24clxx_close,
- fm24clxx_read,
- fm24clxx_write,
- fm24clxx_control
-};
-#endif
-
-rt_err_t fm24clxx_register(const char *fm_device_name, const char *i2c_bus, void *user_data)
-{
- static struct fm24clxx_device fm24clxx_drv;
- struct rt_i2c_bus_device *bus;
-
- bus = rt_i2c_bus_device_find(i2c_bus);
- if (bus == RT_NULL)
- {
- return RT_ENOSYS;
- }
-
- fm24clxx_drv.bus = bus;
- fm24clxx_drv.parent.type = RT_Device_Class_Block;
-#ifdef RT_USING_DEVICE_OPS
- fm24clxx_drv.parent.ops = &fm24clxx_ops;
-#else
- fm24clxx_drv.parent.init = fm24clxx_init;
- fm24clxx_drv.parent.open = fm24clxx_open;
- fm24clxx_drv.parent.close = fm24clxx_close;
- fm24clxx_drv.parent.read = fm24clxx_read;
- fm24clxx_drv.parent.write = fm24clxx_write;
- fm24clxx_drv.parent.control = fm24clxx_control;
-#endif
-
- fm24clxx_drv.parent.user_data = user_data;
-
- return rt_device_register(&fm24clxx_drv.parent, fm_device_name, RT_DEVICE_FLAG_RDWR);
-} \ No newline at end of file
diff --git a/components/drivers/i2c/fm24clxx.h b/components/drivers/i2c/fm24clxx.h
deleted file mode 100644
index 74ee065470..0000000000
--- a/components/drivers/i2c/fm24clxx.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2017-07-14 aubr.cool 1st version
- */
-
-#ifndef __FM24CLXX_H__
-#define __FM24CLXX_H__
-
-#include <rtthread.h>
-
-struct fm24clxx_config
-{
- rt_uint32_t size;
- rt_uint16_t addr;
- rt_uint16_t flags;
-};
-
-extern rt_err_t fm24clxx_register(const char *e2m_device_name,
- const char *i2c_bus, void *user_data);
-
-#endif /*__FM24CLXX_H__*/ \ No newline at end of file
diff --git a/components/drivers/i2c/i2c-bit-ops.c b/components/drivers/i2c/i2c-bit-ops.c
index 26479a1d68..99338eef54 100644
--- a/components/drivers/i2c/i2c-bit-ops.c
+++ b/components/drivers/i2c/i2c-bit-ops.c
@@ -10,11 +10,13 @@
#include <rtdevice.h>
-#ifdef RT_I2C_BIT_DEBUG
-#define bit_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__)
+#define DBG_TAG "I2C"
+#ifdef RT_I2C_BITOPS_DEBUG
+#define DBG_LVL DBG_LOG
#else
-#define bit_dbg(fmt, ...)
+#define DBG_LVL DBG_INFO
#endif
+#include <rtdbg.h>
#define SET_SDA(ops, val) ops->set_sda(ops->data, val)
#define SET_SCL(ops, val) ops->set_scl(ops->data, val)
@@ -54,11 +56,11 @@ static rt_err_t SCL_H(struct rt_i2c_bit_ops *ops)
return -RT_ETIMEOUT;
rt_thread_delay((ops->timeout + 1) >> 1);
}
-#ifdef RT_I2C_BIT_DEBUG
+#ifdef RT_I2C_BITOPS_DEBUG
if (rt_tick_get() != start)
{
- bit_dbg("wait %ld tick for SCL line to go high\n",
- rt_tick_get() - start);
+ LOG_D("wait %ld tick for SCL line to go high",
+ rt_tick_get() - start);
}
#endif
@@ -70,14 +72,14 @@ done:
static void i2c_start(struct rt_i2c_bit_ops *ops)
{
-#ifdef RT_I2C_BIT_DEBUG
+#ifdef RT_I2C_BITOPS_DEBUG
if (ops->get_scl && !GET_SCL(ops))
{
- bit_dbg("I2C bus error, SCL line low\n");
+ LOG_E("I2C bus error, SCL line low");
}
if (ops->get_sda && !GET_SDA(ops))
{
- bit_dbg("I2C bus error, SDA line low\n");
+ LOG_E("I2C bus error, SDA line low");
}
#endif
SDA_L(ops);
@@ -114,13 +116,13 @@ rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops)
if (SCL_H(ops) < 0)
{
- bit_dbg("wait ack timeout\n");
+ LOG_W("wait ack timeout");
return -RT_ETIMEOUT;
}
ack = !GET_SDA(ops); /* ACK : SDA pin is pulled low */
- bit_dbg("%s\n", ack ? "ACK" : "NACK");
+ LOG_D("%s", ack ? "ACK" : "NACK");
SCL_L(ops);
@@ -132,7 +134,7 @@ static rt_int32_t i2c_writeb(struct rt_i2c_bus_device *bus, rt_uint8_t data)
rt_int32_t i;
rt_uint8_t bit;
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
for (i = 7; i >= 0; i--)
{
@@ -142,8 +144,8 @@ static rt_int32_t i2c_writeb(struct rt_i2c_bus_device *bus, rt_uint8_t data)
i2c_delay(ops);
if (SCL_H(ops) < 0)
{
- bit_dbg("i2c_writeb: 0x%02x, "
- "wait scl pin high timeout at bit %d\n",
+ LOG_D("i2c_writeb: 0x%02x, "
+ "wait scl pin high timeout at bit %d",
data, i);
return -RT_ETIMEOUT;
@@ -159,7 +161,7 @@ static rt_int32_t i2c_readb(struct rt_i2c_bus_device *bus)
{
rt_uint8_t i;
rt_uint8_t data = 0;
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
SDA_H(ops);
i2c_delay(ops);
@@ -169,8 +171,8 @@ static rt_int32_t i2c_readb(struct rt_i2c_bus_device *bus)
if (SCL_H(ops) < 0)
{
- bit_dbg("i2c_readb: wait scl pin high "
- "timeout at bit %d\n", 7 - i);
+ LOG_D("i2c_readb: wait scl pin high "
+ "timeout at bit %d", 7 - i);
return -RT_ETIMEOUT;
}
@@ -205,13 +207,13 @@ static rt_size_t i2c_send_bytes(struct rt_i2c_bus_device *bus,
}
else if (ret == 0)
{
- i2c_dbg("send bytes: NACK.\n");
+ LOG_D("send bytes: NACK.");
return 0;
}
else
{
- i2c_dbg("send bytes: error %d\n", ret);
+ LOG_E("send bytes: error %d", ret);
return ret;
}
@@ -222,14 +224,14 @@ static rt_size_t i2c_send_bytes(struct rt_i2c_bus_device *bus,
static rt_err_t i2c_send_ack_or_nack(struct rt_i2c_bus_device *bus, int ack)
{
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
if (ack)
SET_SDA(ops, 0);
i2c_delay(ops);
if (SCL_H(ops) < 0)
{
- bit_dbg("ACK or NACK timeout\n");
+ LOG_E("ACK or NACK timeout.");
return -RT_ETIMEOUT;
}
@@ -263,7 +265,7 @@ static rt_size_t i2c_recv_bytes(struct rt_i2c_bus_device *bus,
ptr ++;
count --;
- bit_dbg("recieve bytes: 0x%02x, %s\n",
+ LOG_D("recieve bytes: 0x%02x, %s",
val, (flags & RT_I2C_NO_READ_ACK) ?
"(No ACK/NACK)" : (count ? "ACK" : "NACK"));
@@ -282,7 +284,7 @@ static rt_int32_t i2c_send_address(struct rt_i2c_bus_device *bus,
rt_uint8_t addr,
rt_int32_t retries)
{
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
rt_int32_t i;
rt_err_t ret = 0;
@@ -291,10 +293,10 @@ static rt_int32_t i2c_send_address(struct rt_i2c_bus_device *bus,
ret = i2c_writeb(bus, addr);
if (ret == 1 || i == retries)
break;
- bit_dbg("send stop condition\n");
+ LOG_D("send stop condition");
i2c_stop(ops);
i2c_delay2(ops);
- bit_dbg("send start condition\n");
+ LOG_D("send start condition");
i2c_start(ops);
}
@@ -306,7 +308,7 @@ static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus,
{
rt_uint16_t flags = msg->flags;
rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
rt_uint8_t addr1, addr2;
rt_int32_t retries;
@@ -319,12 +321,12 @@ static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus,
addr1 = 0xf0 | ((msg->addr >> 7) & 0x06);
addr2 = msg->addr & 0xff;
- bit_dbg("addr1: %d, addr2: %d\n", addr1, addr2);
+ LOG_D("addr1: %d, addr2: %d", addr1, addr2);
ret = i2c_send_address(bus, addr1, retries);
if ((ret != 1) && !ignore_nack)
{
- bit_dbg("NACK: sending first addr\n");
+ LOG_W("NACK: sending first addr");
return -RT_EIO;
}
@@ -332,19 +334,19 @@ static rt_err_t i2c_bit_send_address(struct rt_i2c_bus_device *bus,
ret = i2c_writeb(bus, addr2);
if ((ret != 1) && !ignore_nack)
{
- bit_dbg("NACK: sending second addr\n");
+ LOG_W("NACK: sending second addr");
return -RT_EIO;
}
if (flags & RT_I2C_RD)
{
- bit_dbg("send repeated start condition\n");
+ LOG_D("send repeated start condition");
i2c_restart(ops);
addr1 |= 0x01;
ret = i2c_send_address(bus, addr1, retries);
if ((ret != 1) && !ignore_nack)
{
- bit_dbg("NACK: sending repeated addr\n");
+ LOG_E("NACK: sending repeated addr");
return -RT_EIO;
}
@@ -369,11 +371,11 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
rt_uint32_t num)
{
struct rt_i2c_msg *msg;
- struct rt_i2c_bit_ops *ops = bus->priv;
+ struct rt_i2c_bit_ops *ops = (struct rt_i2c_bit_ops *)bus->priv;
rt_int32_t i, ret;
rt_uint16_t ignore_nack;
- bit_dbg("send start condition\n");
+ LOG_D("send start condition");
i2c_start(ops);
for (i = 0; i < num; i++)
{
@@ -388,7 +390,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
ret = i2c_bit_send_address(bus, msg);
if ((ret != RT_EOK) && !ignore_nack)
{
- bit_dbg("receive NACK from device addr 0x%02x msg %d\n",
+ LOG_D("receive NACK from device addr 0x%02x msg %d",
msgs[i].addr, i);
goto out;
}
@@ -397,7 +399,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
{
ret = i2c_recv_bytes(bus, msg);
if (ret >= 1)
- bit_dbg("read %d byte%s\n", ret, ret == 1 ? "" : "s");
+ LOG_D("read %d byte%s", ret, ret == 1 ? "" : "s");
if (ret < msg->len)
{
if (ret >= 0)
@@ -409,7 +411,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
{
ret = i2c_send_bytes(bus, msg);
if (ret >= 1)
- bit_dbg("write %d byte%s\n", ret, ret == 1 ? "" : "s");
+ LOG_D("write %d byte%s", ret, ret == 1 ? "" : "s");
if (ret < msg->len)
{
if (ret >= 0)
@@ -421,7 +423,7 @@ static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus,
ret = i;
out:
- bit_dbg("send stop condition\n");
+ LOG_D("send stop condition");
i2c_stop(ops);
return ret;
diff --git a/components/drivers/i2c/i2c_core.c b/components/drivers/i2c/i2c_core.c
index f245abb9ca..f358c2b758 100644
--- a/components/drivers/i2c/i2c_core.c
+++ b/components/drivers/i2c/i2c_core.c
@@ -10,6 +10,14 @@
#include <rtdevice.h>
+#define DBG_TAG "I2C"
+#ifdef RT_I2C_DEBUG
+#define DBG_LVL DBG_LOG
+#else
+#define DBG_LVL DBG_INFO
+#endif
+#include <rtdbg.h>
+
rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
const char *bus_name)
{
@@ -21,7 +29,7 @@ rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
res = rt_i2c_bus_device_device_init(bus, bus_name);
- i2c_dbg("I2C bus [%s] registered\n", bus_name);
+ LOG_I("I2C bus [%s] registered", bus_name);
return res;
}
@@ -32,7 +40,7 @@ struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name)
rt_device_t dev = rt_device_find(bus_name);
if (dev == RT_NULL || dev->type != RT_Device_Class_I2CBUS)
{
- i2c_dbg("I2C bus %s not exist\n", bus_name);
+ LOG_E("I2C bus %s not exist", bus_name);
return RT_NULL;
}
@@ -53,9 +61,9 @@ rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
#ifdef RT_I2C_DEBUG
for (ret = 0; ret < num; ret++)
{
- i2c_dbg("msgs[%d] %c, addr=0x%02x, len=%d\n", ret,
- (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W',
- msgs[ret].addr, msgs[ret].len);
+ LOG_D("msgs[%d] %c, addr=0x%02x, len=%d", ret,
+ (msgs[ret].flags & RT_I2C_RD) ? 'R' : 'W',
+ msgs[ret].addr, msgs[ret].len);
}
#endif
@@ -67,7 +75,7 @@ rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
}
else
{
- i2c_dbg("I2C bus operation not supported\n");
+ LOG_E("I2C bus operation not supported");
return 0;
}
@@ -83,7 +91,7 @@ rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus,
struct rt_i2c_msg msg;
msg.addr = addr;
- msg.flags = flags & RT_I2C_ADDR_10BIT;
+ msg.flags = flags;
msg.len = count;
msg.buf = (rt_uint8_t *)buf;
@@ -103,8 +111,7 @@ rt_size_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus,
RT_ASSERT(bus != RT_NULL);
msg.addr = addr;
- msg.flags = flags & RT_I2C_ADDR_10BIT;
- msg.flags |= RT_I2C_RD;
+ msg.flags = flags | RT_I2C_RD;
msg.len = count;
msg.buf = buf;
diff --git a/components/drivers/i2c/i2c_dev.c b/components/drivers/i2c/i2c_dev.c
index 6c7df8e427..59f728be09 100644
--- a/components/drivers/i2c/i2c_dev.c
+++ b/components/drivers/i2c/i2c_dev.c
@@ -11,6 +11,14 @@
#include <rtdevice.h>
+#define DBG_TAG "I2C"
+#ifdef RT_I2C_DEBUG
+#define DBG_LVL DBG_LOG
+#else
+#define DBG_LVL DBG_INFO
+#endif
+#include <rtdbg.h>
+
static rt_size_t i2c_bus_device_read(rt_device_t dev,
rt_off_t pos,
void *buffer,
@@ -23,12 +31,12 @@ static rt_size_t i2c_bus_device_read(rt_device_t dev,
RT_ASSERT(bus != RT_NULL);
RT_ASSERT(buffer != RT_NULL);
- i2c_dbg("I2C bus dev [%s] reading %u bytes.\n", dev->parent.name, count);
+ LOG_D("I2C bus dev [%s] reading %u bytes.", dev->parent.name, count);
addr = pos & 0xffff;
flags = (pos >> 16) & 0xffff;
- return rt_i2c_master_recv(bus, addr, flags, buffer, count);
+ return rt_i2c_master_recv(bus, addr, flags, (rt_uint8_t *)buffer, count);
}
static rt_size_t i2c_bus_device_write(rt_device_t dev,
@@ -43,12 +51,12 @@ static rt_size_t i2c_bus_device_write(rt_device_t dev,
RT_ASSERT(bus != RT_NULL);
RT_ASSERT(buffer != RT_NULL);
- i2c_dbg("I2C bus dev [%s] writing %u bytes.\n", dev->parent.name, count);
+ LOG_D("I2C bus dev [%s] writing %u bytes.", dev->parent.name, count);
addr = pos & 0xffff;
flags = (pos >> 16) & 0xffff;
- return rt_i2c_master_send(bus, addr, flags, buffer, count);
+ return rt_i2c_master_send(bus, addr, flags, (const rt_uint8_t *)buffer, count);
}
static rt_err_t i2c_bus_device_control(rt_device_t dev,
diff --git a/components/drivers/include/drivers/alarm.h b/components/drivers/include/drivers/alarm.h
index b5ebbc86d9..dd59f4c1e8 100644
--- a/components/drivers/include/drivers/alarm.h
+++ b/components/drivers/include/drivers/alarm.h
@@ -6,6 +6,8 @@
* Change Logs:
* Date Author Notes
* 2012-10-27 heyuanjie87 first version.
+ * 2013-05-17 aozima initial alarm event & mutex in system init.
+ * 2020-10-15 zhangsz add alarm flags hour minute second.
*/
#ifndef __ALARM_H__
@@ -22,6 +24,9 @@
#define RT_ALARM_WEEKLY 0x200 /* alarm weekly at Monday or Friday etc. */
#define RT_ALARM_MONTHLY 0x400 /* alarm monthly at someday */
#define RT_ALARM_YAERLY 0x800 /* alarm yearly at a certain date */
+#define RT_ALARM_HOUR 0x1000 /* alarm each hour at a certain min:second */
+#define RT_ALARM_MINUTE 0x2000 /* alarm each minute at a certain second */
+#define RT_ALARM_SECOND 0x4000 /* alarm each second */
/* alarm control cmd */
#define RT_ALARM_CTRL_MODIFY 1 /* modify alarm time or alarm flag */
@@ -67,6 +72,6 @@ void rt_alarm_update(rt_device_t dev, rt_uint32_t event);
rt_err_t rt_alarm_delete(rt_alarm_t alarm);
rt_err_t rt_alarm_start(rt_alarm_t alarm);
rt_err_t rt_alarm_stop(rt_alarm_t alarm);
-void rt_alarm_system_init(void);
+int rt_alarm_system_init(void);
#endif /* __ALARM_H__ */
diff --git a/components/drivers/include/drivers/audio.h b/components/drivers/include/drivers/audio.h
index 7d2cb36728..86057e7626 100644
--- a/components/drivers/include/drivers/audio.h
+++ b/components/drivers/include/drivers/audio.h
@@ -5,52 +5,30 @@
*
* Change Logs:
* Date Author Notes
- * 2017-05-09 Urey first version
+ * 2017-05-09 Urey first version
+ * 2019-07-09 Zero-Free improve device ops interface and data flows
+ *
*/
#ifndef __AUDIO_H__
#define __AUDIO_H__
+#include "audio_pipe.h"
+
/* AUDIO command */
#define _AUDIO_CTL(a) (0x10 + a)
#define AUDIO_CTL_GETCAPS _AUDIO_CTL(1)
#define AUDIO_CTL_CONFIGURE _AUDIO_CTL(2)
-#define AUDIO_CTL_SHUTDOWN _AUDIO_CTL(3)
-#define AUDIO_CTL_START _AUDIO_CTL(4)
-#define AUDIO_CTL_STOP _AUDIO_CTL(5)
-#define AUDIO_CTL_PAUSE _AUDIO_CTL(6)
-#define AUDIO_CTL_RESUME _AUDIO_CTL(7)
-#define AUDIO_CTL_GETBUFFERINFO _AUDIO_CTL(8)
-#define AUDIO_CTL_ALLOCBUFFER _AUDIO_CTL(9)
-#define AUDIO_CTL_FREEBUFFER _AUDIO_CTL(10)
-#define AUDIO_CTL_HWRESET _AUDIO_CTL(11)
-
+#define AUDIO_CTL_START _AUDIO_CTL(3)
+#define AUDIO_CTL_STOP _AUDIO_CTL(4)
+#define AUDIO_CTL_GETBUFFERINFO _AUDIO_CTL(5)
/* Audio Device Types */
#define AUDIO_TYPE_QUERY 0x00
#define AUDIO_TYPE_INPUT 0x01
#define AUDIO_TYPE_OUTPUT 0x02
#define AUDIO_TYPE_MIXER 0x04
-#define AUDIO_TYPE_SELECTOR 0x08
-#define AUDIO_TYPE_EFFECT 0x10
-
-/* Audio Format Types */
-#define AUDIO_FMT_PCM_U8 0x0001
-#define AUDIO_FMT_PCM_S8 0x0002
-
-#define AUDIO_FMT_PCM_U16_LE 0x0010
-#define AUDIO_FMT_PCM_S16_BE 0x0020
-#define AUDIO_FMT_PCM_S16_LE 0x0040
-#define AUDIO_FMT_PCM_U16_BE 0x0080
-#define AUDIO_FMT_PCM_U24_LE 0x0100
-#define AUDIO_FMT_PCM_S24_BE 0x0200
-#define AUDIO_FMT_PCM_S24_LE 0x0400
-#define AUDIO_FMT_PCM_U24_BE 0x0800
-#define AUDIO_FMT_PCM_U32_LE 0x1000
-#define AUDIO_FMT_PCM_S32_BE 0x2000
-#define AUDIO_FMT_PCM_S32_LE 0x4000
-#define AUDIO_FMT_PCM_U32_BE 0x8000
/* Supported Sampling Rates */
#define AUDIO_SAMP_RATE_8K 0x0001
@@ -76,13 +54,11 @@
#define AUDIO_BIT_RATE_172K 0x40
#define AUDIO_BIT_RATE_192K 0x80
-
-
/* Support Dsp(input/output) Units controls */
#define AUDIO_DSP_PARAM 0 /* get/set all params */
-#define AUDIO_DSP_SAMPLERATE 1 /* 采样频率 */
-#define AUDIO_DSP_FMT 2
-#define AUDIO_DSP_CHANNELS 3
+#define AUDIO_DSP_SAMPLERATE 1 /* samplerate */
+#define AUDIO_DSP_CHANNELS 2 /* channels */
+#define AUDIO_DSP_SAMPLEBITS 3 /* sample bits width */
/* Supported Mixer Units controls */
#define AUDIO_MIXER_QUERY 0x0000
@@ -95,15 +71,13 @@
#define AUDIO_MIXER_LINE 0x0040
#define AUDIO_MIXER_DIGITAL 0x0080
#define AUDIO_MIXER_MIC 0x0100
+#define AUDIO_MIXER_VITURAL 0x0200
+#define AUDIO_MIXER_EXTEND 0x8000 /* extend mixer command */
-#define AUDIO_MIXER_EXTEND 0x8000 //extend mixer command
+#define AUDIO_VOLUME_MAX (100)
+#define AUDIO_VOLUME_MIN (0)
#define CFG_AUDIO_REPLAY_QUEUE_COUNT 4
-#define CFG_AUDIO_RECORD_PIPE_SIZE (8 * 1024)
-#define AUDIO_DEVICE_MP_CNT (4)
-#define AUDIO_DEVICE_DECODE_MP_BLOCK_SZ (4352 * 4)
-#define AUDIO_DEVICE_DECODE_MP_SZ ((AUDIO_DEVICE_DECODE_MP_BLOCK_SZ*2 + 4)*AUDIO_DEVICE_MP_CNT)
-
enum
{
@@ -115,19 +89,10 @@ enum
/* the preferred number and size of audio pipeline buffer for the audio device */
struct rt_audio_buf_info
{
- rt_uint32_t buffer_size; /* Preferred qty of buffers */
- rt_uint32_t buffer_count; /* Preferred size of the buffers */
-};
-struct rt_audio_buf_desc
-{
- rt_uint8_t *data_ptr;
- rt_size_t data_size;
-};
-
-struct rt_audio_frame
-{
- const void *data_ptr;
- rt_size_t data_size;
+ rt_uint8_t *buffer;
+ rt_uint16_t block_size;
+ rt_uint16_t block_count;
+ rt_uint32_t total_size;
};
struct rt_audio_device;
@@ -135,73 +100,68 @@ struct rt_audio_caps;
struct rt_audio_configure;
struct rt_audio_ops
{
- rt_err_t (*getcaps) (struct rt_audio_device *audio,struct rt_audio_caps *caps);
- rt_err_t (*configure) (struct rt_audio_device *audio,struct rt_audio_caps *caps);
-
- rt_err_t (*init) (struct rt_audio_device *audio);
- rt_err_t (*shutdown) (struct rt_audio_device *audio);
- rt_err_t (*start) (struct rt_audio_device *audio,int stream);
- rt_err_t (*stop) (struct rt_audio_device *audio,int stream);
- rt_err_t (*suspend) (struct rt_audio_device *audio,int stream);
- rt_err_t (*resume) (struct rt_audio_device *audio,int stream);
-
- rt_err_t (*control) (struct rt_audio_device *audio, int cmd, void *arg);
- rt_size_t (*transmit) (struct rt_audio_device *audio, const void *writeBuf,void *readBuf, rt_size_t size);
-
- //get page size of codec or private buffer's info
- void (*buffer_info) (struct rt_audio_device *audio,struct rt_audio_buf_info *info );
+ rt_err_t (*getcaps)(struct rt_audio_device *audio, struct rt_audio_caps *caps);
+ rt_err_t (*configure)(struct rt_audio_device *audio, struct rt_audio_caps *caps);
+ rt_err_t (*init)(struct rt_audio_device *audio);
+ rt_err_t (*start)(struct rt_audio_device *audio, int stream);
+ rt_err_t (*stop)(struct rt_audio_device *audio, int stream);
+ rt_size_t (*transmit)(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size);
+ /* get page size of codec or private buffer's info */
+ void (*buffer_info)(struct rt_audio_device *audio, struct rt_audio_buf_info *info);
};
-
struct rt_audio_configure
{
- rt_uint32_t channels;
-
- rt_uint32_t samplefmt;
rt_uint32_t samplerate;
- rt_uint32_t samplefmts;
+ rt_uint16_t channels;
+ rt_uint16_t samplebits;
};
struct rt_audio_caps
{
- int main_type;
- int sub_type;
+ int main_type;
+ int sub_type;
- union
- {
- rt_uint32_t mask;
- int value;
- struct rt_audio_configure config;
- }udata;
+ union
+ {
+ rt_uint32_t mask;
+ int value;
+ struct rt_audio_configure config;
+ } udata;
};
struct rt_audio_replay
{
- rt_bool_t activated;
+ struct rt_mempool *mp;
struct rt_data_queue queue;
+ struct rt_mutex lock;
+ struct rt_completion cmp;
+ struct rt_audio_buf_info buf_info;
+ rt_uint8_t *write_data;
+ rt_uint16_t write_index;
+ rt_uint16_t read_index;
+ rt_uint32_t pos;
+ rt_uint8_t event;
+ rt_bool_t activated;
};
struct rt_audio_record
{
+ struct rt_audio_pipe pipe;
rt_bool_t activated;
};
struct rt_audio_device
{
- struct rt_device parent;
+ struct rt_device parent;
struct rt_audio_ops *ops;
-
- struct rt_mempool mp;
-
struct rt_audio_replay *replay;
struct rt_audio_record *record;
};
-rt_err_t rt_audio_register (struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data);
-void rt_audio_tx_complete (struct rt_audio_device *audio,rt_uint8_t *pbuf);
-void rt_audio_rx_done (struct rt_audio_device *audio,rt_uint8_t *pbuf,rt_size_t len);
-rt_uint32_t rt_audio_format_to_bits (rt_uint32_t format);
-
+rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data);
+void rt_audio_tx_complete(struct rt_audio_device *audio);
+void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len);
/* Device Control Commands */
#define CODEC_CMD_RESET 0
diff --git a/components/drivers/include/drivers/can.h b/components/drivers/include/drivers/can.h
index c61fb19eaa..d4fcc845b4 100644
--- a/components/drivers/include/drivers/can.h
+++ b/components/drivers/include/drivers/can.h
@@ -221,7 +221,7 @@ struct rt_can_msg
rt_uint32_t rsv : 1;
rt_uint32_t len : 8;
rt_uint32_t priv : 8;
- rt_uint32_t hdr : 8;
+ rt_int32_t hdr : 8;
rt_uint32_t reserved : 8;
rt_uint8_t data[8];
};
@@ -252,7 +252,7 @@ struct rt_can_rx_fifo
#define RT_CAN_EVENT_RX_IND 0x01 /* Rx indication */
#define RT_CAN_EVENT_TX_DONE 0x02 /* Tx complete */
-#define RT_CAN_EVENT_TX_FAIL 0x03 /* Tx complete */
+#define RT_CAN_EVENT_TX_FAIL 0x03 /* Tx fail */
#define RT_CAN_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */
#define RT_CAN_EVENT_RXOF_IND 0x06 /* Rx overflow */
@@ -278,7 +278,7 @@ struct rt_can_ops
int (*recvmsg)(struct rt_can_device *can, void *buf, rt_uint32_t boxno);
};
-rt_err_t rt_hw_can_register(struct rt_can_device *can,
+rt_err_t rt_hw_can_register(struct rt_can_device *can,
const char *name,
const struct rt_can_ops *ops,
void *data);
diff --git a/components/drivers/include/drivers/crypto.h b/components/drivers/include/drivers/crypto.h
new file mode 100644
index 0000000000..5341d9ee48
--- /dev/null
+++ b/components/drivers/include/drivers/crypto.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-17 tyx the first version
+ */
+
+#ifndef __CRYPTO_H__
+#define __CRYPTO_H__
+
+#include <rtthread.h>
+#include <hwcrypto.h>
+#include <hw_symmetric.h>
+#include <hw_rng.h>
+#include <hw_hash.h>
+#include <hw_crc.h>
+#include <hw_gcm.h>
+#include <hw_bignum.h>
+
+#endif
diff --git a/components/drivers/include/drivers/dac.h b/components/drivers/include/drivers/dac.h
new file mode 100644
index 0000000000..b6043348dc
--- /dev/null
+++ b/components/drivers/include/drivers/dac.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-06-19 thread-liu the first version
+ */
+
+#ifndef __DAC_H__
+#define __DAC_H__
+#include <rtthread.h>
+
+struct rt_dac_device;
+struct rt_dac_ops
+{
+ rt_err_t (*disabled)(struct rt_dac_device *device, rt_uint32_t channel);
+ rt_err_t (*enabled)(struct rt_dac_device *device, rt_uint32_t channel);
+ rt_err_t (*convert)(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value);
+};
+
+struct rt_dac_device
+{
+ struct rt_device parent;
+ const struct rt_dac_ops *ops;
+};
+typedef struct rt_dac_device *rt_dac_device_t;
+
+typedef enum
+{
+ RT_DAC_CMD_ENABLE,
+ RT_DAC_CMD_DISABLE,
+} rt_dac_cmd_t;
+
+rt_err_t rt_hw_dac_register(rt_dac_device_t dac,const char *name, const struct rt_dac_ops *ops, const void *user_data);
+
+rt_uint32_t rt_dac_write(rt_dac_device_t dev, rt_uint32_t channel, rt_uint32_t value);
+rt_err_t rt_dac_enable(rt_dac_device_t dev, rt_uint32_t channel);
+rt_err_t rt_dac_disable(rt_dac_device_t dev, rt_uint32_t channel);
+
+#endif /* __dac_H__ */
diff --git a/components/drivers/include/drivers/i2c.h b/components/drivers/include/drivers/i2c.h
index e2a9e7d0b8..17d57288cd 100644
--- a/components/drivers/include/drivers/i2c.h
+++ b/components/drivers/include/drivers/i2c.h
@@ -60,11 +60,12 @@ struct rt_i2c_bus_device
void *priv;
};
-#ifdef RT_I2C_DEBUG
-#define i2c_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__)
-#else
-#define i2c_dbg(fmt, ...)
-#endif
+struct rt_i2c_client
+{
+ struct rt_device parent;
+ struct rt_i2c_bus_device *bus;
+ rt_uint16_t client_addr;
+};
rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
const char *bus_name);
diff --git a/components/drivers/include/drivers/mtd.h b/components/drivers/include/drivers/mtd.h
deleted file mode 100644
index fb7ea4389d..0000000000
--- a/components/drivers/include/drivers/mtd.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- 2018-09-10 heyuanjie87 first version
-
- */
-
-#ifndef __MTD_H__
-#define __MTD_H__
-
-#include <rtthread.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#define MTD_TYPE_NOR 1
-#define MTD_TYPE_NAND 2
-
- /**
- * MTD operation modes
- *
- * @MTD_OPM_PLACE_OOB: OOB data are placed at the given offset (default)
- * @MTD_OPM_AUTO_OOB: OOB data are automatically placed at the free areas
- * @MTD_OPM_RAW: data are transferred as-is, with no error correction;
- */
-enum mtd_opm
-{
- MTD_OPM_PLACE_OOB = 0,
- MTD_OPM_AUTO_OOB = 1,
- MTD_OPM_RAW = 2,
-};
-
-#ifndef loff_t
-typedef long loff_t;
-#endif
-
-struct mtd_oob_region
-{
- uint8_t offset;
- uint8_t length;
-};
-
-typedef struct mtd_info
-{
- struct rt_device parent;
-
- const struct mtd_ops *ops;
-
- uint16_t oob_size;
- uint16_t sector_size; /* Minimal writable flash unit size */
- uint32_t block_size:28; /* Erase size for the device */
- uint32_t type:4;
-
- size_t size; /* Total size of the MTD */
- loff_t offset; /* At which this MTD starts, from the beginning of the MEMORY */
- struct mtd_info *master;
-
- void *priv;
-}rt_mtd_t;
-
-struct mtd_io_desc
-{
- uint8_t mode; /* operation mode(enum mtd_opm) */
- uint8_t ooblen; /* number of oob bytes to write/read */
- uint8_t oobretlen; /* number of oob bytes written/read */
- uint8_t ooboffs; /* offset in the oob area */
- uint8_t *oobbuf;
-
- size_t datlen; /* number of data bytes to write/read */
- size_t datretlen; /* number of data bytes written/read */
- uint8_t *datbuf; /* if NULL only oob are read/written */
-};
-
-struct mtd_ops
-{
- int(*erase)(rt_mtd_t *mtd, loff_t addr, size_t len); /* return 0 if success */
- int(*read) (rt_mtd_t *mtd, loff_t from, struct mtd_io_desc *ops); /* return 0 if success */
- int(*write) (rt_mtd_t *mtd, loff_t to, struct mtd_io_desc *ops); /* return 0 if success */
- int(*isbad) (rt_mtd_t *mtd, uint32_t block); /* return 1 if bad, 0 not bad */
- int(*markbad) (rt_mtd_t *mtd, uint32_t block); /* return 0 if success */
-};
-
-struct mtd_part
-{
- const char *name; /* name of the MTD partion */
- loff_t offset; /* start addr of partion */
- size_t size; /* size of partion */
-};
-
-int rt_mtd_erase(rt_mtd_t *mtd, loff_t addr, size_t size);
-int rt_mtd_block_erase(rt_mtd_t *mtd, uint32_t block);
-int rt_mtd_read_oob(rt_mtd_t *mtd, loff_t from, struct mtd_io_desc *desc);
-int rt_mtd_write_oob(rt_mtd_t *mtd, loff_t to, struct mtd_io_desc *desc);
-int rt_mtd_read(rt_mtd_t *mtd, loff_t from, uint8_t *buf, size_t len);
-int rt_mtd_write(rt_mtd_t *mtd, loff_t to, const uint8_t *buf, size_t len);
-int rt_mtd_block_markbad(rt_mtd_t *mtd, uint32_t block);
-int rt_mtd_block_isbad(rt_mtd_t *mtd, uint32_t block);
-
-rt_mtd_t* rt_mtd_get(const char *name);
-int rt_mtd_register(rt_mtd_t *master, const struct mtd_part *parts, int np);
-
-#endif
diff --git a/components/drivers/include/drivers/mtd_nand.h b/components/drivers/include/drivers/mtd_nand.h
index 8afed000dd..f7675aede6 100644
--- a/components/drivers/include/drivers/mtd_nand.h
+++ b/components/drivers/include/drivers/mtd_nand.h
@@ -21,13 +21,13 @@
struct rt_mtd_nand_driver_ops;
#define RT_MTD_NAND_DEVICE(device) ((struct rt_mtd_nand_device*)(device))
-#define RT_MTD_EOK 0 /* NO error */
-#define RT_MTD_EECC 1 /* ECC error */
-#define RT_MTD_EBUSY 2 /* hardware busy */
-#define RT_MTD_EIO 3 /* generic IO issue */
-#define RT_MTD_ENOMEM 4 /* out of memory */
-#define RT_MTD_ESRC 5 /* source issue */
-#define RT_MTD_EECC_CORRECT 6 /* ECC error but correct */
+#define RT_MTD_EOK 0 /* NO error */
+#define RT_MTD_EECC 101 /* ECC error */
+#define RT_MTD_EBUSY 102 /* hardware busy */
+#define RT_MTD_EIO 103 /* generic IO issue */
+#define RT_MTD_ENOMEM 104 /* out of memory */
+#define RT_MTD_ESRC 105 /* source issue */
+#define RT_MTD_EECC_CORRECT 106 /* ECC error but correct */
struct rt_mtd_nand_device
{
@@ -41,77 +41,97 @@ struct rt_mtd_nand_device
rt_uint32_t pages_per_block; /* The number of page a block */
rt_uint16_t block_total;
+ /* Only be touched by driver */
rt_uint32_t block_start; /* The start of available block*/
rt_uint32_t block_end; /* The end of available block */
/* operations interface */
- const struct rt_mtd_nand_driver_ops* ops;
+ const struct rt_mtd_nand_driver_ops *ops;
};
struct rt_mtd_nand_driver_ops
{
- rt_err_t (*read_id) (struct rt_mtd_nand_device* device);
+ rt_err_t (*read_id)(struct rt_mtd_nand_device *device);
- rt_err_t (*read_page)(struct rt_mtd_nand_device* device,
+ rt_err_t (*read_page)(struct rt_mtd_nand_device *device,
rt_off_t page,
- rt_uint8_t* data, rt_uint32_t data_len,
- rt_uint8_t * spare, rt_uint32_t spare_len);
+ rt_uint8_t *data, rt_uint32_t data_len,
+ rt_uint8_t *spare, rt_uint32_t spare_len);
- rt_err_t (*write_page)(struct rt_mtd_nand_device * device,
+ rt_err_t (*write_page)(struct rt_mtd_nand_device *device,
rt_off_t page,
- const rt_uint8_t * data, rt_uint32_t data_len,
- const rt_uint8_t * spare, rt_uint32_t spare_len);
- rt_err_t (*move_page) (struct rt_mtd_nand_device *device, rt_off_t src_page, rt_off_t dst_page);
+ const rt_uint8_t *data, rt_uint32_t data_len,
+ const rt_uint8_t *spare, rt_uint32_t spare_len);
+ rt_err_t (*move_page)(struct rt_mtd_nand_device *device, rt_off_t src_page, rt_off_t dst_page);
- rt_err_t (*erase_block)(struct rt_mtd_nand_device* device, rt_uint32_t block);
- rt_err_t (*check_block)(struct rt_mtd_nand_device* device, rt_uint32_t block);
- rt_err_t (*mark_badblock)(struct rt_mtd_nand_device* device, rt_uint32_t block);
+ rt_err_t (*erase_block)(struct rt_mtd_nand_device *device, rt_uint32_t block);
+ rt_err_t (*check_block)(struct rt_mtd_nand_device *device, rt_uint32_t block);
+ rt_err_t (*mark_badblock)(struct rt_mtd_nand_device *device, rt_uint32_t block);
};
-rt_err_t rt_mtd_nand_register_device(const char* name, struct rt_mtd_nand_device* device);
+rt_err_t rt_mtd_nand_register_device(const char *name, struct rt_mtd_nand_device *device);
-rt_inline rt_uint32_t rt_mtd_nand_read_id(struct rt_mtd_nand_device* device)
+rt_inline rt_uint32_t rt_mtd_nand_read_id(struct rt_mtd_nand_device *device)
{
+ RT_ASSERT(device->ops->read_id);
return device->ops->read_id(device);
}
rt_inline rt_err_t rt_mtd_nand_read(
- struct rt_mtd_nand_device* device,
+ struct rt_mtd_nand_device *device,
rt_off_t page,
- rt_uint8_t* data, rt_uint32_t data_len,
- rt_uint8_t * spare, rt_uint32_t spare_len)
+ rt_uint8_t *data, rt_uint32_t data_len,
+ rt_uint8_t *spare, rt_uint32_t spare_len)
{
+ RT_ASSERT(device->ops->read_page);
return device->ops->read_page(device, page, data, data_len, spare, spare_len);
}
rt_inline rt_err_t rt_mtd_nand_write(
- struct rt_mtd_nand_device* device,
+ struct rt_mtd_nand_device *device,
rt_off_t page,
- const rt_uint8_t* data, rt_uint32_t data_len,
- const rt_uint8_t * spare, rt_uint32_t spare_len)
+ const rt_uint8_t *data, rt_uint32_t data_len,
+ const rt_uint8_t *spare, rt_uint32_t spare_len)
{
+ RT_ASSERT(device->ops->write_page);
return device->ops->write_page(device, page, data, data_len, spare, spare_len);
}
-rt_inline rt_err_t rt_mtd_nand_move_page(struct rt_mtd_nand_device* device,
- rt_off_t src_page, rt_off_t dst_page)
+rt_inline rt_err_t rt_mtd_nand_move_page(struct rt_mtd_nand_device *device,
+ rt_off_t src_page, rt_off_t dst_page)
{
+ RT_ASSERT(device->ops->move_page);
return device->ops->move_page(device, src_page, dst_page);
}
-rt_inline rt_err_t rt_mtd_nand_erase_block(struct rt_mtd_nand_device* device, rt_uint32_t block)
+rt_inline rt_err_t rt_mtd_nand_erase_block(struct rt_mtd_nand_device *device, rt_uint32_t block)
{
+ RT_ASSERT(device->ops->erase_block);
return device->ops->erase_block(device, block);
}
-rt_inline rt_err_t rt_mtd_nand_check_block(struct rt_mtd_nand_device* device, rt_uint32_t block)
+rt_inline rt_err_t rt_mtd_nand_check_block(struct rt_mtd_nand_device *device, rt_uint32_t block)
{
- return device->ops->check_block(device, block);
+ if (device->ops->check_block)
+ {
+ return device->ops->check_block(device, block);
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
}
-rt_inline rt_err_t rt_mtd_nand_mark_badblock(struct rt_mtd_nand_device* device, rt_uint32_t block)
+rt_inline rt_err_t rt_mtd_nand_mark_badblock(struct rt_mtd_nand_device *device, rt_uint32_t block)
{
- return device->ops->mark_badblock(device, block);
+ if (device->ops->mark_badblock)
+ {
+ return device->ops->mark_badblock(device, block);
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
}
#endif /* MTD_NAND_H_ */
diff --git a/components/drivers/include/drivers/mtdnand.h b/components/drivers/include/drivers/mtdnand.h
deleted file mode 100644
index 2e836cb2fb..0000000000
--- a/components/drivers/include/drivers/mtdnand.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- 2018-09-10 heyuanjie87 first version
-
- */
-
-#ifndef _MTDNAND_H_
-#define _MTDNAND_H_
-
-#include "mtd.h"
-
- /* Status bits */
-#define NAND_STATUS_FAIL 0x01
-#define NAND_STATUS_FAIL_N1 0x02
-#define NAND_STATUS_WP 0x80
-
-typedef enum
-{
- NAND_CMD_PAGE_RD, /* read data to chip's page buffer,do WaitBusy after this cmd in low driver */
- NAND_CMD_PAGE_WR0, /* write data to chip's page buffer */
- NAND_CMD_PAGE_WR1, /* do flash programe */
- NAND_CMD_BLK_ERASE, /* erase block */
- NAND_CMD_ECC_EN, /* enable gen HWECC */
- NAND_CMD_ECC_DIS /* disable gen HWECC */
-} nand_cmd_t;
-
-typedef enum
-{
- NAND_ECCM_NONE,
- NAND_ECCM_HW,
-} nand_eccmode_t;
-
-struct nand_chip;
-struct nand_ops;
-
-/**
-* struct nand_buffers - buffer structure for read/write
-* @ecccalc: buffer pointer for calculated ECC, size is oobsize.
-* @ecccode: buffer pointer for ECC read from flash, size is oobsize.
-*
-*/
-struct nand_buffers
-{
- uint8_t *ecccalc;
- uint8_t *ecccode;
-};
-
-struct nand_ecc
-{
- uint8_t mode; /* nand_eccmode_t */
- uint8_t bytes; /* gen ecc bytes per ecc step(usually 3) */
- uint16_t stepsize:12; /* min 256 */
- uint16_t _step:4; /* */
-
- /* driver must set the two interface if HWECC */
- void (*calculate)(struct nand_chip *chip, const uint8_t *dat, uint8_t *ecc_code);
- /* return max bit flips if can't correct,return -1 ECC is error(0 success) */
- int(*correct)(struct nand_chip *chip, uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc);
- /* ignore if NONECC */
- const struct mtd_oob_region *layout;
-};
-
-typedef struct nand_chip
-{
- rt_mtd_t parent;
-
- /* driver must init these */
- const struct nand_ops *ops;
- struct nand_ecc ecc;
- const struct mtd_oob_region *freelayout;
-
- /* driver do not touch */
- struct nand_buffers buffers;
- uint8_t *oob_poi;
- uint8_t *pagebuf;
- uint32_t size;
- uint16_t oobsize;
- uint8_t pages_pb;
- uint16_t page_size;
- int(*read_page)(struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
- int(*write_page)(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page);
-}rt_nand_t;
-
-struct nand_ops
-{
- int(*cmdfunc)(rt_nand_t *nand, int cmd, int page, int offset); /* send nand operation cmd, return Status bits(0 success),
- if nand is busy please wait in low driver */
- int(*read_buf)(rt_nand_t *nand, uint8_t *buf, int len); /* read data from nand chip's page buffer */
- int(*write_buf)(rt_nand_t *nand, const uint8_t *buf, int len);/* write data to nand chip's page buffer */
- int(*isbad)(rt_nand_t *nand, uint32_t blk); /* if NULL OOB[0] used as bad mark(not 0xff is bad) */
- int(*markbad)(rt_nand_t *nand, uint32_t blk); /* if NULL OOB[0] used as bad mark(set to 0x00) */
-};
-
-int rt_mtd_nand_init(rt_nand_t *nand, int blk_size, int page_size, int oob_size);
-
-#endif /* MTD_NAND_H_ */
diff --git a/components/drivers/include/drivers/mtdnor.h b/components/drivers/include/drivers/mtdnor.h
deleted file mode 100644
index ccb7466b4b..0000000000
--- a/components/drivers/include/drivers/mtdnor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- 2018-09-10 heyuanjie87 first version
-
- */
-
-#ifndef __MTDNOR_H__
-#define __MTDNOR_H__
-
-#include <drivers/mtd.h>
-
-struct nor_ops;
-
-typedef struct
-{
- rt_mtd_t parent;
-
- const struct nor_ops *ops; /* operations interface */
-}rt_nor_t;
-
-struct nor_ops
-{
- int (*erase)(rt_nor_t *nor, loff_t addr, size_t len); /* return success erased len or error code */
- int (*read)(rt_nor_t *nor, loff_t addr, uint8_t *buf, size_t len); /* return success data size or error code */
- int (*write)(rt_nor_t *nor, loff_t addr, const uint8_t *buf, size_t len); /* return success data size or error code */
-};
-
-int rt_mtd_nor_init(rt_nor_t *nor, int blksize);
-
-#endif
diff --git a/components/drivers/include/drivers/phy.h b/components/drivers/include/drivers/phy.h
new file mode 100644
index 0000000000..2d1ad9f91f
--- /dev/null
+++ b/components/drivers/include/drivers/phy.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-10-14 wangqiang the first version
+ */
+
+#ifndef __PHY_H__
+#define __PHY_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Defines the PHY link speed. This is align with the speed for MAC. */
+enum phy_speed
+{
+ PHY_SPEED_10M = 0U, /* PHY 10M speed. */
+ PHY_SPEED_100M /* PHY 100M speed. */
+};
+
+/* Defines the PHY link duplex. */
+enum phy_duplex
+{
+ PHY_HALF_DUPLEX = 0U, /* PHY half duplex. */
+ PHY_FULL_DUPLEX /* PHY full duplex. */
+};
+
+/*! @brief Defines the PHY loopback mode. */
+enum phy_loop
+{
+ PHY_LOCAL_LOOP = 0U, /* PHY local loopback. */
+ PHY_REMOTE_LOOP /* PHY remote loopback. */
+};
+
+
+struct rt_phy_msg
+{
+ rt_uint32_t reg;
+ rt_uint32_t value;
+};
+
+typedef struct rt_phy_msg rt_phy_msg_t;
+
+
+struct rt_phy_device
+{
+ struct rt_device parent;
+ struct rt_mdio_bus *bus;
+ rt_uint32_t addr;
+ struct rt_phy_ops *ops;
+};
+
+typedef struct rt_phy_device rt_phy_t;
+
+
+enum {
+ PHY_STATUS_OK = 0,
+ PHY_STATUS_FAIL,
+ PHY_STATUS_TIMEOUT,
+};
+
+typedef rt_int32_t rt_phy_status;
+
+struct rt_phy_ops
+{
+ rt_phy_status (*init)(void *object, rt_uint32_t phy_addr, rt_uint32_t src_clock_hz);
+ rt_phy_status (*read)(rt_uint32_t reg, rt_uint32_t *data);
+ rt_phy_status (*write)(rt_uint32_t reg, rt_uint32_t data);
+ rt_phy_status (*loopback)(rt_uint32_t mode, rt_uint32_t speed, rt_bool_t enable);
+ rt_phy_status (*get_link_status)(rt_bool_t *status);
+ rt_phy_status (*get_link_speed_duplex)(rt_uint32_t *speed, rt_uint32_t *duplex);
+};
+
+rt_err_t rt_hw_phy_register(struct rt_phy_device *phy, const char *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PHY_H__*/
diff --git a/components/drivers/include/drivers/phy_mdio.h b/components/drivers/include/drivers/phy_mdio.h
new file mode 100644
index 0000000000..d978ec2984
--- /dev/null
+++ b/components/drivers/include/drivers/phy_mdio.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-10-14 wangqiang the first version
+ */
+
+#ifndef __MDIO_H__
+#define __MDIO_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+struct rt_mdio_bus_ops
+{
+ rt_bool_t (*init)(void *bus, rt_uint32_t src_clock_hz);
+ rt_size_t (*read)(void *bus, rt_uint32_t addr, rt_uint32_t reg, void *data, rt_uint32_t size);
+ rt_size_t (*write)(void *bus, rt_uint32_t addr, rt_uint32_t reg, void *data, rt_uint32_t size);
+ rt_bool_t (*uninit)(void *bus);
+};
+
+struct rt_mdio_bus
+{
+ void *hw_obj;
+ char *name;
+ struct rt_mdio_bus_ops *ops;
+};
+
+typedef struct rt_mdio_bus rt_mdio_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/include/drivers/pin.h b/components/drivers/include/drivers/pin.h
index ca35407932..f5b2ded9f6 100644
--- a/components/drivers/include/drivers/pin.h
+++ b/components/drivers/include/drivers/pin.h
@@ -74,10 +74,13 @@ struct rt_pin_ops
rt_uint32_t mode, void (*hdr)(void *args), void *args);
rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_int32_t pin);
rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled);
+ rt_base_t (*pin_get)(const char *name);
};
int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data);
+/* Get pin number by name,such as PA.0,P0.12 */
+rt_base_t rt_pin_get(const char *name);
void rt_pin_mode(rt_base_t pin, rt_base_t mode);
void rt_pin_write(rt_base_t pin, rt_base_t value);
int rt_pin_read(rt_base_t pin);
diff --git a/components/drivers/include/drivers/pm.h b/components/drivers/include/drivers/pm.h
index 94d4c8559b..dd5875aa1d 100644
--- a/components/drivers/include/drivers/pm.h
+++ b/components/drivers/include/drivers/pm.h
@@ -7,6 +7,7 @@
* Date Author Notes
* 2012-06-02 Bernard the first version
* 2018-08-02 Tanek split run and sleep modes, support custom mode
+ * 2019-04-28 Zero-Free improve PM mode and device ops interface
*/
#ifndef __PM_H__
@@ -16,96 +17,67 @@
#ifndef PM_HAS_CUSTOM_CONFIG
-/* All modes used for rt_pm_request() adn rt_pm_release() */
+/* All modes used for rt_pm_request() and rt_pm_release() */
enum
{
- /* run modes */
- PM_RUN_MODE_NORMAL = 0,
-
/* sleep modes */
- PM_SLEEP_MODE_SLEEP,
- PM_SLEEP_MODE_TIMER,
+ PM_SLEEP_MODE_NONE = 0,
+ PM_SLEEP_MODE_IDLE,
+ PM_SLEEP_MODE_LIGHT,
+ PM_SLEEP_MODE_DEEP,
+ PM_SLEEP_MODE_STANDBY,
PM_SLEEP_MODE_SHUTDOWN,
+ PM_SLEEP_MODE_MAX,
+};
+
+enum
+{
+ /* run modes*/
+ PM_RUN_MODE_HIGH_SPEED = 0,
+ PM_RUN_MODE_NORMAL_SPEED,
+ PM_RUN_MODE_MEDIUM_SPEED,
+ PM_RUN_MODE_LOW_SPEED,
+ PM_RUN_MODE_MAX,
+};
+
+enum
+{
+ RT_PM_FREQUENCY_PENDING = 0x01,
};
+#define RT_PM_DEFAULT_SLEEP_MODE PM_SLEEP_MODE_IDLE
+#define RT_PM_DEFAULT_RUN_MODE PM_RUN_MODE_NORMAL_SPEED
+
/* The name of all modes used in the msh command "pm_dump" */
-#define PM_MODE_NAMES \
+#define PM_SLEEP_MODE_NAMES \
{ \
- "Running Mode", \
- \
- "Sleep Mode", \
- "Timer Mode", \
+ "None Mode", \
+ "Idle Mode", \
+ "LightSleep Mode", \
+ "DeepSleep Mode", \
+ "Standby Mode", \
"Shutdown Mode", \
}
-/* run mode count : 1 */
-#define PM_RUN_MODE_COUNT 1
-/* sleep mode count : 3 */
-#define PM_SLEEP_MODE_COUNT 3
-
-/* support redefining default run mode */
-#ifndef PM_RUN_MODE_DEFAULT
-#define PM_RUN_MODE_DEFAULT 0
-#endif
-
-/* support redefining default sleep mode */
-#ifndef PM_SLEEP_MODE_DEFAULT
-#define PM_SLEEP_MODE_DEFAULT (PM_SLEEP_MODE_START)
-#endif
-
-/* support redefining the minimum tick into sleep mode */
-#ifndef PM_MIN_ENTER_SLEEP_TICK
-#define PM_MIN_ENTER_SLEEP_TICK (1)
-#endif
+#define PM_RUN_MODE_NAMES \
+{ \
+ "High Speed", \
+ "Normal Speed", \
+ "Medium Speed", \
+ "Low Mode", \
+}
#else /* PM_HAS_CUSTOM_CONFIG */
#include <pm_cfg.h>
-#ifndef PM_RUN_MODE_COUNT
-#error "You must defined PM_RUN_MODE_COUNT on pm_cfg.h"
-#endif
-
-#ifndef PM_SLEEP_MODE_COUNT
-#error "You must defined PM_SLEEP_MODE_COUNT on pm_cfg.h"
-#endif
-
-#ifndef PM_MODE_DEFAULT
-#error "You must defined PM_MODE_DEFAULT on pm_cfg.h"
-#endif
-
-#ifndef PM_MODE_NAMES
-#error "You must defined PM_MODE_NAMES on pm_cfg.h"
-#endif
-
-#ifndef PM_RUN_MODE_DEFAULT
-#error "You must defined PM_RUN_MODE_DEFAULT on pm_cfg.h"
-#endif
-
-/* The default sleep mode(PM_SLEEP_MODE_DEFAULT) are not required.
- * If the default mode is defined, it is requested once in rt_system_pm_init()
- */
-
#endif /* PM_HAS_CUSTOM_CONFIG */
-/* run mode must start at 0 */
-#define PM_RUN_MODE_START 0
-/* the values of the run modes and sleep mode must be consecutive */
-#define PM_SLEEP_MODE_START PM_RUN_MODE_COUNT
-/* all mode count */
-#define PM_MODE_COUNT (PM_RUN_MODE_COUNT + PM_SLEEP_MODE_COUNT)
-/* The last mode, will be request in rt_system_pm_init() */
-#define PM_MODE_MAX (PM_RUN_MODE_COUNT + PM_SLEEP_MODE_COUNT - 1)
-
-#if PM_MODE_COUNT > 32
-#error "The number of modes cannot exceed 32"
-#endif
-
/**
* device control flag to request or release power
*/
#define RT_PM_DEVICE_CTRL_REQUEST 0x01
-#define RT_PM_DEVICE_CTRL_RELEASE 0x02
+#define RT_PM_DEVICE_CTRL_RELEASE 0x00
struct rt_pm;
@@ -114,13 +86,8 @@ struct rt_pm;
*/
struct rt_pm_ops
{
- void (*enter)(struct rt_pm *pm);
- void (*exit)(struct rt_pm *pm);
-
-#if PM_RUN_MODE_COUNT > 1
- void (*frequency_change)(struct rt_pm *pm, rt_uint32_t frequency);
-#endif
-
+ void (*sleep)(struct rt_pm *pm, rt_uint8_t mode);
+ void (*run)(struct rt_pm *pm, rt_uint8_t mode);
void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout);
void (*timer_stop)(struct rt_pm *pm);
rt_tick_t (*timer_get_tick)(struct rt_pm *pm);
@@ -128,18 +95,15 @@ struct rt_pm_ops
struct rt_device_pm_ops
{
-#if PM_RUN_MODE_COUNT > 1
- void (*frequency_change)(const struct rt_device* device);
-#endif
-
- void (*suspend)(const struct rt_device* device);
- void (*resume) (const struct rt_device* device);
+ int (*suspend)(const struct rt_device *device, rt_uint8_t mode);
+ void (*resume)(const struct rt_device *device, rt_uint8_t mode);
+ int (*frequency_change)(const struct rt_device *device, rt_uint8_t mode);
};
struct rt_device_pm
{
- const struct rt_device* device;
- const struct rt_device_pm_ops* ops;
+ const struct rt_device *device;
+ const struct rt_device_pm_ops *ops;
};
/**
@@ -150,32 +114,45 @@ struct rt_pm
struct rt_device parent;
/* modes */
- rt_uint8_t modes[PM_MODE_COUNT];
- rt_uint8_t current_mode; /* current pm mode */
- rt_uint8_t exit_count;
+ rt_uint8_t modes[PM_SLEEP_MODE_MAX];
+ rt_uint8_t sleep_mode; /* current sleep mode */
+ rt_uint8_t run_mode; /* current running mode */
/* the list of device, which has PM feature */
rt_uint8_t device_pm_number;
- struct rt_device_pm* device_pm;
- struct rt_semaphore device_lock;
+ struct rt_device_pm *device_pm;
/* if the mode has timer, the corresponding bit is 1*/
- rt_uint32_t timer_mask;
+ rt_uint8_t timer_mask;
+ rt_uint8_t flags;
const struct rt_pm_ops *ops;
};
-void rt_pm_enter(void);
-void rt_pm_exit(void);
+enum
+{
+ RT_PM_ENTER_SLEEP = 0,
+ RT_PM_EXIT_SLEEP,
+};
+
+struct rt_pm_notify
+{
+ void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data);
+ void *data;
+};
+
+void rt_pm_request(rt_uint8_t sleep_mode);
+void rt_pm_release(rt_uint8_t sleep_mode);
+int rt_pm_run_enter(rt_uint8_t run_mode);
-void rt_pm_request(rt_ubase_t mode);
-void rt_pm_release(rt_ubase_t mode);
+void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops);
+void rt_pm_device_unregister(struct rt_device *device);
-void rt_pm_register_device(struct rt_device* device, const struct rt_device_pm_ops* ops);
-void rt_pm_unregister_device(struct rt_device* device);
+void rt_pm_notify_set(void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data), void *data);
+void rt_pm_default_set(rt_uint8_t sleep_mode);
void rt_system_pm_init(const struct rt_pm_ops *ops,
rt_uint8_t timer_mask,
- void *user_data);
+ void *user_data);
#endif /* __PM_H__ */
diff --git a/components/drivers/include/drivers/pulse_encoder.h b/components/drivers/include/drivers/pulse_encoder.h
new file mode 100644
index 0000000000..0c7df04cd6
--- /dev/null
+++ b/components/drivers/include/drivers/pulse_encoder.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-08-08 balanceTWK the first version
+ */
+
+#ifndef __PULSE_ENCODER_H__
+#define __PULSE_ENCODER_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* pulse_encoder control command */
+#define PULSE_ENCODER_CMD_GET_TYPE (128 + 0) /* get a pulse_encoder type information */
+#define PULSE_ENCODER_CMD_ENABLE (128 + 1) /* enable pulse_encoder */
+#define PULSE_ENCODER_CMD_DISABLE (128 + 2) /* disable pulse_encoder */
+#define PULSE_ENCODER_CMD_CLEAR_COUNT (128 + 3) /* clear pulse_encoder count */
+
+/* pulse_encoder type */
+enum rt_pulse_encoder_type
+{
+ UNKNOWN_PULSE_ENCODER_TYPE = 0x00, /* Unknown pulse_encoder type */
+ SINGLE_PHASE_PULSE_ENCODER, /* single phase pulse_encoder */
+ AB_PHASE_PULSE_ENCODER /* two phase pulse_encoder */
+};
+
+struct rt_pulse_encoder_device;
+
+struct rt_pulse_encoder_ops
+{
+ rt_err_t (*init)(struct rt_pulse_encoder_device *pulse_encoder);
+ rt_int32_t (*get_count)(struct rt_pulse_encoder_device *pulse_encoder);
+ rt_err_t (*clear_count)(struct rt_pulse_encoder_device *pulse_encoder);
+ rt_err_t (*control)(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args);
+};
+
+struct rt_pulse_encoder_device
+{
+ struct rt_device parent;
+ const struct rt_pulse_encoder_ops *ops;
+ enum rt_pulse_encoder_type type;
+};
+
+rt_err_t rt_device_pulse_encoder_register(struct rt_pulse_encoder_device *pulse_encoder, const char *name, void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PULSE_ENCODER_H__ */
diff --git a/components/drivers/include/drivers/rt_inputcapture.h b/components/drivers/include/drivers/rt_inputcapture.h
new file mode 100644
index 0000000000..40cd55883d
--- /dev/null
+++ b/components/drivers/include/drivers/rt_inputcapture.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-08-13 balanceTWK first version.
+ */
+
+#ifndef __RT_INPUT_CAPTURE_H__
+#define __RT_INPUT_CAPTURE_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* capture control command */
+#define INPUTCAPTURE_CMD_CLEAR_BUF (128 + 0) /* clear capture buf */
+#define INPUTCAPTURE_CMD_SET_WATERMARK (128 + 1) /* Set the callback threshold */
+
+struct rt_inputcapture_data
+{
+ rt_uint32_t pulsewidth_us;
+ rt_bool_t is_high;
+};
+
+struct rt_inputcapture_device
+{
+ struct rt_device parent;
+
+ const struct rt_inputcapture_ops *ops;
+ struct rt_ringbuffer *ringbuff;
+ rt_size_t watermark;
+};
+
+/**
+ * capture operators
+ */
+struct rt_inputcapture_ops
+{
+ rt_err_t (*init)(struct rt_inputcapture_device *inputcapture);
+ rt_err_t (*open)(struct rt_inputcapture_device *inputcapture);
+ rt_err_t (*close)(struct rt_inputcapture_device *inputcapture);
+ rt_err_t (*get_pulsewidth)(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us);
+};
+
+void rt_hw_inputcapture_isr(struct rt_inputcapture_device *inputcapture, rt_bool_t level);
+
+rt_err_t rt_device_inputcapture_register(struct rt_inputcapture_device *inputcapture,
+ const char *name,
+ void *data);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RT_INPUT_CAPTURE_H__ */
diff --git a/components/drivers/include/drivers/spi.h b/components/drivers/include/drivers/spi.h
index 04a65421a5..d92518cd94 100644
--- a/components/drivers/include/drivers/spi.h
+++ b/components/drivers/include/drivers/spi.h
@@ -1,11 +1,12 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-11-23 Bernard Add extern "C"
+ * 2020-06-13 armink fix the 3 wires issue
*/
#ifndef __SPI_H__
@@ -18,8 +19,6 @@
extern "C"{
#endif
-#define RT_SPI_CPHA (1<<0) /* bit[0]:CPHA, clock phase */
-#define RT_SPI_CPOL (1<<1) /* bit[1]:CPOL, clock polarity */
/**
* At CPOL=0 the base value of the clock is zero
* - For CPHA=0, data are captured on the clock's rising edge (low->high transition)
@@ -32,26 +31,29 @@ extern "C"{
* - For CPHA=1, data are captured on clock's rising edge and data are propagated
* on a falling edge.
*/
+#define RT_SPI_CPHA (1<<0) /* bit[0]:CPHA, clock phase */
+#define RT_SPI_CPOL (1<<1) /* bit[1]:CPOL, clock polarity */
+
#define RT_SPI_LSB (0<<2) /* bit[2]: 0-LSB */
#define RT_SPI_MSB (1<<2) /* bit[2]: 1-MSB */
#define RT_SPI_MASTER (0<<3) /* SPI master device */
#define RT_SPI_SLAVE (1<<3) /* SPI slave device */
+#define RT_SPI_CS_HIGH (1<<4) /* Chipselect active high */
+#define RT_SPI_NO_CS (1<<5) /* No chipselect */
+#define RT_SPI_3WIRE (1<<6) /* SI/SO pin shared */
+#define RT_SPI_READY (1<<7) /* Slave pulls low to pause */
+
+#define RT_SPI_MODE_MASK (RT_SPI_CPHA | RT_SPI_CPOL | RT_SPI_MSB | RT_SPI_SLAVE | RT_SPI_CS_HIGH | RT_SPI_NO_CS | RT_SPI_3WIRE | RT_SPI_READY)
+
#define RT_SPI_MODE_0 (0 | 0) /* CPOL = 0, CPHA = 0 */
#define RT_SPI_MODE_1 (0 | RT_SPI_CPHA) /* CPOL = 0, CPHA = 1 */
#define RT_SPI_MODE_2 (RT_SPI_CPOL | 0) /* CPOL = 1, CPHA = 0 */
#define RT_SPI_MODE_3 (RT_SPI_CPOL | RT_SPI_CPHA) /* CPOL = 1, CPHA = 1 */
-#define RT_SPI_MODE_MASK (RT_SPI_CPHA | RT_SPI_CPOL | RT_SPI_MSB)
-
-#define RT_SPI_BUS_MODE_SPI (1<<0)
-#define RT_SPI_BUS_MODE_QSPI (1<<1)
-
-#define RT_SPI_CS_HIGH (1<<4) /* Chipselect active high */
-#define RT_SPI_NO_CS (1<<5) /* No chipselect */
-#define RT_SPI_3WIRE (1<<6) /* SI/SO pin shared */
-#define RT_SPI_READY (1<<7) /* Slave pulls low to pause */
+#define RT_SPI_BUS_MODE_SPI (1<<0)
+#define RT_SPI_BUS_MODE_QSPI (1<<1)
/**
* SPI message structure
diff --git a/components/drivers/include/drivers/usb_common.h b/components/drivers/include/drivers/usb_common.h
index c26d83391e..4d85a85e35 100644
--- a/components/drivers/include/drivers/usb_common.h
+++ b/components/drivers/include/drivers/usb_common.h
@@ -435,15 +435,15 @@ typedef struct usb_os_proerty * usb_os_proerty_t;
// 5 A big-endian 32-bit integer (REG_DWORD_BIG_ENDIAN)
// 6 A NULL-terminated Unicode string that contains a symbolic link (REG_LINK)
// 7 Multiple NULL-terminated Unicode strings (REG_MULTI_SZ)
-#define USB_OS_PROERTY_TYPE_REG_SZ 0x01UL
-#define USB_OS_PROERTY_TYPE_REG_EXPAND_SZ 0x02UL
-#define USB_OS_PROERTY_TYPE_REG_BINARY 0x03UL
-#define USB_OS_PROERTY_TYPE_REG_DWORD_LITTLE_ENDIAN 0x04UL
-#define USB_OS_PROERTY_TYPE_REG_DWORD_BIG_ENDIAN 0x05UL
-#define USB_OS_PROERTY_TYPE_REG_LINK 0x06UL
-#define USB_OS_PROERTY_TYPE_REG_MULTI_SZ 0x07UL
+#define USB_OS_PROPERTY_TYPE_REG_SZ 0x01UL
+#define USB_OS_PROPERTY_TYPE_REG_EXPAND_SZ 0x02UL
+#define USB_OS_PROPERTY_TYPE_REG_BINARY 0x03UL
+#define USB_OS_PROPERTY_TYPE_REG_DWORD_LITTLE_ENDIAN 0x04UL
+#define USB_OS_PROPERTY_TYPE_REG_DWORD_BIG_ENDIAN 0x05UL
+#define USB_OS_PROPERTY_TYPE_REG_LINK 0x06UL
+#define USB_OS_PROPERTY_TYPE_REG_MULTI_SZ 0x07UL
-#define USB_OS_PROERTY_DESC(PropertyDataType,PropertyName,PropertyData) \
+#define USB_OS_PROPERTY_DESC(PropertyDataType,PropertyName,PropertyData) \
{\
.dwSize = sizeof(struct usb_os_proerty)-sizeof(const char *)*2\
+sizeof(PropertyName)*2+sizeof(PropertyData)*2,\
diff --git a/components/drivers/include/ipc/dataqueue.h b/components/drivers/include/ipc/dataqueue.h
index f584c267bf..0262f4702b 100644
--- a/components/drivers/include/ipc/dataqueue.h
+++ b/components/drivers/include/ipc/dataqueue.h
@@ -17,17 +17,19 @@
#define RT_DATAQUEUE_EVENT_LWM 0x03
struct rt_data_item;
-#define RT_DATAQUEUE_SIZE(dq) ((dq)->put_index - (dq)->get_index)
-#define RT_DATAQUEUE_EMPTY(dq) ((dq)->size - RT_DATAQUEUE_SIZE(dq))
+
/* data queue implementation */
struct rt_data_queue
{
+ rt_uint32_t magic;
+
rt_uint16_t size;
rt_uint16_t lwm;
- rt_bool_t waiting_lwm;
- rt_uint16_t get_index;
- rt_uint16_t put_index;
+ rt_uint16_t get_index : 15;
+ rt_uint16_t is_empty : 1;
+ rt_uint16_t put_index : 15;
+ rt_uint16_t is_full : 1;
struct rt_data_item *queue;
@@ -57,5 +59,7 @@ rt_err_t rt_data_queue_peak(struct rt_data_queue *queue,
const void **data_ptr,
rt_size_t *size);
void rt_data_queue_reset(struct rt_data_queue *queue);
+rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue);
+rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue);
#endif
diff --git a/components/drivers/include/ipc/pipe.h b/components/drivers/include/ipc/pipe.h
index 25b19f540d..93ba95cd2c 100644
--- a/components/drivers/include/ipc/pipe.h
+++ b/components/drivers/include/ipc/pipe.h
@@ -24,6 +24,7 @@
struct rt_pipe_device
{
struct rt_device parent;
+ rt_bool_t is_named;
/* ring buffer in pipe device */
struct rt_ringbuffer *fifo;
diff --git a/components/drivers/include/ipc/workqueue.h b/components/drivers/include/ipc/workqueue.h
index 9e23e181b1..23e256c420 100644
--- a/components/drivers/include/ipc/workqueue.h
+++ b/components/drivers/include/ipc/workqueue.h
@@ -11,13 +11,27 @@
#include <rtthread.h>
+enum
+{
+ RT_WORK_STATE_PENDING = 0x0001, /* Work item pending state */
+ RT_WORK_STATE_SUBMITTING = 0x0002, /* Work item submitting state */
+};
+
+/**
+ * work type defitions
+ */
+enum
+{
+ RT_WORK_TYPE_DELAYED = 0x0001,
+};
+
/* workqueue implementation */
struct rt_workqueue
{
rt_list_t work_list;
struct rt_work *work_current; /* current work */
- struct rt_semaphore sem;
+ struct rt_semaphore sem;
rt_thread_t work_thread;
};
@@ -25,28 +39,50 @@ struct rt_work
{
rt_list_t list;
- void (*work_func)(struct rt_work* work, void* work_data);
+ void (*work_func)(struct rt_work *work, void *work_data);
void *work_data;
+ rt_uint16_t flags;
+ rt_uint16_t type;
+ struct rt_timer timer;
+ struct rt_workqueue *workqueue;
+};
+
+struct rt_delayed_work
+{
+ struct rt_work work;
};
#ifdef RT_USING_HEAP
/**
* WorkQueue for DeviceDriver
*/
-struct rt_workqueue *rt_workqueue_create(const char* name, rt_uint16_t stack_size, rt_uint8_t priority);
-rt_err_t rt_workqueue_destroy(struct rt_workqueue* queue);
-rt_err_t rt_workqueue_dowork(struct rt_workqueue* queue, struct rt_work* work);
-rt_err_t rt_workqueue_cancel_work(struct rt_workqueue* queue, struct rt_work* work);
-rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue* queue, struct rt_work* work);
+struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_size, rt_uint8_t priority);
+rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue);
+rt_err_t rt_workqueue_dowork(struct rt_workqueue *queue, struct rt_work *work);
+rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work, rt_tick_t time);
+rt_err_t rt_workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work);
+rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue *queue, struct rt_work *work);
+
+#ifdef RT_USING_SYSTEM_WORKQUEUE
+rt_err_t rt_work_submit(struct rt_work *work, rt_tick_t time);
+rt_err_t rt_work_cancel(struct rt_work *work);
+#endif
-rt_inline void rt_work_init(struct rt_work* work, void (*work_func)(struct rt_work* work, void* work_data),
- void* work_data)
+rt_inline void rt_work_init(struct rt_work *work, void (*work_func)(struct rt_work *work, void *work_data),
+ void *work_data)
{
rt_list_init(&(work->list));
work->work_func = work_func;
work->work_data = work_data;
+ work->workqueue = RT_NULL;
+ work->flags = 0;
+ work->type = 0;
}
-#endif
+void rt_delayed_work_init(struct rt_delayed_work *work, void (*work_func)(struct rt_work *work,
+ void *work_data), void *work_data);
+
+int rt_work_sys_workqueue_init(void);
#endif
+#endif
diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h
index d59b40cc47..f0fa2f5b4a 100644
--- a/components/drivers/include/rtdevice.h
+++ b/components/drivers/include/rtdevice.h
@@ -69,6 +69,11 @@ extern "C" {
#endif /* RT_USING_I2C_BITOPS */
#endif /* RT_USING_I2C */
+#ifdef RT_USING_PHY
+#include "drivers/phy.h"
+#include "drivers/phy_mdio.h"
+#endif /* RT_USING_PHY */
+
#ifdef RT_USING_SDIO
#include "drivers/mmcsd_core.h"
#include "drivers/sd.h"
@@ -103,6 +108,10 @@ extern "C" {
#include "drivers/adc.h"
#endif
+#ifdef RT_USING_DAC
+#include "drivers/dac.h"
+#endif
+
#ifdef RT_USING_PWM
#include "drivers/rt_drv_pwm.h"
#endif
@@ -122,6 +131,18 @@ extern "C" {
#include "drivers/mtdnand.h"
#endif
+#ifdef RT_USING_HWCRYPTO
+#include "drivers/crypto.h"
+#endif
+
+#ifdef RT_USING_PULSE_ENCODER
+#include "drivers/pulse_encoder.h"
+#endif
+
+#ifdef RT_USING_INPUT_CAPTURE
+#include "drivers/rt_inputcapture.h"
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/components/drivers/misc/SConscript b/components/drivers/misc/SConscript
index c45ba524c5..72058eeeca 100644
--- a/components/drivers/misc/SConscript
+++ b/components/drivers/misc/SConscript
@@ -11,8 +11,17 @@ if GetDepend(['RT_USING_PIN']):
if GetDepend(['RT_USING_ADC']):
src = src + ['adc.c']
+if GetDepend(['RT_USING_DAC']):
+ src = src + ['dac.c']
+
if GetDepend(['RT_USING_PWM']):
src = src + ['rt_drv_pwm.c']
+
+if GetDepend(['RT_USING_PULSE_ENCODER']):
+ src = src + ['pulse_encoder.c']
+
+if GetDepend(['RT_USING_INPUT_CAPTURE']):
+ src = src + ['rt_inputcapture.c']
if len(src):
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
diff --git a/components/drivers/misc/adc.c b/components/drivers/misc/adc.c
index 83e789a6e4..2d26beb243 100644
--- a/components/drivers/misc/adc.c
+++ b/components/drivers/misc/adc.c
@@ -15,10 +15,8 @@
#include <string.h>
#include <stdlib.h>
-#define DBG_ENABLE
-#define DBG_SECTION_NAME "adc"
-#define DBG_LEVEL DBG_INFO
-#define DBG_COLOR
+#define DBG_TAG "adc"
+#define DBG_LVL DBG_INFO
#include <rtdbg.h>
static rt_size_t _adc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
@@ -62,19 +60,37 @@ static rt_err_t _adc_control(rt_device_t dev, int cmd, void *args)
return result;
}
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops adc_ops =
+{
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ _adc_read,
+ RT_NULL,
+ _adc_control,
+};
+#endif
+
rt_err_t rt_hw_adc_register(rt_adc_device_t device, const char *name, const struct rt_adc_ops *ops, const void *user_data)
{
rt_err_t result = RT_EOK;
RT_ASSERT(ops != RT_NULL && ops->convert != RT_NULL);
device->parent.type = RT_Device_Class_Miscellaneous;
- device->parent.init = RT_NULL;
- device->parent.open = RT_NULL;
- device->parent.close = RT_NULL;
- device->parent.read = _adc_read;
- device->parent.write = RT_NULL;
- device->parent.control = _adc_control;
+ device->parent.rx_indicate = RT_NULL;
+ device->parent.tx_complete = RT_NULL;
+#ifdef RT_USING_DEVICE_OPS
+ device->parent.ops = &adc_ops;
+#else
+ device->parent.init = RT_NULL;
+ device->parent.open = RT_NULL;
+ device->parent.close = RT_NULL;
+ device->parent.read = _adc_read;
+ device->parent.write = RT_NULL;
+ device->parent.control = _adc_control;
+#endif
device->ops = ops;
device->parent.user_data = (void *)user_data;
diff --git a/components/drivers/misc/dac.c b/components/drivers/misc/dac.c
new file mode 100644
index 0000000000..336c78d018
--- /dev/null
+++ b/components/drivers/misc/dac.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-06-19 thread-liu the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#define DBG_TAG "dac"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+static rt_size_t _dac_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ rt_err_t result = RT_EOK;
+ rt_size_t i;
+ struct rt_dac_device *dac = (struct rt_dac_device *)dev;
+ rt_uint32_t *value = (rt_uint32_t *)buffer;
+
+ for (i = 0; i < size; i += sizeof(int))
+ {
+ result = dac->ops->convert(dac, pos + i, value);
+ if (result != RT_EOK)
+ {
+ return 0;
+ }
+ value++;
+ }
+
+ return i;
+}
+
+static rt_err_t _dac_control(rt_device_t dev, int cmd, void *args)
+{
+ rt_err_t result = RT_EOK;
+ rt_dac_device_t dac = (struct rt_dac_device *)dev;
+
+ if (dac->ops->enabled == RT_NULL)
+ {
+ return -RT_ENOSYS;
+ }
+ if (cmd == RT_DAC_CMD_ENABLE)
+ {
+ result = dac->ops->enabled(dac, (rt_uint32_t)args);
+ }
+ else if (cmd == RT_DAC_CMD_DISABLE)
+ {
+ result = dac->ops->disabled(dac, (rt_uint32_t)args);
+ }
+
+ return result;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops dac_ops =
+{
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ _dac_write,
+ _dac_control,
+};
+#endif
+
+rt_err_t rt_hw_dac_register(rt_dac_device_t device, const char *name, const struct rt_dac_ops *ops, const void *user_data)
+{
+ rt_err_t result = RT_EOK;
+ RT_ASSERT(ops != RT_NULL && ops->convert != RT_NULL);
+
+ device->parent.type = RT_Device_Class_Miscellaneous;
+ device->parent.rx_indicate = RT_NULL;
+ device->parent.tx_complete = RT_NULL;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->parent.ops = &dac_ops;
+#else
+ device->parent.init = RT_NULL;
+ device->parent.open = RT_NULL;
+ device->parent.close = RT_NULL;
+ device->parent.read = RT_NULL;
+ device->parent.write = _dac_write;
+ device->parent.control = _dac_control;
+#endif
+ device->ops = ops;
+ device->parent.user_data = (void *)user_data;
+
+ result = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR);
+
+ return result;
+}
+
+rt_uint32_t rt_dac_write(rt_dac_device_t dev, rt_uint32_t channel, rt_uint32_t value)
+{
+ RT_ASSERT(dev);
+
+ dev->ops->convert(dev, channel, &value);
+
+ return RT_EOK;
+}
+
+rt_err_t rt_dac_enable(rt_dac_device_t dev, rt_uint32_t channel)
+{
+ rt_err_t result = RT_EOK;
+
+ RT_ASSERT(dev);
+ if (dev->ops->enabled != RT_NULL)
+ {
+ result = dev->ops->enabled(dev, channel);
+ }
+ else
+ {
+ result = -RT_ENOSYS;
+ }
+
+ return result;
+}
+
+rt_err_t rt_dac_disabled(rt_dac_device_t dev, rt_uint32_t channel)
+{
+ rt_err_t result = RT_EOK;
+
+ RT_ASSERT(dev);
+ if (dev->ops->disabled != RT_NULL)
+ {
+ result = dev->ops->disabled(dev, channel);
+ }
+ else
+ {
+ result = -RT_ENOSYS;
+ }
+
+ return result;
+}
+
+#ifdef FINSH_USING_MSH
+
+static int dac(int argc, char **argv)
+{
+ int result = RT_EOK;
+ static rt_dac_device_t dac_device = RT_NULL;
+ char *result_str;
+
+ if (argc > 1)
+ {
+ if (!strcmp(argv[1], "probe"))
+ {
+ if (argc == 3)
+ {
+ dac_device = (rt_dac_device_t)rt_device_find(argv[2]);
+ result_str = (dac_device == RT_NULL) ? "failure" : "success";
+ rt_kprintf("probe %s %s \n", argv[2], result_str);
+ }
+ else
+ {
+ rt_kprintf("dac probe <dac_name> - probe dac by name\n");
+ }
+ }
+ else
+ {
+ if (dac_device == RT_NULL)
+ {
+ rt_kprintf("Please using 'dac probe <dac_name>' first\n");
+ return -RT_ERROR;
+ }
+ if (!strcmp(argv[1], "enable"))
+ {
+ if (argc == 3)
+ {
+ result = rt_dac_enable(dac_device, atoi(argv[2]));
+ result_str = (result == RT_EOK) ? "success" : "failure";
+ rt_kprintf("%s channel %d enables %s \n", dac_device->parent.parent.name, atoi(argv[2]), result_str);
+ }
+ else
+ {
+ rt_kprintf("dac enable <channel> - enable dac channel\n");
+ }
+ }
+ else if (!strcmp(argv[1], "write"))
+ {
+ if (argc == 4)
+ {
+ rt_dac_write(dac_device, atoi(argv[2]), atoi(argv[3]));
+ rt_kprintf("%s channel %d write value is %d \n", dac_device->parent.parent.name, atoi(argv[2]), atoi(argv[3]));
+ }
+ else
+ {
+ rt_kprintf("dac write <channel> <value> - write dac value on the channel\n");
+ }
+ }
+ else if (!strcmp(argv[1], "disable"))
+ {
+ if (argc == 3)
+ {
+ result = rt_dac_disabled(dac_device, atoi(argv[2]));
+ result_str = (result == RT_EOK) ? "success" : "failure";
+ rt_kprintf("%s channel %d disable %s \n", dac_device->parent.parent.name, atoi(argv[2]), result_str);
+ }
+ else
+ {
+ rt_kprintf("dac disable <channel> - disable dac channel\n");
+ }
+ }
+ else
+ {
+ rt_kprintf("Unknown command. Please enter 'dac' for help\n");
+ }
+ }
+ }
+ else
+ {
+ rt_kprintf("Usage: \n");
+ rt_kprintf("dac probe <dac_name> - probe dac by name\n");
+ rt_kprintf("dac write <channel> <value> - write dac value on the channel\n");
+ rt_kprintf("dac disable <channel> - disable dac channel\n");
+ rt_kprintf("dac enable <channel> - enable dac channel\n");
+ result = -RT_ERROR;
+ }
+ return RT_EOK;
+}
+MSH_CMD_EXPORT(dac, dac function);
+
+#endif /* FINSH_USING_MSH */
diff --git a/components/drivers/misc/pin.c b/components/drivers/misc/pin.c
index aca58ee21b..2750f5105a 100644
--- a/components/drivers/misc/pin.c
+++ b/components/drivers/misc/pin.c
@@ -151,3 +151,18 @@ int rt_pin_read(rt_base_t pin)
return _hw_pin.ops->pin_read(&_hw_pin.parent, pin);
}
FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_read, pinRead, read status from hardware pin);
+
+rt_base_t rt_pin_get(const char *name)
+{
+ RT_ASSERT(_hw_pin.ops != RT_NULL);
+ RT_ASSERT(name[0] == 'P');
+
+ if(_hw_pin.ops->pin_get == RT_NULL)
+ {
+ return -RT_ENOSYS;
+ }
+
+ return _hw_pin.ops->pin_get(name);
+}
+FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_get, pinGet, get pin number from hardware pin);
+
diff --git a/components/drivers/misc/pulse_encoder.c b/components/drivers/misc/pulse_encoder.c
new file mode 100644
index 0000000000..3145c24675
--- /dev/null
+++ b/components/drivers/misc/pulse_encoder.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-08-08 balanceTWK the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+static rt_err_t rt_pulse_encoder_init(struct rt_device *dev)
+{
+ struct rt_pulse_encoder_device *pulse_encoder;
+
+ pulse_encoder = (struct rt_pulse_encoder_device *)dev;
+ if (pulse_encoder->ops->init)
+ {
+ return pulse_encoder->ops->init(pulse_encoder);
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
+}
+
+static rt_err_t rt_pulse_encoder_open(struct rt_device *dev, rt_uint16_t oflag)
+{
+ struct rt_pulse_encoder_device *pulse_encoder;
+
+ pulse_encoder = (struct rt_pulse_encoder_device *)dev;
+ if (pulse_encoder->ops->control)
+ {
+ return pulse_encoder->ops->control(pulse_encoder, PULSE_ENCODER_CMD_ENABLE, RT_NULL);
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
+}
+
+static rt_err_t rt_pulse_encoder_close(struct rt_device *dev)
+{
+ struct rt_pulse_encoder_device *pulse_encoder;
+
+ pulse_encoder = (struct rt_pulse_encoder_device *)dev;
+ if (pulse_encoder->ops->control)
+ {
+ return pulse_encoder->ops->control(pulse_encoder, PULSE_ENCODER_CMD_DISABLE, RT_NULL);
+ }
+ else
+ {
+ return -RT_ENOSYS;
+ }
+}
+
+static rt_size_t rt_pulse_encoder_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ struct rt_pulse_encoder_device *pulse_encoder;
+
+ pulse_encoder = (struct rt_pulse_encoder_device *)dev;
+ if (pulse_encoder->ops->get_count)
+ {
+ *(rt_int32_t *)buffer = pulse_encoder->ops->get_count(pulse_encoder);
+ }
+ return 1;
+}
+
+static rt_err_t rt_pulse_encoder_control(struct rt_device *dev, int cmd, void *args)
+{
+ rt_err_t result;
+ struct rt_pulse_encoder_device *pulse_encoder;
+
+ result = RT_EOK;
+ pulse_encoder = (struct rt_pulse_encoder_device *)dev;
+ switch (cmd)
+ {
+ case PULSE_ENCODER_CMD_CLEAR_COUNT:
+ result = pulse_encoder->ops->clear_count(pulse_encoder);
+ break;
+ case PULSE_ENCODER_CMD_GET_TYPE:
+ *(enum rt_pulse_encoder_type *)args = pulse_encoder->type;
+ break;
+ case PULSE_ENCODER_CMD_ENABLE:
+ case PULSE_ENCODER_CMD_DISABLE:
+ result = pulse_encoder->ops->control(pulse_encoder, cmd, args);
+ break;
+ default:
+ result = -RT_ENOSYS;
+ break;
+ }
+
+ return result;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops pulse_encoder_ops =
+{
+ rt_pulse_encoder_init,
+ rt_pulse_encoder_open,
+ rt_pulse_encoder_close,
+ rt_pulse_encoder_read,
+ RT_NULL,
+ rt_pulse_encoder_control
+};
+#endif
+
+rt_err_t rt_device_pulse_encoder_register(struct rt_pulse_encoder_device *pulse_encoder, const char *name, void *user_data)
+{
+ struct rt_device *device;
+
+ RT_ASSERT(pulse_encoder != RT_NULL);
+ RT_ASSERT(pulse_encoder->ops != RT_NULL);
+
+ device = &(pulse_encoder->parent);
+
+ device->type = RT_Device_Class_Miscellaneous;
+ device->rx_indicate = RT_NULL;
+ device->tx_complete = RT_NULL;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = &pulse_encoder_ops;
+#else
+ device->init = rt_pulse_encoder_init;
+ device->open = rt_pulse_encoder_open;
+ device->close = rt_pulse_encoder_close;
+ device->read = rt_pulse_encoder_read;
+ device->write = RT_NULL;
+ device->control = rt_pulse_encoder_control;
+#endif
+ device->user_data = user_data;
+
+ return rt_device_register(device, name, RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_STANDALONE);
+}
diff --git a/components/drivers/misc/rt_drv_pwm.c b/components/drivers/misc/rt_drv_pwm.c
index 2b7986b4d8..97d38d51b3 100644
--- a/components/drivers/misc/rt_drv_pwm.c
+++ b/components/drivers/misc/rt_drv_pwm.c
@@ -259,7 +259,7 @@ static int pwm_set(int argc, char **argv)
_exit:
return result;
}
-MSH_CMD_EXPORT(pwm_set, pwm_set 1 100 50);
+MSH_CMD_EXPORT(pwm_set, pwm_set pwm1 1 100 50);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */
diff --git a/components/drivers/misc/rt_inputcapture.c b/components/drivers/misc/rt_inputcapture.c
new file mode 100644
index 0000000000..d1886186d7
--- /dev/null
+++ b/components/drivers/misc/rt_inputcapture.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-08-13 balanceTWK the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <rtdbg.h>
+
+static rt_err_t rt_inputcapture_init(struct rt_device *dev)
+{
+ rt_err_t ret;
+ struct rt_inputcapture_device *inputcapture;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ ret = RT_EOK;
+ inputcapture = (struct rt_inputcapture_device *)dev;
+ inputcapture->watermark = RT_INPUT_CAPTURE_RB_SIZE / 2;
+ if (inputcapture->ops->init)
+ {
+ ret = inputcapture->ops->init(inputcapture);
+ }
+
+ return ret;
+}
+
+static rt_err_t rt_inputcapture_open(struct rt_device *dev, rt_uint16_t oflag)
+{
+ rt_err_t ret;
+ struct rt_inputcapture_device *inputcapture;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ ret = RT_EOK;
+ inputcapture = (struct rt_inputcapture_device *)dev;
+ if (inputcapture->ringbuff == RT_NULL)
+ {
+ inputcapture->ringbuff = rt_ringbuffer_create(sizeof(struct rt_inputcapture_data) * RT_INPUT_CAPTURE_RB_SIZE);
+ }
+ if (inputcapture->ops->open)
+ {
+ ret = inputcapture->ops->open(inputcapture);
+ }
+
+ return ret;
+}
+
+static rt_err_t rt_inputcapture_close(struct rt_device *dev)
+{
+ rt_err_t ret;
+ struct rt_inputcapture_device *inputcapture;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ ret = -RT_ERROR;
+ inputcapture = (struct rt_inputcapture_device *)dev;
+
+ if (inputcapture->ops->close)
+ {
+ ret = inputcapture->ops->close(inputcapture);
+ }
+
+ if (ret != RT_EOK)
+ {
+ return ret;
+ }
+
+ if (inputcapture->ringbuff)
+ {
+ rt_ringbuffer_destroy(inputcapture->ringbuff);
+ inputcapture->ringbuff = RT_NULL;
+ }
+ return ret;
+}
+
+static rt_size_t rt_inputcapture_read(struct rt_device *dev,
+ rt_off_t pos,
+ void *buffer,
+ rt_size_t size)
+{
+ rt_size_t receive_size;
+ struct rt_inputcapture_device *inputcapture;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ inputcapture = (struct rt_inputcapture_device *)dev;
+ receive_size = rt_ringbuffer_get(inputcapture->ringbuff, (rt_uint8_t *)buffer, sizeof(struct rt_inputcapture_data) * size);
+
+ return receive_size / sizeof(struct rt_inputcapture_data);
+}
+
+static rt_err_t rt_inputcapture_control(struct rt_device *dev, int cmd, void *args)
+{
+ rt_err_t result;
+ struct rt_inputcapture_device *inputcapture;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ result = RT_EOK;
+ inputcapture = (struct rt_inputcapture_device *)dev;
+ switch (cmd)
+ {
+ case INPUTCAPTURE_CMD_CLEAR_BUF:
+ if (inputcapture->ringbuff)
+ {
+ rt_ringbuffer_reset(inputcapture->ringbuff);
+ }
+ break;
+ case INPUTCAPTURE_CMD_SET_WATERMARK:
+ inputcapture->watermark = *(rt_size_t *)args;
+ break;
+ default:
+ result = -RT_ENOSYS;
+ break;
+ }
+
+ return result;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops inputcapture_ops =
+{
+ rt_inputcapture_init,
+ rt_inputcapture_open,
+ rt_inputcapture_close,
+ rt_inputcapture_read,
+ RT_NULL,
+ rt_inputcapture_control
+};
+#endif
+
+rt_err_t rt_device_inputcapture_register(struct rt_inputcapture_device *inputcapture, const char *name, void *user_data)
+{
+ struct rt_device *device;
+
+ RT_ASSERT(inputcapture != RT_NULL);
+ RT_ASSERT(inputcapture->ops != RT_NULL);
+ RT_ASSERT(inputcapture->ops->get_pulsewidth != RT_NULL);
+
+ device = &(inputcapture->parent);
+
+ device->type = RT_Device_Class_Miscellaneous;
+ device->rx_indicate = RT_NULL;
+ device->tx_complete = RT_NULL;
+ inputcapture->ringbuff = RT_NULL;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = &inputcapture_ops;
+#else
+ device->init = rt_inputcapture_init;
+ device->open = rt_inputcapture_open;
+ device->close = rt_inputcapture_close;
+ device->read = rt_inputcapture_read;
+ device->write = RT_NULL;
+ device->control = rt_inputcapture_control;
+#endif
+ device->user_data = user_data;
+
+ return rt_device_register(device, name, RT_DEVICE_FLAG_RDONLY | RT_DEVICE_FLAG_STANDALONE);
+}
+
+/**
+ * This function is ISR for inputcapture interrupt.
+ * level: RT_TRUE denotes high level pulse, and RT_FALSE denotes low level pulse.
+ */
+void rt_hw_inputcapture_isr(struct rt_inputcapture_device *inputcapture, rt_bool_t level)
+{
+ struct rt_inputcapture_data data;
+ rt_size_t receive_size;
+ if (inputcapture->ops->get_pulsewidth(inputcapture, &data.pulsewidth_us) != RT_EOK)
+ {
+ return;
+ }
+
+ data.is_high = level;
+ if (rt_ringbuffer_put(inputcapture->ringbuff, (rt_uint8_t *)&data, sizeof(struct rt_inputcapture_data)) == 0)
+ {
+ LOG_W("inputcapture ringbuffer doesn't have enough space.");
+ }
+
+ receive_size = rt_ringbuffer_data_len(inputcapture->ringbuff) / sizeof(struct rt_inputcapture_data);
+
+ if (receive_size >= inputcapture->watermark)
+ {
+ /* indicate to upper layer application */
+ if (inputcapture->parent.rx_indicate != RT_NULL)
+ inputcapture->parent.rx_indicate(&inputcapture->parent, receive_size);
+ }
+}
diff --git a/components/drivers/mtd/SConscript b/components/drivers/mtd/SConscript
index 462c38194c..6f86656187 100644
--- a/components/drivers/mtd/SConscript
+++ b/components/drivers/mtd/SConscript
@@ -1,5 +1,3 @@
-Import('RTT_ROOT')
-Import('rtconfig')
from building import *
cwd = GetCurrentDir()
@@ -9,17 +7,6 @@ depend = []
CPPPATH = [cwd + '/../include']
group = []
-if GetDepend(['RT_USING_MTD']):
- src += ['mtd.c']
- depend += ['RT_USING_MTD']
-
- if GetDepend(['MTD_USING_NOR']):
- src += ['mtdnor.c']
- depend += ['MTD_USING_NOR']
- if GetDepend(['MTD_USING_NAND']):
- src += ['mtdnand.c']
- depend += ['MTD_USING_NAND']
-
if GetDepend(['RT_USING_MTD_NOR']):
src += ['mtd_nor.c']
depend += ['RT_USING_MTD_NOR']
@@ -31,4 +18,4 @@ if GetDepend(['RT_USING_MTD_NAND']):
if src:
group = DefineGroup('DeviceDrivers', src, depend = depend, CPPPATH = CPPPATH)
-Return('group') \ No newline at end of file
+Return('group')
diff --git a/components/drivers/mtd/mtd.c b/components/drivers/mtd/mtd.c
deleted file mode 100644
index 3e7b4f2b54..0000000000
--- a/components/drivers/mtd/mtd.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- 2018-09-10 heyuanjie87 first version
-
- */
-
-#include <drivers/mtd.h>
-
-static rt_mtd_t* mtd_part_alloc(rt_mtd_t *master, const struct mtd_part *part)
-{
- rt_mtd_t *slave;
-
- slave = rt_malloc(sizeof(rt_mtd_t));
- if (slave == RT_NULL)
- goto out;
-
- slave->master = master;
-
- *slave = *master;
- slave->size = part->size;
- slave->offset = part->offset;
-
-out:
-
- return slave;
-}
-
-rt_mtd_t* rt_mtd_get(const char *name)
-{
- rt_mtd_t *mtd;
-
- mtd = (rt_mtd_t *)rt_device_find(name);
- if (mtd == RT_NULL)
- return RT_NULL;
-
- if (mtd->parent.type != RT_Device_Class_MTD)
- return RT_NULL;
-
- return mtd;
-}
-
-/*
- * Register MTD driver
- *
- * @parts partion description
- * @np number of partitions
- * @return number of unregistered partitions
- *
-*/
-int rt_mtd_register(rt_mtd_t *master, const struct mtd_part *parts, int np)
-{
- int ret;
- rt_mtd_t *slave;
-
- master->master = master;
- master->parent.type = RT_Device_Class_MTD;
-
- if (np > 0)
- {
- master->offset = parts->offset;
- master->size = parts->size;
-
- ret = rt_device_register((rt_device_t)master, parts->name, 0);
- if (ret != 0)
- goto _out;
-
- np --;
- parts ++;
- }
-
- while (np > 0)
- {
- slave = mtd_part_alloc(master, parts);
- if (!slave)
- break;
- ret = rt_device_register((rt_device_t)slave, parts->name, 0);
- if (ret)
- break;
- parts ++;
- np --;
- }
-
-_out:
- return np;
-}
-
-int rt_mtd_block_erase(rt_mtd_t *mtd, uint32_t block)
-{
- uint32_t total_blks;
- loff_t addr;
-
- total_blks = mtd->size/mtd->block_size;
- if (block >= total_blks)
- return -EINVAL;
- addr = mtd->offset + mtd->block_size * block;
-
- return mtd->ops->erase(mtd->master, addr, mtd->block_size);
-}
-
-int rt_mtd_block_isbad(rt_mtd_t *mtd, uint32_t block)
-{
- uint32_t total_blks, offset_blk;
-
- if (!mtd->ops->isbad)
- return 0;
-
- total_blks = mtd->size / mtd->block_size;
- if (block >= total_blks)
- return -EINVAL;
- offset_blk = mtd->offset / mtd->block_size;
-
- return mtd->ops->isbad(mtd->master, block + offset_blk);
-}
-
-int rt_mtd_block_markbad(rt_mtd_t *mtd, uint32_t block)
-{
- uint32_t total_blks, offset_blk;
-
- if (!mtd->ops->markbad)
- return -EOPNOTSUPP;
-
- total_blks = mtd->size / mtd->block_size;
- if (block >= total_blks)
- return -EINVAL;
- offset_blk = mtd->offset / mtd->block_size;
-
- return mtd->ops->markbad(mtd->master, block + offset_blk);
-}
-
-int rt_mtd_erase(rt_mtd_t *mtd, loff_t addr, size_t size)
-{
- if (addr > mtd->size || (addr + size) > mtd->size)
- return -EINVAL;
- addr += mtd->offset;
-
- return mtd->ops->erase(mtd->master, addr, size);
-}
-
-/*
-* Read data only
-*
-* @from offset to read from
-* @return success size or error code
-*/
-int rt_mtd_read(rt_mtd_t *mtd, loff_t from, uint8_t *buf, size_t len)
-{
- int ret;
- struct mtd_io_desc desc = {0};
-
- if (from < 0 || from >= (loff_t)mtd->size || len > mtd->size - from)
- return -EINVAL;
- if (!len)
- return 0;
-
- desc.datbuf = buf;
- desc.datlen = len;
- ret = mtd->ops->read(mtd->master, from + mtd->offset, &desc);
- if (ret)
- return ret;
-
- return desc.datretlen;
-}
-
-/**
-* Write data only
-*
-* @to offset to write from
-* @return success size or error code
-*/
-int rt_mtd_write(rt_mtd_t *mtd, loff_t to, const uint8_t *buf, size_t len)
-{
- int ret;
- struct mtd_io_desc desc = {0};
-
- if (to < 0 || to >= (loff_t)mtd->size || len > mtd->size - to)
- return -EINVAL;
- if (!mtd->ops->write)
- return -EROFS;
- if (!len)
- return 0;
-
- desc.datbuf = (uint8_t*)buf;
- desc.datlen = len;
- ret = mtd->ops->write(mtd->master, to + mtd->offset, &desc);
- if (ret)
- return ret;
-
- return desc.datretlen;
-}
-
-/**
-* Read data and/or out-of-band
-*
-* @from offset to read from
-* @desc sector operation description structure
-* @return error code, 0 success
-*/
-int rt_mtd_read_oob(rt_mtd_t *mtd, loff_t from, struct mtd_io_desc *desc)
-{
- desc->datretlen = 0;
- desc->oobretlen = 0;
-
- if (from < 0 || from >= (loff_t)mtd->size)
- return -EINVAL;
-
- if (desc->datbuf && (desc->datlen > (mtd->size - from)))
- return -EINVAL;
-
- return mtd->ops->read(mtd->master, from + mtd->offset, desc);
-}
-
-/**
-* Write data and/or out-of-band
-*
-* @to offset to read from
-* @desc sector operation description structure
-* @return error code, 0 success
-*/
-int rt_mtd_write_oob(rt_mtd_t *mtd, loff_t to, struct mtd_io_desc *desc)
-{
- desc->datretlen = 0;
- desc->oobretlen = 0;
-
- if (to < 0 || to >= (loff_t)mtd->size)
- return -EINVAL;
-
- if (desc->datbuf && (desc->datlen >(mtd->size - to)))
- return -EINVAL;
-
- return mtd->ops->write(mtd->master, to + mtd->offset, desc);
-}
diff --git a/components/drivers/mtd/mtd_nand.c b/components/drivers/mtd/mtd_nand.c
index 3e4582ceaf..ae5aa9c172 100644
--- a/components/drivers/mtd/mtd_nand.c
+++ b/components/drivers/mtd/mtd_nand.c
@@ -56,7 +56,7 @@ static rt_err_t _mtd_control(rt_device_t dev, int cmd, void *args)
}
#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device_ops mtd_nand_ops =
+const static struct rt_device_ops mtd_nand_ops =
{
_mtd_init,
_mtd_open,
@@ -78,7 +78,7 @@ rt_err_t rt_mtd_nand_register_device(const char *name,
/* set device class and generic device interface */
dev->type = RT_Device_Class_MTD;
#ifdef RT_USING_DEVICE_OPS
- dev->ops = &mtd_nand_ops;
+ dev->ops = &mtd_nand_ops;
#else
dev->init = _mtd_init;
dev->open = _mtd_open;
@@ -101,188 +101,262 @@ rt_err_t rt_mtd_nand_register_device(const char *name,
static void mtd_dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
{
- unsigned char *buf = (unsigned char*)ptr;
- int i, j;
- for (i=0; i<buflen; i+=16)
- {
- rt_kprintf("%06x: ", i);
- for (j=0; j<16; j++)
- if (i+j < buflen)
- rt_kprintf("%02x ", buf[i+j]);
- else
- rt_kprintf(" ");
- rt_kprintf(" ");
- for (j=0; j<16; j++)
- if (i+j < buflen)
- rt_kprintf("%c", __is_print(buf[i+j]) ? buf[i+j] : '.');
- rt_kprintf("\n");
- }
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%06x: ", i);
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%02x ", buf[i + j]);
+ else
+ rt_kprintf(" ");
+ rt_kprintf(" ");
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ rt_kprintf("\n");
+ }
}
-int mtd_nandid(const char* name)
+int mtd_nandid(const char *name)
{
- struct rt_mtd_nand_device *nand;
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ struct rt_mtd_nand_device *nand;
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
- return rt_mtd_nand_read_id(nand);
+ return rt_mtd_nand_read_id(nand);
}
-FINSH_FUNCTION_EXPORT_ALIAS(mtd_nandid, nand_id, read ID - nandid(name));
-int mtd_nand_read(const char* name, int block, int page)
+int mtd_nand_read(const char *name, int block, int page)
{
- rt_err_t result;
- rt_uint8_t *page_ptr;
- rt_uint8_t *oob_ptr;
- struct rt_mtd_nand_device *nand;
+ rt_err_t result;
+ rt_uint8_t *page_ptr;
+ rt_uint8_t *oob_ptr;
+ struct rt_mtd_nand_device *nand;
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
- page_ptr = rt_malloc(nand->page_size + nand->oob_size);
- if (page_ptr == RT_NULL)
- {
- rt_kprintf("out of memory!\n");
- return -RT_ENOMEM;
- }
+ page_ptr = rt_malloc(nand->page_size + nand->oob_size);
+ if (page_ptr == RT_NULL)
+ {
+ rt_kprintf("out of memory!\n");
+ return -RT_ENOMEM;
+ }
- oob_ptr = page_ptr + nand->page_size;
- rt_memset(page_ptr, 0xff, nand->page_size + nand->oob_size);
+ oob_ptr = page_ptr + nand->page_size;
+ rt_memset(page_ptr, 0xff, nand->page_size + nand->oob_size);
- /* calculate the page number */
- page = block * nand->pages_per_block + page;
- result = rt_mtd_nand_read(nand, page, page_ptr, nand->page_size,
- oob_ptr, nand->oob_size);
+ /* calculate the page number */
+ page = block * nand->pages_per_block + page;
+ result = rt_mtd_nand_read(nand, page, page_ptr, nand->page_size,
+ oob_ptr, nand->oob_size);
- rt_kprintf("read page, rc=%d\n", result);
- mtd_dump_hex(page_ptr, nand->page_size);
- mtd_dump_hex(oob_ptr, nand->oob_size);
+ rt_kprintf("read page, rc=%d\n", result);
+ mtd_dump_hex(page_ptr, nand->page_size);
+ mtd_dump_hex(oob_ptr, nand->oob_size);
- rt_free(page_ptr);
- return 0;
+ rt_free(page_ptr);
+ return 0;
}
-FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_read, nand_read, read page in nand - nand_read(name, block, page));
-int mtd_nand_readoob(const char* name, int block, int page)
+int mtd_nand_readoob(const char *name, int block, int page)
{
- struct rt_mtd_nand_device *nand;
- rt_uint8_t *oob_ptr;
+ struct rt_mtd_nand_device *nand;
+ rt_uint8_t *oob_ptr;
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
- oob_ptr = rt_malloc(nand->oob_size);
- if (oob_ptr == RT_NULL)
- {
- rt_kprintf("out of memory!\n");
- return -RT_ENOMEM;
- }
+ oob_ptr = rt_malloc(nand->oob_size);
+ if (oob_ptr == RT_NULL)
+ {
+ rt_kprintf("out of memory!\n");
+ return -RT_ENOMEM;
+ }
- /* calculate the page number */
- page = block * nand->pages_per_block + page;
- rt_mtd_nand_read(nand, page, RT_NULL, nand->page_size,
- oob_ptr, nand->oob_size);
- mtd_dump_hex(oob_ptr, nand->oob_size);
+ /* calculate the page number */
+ page = block * nand->pages_per_block + page;
+ rt_mtd_nand_read(nand, page, RT_NULL, nand->page_size,
+ oob_ptr, nand->oob_size);
+ mtd_dump_hex(oob_ptr, nand->oob_size);
- rt_free(oob_ptr);
- return 0;
+ rt_free(oob_ptr);
+ return 0;
}
-FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_readoob, nand_readoob, read spare data in nand - nand_readoob(name, block, page));
-int mtd_nand_write(const char* name, int block, int page)
+int mtd_nand_write(const char *name, int block, int page)
{
- rt_err_t result;
- rt_uint8_t *page_ptr;
- rt_uint8_t *oob_ptr;
- rt_uint32_t index;
- struct rt_mtd_nand_device *nand;
+ rt_err_t result;
+ rt_uint8_t *page_ptr;
+ rt_uint8_t *oob_ptr;
+ rt_uint32_t index;
+ struct rt_mtd_nand_device *nand;
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
- page_ptr = rt_malloc(nand->page_size + nand->oob_size);
- if (page_ptr == RT_NULL)
- {
- rt_kprintf("out of memory!\n");
- return -RT_ENOMEM;
- }
+ page_ptr = rt_malloc(nand->page_size + nand->oob_size);
+ if (page_ptr == RT_NULL)
+ {
+ rt_kprintf("out of memory!\n");
+ return -RT_ENOMEM;
+ }
- oob_ptr = page_ptr + nand->page_size;
- /* prepare page data */
- for (index = 0; index < nand->page_size; index ++)
- {
- page_ptr[index] = index & 0xff;
- }
- /* prepare oob data */
- for (index = 0; index < nand->oob_size; index ++)
- {
- oob_ptr[index] = index & 0xff;
- }
+ oob_ptr = page_ptr + nand->page_size;
+ /* prepare page data */
+ for (index = 0; index < nand->page_size; index ++)
+ {
+ page_ptr[index] = index & 0xff;
+ }
+ /* prepare oob data */
+ for (index = 0; index < nand->oob_size; index ++)
+ {
+ oob_ptr[index] = index & 0xff;
+ }
- /* calculate the page number */
- page = block * nand->pages_per_block + page;
- result = rt_mtd_nand_write(nand, page, page_ptr, nand->page_size,
- oob_ptr, nand->oob_size);
- if (result != RT_MTD_EOK)
- {
- rt_kprintf("write page failed!, rc=%d\n", result);
- }
+ /* calculate the page number */
+ page = block * nand->pages_per_block + page;
+ result = rt_mtd_nand_write(nand, page, page_ptr, nand->page_size,
+ oob_ptr, nand->oob_size);
+ if (result != RT_MTD_EOK)
+ {
+ rt_kprintf("write page failed!, rc=%d\n", result);
+ }
- rt_free(page_ptr);
- return 0;
+ rt_free(page_ptr);
+ return 0;
}
-FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_write, nand_write, write dump data to nand - nand_write(name, block, page));
-int mtd_nand_erase(const char* name, int block)
+int mtd_nand_erase(const char *name, int block)
{
- struct rt_mtd_nand_device *nand;
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ struct rt_mtd_nand_device *nand;
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
- return rt_mtd_nand_erase_block(nand, block);
+ return rt_mtd_nand_erase_block(nand, block);
}
-FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_erase, nand_erase, nand_erase(name, block));
-int mtd_nand_erase_all(const char* name)
+int mtd_nand_erase_all(const char *name)
{
- rt_uint32_t index = 0;
- struct rt_mtd_nand_device *nand;
-
- nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
- if (nand == RT_NULL)
- {
- rt_kprintf("no nand device found!\n");
- return -RT_ERROR;
- }
+ rt_uint32_t index = 0;
+ struct rt_mtd_nand_device *nand;
- for (index = 0; index < (nand->block_end - nand->block_start); index ++)
- {
- rt_mtd_nand_erase_block(nand, index);
- }
-
- return 0;
+ nand = RT_MTD_NAND_DEVICE(rt_device_find(name));
+ if (nand == RT_NULL)
+ {
+ rt_kprintf("no nand device found!\n");
+ return -RT_ERROR;
+ }
+
+ for (index = 0; index < (nand->block_end - nand->block_start); index ++)
+ {
+ rt_mtd_nand_erase_block(nand, index);
+ }
+
+ return 0;
+}
+
+#ifdef FINSH_USING_MSH
+static void mtd_nand(int argc, char **argv)
+{
+ /* If the number of arguments less than 2 */
+ if (argc < 3)
+ {
+help:
+ rt_kprintf("\n");
+ rt_kprintf("mtd_nand [OPTION] [PARAM ...]\n");
+ rt_kprintf(" id <name> Get nandid by given name\n");
+ rt_kprintf(" read <name> <bn> <pn> Read data on page <pn> of block <bn> of device <name>\n");
+ rt_kprintf(" readoob <name> <bn> <pn> Read oob on page <pn> of block <bn> of device <name>\n");
+ rt_kprintf(" write <name> <bn> <pn> Run write test on page <pn> of block <bn> of device <name>\n");
+ rt_kprintf(" erase <name> <bn> Erase on block <bn> of device <name>\n");
+ rt_kprintf(" eraseall <name> Erase all block on device <name>\n");
+ return ;
+ }
+ else if (!strcmp(argv[1], "id"))
+ {
+ mtd_nandid(argv[2]);
+ }
+ else if (!strcmp(argv[1], "read"))
+ {
+ if (argc < 5)
+ {
+ rt_kprintf("The input parameters are too few!\n");
+ goto help;
+ }
+ mtd_nand_read(argv[2], atoi(argv[3]), atoi(argv[4]));
+ }
+ else if (!strcmp(argv[1], "readoob"))
+ {
+ if (argc < 5)
+ {
+ rt_kprintf("The input parameters are too few!\n");
+ goto help;
+ }
+ mtd_nand_readoob(argv[2], atoi(argv[3]), atoi(argv[4]));
+ }
+ else if (!strcmp(argv[1], "write"))
+ {
+ if (argc < 5)
+ {
+ rt_kprintf("The input parameters are too few!\n");
+ goto help;
+ }
+ mtd_nand_write(argv[2], atoi(argv[3]), atoi(argv[4]));
+ }
+ else if (!strcmp(argv[1], "erase"))
+ {
+ if (argc < 4)
+ {
+ rt_kprintf("The input parameters are too few!\n");
+ goto help;
+ }
+ mtd_nand_erase(argv[2], atoi(argv[3]));
+ }
+ else if (!strcmp(argv[1], "eraseall"))
+ {
+ mtd_nand_erase_all(argv[2]);
+ }
+ else
+ {
+ rt_kprintf("Input parameters are not supported!\n");
+ goto help;
+ }
}
+MSH_CMD_EXPORT(mtd_nand, MTD nand device test function);
+#endif /* FINSH_USING_MSH */
+
+#ifndef FINSH_USING_MSH_ONLY
+FINSH_FUNCTION_EXPORT_ALIAS(mtd_nandid, nand_id, read ID - nandid(name));
+FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_read, nand_read, read page in nand - nand_read(name, block, page));
+FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_readoob, nand_readoob, read spare data in nand - nand_readoob(name, block, page));
+FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_write, nand_write, write dump data to nand - nand_write(name, block, page));
+FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_erase, nand_erase, nand_erase(name, block));
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_erase_all, nand_erase_all, erase all of nand device - nand_erase_all(name, block));
-#endif
+#endif /* FINSH_USING_MSH_ONLY */
-#endif
+#endif /* defined(RT_MTD_NAND_DEBUG) && defined(RT_USING_FINSH) */
+
+#endif /* RT_USING_MTD_NAND */
diff --git a/components/drivers/mtd/mtdnand.c b/components/drivers/mtd/mtdnand.c
deleted file mode 100644
index 50012219fb..0000000000
--- a/components/drivers/mtd/mtdnand.c
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2018-09-10 heyuanjie87 first version
- */
-
-#include <rtdevice.h>
-
-#define MTDTONAND(x) ((rt_nand_t*)(x))
-#define NOTALIGNED(x) ((x & (chip->page_size - 1)) != 0)
-#ifndef min
-#define min(a,b) (a>b? b:a)
-#endif
-
-static uint8_t *nand_fill_oob(rt_nand_t *chip, uint8_t *oob, size_t len, struct mtd_io_desc *desc)
-{
- rt_memset(chip->oob_poi, 0xff, chip->oobsize);
-
- switch (desc->mode)
- {
- case MTD_OPM_PLACE_OOB:
- case MTD_OPM_RAW:
- rt_memcpy(chip->oob_poi + desc->ooboffs, oob, len);
- return oob + len;
-
- case MTD_OPM_AUTO_OOB:
- {
- const struct mtd_oob_region *free = chip->freelayout;
- uint32_t boffs;
- size_t bytes;
-
- bytes = min(len, free->length);
- boffs = free->offset;
-
- rt_memcpy(chip->oob_poi + boffs, oob, bytes);
- oob += bytes;
-
- return oob;
- }
- }
-
- return NULL;
-}
-
-static uint8_t *nand_transfer_oob(rt_nand_t *chip, uint8_t *oob, struct mtd_io_desc *desc, size_t len)
-{
- switch (desc->mode)
- {
- case MTD_OPM_PLACE_OOB:
- case MTD_OPM_RAW:
- rt_memcpy(oob, chip->oob_poi + desc->ooboffs, len);
- return oob + len;
-
- case MTD_OPM_AUTO_OOB:
- {
- struct mtd_oob_region *free = (struct mtd_oob_region *)chip->freelayout;
- uint32_t boffs = 0, roffs = desc->ooboffs;
- size_t bytes = 0;
-
- for (; free->length && len; free++, len -= bytes)
- {
- /* Read request not from offset 0? */
- if (roffs)
- {
- if (roffs >= free->length)
- {
- roffs -= free->length;
- continue;
- }
- boffs = free->offset + roffs;
- bytes = min(len, (free->length - roffs));
- roffs = 0;
- }
- else
- {
- bytes = min(len, free->length);
- boffs = free->offset;
- }
-
- rt_memcpy(oob, chip->oob_poi + boffs, bytes);
- oob += bytes;
- }
-
- return oob;
- }
- }
-
- return NULL;
-}
-
-static int nand_read_page_raw(rt_nand_t *chip, uint8_t *buf, int oob_required, int page)
-{
- chip->ops->read_buf(chip, buf, chip->page_size);
-
- if (oob_required)
- chip->ops->read_buf(chip, chip->oob_poi, chip->oobsize);
-
- return 0;
-}
-
-static int nand_write_page_raw(rt_nand_t *chip, const uint8_t *buf, int oob_required, int page)
-{
- chip->ops->write_buf(chip, buf, chip->page_size);
-
- if (oob_required)
- chip->ops->write_buf(chip, chip->oob_poi, chip->oobsize);
-
- return 0;
-}
-
-static int nand_write_page_hwecc(rt_nand_t *chip, const uint8_t *buf, int oob_required, int page)
-{
- uint16_t i;
- uint16_t stepsize = chip->ecc.stepsize;
- uint16_t eccbytes = chip->ecc.bytes;
- uint16_t eccsteps = chip->ecc._step;
- uint16_t eccpos = chip->ecc.layout->offset;
- uint8_t *ecc_calc = chip->buffers.ecccalc;
- const uint8_t *p = buf;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += stepsize)
- {
- chip->ops->cmdfunc(chip, NAND_CMD_ECC_EN, 0, 0);
- chip->ops->write_buf(chip, p, stepsize);
- chip->ecc.calculate(chip, p, &ecc_calc[i]);
- chip->ops->cmdfunc(chip, NAND_CMD_ECC_DIS, 0, 0);
- }
-
- rt_memcpy(&chip->oob_poi[eccpos], ecc_calc, chip->ecc.layout->length);
-
- chip->ops->write_buf(chip, chip->oob_poi, chip->oobsize);
-
- return 0;
-}
-
-static int nand_read_page_hwecc(rt_nand_t *chip, uint8_t *buf, int oob_required, int page)
-{
- uint16_t i;
- uint16_t eccsize = chip->ecc.stepsize;
- uint16_t eccbytes = chip->ecc.bytes;
- uint16_t eccsteps = chip->ecc._step;
- uint16_t eccpos = chip->ecc.layout->offset;
- uint8_t *p = buf;
- uint8_t *ecc_calc = chip->buffers.ecccalc;
- uint8_t *ecc_code = chip->buffers.ecccode;
- int ret = 0;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
- {
- chip->ops->cmdfunc(chip, NAND_CMD_ECC_EN, 0, 0);
- chip->ops->read_buf(chip, p, eccsize);
- chip->ecc.calculate(chip, p, &ecc_calc[i]);
- chip->ops->cmdfunc(chip, NAND_CMD_ECC_DIS, 0, 0);
- }
-
- chip->ops->read_buf(chip, chip->oob_poi, chip->oobsize);
- rt_memcpy(ecc_code, &chip->oob_poi[eccpos], chip->ecc.layout->length);
-
- eccsteps = chip->ecc._step;
- p = buf;
-
- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
- {
- int stat;
-
- stat = chip->ecc.correct(chip, p, &ecc_code[i], &ecc_calc[i]);
- if (stat != 0)
- ret = -1;
- }
-
- return ret;
-}
-
-static int nand_write_page(rt_nand_t *chip, const uint8_t *buf,
- int oob_required, int page, int raw)
-{
- int status;
-
- chip->ops->cmdfunc(chip, NAND_CMD_PAGE_WR0, page, 0x00);
-
- if (raw)
- {
- nand_write_page_raw(chip, buf, oob_required, page);
- }
- else
- {
- chip->write_page(chip, buf, oob_required, page);
- }
-
- status = chip->ops->cmdfunc(chip, NAND_CMD_PAGE_WR1, -1, -1);
-
- return status;
-}
-
-static int nand_do_read_desc(rt_nand_t *chip, loff_t from, struct mtd_io_desc *desc)
-{
- int page, bytes;
- char oob_required;
- char ecc_fail = 0;
- int ret = 0;
- uint32_t readlen = desc->datlen;
- uint16_t oobreadlen = desc->ooblen;
- uint16_t max_oobsize = desc->mode == MTD_OPM_AUTO_OOB ?
- chip->freelayout->length : chip->oobsize;
-
- uint8_t *oob, *buf, *notalign = 0;
-
- /* Reject reads, which are not page aligned */
- if (NOTALIGNED(from))
- {
- return -EINVAL;
- }
-
- buf = desc->datbuf;
- if (NOTALIGNED(desc->datlen) && !chip->pagebuf)
- {
- chip->pagebuf = rt_malloc(chip->page_size);
- if (!chip->pagebuf)
- return -ENOMEM;
- }
-
- page = (int)(from / chip->page_size);
-
- oob = desc->oobbuf;
- oob_required = oob ? 1 : 0;
-
- while (1)
- {
- bytes = min(chip->page_size, readlen);
-
- chip->ops->cmdfunc(chip, NAND_CMD_PAGE_RD, page, 0x00);
- if (NOTALIGNED(bytes))
- {
- notalign = buf;
- buf = chip->pagebuf;
- }
- /*
- * Now read the page into the buffer. Absent an error,
- * the read methods return max bitflips per ecc step.
- */
- if (desc->mode == MTD_OPM_RAW)
- {
- ret = nand_read_page_raw(chip, buf, oob_required, page);
- }
- else
- {
- ret = chip->read_page(chip, buf, oob_required, page);
- }
-
- if (ret != 0)
- {
- ret = -EBADMSG;
- break;
- }
-
- if (oob)
- {
- int toread = min(oobreadlen, max_oobsize);
-
- if (toread)
- {
- oob = nand_transfer_oob(chip, oob, desc, toread);
- oobreadlen -= toread;
- }
- }
-
- if (notalign)
- {
- rt_memcpy(notalign, buf, bytes);
- }
-
- buf += bytes;
- readlen -= bytes;
-
- if (!readlen)
- break;
-
- page++;
- }
-
- desc->datretlen = desc->datlen - (size_t)readlen;
- if (oob)
- desc->oobretlen = desc->ooblen - oobreadlen;
-
- return ret;
-}
-
-/*
- * write with ECC
- *
-*/
-static int nand_do_write_desc(rt_nand_t *chip, loff_t to, struct mtd_io_desc *desc)
-{
- int page;
- uint16_t writelen = desc->datlen;
- uint16_t oob_required = desc->oobbuf ? 1 : 0;
- uint16_t oobwritelen = desc->ooblen;
- uint16_t oobmaxlen = desc->mode == MTD_OPM_AUTO_OOB ?
- chip->freelayout->length : chip->oobsize;
-
- uint8_t *oob = desc->oobbuf;
- uint8_t *buf = desc->datbuf;
- int ret;
-
- if (!writelen)
- return 0;
-
- /* Reject writes, which are not page aligned */
- if (NOTALIGNED(to))
- {
- return -EINVAL;
- }
-
- page = (int)(to / chip->page_size);
-
- /* Don't allow multipage oob writes with offset */
- if (oob && desc->ooboffs && (desc->ooboffs + desc->ooblen > oobmaxlen))
- {
- ret = -EINVAL;
- goto err_out;
- }
-
- if (NOTALIGNED(desc->datlen) && !chip->pagebuf)
- {
- chip->pagebuf = rt_malloc(chip->page_size);
- if (!chip->pagebuf)
- return -ENOMEM;
- }
-
- while (1)
- {
- uint16_t bytes = min(chip->page_size, writelen);
-
- if (oob)
- {
- size_t len = min(oobwritelen, oobmaxlen);
- oob = nand_fill_oob(chip, oob, len, desc);
- oobwritelen -= len;
- }
- else
- {
- /* We still need to erase leftover OOB data */
- rt_memset(chip->oob_poi, 0xff, chip->oobsize);
- }
-
- if (NOTALIGNED(bytes))
- {
- uint8_t *dbtmp = buf;
- buf = chip->pagebuf;
- rt_memset(&buf[bytes], 0xff, chip->page_size - bytes);
- rt_memcpy(buf, dbtmp, bytes);
- }
- ret = nand_write_page(chip, buf, oob_required, page, (desc->mode == MTD_OPM_RAW));
- if (ret)
- break;
-
- writelen -= bytes;
- if (!writelen)
- break;
-
- buf += bytes;
- page++;
- }
-
- desc->datretlen = desc->datlen - writelen;
- if (oob)
- desc->oobretlen = desc->ooblen;
-
-err_out:
-
- return ret;
-}
-
-static int nand_read_oob_std(rt_nand_t *chip, int page)
-{
- chip->ops->cmdfunc(chip, NAND_CMD_PAGE_RD, page, chip->page_size);
- chip->ops->read_buf(chip, chip->oob_poi, chip->oobsize);
-
- return 0;
-}
-
-/*
- * read one page of OOB
-*/
-static int nand_only_read_oob(rt_nand_t *chip, loff_t from, struct mtd_io_desc *desc)
-{
- int page;
- int readlen = desc->ooblen;
- int len;
- uint8_t *buf = desc->oobbuf;
- int ret = 0;
-
- if (desc->mode == MTD_OPM_AUTO_OOB)
- len = chip->freelayout->length;
- else
- len = chip->oobsize;
-
- if (desc->ooboffs >= len) //attempt to start read outside oob
- {
- return -EINVAL;
- }
-
- page = (int)(from / chip->page_size);
-
- ret = nand_read_oob_std(chip, page);
- if (ret == 0)
- {
- len = min(len, readlen);
- buf = nand_transfer_oob(chip, buf, desc, len);
- desc->oobretlen = len;
- }
-
- return ret;
-}
-
-static int nand_write_oob_std(rt_nand_t *chip, int page)
-{
- int status;
-
- chip->ops->cmdfunc(chip, NAND_CMD_PAGE_WR0, page, chip->page_size);
- chip->ops->write_buf(chip, chip->oob_poi, chip->oobsize);
- /* Send command to program the OOB data */
- status = chip->ops->cmdfunc(chip, NAND_CMD_PAGE_WR1, -1, -1);
-
- return status & NAND_STATUS_FAIL ? -EIO : 0;
-}
-
-static int nand_only_write_oob(rt_nand_t *chip, loff_t to, struct mtd_io_desc *desc)
-{
- int page, ret, len;
-
- if (desc->mode == MTD_OPM_AUTO_OOB)
- len = chip->freelayout->length;
- else
- len = chip->oobsize;
-
- /* Do not allow write past end of page */
- if ((desc->ooboffs + desc->ooblen) > len)
- {
- return -EINVAL;
- }
-
- if (desc->ooblen == 0)
- {
- return -EINVAL;
- }
-
- /* get page */
- page = (int)(to / chip->page_size);
-
- nand_fill_oob(chip, desc->oobbuf, desc->ooblen, desc);
-
- ret = nand_write_oob_std(chip, page);
- if (ret == 0)
- desc->oobretlen = len;
-
- return ret;
-}
-
-static int nand_erase(rt_mtd_t *mtd, loff_t addr, size_t size)
-{
- rt_nand_t *chip;
- int status;
- int page;
- uint32_t blksize;
-
- chip = MTDTONAND(mtd);
- blksize = mtd->block_size;
- page = addr / chip->page_size;
-
- while (size >= blksize)
- {
- status = chip->ops->cmdfunc(chip, NAND_CMD_BLK_ERASE, page, 0);
- if (status & NAND_STATUS_FAIL)
- {
- break;
- }
- size -= blksize;
- page += chip->pages_pb;
- }
-
- return size;
-}
-
-static int nand_read(rt_mtd_t *mtd, loff_t from, struct mtd_io_desc *desc)
-{
- int ret = -ENOTSUP;
- rt_nand_t *chip;
-
- chip = MTDTONAND(mtd);
-
- switch (desc->mode)
- {
- case MTD_OPM_PLACE_OOB:
- case MTD_OPM_AUTO_OOB:
- case MTD_OPM_RAW:
- break;
-
- default:
- goto out;
- }
-
- if (!desc->datbuf || !desc->datlen)
- ret = nand_only_read_oob(chip, from, desc);
- else
- ret = nand_do_read_desc(chip, from, desc);
-
-out:
-
- return ret;
-}
-
-static int nand_write(rt_mtd_t *mtd, loff_t to, struct mtd_io_desc *desc)
-{
- int ret = -ENOTSUP;
- rt_nand_t *chip;
-
- chip = MTDTONAND(mtd);
-
- switch (desc->mode)
- {
- case MTD_OPM_PLACE_OOB:
- case MTD_OPM_AUTO_OOB:
- case MTD_OPM_RAW:
- break;
-
- default:
- goto out;
- }
-
- if (!desc->datbuf || !desc->datlen)
- ret = nand_only_write_oob(chip, to, desc);
- else
- ret = nand_do_write_desc(chip, to, desc);
-
-out:
-
- return ret;
-}
-
-static int nand_block_isbad(rt_mtd_t *mtd, uint32_t blk)
-{
- int ret;
- rt_nand_t *chip = MTDTONAND(mtd);
-
- if (chip->ops->isbad)
- {
- ret = chip->ops->isbad(chip, blk);
- }
- else
- {
- int page;
-
- page = blk * chip->pages_pb;
- nand_read_oob_std(chip, page);
- ret = chip->oob_poi[0] != 0xFF;
- }
-
- return ret;
-}
-
-static int nand_block_markbad(rt_mtd_t *mtd, uint32_t blk)
-{
- int ret;
- rt_nand_t *chip;
-
- chip = MTDTONAND(mtd);
-
- if (chip->ops->markbad)
- {
- ret = chip->ops->markbad(chip, blk);
- }
- else
- {
- int page;
-
- page = blk * chip->pages_pb;
- rt_memset(chip->oob_poi, 0xff, chip->oobsize);
- chip->oob_poi[0] = 0;
- ret = nand_write_oob_std(chip, page);
- }
-
- return ret;
-}
-
-static const struct mtd_ops _ops =
-{
- nand_erase,
- nand_read,
- nand_write,
- nand_block_isbad,
- nand_block_markbad,
-};
-
-int rt_mtd_nand_init(rt_nand_t *nand, int blk_size, int page_size, int oob_size)
-{
- uint8_t *buf;
-
- buf = rt_malloc(oob_size * 3);
- if (buf == RT_NULL)
- return -ENOMEM;
-
- nand->oob_poi = buf;
- buf += oob_size;
- nand->buffers.ecccalc = buf;
- buf += oob_size;
- nand->buffers.ecccode = buf;
- nand->pagebuf = 0; /* alloc when unaligen access */
-
- nand->pages_pb = blk_size / page_size;
- nand->ecc._step = page_size / nand->ecc.stepsize;
- nand->page_size = page_size;
- nand->oobsize = oob_size;
-
- nand->parent.type = MTD_TYPE_NAND;
- nand->parent.ops = &_ops;
- nand->parent.sector_size = page_size;
- nand->parent.block_size = blk_size;
- nand->parent.oob_size = oob_size;
-
- switch (nand->ecc.mode)
- {
- case NAND_ECCM_NONE:
- {
- nand->read_page = nand_read_page_raw;
- nand->write_page = nand_write_page_raw;
- }break;
- case NAND_ECCM_HW:
- {
- nand->read_page = nand_read_page_hwecc;
- nand->write_page = nand_write_page_hwecc;
- }break;
- default:
- {
- rt_free(buf);
- return -1;
- }
- }
-
- return 0;
-}
diff --git a/components/drivers/mtd/mtdnor.c b/components/drivers/mtd/mtdnor.c
deleted file mode 100644
index 481d26167e..0000000000
--- a/components/drivers/mtd/mtdnor.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- 2018-09-10 heyuanjie87 first version
-
- */
-
-#include <drivers/mtdnor.h>
-
-#ifdef MTD_USING_NOR
-static int _nor_erase(rt_mtd_t *mtd, loff_t addr, size_t len)
-{
- rt_nor_t *nor;
-
- nor = (rt_nor_t *)mtd;
- return nor->ops->erase(nor, addr, len);
-}
-
-static int _nor_read(rt_mtd_t *mtd, loff_t from, struct mtd_io_desc *desc)
-{
- rt_nor_t *nor;
- int ret;
-
- nor = (rt_nor_t *)mtd;
- ret = nor->ops->read(nor, from, desc->datbuf, desc->datlen);
- if (ret > 0)
- {
- desc->datretlen = ret;
- ret = 0;
- }
-
- return ret;
-}
-
-static int _nor_write(rt_mtd_t *mtd, loff_t to, struct mtd_io_desc *desc)
-{
- rt_nor_t *nor;
- int ret;
-
- nor = (rt_nor_t *)mtd;
- ret = nor->ops->write(nor, to, desc->datbuf, desc->datlen);
- if (ret > 0)
- {
- desc->datretlen = ret;
- ret = 0;
- }
-
- return ret;
-}
-
-static const struct mtd_ops _ops =
-{
- _nor_erase,
- _nor_read,
- _nor_write,
- 0,
- 0
-};
-
-int rt_mtd_nor_init(rt_nor_t *nor, int blksize)
-{
- nor->parent.sector_size = 1;
- nor->parent.block_size = blksize;
- nor->parent.ops = &_ops;
- nor->parent.type = MTD_TYPE_NOR;
- nor->parent.oob_size = 0;
-
- return 0;
-}
-#endif
diff --git a/components/drivers/phy/SConscript b/components/drivers/phy/SConscript
new file mode 100644
index 0000000000..ec12ed24c2
--- /dev/null
+++ b/components/drivers/phy/SConscript
@@ -0,0 +1,8 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+CPPPATH = [cwd + '/../include']
+group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_PHY'], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/components/drivers/phy/phy.c b/components/drivers/phy/phy.c
new file mode 100644
index 0000000000..3ed4a1a265
--- /dev/null
+++ b/components/drivers/phy/phy.c
@@ -0,0 +1,78 @@
+
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-09-27 wangqiang first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "PHY"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+
+static rt_size_t phy_device_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t count)
+{
+ struct rt_phy_device *phy = (struct rt_phy_device *)dev->user_data;
+ struct rt_phy_msg *msg = (struct rt_phy_msg *)buffer;
+ return phy->bus->ops->read(phy->bus, phy->addr, msg->reg, &(msg->value), 4);
+}
+static rt_size_t phy_device_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t count)
+{
+ struct rt_phy_device *phy = (struct rt_phy_device *)dev->user_data;
+ struct rt_phy_msg *msg = (struct rt_phy_msg *)buffer;
+ return phy->bus->ops->write(phy->bus, phy->addr, msg->reg, &(msg->value), 4);
+}
+
+
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops phy_ops =
+{
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ phy_device_read,
+ phy_device_write,
+ RT_NULL,
+};
+#endif
+
+/*
+* phy device register
+*/
+rt_err_t rt_hw_phy_register(struct rt_phy_device *phy, const char *name)
+{
+ rt_err_t ret;
+ struct rt_device *device;
+
+ device = &(phy->parent);
+
+ device->type = RT_Device_Class_PHY;
+ device->rx_indicate = RT_NULL;
+ device->tx_complete = RT_NULL;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = phy_ops;
+#else
+ device->init = NULL;
+ device->open = NULL;
+ device->close = NULL;
+ device->read = phy_device_read;
+ device->write = phy_device_write;
+ device->control = NULL;
+#endif
+ device->user_data = phy;
+
+ /* register a character device */
+ ret = rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
+
+ return ret;
+}
diff --git a/components/drivers/pm/pm.c b/components/drivers/pm/pm.c
index c300414444..dd7cc2ae63 100644
--- a/components/drivers/pm/pm.c
+++ b/components/drivers/pm/pm.c
@@ -7,6 +7,7 @@
* Date Author Notes
* 2012-06-02 Bernard the first version
* 2018-08-02 Tanek split run and sleep modes, support custom mode
+ * 2019-04-28 Zero-Free improve PM mode and device ops interface
*/
#include <rthw.h>
@@ -16,27 +17,46 @@
#ifdef RT_USING_PM
static struct rt_pm _pm;
+static rt_uint8_t _pm_default_sleep = RT_PM_DEFAULT_SLEEP_MODE;
+static struct rt_pm_notify _pm_notify;
+static rt_uint8_t _pm_init_flag = 0;
+
+#define RT_PM_TICKLESS_THRESH (2)
+
+RT_WEAK rt_uint32_t rt_pm_enter_critical(rt_uint8_t sleep_mode)
+{
+ return rt_hw_interrupt_disable();
+}
+
+RT_WEAK void rt_pm_exit_critical(rt_uint32_t ctx, rt_uint8_t sleep_mode)
+{
+ rt_hw_interrupt_enable(ctx);
+}
/**
* This function will suspend all registered devices
*/
-static void _pm_device_suspend(void)
+static int _pm_device_suspend(rt_uint8_t mode)
{
- int index;
+ int index, ret = RT_EOK;
for (index = 0; index < _pm.device_pm_number; index++)
{
if (_pm.device_pm[index].ops->suspend != RT_NULL)
{
- _pm.device_pm[index].ops->suspend(_pm.device_pm[index].device);
+ ret = _pm.device_pm[index].ops->suspend(_pm.device_pm[index].device, mode);
+ if(ret != RT_EOK)
+ break;
}
}
+
+ return ret;
}
/**
* This function will resume all registered devices
*/
-static void _pm_device_resume(void)
+static void _pm_device_resume(rt_uint8_t mode)
{
int index;
@@ -44,16 +64,15 @@ static void _pm_device_resume(void)
{
if (_pm.device_pm[index].ops->resume != RT_NULL)
{
- _pm.device_pm[index].ops->resume(_pm.device_pm[index].device);
+ _pm.device_pm[index].ops->resume(_pm.device_pm[index].device, mode);
}
}
}
-#if PM_RUN_MODE_COUNT > 1
/**
* This function will update the frequency of all registered devices
*/
-static void _pm_device_frequency_change(void)
+static void _pm_device_frequency_change(rt_uint8_t mode)
{
rt_uint32_t index;
@@ -61,152 +80,151 @@ static void _pm_device_frequency_change(void)
for (index = 0; index < _pm.device_pm_number; index ++)
{
if (_pm.device_pm[index].ops->frequency_change != RT_NULL)
- _pm.device_pm[index].ops->frequency_change(_pm.device_pm[index].device);
+ _pm.device_pm[index].ops->frequency_change(_pm.device_pm[index].device, mode);
}
}
-#endif
/**
- * This function will enter corresponding power mode.
+ * This function will update the system clock frequency when idle
*/
-void rt_pm_enter(void)
+static void _pm_frequency_scaling(struct rt_pm *pm)
{
- rt_ubase_t level;
- struct rt_pm *pm;
- rt_uint32_t index;
- rt_tick_t timeout_tick;
+ rt_base_t level;
- pm = &_pm;
+ if (pm->flags & RT_PM_FREQUENCY_PENDING)
+ {
+ level = rt_hw_interrupt_disable();
+ /* change system runing mode */
+ pm->ops->run(pm, pm->run_mode);
+ /* changer device frequency */
+ _pm_device_frequency_change(pm->run_mode);
+ pm->flags &= ~RT_PM_FREQUENCY_PENDING;
+ rt_hw_interrupt_enable(level);
+ }
+}
- /* disable interrupt before check run modes */
- level = rt_hw_interrupt_disable();
- /* check each run mode, and decide to swithc to run mode or sleep mode */
- for (index = 0; index < PM_RUN_MODE_COUNT; index++)
+/**
+ * This function selects the sleep mode according to the rt_pm_request/rt_pm_release count.
+ */
+static rt_uint8_t _pm_select_sleep_mode(struct rt_pm *pm)
+{
+ int index;
+ rt_uint8_t mode;
+
+ mode = _pm_default_sleep;
+ for (index = PM_SLEEP_MODE_NONE; index < PM_SLEEP_MODE_MAX; index ++)
{
if (pm->modes[index])
{
- if (index > pm->current_mode)
- {
- pm->ops->exit(pm);
- pm->current_mode = index;
- pm->ops->enter(pm);
-#if PM_RUN_MODE_COUNT > 1
- pm->ops->frequency_change(pm, 0);
- _pm_device_frequency_change();
-#endif
- }
-
- rt_hw_interrupt_enable(level);
- /* The current mode is run mode, no need to check sleep mode */
- return ;
+ mode = index;
+ break;
}
}
- /* enable interrupt after check run modes */
- rt_hw_interrupt_enable(level);
+ pm->sleep_mode = mode;
- level = rt_hw_interrupt_disable();
- /* check each sleep mode to decide which mode can system sleep. */
- for (index = PM_SLEEP_MODE_START; index < PM_SLEEP_MODE_START + PM_SLEEP_MODE_COUNT; index++)
+ return mode;
+}
+
+/**
+ * This function changes the power sleep mode base on the result of selection
+ */
+static void _pm_change_sleep_mode(struct rt_pm *pm, rt_uint8_t mode)
+{
+ rt_tick_t timeout_tick, delta_tick;
+ rt_base_t level;
+ int ret = RT_EOK;
+
+ if (mode == PM_SLEEP_MODE_NONE)
{
- if (pm->modes[index])
- {
- /* let mcu sleep when system is idle */
+ pm->sleep_mode = mode;
+ pm->ops->sleep(pm, PM_SLEEP_MODE_NONE);
+ }
+ else
+ {
+ level = rt_pm_enter_critical(mode);
- /* run mode to sleep mode */
- if (pm->current_mode < PM_SLEEP_MODE_START)
- {
- /* exit run mode */
- pm->ops->exit(pm);
- }
+ /* Notify app will enter sleep mode */
+ if (_pm_notify.notify)
+ _pm_notify.notify(RT_PM_ENTER_SLEEP, mode, _pm_notify.data);
- /* set current power mode */
- pm->current_mode = index;
- pm->exit_count = 1;
+ /* Suspend all peripheral device */
+ ret = _pm_device_suspend(mode);
+ if (ret != RT_EOK)
+ {
+ _pm_device_resume(mode);
+ if (_pm_notify.notify)
+ _pm_notify.notify(RT_PM_EXIT_SLEEP, mode, _pm_notify.data);
+ rt_pm_exit_critical(level, mode);
- /* suspend all of devices with PM feature */
- _pm_device_suspend();
+ return;
+ }
- /* should start pm timer */
- if (pm->timer_mask & (1 << index))
+ /* Tickless*/
+ if (pm->timer_mask & (0x01 << mode))
+ {
+ timeout_tick = rt_timer_next_timeout_tick();
+ if (timeout_tick == RT_TICK_MAX)
{
- /* get next os tick */
- timeout_tick = rt_timer_next_timeout_tick();
- if (timeout_tick != RT_TICK_MAX)
+ if (pm->ops->timer_start)
{
- timeout_tick -= rt_tick_get();
-
-#if defined(PM_MIN_ENTER_SLEEP_TICK) && PM_MIN_ENTER_SLEEP_TICK > 0
- if (timeout_tick < PM_MIN_ENTER_SLEEP_TICK)
- {
- rt_hw_interrupt_enable(level);
- /* limit the minimum time to enter timer sleep mode */
- return ;
- }
-#endif
+ pm->ops->timer_start(pm, RT_TICK_MAX);
}
- /* startup pm timer */
- pm->ops->timer_start(pm, timeout_tick);
}
+ else
+ {
+ timeout_tick = timeout_tick - rt_tick_get();
+ if (timeout_tick < RT_PM_TICKLESS_THRESH)
+ {
+ mode = PM_SLEEP_MODE_IDLE;
+ }
+ else
+ {
+ pm->ops->timer_start(pm, timeout_tick);
+ }
+ }
+ }
- /* enter sleep and wait to be waken up */
- pm->ops->enter(pm);
-
- /* exit from low power mode */
- rt_pm_exit();
+ /* enter lower power state */
+ pm->ops->sleep(pm, mode);
- rt_hw_interrupt_enable(level);
- return ;
+ /* wake up from lower power state*/
+ if (pm->timer_mask & (0x01 << mode))
+ {
+ delta_tick = pm->ops->timer_get_tick(pm);
+ pm->ops->timer_stop(pm);
+ if (delta_tick)
+ {
+ rt_tick_set(rt_tick_get() + delta_tick);
+ rt_timer_check();
+ }
}
- }
- rt_hw_interrupt_enable(level);
+ /* resume all device */
+ _pm_device_resume(pm->sleep_mode);
+
+ if (_pm_notify.notify)
+ _pm_notify.notify(RT_PM_EXIT_SLEEP, mode, _pm_notify.data);
+
+ rt_pm_exit_critical(level, mode);
+ }
}
/**
- * This function exits from sleep mode.
+ * This function will enter corresponding power mode.
*/
-void rt_pm_exit(void)
+void rt_system_power_manager(void)
{
- rt_ubase_t level;
- struct rt_pm *pm;
- rt_tick_t delta_tick;
+ rt_uint8_t mode;
- pm = &_pm;
-
- level = rt_hw_interrupt_disable();
-
- if (pm->exit_count)
- {
- pm->exit_count = 0;
-
- if (pm->current_mode >= PM_SLEEP_MODE_START)
- {
- /* sleep mode with timer */
- if (pm->timer_mask & (1 << pm->current_mode))
- {
- /* get the tick of pm timer */
- delta_tick = pm->ops->timer_get_tick(pm);
-
- /* stop pm timer */
- pm->ops->timer_stop(pm);
-
- if (delta_tick)
- {
- /* adjust OS tick */
- rt_tick_set(rt_tick_get() + delta_tick);
- /* check system timer */
- rt_timer_check();
- }
- }
+ if (_pm_init_flag == 0)
+ return;
- /* exit from sleep mode */
- pm->ops->exit(pm);
- /* resume the device with PM feature */
- _pm_device_resume();
- }
- }
+ /* CPU frequency scaling according to the runing mode settings */
+ _pm_frequency_scaling(&_pm);
- rt_hw_interrupt_enable(level);
+ /* Low Power Mode Processing */
+ mode = _pm_select_sleep_mode(&_pm);
+ _pm_change_sleep_mode(&_pm, mode);
}
/**
@@ -215,60 +233,21 @@ void rt_pm_exit(void)
*
* @param parameter the parameter of run mode or sleep mode
*/
-void rt_pm_request(rt_ubase_t mode)
+void rt_pm_request(rt_uint8_t mode)
{
- rt_ubase_t level;
+ rt_base_t level;
struct rt_pm *pm;
- pm = &_pm;
+ if (_pm_init_flag == 0)
+ return;
- if (mode > PM_MODE_MAX)
+ if (mode > (PM_SLEEP_MODE_MAX - 1))
return;
level = rt_hw_interrupt_disable();
-
- /* update pm modes table */
- pm->modes[mode] ++;
-
- /* request higter mode with a smaller mode value*/
- if (mode < pm->current_mode)
- {
- /* the old current mode is RUN mode, need to all pm->ops->exit(),
- * if not, it has already called in rt_pm_exit()
- */
- if (pm->current_mode < PM_SLEEP_MODE_START)
- {
- pm->ops->exit(pm);
- }
- else if (pm->exit_count)
- {
- /* call exeit when global interrupt is disable */
- pm->ops->exit(pm);
- pm->exit_count = 0;
- }
-
- /* update current mode */
- pm->current_mode = mode;
-
- /* current mode is higher run mode */
- if (mode < PM_SLEEP_MODE_START)
- {
- /* enter run mode */
- pm->ops->enter(pm);
-#if PM_RUN_MODE_COUNT > 1
- /* frequency change */
- pm->ops->frequency_change(pm, 0);
- _pm_device_frequency_change();
-#endif
- }
- else
- {
- /* do nothing when request higher sleep mode,
- * and swithc to new sleep mode in rt_pm_enter()
- */
- }
- }
-
+ pm = &_pm;
+ if (pm->modes[mode] < 255)
+ pm->modes[mode] ++;
rt_hw_interrupt_enable(level);
}
@@ -279,21 +258,21 @@ void rt_pm_request(rt_ubase_t mode)
* @param parameter the parameter of run mode or sleep mode
*
*/
-void rt_pm_release(rt_ubase_t mode)
+void rt_pm_release(rt_uint8_t mode)
{
rt_ubase_t level;
struct rt_pm *pm;
- pm = &_pm;
+ if (_pm_init_flag == 0)
+ return;
- if (mode > PM_MODE_MAX)
+ if (mode > (PM_SLEEP_MODE_MAX - 1))
return;
level = rt_hw_interrupt_disable();
-
+ pm = &_pm;
if (pm->modes[mode] > 0)
pm->modes[mode] --;
-
rt_hw_interrupt_enable(level);
}
@@ -303,9 +282,9 @@ void rt_pm_release(rt_ubase_t mode)
* @param device the device with PM feature
* @param ops the PM ops for device
*/
-void rt_pm_register_device(struct rt_device *device, const struct rt_device_pm_ops *ops)
+void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops)
{
- rt_ubase_t level;
+ rt_base_t level;
struct rt_device_pm *device_pm;
RT_DEBUG_NOT_IN_INTERRUPT;
@@ -322,8 +301,6 @@ void rt_pm_register_device(struct rt_device *device, const struct rt_device_pm_o
_pm.device_pm_number += 1;
}
- rt_sem_release(&(_pm.device_lock));
-
rt_hw_interrupt_enable(level);
}
@@ -332,7 +309,7 @@ void rt_pm_register_device(struct rt_device *device, const struct rt_device_pm_o
*
* @param device the device with PM feature
*/
-void rt_pm_unregister_device(struct rt_device *device)
+void rt_pm_device_unregister(struct rt_device *device)
{
rt_ubase_t level;
rt_uint32_t index;
@@ -363,6 +340,23 @@ void rt_pm_unregister_device(struct rt_device *device)
}
/**
+ * This function set notification callback for application
+ */
+void rt_pm_notify_set(void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data), void *data)
+{
+ _pm_notify.notify = notify;
+ _pm_notify.data = data;
+}
+
+/**
+ * This function set default sleep mode when no pm_request
+ */
+void rt_pm_default_set(rt_uint8_t sleep_mode)
+{
+ _pm_default_sleep = sleep_mode;
+}
+
+/**
* RT-Thread device interface for PM device
*/
static rt_size_t _rt_pm_device_read(rt_device_t dev,
@@ -377,7 +371,7 @@ static rt_size_t _rt_pm_device_read(rt_device_t dev,
pm = (struct rt_pm *)dev;
RT_ASSERT(pm != RT_NULL);
- if (pos <= PM_MODE_MAX)
+ if (pos < PM_SLEEP_MODE_MAX)
{
int mode;
@@ -399,11 +393,11 @@ static rt_size_t _rt_pm_device_write(rt_device_t dev,
{
/* get request */
request = *(unsigned char *)buffer;
- if (request == '1')
+ if (request == 0x01)
{
rt_pm_request(pos);
}
- else if (request == '0')
+ else if (request == 0x00)
{
rt_pm_release(pos);
}
@@ -434,6 +428,48 @@ static rt_err_t _rt_pm_device_control(rt_device_t dev,
return RT_EOK;
}
+int rt_pm_run_enter(rt_uint8_t mode)
+{
+ rt_base_t level;
+ struct rt_pm *pm;
+
+ if (_pm_init_flag == 0)
+ return -RT_EIO;
+
+ if (mode > PM_RUN_MODE_MAX)
+ return -RT_EINVAL;
+
+ level = rt_hw_interrupt_disable();
+ pm = &_pm;
+ if (mode < pm->run_mode)
+ {
+ /* change system runing mode */
+ pm->ops->run(pm, mode);
+ /* changer device frequency */
+ _pm_device_frequency_change(mode);
+ }
+ else
+ {
+ pm->flags |= RT_PM_FREQUENCY_PENDING;
+ }
+ pm->run_mode = mode;
+ rt_hw_interrupt_enable(level);
+
+ return RT_EOK;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops pm_ops =
+{
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ _rt_pm_device_read,
+ _rt_pm_device_write,
+ _rt_pm_device_control,
+};
+#endif
+
/**
* This function will initialize power management.
*
@@ -455,23 +491,24 @@ void rt_system_pm_init(const struct rt_pm_ops *ops,
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = &pm_ops;
+#else
device->init = RT_NULL;
device->open = RT_NULL;
device->close = RT_NULL;
device->read = _rt_pm_device_read;
device->write = _rt_pm_device_write;
device->control = _rt_pm_device_control;
+#endif
device->user_data = user_data;
/* register PM device to the system */
rt_device_register(device, "pm", RT_DEVICE_FLAG_RDWR);
- /* todo : add to kernel source code */
- rt_thread_idle_sethook(rt_pm_enter);
-
rt_memset(pm->modes, 0, sizeof(pm->modes));
- pm->current_mode = PM_RUN_MODE_DEFAULT;
-
+ pm->sleep_mode = _pm_default_sleep;
+ pm->run_mode = RT_PM_DEFAULT_RUN_MODE;
pm->timer_mask = timer_mask;
pm->ops = ops;
@@ -479,24 +516,15 @@ void rt_system_pm_init(const struct rt_pm_ops *ops,
pm->device_pm = RT_NULL;
pm->device_pm_number = 0;
- /* initialize semaphore */
- rt_sem_init(&(pm->device_lock), "pm", 1, RT_IPC_FLAG_FIFO);
-
- /* request in default running mode */
- rt_pm_request(PM_RUN_MODE_DEFAULT);
-
-#ifdef PM_SLEEP_MODE_DEFAULT
- /* request in default sleep mode */
- rt_pm_request(PM_SLEEP_MODE_DEFAULT);
-#endif
-
- /* must hold on deep shutdown mode */
- rt_pm_request(PM_MODE_MAX);
+ _pm_init_flag = 1;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
+static const char *_pm_sleep_str[] = PM_SLEEP_MODE_NAMES;
+static const char *_pm_run_str[] = PM_RUN_MODE_NAMES;
+
static void rt_pm_release_mode(int argc, char **argv)
{
int mode = 0;
@@ -521,9 +549,20 @@ static void rt_pm_request_mode(int argc, char **argv)
}
MSH_CMD_EXPORT_ALIAS(rt_pm_request_mode, pm_request, request power management mode);
+static void rt_pm_run_mode_switch(int argc, char **argv)
+{
+ int mode = 0;
+ if (argc >= 2)
+ {
+ mode = atoi(argv[1]);
+ }
+
+ rt_pm_run_enter(mode);
+}
+MSH_CMD_EXPORT_ALIAS(rt_pm_run_mode_switch, pm_run, switch power management run mode);
+
static void rt_pm_dump_status(void)
{
- static const char *pm_str[] = PM_MODE_NAMES;
rt_uint32_t index;
struct rt_pm *pm;
@@ -531,17 +570,18 @@ static void rt_pm_dump_status(void)
rt_kprintf("| Power Management Mode | Counter | Timer |\n");
rt_kprintf("+-----------------------+---------+-------+\n");
- for (index = 0; index <= PM_MODE_MAX; index ++)
+ for (index = 0; index < PM_SLEEP_MODE_MAX; index ++)
{
int has_timer = 0;
if (pm->timer_mask & (1 << index))
has_timer = 1;
- rt_kprintf("| %021s | %7d | %5d |\n", pm_str[index], pm->modes[index], has_timer);
+ rt_kprintf("| %021s | %7d | %5d |\n", _pm_sleep_str[index], pm->modes[index], has_timer);
}
rt_kprintf("+-----------------------+---------+-------+\n");
- rt_kprintf("pm current mode: %s\n", pm_str[pm->current_mode]);
+ rt_kprintf("pm current sleep mode: %s\n", _pm_sleep_str[pm->sleep_mode]);
+ rt_kprintf("pm current run mode: %s\n", _pm_run_str[pm->run_mode]);
}
FINSH_FUNCTION_EXPORT_ALIAS(rt_pm_dump_status, pm_dump, dump power management status);
MSH_CMD_EXPORT_ALIAS(rt_pm_dump_status, pm_dump, dump power management status);
diff --git a/components/drivers/rtc/alarm.c b/components/drivers/rtc/alarm.c
index c497ebf727..71b6e7236a 100644
--- a/components/drivers/rtc/alarm.c
+++ b/components/drivers/rtc/alarm.c
@@ -7,6 +7,7 @@
* Date Author Notes
* 2012-10-27 heyuanjie87 first version.
* 2013-05-17 aozima initial alarm event & mutex in system init.
+ * 2020-10-15 zhangsz add alarm flags hour minute second.
*/
#include <rtthread.h>
@@ -97,6 +98,61 @@ static void alarm_wakeup(struct rt_alarm *alarm, struct tm *now)
}
}
break;
+ case RT_ALARM_SECOND:
+ {
+ alarm->wktime.tm_hour = now->tm_hour;
+ alarm->wktime.tm_min = now->tm_min;
+ alarm->wktime.tm_sec = alarm->wktime.tm_sec + 1;
+ if (alarm->wktime.tm_sec > 59)
+ {
+ alarm->wktime.tm_sec = 0;
+ alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
+ if (alarm->wktime.tm_min > 59)
+ {
+ alarm->wktime.tm_min = 0;
+ alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ }
+ }
+ wakeup = RT_TRUE;
+ }
+ break;
+ case RT_ALARM_MINUTE:
+ {
+ alarm->wktime.tm_hour = now->tm_hour;
+ if (alarm->wktime.tm_sec == now->tm_sec)
+ {
+ alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
+ if (alarm->wktime.tm_min > 59)
+ {
+ alarm->wktime.tm_min = 0;
+ alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ }
+ wakeup = RT_TRUE;
+ }
+ }
+ break;
+ case RT_ALARM_HOUR:
+ {
+ if ((alarm->wktime.tm_min == now->tm_min) &&
+ (alarm->wktime.tm_sec == now->tm_sec))
+ {
+ alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ wakeup = RT_TRUE;
+ }
+ }
+ break;
case RT_ALARM_DAILY:
{
if (((sec_now - sec_alarm) <= RT_ALARM_DELAY) && (sec_now >= sec_alarm))
@@ -177,7 +233,7 @@ static void alarm_update(rt_uint32_t event)
/* calculate seconds from 00:00:00 */
sec_alarm = alarm_mkdaysec(&alarm->wktime);
- if ((alarm->flag & RT_ALARM_STATE_START) && (alarm != _container.current))
+ if (alarm->flag & RT_ALARM_STATE_START)
{
sec_tmp = sec_alarm - sec_now;
if (sec_tmp > 0)
@@ -212,6 +268,11 @@ static void alarm_update(rt_uint32_t event)
if (alarm_set(alm_prev) == RT_EOK)
_container.current = alm_prev;
}
+ else
+ {
+ if (_container.current != RT_NULL)
+ alarm_set(_container.current);
+ }
}
rt_mutex_release(&_container.mutex);
}
@@ -279,6 +340,51 @@ static rt_err_t alarm_setup(rt_alarm_t alarm, struct tm *wktime)
switch (alarm->flag & 0xFF00)
{
+ case RT_ALARM_SECOND:
+ {
+ alarm->wktime.tm_hour = now.tm_hour;
+ alarm->wktime.tm_min = now.tm_min;
+ alarm->wktime.tm_sec = now.tm_sec + 1;
+ if (alarm->wktime.tm_sec > 59)
+ {
+ alarm->wktime.tm_sec = 0;
+ alarm->wktime.tm_min = alarm->wktime.tm_min + 1;
+ if (alarm->wktime.tm_min > 59)
+ {
+ alarm->wktime.tm_min = 0;
+ alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ }
+ }
+ }
+ break;
+ case RT_ALARM_MINUTE:
+ {
+ alarm->wktime.tm_hour = now.tm_hour;
+ alarm->wktime.tm_min = now.tm_min + 1;
+ if (alarm->wktime.tm_min > 59)
+ {
+ alarm->wktime.tm_min = 0;
+ alarm->wktime.tm_hour = alarm->wktime.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ }
+ }
+ break;
+ case RT_ALARM_HOUR:
+ {
+ alarm->wktime.tm_hour = now.tm_hour + 1;
+ if (alarm->wktime.tm_hour > 23)
+ {
+ alarm->wktime.tm_hour = 0;
+ }
+ }
+ break;
case RT_ALARM_DAILY:
{
/* do nothing but needed */
@@ -426,17 +532,17 @@ rt_err_t rt_alarm_start(rt_alarm_t alarm)
if (alarm == RT_NULL)
return (ret);
rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
- if (!(alarm->flag & RT_ALARM_STATE_INITED))
+
+ if (!(alarm->flag & RT_ALARM_STATE_START))
{
if (alarm_setup(alarm, &alarm->wktime) != RT_EOK)
goto _exit;
- }
- if ((alarm->flag & 0x01) == RT_ALARM_STATE_STOP)
- {
+
timestamp = time(RT_NULL);
localtime_r(&timestamp, &now);
alarm->flag |= RT_ALARM_STATE_START;
+
/* set alarm */
if (_container.current == RT_NULL)
{
@@ -518,10 +624,10 @@ _exit:
*/
rt_err_t rt_alarm_delete(rt_alarm_t alarm)
{
- rt_err_t ret = RT_ERROR;
+ rt_err_t ret = RT_EOK;
if (alarm == RT_NULL)
- return (ret);
+ return RT_ERROR;
rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
/* stop the alarm */
alarm->flag &= ~RT_ALARM_STATE_START;
@@ -551,9 +657,11 @@ rt_alarm_t rt_alarm_create(rt_alarm_callback_t callback, struct rt_alarm_setup *
if (setup == RT_NULL)
return (RT_NULL);
+
alarm = rt_malloc(sizeof(struct rt_alarm));
if (alarm == RT_NULL)
return (RT_NULL);
+
rt_list_init(&alarm->list);
alarm->wktime = setup->wktime;
@@ -586,13 +694,33 @@ static void rt_alarmsvc_thread_init(void *param)
}
}
+void rt_alarm_dump(void)
+{
+ rt_list_t *next;
+ rt_alarm_t alarm;
+ rt_uint8_t index = 0;
+
+ rt_kprintf("| alarm_id | YYYY-MM-DD hh:mm:ss | weekday | flags |\n");
+ rt_kprintf("+----------+---------------------+---------+---------+\n");
+ for (next = _container.head.next; next != &_container.head; next = next->next)
+ {
+ alarm = rt_list_entry(next, struct rt_alarm, list);
+ rt_kprintf("| No %5d | %04d-%02d-%02d %02d:%02d:%02d | %7d | 0x%04x |\n",
+ index++, alarm->wktime.tm_year + 1900, alarm->wktime.tm_mon + 1, alarm->wktime.tm_mday,
+ alarm->wktime.tm_hour, alarm->wktime.tm_min, alarm->wktime.tm_sec,
+ alarm->wktime.tm_wday, alarm->flag);
+ }
+ rt_kprintf("+----------+---------------------+---------+---------+\n");
+}
+
+FINSH_FUNCTION_EXPORT_ALIAS(rt_alarm_dump, __cmd_alarm_dump, dump alarm info);
/** \brief initialize alarm service system
*
* \param none
* \return none
*/
-void rt_alarm_system_init(void)
+int rt_alarm_system_init(void)
{
rt_thread_t tid;
@@ -602,8 +730,12 @@ void rt_alarm_system_init(void)
tid = rt_thread_create("alarmsvc",
rt_alarmsvc_thread_init, RT_NULL,
- 512, 8, 1);
+ 2048, 10, 5);
if (tid != RT_NULL)
rt_thread_startup(tid);
+
+ return 0;
}
+
+INIT_PREV_EXPORT(rt_alarm_system_init);
#endif
diff --git a/components/drivers/rtc/rtc.c b/components/drivers/rtc/rtc.c
index e17c0fe7dd..682515ce98 100644
--- a/components/drivers/rtc/rtc.c
+++ b/components/drivers/rtc/rtc.c
@@ -179,7 +179,7 @@ void list_date(void)
time_t now;
now = time(RT_NULL);
- rt_kprintf("%s\n", ctime(&now));
+ rt_kprintf("%.*s\n", 25, ctime(&now));
}
FINSH_FUNCTION_EXPORT(list_date, show date and time.)
@@ -194,7 +194,7 @@ static void date(uint8_t argc, char **argv)
time_t now;
/* output current time */
now = time(RT_NULL);
- rt_kprintf("%s", ctime(&now));
+ rt_kprintf("%.*s", 25, ctime(&now));
}
else if (argc >= 7)
{
diff --git a/components/drivers/sdio/block_dev.c b/components/drivers/sdio/block_dev.c
index 23be319fc6..602acb9aa7 100644
--- a/components/drivers/sdio/block_dev.c
+++ b/components/drivers/sdio/block_dev.c
@@ -13,14 +13,12 @@
#include <drivers/mmcsd_core.h>
-#define DBG_ENABLE
-#define DBG_SECTION_NAME "SDIO"
+#define DBG_TAG "SDIO"
#ifdef RT_SDIO_DEBUG
-#define DBG_LEVEL DBG_LOG
+#define DBG_LVL DBG_LOG
#else
-#define DBG_LEVEL DBG_INFO
+#define DBG_LVL DBG_INFO
#endif /* RT_SDIO_DEBUG */
-#define DBG_COLOR
#include <rtdbg.h>
static rt_list_t blk_devices = RT_LIST_OBJECT_INIT(blk_devices);
@@ -369,7 +367,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
return err;
}
- LOG_I("probe mmcsd block device!");
+ LOG_D("probe mmcsd block device!");
/* get the first sector to read partition table */
sector = (rt_uint8_t *)rt_malloc(SECTOR_SIZE);
@@ -462,8 +460,6 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
rt_device_register(&blk_dev->dev, "sd0",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
rt_list_insert_after(&blk_devices, &blk_dev->list);
-
- break;
}
else
{
@@ -474,7 +470,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
}
#ifdef RT_USING_DFS_MNTTABLE
- if (0) // if (blk_dev)
+ if (blk_dev)
{
LOG_I("try to mount file system!");
/* try to mount file system on this block device */
@@ -509,9 +505,10 @@ void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card)
const char * mounted_path = dfs_filesystem_get_mounted_path(&(blk_dev->dev));
if (mounted_path)
{
- dfs_unmount(mounted_path);
+ dfs_unmount(mounted_path);
+ LOG_D("unmount file system %s for device %s.\r\n", mounted_path, blk_dev->dev.parent.name);
}
-
+ rt_sem_delete(blk_dev->part.lock);
rt_device_unregister(&blk_dev->dev);
rt_list_remove(&blk_dev->list);
rt_free(blk_dev);
diff --git a/components/drivers/sdio/mmc.c b/components/drivers/sdio/mmc.c
index bbf0ff838c..c1c56d37fd 100644
--- a/components/drivers/sdio/mmc.c
+++ b/components/drivers/sdio/mmc.c
@@ -4,21 +4,19 @@
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
- * Date Author Notes
- * 2015-06-15 hichard first version
+ * Date Author Notes
+ * 2015-06-15 hichard first version
*/
#include <drivers/mmcsd_core.h>
#include <drivers/mmc.h>
-#define DBG_ENABLE
-#define DBG_SECTION_NAME "SDIO"
+#define DBG_TAG "SDIO"
#ifdef RT_SDIO_DEBUG
-#define DBG_LEVEL DBG_LOG
+#define DBG_LVL DBG_LOG
#else
-#define DBG_LEVEL DBG_INFO
+#define DBG_LVL DBG_INFO
#endif /* RT_SDIO_DEBUG */
-#define DBG_COLOR
#include <rtdbg.h>
static const rt_uint32_t tran_unit[] =
@@ -184,6 +182,8 @@ static int mmc_get_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t **new_ext_csd)
*/
static int mmc_parse_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
{
+ rt_uint64_t card_capacity = 0;
+
if(card == RT_NULL || ext_csd == RT_NULL)
{
LOG_E("emmc parse ext csd fail, invaild args");
@@ -191,11 +191,12 @@ static int mmc_parse_ext_csd(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
}
card->flags |= CARD_FLAG_HIGHSPEED;
- card->hs_max_data_rate = 200000000;
+ card->hs_max_data_rate = 52000000;
- card->card_capacity = *((rt_uint32_t *)&ext_csd[EXT_CSD_SEC_CNT]);
- card->card_capacity *= card->card_blksize;
- card->card_capacity >>= 10; /* unit:KB */
+ card_capacity = *((rt_uint32_t *)&ext_csd[EXT_CSD_SEC_CNT]);
+ card_capacity *= card->card_blksize;
+ card_capacity >>= 10; /* unit:KB */
+ card->card_capacity = card_capacity;
LOG_I("emmc card capacity %d KB.", card->card_capacity);
return 0;
@@ -317,8 +318,17 @@ static int mmc_select_bus_width(struct rt_mmcsd_card *card, rt_uint8_t *ext_csd)
* the device to work in 8bit transfer mode. If the
* mmc switch command returns error then switch to
* 4bit transfer mode. On success set the corresponding
- * bus width on the host.
+ * bus width on the host. Meanwhile, mmc core would
+ * bail out early if corresponding bus capable wasn't
+ * set by drivers.
*/
+ if ((!(host->flags & MMCSD_BUSWIDTH_8) &&
+ ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8) ||
+ (!(host->flags & MMCSD_BUSWIDTH_4) &&
+ (ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_4 ||
+ ext_csd_bits[idx] == EXT_CSD_BUS_WIDTH_8)))
+ continue;
+
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_BUS_WIDTH,
ext_csd_bits[idx]);
@@ -503,16 +513,10 @@ static rt_int32_t mmcsd_mmc_init_card(struct rt_mmcsd_host *host,
card->flags |= CARD_FLAG_SDHC;
/* set bus speed */
- max_data_rate = (unsigned int)-1;
if (card->flags & CARD_FLAG_HIGHSPEED)
- {
- if (max_data_rate > card->hs_max_data_rate)
- max_data_rate = card->hs_max_data_rate;
- }
- else if (max_data_rate > card->max_data_rate)
- {
+ max_data_rate = card->hs_max_data_rate;
+ else
max_data_rate = card->max_data_rate;
- }
mmcsd_set_clock(host, max_data_rate);
diff --git a/components/drivers/sdio/mmcsd_core.c b/components/drivers/sdio/mmcsd_core.c
index d1f5978374..99bc6ce744 100644
--- a/components/drivers/sdio/mmcsd_core.c
+++ b/components/drivers/sdio/mmcsd_core.c
@@ -14,14 +14,12 @@
#include <drivers/mmc.h>
#include <drivers/sdio.h>
-#define DBG_ENABLE
-#define DBG_SECTION_NAME "SDIO"
+#define DBG_TAG "SDIO"
#ifdef RT_SDIO_DEBUG
-#define DBG_LEVEL DBG_LOG
+#define DBG_LVL DBG_LOG
#else
-#define DBG_LEVEL DBG_INFO
+#define DBG_LVL DBG_INFO
#endif /* RT_SDIO_DEBUG */
-#define DBG_COLOR
#include <rtdbg.h>
#ifndef RT_MMCSD_STACK_SIZE
@@ -595,7 +593,7 @@ static void mmcsd_power_off(struct rt_mmcsd_host *host)
int mmcsd_wait_cd_changed(rt_int32_t timeout)
{
struct rt_mmcsd_host *host;
- if (rt_mb_recv(&mmcsd_hotpluge_mb, (rt_uint32_t*)&host, timeout) == RT_EOK)
+ if (rt_mb_recv(&mmcsd_hotpluge_mb, (rt_ubase_t *)&host, timeout) == RT_EOK)
{
if(host->card == RT_NULL)
{
@@ -612,7 +610,7 @@ RTM_EXPORT(mmcsd_wait_cd_changed);
void mmcsd_change(struct rt_mmcsd_host *host)
{
- rt_mb_send(&mmcsd_detect_mb, (rt_uint32_t)host);
+ rt_mb_send(&mmcsd_detect_mb, (rt_ubase_t)host);
}
void mmcsd_detect(void *param)
@@ -623,7 +621,7 @@ void mmcsd_detect(void *param)
while (1)
{
- if (rt_mb_recv(&mmcsd_detect_mb, (rt_uint32_t*)&host, RT_WAITING_FOREVER) == RT_EOK)
+ if (rt_mb_recv(&mmcsd_detect_mb, (rt_ubase_t *)&host, RT_WAITING_FOREVER) == RT_EOK)
{
if (host->card == RT_NULL)
{
@@ -651,7 +649,7 @@ void mmcsd_detect(void *param)
if (init_sd(host, ocr))
mmcsd_power_off(host);
mmcsd_host_unlock(host);
- rt_mb_send(&mmcsd_hotpluge_mb, (rt_uint32_t)host);
+ rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host);
continue;
}
@@ -664,7 +662,7 @@ void mmcsd_detect(void *param)
if (init_mmc(host, ocr))
mmcsd_power_off(host);
mmcsd_host_unlock(host);
- rt_mb_send(&mmcsd_hotpluge_mb, (rt_uint32_t)host);
+ rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host);
continue;
}
mmcsd_host_unlock(host);
@@ -685,7 +683,7 @@ void mmcsd_detect(void *param)
host->card = RT_NULL;
}
mmcsd_host_unlock(host);
- rt_mb_send(&mmcsd_hotpluge_mb, (rt_uint32_t)host);
+ rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host);
}
}
}
diff --git a/components/drivers/sdio/sd.c b/components/drivers/sdio/sd.c
index 69a4561fb0..f7e4e46720 100644
--- a/components/drivers/sdio/sd.c
+++ b/components/drivers/sdio/sd.c
@@ -11,14 +11,12 @@
#include <drivers/mmcsd_core.h>
#include <drivers/sd.h>
-#define DBG_ENABLE
-#define DBG_SECTION_NAME "SDIO"
+#define DBG_TAG "SDIO"
#ifdef RT_SDIO_DEBUG
-#define DBG_LEVEL DBG_LOG
+#define DBG_LVL DBG_LOG
#else
-#define DBG_LEVEL DBG_INFO
+#define DBG_LVL DBG_INFO
#endif /* RT_SDIO_DEBUG */
-#define DBG_COLOR
#include <rtdbg.h>
static const rt_uint32_t tran_unit[] =
@@ -95,25 +93,6 @@ static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card)
card->tacc_ns = (tacc_uint[csd->taac&0x07] * tacc_value[(csd->taac&0x78)>>3] + 9) / 10;
card->max_data_rate = tran_unit[csd->tran_speed&0x07] * tran_value[(csd->tran_speed&0x78)>>3];
- #if 0
- val = GET_BITS(resp, 115, 4);
- unit = GET_BITS(resp, 112, 3);
- csd->tacc_ns = (tacc_uint[unit] * tacc_value[val] + 9) / 10;
- csd->tacc_clks = GET_BITS(resp, 104, 8) * 100;
-
- val = GET_BITS(resp, 99, 4);
- unit = GET_BITS(resp, 96, 3);
- csd->max_data_rate = tran_unit[unit] * tran_value[val];
- csd->ccc = GET_BITS(resp, 84, 12);
-
- unit = GET_BITS(resp, 47, 3);
- val = GET_BITS(resp, 62, 12);
- csd->device_size = (1 + val) << (unit + 2);
-
- csd->read_bl_len = GET_BITS(resp, 80, 4);
- csd->write_bl_len = GET_BITS(resp, 22, 4);
- csd->r2w_factor = GET_BITS(resp, 26, 3);
- #endif
break;
case 1:
card->flags |= CARD_FLAG_SDHC;
@@ -144,23 +123,6 @@ static rt_int32_t mmcsd_parse_csd(struct rt_mmcsd_card *card)
card->tacc_ns = 0;
card->max_data_rate = tran_unit[csd->tran_speed&0x07] * tran_value[(csd->tran_speed&0x78)>>3];
- #if 0
- csd->tacc_ns = 0;
- csd->tacc_clks = 0;
-
- val = GET_BITS(resp, 99, 4);
- unit = GET_BITS(resp, 96, 3);
- csd->max_data_rate = tran_unit[unit] * tran_value[val];
- csd->ccc = GET_BITS(resp, 84, 12);
-
- val = GET_BITS(resp, 48, 22);
- csd->device_size = (1 + val) << 10;
-
- csd->read_bl_len = 9;
- csd->write_bl_len = 9;
- /* host should not use this factor and should use 250ms for write timeout */
- csd->r2w_factor = 2;
- #endif
break;
default:
LOG_E("unrecognised CSD structure version %d!", csd->csd_structure);
@@ -266,7 +228,7 @@ static rt_int32_t mmcsd_switch(struct rt_mmcsd_card *card)
if ((buf[16] & 0xF) != 1)
{
- LOG_E("switching card to high speed failed!");
+ LOG_I("switching card to high speed failed!");
goto err;
}
diff --git a/components/drivers/sdio/sdio.c b/components/drivers/sdio/sdio.c
index 6045c4ade8..65bf87b895 100644
--- a/components/drivers/sdio/sdio.c
+++ b/components/drivers/sdio/sdio.c
@@ -12,14 +12,12 @@
#include <drivers/sdio.h>
#include <drivers/sd.h>
-#define DBG_ENABLE
-#define DBG_SECTION_NAME "SDIO"
+#define DBG_TAG "SDIO"
#ifdef RT_SDIO_DEBUG
-#define DBG_LEVEL DBG_LOG
+#define DBG_LVL DBG_LOG
#else
-#define DBG_LEVEL DBG_INFO
+#define DBG_LVL DBG_INFO
#endif /* RT_SDIO_DEBUG */
-#define DBG_COLOR
#include <rtdbg.h>
#ifndef RT_SDIO_STACK_SIZE
@@ -711,6 +709,16 @@ static rt_int32_t sdio_initialize_function(struct rt_mmcsd_card *card,
if (ret)
goto err1;
+ /*
+ * product/manufacturer id is optional for function CIS, so
+ * copy it from the card structure as needed.
+ */
+ if (func->product == 0)
+ {
+ func->manufacturer = card->cis.manufacturer;
+ func->product = card->cis.product;
+ }
+
card->sdio_function[func_num] = func;
return 0;
diff --git a/components/drivers/sensors/SConscript b/components/drivers/sensors/SConscript
index db409cfd2b..51c4b50eef 100644
--- a/components/drivers/sensors/SConscript
+++ b/components/drivers/sensors/SConscript
@@ -3,14 +3,11 @@
from building import *
cwd = GetCurrentDir()
-src = ['sensor.cpp']
+src = ['sensor.c']
CPPPATH = [cwd, cwd + '/../include']
-if GetDepend('SENSOR_USING_MPU6050') and GetDepend('RT_USING_I2C'):
- src += ['mpu6050_sensor.cpp'];
-
-if GetDepend('SENSOR_USING_BMI055') and GetDepend('RT_USING_I2C'):
- src += ['bmi055_sensor.cpp']
+if GetDepend('RT_USING_SENSOR_CMD'):
+ src += ['sensor_cmd.c'];
group = DefineGroup('Sensors', src, depend = ['RT_USING_SENSOR', 'RT_USING_DEVICE'], CPPPATH = CPPPATH)
diff --git a/components/drivers/sensors/bmi055_sensor.cpp b/components/drivers/sensors/bmi055_sensor.cpp
deleted file mode 100644
index b6e7f99da5..0000000000
--- a/components/drivers/sensors/bmi055_sensor.cpp
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2015-1-11 RT_learning the first version
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <rtdevice.h>
-#include "bmi055_sensor.h"
-
-
-const static sensor_t _BMI055_sensor[] =
-{
- {
- .name = "Accelerometer",
- .vendor = "Bosch",
- .version = sizeof(sensor_t),
- .handle = 0,
- .type = SENSOR_TYPE_ACCELEROMETER,
- .maxRange = SENSOR_ACCEL_RANGE_16G,
- .resolution = 1.0f,
- .power = 0.5f,
- .minDelay = 10000,
- .fifoReservedEventCount = 0,
- .fifoMaxEventCount = 64,
- },
- {
- .name = "Gyroscope",
- .vendor = "Bosch",
- .version = sizeof(sensor_t),
- .handle = 0,
- .type = SENSOR_TYPE_GYROSCOPE,
- .maxRange = SENSOR_GYRO_RANGE_2000DPS,
- .resolution = 1.0f,
- .power = 0.5f,
- .minDelay = 10000,
- .fifoReservedEventCount = 0,
- .fifoMaxEventCount = 64,
- }
-};
-
-BMI055::BMI055(int sensor_type, const char* iic_bus, int addr)
- : SensorBase(sensor_type)
-{
- this->i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(iic_bus);
- if (this->i2c_bus == NULL)
- {
- printf("BMI055: No IIC device:%s\n", iic_bus);
- return;
- }
-
- this->i2c_addr = addr;
-
- /* register to sensor manager */
- SensorManager::registerSensor(this);
-}
-
-int BMI055::read_reg(rt_uint8_t reg, rt_uint8_t *value)
-{
- struct rt_i2c_msg msgs[2];
-
- msgs[0].addr = this->i2c_addr;
- msgs[0].flags = RT_I2C_WR;
- msgs[0].buf = &reg;
- msgs[0].len = 1;
-
- msgs[1].addr = this->i2c_addr;
- msgs[1].flags = RT_I2C_RD; /* Read from slave */
- msgs[1].buf = (rt_uint8_t *)value;
- msgs[1].len = 1;
-
- if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
- return RT_EOK;
-
- return -RT_ERROR;
-}
-
-int BMI055::read_buffer(rt_uint8_t reg, rt_uint8_t* value, rt_size_t size)
-{
- struct rt_i2c_msg msgs[2];
-
- msgs[0].addr = this->i2c_addr;
- msgs[0].flags = RT_I2C_WR;
- msgs[0].buf = &reg;
- msgs[0].len = 1;
-
- msgs[1].addr = this->i2c_addr;
- msgs[1].flags = RT_I2C_RD; /* Read from slave */
- msgs[1].buf = (rt_uint8_t *)value;
- msgs[1].len = size;
-
- if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
- return RT_EOK;
-
- return -RT_ERROR;
-}
-
-int BMI055::write_reg(rt_uint8_t reg, rt_uint8_t value)
-{
- struct rt_i2c_msg msgs[2];
-
- msgs[0].addr = this->i2c_addr;
- msgs[0].flags = RT_I2C_WR;
- msgs[0].buf = &reg;
- msgs[0].len = 1;
-
- msgs[1].addr = this->i2c_addr;
- msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START;
- msgs[1].buf = (rt_uint8_t *)&value;
- msgs[1].len = 1;
-
- if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
- return RT_EOK;
-
- return -RT_ERROR;
-}
-
-
-BMI055_Accelerometer::BMI055_Accelerometer(const char* iic_name, int addr)
- : BMI055(SENSOR_TYPE_ACCELEROMETER, iic_name, addr)
-{
- int index;
- uint8_t id;
- rt_uint8_t value[6] = {0};
- rt_int32_t x, y, z;
- SensorConfig config = {SENSOR_MODE_NORMAL, SENSOR_DATARATE_400HZ, SENSOR_ACCEL_RANGE_2G};
-
- write_reg(BMI055_BGW_SOFTRESET, 0xB6); /* reset of the sensor P57 */
- write_reg(BMI055_PMU_LPW, 0x00); /* PMU_LPW NORMAL mode P55 */
- write_reg(BMI055_PMU_BW, 0x0A); /* 01010b 31.25 Hz P55 */
- write_reg(BMI055_PMU_RANGE, 0x05); /* 0101b 卤4g range PMU_RANGE set acc +-4g/s P54 */
-
-
- x_offset = y_offset = z_offset = 0;
- x = y = z = 0;
-
- /* read BMI055 id */
- read_buffer(BMI055_ACC_BGW_CHIPID, &id, 1); /* BGW_CHIPID P47*/
- if (id != BMI055_ACC_BGW_CHIPID_VALUE)
- {
- printf("Warning: not found BMI055 id: %02x\n", id);
- }
-
- /* get offset */
- for (index = 0; index < 200; index ++)
- {
- read_buffer(BMI055_ACCD_X_LSB, value, 6); /*ACCD_X_LSB P47 */
-
- x += (((rt_int16_t)value[1] << 8) | value[0]);
- y += (((rt_int16_t)value[3] << 8) | value[2]);
- z += (((rt_int16_t)value[5] << 8) | value[4]);
- }
- x_offset = x / 200;
- y_offset = y / 200;
- z_offset = z / 200;
-
- this->enable = RT_FALSE;
- this->sensitivity = SENSOR_ACCEL_SENSITIVITY_2G;
- this->config = config;
-}
-
-int
-BMI055_Accelerometer::configure(SensorConfig *config)
-{
- int range;
- uint8_t value;
-
- if (config == RT_NULL) return -1;
-
- /* TODO: set datarate */
-
- /* get range and calc the sensitivity */
- range = config->range.accel_range;
- switch (range)
- {
- case SENSOR_ACCEL_RANGE_2G:
- this->sensitivity = SENSOR_ACCEL_SENSITIVITY_2G;
- range = 0x03; //0011b
- break;
- case SENSOR_ACCEL_RANGE_4G:
- this->sensitivity = SENSOR_ACCEL_SENSITIVITY_4G;
- range = 0x05; //0101b
- break;
- case SENSOR_ACCEL_RANGE_8G:
- this->sensitivity = SENSOR_ACCEL_SENSITIVITY_8G;
- range = 0x01 << 3; //1000b
- break;
- case SENSOR_ACCEL_RANGE_16G:
- this->sensitivity = SENSOR_ACCEL_SENSITIVITY_16G;
- range = 0x03 << 2; //1100b
- break;
- default:
- return -1;
- }
-
- /* set range to sensor */
- read_reg(BMI055_PMU_RANGE, &value); /* PMU_RANGE P54 */
- value &= 0xF0;
- value |= range;
- write_reg(BMI055_PMU_RANGE, value);
-
- return 0;
-}
-
-int
-BMI055_Accelerometer::activate(int enable)
-{
- uint8_t value;
-
- if (enable && this->enable == RT_FALSE)
- {
- /* enable accelerometer */
- read_reg(BMI055_PMU_LPW, &value); /* P55 */
- value &= ~(0x07 << 7);
- write_reg(BMI055_PMU_LPW, value);
- }
-
- if (!enable && this->enable == RT_TRUE)
- {
- /* disable accelerometer */
- read_reg(BMI055_PMU_LPW, &value);
- value &= ~(0x07 << 7);
- value |= (0x01 << 7);
- write_reg(BMI055_PMU_LPW, value);
- }
-
- if (enable) this->enable = RT_TRUE;
- else this->enable = RT_FALSE;
-
- return 0;
-}
-
-int
-BMI055_Accelerometer::poll(sensors_event_t *event)
-{
- rt_uint8_t value[6];
- rt_int16_t x, y, z;
-
- /* parameters check */
- if (event == NULL) return -1;
-
- /* get event data */
- event->version = sizeof(sensors_event_t);
- event->sensor = (int32_t) this;
- event->timestamp = rt_tick_get();
- event->type = SENSOR_TYPE_ACCELEROMETER;
-
- read_buffer(0x02, value, 6);
-
- /* get raw data */
- x = (((rt_int16_t)value[1] << 8) | value[0]);
- y = (((rt_int16_t)value[3] << 8) | value[2]);
- z = (((rt_int16_t)value[5] << 8) | value[4]);
-
- if (config.mode == SENSOR_MODE_RAW)
- {
- event->raw_acceleration.x = x;
- event->raw_acceleration.y = y;
- event->raw_acceleration.z = z;
- }
- else
- {
-
- x -= x_offset; y -= y_offset; z -= z_offset;
- event->acceleration.x = x * this->sensitivity * SENSORS_GRAVITY_STANDARD;
- event->acceleration.y = y * this->sensitivity * SENSORS_GRAVITY_STANDARD;
- event->acceleration.z = z * this->sensitivity * SENSORS_GRAVITY_STANDARD;
- }
-
- return 0;
-}
-
-void
-BMI055_Accelerometer::getSensor(sensor_t *sensor)
-{
- /* get sensor description */
- if (sensor)
- {
- memcpy(sensor, &_BMI055_sensor[0], sizeof(sensor_t));
- }
-}
-
-BMI055_Gyroscope::BMI055_Gyroscope(const char* iic_name, int addr)
- : BMI055(SENSOR_TYPE_GYROSCOPE, iic_name, addr)
-{
- int index;
- uint8_t id;
- rt_uint8_t value[6];
- rt_int32_t x, y, z;
-
- /* initialize BMI055 */
- write_reg(BMI055_MODE_LPM1_ADDR, 0x00); /* normal mode */
- write_reg(BMI055_MODE_LPM2_ADDR, 0x80); /* fast powerup */
- write_reg(BMI055_BW_ADDR, 0x03); /* ODR:400Hz Filter Bandwidth:47Hz */
- write_reg(BMI055_RANGE_ADDR, 0x00); /* 2000dps */
-
-
- x_offset = y_offset = z_offset = 0;
- x = y = z = 0;
-
- /* read BMI055 id */
- read_buffer(BMI055_CHIP_ID_ADDR, &id, 1);
- if (id != BMI055_GRRO_CHIP_ID)
- {
- printf("Warning: not found BMI055 id: %02x\n", id);
- }
-
- /* get offset */
- for (index = 0; index < 200; index ++)
- {
- read_buffer(BMI055_RATE_X_LSB_ADDR, value, 6);
-
- x += (((rt_int16_t)value[1] << 8) | value[0]);
- y += (((rt_int16_t)value[3] << 8) | value[2]);
- z += (((rt_int16_t)value[5] << 8) | value[4]);
- }
- x_offset = x / 200;
- y_offset = y / 200;
- z_offset = z / 200;
-
- this->enable = RT_FALSE;
- this->sensitivity = SENSOR_GYRO_SENSITIVITY_250DPS;
-}
-
-int
-BMI055_Gyroscope::configure(SensorConfig *config)
-{
- int range;
- uint8_t value;
-
- if (config == RT_NULL) return -1;
-
- /* TODO: set datarate */
-
- /* get range and calc the sensitivity */
- range = config->range.gyro_range;
- switch (range)
- {
- //to do add more range e.g 125DPS
- //case
- case SENSOR_GYRO_RANGE_250DPS:
- this->sensitivity = SENSOR_GYRO_SENSITIVITY_250DPS;
- range = 0x11;
- break;
- case SENSOR_GYRO_RANGE_500DPS:
- this->sensitivity = SENSOR_GYRO_SENSITIVITY_500DPS;
- range = 0x10;
- break;
- case SENSOR_GYRO_RANGE_1000DPS:
- this->sensitivity = SENSOR_GYRO_SENSITIVITY_1000DPS;
- range = 0x01;
- break;
- case SENSOR_GYRO_RANGE_2000DPS:
- this->sensitivity = SENSOR_GYRO_SENSITIVITY_2000DPS;
- range = 0x00;
- break;
- default:
- return -1;
- }
-
- /* set range to sensor */
- read_reg(BMI055_RANGE_ADDR, &value);
- value &= ~0x07;
- value |= range;
- write_reg(BMI055_RANGE_ADDR, value);
-
- return 0;
-}
-
-int
-BMI055_Gyroscope::activate(int enable)
-{
- uint8_t value;
-
- if (enable && this->enable == RT_FALSE)
- {
- /* enable gyroscope */
- read_reg(BMI055_MODE_LPM1_ADDR, &value);
- value &= ~(0x1010 << 4); //{0; 0} NORMAL mode
- write_reg(BMI055_MODE_LPM1_ADDR, value); //P101 NORMAL mode
- }
-
- if (!enable && this->enable == RT_TRUE)
- {
- /* disable gyroscope */
- read_reg(BMI055_MODE_LPM1_ADDR, &value);
- value &= ~(0x01 << 5); //set bit5 deep_suspend 0
- value |= (0x01 << 7); //set bit1 suspend 1
- write_reg(BMI055_MODE_LPM1_ADDR, value); //{1; 0} SUSPEND mode
- }
-
- if (enable) this->enable = RT_TRUE;
- else this->enable = RT_FALSE;
-
- return 0;
-}
-
-int
-BMI055_Gyroscope::poll(sensors_event_t *event)
-{
- rt_uint8_t value[6];
- rt_int16_t x, y, z;
-
- /* parameters check */
- if (event == NULL) return -1;
-
- /* get event data */
- event->version = sizeof(sensors_event_t);
- event->sensor = (int32_t) this;
- event->timestamp = rt_tick_get();
- event->type = SENSOR_TYPE_GYROSCOPE;
-
- read_buffer(BMI055_RATE_X_LSB_ADDR, value, 6);
-
- /* get raw data */
- x = (((rt_int16_t)value[1] << 8) | value[0]);
- y = (((rt_int16_t)value[3] << 8) | value[2]);
- z = (((rt_int16_t)value[5] << 8) | value[4]);
-
-
- if (config.mode == SENSOR_MODE_RAW)
- {
- event->raw_gyro.x = x;
- event->raw_gyro.y = y;
- event->raw_gyro.z = z;
- }
- else
- {
- x -= x_offset; y -= y_offset; z -= z_offset;
- event->gyro.x = x * this->sensitivity * SENSORS_DPS_TO_RADS;
- event->gyro.y = y * this->sensitivity * SENSORS_DPS_TO_RADS;
- event->gyro.z = z * this->sensitivity * SENSORS_DPS_TO_RADS;
- }
-
- return 0;
-}
-
-void
-BMI055_Gyroscope::getSensor(sensor_t *sensor)
-{
- /* get sensor description */
- if (sensor)
- {
- memcpy(sensor, &_BMI055_sensor[1], sizeof(sensor_t));
- }
-}
diff --git a/components/drivers/sensors/bmi055_sensor.h b/components/drivers/sensors/bmi055_sensor.h
deleted file mode 100644
index 713aa74ad0..0000000000
--- a/components/drivers/sensors/bmi055_sensor.h
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2015-1-11 RT_learning the first version
- */
-#ifndef __BMI055_H__
-#define __BMI055_H__
-
-#include <sensor.h>
-
-/**************************************************************************************************/
-/************************************Register map accelerometer************************************/
-
-#define BMI055_ACC_I2C_ADDR1 0x18 //SDO is low(GND)
-#define BMI055_ACC_I2C_ADDR2 0x19 //SDO is high(VCC)
-
-#define BMI055_ACC_DEFAULT_ADDRESS BMI055_ACC_I2C_ADDR2 //in the LPC54102 SPM-S
-
-#define BMI055_ACC_BGW_CHIPID_VALUE 0xFA
-
-#define BMI055_ACC_BGW_CHIPID 0x00
-/**<Address of ACC Chip ID Register */
-#define BMI055_ACCD_X_LSB 0x02
-/**< Address of X axis ACC LSB Register */
-#define BMI055_ACCD_X_MSB 0x03
-/**< Address of X axis ACC MSB Register */
-#define BMI055_ACCD_Y_LSB 0x04
-/**< Address of Y axis ACC LSB Register */
-#define BMI055_ACCD_Y_MSB 0x05
-/**< Address of Y axis ACC MSB Register */
-#define BMI055_ACCD_Z_LSB 0x06
-/**< Address of Z axis ACC LSB Register */
-#define BMI055_ACCD_Z_MSB 0x07
-/**< Address of Z axis ACC MSB Register */
-#define BMI055_ACCD_TEMP 0x08
-/**< Address of Temperature Data Register */
-
-/* Status Register */
-#define BMI055_INT_STATUS_0 0x09
-/**< Address of Interrupt status Register 0 */
-#define BMI055_INT_STATUS_1 0x0A
-/**< Address of Interrupt status Register 1 */
-#define BMI055_INT_STATUS_2 0x0B
-/**< Address of Interrupt status Register 2 */
-#define BMI055_INT_STATUS_3 0x0C
-/**< Address of Interrupt status Register 3 */
-#define BMI055_FIFO_STATUS 0x0E
-/**< Address of FIFO status Register */
-
-/* Control Register */
-#define BMI055_PMU_RANGE 0x0F
-/**< Address of Range address Register */
-#define BMI055_PMU_BW 0x10
-/**< Address of Bandwidth Register */
-#define BMI055_PMU_LPW 0x11
-/**< Address of PMU LPW */
-#define BMI055_PMU_LOW_POWER 0x12
-/**< Address of PMU LOW POWER */
-#define BMI055_ACCD_HBW 0x13
-/**< Address of ACCD HBW */
-#define BMI055_BGW_SOFTRESET 0x14
-/**< Address of BGW SOFTRESET */
-#define BMI055_INT_EN_0 0x16
-/**< Address of interrupt engines in group 0 */
-#define BMI055_INT_EN_1 0x17
-/**< Address of interrupt engines in group 1 */
-#define BMI055_INT_EN_2 0x18
-/**< Address of interrupt engines in group 2 */
-#define BMI055_INT_MAP_0 0x19
-/**< Address of Interrupt MAP 0 */
-#define BMI055_INT_MAP_1 0x1A
-/**< Address of Interrupt MAP 1 */
-#define BMI055_INT_MAP_2 0x1B
-/**< Address of Interrupt MAP 2 */
-#define BMI055_INT_SRC 0x1E
-/**< Address of Interrupt source */
-#define BMI055_INT_OUT_CTRL 0x20
-/**< Address of Interrupt Register */
-#define BMI055_INT_RST_LATCH 0x21
-/**< Address of Interrupt reset and mode Register */
-#define BMI055_INT_0 0x22
-/**< Address of low-g Interrupt delay time Register */
-#define BMI055_INT_1 0x23
-/**< Address of low-g Interrupt threshold Register */
-#define BMI055_INT_2 0x24
-/**< Address of Interrupt 2 Register */
-#define BMI055_INT_3 0x25
-/**< Address of high-g Interrupt delay time Register */
-#define BMI055_INT_4 0x26
-/**< Address of high-g Interrupt threshold Register */
-#define BMI055_INT_5 0x27
-/**< Address of high-g Interrupt 5 Register */
-#define BMI055_INT_6 0x28
-/**< Address of any-motion Interrupt threshold Register */
-#define BMI055_INT_7 0x29
-/**< Address of slow/no-motion interrupt threshold Register */
-#define BMI055_INT_8 0x2A
-/**< Address of high-g Interrupt 8 Register */
-#define BMI055_INT_9 0x2B
-/**< Address of high-g Interrupt 9 Register */
-#define BMI055_INT_A 0x2C
-/**< Address of Interrupt A Register */
-#define BMI055_INT_B 0x2D
-/**< Address of Interrupt B Register */
-#define BMI055_INT_C 0x2E
-/**< Address of Interrupt C Register */
-#define BMI055_INT_D 0x2F
-/**< Address of Interrupt D Register */
-#define BMI055_FIFO_CONFIG_0 0x30
-/**< Address of FIFO CONFIG 0 Register */
-#define BMI055_PMU_SELF_TEST 0x32
-/**< Address of PMU SELF TEST Register */
-#define BMI055_TRIM_NVM_CTRL 0x33
-/**< Address of TRIM NVM CTRL Register */
-#define BMI055_BGW_SPI3_WDT 0x34
-/**< Address of BGW SPI3 WDT Register */
-#define BMI055_OFC_CTRL 0x36
-/**< Address of OFC CTRL Register */
-#define BMI055_OFC_SETTING 0x37
-/**< Address of OFC SETTING Register */
-#define BMI055_OFC_OFFSET_X 0x38
-/**< Address of OFC OFFSET X Register */
-#define BMI055_OFC_OFFSET_Y 0x39
-/**< Address of OFC OFFSET Y Register */
-#define BMI055_OFC_OFFSET_Z 0x3A
-/**< Address of OFC OFFSET Z Register */
-
-/* Trim Register */
-#define BMI055_TRIM_GP0 0x3B
-/**< Address of TRIM GP0 Register */
-#define BMI055_TRIM_GP1 0x3C
-/**< Address of TRIM GP1 Register */
-
-/* Control Register */
-#define BMI055_FIFO_CONFIG_1 0x3E
-/**< Address of FIFO CONFIG 1 Register */
-
-/* Data Register */
-#define BMI055_FIFO_DATA 0x3F
-/**< Address of FIFO DATA Register */
-
-
-/**************************************************************************************************/
-
-
-
-
-/**************************************************************************************************/
-/************************************Register map gyroscope****************************************/
-
-
-/**< This refers BMI055 return type as signed */
-
-// #define BMI055_I2C_ADDR1 0x68 //SDO is low(GND)
-// #define BMI055_I2C_ADDR2 0x69 //SDO is high(VCC)
-#define BMI055_GYRO_I2C_ADDR1 0x68 //SDO is low(GND)
-#define BMI055_GYRO_I2C_ADDR2 0x69 //SDO is high(VCC)
-
-#define BMI055_GYRO_DEFAULT_ADDRESS BMI055_GYRO_I2C_ADDR2
-
-#define BMI055_GRRO_CHIP_ID 0x0F
-
-/*Define of registers*/
-
-/* Hard Wired */
-#define BMI055_CHIP_ID_ADDR 0x00
-/**<Address of Chip ID Register*/
-
-/* Data Register */
-#define BMI055_RATE_X_LSB_ADDR 0x02
-/**< Address of X axis Rate LSB Register */
-#define BMI055_RATE_X_MSB_ADDR 0x03
-/**< Address of X axis Rate MSB Register */
-#define BMI055_RATE_Y_LSB_ADDR 0x04
-/**< Address of Y axis Rate LSB Register */
-#define BMI055_RATE_Y_MSB_ADDR 0x05
-/**< Address of Y axis Rate MSB Register */
-#define BMI055_RATE_Z_LSB_ADDR 0x06
-/**< Address of Z axis Rate LSB Register */
-#define BMI055_RATE_Z_MSB_ADDR 0x07
-/**< Address of Z axis Rate MSB Register */
-#define BMI055_TEMP_ADDR 0x08
-/**< Address of Temperature Data LSB Register */
-
-/* Status Register */
-#define BMI055_INTR_STAT0_ADDR 0x09
-/**< Address of Interrupt status Register 0 */
-#define BMI055_INTR_STAT1_ADDR 0x0A
-/**< Address of Interrupt status Register 1 */
-#define BMI055_INTR_STAT2_ADDR 0x0B
-/**< Address of Interrupt status Register 2 */
-#define BMI055_INTR_STAT3_ADDR 0x0C
-/**< Address of Interrupt status Register 3 */
-#define BMI055_FIFO_STAT_ADDR 0x0E
-/**< Address of FIFO status Register */
-
-/* Control Register */
-#define BMI055_RANGE_ADDR 0x0F
-/**< Address of Range address Register */
-#define BMI055_BW_ADDR 0x10
-/**< Address of Bandwidth Register */
-#define BMI055_MODE_LPM1_ADDR 0x11
-/**< Address of Mode LPM1 Register */
-#define BMI055_MODE_LPM2_ADDR 0x12
-/**< Address of Mode LPM2 Register */
-#define BMI055_HIGH_BW_ADDR 0x13
-/**< Address of Rate HIGH_BW Register */
-#define BMI055_BGW_SOFT_RST_ADDR 0x14
-/**< Address of BGW Softreset Register */
-#define BMI055_INTR_ENABLE0_ADDR 0x15
-/**< Address of Interrupt Enable 0 */
-#define BMI055_INTR_ENABLE1_ADDR 0x16
-/**< Address of Interrupt Enable 1 */
-#define BMI055_INTR_MAP_ZERO_ADDR 0x17
-/**< Address of Interrupt MAP 0 */
-#define BMI055_INTR_MAP_ONE_ADDR 0x18
-/**< Address of Interrupt MAP 1 */
-#define BMI055_INTR_MAP_TWO_ADDR 0x19
-/**< Address of Interrupt MAP 2 */
-#define BMI055_INTR_ZERO_ADDR 0x1A
-/**< Address of Interrupt 0 register */
-#define BMI055_INTR_ONE_ADDR 0x1B
-/**< Address of Interrupt 1 register */
-#define BMI055_INTR_TWO_ADDR 0x1C
-/**< Address of Interrupt 2 register */
-#define BMI055_INTR_4_ADDR 0x1E
-/**< Address of Interrupt 4 register */
-#define BMI055_RST_LATCH_ADDR 0x21
-/**< Address of Reset Latch Register */
-#define BMI055_HIGHRATE_THRES_X_ADDR 0x22
-/**< Address of High Th x Address register */
-#define BMI055_HIGHRATE_DURN_X_ADDR 0x23
-/**< Address of High Dur x Address register */
-#define BMI055_HIGHRATE_THRES_Y_ADDR 0x24
-/**< Address of High Th y Address register */
-#define BMI055_HIGHRATE_DURN_Y_ADDR 0x25
-/**< Address of High Dur y Address register */
-#define BMI055_HIGHRATE_THRES_Z_ADDR 0x26
-/**< Address of High Th z Address register */
-#define BMI055_HIGHRATE_DURN_Z_ADDR 0x27
-/**< Address of High Dur z Address register */
-#define BMI055_SOC_ADDR 0x31
-/**< Address of SOC register */
-#define BMI055_A_FOC_ADDR 0x32
-/**< Address of A_FOC Register */
-#define BMI055_TRIM_NVM_CTRL_ADDR 0x33
-/**< Address of Trim NVM control register */
-#define BMI055_BGW_SPI3_WDT_ADDR 0x34
-/**< Address of BGW SPI3,WDT Register */
-
-/* Trim Register */
-#define BMI055_OFC1_ADDR 0x36
-/**< Address of OFC1 Register */
-#define BMI055_OFC2_ADDR 0x37
-/**< Address of OFC2 Register */
-#define BMI055_OFC3_ADDR 0x38
-/**< Address of OFC3 Register */
-#define BMI055_OFC4_ADDR 0x39
-/**< Address of OFC4 Register */
-#define BMI055_TRIM_GP0_ADDR 0x3A
-/**< Address of Trim GP0 Register */
-#define BMI055_TRIM_GP1_ADDR 0x3B
-/**< Address of Trim GP1 Register */
-#define BMI055_SELECTF_TEST_ADDR 0x3C
-/**< Address of BGW Self test Register */
-
-/* Control Register */
-#define BMI055_FIFO_CGF1_ADDR 0x3D
-/**< Address of FIFO CGF0 Register */
-#define BMI055_FIFO_CGF0_ADDR 0x3E
-/**< Address of FIFO CGF1 Register */
-
-/* Data Register */
-#define BMI055_FIFO_DATA_ADDR 0x3F
-/**< Address of FIFO Data Register */
-
-
-/**************************************************************************************************/
-
-class BMI055 :public SensorBase
-{
-public:
- BMI055(int sensor_type, const char* iic_bus, int addr);
-
- int read_reg(rt_uint8_t reg, rt_uint8_t* value);
- int write_reg(rt_uint8_t reg, rt_uint8_t value);
- int read_buffer(rt_uint8_t reg, rt_uint8_t* value, rt_size_t size);
-
-private:
- struct rt_i2c_bus_device *i2c_bus;
- int i2c_addr;
-};
-
-class BMI055_Accelerometer:public BMI055
-{
-public:
- BMI055_Accelerometer(const char* iic_name, int addr);
-
- virtual int configure(SensorConfig *config);
- virtual int activate(int enable);
-
- virtual int poll(sensors_event_t *event);
- virtual void getSensor(sensor_t *sensor);
-
-private:
- rt_int16_t x_offset, y_offset, z_offset;
-
- rt_bool_t enable;
- float sensitivity;
-};
-
-class BMI055_Gyroscope:public BMI055
-{
-public:
- BMI055_Gyroscope(const char* iic_name, int addr);
-
- virtual int configure(SensorConfig *config);
- virtual int activate(int enable);
-
- virtual int poll(sensors_event_t *event);
- virtual void getSensor(sensor_t *sensor);
-
-private:
- rt_int16_t x_offset, y_offset, z_offset;
-
- rt_bool_t enable;
- float sensitivity;
-};
-
-#endif
diff --git a/components/drivers/sensors/mpu6050_sensor.cpp b/components/drivers/sensors/mpu6050_sensor.cpp
deleted file mode 100644
index 358796bc30..0000000000
--- a/components/drivers/sensors/mpu6050_sensor.cpp
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2014-12-20 Bernard the first version
- * 2015-1-11 RT_learning modify the mpu6050 initialize
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <rtdevice.h>
-
-#include "mpu6050_sensor.h"
-
-
-const static sensor_t _MPU6050_sensor[] =
-{
- {
- .name = "Accelerometer",
- .vendor = "Invensense",
- .version = sizeof(sensor_t),
- .handle = 0,
- .type = SENSOR_TYPE_ACCELEROMETER,
- .maxRange = SENSOR_ACCEL_RANGE_16G,
- .resolution = 1.0f,
- .power = 0.5f,
- .minDelay = 10000,
- .fifoReservedEventCount = 0,
- .fifoMaxEventCount = 64,
- },
- {
- .name = "Gyroscope",
- .vendor = "Invensense",
- .version = sizeof(sensor_t),
- .handle = 0,
- .type = SENSOR_TYPE_GYROSCOPE,
- .maxRange = SENSOR_GYRO_RANGE_2000DPS,
- .resolution = 1.0f,
- .power = 0.5f,
- .minDelay = 10000,
- .fifoReservedEventCount = 0,
- .fifoMaxEventCount = 64,
- }
-};
-
-MPU6050::MPU6050(int sensor_type, const char* iic_bus, int addr)
- : SensorBase(sensor_type)
-{
- this->i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(iic_bus);
- if (this->i2c_bus == NULL)
- {
- printf("MPU6050: No IIC device:%s\n", iic_bus);
- return;
- }
-
- this->i2c_addr = addr;
-
- /* register to sensor manager */
- SensorManager::registerSensor(this);
-}
-
-int MPU6050::read_reg(rt_uint8_t reg, rt_uint8_t *value)
-{
- struct rt_i2c_msg msgs[2];
-
- msgs[0].addr = this->i2c_addr;
- msgs[0].flags = RT_I2C_WR;
- msgs[0].buf = &reg;
- msgs[0].len = 1;
-
- msgs[1].addr = this->i2c_addr;
- msgs[1].flags = RT_I2C_RD; /* Read from slave */
- msgs[1].buf = (rt_uint8_t *)value;
- msgs[1].len = 1;
-
- if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
- return RT_EOK;
-
- return -RT_ERROR;
-}
-
-int MPU6050::read_buffer(rt_uint8_t reg, rt_uint8_t* value, rt_size_t size)
-{
- struct rt_i2c_msg msgs[2];
-
- msgs[0].addr = this->i2c_addr;
- msgs[0].flags = RT_I2C_WR;
- msgs[0].buf = &reg;
- msgs[0].len = 1;
-
- msgs[1].addr = this->i2c_addr;
- msgs[1].flags = RT_I2C_RD; /* Read from slave */
- msgs[1].buf = (rt_uint8_t *)value;
- msgs[1].len = size;
-
- if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
- return RT_EOK;
-
- return -RT_ERROR;
-}
-
-int MPU6050::write_reg(rt_uint8_t reg, rt_uint8_t value)
-{
- struct rt_i2c_msg msgs[2];
-
- msgs[0].addr = this->i2c_addr;
- msgs[0].flags = RT_I2C_WR;
- msgs[0].buf = &reg;
- msgs[0].len = 1;
-
- msgs[1].addr = this->i2c_addr;
- msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START;
- msgs[1].buf = (rt_uint8_t *)&value;
- msgs[1].len = 1;
-
- if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
- return RT_EOK;
-
- return -RT_ERROR;
-}
-
-
-MPU6050_Accelerometer::MPU6050_Accelerometer(const char* iic_name, int addr)
- : MPU6050(SENSOR_TYPE_ACCELEROMETER, iic_name, addr)
-{
- int index;
- uint8_t id;
- rt_uint8_t value[6] = {0};
- rt_int32_t x, y, z;
- SensorConfig config = {SENSOR_MODE_NORMAL, SENSOR_DATARATE_400HZ, SENSOR_ACCEL_RANGE_2G};
-
- /* initialize MPU6050 */
- write_reg(MPU6050_PWR_MGMT_1, 0x80); /* reset mpu6050 device */
- write_reg(MPU6050_SMPLRT_DIV, 0x00); /* Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV) */
- write_reg(MPU6050_PWR_MGMT_1, 0x03); /* Wake up device , set device clock Z axis gyroscope */
- write_reg(MPU6050_CONFIG, 0x03); /* set DLPF_CFG 42Hz */
- write_reg(MPU6050_GYRO_CONFIG, 0x18); /* set gyro 2000deg/s */
- write_reg(MPU6050_ACCEL_CONFIG, 0x08); /* set acc +-4g/s */
-
-
- x_offset = y_offset = z_offset = 0;
- x = y = z = 0;
-
- /* read MPU6050 id */
- read_buffer(MPU6050_WHOAMI, &id, 1);
- if (id != MPU6050_ID)
- {
- printf("Warning: not found MPU6050 id: %02x\n", id);
- }
-
- /* get offset */
- for (index = 0; index < 200; index ++)
- {
- read_buffer(MPU6050_ACCEL_XOUT_H, value, 6);
-
- x += (((rt_int16_t)value[0] << 8) | value[1]);
- y += (((rt_int16_t)value[2] << 8) | value[3]);
- z += (((rt_int16_t)value[4] << 8) | value[5]);
- }
- x_offset = x / 200;
- y_offset = y / 200;
- z_offset = z / 200;
-
- this->enable = RT_FALSE;
- this->sensitivity = SENSOR_ACCEL_SENSITIVITY_2G;
- this->config = config;
-}
-
-int
-MPU6050_Accelerometer::configure(SensorConfig *config)
-{
- int range;
- uint8_t value;
-
- if (config == RT_NULL) return -1;
-
- /* TODO: set datarate */
-
- /* get range and calc the sensitivity */
- range = config->range.accel_range;
- switch (range)
- {
- case SENSOR_ACCEL_RANGE_2G:
- this->sensitivity = SENSOR_ACCEL_SENSITIVITY_2G;
- range = 0;
- break;
- case SENSOR_ACCEL_RANGE_4G:
- this->sensitivity = SENSOR_ACCEL_SENSITIVITY_4G;
- range = 0x01 << 2;
- break;
- case SENSOR_ACCEL_RANGE_8G:
- this->sensitivity = SENSOR_ACCEL_SENSITIVITY_8G;
- range = 0x02 << 2;
- break;
- case SENSOR_ACCEL_RANGE_16G:
- this->sensitivity = SENSOR_ACCEL_SENSITIVITY_16G;
- range = 0x03 << 2;
- break;
- default:
- return -1;
- }
-
- /* set range to sensor */
- read_reg(MPU6050_ACCEL_CONFIG, &value);
- value &= ~(0x3 << 2);
- value |= range;
- write_reg(MPU6050_ACCEL_CONFIG, value);
-
- return 0;
-}
-
-int
-MPU6050_Accelerometer::activate(int enable)
-{
- uint8_t value;
-
- if (enable && this->enable == RT_FALSE)
- {
- /* enable accelerometer */
- read_reg(MPU6050_PWR_MGMT_2, &value);
- value &= ~(0x07 << 2);
- write_reg(MPU6050_PWR_MGMT_2, value);
- }
-
- if (!enable && this->enable == RT_TRUE)
- {
- /* disable accelerometer */
- read_reg(MPU6050_PWR_MGMT_2, &value);
- value |= (0x07 << 2);
- write_reg(MPU6050_PWR_MGMT_2, value);
- }
-
- if (enable) this->enable = RT_TRUE;
- else this->enable = RT_FALSE;
-
- return 0;
-}
-
-int
-MPU6050_Accelerometer::poll(sensors_event_t *event)
-{
- rt_uint8_t value[6];
- rt_int16_t x, y, z;
-
- /* parameters check */
- if (event == NULL) return -1;
-
- /* get event data */
- event->version = sizeof(sensors_event_t);
- event->sensor = (int32_t) this;
- event->timestamp = rt_tick_get();
- event->type = SENSOR_TYPE_ACCELEROMETER;
-
- read_buffer(MPU6050_ACCEL_XOUT_H, value, 6);
-
- /* get raw data */
- x = (((rt_int16_t)value[0] << 8) | value[1]);
- y = (((rt_int16_t)value[2] << 8) | value[3]);
- z = (((rt_int16_t)value[4] << 8) | value[5]);
-
- if (config.mode == SENSOR_MODE_RAW)
- {
- event->raw_acceleration.x = x;
- event->raw_acceleration.y = y;
- event->raw_acceleration.z = z;
- }
- else
- {
-
- x -= x_offset; y -= y_offset; z -= z_offset;
- event->acceleration.x = x * this->sensitivity * SENSORS_GRAVITY_STANDARD;
- event->acceleration.y = y * this->sensitivity * SENSORS_GRAVITY_STANDARD;
- event->acceleration.z = z * this->sensitivity * SENSORS_GRAVITY_STANDARD;
- }
-
- return 0;
-}
-
-void
-MPU6050_Accelerometer::getSensor(sensor_t *sensor)
-{
- /* get sensor description */
- if (sensor)
- {
- memcpy(sensor, &_MPU6050_sensor[0], sizeof(sensor_t));
- }
-}
-
-MPU6050_Gyroscope::MPU6050_Gyroscope(const char* iic_name, int addr)
- : MPU6050(SENSOR_TYPE_GYROSCOPE, iic_name, addr)
-{
- int index;
- uint8_t id;
- rt_uint8_t value[6];
- rt_int32_t x, y, z;
-
- /* initialize MPU6050 */
- write_reg(MPU6050_PWR_MGMT_1, 0x80); /* reset mpu6050 device */
- write_reg(MPU6050_SMPLRT_DIV, 0x00); /* Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV) */
- write_reg(MPU6050_PWR_MGMT_1, 0x03); /* Wake up device , set device clock Z axis gyroscope */
- write_reg(MPU6050_CONFIG, 0x03); /* set DLPF_CFG 42Hz */
- write_reg(MPU6050_GYRO_CONFIG, 0x18); /* set gyro 2000deg/s */
- write_reg(MPU6050_ACCEL_CONFIG, 0x08); /* set acc +-4g/s */
-
- x_offset = y_offset = z_offset = 0;
- x = y = z = 0;
-
- /* read MPU6050 id */
- read_reg(MPU6050_WHOAMI, &id);
- if (id != MPU6050_ID)
- {
- printf("Warning: not found MPU6050 id: %02x\n", id);
- }
-
- /* get offset */
- for (index = 0; index < 200; index ++)
- {
- read_buffer(MPU6050_GYRO_XOUT_H, value, 6);
-
- x += (((rt_int16_t)value[0] << 8) | value[1]);
- y += (((rt_int16_t)value[2] << 8) | value[3]);
- z += (((rt_int16_t)value[4] << 8) | value[5]);
- }
- x_offset = x / 200;
- y_offset = y / 200;
- z_offset = z / 200;
-
- this->enable = RT_FALSE;
- this->sensitivity = SENSOR_GYRO_SENSITIVITY_250DPS;
-}
-
-int
-MPU6050_Gyroscope::configure(SensorConfig *config)
-{
- int range;
- uint8_t value;
-
- if (config == RT_NULL) return -1;
-
- /* TODO: set datarate */
-
- /* get range and calc the sensitivity */
- range = config->range.gyro_range;
- switch (range)
- {
- case SENSOR_GYRO_RANGE_250DPS:
- this->sensitivity = SENSOR_GYRO_SENSITIVITY_250DPS;
- range = 0;
- break;
- case SENSOR_GYRO_RANGE_500DPS:
- this->sensitivity = SENSOR_GYRO_SENSITIVITY_500DPS;
- range = 0x01 << 2;
- break;
- case SENSOR_GYRO_RANGE_1000DPS:
- this->sensitivity = SENSOR_GYRO_SENSITIVITY_1000DPS;
- range = 0x02 << 2;
- break;
- case SENSOR_GYRO_RANGE_2000DPS:
- this->sensitivity = SENSOR_GYRO_SENSITIVITY_2000DPS;
- range = 0x03 << 2;
- break;
- default:
- return -1;
- }
-
- /* set range to sensor */
- read_reg(MPU6050_GYRO_CONFIG, &value);
- value &= ~(0x3 << 2);
- value |= range;
- write_reg(MPU6050_GYRO_CONFIG, value);
-
- return 0;
-}
-
-int
-MPU6050_Gyroscope::activate(int enable)
-{
- uint8_t value;
-
- if (enable && this->enable == RT_FALSE)
- {
- /* enable gyroscope */
- read_reg(MPU6050_PWR_MGMT_1, &value);
- value &= ~(0x01 << 4);
- write_reg(MPU6050_PWR_MGMT_1, value);
-
- read_reg(MPU6050_PWR_MGMT_2, &value);
- value &= ~(0x07 << 0);
- write_reg(MPU6050_PWR_MGMT_2, value);
- }
-
- if (!enable && this->enable == RT_TRUE)
- {
- /* disable gyroscope */
- read_reg(MPU6050_PWR_MGMT_2, &value);
- value |= (0x07 << 0);
- write_reg(MPU6050_PWR_MGMT_2, value);
- }
-
- if (enable) this->enable = RT_TRUE;
- else this->enable = RT_FALSE;
-
- return 0;
-}
-
-int
-MPU6050_Gyroscope::poll(sensors_event_t *event)
-{
- rt_uint8_t value[6];
- rt_int16_t x, y, z;
-
- /* parameters check */
- if (event == NULL) return -1;
-
- /* get event data */
- event->version = sizeof(sensors_event_t);
- event->sensor = (int32_t) this;
- event->timestamp = rt_tick_get();
- event->type = SENSOR_TYPE_GYROSCOPE;
-
- read_buffer(MPU6050_GYRO_XOUT_H, value, 6);
-
- /* get raw data */
- x = (((rt_int16_t)value[0] << 8) | value[1]);
- y = (((rt_int16_t)value[2] << 8) | value[3]);
- z = (((rt_int16_t)value[4] << 8) | value[5]);
-
-
- if (config.mode == SENSOR_MODE_RAW)
- {
- event->raw_gyro.x = x;
- event->raw_gyro.y = y;
- event->raw_gyro.z = z;
- }
- else
- {
- x -= x_offset; y -= y_offset; z -= z_offset;
- event->gyro.x = x * this->sensitivity * SENSORS_DPS_TO_RADS;
- event->gyro.y = y * this->sensitivity * SENSORS_DPS_TO_RADS;
- event->gyro.z = z * this->sensitivity * SENSORS_DPS_TO_RADS;
- }
-
- return 0;
-}
-
-void
-MPU6050_Gyroscope::getSensor(sensor_t *sensor)
-{
- /* get sensor description */
- if (sensor)
- {
- memcpy(sensor, &_MPU6050_sensor[1], sizeof(sensor_t));
- }
-}
-
diff --git a/components/drivers/sensors/mpu6050_sensor.h b/components/drivers/sensors/mpu6050_sensor.h
deleted file mode 100644
index 8f70c3e5ed..0000000000
--- a/components/drivers/sensors/mpu6050_sensor.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2014-12-20 Bernard the first version
- * 2015-1-11 RT_learning modify the mpu6050 ID
- */
-
-#ifndef MPU6050_SENSOR_H__
-#define MPU6050_SENSOR_H__
-
-#include <sensor.h>
-
-#define MPU6050_ADDRESS_AD0_LOW 0x68 // address pin low (GND), default for InvenSense evaluation board
-#define MPU6050_ADDRESS_AD0_HIGH 0x69 // address pin high (VCC)
-#define MPU6050_DEFAULT_ADDRESS MPU6050_ADDRESS_AD0_LOW
-
-#define MPU6050_XG_OFFS_TC 0x00
-#define MPU6050_YG_OFFS_TC 0x01
-#define MPU6050_ZG_OFFS_TC 0x02
-#define MPU6050_X_FINE_GAIN 0x03
-#define MPU6050_Y_FINE_GAIN 0x04
-#define MPU6050_Z_FINE_GAIN 0x05
-#define MPU6050_XA_OFFS_H 0x06
-#define MPU6050_XA_OFFS_L 0x07
-#define MPU6050_YA_OFFS_H 0x08
-#define MPU6050_YA_OFFS_L 0x09
-#define MPU6050_ZA_OFFS_H 0x0A
-#define MPU6050_ZA_OFFS_L 0x0B
-#define MPU6050_PRODUCT_ID 0x0C
-#define MPU6050_SELF_TEST_X 0x0D
-#define MPU6050_SELF_TEST_Y 0x0E
-#define MPU6050_SELF_TEST_Z 0x0F
-#define MPU6050_SELF_TEST_A 0x10
-#define MPU6050_XG_OFFS_USRH 0x13
-#define MPU6050_XG_OFFS_USRL 0x14
-#define MPU6050_YG_OFFS_USRH 0x15
-#define MPU6050_YG_OFFS_USRL 0x16
-#define MPU6050_ZG_OFFS_USRH 0x17
-#define MPU6050_ZG_OFFS_USRL 0x18
-#define MPU6050_SMPLRT_DIV 0x19
-#define MPU6050_CONFIG 0x1A
-#define MPU6050_GYRO_CONFIG 0x1B
-#define MPU6050_ACCEL_CONFIG 0x1C
-#define MPU6050_ACCEL_CONFIG_2 0x1D
-#define MPU6050_LP_ACCEL_ODR 0x1E
-#define MPU6050_MOT_THR 0x1F
-#define MPU6050_FIFO_EN 0x23
-#define MPU6050_I2C_MST_CTRL 0x24
-#define MPU6050_I2C_SLV0_ADDR 0x25
-#define MPU6050_I2C_SLV0_REG 0x26
-#define MPU6050_I2C_SLV0_CTRL 0x27
-#define MPU6050_I2C_SLV1_ADDR 0x28
-#define MPU6050_I2C_SLV1_REG 0x29
-#define MPU6050_I2C_SLV1_CTRL 0x2A
-#define MPU6050_I2C_SLV2_ADDR 0x2B
-#define MPU6050_I2C_SLV2_REG 0x2C
-#define MPU6050_I2C_SLV2_CTRL 0x2D
-#define MPU6050_I2C_SLV3_ADDR 0x2E
-#define MPU6050_I2C_SLV3_REG 0x2F
-#define MPU6050_I2C_SLV3_CTRL 0x30
-#define MPU6050_I2C_SLV4_ADDR 0x31
-#define MPU6050_I2C_SLV4_REG 0x32
-#define MPU6050_I2C_SLV4_DO 0x33
-#define MPU6050_I2C_SLV4_CTRL 0x34
-#define MPU6050_I2C_SLV4_DI 0x35
-#define MPU6050_I2C_MST_STATUS 0x36
-#define MPU6050_INT_PIN_CFG 0x37
-#define MPU6050_INT_ENABLE 0x38
-#define MPU6050_ACCEL_XOUT_H 0x3B
-#define MPU6050_ACCEL_XOUT_L 0x3C
-#define MPU6050_ACCEL_YOUT_H 0x3D
-#define MPU6050_ACCEL_YOUT_L 0x3E
-#define MPU6050_ACCEL_ZOUT_H 0x3F
-#define MPU6050_ACCEL_ZOUT_L 0x40
-#define MPU6050_TEMP_OUT_H 0x41
-#define MPU6050_TEMP_OUT_L 0x42
-#define MPU6050_GYRO_XOUT_H 0x43
-#define MPU6050_GYRO_XOUT_L 0x44
-#define MPU6050_GYRO_YOUT_H 0x45
-#define MPU6050_GYRO_YOUT_L 0x46
-#define MPU6050_GYRO_ZOUT_H 0x47
-#define MPU6050_GYRO_ZOUT_L 0x48
-#define MPU6050_EXT_SENS_DATA_00 0x49
-#define MPU6050_EXT_SENS_DATA_01 0x4A
-#define MPU6050_EXT_SENS_DATA_02 0x4B
-#define MPU6050_EXT_SENS_DATA_03 0x4C
-#define MPU6050_EXT_SENS_DATA_04 0x4D
-#define MPU6050_EXT_SENS_DATA_05 0x4E
-#define MPU6050_EXT_SENS_DATA_06 0x4F
-#define MPU6050_EXT_SENS_DATA_07 0x50
-#define MPU6050_EXT_SENS_DATA_08 0x51
-#define MPU6050_EXT_SENS_DATA_09 0x52
-#define MPU6050_EXT_SENS_DATA_10 0x53
-#define MPU6050_EXT_SENS_DATA_11 0x54
-#define MPU6050_EXT_SENS_DATA_12 0x55
-#define MPU6050_EXT_SENS_DATA_13 0x56
-#define MPU6050_EXT_SENS_DATA_14 0x57
-#define MPU6050_EXT_SENS_DATA_15 0x58
-#define MPU6050_EXT_SENS_DATA_16 0x59
-#define MPU6050_EXT_SENS_DATA_17 0x5A
-#define MPU6050_EXT_SENS_DATA_18 0x5B
-#define MPU6050_EXT_SENS_DATA_19 0x5C
-#define MPU6050_EXT_SENS_DATA_20 0x5D
-#define MPU6050_EXT_SENS_DATA_21 0x5E
-#define MPU6050_EXT_SENS_DATA_22 0x5F
-#define MPU6050_EXT_SENS_DATA_23 0x60
-#define MPU6050_I2C_SLV0_DO 0x63
-#define MPU6050_I2C_SLV1_DO 0x64
-#define MPU6050_I2C_SLV2_DO 0x65
-#define MPU6050_I2C_SLV3_DO 0x66
-#define MPU6050_I2C_MST_DELAY_CTRL 0x67
-#define MPU6050_SIGNAL_PATH_RESET 0x68
-#define MPU6050_MOT_DETECT_CTRL 0x69
-#define MPU6050_USER_CTRL 0x6A
-#define MPU6050_PWR_MGMT_1 0x6B
-#define MPU6050_PWR_MGMT_2 0x6C
-#define MPU6050_BANK_SEL 0x6D
-#define MPU6050_MEM_START_ADDR 0x6E
-#define MPU6050_MEM_R_W 0x6F
-#define MPU6050_DMP_CFG_1 0x70
-#define MPU6050_DMP_CFG_2 0x71
-#define MPU6050_FIFO_COUNTH 0x72
-#define MPU6050_FIFO_COUNTL 0x73
-#define MPU6050_FIFO_R_W 0x74
-#define MPU6050_WHOAMI 0x75
-#define MPU6050_XA_OFFSET_H 0x77
-#define MPU6050_XA_OFFSET_L 0x78
-#define MPU6050_YA_OFFSET_H 0x7A
-#define MPU6050_YA_OFFSET_L 0x7B
-#define MPU6050_ZA_OFFSET_H 0x7D
-#define MPU6050_ZA_OFFSET_L 0x7E
-
-#define MPU6050_ID 0x68
-
-class MPU6050 :public SensorBase
-{
-public:
- MPU6050(int sensor_type, const char* iic_bus, int addr);
-
- int read_reg(rt_uint8_t reg, rt_uint8_t* value);
- int write_reg(rt_uint8_t reg, rt_uint8_t value);
- int read_buffer(rt_uint8_t reg, rt_uint8_t* value, rt_size_t size);
-
-private:
- struct rt_i2c_bus_device *i2c_bus;
- int i2c_addr;
-};
-
-class MPU6050_Accelerometer:public MPU6050
-{
-public:
- MPU6050_Accelerometer(const char* iic_name, int addr);
-
- virtual int configure(SensorConfig *config);
- virtual int activate(int enable);
-
- virtual int poll(sensors_event_t *event);
- virtual void getSensor(sensor_t *sensor);
-
-private:
- rt_int16_t x_offset, y_offset, z_offset;
-
- rt_bool_t enable;
- float sensitivity;
-};
-
-class MPU6050_Gyroscope:public MPU6050
-{
-public:
- MPU6050_Gyroscope(const char* iic_name, int addr);
-
- virtual int configure(SensorConfig *config);
- virtual int activate(int enable);
-
- virtual int poll(sensors_event_t *event);
- virtual void getSensor(sensor_t *sensor);
-
-private:
- rt_int16_t x_offset, y_offset, z_offset;
-
- rt_bool_t enable;
- float sensitivity;
-};
-
-#endif
diff --git a/components/drivers/sensors/sensor.c b/components/drivers/sensors/sensor.c
new file mode 100644
index 0000000000..eb5c97a574
--- /dev/null
+++ b/components/drivers/sensors/sensor.c
@@ -0,0 +1,455 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-01-31 flybreak first version
+ * 2020-02-22 luhuadong support custom commands
+ */
+
+#include "sensor.h"
+
+#define DBG_TAG "sensor"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <string.h>
+
+static char *const sensor_name_str[] =
+{
+ "none",
+ "acce_", /* Accelerometer */
+ "gyro_", /* Gyroscope */
+ "mag_", /* Magnetometer */
+ "temp_", /* Temperature */
+ "humi_", /* Relative Humidity */
+ "baro_", /* Barometer */
+ "li_", /* Ambient light */
+ "pr_", /* Proximity */
+ "hr_", /* Heart Rate */
+ "tvoc_", /* TVOC Level */
+ "noi_", /* Noise Loudness */
+ "step_", /* Step sensor */
+ "forc_", /* Force sensor */
+ "dust_", /* Dust sensor */
+ "eco2_", /* eCO2 sensor */
+ "gnss_" /* GPS/GNSS sensor */
+};
+
+/* Sensor interrupt correlation function */
+/*
+ * Sensor interrupt handler function
+ */
+void rt_sensor_cb(rt_sensor_t sen)
+{
+ if (sen->parent.rx_indicate == RT_NULL)
+ {
+ return;
+ }
+
+ if (sen->irq_handle != RT_NULL)
+ {
+ sen->irq_handle(sen);
+ }
+
+ /* The buffer is not empty. Read the data in the buffer first */
+ if (sen->data_len > 0)
+ {
+ sen->parent.rx_indicate(&sen->parent, sen->data_len / sizeof(struct rt_sensor_data));
+ }
+ else if (sen->config.mode == RT_SENSOR_MODE_INT)
+ {
+ /* The interrupt mode only produces one data at a time */
+ sen->parent.rx_indicate(&sen->parent, 1);
+ }
+ else if (sen->config.mode == RT_SENSOR_MODE_FIFO)
+ {
+ sen->parent.rx_indicate(&sen->parent, sen->info.fifo_max);
+ }
+}
+
+/* ISR for sensor interrupt */
+static void irq_callback(void *args)
+{
+ rt_sensor_t sensor = (rt_sensor_t)args;
+ rt_uint8_t i;
+
+ if (sensor->module)
+ {
+ /* Invoke a callback for all sensors in the module */
+ for (i = 0; i < sensor->module->sen_num; i++)
+ {
+ rt_sensor_cb(sensor->module->sen[i]);
+ }
+ }
+ else
+ {
+ rt_sensor_cb(sensor);
+ }
+}
+
+/* Sensor interrupt initialization function */
+static rt_err_t rt_sensor_irq_init(rt_sensor_t sensor)
+{
+ if (sensor->config.irq_pin.pin == RT_PIN_NONE)
+ {
+ return -RT_EINVAL;
+ }
+
+ rt_pin_mode(sensor->config.irq_pin.pin, sensor->config.irq_pin.mode);
+
+ if (sensor->config.irq_pin.mode == PIN_MODE_INPUT_PULLDOWN)
+ {
+ rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_RISING, irq_callback, (void *)sensor);
+ }
+ else if (sensor->config.irq_pin.mode == PIN_MODE_INPUT_PULLUP)
+ {
+ rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_FALLING, irq_callback, (void *)sensor);
+ }
+ else if (sensor->config.irq_pin.mode == PIN_MODE_INPUT)
+ {
+ rt_pin_attach_irq(sensor->config.irq_pin.pin, PIN_IRQ_MODE_RISING_FALLING, irq_callback, (void *)sensor);
+ }
+
+ rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_TRUE);
+
+ LOG_I("interrupt init success");
+
+ return 0;
+}
+
+/* RT-Thread Device Interface */
+static rt_err_t rt_sensor_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ rt_sensor_t sensor = (rt_sensor_t)dev;
+ RT_ASSERT(dev != RT_NULL);
+ rt_err_t res = RT_EOK;
+
+ if (sensor->module)
+ {
+ /* take the module mutex */
+ rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER);
+ }
+
+ if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf == RT_NULL)
+ {
+ /* Allocate memory for the sensor buffer */
+ sensor->data_buf = rt_malloc(sizeof(struct rt_sensor_data) * sensor->info.fifo_max);
+ if (sensor->data_buf == RT_NULL)
+ {
+ res = -RT_ENOMEM;
+ goto __exit;
+ }
+ }
+
+ if (oflag & RT_DEVICE_FLAG_RDONLY && dev->flag & RT_DEVICE_FLAG_RDONLY)
+ {
+ if (sensor->ops->control != RT_NULL)
+ {
+ /* If polling mode is supported, configure it to polling mode */
+ sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_POLLING);
+ }
+ sensor->config.mode = RT_SENSOR_MODE_POLLING;
+ }
+ else if (oflag & RT_DEVICE_FLAG_INT_RX && dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ if (sensor->ops->control != RT_NULL)
+ {
+ /* If interrupt mode is supported, configure it to interrupt mode */
+ sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_INT);
+ }
+ /* Initialization sensor interrupt */
+ rt_sensor_irq_init(sensor);
+ sensor->config.mode = RT_SENSOR_MODE_INT;
+ }
+ else if (oflag & RT_DEVICE_FLAG_FIFO_RX && dev->flag & RT_DEVICE_FLAG_FIFO_RX)
+ {
+ if (sensor->ops->control != RT_NULL)
+ {
+ /* If fifo mode is supported, configure it to fifo mode */
+ sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_MODE, (void *)RT_SENSOR_MODE_FIFO);
+ }
+ /* Initialization sensor interrupt */
+ rt_sensor_irq_init(sensor);
+ sensor->config.mode = RT_SENSOR_MODE_FIFO;
+ }
+ else
+ {
+ res = -RT_EINVAL;
+ goto __exit;
+ }
+
+ /* Configure power mode to normal mode */
+ if (sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_POWER, (void *)RT_SENSOR_POWER_NORMAL) == RT_EOK)
+ {
+ sensor->config.power = RT_SENSOR_POWER_NORMAL;
+ }
+
+__exit:
+ if (sensor->module)
+ {
+ /* release the module mutex */
+ rt_mutex_release(sensor->module->lock);
+ }
+
+ return res;
+}
+
+static rt_err_t rt_sensor_close(rt_device_t dev)
+{
+ rt_sensor_t sensor = (rt_sensor_t)dev;
+ int i;
+
+ RT_ASSERT(dev != RT_NULL);
+
+ if (sensor->module)
+ {
+ rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER);
+ }
+
+ /* Configure power mode to power down mode */
+ if (sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_POWER, (void *)RT_SENSOR_POWER_DOWN) == RT_EOK)
+ {
+ sensor->config.power = RT_SENSOR_POWER_DOWN;
+ }
+
+ /* Sensor disable interrupt */
+ if (sensor->config.irq_pin.pin != RT_PIN_NONE)
+ {
+ rt_pin_irq_enable(sensor->config.irq_pin.pin, RT_FALSE);
+ }
+
+ if (sensor->module != RT_NULL && sensor->info.fifo_max > 0 && sensor->data_buf != RT_NULL)
+ {
+ for (i = 0; i < sensor->module->sen_num; i ++)
+ {
+ if (sensor->module->sen[i]->parent.ref_count > 0)
+ goto __exit;
+ }
+
+ /* Free memory for the sensor buffer */
+ for (i = 0; i < sensor->module->sen_num; i ++)
+ {
+ if (sensor->module->sen[i]->data_buf != RT_NULL)
+ {
+ rt_free(sensor->module->sen[i]->data_buf);
+ sensor->module->sen[i]->data_buf = RT_NULL;
+ }
+ }
+ }
+
+__exit:
+ if (sensor->module)
+ {
+ rt_mutex_release(sensor->module->lock);
+ }
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_sensor_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t len)
+{
+ rt_sensor_t sensor = (rt_sensor_t)dev;
+ rt_size_t result = 0;
+ RT_ASSERT(dev != RT_NULL);
+
+ if (buf == NULL || len == 0)
+ {
+ return 0;
+ }
+
+ if (sensor->module)
+ {
+ rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER);
+ }
+
+ /* The buffer is not empty. Read the data in the buffer first */
+ if (sensor->data_len > 0)
+ {
+ if (len > sensor->data_len / sizeof(struct rt_sensor_data))
+ {
+ len = sensor->data_len / sizeof(struct rt_sensor_data);
+ }
+
+ rt_memcpy(buf, sensor->data_buf, len * sizeof(struct rt_sensor_data));
+
+ /* Clear the buffer */
+ sensor->data_len = 0;
+ result = len;
+ }
+ else
+ {
+ /* If the buffer is empty read the data */
+ result = sensor->ops->fetch_data(sensor, buf, len);
+ }
+
+ if (sensor->module)
+ {
+ rt_mutex_release(sensor->module->lock);
+ }
+
+ return result;
+}
+
+static rt_err_t rt_sensor_control(rt_device_t dev, int cmd, void *args)
+{
+ rt_sensor_t sensor = (rt_sensor_t)dev;
+ rt_err_t result = RT_EOK;
+ RT_ASSERT(dev != RT_NULL);
+
+ if (sensor->module)
+ {
+ rt_mutex_take(sensor->module->lock, RT_WAITING_FOREVER);
+ }
+
+ switch (cmd)
+ {
+ case RT_SENSOR_CTRL_GET_ID:
+ if (args)
+ {
+ result = sensor->ops->control(sensor, RT_SENSOR_CTRL_GET_ID, args);
+ }
+ break;
+ case RT_SENSOR_CTRL_GET_INFO:
+ if (args)
+ {
+ rt_memcpy(args, &sensor->info, sizeof(struct rt_sensor_info));
+ }
+ break;
+ case RT_SENSOR_CTRL_SET_RANGE:
+
+ /* Configuration measurement range */
+ result = sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_RANGE, args);
+ if (result == RT_EOK)
+ {
+ sensor->config.range = (rt_int32_t)args;
+ LOG_D("set range %d", sensor->config.range);
+ }
+ break;
+ case RT_SENSOR_CTRL_SET_ODR:
+
+ /* Configuration data output rate */
+ result = sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_ODR, args);
+ if (result == RT_EOK)
+ {
+ sensor->config.odr = (rt_uint32_t)args & 0xFFFF;
+ LOG_D("set odr %d", sensor->config.odr);
+ }
+ break;
+ case RT_SENSOR_CTRL_SET_POWER:
+
+ /* Configuration sensor power mode */
+ result = sensor->ops->control(sensor, RT_SENSOR_CTRL_SET_POWER, args);
+ if (result == RT_EOK)
+ {
+ sensor->config.power = (rt_uint32_t)args & 0xFF;
+ LOG_D("set power mode code:", sensor->config.power);
+ }
+ break;
+ case RT_SENSOR_CTRL_SELF_TEST:
+
+ /* Device self-test */
+ result = sensor->ops->control(sensor, RT_SENSOR_CTRL_SELF_TEST, args);
+ break;
+ default:
+
+ if (cmd > RT_SENSOR_CTRL_USER_CMD_START)
+ {
+ /* Custom commands */
+ result = sensor->ops->control(sensor, cmd, args);
+ }
+ else
+ {
+ result = -RT_ERROR;
+ }
+ break;
+ }
+
+ if (sensor->module)
+ {
+ rt_mutex_release(sensor->module->lock);
+ }
+
+ return result;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops rt_sensor_ops =
+{
+ RT_NULL,
+ rt_sensor_open,
+ rt_sensor_close,
+ rt_sensor_read,
+ RT_NULL,
+ rt_sensor_control
+};
+#endif
+
+/*
+ * sensor register
+ */
+int rt_hw_sensor_register(rt_sensor_t sensor,
+ const char *name,
+ rt_uint32_t flag,
+ void *data)
+{
+ rt_int8_t result;
+ rt_device_t device;
+ RT_ASSERT(sensor != RT_NULL);
+
+ char *sensor_name = RT_NULL, *device_name = RT_NULL;
+
+ /* Add a type name for the sensor device */
+ sensor_name = sensor_name_str[sensor->info.type];
+ device_name = (char *)rt_calloc(1, rt_strlen(sensor_name) + 1 + rt_strlen(name));
+ if (device_name == RT_NULL)
+ {
+ LOG_E("device_name calloc failed!");
+ return -RT_ERROR;
+ }
+
+ rt_memcpy(device_name, sensor_name, rt_strlen(sensor_name) + 1);
+ strcat(device_name, name);
+
+ if (sensor->module != RT_NULL && sensor->module->lock == RT_NULL)
+ {
+ /* Create a mutex lock for the module */
+ sensor->module->lock = rt_mutex_create(name, RT_IPC_FLAG_FIFO);
+ if (sensor->module->lock == RT_NULL)
+ {
+ rt_free(device_name);
+ return -RT_ERROR;
+ }
+ }
+
+ device = &sensor->parent;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = &rt_sensor_ops;
+#else
+ device->init = RT_NULL;
+ device->open = rt_sensor_open;
+ device->close = rt_sensor_close;
+ device->read = rt_sensor_read;
+ device->write = RT_NULL;
+ device->control = rt_sensor_control;
+#endif
+ device->type = RT_Device_Class_Sensor;
+ device->rx_indicate = RT_NULL;
+ device->tx_complete = RT_NULL;
+ device->user_data = data;
+
+ result = rt_device_register(device, device_name, flag | RT_DEVICE_FLAG_STANDALONE);
+ if (result != RT_EOK)
+ {
+ rt_free(device_name);
+ LOG_E("rt_sensor register err code: %d", result);
+ return result;
+ }
+
+ rt_free(device_name);
+ LOG_I("rt_sensor init success");
+ return RT_EOK;
+}
diff --git a/components/drivers/sensors/sensor.cpp b/components/drivers/sensors/sensor.cpp
deleted file mode 100644
index f986510f63..0000000000
--- a/components/drivers/sensors/sensor.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2014-08-03 Bernard the first version
- */
-
-#include <stddef.h>
-#include <string.h>
-
-#include "sensor.h"
-
-/**
- * SensorBase
- */
-SensorBase::SensorBase(int type)
-{
- memset(&(this->config), 0x0, sizeof(SensorConfig));
-
- this->type = type;
- this->next = this->prev = NULL;
- subscribe(NULL, NULL);
-}
-
-SensorBase::~SensorBase()
-{
-}
-
-int SensorBase::getType(void)
-{
- return this->type;
-}
-
-int SensorBase::setConfig(SensorConfig *config)
-{
- int result;
-
- /* configure to the low level sensor */
- result = this->configure(config);
- if (result == 0)
- {
- this->config = *config;
- }
-
- return result;
-}
-
-int SensorBase::getConfig(SensorConfig *config)
-{
- *config = this->config;
- return 0;
-}
-
-int SensorBase::subscribe(SensorEventHandler_t handler, void *user_data)
-{
- this->evtHandler = handler;
- this->userData = user_data;
-
- return 0;
-}
-
-int SensorBase::publish(void)
-{
- if (this->evtHandler != NULL)
- {
- /* invoke subscribed handler */
- (*evtHandler)(this->userData);
- }
-
- return 0;
-}
-
-/**
- * Sensor Manager
- */
-/* sensors list */
-static SensorBase *sensor_list = NULL;
-
-SensorManager::SensorManager()
-{
-}
-
-SensorManager::~SensorManager()
-{
-}
-
-int SensorManager::registerSensor(SensorBase *sensor)
-{
- RT_ASSERT(sensor != RT_NULL);
-
- /* add sensor into the list */
- if (sensor_list == NULL)
- {
- sensor->prev = sensor->next = sensor;
- }
- else
- {
- sensor_list->prev->next = sensor;
- sensor->prev = sensor_list->prev;
-
- sensor_list->prev = sensor;
- sensor->next = sensor_list;
- }
-
- /* point the sensorList to this sensor */
- sensor_list = sensor;
-
- return 0;
-}
-
-int SensorManager::unregisterSensor(SensorBase *sensor)
-{
- /* disconnect sensor list */
- sensor->next->prev = sensor->prev;
- sensor->prev->next = sensor->next;
-
- /* check the sensorList */
- if (sensor == sensor_list)
- {
- if (sensor->next == sensor) sensor_list = NULL; /* empty list */
- else sensor_list = sensor->next;
- }
-
- /* re-initialize sensor node */
- sensor->next = sensor->prev = sensor;
-
- return 0;
-}
-
-SensorBase *SensorManager::getDefaultSensor(int type)
-{
- SensorBase *sensor = sensor_list;
-
- if (sensor == NULL) return NULL;
-
- do
- {
- /* find the same type */
- if (sensor->getType() == type) return sensor;
-
- sensor = sensor->next;
- }while (sensor != sensor_list);
-
- return NULL;
-}
-
-int SensorManager::subscribe(int type, SensorEventHandler_t handler, void *user_data)
-{
- SensorBase *sensor;
-
- sensor = SensorManager::getDefaultSensor(type);
- if (sensor != NULL)
- {
- sensor->subscribe(handler, user_data);
- return 0;
- }
-
- return -1;
-}
-
-int SensorManager::sensorEventReady(SensorBase *sensor)
-{
- return 0;
-}
-
-int SensorManager::pollSensor(SensorBase *sensor, sensors_event_t *events, int number, int duration)
-{
- rt_tick_t tick;
- int result, index;
-
- if (sensor == NULL) return -1;
-
- tick = rt_tick_get();
- for (index = 0; index < number; index ++)
- {
- result = sensor->poll(&events[index]);
- if (result < 0) break;
-
- if (rt_tick_get() - tick > duration) break;
- }
-
- return index;
-}
-
-rt_sensor_t rt_sensor_get_default(int type)
-{
- return (rt_sensor_t)SensorManager::getDefaultSensor(type);
-}
-
-int rt_sensor_subscribe(rt_sensor_t sensor, SensorEventHandler_t handler, void *user_data)
-{
- SensorBase *sensor_base;
- if (sensor == NULL) return -1;
-
- sensor_base = (SensorBase*)sensor;
-
- return sensor_base->subscribe(handler, user_data);
-}
-
-int rt_sensor_poll(rt_sensor_t sensor, sensors_event_t *event)
-{
- SensorBase *sensor_base;
- if (sensor == NULL || event == NULL) return -1;
-
- sensor_base = (SensorBase*)sensor;
- return sensor_base->poll(event);
-}
-
-int rt_sensor_configure(rt_sensor_t sensor, SensorConfig *config)
-{
- SensorBase *sensor_base;
- if (sensor == NULL || config == NULL) return -1;
-
- sensor_base = (SensorBase*)sensor;
- return sensor_base->setConfig(config);
-}
-
-int rt_sensor_activate(rt_sensor_t sensor, int enable)
-{
- SensorBase *sensor_base;
- if (sensor == NULL) return -1;
-
- sensor_base = (SensorBase*)sensor;
- return sensor_base->activate(enable);
-}
diff --git a/components/drivers/sensors/sensor.h b/components/drivers/sensors/sensor.h
index 916360d34b..5a069edc25 100644..100755
--- a/components/drivers/sensors/sensor.h
+++ b/components/drivers/sensors/sensor.h
@@ -5,1125 +5,233 @@
*
* Change Logs:
* Date Author Notes
- * 2014-08-03 Bernard the first version
+ * 2019-01-31 flybreak first version
*/
-/* Modified from: https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h */
-
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SENSORS_H__
-#define SENSORS_H__
+#ifndef __SENSOR_H__
+#define __SENSOR_H__
+#include <rtthread.h>
#include <rtdevice.h>
-#include <stdint.h>
-#ifdef __CC_ARM /* skip warning in armcc */
-#pragma anon_unions
+#ifdef __cplusplus
+extern "C" {
#endif
-/**
- * Handles must be higher than SENSORS_HANDLE_BASE and must be unique.
- * A Handle identifies a given sensors. The handle is used to activate
- * and/or deactivate sensors.
- * In this version of the API there can only be 256 handles.
- */
-#define SENSORS_HANDLE_BASE 0
-#define SENSORS_HANDLE_BITS 8
-#define SENSORS_HANDLE_COUNT (1<<SENSORS_HANDLE_BITS)
-
-
-/*
- * flags for (*batch)()
- * Availability: SENSORS_DEVICE_API_VERSION_1_0
- * see (*batch)() documentation for details
- */
-enum
-{
- SENSORS_BATCH_DRY_RUN = 0x00000001,
- SENSORS_BATCH_WAKE_UPON_FIFO_FULL = 0x00000002
-};
-
-/*
- * what field for meta_data_event_t
- */
-enum
-{
- /* a previous flush operation has completed */
- META_DATA_FLUSH_COMPLETE = 1,
- META_DATA_VERSION /* always last, leave auto-assigned */
-};
-
-/**
- * Definition of the axis used by the sensor HAL API
- *
- * This API is relative to the screen of the device in its default orientation,
- * that is, if the device can be used in portrait or landscape, this API
- * is only relative to the NATURAL orientation of the screen. In other words,
- * the axis are not swapped when the device's screen orientation changes.
- * Higher level services /may/ perform this transformation.
- *
- * x<0 x>0
- * ^
- * |
- * +-----------+--> y>0
- * | |
- * | |
- * | |
- * | | / z<0
- * | | /
- * | | /
- * O-----------+/
- * |[] [ ] []/
- * +----------/+ y<0
- * /
- * /
- * |/ z>0 (toward the sky)
- *
- * O: Origin (x=0,y=0,z=0)
- *
- */
-
-/*
- * Interaction with suspend mode
- *
- * Unless otherwise noted, an enabled sensor shall not prevent the
- * SoC to go into suspend mode. It is the responsibility of applications
- * to keep a partial wake-lock should they wish to receive sensor
- * events while the screen is off. While in suspend mode, and unless
- * otherwise noted (batch mode, sensor particularities, ...), enabled sensors'
- * events are lost.
- *
- * Note that conceptually, the sensor itself is not de-activated while in
- * suspend mode -- it's just that the data it returns are lost. As soon as
- * the SoC gets out of suspend mode, operations resume as usual. Of course,
- * in practice sensors shall be disabled while in suspend mode to
- * save power, unless batch mode is active, in which case they must
- * continue fill their internal FIFO (see the documentation of batch() to
- * learn how suspend interacts with batch mode).
- *
- * In batch mode, and only when the flag SENSORS_BATCH_WAKE_UPON_FIFO_FULL is
- * set and supported, the specified sensor must be able to wake-up the SoC and
- * be able to buffer at least 10 seconds worth of the requested sensor events.
- *
- * There are notable exceptions to this behavior, which are sensor-dependent
- * (see sensor types definitions below)
- *
- *
- * The sensor type documentation below specifies the wake-up behavior of
- * each sensor:
- * wake-up: yes this sensor must wake-up the SoC to deliver events
- * wake-up: no this sensor shall not wake-up the SoC, events are dropped
- *
- */
-
-/*
- * Sensor type
- *
- * Each sensor has a type which defines what this sensor measures and how
- * measures are reported. All types are defined below.
- *
- * Device manufacturers (OEMs) can define their own sensor types, for
- * their private use by applications or services provided by them. Such
- * sensor types are specific to an OEM and can't be exposed in the SDK.
- * These types must start at SENSOR_TYPE_DEVICE_PRIVATE_BASE.
- */
-
-/*
- * Base for device manufacturers private sensor types.
- * These sensor types can't be exposed in the SDK.
- */
-#define SENSOR_TYPE_DEVICE_PRIVATE_BASE 0x10000
-
-/*
- * Sensor fusion and virtual sensors
- *
- * Many sensor types are or can be implemented as virtual sensors from
- * physical sensors on the device. For instance the rotation vector sensor,
- * orientation sensor, step-detector, step-counter, etc...
- *
- * From the point of view of this API these virtual sensors MUST appear as
- * real, individual sensors. It is the responsibility of the driver and HAL
- * to make sure this is the case.
- *
- * In particular, all sensors must be able to function concurrently.
- * For example, if defining both an accelerometer and a step counter,
- * then both must be able to work concurrently.
- */
-
-/*
- * Trigger modes
- *
- * Sensors can report events in different ways called trigger modes,
- * each sensor type has one and only one trigger mode associated to it.
- * Currently there are four trigger modes defined:
- *
- * continuous: events are reported at a constant rate defined by setDelay().
- * eg: accelerometers, gyroscopes.
- * on-change: events are reported only if the sensor's value has changed.
- * setDelay() is used to set a lower limit to the reporting
- * period (minimum time between two events).
- * The HAL must return an event immediately when an on-change
- * sensor is activated.
- * eg: proximity, light sensors
- * one-shot: upon detection of an event, the sensor deactivates itself and
- * then sends a single event. Order matters to avoid race
- * conditions. No other event is sent until the sensor get
- * reactivated. setDelay() is ignored.
- * eg: significant motion sensor
- * special: see details in the sensor type specification below
- *
- */
-
-/*
- * SENSOR_TYPE_META_DATA
- * trigger-mode: n/a
- * wake-up sensor: n/a
- *
- * NO SENSOR OF THAT TYPE MUST BE RETURNED (*get_sensors_list)()
- *
- * SENSOR_TYPE_META_DATA is a special token used to populate the
- * sensors_meta_data_event structure. It doesn't correspond to a physical
- * sensor. sensors_meta_data_event are special, they exist only inside
- * the HAL and are generated spontaneously, as opposed to be related to
- * a physical sensor.
- *
- * sensors_meta_data_event_t.version must be META_DATA_VERSION
- * sensors_meta_data_event_t.sensor must be 0
- * sensors_meta_data_event_t.type must be SENSOR_TYPE_META_DATA
- * sensors_meta_data_event_t.reserved must be 0
- * sensors_meta_data_event_t.timestamp must be 0
- *
- * The payload is a meta_data_event_t, where:
- * meta_data_event_t.what can take the following values:
- *
- * META_DATA_FLUSH_COMPLETE
- * This event indicates that a previous (*flush)() call has completed for the sensor
- * handle specified in meta_data_event_t.sensor.
- * see (*flush)() for more details
- *
- * All other values for meta_data_event_t.what are reserved and
- * must not be used.
- *
- */
-#define SENSOR_TYPE_META_DATA (0)
-
-/*
- * SENSOR_TYPE_ACCELEROMETER
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * All values are in SI units (m/s^2) and measure the acceleration of the
- * device minus the force of gravity.
- *
- * Acceleration sensors return sensor events for all 3 axes at a constant
- * rate defined by setDelay().
- *
- * x: Acceleration on the x-axis
- * y: Acceleration on the y-axis
- * z: Acceleration on the z-axis
- *
- * Note that the readings from the accelerometer include the acceleration
- * due to gravity (which is opposite to the direction of the gravity vector).
- *
- * Examples:
- * The norm of <x, y, z> should be close to 0 when in free fall.
- *
- * When the device lies flat on a table and is pushed on its left side
- * toward the right, the x acceleration value is positive.
- *
- * When the device lies flat on a table, the acceleration value is +9.81,
- * which correspond to the acceleration of the device (0 m/s^2) minus the
- * force of gravity (-9.81 m/s^2).
- *
- * When the device lies flat on a table and is pushed toward the sky, the
- * acceleration value is greater than +9.81, which correspond to the
- * acceleration of the device (+A m/s^2) minus the force of
- * gravity (-9.81 m/s^2).
- */
-#define SENSOR_TYPE_ACCELEROMETER (1)
-
-/*
- * SENSOR_TYPE_GEOMAGNETIC_FIELD
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * All values are in micro-Tesla (uT) and measure the geomagnetic
- * field in the X, Y and Z axis.
- *
- * Returned values include calibration mechanisms such that the vector is
- * aligned with the magnetic declination and heading of the earth's
- * geomagnetic field.
- *
- * Magnetic Field sensors return sensor events for all 3 axes at a constant
- * rate defined by setDelay().
- */
-#define SENSOR_TYPE_GEOMAGNETIC_FIELD (2)
-#define SENSOR_TYPE_MAGNETIC_FIELD SENSOR_TYPE_GEOMAGNETIC_FIELD
-
-/*
- * SENSOR_TYPE_ORIENTATION
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * All values are angles in degrees.
- *
- * Orientation sensors return sensor events for all 3 axes at a constant
- * rate defined by setDelay().
- *
- * azimuth: angle between the magnetic north direction and the Y axis, around
- * the Z axis (0<=azimuth<360).
- * 0=North, 90=East, 180=South, 270=West
- *
- * pitch: Rotation around X axis (-180<=pitch<=180), with positive values when
- * the z-axis moves toward the y-axis.
- *
- * roll: Rotation around Y axis (-90<=roll<=90), with positive values when
- * the x-axis moves towards the z-axis.
- *
- * Note: For historical reasons the roll angle is positive in the clockwise
- * direction (mathematically speaking, it should be positive in the
- * counter-clockwise direction):
- *
- * Z
- * ^
- * (+roll) .--> |
- * / |
- * | | roll: rotation around Y axis
- * X <-------(.)
- * Y
- * note that +Y == -roll
- *
- *
- *
- * Note: This definition is different from yaw, pitch and roll used in aviation
- * where the X axis is along the long side of the plane (tail to nose).
- */
-#define SENSOR_TYPE_ORIENTATION (3)
-
-/*
- * SENSOR_TYPE_GYROSCOPE
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * All values are in radians/second and measure the rate of rotation
- * around the X, Y and Z axis. The coordinate system is the same as is
- * used for the acceleration sensor. Rotation is positive in the
- * counter-clockwise direction (right-hand rule). That is, an observer
- * looking from some positive location on the x, y or z axis at a device
- * positioned on the origin would report positive rotation if the device
- * appeared to be rotating counter clockwise. Note that this is the
- * standard mathematical definition of positive rotation and does not agree
- * with the definition of roll given earlier.
- * The range should at least be 17.45 rad/s (ie: ~1000 deg/s).
- *
- * automatic gyro-drift compensation is allowed but not required.
- */
-#define SENSOR_TYPE_GYROSCOPE (4)
-
-/*
- * SENSOR_TYPE_LIGHT
- * trigger-mode: on-change
- * wake-up sensor: no
- *
- * The light sensor value is returned in SI lux units.
- */
-#define SENSOR_TYPE_LIGHT (5)
-
-/*
- * SENSOR_TYPE_PRESSURE
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * The pressure sensor return the athmospheric pressure in hectopascal (hPa)
- */
-#define SENSOR_TYPE_PRESSURE (6)
-
-/* SENSOR_TYPE_TEMPERATURE is deprecated in the HAL */
-#define SENSOR_TYPE_TEMPERATURE (7)
-
-/*
- * SENSOR_TYPE_PROXIMITY
- * trigger-mode: on-change
- * wake-up sensor: yes
- *
- * The distance value is measured in centimeters. Note that some proximity
- * sensors only support a binary "close" or "far" measurement. In this case,
- * the sensor should report its maxRange value in the "far" state and a value
- * less than maxRange in the "near" state.
- */
-#define SENSOR_TYPE_PROXIMITY (8)
-
-/*
- * SENSOR_TYPE_GRAVITY
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * A gravity output indicates the direction of and magnitude of gravity in
- * the devices's coordinates. On Earth, the magnitude is 9.8 m/s^2.
- * Units are m/s^2. The coordinate system is the same as is used for the
- * acceleration sensor. When the device is at rest, the output of the
- * gravity sensor should be identical to that of the accelerometer.
- */
-#define SENSOR_TYPE_GRAVITY (9)
-
-/*
- * SENSOR_TYPE_LINEAR_ACCELERATION
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * Indicates the linear acceleration of the device in device coordinates,
- * not including gravity.
- *
- * The output is conceptually:
- * output of TYPE_ACCELERATION - output of TYPE_GRAVITY
- *
- * Readings on all axes should be close to 0 when device lies on a table.
- * Units are m/s^2.
- * The coordinate system is the same as is used for the acceleration sensor.
- */
-#define SENSOR_TYPE_LINEAR_ACCELERATION (10)
-
-/*
- * SENSOR_TYPE_ROTATION_VECTOR
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * The rotation vector symbolizes the orientation of the device relative to the
- * East-North-Up coordinates frame. It is usually obtained by integration of
- * accelerometer, gyroscope and magnetometer readings.
- *
- * The East-North-Up coordinate system is defined as a direct orthonormal basis
- * where:
- * - X points east and is tangential to the ground.
- * - Y points north and is tangential to the ground.
- * - Z points towards the sky and is perpendicular to the ground.
- *
- * The orientation of the phone is represented by the rotation necessary to
- * align the East-North-Up coordinates with the phone's coordinates. That is,
- * applying the rotation to the world frame (X,Y,Z) would align them with the
- * phone coordinates (x,y,z).
- *
- * The rotation can be seen as rotating the phone by an angle theta around
- * an axis rot_axis to go from the reference (East-North-Up aligned) device
- * orientation to the current device orientation.
- *
- * The rotation is encoded as the 4 (reordered) components of a unit quaternion:
- * sensors_event_t.data[0] = rot_axis.x*sin(theta/2)
- * sensors_event_t.data[1] = rot_axis.y*sin(theta/2)
- * sensors_event_t.data[2] = rot_axis.z*sin(theta/2)
- * sensors_event_t.data[3] = cos(theta/2)
- * where
- * - rot_axis.x,y,z are the North-East-Up coordinates of a unit length vector
- * representing the rotation axis
- * - theta is the rotation angle
- *
- * The quaternion must be of norm 1 (it is a unit quaternion). Failure to ensure
- * this will cause erratic client behaviour.
- *
- * In addition, this sensor reports an estimated heading accuracy.
- * sensors_event_t.data[4] = estimated_accuracy (in radians)
- * The heading error must be less than estimated_accuracy 95% of the time
- *
- * This sensor must use a gyroscope and an accelerometer as main orientation
- * change input.
- *
- * This sensor can also include magnetometer input to make up for gyro drift,
- * but it cannot be implemented using only a magnetometer.
- */
-#define SENSOR_TYPE_ROTATION_VECTOR (11)
-
-/*
- * SENSOR_TYPE_RELATIVE_HUMIDITY
- * trigger-mode: on-change
- * wake-up sensor: no
- *
- * A relative humidity sensor measures relative ambient air humidity and
- * returns a value in percent.
- */
-#define SENSOR_TYPE_RELATIVE_HUMIDITY (12)
-
-/*
- * SENSOR_TYPE_AMBIENT_TEMPERATURE
- * trigger-mode: on-change
- * wake-up sensor: no
- *
- * The ambient (room) temperature in degree Celsius.
- */
-#define SENSOR_TYPE_AMBIENT_TEMPERATURE (13)
-
-/*
- * SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * Similar to SENSOR_TYPE_MAGNETIC_FIELD, but the hard iron calibration is
- * reported separately instead of being included in the measurement.
- * Factory calibration and temperature compensation should still be applied to
- * the "uncalibrated" measurement.
- * Separating away the hard iron calibration estimation allows the system to
- * better recover from bad hard iron estimation.
- *
- * All values are in micro-Tesla (uT) and measure the ambient magnetic
- * field in the X, Y and Z axis. Assumptions that the the magnetic field
- * is due to the Earth's poles should be avoided.
- *
- * The uncalibrated_magnetic event contains
- * - 3 fields for uncalibrated measurement: x_uncalib, y_uncalib, z_uncalib.
- * Each is a component of the measured magnetic field, with soft iron
- * and temperature compensation applied, but not hard iron calibration.
- * These values should be continuous (no re-calibration should cause a jump).
- * - 3 fields for hard iron bias estimates: x_bias, y_bias, z_bias.
- * Each field is a component of the estimated hard iron calibration.
- * They represent the offsets to apply to the calibrated readings to obtain
- * uncalibrated readings (x_uncalib ~= x_calibrated + x_bias)
- * These values are expected to jump as soon as the estimate of the hard iron
- * changes, and they should be stable the rest of the time.
- *
- * If this sensor is present, then the corresponding
- * SENSOR_TYPE_MAGNETIC_FIELD must be present and both must return the
- * same sensor_t::name and sensor_t::vendor.
- *
- * Minimum filtering should be applied to this sensor. In particular, low pass
- * filters should be avoided.
- *
- * See SENSOR_TYPE_MAGNETIC_FIELD for more information
- */
-#define SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED (14)
+#ifdef RT_USING_RTC
+#define rt_sensor_get_ts() time(RT_NULL) /* API for the sensor to get the timestamp */
+#else
+#define rt_sensor_get_ts() rt_tick_get() /* API for the sensor to get the timestamp */
+#endif
-/*
- * SENSOR_TYPE_GAME_ROTATION_VECTOR
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * Similar to SENSOR_TYPE_ROTATION_VECTOR, but not using the geomagnetic
- * field. Therefore the Y axis doesn't point north, but instead to some other
- * reference. That reference is allowed to drift by the same order of
- * magnitude than the gyroscope drift around the Z axis.
- *
- * This sensor does not report an estimated heading accuracy:
- * sensors_event_t.data[4] is reserved and should be set to 0
- *
- * In the ideal case, a phone rotated and returning to the same real-world
- * orientation should report the same game rotation vector
- * (without using the earth's geomagnetic field).
- *
- * This sensor must be based on a gyroscope. It cannot be implemented using
- * a magnetometer.
- *
- * see SENSOR_TYPE_ROTATION_VECTOR for more details
- */
-#define SENSOR_TYPE_GAME_ROTATION_VECTOR (15)
+#define RT_PIN_NONE 0xFFFF /* RT PIN NONE */
+#define RT_DEVICE_FLAG_FIFO_RX 0x200 /* Flag to use when the sensor is open by fifo mode */
-/*
- * SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * All values are in radians/second and measure the rate of rotation
- * around the X, Y and Z axis. An estimation of the drift on each axis is
- * reported as well.
- *
- * No gyro-drift compensation shall be performed.
- * Factory calibration and temperature compensation should still be applied
- * to the rate of rotation (angular speeds).
- *
- * The coordinate system is the same as is
- * used for the acceleration sensor. Rotation is positive in the
- * counter-clockwise direction (right-hand rule). That is, an observer
- * looking from some positive location on the x, y or z axis at a device
- * positioned on the origin would report positive rotation if the device
- * appeared to be rotating counter clockwise. Note that this is the
- * standard mathematical definition of positive rotation and does not agree
- * with the definition of roll given earlier.
- * The range should at least be 17.45 rad/s (ie: ~1000 deg/s).
- *
- * Content of an uncalibrated_gyro event: (units are rad/sec)
- * x_uncalib : angular speed (w/o drift compensation) around the X axis
- * y_uncalib : angular speed (w/o drift compensation) around the Y axis
- * z_uncalib : angular speed (w/o drift compensation) around the Z axis
- * x_bias : estimated drift around X axis in rad/s
- * y_bias : estimated drift around Y axis in rad/s
- * z_bias : estimated drift around Z axis in rad/s
- *
- * IMPLEMENTATION NOTES:
- *
- * If the implementation is not able to estimate the drift, then this
- * sensor MUST NOT be reported by this HAL. Instead, the regular
- * SENSOR_TYPE_GYROSCOPE is used without drift compensation.
- *
- * If this sensor is present, then the corresponding
- * SENSOR_TYPE_GYROSCOPE must be present and both must return the
- * same sensor_t::name and sensor_t::vendor.
- */
-#define SENSOR_TYPE_GYROSCOPE_UNCALIBRATED (16)
+#define RT_SENSOR_MODULE_MAX (3) /* The maximum number of members of a sensor module */
-/*
- * SENSOR_TYPE_SIGNIFICANT_MOTION
- * trigger-mode: one-shot
- * wake-up sensor: yes
- *
- * A sensor of this type triggers an event each time significant motion
- * is detected and automatically disables itself.
- * The only allowed value to return is 1.0.
- *
- * A significant motion is a motion that might lead to a change in the user
- * location.
- * Examples of such motions are:
- * walking, biking, sitting in a moving car, coach or train.
- * Examples of situations that should not trigger significant motion:
- * - phone in pocket and person is not moving
- * - phone is on a table, even if the table shakes a bit due to nearby traffic
- * or washing machine
- *
- * A note on false positive / false negative / power consumption tradeoff
- * - The goal of this sensor is to save power.
- * - Triggering an event when the user is not moving (false positive) is costly
- * in terms of power, so it should be avoided.
- * - Not triggering an event when the user is moving (false negative) is
- * acceptable as long as it is not done repeatedly. If the user has been
- * walking for 10 seconds, not triggering an event within those 10 seconds
- * is not acceptable.
- *
- * IMPORTANT NOTE: this sensor type is very different from other types
- * in that it must work when the screen is off without the need of
- * holding a partial wake-lock and MUST allow the SoC to go into suspend.
- * When significant motion is detected, the sensor must awaken the SoC and
- * the event be reported.
- *
- * If a particular hardware cannot support this mode of operation then this
- * sensor type MUST NOT be reported by the HAL. ie: it is not acceptable
- * to "emulate" this sensor in the HAL.
- *
- * The whole point of this sensor type is to save power by keeping the
- * SoC in suspend mode when the device is at rest.
- *
- * When the sensor is not activated, it must also be deactivated in the
- * hardware: it must not wake up the SoC anymore, even in case of
- * significant motion.
- *
- * setDelay() has no effect and is ignored.
- * Once a "significant motion" event is returned, a sensor of this type
- * must disables itself automatically, as if activate(..., 0) had been called.
- */
+/* Sensor types */
-#define SENSOR_TYPE_SIGNIFICANT_MOTION (17)
+#define RT_SENSOR_CLASS_NONE (0)
+#define RT_SENSOR_CLASS_ACCE (1) /* Accelerometer */
+#define RT_SENSOR_CLASS_GYRO (2) /* Gyroscope */
+#define RT_SENSOR_CLASS_MAG (3) /* Magnetometer */
+#define RT_SENSOR_CLASS_TEMP (4) /* Temperature */
+#define RT_SENSOR_CLASS_HUMI (5) /* Relative Humidity */
+#define RT_SENSOR_CLASS_BARO (6) /* Barometer */
+#define RT_SENSOR_CLASS_LIGHT (7) /* Ambient light */
+#define RT_SENSOR_CLASS_PROXIMITY (8) /* Proximity */
+#define RT_SENSOR_CLASS_HR (9) /* Heart Rate */
+#define RT_SENSOR_CLASS_TVOC (10) /* TVOC Level */
+#define RT_SENSOR_CLASS_NOISE (11) /* Noise Loudness */
+#define RT_SENSOR_CLASS_STEP (12) /* Step sensor */
+#define RT_SENSOR_CLASS_FORCE (13) /* Force sensor */
+#define RT_SENSOR_CLASS_DUST (14) /* Dust sensor */
+#define RT_SENSOR_CLASS_ECO2 (15) /* eCO2 sensor */
+#define RT_SENSOR_CLASS_GNSS (16) /* GPS/GNSS sensor */
-/*
- * SENSOR_TYPE_STEP_DETECTOR
- * trigger-mode: special
- * wake-up sensor: no
- *
- * A sensor of this type triggers an event each time a step is taken
- * by the user. The only allowed value to return is 1.0 and an event is
- * generated for each step. Like with any other event, the timestamp
- * indicates when the event (here the step) occurred, this corresponds to when
- * the foot hit the ground, generating a high variation in acceleration.
- *
- * While this sensor operates, it shall not disrupt any other sensors, in
- * particular, but not limited to, the accelerometer; which might very well
- * be in use as well.
- *
- * This sensor must be low power. That is, if the step detection cannot be
- * done in hardware, this sensor should not be defined. Also, when the
- * step detector is activated and the accelerometer is not, only steps should
- * trigger interrupts (not accelerometer data).
- *
- * setDelay() has no impact on this sensor type
- */
+/* Sensor vendor types */
-#define SENSOR_TYPE_STEP_DETECTOR (18)
+#define RT_SENSOR_VENDOR_UNKNOWN (0)
+#define RT_SENSOR_VENDOR_STM (1) /* STMicroelectronics */
+#define RT_SENSOR_VENDOR_BOSCH (2) /* Bosch */
+#define RT_SENSOR_VENDOR_INVENSENSE (3) /* Invensense */
+#define RT_SENSOR_VENDOR_SEMTECH (4) /* Semtech */
+#define RT_SENSOR_VENDOR_GOERTEK (5) /* Goertek */
+#define RT_SENSOR_VENDOR_MIRAMEMS (6) /* MiraMEMS */
+#define RT_SENSOR_VENDOR_DALLAS (7) /* Dallas */
+#define RT_SENSOR_VENDOR_ASAIR (8) /* Aosong */
+#define RT_SENSOR_VENDOR_SHARP (9) /* Sharp */
+#define RT_SENSOR_VENDOR_SENSIRION (10) /* Sensirion */
+#define RT_SENSOR_VENDOR_TI (11) /* Texas Instruments */
+#define RT_SENSOR_VENDOR_PLANTOWER (12) /* Plantower */
+#define RT_SENSOR_VENDOR_AMS (13) /* ams AG */
+#define RT_SENSOR_VENDOR_MAXIM (14) /* Maxim Integrated */
-/*
- * SENSOR_TYPE_STEP_COUNTER
- * trigger-mode: on-change
- * wake-up sensor: no
- *
- * A sensor of this type returns the number of steps taken by the user since
- * the last reboot while activated. The value is returned as a uint64_t and is
- * reset to zero only on a system / android reboot.
- *
- * The timestamp of the event is set to the time when the first step
- * for that event was taken.
- * See SENSOR_TYPE_STEP_DETECTOR for the signification of the time of a step.
- *
- * The minimum size of the hardware's internal counter shall be 16 bits
- * (this restriction is here to avoid too frequent wake-ups when the
- * delay is very large).
- *
- * IMPORTANT NOTE: this sensor type is different from other types
- * in that it must work when the screen is off without the need of
- * holding a partial wake-lock and MUST allow the SoC to go into suspend.
- * Unlike other sensors, while in suspend mode this sensor must stay active,
- * no events are reported during that time but, steps continue to be
- * accounted for; an event will be reported as soon as the SoC resumes if
- * the timeout has expired.
- *
- * In other words, when the screen is off and the device allowed to
- * go into suspend mode, we don't want to be woken up, regardless of the
- * setDelay() value, but the steps shall continue to be counted.
- *
- * The driver must however ensure that the internal step count never
- * overflows. It is allowed in this situation to wake the SoC up so the
- * driver can do the counter maintenance.
- *
- * While this sensor operates, it shall not disrupt any other sensors, in
- * particular, but not limited to, the accelerometer; which might very well
- * be in use as well.
- *
- * If a particular hardware cannot support these modes of operation then this
- * sensor type MUST NOT be reported by the HAL. ie: it is not acceptable
- * to "emulate" this sensor in the HAL.
- *
- * This sensor must be low power. That is, if the step detection cannot be
- * done in hardware, this sensor should not be defined. Also, when the
- * step counter is activated and the accelerometer is not, only steps should
- * trigger interrupts (not accelerometer data).
- *
- * The whole point of this sensor type is to save power by keeping the
- * SoC in suspend mode when the device is at rest.
- */
-#define SENSOR_TYPE_STEP_COUNTER (19)
+/* Sensor unit types */
-/*
- * SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR
- * trigger-mode: continuous
- * wake-up sensor: no
- *
- * Similar to SENSOR_TYPE_ROTATION_VECTOR, but using a magnetometer instead
- * of using a gyroscope.
- *
- * This sensor must be based on a magnetometer. It cannot be implemented using
- * a gyroscope, and gyroscope input cannot be used by this sensor, as the
- * goal of this sensor is to be low power.
- * The accelerometer can be (and usually is) used.
- *
- * Just like SENSOR_TYPE_ROTATION_VECTOR, this sensor reports an estimated
- * heading accuracy:
- * sensors_event_t.data[4] = estimated_accuracy (in radians)
- * The heading error must be less than estimated_accuracy 95% of the time
- *
- * see SENSOR_TYPE_ROTATION_VECTOR for more details
- */
-#define SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR (20)
+#define RT_SENSOR_UNIT_NONE (0)
+#define RT_SENSOR_UNIT_MG (1) /* Accelerometer unit: mG */
+#define RT_SENSOR_UNIT_MDPS (2) /* Gyroscope unit: mdps */
+#define RT_SENSOR_UNIT_MGAUSS (3) /* Magnetometer unit: mGauss */
+#define RT_SENSOR_UNIT_LUX (4) /* Ambient light unit: lux */
+#define RT_SENSOR_UNIT_CM (5) /* Distance unit: cm */
+#define RT_SENSOR_UNIT_PA (6) /* Barometer unit: pa */
+#define RT_SENSOR_UNIT_PERMILLAGE (7) /* Relative Humidity unit: permillage */
+#define RT_SENSOR_UNIT_DCELSIUS (8) /* Temperature unit: dCelsius */
+#define RT_SENSOR_UNIT_HZ (9) /* Frequency unit: HZ */
+#define RT_SENSOR_UNIT_ONE (10) /* Dimensionless quantity unit: 1 */
+#define RT_SENSOR_UNIT_BPM (11) /* Heart rate unit: bpm */
+#define RT_SENSOR_UNIT_MM (12) /* Distance unit: mm */
+#define RT_SENSOR_UNIT_MN (13) /* Force unit: mN */
+#define RT_SENSOR_UNIT_PPM (14) /* Concentration unit: ppm */
+#define RT_SENSOR_UNIT_PPB (15) /* Concentration unit: ppb */
+#define RT_SENSOR_UNIT_DMS (16) /* Coordinates unit: DMS */
+#define RT_SENSOR_UNIT_DD (17) /* Coordinates unit: DD */
-/**
- * Values returned by the accelerometer in various locations in the universe.
- * all values are in SI units (m/s^2)
- */
-#define SENSORS_GRAVITY_SUN (275.0f)
-#define SENSORS_GRAVITY_MOON (1.6f)
-#define SENSORS_GRAVITY_EARTH (9.80665f)
-#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH)
+/* Sensor communication interface types */
-/** Maximum magnetic field on Earth's surface */
-#define MAGNETIC_FIELD_EARTH_MAX (60.0f)
+#define RT_SENSOR_INTF_I2C (1 << 0)
+#define RT_SENSOR_INTF_SPI (1 << 1)
+#define RT_SENSOR_INTF_UART (1 << 2)
+#define RT_SENSOR_INTF_ONEWIRE (1 << 3)
-/** Minimum magnetic field on Earth's surface */
-#define MAGNETIC_FIELD_EARTH_MIN (30.0f)
+/* Sensor power mode types */
-/** Average sea level pressure is 1013.25 hPa */
-#define SENSORS_PRESSURE_SEALEVELHPA (1013.25F)
+#define RT_SENSOR_POWER_NONE (0)
+#define RT_SENSOR_POWER_DOWN (1) /* power down mode */
+#define RT_SENSOR_POWER_NORMAL (2) /* normal-power mode */
+#define RT_SENSOR_POWER_LOW (3) /* low-power mode */
+#define RT_SENSOR_POWER_HIGH (4) /* high-power mode */
-/** Degrees/s to rad/s multiplier */
-#define SENSORS_DPS_TO_RADS (0.017453293F)
-/** Gauss to micro-Tesla multiplier */
-#define SENSORS_GAUSS_TO_MICROTESLA (100)
+/* Sensor work mode types */
-/**
- * status of orientation sensor
- */
-#define SENSOR_STATUS_UNRELIABLE 0
-#define SENSOR_STATUS_ACCURACY_LOW 1
-#define SENSOR_STATUS_ACCURACY_MEDIUM 2
-#define SENSOR_STATUS_ACCURACY_HIGH 3
+#define RT_SENSOR_MODE_NONE (0)
+#define RT_SENSOR_MODE_POLLING (1) /* One shot only read a data */
+#define RT_SENSOR_MODE_INT (2) /* TODO: One shot interrupt only read a data */
+#define RT_SENSOR_MODE_FIFO (3) /* TODO: One shot interrupt read all fifo data */
-/**
- * sensor event data
- */
-typedef struct
-{
- union
- {
- float v[3];
- struct
- {
- float x;
- float y;
- float z;
- };
- struct
- {
- float azimuth;
- float pitch;
- float roll;
- };
- };
- int8_t status;
- uint8_t reserved[3];
-} sensors_vec_t;
+/* Sensor control cmd types */
-/**
- * sensor raw vector data
- */
-typedef struct
-{
- struct
- {
- int16_t x;
- int16_t y;
- int16_t z;
- };
+#define RT_SENSOR_CTRL_GET_ID (0) /* Get device id */
+#define RT_SENSOR_CTRL_GET_INFO (1) /* Get sensor info */
+#define RT_SENSOR_CTRL_SET_RANGE (2) /* Set the measure range of sensor. unit is info of sensor */
+#define RT_SENSOR_CTRL_SET_ODR (3) /* Set output date rate. unit is HZ */
+#define RT_SENSOR_CTRL_SET_MODE (4) /* Set sensor's work mode. ex. RT_SENSOR_MODE_POLLING,RT_SENSOR_MODE_INT */
+#define RT_SENSOR_CTRL_SET_POWER (5) /* Set power mode. args type of sensor power mode. ex. RT_SENSOR_POWER_DOWN,RT_SENSOR_POWER_NORMAL */
+#define RT_SENSOR_CTRL_SELF_TEST (6) /* Take a self test */
- int8_t status;
- uint8_t reserved[1];
-} sensors_raw_vec_t;
+#define RT_SENSOR_CTRL_USER_CMD_START 0x100 /* User commands should be greater than 0x100 */
-/**
- * uncalibrated gyroscope and magnetometer event data
- */
-typedef struct
+struct rt_sensor_info
{
- union
- {
- float uncalib[3];
- struct
- {
- float x_uncalib;
- float y_uncalib;
- float z_uncalib;
- };
- };
- union
- {
- float bias[3];
- struct
- {
- float x_bias;
- float y_bias;
- float z_bias;
- };
- };
-} uncalibrated_event_t;
+ rt_uint8_t type; /* The sensor type */
+ rt_uint8_t vendor; /* Vendor of sensors */
+ const char *model; /* model name of sensor */
+ rt_uint8_t unit; /* unit of measurement */
+ rt_uint8_t intf_type; /* Communication interface type */
+ rt_int32_t range_max; /* maximum range of this sensor's value. unit is 'unit' */
+ rt_int32_t range_min; /* minimum range of this sensor's value. unit is 'unit' */
+ rt_uint32_t period_min; /* Minimum measurement period,unit:ms. zero = not a constant rate */
+ rt_uint8_t fifo_max;
+};
-typedef struct meta_data_event
+struct rt_sensor_intf
{
- int32_t what;
- int32_t sensor;
-} meta_data_event_t;
+ char *dev_name; /* The name of the communication device */
+ rt_uint8_t type; /* Communication interface type */
+ void *user_data; /* Private data for the sensor. ex. i2c addr,spi cs,control I/O */
+};
-/**
- * Union of the various types of sensor data
- * that can be returned.
- */
-typedef struct sensors_event_t
+struct rt_sensor_config
{
- /* must be sizeof(struct sensors_event_t) */
- int32_t version;
-
- /* sensor identifier */
- int32_t sensor;
-
- /* sensor type */
- int32_t type;
-
- /* reserved */
- int32_t reserved0;
-
- /* time is in nanosecond */
- int64_t timestamp;
-
- union
- {
- union
- {
- float data[16];
-
- /* acceleration values are in meter per second per second (m/s^2) */
- sensors_vec_t acceleration;
- /* raw acceleration data */
- sensors_raw_vec_t raw_acceleration;
-
- /* magnetic vector values are in micro-Tesla (uT) */
- sensors_vec_t magnetic;
- /* raw magnetic data */
- sensors_raw_vec_t raw_magnetic;
-
- /* orientation values are in degrees */
- sensors_vec_t orientation;
-
- /* gyroscope values are in rad/s */
- sensors_vec_t gyro;
- /* raw gyroscope data */
- sensors_raw_vec_t raw_gyro;
-
- /* temperature is in degrees centigrade (Celsius) */
- float temperature;
-
- /* distance in centimeters */
- float distance;
-
- /* light in SI lux units */
- float light;
-
- /* pressure in hectopascal (hPa) */
- float pressure;
-
- /* relative humidity in percent */
- float relative_humidity;
-
- /* uncalibrated gyroscope values are in rad/s */
- uncalibrated_event_t uncalibrated_gyro;
-
- /* uncalibrated magnetometer values are in micro-Teslas */
- uncalibrated_event_t uncalibrated_magnetic;
-
- /* this is a special event. see SENSOR_TYPE_META_DATA above.
- * sensors_meta_data_event_t events are all reported with a type of
- * SENSOR_TYPE_META_DATA. The handle is ignored and must be zero.
- */
- meta_data_event_t meta_data;
- };
-
- union
- {
- uint64_t data[8];
-
- /* step-counter */
- uint64_t step_counter;
- } u64;
- };
- uint32_t reserved1[4];
-} sensors_event_t;
+ struct rt_sensor_intf intf; /* sensor interface config */
+ struct rt_device_pin_mode irq_pin; /* Interrupt pin, The purpose of this pin is to notification read data */
+ rt_uint8_t mode; /* sensor work mode */
+ rt_uint8_t power; /* sensor power mode */
+ rt_uint16_t odr; /* sensor out data rate */
+ rt_int32_t range; /* sensor range of measurement */
+};
-/* see SENSOR_TYPE_META_DATA */
-typedef sensors_event_t sensors_meta_data_event_t;
+typedef struct rt_sensor_device *rt_sensor_t;
-typedef struct sensor_t
+struct rt_sensor_device
{
- /* Name of this sensor.
- * All sensors of the same "type" must have a different "name".
- */
- const char *name;
-
- /* vendor of the hardware part */
- const char *vendor;
-
- /* version of the hardware part + driver. The value of this field
- * must increase when the driver is updated in a way that changes the
- * output of this sensor. This is important for fused sensors when the
- * fusion algorithm is updated.
- */
- int version;
-
- /* handle that identifies this sensors. This handle is used to reference
- * this sensor throughout the HAL API.
- */
- int handle;
-
- /* this sensor's type. */
- int type;
-
- /* maximum range of this sensor's value in SI units */
- float maxRange;
-
- /* smallest difference between two values reported by this sensor */
- float resolution;
-
- /* rough estimate of this sensor's power consumption in mA */
- float power;
+ struct rt_device parent; /* The standard device */
- /* this value depends on the trigger mode:
- *
- * continuous: minimum sample period allowed in microseconds
- * on-change : 0
- * one-shot :-1
- * special : 0, unless otherwise noted
- */
- int32_t minDelay;
+ struct rt_sensor_info info; /* The sensor info data */
+ struct rt_sensor_config config; /* The sensor config data */
- /* number of events reserved for this sensor in the batch mode FIFO.
- * If there is a dedicated FIFO for this sensor, then this is the
- * size of this FIFO. If the FIFO is shared with other sensors,
- * this is the size reserved for that sensor and it can be zero.
- */
- uint32_t fifoReservedEventCount;
+ void *data_buf; /* The buf of the data received */
+ rt_size_t data_len; /* The size of the data received */
- /* maximum number of events of this sensor that could be batched.
- * This is especially relevant when the FIFO is shared between
- * several sensors; this value is then set to the size of that FIFO.
- */
- uint32_t fifoMaxEventCount;
+ const struct rt_sensor_ops *ops; /* The sensor ops */
- /* reserved fields, must be zero */
- void *reserved[6];
-} sensor_t;
-
-enum SensorMode
-{
- SENSOR_MODE_RAW,
- SENSOR_MODE_CALIBRATED,
- SENSOR_MODE_NORMAL,
+ struct rt_sensor_module *module; /* The sensor module */
+
+ rt_err_t (*irq_handle)(rt_sensor_t sensor); /* Called when an interrupt is generated, registered by the driver */
};
-enum SensorAccelRange
+struct rt_sensor_module
{
- SENSOR_ACCEL_RANGE_2G,
- SENSOR_ACCEL_RANGE_4G,
- SENSOR_ACCEL_RANGE_8G,
- SENSOR_ACCEL_RANGE_16G,
+ rt_mutex_t lock; /* The module lock */
+
+ rt_sensor_t sen[RT_SENSOR_MODULE_MAX]; /* The module contains a list of sensors */
+ rt_uint8_t sen_num; /* Number of sensors contained in the module */
};
-#define SENSOR_ACCEL_SENSITIVITY_2G ((float)2/32768)
-#define SENSOR_ACCEL_SENSITIVITY_4G ((float)4/32768)
-#define SENSOR_ACCEL_SENSITIVITY_8G ((float)8/32768)
-#define SENSOR_ACCEL_SENSITIVITY_16G ((float)16/32768)
-enum SensorGyroRange
+/* 3-axis Data Type */
+struct sensor_3_axis
{
- SENSOR_GYRO_RANGE_250DPS,
- SENSOR_GYRO_RANGE_500DPS,
- SENSOR_GYRO_RANGE_1000DPS,
- SENSOR_GYRO_RANGE_2000DPS,
+ rt_int32_t x;
+ rt_int32_t y;
+ rt_int32_t z;
};
-#define SENSOR_GYRO_SENSITIVITY_250DPS (0.00875F)
-#define SENSOR_GYRO_SENSITIVITY_500DPS (0.0175F)
-#define SENSOR_GYRO_SENSITIVITY_1000DPS (0.035F)
-#define SENSOR_GYRO_SENSITIVITY_2000DPS (0.070F)
-enum SensorDataRate
+struct coordinates
{
- SENSOR_DATARATE_3200HZ,
- SENSOR_DATARATE_1600HZ,
- SENSOR_DATARATE_800HZ,
- SENSOR_DATARATE_400HZ,
- SENSOR_DATARATE_200HZ,
- SENSOR_DATARATE_100HZ,
- SENSOR_DATARATE_50HZ,
- SENSOR_DATARATE_25HZ,
- SENSOR_DATARATE_12_5HZ,
- SENSOR_DATARATE_6_25HZ,
- SENSOR_DATARATE_3_13HZ,
- SENSOR_DATARATE_1_56HZ,
- SENSOR_DATARATE_0_78HZ,
- SENSOR_DATARATE_0_39HZ,
- SENSOR_DATARATE_0_20HZ,
- SENSOR_DATARATE_0_10HZ,
+ double longitude;
+ double latitude;
};
-/**
- * Sensor Configuration
- */
-typedef struct SensorConfig
+struct rt_sensor_data
{
- int mode;
-
- enum SensorDataRate data_rate;
-
- union range
+ rt_uint32_t timestamp; /* The timestamp when the data was received */
+ rt_uint8_t type; /* The sensor type of the data */
+ union
{
- int range;
- enum SensorAccelRange accel_range;
- enum SensorGyroRange gyro_range;
- } range;
-}SensorConfig;
-
-typedef void (*SensorEventHandler_t)(void *user_data);
-
-#ifdef __cplusplus
-class SensorBase;
-class SensorManager;
-
-/**
- * Sensor Base Class
- */
-class SensorBase
-{
-private:
- int type;
-
-public:
- SensorBase(int type);
- ~SensorBase();
-
- virtual int configure(SensorConfig *config) = 0;
- virtual int activate(int enable) = 0;
-
- virtual int poll(sensors_event_t *events) = 0;
- virtual void getSensor(struct sensor_t *sensor) = 0;
-
- int getType(void);
-
- int setConfig(SensorConfig *config);
- int getConfig(SensorConfig *config);
-
- int subscribe(SensorEventHandler_t handler, void *user_data);
- int publish(void);
-
-protected:
- SensorBase *next;
- SensorBase *prev;
-
- /* sensor configuration */
- SensorConfig config;
-
- SensorEventHandler_t evtHandler;
- void *userData;
-
- friend class SensorManager;
+ struct sensor_3_axis acce; /* Accelerometer. unit: mG */
+ struct sensor_3_axis gyro; /* Gyroscope. unit: mdps */
+ struct sensor_3_axis mag; /* Magnetometer. unit: mGauss */
+ struct coordinates coord; /* Coordinates unit: degrees */
+ rt_int32_t temp; /* Temperature. unit: dCelsius */
+ rt_int32_t humi; /* Relative humidity. unit: permillage */
+ rt_int32_t baro; /* Pressure. unit: pascal (Pa) */
+ rt_int32_t light; /* Light. unit: lux */
+ rt_int32_t proximity; /* Distance. unit: centimeters */
+ rt_int32_t hr; /* Heart rate. unit: bpm */
+ rt_int32_t tvoc; /* TVOC. unit: permillage */
+ rt_int32_t noise; /* Noise Loudness. unit: HZ */
+ rt_uint32_t step; /* Step sensor. unit: 1 */
+ rt_int32_t force; /* Force sensor. unit: mN */
+ rt_uint32_t dust; /* Dust sensor. unit: ug/m3 */
+ rt_uint32_t eco2; /* eCO2 sensor. unit: ppm */
+ } data;
};
-/**
- * Sensor Manager
- */
-class SensorManager
+struct rt_sensor_ops
{
-public:
- SensorManager();
- ~SensorManager();
-
- static int registerSensor(SensorBase *sensor);
- static int unregisterSensor(SensorBase *sensor);
-
- static SensorBase *getDefaultSensor(int type);
- static int subscribe(int type, SensorEventHandler_t handler, void *user_data);
-
- static int sensorEventReady(SensorBase *sensor);
- static int pollSensor(SensorBase *sensor, sensors_event_t *events, int number, int duration);
+ rt_size_t (*fetch_data)(struct rt_sensor_device *sensor, void *buf, rt_size_t len);
+ rt_err_t (*control)(struct rt_sensor_device *sensor, int cmd, void *arg);
};
-#endif
-
-/* C programming language APIs */
-/* rt_sensor_t is a C typedef for SensorBase */
-typedef void* rt_sensor_t;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-rt_sensor_t rt_sensor_get_default(int type);
-
-int rt_sensor_subscribe(rt_sensor_t sensor, SensorEventHandler_t handler, void *user_data);
-int rt_sensor_activate (rt_sensor_t sensor, int enable);
-int rt_sensor_configure(rt_sensor_t sensor, SensorConfig *config);
-int rt_sensor_poll(rt_sensor_t sensor, sensors_event_t *event);
+int rt_hw_sensor_register(rt_sensor_t sensor,
+ const char *name,
+ rt_uint32_t flag,
+ void *data);
#ifdef __cplusplus
}
#endif
-#endif
+#endif /* __SENSOR_H__ */
diff --git a/components/drivers/sensors/sensor_cmd.c b/components/drivers/sensors/sensor_cmd.c
new file mode 100755
index 0000000000..284db75cf6
--- /dev/null
+++ b/components/drivers/sensors/sensor_cmd.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-01-31 flybreak first version
+ * 2019-07-16 WillianChan Increase the output of sensor information
+ * 2020-02-22 luhuadong Add vendor info and sensor types for cmd
+ */
+
+#include "sensor.h"
+
+#define DBG_TAG "sensor.cmd"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+static rt_sem_t sensor_rx_sem = RT_NULL;
+
+static void sensor_show_data(rt_size_t num, rt_sensor_t sensor, struct rt_sensor_data *sensor_data)
+{
+ switch (sensor->info.type)
+ {
+ case RT_SENSOR_CLASS_ACCE:
+ LOG_I("num:%3d, x:%5d, y:%5d, z:%5d mg, timestamp:%5d", num, sensor_data->data.acce.x, sensor_data->data.acce.y, sensor_data->data.acce.z, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_GYRO:
+ LOG_I("num:%3d, x:%8d, y:%8d, z:%8d dps, timestamp:%5d", num, sensor_data->data.gyro.x / 1000, sensor_data->data.gyro.y / 1000, sensor_data->data.gyro.z / 1000, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_MAG:
+ LOG_I("num:%3d, x:%5d, y:%5d, z:%5d mGauss, timestamp:%5d", num, sensor_data->data.mag.x, sensor_data->data.mag.y, sensor_data->data.mag.z, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_GNSS:
+ LOG_I("num:%3d, lon:%5d, lat:%5d, timestamp:%5d", num, sensor_data->data.coord.longitude, sensor_data->data.coord.latitude, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_TEMP:
+ LOG_I("num:%3d, temp:%3d.%d C, timestamp:%5d", num, sensor_data->data.temp / 10, (rt_uint32_t)sensor_data->data.temp % 10, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_HUMI:
+ LOG_I("num:%3d, humi:%3d.%d%%, timestamp:%5d", num, sensor_data->data.humi / 10, sensor_data->data.humi % 10, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_BARO:
+ LOG_I("num:%3d, press:%5d pa, timestamp:%5d", num, sensor_data->data.baro, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_LIGHT:
+ LOG_I("num:%3d, light:%5d lux, timestamp:%5d", num, sensor_data->data.light, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_PROXIMITY:
+ LOG_I("num:%3d, distance:%5d, timestamp:%5d", num, sensor_data->data.proximity, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_HR:
+ LOG_I("num:%3d, heart rate:%5d bpm, timestamp:%5d", num, sensor_data->data.hr, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_TVOC:
+ LOG_I("num:%3d, tvoc:%5d ppb, timestamp:%5d", num, sensor_data->data.tvoc, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_NOISE:
+ LOG_I("num:%3d, noise:%5d, timestamp:%5d", num, sensor_data->data.noise, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_STEP:
+ LOG_I("num:%3d, step:%5d, timestamp:%5d", num, sensor_data->data.step, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_FORCE:
+ LOG_I("num:%3d, force:%5d, timestamp:%5d", num, sensor_data->data.force, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_DUST:
+ LOG_I("num:%3d, dust:%5d ug/m3, timestamp:%5d", num, sensor_data->data.dust, sensor_data->timestamp);
+ break;
+ case RT_SENSOR_CLASS_ECO2:
+ LOG_I("num:%3d, eco2:%5d ppm, timestamp:%5d", num, sensor_data->data.eco2, sensor_data->timestamp);
+ break;
+ default:
+ break;
+ }
+}
+
+static rt_err_t rx_callback(rt_device_t dev, rt_size_t size)
+{
+ rt_sem_release(sensor_rx_sem);
+ return 0;
+}
+
+static void sensor_fifo_rx_entry(void *parameter)
+{
+ rt_device_t dev = (rt_device_t)parameter;
+ rt_sensor_t sensor = (rt_sensor_t)parameter;
+ struct rt_sensor_data *data = RT_NULL;
+ struct rt_sensor_info info;
+ rt_size_t res, i;
+
+ rt_device_control(dev, RT_SENSOR_CTRL_GET_INFO, &info);
+
+ data = (struct rt_sensor_data *)rt_malloc(sizeof(struct rt_sensor_data) * info.fifo_max);
+ if (data == RT_NULL)
+ {
+ LOG_E("Memory allocation failed!");
+ }
+
+ while (1)
+ {
+ rt_sem_take(sensor_rx_sem, RT_WAITING_FOREVER);
+
+ res = rt_device_read(dev, 0, data, info.fifo_max);
+ for (i = 0; i < res; i++)
+ {
+ sensor_show_data(i, sensor, &data[i]);
+ }
+ }
+}
+
+static void sensor_fifo(int argc, char **argv)
+{
+ static rt_thread_t tid1 = RT_NULL;
+ rt_device_t dev = RT_NULL;
+ rt_sensor_t sensor;
+
+ dev = rt_device_find(argv[1]);
+ if (dev == RT_NULL)
+ {
+ LOG_E("Can't find device:%s", argv[1]);
+ return;
+ }
+ sensor = (rt_sensor_t)dev;
+
+ if (rt_device_open(dev, RT_DEVICE_FLAG_FIFO_RX) != RT_EOK)
+ {
+ LOG_E("open device failed!");
+ return;
+ }
+
+ if (sensor_rx_sem == RT_NULL)
+ {
+ sensor_rx_sem = rt_sem_create("sen_rx_sem", 0, RT_IPC_FLAG_FIFO);
+ }
+ else
+ {
+ LOG_E("The thread is running, please reboot and try again");
+ return;
+ }
+
+ tid1 = rt_thread_create("sen_rx_thread",
+ sensor_fifo_rx_entry, sensor,
+ 1024,
+ 15, 5);
+
+ if (tid1 != RT_NULL)
+ rt_thread_startup(tid1);
+
+ rt_device_set_rx_indicate(dev, rx_callback);
+
+ rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)20);
+}
+#ifdef FINSH_USING_MSH
+MSH_CMD_EXPORT(sensor_fifo, Sensor fifo mode test function);
+#endif
+
+static void sensor_irq_rx_entry(void *parameter)
+{
+ rt_device_t dev = (rt_device_t)parameter;
+ rt_sensor_t sensor = (rt_sensor_t)parameter;
+ struct rt_sensor_data data;
+ rt_size_t res, i = 0;
+
+ while (1)
+ {
+ rt_sem_take(sensor_rx_sem, RT_WAITING_FOREVER);
+
+ res = rt_device_read(dev, 0, &data, 1);
+ if (res == 1)
+ {
+ sensor_show_data(i++, sensor, &data);
+ }
+ }
+}
+
+static void sensor_int(int argc, char **argv)
+{
+ static rt_thread_t tid1 = RT_NULL;
+ rt_device_t dev = RT_NULL;
+ rt_sensor_t sensor;
+
+ dev = rt_device_find(argv[1]);
+ if (dev == RT_NULL)
+ {
+ LOG_E("Can't find device:%s", argv[1]);
+ return;
+ }
+ sensor = (rt_sensor_t)dev;
+
+ if (sensor_rx_sem == RT_NULL)
+ {
+ sensor_rx_sem = rt_sem_create("sen_rx_sem", 0, RT_IPC_FLAG_FIFO);
+ }
+ else
+ {
+ LOG_E("The thread is running, please reboot and try again");
+ return;
+ }
+
+ tid1 = rt_thread_create("sen_rx_thread",
+ sensor_irq_rx_entry, sensor,
+ 1024,
+ 15, 5);
+
+ if (tid1 != RT_NULL)
+ rt_thread_startup(tid1);
+
+ rt_device_set_rx_indicate(dev, rx_callback);
+
+ if (rt_device_open(dev, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
+ {
+ LOG_E("open device failed!");
+ return;
+ }
+ rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)20);
+}
+#ifdef FINSH_USING_MSH
+MSH_CMD_EXPORT(sensor_int, Sensor interrupt mode test function);
+#endif
+
+static void sensor_polling(int argc, char **argv)
+{
+ uint16_t num = 10;
+ rt_device_t dev = RT_NULL;
+ rt_sensor_t sensor;
+ struct rt_sensor_data data;
+ rt_size_t res, i;
+ rt_int32_t delay;
+
+ dev = rt_device_find(argv[1]);
+ if (dev == RT_NULL)
+ {
+ LOG_E("Can't find device:%s", argv[1]);
+ return;
+ }
+ if (argc > 2)
+ num = atoi(argv[2]);
+
+ sensor = (rt_sensor_t)dev;
+ delay = sensor->info.period_min > 100 ? sensor->info.period_min : 100;
+
+ if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)
+ {
+ LOG_E("open device failed!");
+ return;
+ }
+ rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)100);
+
+ for (i = 0; i < num; i++)
+ {
+ res = rt_device_read(dev, 0, &data, 1);
+ if (res != 1)
+ {
+ LOG_E("read data failed!size is %d", res);
+ }
+ else
+ {
+ sensor_show_data(i, sensor, &data);
+ }
+ rt_thread_mdelay(delay);
+ }
+ rt_device_close(dev);
+}
+#ifdef FINSH_USING_MSH
+MSH_CMD_EXPORT(sensor_polling, Sensor polling mode test function);
+#endif
+
+static void sensor(int argc, char **argv)
+{
+ static rt_device_t dev = RT_NULL;
+ struct rt_sensor_data data;
+ rt_sensor_t sensor;
+ rt_size_t res, i;
+ rt_int32_t delay;
+
+ /* If the number of arguments less than 2 */
+ if (argc < 2)
+ {
+ rt_kprintf("\n");
+ rt_kprintf("sensor [OPTION] [PARAM]\n");
+ rt_kprintf(" probe <dev_name> Probe sensor by given name\n");
+ rt_kprintf(" info Get sensor info\n");
+ rt_kprintf(" sr <var> Set range to var\n");
+ rt_kprintf(" sm <var> Set work mode to var\n");
+ rt_kprintf(" sp <var> Set power mode to var\n");
+ rt_kprintf(" sodr <var> Set output date rate to var\n");
+ rt_kprintf(" read [num] Read [num] times sensor\n");
+ rt_kprintf(" num default 5\n");
+ return ;
+ }
+ else if (!strcmp(argv[1], "info"))
+ {
+ struct rt_sensor_info info;
+ if (dev == RT_NULL)
+ {
+ LOG_W("Please probe sensor device first!");
+ return ;
+ }
+ rt_device_control(dev, RT_SENSOR_CTRL_GET_INFO, &info);
+ switch (info.vendor)
+ {
+ case RT_SENSOR_VENDOR_UNKNOWN:
+ rt_kprintf("vendor :unknown vendor\n");
+ break;
+ case RT_SENSOR_VENDOR_STM:
+ rt_kprintf("vendor :STMicroelectronics\n");
+ break;
+ case RT_SENSOR_VENDOR_BOSCH:
+ rt_kprintf("vendor :Bosch\n");
+ break;
+ case RT_SENSOR_VENDOR_INVENSENSE:
+ rt_kprintf("vendor :Invensense\n");
+ break;
+ case RT_SENSOR_VENDOR_SEMTECH:
+ rt_kprintf("vendor :Semtech\n");
+ break;
+ case RT_SENSOR_VENDOR_GOERTEK:
+ rt_kprintf("vendor :Goertek\n");
+ break;
+ case RT_SENSOR_VENDOR_MIRAMEMS:
+ rt_kprintf("vendor :MiraMEMS\n");
+ break;
+ case RT_SENSOR_VENDOR_DALLAS:
+ rt_kprintf("vendor :Dallas\n");
+ break;
+ case RT_SENSOR_VENDOR_ASAIR:
+ rt_kprintf("vendor :Asair\n");
+ break;
+ case RT_SENSOR_VENDOR_SHARP:
+ rt_kprintf("vendor :Sharp\n");
+ break;
+ case RT_SENSOR_VENDOR_SENSIRION:
+ rt_kprintf("vendor :Sensirion\n");
+ break;
+ case RT_SENSOR_VENDOR_TI:
+ rt_kprintf("vendor :Texas Instruments\n");
+ break;
+ case RT_SENSOR_VENDOR_PLANTOWER:
+ rt_kprintf("vendor :Plantower\n");
+ break;
+ case RT_SENSOR_VENDOR_AMS:
+ rt_kprintf("vendor :AMS\n");
+ break;
+ case RT_SENSOR_VENDOR_MAXIM:
+ rt_kprintf("vendor :Maxim Integrated\n");
+ break;
+ }
+ rt_kprintf("model :%s\n", info.model);
+ switch (info.unit)
+ {
+ case RT_SENSOR_UNIT_NONE:
+ rt_kprintf("unit :none\n");
+ break;
+ case RT_SENSOR_UNIT_MG:
+ rt_kprintf("unit :mG\n");
+ break;
+ case RT_SENSOR_UNIT_MDPS:
+ rt_kprintf("unit :mdps\n");
+ break;
+ case RT_SENSOR_UNIT_MGAUSS:
+ rt_kprintf("unit :mGauss\n");
+ break;
+ case RT_SENSOR_UNIT_LUX:
+ rt_kprintf("unit :lux\n");
+ break;
+ case RT_SENSOR_UNIT_CM:
+ rt_kprintf("unit :cm\n");
+ break;
+ case RT_SENSOR_UNIT_PA:
+ rt_kprintf("unit :pa\n");
+ break;
+ case RT_SENSOR_UNIT_PERMILLAGE:
+ rt_kprintf("unit :permillage\n");
+ break;
+ case RT_SENSOR_UNIT_DCELSIUS:
+ rt_kprintf("unit :Celsius\n");
+ break;
+ case RT_SENSOR_UNIT_HZ:
+ rt_kprintf("unit :HZ\n");
+ break;
+ case RT_SENSOR_UNIT_ONE:
+ rt_kprintf("unit :1\n");
+ break;
+ case RT_SENSOR_UNIT_BPM:
+ rt_kprintf("unit :bpm\n");
+ break;
+ case RT_SENSOR_UNIT_MM:
+ rt_kprintf("unit :mm\n");
+ break;
+ case RT_SENSOR_UNIT_MN:
+ rt_kprintf("unit :mN\n");
+ break;
+ case RT_SENSOR_UNIT_PPM:
+ rt_kprintf("unit :ppm\n");
+ break;
+ case RT_SENSOR_UNIT_PPB:
+ rt_kprintf("unit :ppb\n");
+ break;
+ }
+ rt_kprintf("range_max :%d\n", info.range_max);
+ rt_kprintf("range_min :%d\n", info.range_min);
+ rt_kprintf("period_min:%dms\n", info.period_min);
+ rt_kprintf("fifo_max :%d\n", info.fifo_max);
+ }
+ else if (!strcmp(argv[1], "read"))
+ {
+ uint16_t num = 5;
+
+ if (dev == RT_NULL)
+ {
+ LOG_W("Please probe sensor device first!");
+ return ;
+ }
+ if (argc == 3)
+ {
+ num = atoi(argv[2]);
+ }
+
+ sensor = (rt_sensor_t)dev;
+ delay = sensor->info.period_min > 100 ? sensor->info.period_min : 100;
+
+ for (i = 0; i < num; i++)
+ {
+ res = rt_device_read(dev, 0, &data, 1);
+ if (res != 1)
+ {
+ LOG_E("read data failed!size is %d", res);
+ }
+ else
+ {
+ sensor_show_data(i, sensor, &data);
+ }
+ rt_thread_mdelay(delay);
+ }
+ }
+ else if (argc == 3)
+ {
+ if (!strcmp(argv[1], "probe"))
+ {
+ rt_uint8_t reg = 0xFF;
+ if (dev)
+ {
+ rt_device_close(dev);
+ }
+
+ dev = rt_device_find(argv[2]);
+ if (dev == RT_NULL)
+ {
+ LOG_E("Can't find device:%s", argv[1]);
+ return;
+ }
+ if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)
+ {
+ LOG_E("open device failed!");
+ return;
+ }
+ rt_device_control(dev, RT_SENSOR_CTRL_GET_ID, &reg);
+ LOG_I("device id: 0x%x!", reg);
+
+ }
+ else if (dev == RT_NULL)
+ {
+ LOG_W("Please probe sensor first!");
+ return ;
+ }
+ else if (!strcmp(argv[1], "sr"))
+ {
+ rt_device_control(dev, RT_SENSOR_CTRL_SET_RANGE, (void *)atoi(argv[2]));
+ }
+ else if (!strcmp(argv[1], "sm"))
+ {
+ rt_device_control(dev, RT_SENSOR_CTRL_SET_MODE, (void *)atoi(argv[2]));
+ }
+ else if (!strcmp(argv[1], "sp"))
+ {
+ rt_device_control(dev, RT_SENSOR_CTRL_SET_POWER, (void *)atoi(argv[2]));
+ }
+ else if (!strcmp(argv[1], "sodr"))
+ {
+ rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)atoi(argv[2]));
+ }
+ else
+ {
+ LOG_W("Unknown command, please enter 'sensor' get help information!");
+ }
+ }
+ else
+ {
+ LOG_W("Unknown command, please enter 'sensor' get help information!");
+ }
+}
+#ifdef FINSH_USING_MSH
+MSH_CMD_EXPORT(sensor, sensor test function);
+#endif
diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c
index c5932df7d9..2511f18102 100644
--- a/components/drivers/serial/serial.c
+++ b/components/drivers/serial/serial.c
@@ -22,16 +22,16 @@
* 2017-11-15 JasonJia fix poll rx issue when data is full.
* add TCFLSH and FIONREAD support.
* 2018-12-08 Ernest Chen add DMA choice
+ * 2020-09-14 WillianChan add a line feed to the carriage return character
+ * when using interrupt tx
*/
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
-// #define DEBUG_ENABLE
-#define DEBUG_LEVEL DBG_LOG
-#define DBG_SECTION_NAME "UART"
-#define DEBUG_COLOR
+#define DBG_TAG "UART"
+#define DBG_LVL DBG_INFO
#include <rtdbg.h>
#ifdef RT_USING_POSIX
@@ -317,6 +317,19 @@ rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *
while (length)
{
+ /*
+ * to be polite with serial console add a line feed
+ * to the carriage return character
+ */
+ if (*data == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
+ {
+ if (serial->ops->putc(serial, '\r') == -1)
+ {
+ rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER);
+ continue;
+ }
+ }
+
if (serial->ops->putc(serial, *(char*)data) == -1)
{
rt_completion_wait(&(tx->completion), RT_WAITING_FOREVER);
@@ -329,6 +342,20 @@ rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *
return size - length;
}
+static void _serial_check_buffer_size(void)
+{
+ static rt_bool_t already_output = RT_FALSE;
+
+ if (already_output == RT_FALSE)
+ {
+#if !defined(RT_USING_ULOG) || defined(ULOG_USING_ISR_LOG)
+ LOG_W("Warning: There is no enough buffer for saving data,"
+ " please increase the RT_SERIAL_RB_BUFSZ option.");
+#endif
+ already_output = RT_TRUE;
+ }
+}
+
#if defined(RT_USING_POSIX) || defined(RT_SERIAL_USING_DMA)
static rt_size_t _serial_fifo_calc_recved_len(struct rt_serial_device *serial)
{
@@ -430,12 +457,11 @@ static void rt_dma_recv_update_put_index(struct rt_serial_device *serial, rt_siz
}
}
- if(rx_fifo->is_full == RT_TRUE)
+ if(rx_fifo->is_full == RT_TRUE)
{
- rx_fifo->get_index = rx_fifo->put_index;
- }
-
- if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
+ _serial_check_buffer_size();
+ rx_fifo->get_index = rx_fifo->put_index;
+ }
}
/*
@@ -478,7 +504,7 @@ rt_inline int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data,
RT_ASSERT(rx_fifo != RT_NULL);
- if (length < fifo_recved_len)
+ if (length < (int)fifo_recved_len)
recv_len = length;
else
recv_len = fifo_recved_len;
@@ -566,13 +592,11 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
LOG_D("open serial device: 0x%08x with open flag: 0x%04x",
dev, oflag);
-#ifdef RT_SERIAL_USING_DMA
/* check device flag with the open flag */
if ((oflag & RT_DEVICE_FLAG_DMA_RX) && !(dev->flag & RT_DEVICE_FLAG_DMA_RX))
return -RT_EIO;
if ((oflag & RT_DEVICE_FLAG_DMA_TX) && !(dev->flag & RT_DEVICE_FLAG_DMA_TX))
return -RT_EIO;
-#endif /* RT_SERIAL_USING_DMA */
if ((oflag & RT_DEVICE_FLAG_INT_RX) && !(dev->flag & RT_DEVICE_FLAG_INT_RX))
return -RT_EIO;
if ((oflag & RT_DEVICE_FLAG_INT_TX) && !(dev->flag & RT_DEVICE_FLAG_INT_TX))
@@ -679,6 +703,8 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
serial->serial_tx = tx_dma;
dev->open_flag |= RT_DEVICE_FLAG_DMA_TX;
+ /* configure low level device */
+ serial->ops->control(serial, RT_DEVICE_CTRL_CONFIG, (void *)RT_DEVICE_FLAG_DMA_TX);
}
#endif /* RT_SERIAL_USING_DMA */
else
@@ -722,6 +748,7 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
rt_free(rx_fifo);
serial->serial_rx = RT_NULL;
dev->open_flag &= ~RT_DEVICE_FLAG_INT_RX;
+
/* configure low level device */
serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_RX);
}
@@ -743,10 +770,11 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
rt_free(rx_fifo);
}
- /* configure low level device */
- serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_RX);
serial->serial_rx = RT_NULL;
dev->open_flag &= ~RT_DEVICE_FLAG_DMA_RX;
+
+ /* configure low level device */
+ serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_RX);
}
#endif /* RT_SERIAL_USING_DMA */
@@ -760,6 +788,7 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
rt_free(tx_fifo);
serial->serial_tx = RT_NULL;
dev->open_flag &= ~RT_DEVICE_FLAG_INT_TX;
+
/* configure low level device */
serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void*)RT_DEVICE_FLAG_INT_TX);
}
@@ -771,10 +800,19 @@ static rt_err_t rt_serial_close(struct rt_device *dev)
tx_dma = (struct rt_serial_tx_dma*)serial->serial_tx;
RT_ASSERT(tx_dma != RT_NULL);
+ rt_data_queue_deinit(&(tx_dma->data_queue));
+
rt_free(tx_dma);
serial->serial_tx = RT_NULL;
dev->open_flag &= ~RT_DEVICE_FLAG_DMA_TX;
+
+ /* configure low level device */
+ serial->ops->control(serial, RT_DEVICE_CTRL_CLR_INT, (void *) RT_DEVICE_FLAG_DMA_TX);
}
+
+ serial->ops->control(serial, RT_DEVICE_CTRL_CLOSE, RT_NULL);
+ dev->flag &= ~RT_DEVICE_FLAG_ACTIVATED;
+
#endif /* RT_SERIAL_USING_DMA */
return RT_EOK;
}
@@ -793,16 +831,16 @@ static rt_size_t rt_serial_read(struct rt_device *dev,
if (dev->open_flag & RT_DEVICE_FLAG_INT_RX)
{
- return _serial_int_rx(serial, buffer, size);
+ return _serial_int_rx(serial, (rt_uint8_t *)buffer, size);
}
#ifdef RT_SERIAL_USING_DMA
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_RX)
{
- return _serial_dma_rx(serial, buffer, size);
+ return _serial_dma_rx(serial, (rt_uint8_t *)buffer, size);
}
#endif /* RT_SERIAL_USING_DMA */
- return _serial_poll_rx(serial, buffer, size);
+ return _serial_poll_rx(serial, (rt_uint8_t *)buffer, size);
}
static rt_size_t rt_serial_write(struct rt_device *dev,
@@ -819,17 +857,17 @@ static rt_size_t rt_serial_write(struct rt_device *dev,
if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
{
- return _serial_int_tx(serial, buffer, size);
+ return _serial_int_tx(serial, (const rt_uint8_t *)buffer, size);
}
#ifdef RT_SERIAL_USING_DMA
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
{
- return _serial_dma_tx(serial, buffer, size);
+ return _serial_dma_tx(serial, (const rt_uint8_t *)buffer, size);
}
#endif /* RT_SERIAL_USING_DMA */
else
{
- return _serial_poll_tx(serial, buffer, size);
+ return _serial_poll_tx(serial, (const rt_uint8_t *)buffer, size);
}
}
@@ -884,6 +922,7 @@ static int _get_baudrate(speed_t speed)
static void _tc_flush(struct rt_serial_device *serial, int queue)
{
+ rt_base_t level;
int ch = -1;
struct rt_serial_rx_fifo *rx_fifo = RT_NULL;
struct rt_device *device = RT_NULL;
@@ -903,10 +942,12 @@ static void _tc_flush(struct rt_serial_device *serial, int queue)
if((device->open_flag & RT_DEVICE_FLAG_INT_RX) || (device->open_flag & RT_DEVICE_FLAG_DMA_RX))
{
RT_ASSERT(RT_NULL != rx_fifo);
+ level = rt_hw_interrupt_disable();
rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
rx_fifo->put_index = 0;
rx_fifo->get_index = 0;
rx_fifo->is_full = RT_FALSE;
+ rt_hw_interrupt_enable(level);
}
else
{
@@ -1171,6 +1212,8 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
rx_fifo->get_index += 1;
rx_fifo->is_full = RT_TRUE;
if (rx_fifo->get_index >= serial->config.bufsz) rx_fifo->get_index = 0;
+
+ _serial_check_buffer_size();
}
/* enable interrupt */
@@ -1272,4 +1315,3 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
#endif /* RT_SERIAL_USING_DMA */
}
}
-
diff --git a/components/drivers/spi/SConscript b/components/drivers/spi/SConscript
index b88671ebc9..e19f30861f 100644
--- a/components/drivers/spi/SConscript
+++ b/components/drivers/spi/SConscript
@@ -14,24 +14,9 @@ src_device = []
if GetDepend('RT_USING_SPI_WIFI'):
src_device += ['spi_wifi_rw009.c']
-if GetDepend('RT_USING_W25QXX'):
- src_device += ['spi_flash_w25qxx.c']
-
-if GetDepend('RT_USING_W25QXX_MTD'):
- src_device += ['spi_flash_w25qxx_mtd.c']
-
if GetDepend('RT_USING_ENC28J60'):
src_device += ['enc28j60.c']
-if GetDepend('RT_USING_AT45DBXX'):
- src_device += ['spi_flash_at45dbxx.c']
-
-if GetDepend('RT_USING_SST25VFXX'):
- src_device += ['spi_flash_sst25vfxx.c']
-
-if GetDepend('RT_USING_GD'):
- src_device += ['spi_flash_gd.c']
-
if GetDepend('RT_USING_SPI_MSD'):
src_device += ['spi_msd.c']
diff --git a/components/drivers/spi/device_driver_list.txt b/components/drivers/spi/device_driver_list.txt
index 2c9d6a16b8..939baa7531 100644
--- a/components/drivers/spi/device_driver_list.txt
+++ b/components/drivers/spi/device_driver_list.txt
@@ -5,11 +5,5 @@ http://www.rt-thread.com/
enc28j60.c/enc28j60.h
http://www.microchip.com/
-spi_flash_at45dbxx.c/spi_flash_at45dbxx.h
-http://www.atmel.com/
-
-spi_flash_sst25vfxx.c/spi_flash_sst25vfxx.h
-http://www.microchip.com/
-
-spi_flash_w25qxx.c/spi_flash_w25qxx.h
-http://www.winbond.com/
+spi_flash_sfud: Serial Flash Universal Driver
+https://github.com/armink/SFUD \ No newline at end of file
diff --git a/components/drivers/spi/sfud/inc/sfud_cfg.h b/components/drivers/spi/sfud/inc/sfud_cfg.h
index 051de6d577..01255775c8 100644
--- a/components/drivers/spi/sfud/inc/sfud_cfg.h
+++ b/components/drivers/spi/sfud/inc/sfud_cfg.h
@@ -38,6 +38,18 @@
#define SFUD_DEBUG_MODE
#endif
+#ifdef RT_DEBUG_SFUD
+#define DBG_LVL DBG_LOG
+#define SFUD_DEBUG(fmt, ...) LOG_D("(%s:%ld) "fmt"", __FILE__, __LINE__, ##__VA_ARGS__)
+#else
+#define DBG_LVL DBG_INFO
+#endif /* RT_DEBUG_SFUD */
+
+#define DBG_TAG "SFUD"
+#include <rtdbg.h>
+extern void rt_kprintf(const char *fmt, ...);
+#define SFUD_INFO(...) LOG_I(__VA_ARGS__)
+
/**
* Using probe flash JEDEC SFDP parameter.
*/
@@ -59,6 +71,6 @@
#define SFUD_USING_FLASH_INFO_TABLE
#endif
-#define SFUD_FLASH_DEVICE_TABLE {0}
+#define SFUD_FLASH_DEVICE_TABLE {{0}}
#endif /* _SFUD_CFG_H_ */
diff --git a/components/drivers/spi/sfud/inc/sfud_flash_def.h b/components/drivers/spi/sfud/inc/sfud_flash_def.h
index 8922375557..03b95cd008 100644
--- a/components/drivers/spi/sfud/inc/sfud_flash_def.h
+++ b/components/drivers/spi/sfud/inc/sfud_flash_def.h
@@ -87,7 +87,7 @@ typedef struct {
#define SFUD_MF_ID_FUDAN 0xA1
#define SFUD_MF_ID_HYUNDAI 0xAD
#define SFUD_MF_ID_SST 0xBF
-#define SFUD_MF_ID_MICRONIX 0xC2
+#define SFUD_MF_ID_MACRONIX 0xC2
#define SFUD_MF_ID_GIGADEVICE 0xC8
#define SFUD_MF_ID_ISSI 0xD5
#define SFUD_MF_ID_WINBOND 0xEF
@@ -110,7 +110,7 @@ typedef struct {
{"GigaDevice", SFUD_MF_ID_GIGADEVICE}, \
{"ISSI", SFUD_MF_ID_ISSI}, \
{"Winbond", SFUD_MF_ID_WINBOND}, \
- {"Micronix", SFUD_MF_ID_MICRONIX}, \
+ {"Macronix", SFUD_MF_ID_MACRONIX}, \
}
#ifdef SFUD_USING_FLASH_INFO_TABLE
@@ -124,6 +124,8 @@ typedef struct {
{"AT45DB161E", SFUD_MF_ID_ATMEL, 0x26, 0x00, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_DUAL_BUFFER, 512, 0x81}, \
{"W25Q40BV", SFUD_MF_ID_WINBOND, 0x40, 0x13, 512L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q16BV", SFUD_MF_ID_WINBOND, 0x40, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
+ {"W25Q64CV", SFUD_MF_ID_WINBOND, 0x40, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
+ {"W25Q64DW", SFUD_MF_ID_WINBOND, 0x60, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q128BV", SFUD_MF_ID_WINBOND, 0x40, 0x18, 16L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"W25Q256FV", SFUD_MF_ID_WINBOND, 0x40, 0x19, 32L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
{"SST25VF016B", SFUD_MF_ID_SST, 0x25, 0x41, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \
@@ -142,7 +144,7 @@ typedef struct {
#endif /* SFUD_USING_FLASH_INFO_TABLE */
#ifdef SFUD_USING_QSPI
-/* This table saves flash read-fast instructions in QSPI mode,
+/* This table saves flash read-fast instructions in QSPI mode,
* SFUD can use this table to select the most appropriate read instruction for flash.
* | mf_id | type_id | capacity_id | qspi_read_mode |
*/
@@ -155,7 +157,7 @@ typedef struct {
/* W25Q16BV */ \
{SFUD_MF_ID_WINBOND, 0x40, 0x15, NORMAL_SPI_READ|DUAL_OUTPUT}, \
/* W25Q32BV */ \
- {SFUD_MF_ID_WINBOND, 0x40, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT}, \
+ {SFUD_MF_ID_WINBOND, 0x40, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT|QUAD_OUTPUT|QUAD_IO}, \
/* W25Q64JV */ \
{SFUD_MF_ID_WINBOND, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \
/* W25Q128JV */ \
@@ -171,7 +173,9 @@ typedef struct {
/* A25LQ64 */ \
{SFUD_MF_ID_AMIC, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_IO}, \
/* MX25L3206E and KH25L3206E */ \
- {SFUD_MF_ID_MICRONIX, 0x20, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT}, \
+ {SFUD_MF_ID_MACRONIX, 0x20, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT}, \
+ /* MX25L51245G */ \
+ {SFUD_MF_ID_MACRONIX, 0x20, 0x1A, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \
/* GD25Q64B */ \
{SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT}, \
}
diff --git a/components/drivers/spi/sfud/src/sfud.c b/components/drivers/spi/sfud/src/sfud.c
index 6cfd1191ef..e5b03131ff 100644
--- a/components/drivers/spi/sfud/src/sfud.c
+++ b/components/drivers/spi/sfud/src/sfud.c
@@ -603,7 +603,8 @@ static sfud_err page256_or_1_byte_write(const sfud_flash *flash, uint32_t addr,
const uint8_t *data) {
sfud_err result = SFUD_SUCCESS;
const sfud_spi *spi = &flash->spi;
- uint8_t cmd_data[5 + SFUD_WRITE_MAX_PAGE_SIZE], cmd_size;
+ static uint8_t cmd_data[5 + SFUD_WRITE_MAX_PAGE_SIZE];
+ uint8_t cmd_size;
size_t data_size;
SFUD_ASSERT(flash);
@@ -690,7 +691,7 @@ __exit:
static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data) {
sfud_err result = SFUD_SUCCESS;
const sfud_spi *spi = &flash->spi;
- uint8_t cmd_data[6], cmd_size;
+ uint8_t cmd_data[8], cmd_size;
bool first_write = true;
SFUD_ASSERT(flash);
@@ -896,7 +897,7 @@ static sfud_err set_write_enabled(const sfud_flash *flash, bool enabled) {
if (enabled && (register_status & SFUD_STATUS_REGISTER_WEL) == 0) {
SFUD_INFO("Error: Can't enable write status.");
return SFUD_ERR_WRITE;
- } else if (!enabled && (register_status & SFUD_STATUS_REGISTER_WEL) == 1) {
+ } else if (!enabled && (register_status & SFUD_STATUS_REGISTER_WEL) != 0) {
SFUD_INFO("Error: Can't disable write status.");
return SFUD_ERR_WRITE;
}
diff --git a/components/drivers/spi/spi_flash_at45dbxx.c b/components/drivers/spi/spi_flash_at45dbxx.c
deleted file mode 100644
index 0a30f0a328..0000000000
--- a/components/drivers/spi/spi_flash_at45dbxx.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- */
-
-#include <stdint.h>
-#include "spi_flash_at45dbxx.h"
-
-#define FLASH_DEBUG
-#define DMA_BUFFER_SIZE 512
-
-#ifdef FLASH_DEBUG
-#define FLASH_TRACE rt_kprintf
-#else
-#define FLASH_TRACE(...)
-#endif /**< #ifdef FLASH_DEBUG */
-
-/* JEDEC Manufacturer’s ID */
-#define MF_ID (0x1F) /* atmel */
-#define DENSITY_CODE_011D (0x02) /* AT45DB011D Density Code : 00010 = 1-Mbit */
-#define DENSITY_CODE_021D (0x03) /* AT45DB021D Density Code : 00011 = 2-Mbit */
-#define DENSITY_CODE_041D (0x04) /* AT45DB041D Density Code : 00100 = 4-Mbit */
-#define DENSITY_CODE_081D (0x05) /* AT45DB081D Density Code : 00101 = 8-Mbit */
-#define DENSITY_CODE_161D (0x06) /* AT45DB161D Density Code : 00110 = 16-Mbit */
-#define DENSITY_CODE_321D (0x07) /* AT45DB321D Density Code : 00111 = 32-Mbit */
-#define DENSITY_CODE_642D (0x08) /* AT45DB642D Density Code : 01000 = 64-Mbit */
-
-struct JEDEC_ID
-{
- uint8_t manufacturer_id; /* Manufacturer ID */
- uint8_t density_code:5; /* Density Code */
- uint8_t family_code:3; /* Family Code */
- uint8_t version_code:5; /* Product Version Code */
- uint8_t mlc_code:3; /* MLC Code */
- uint8_t byte_count; /* Byte Count */
-};
-
-#define AT45DB_BUFFER_1_WRITE 0x84
-#define AT45DB_BUFFER_2_WRITE 0x87
-#define AT45DB_BUFFER_1_READ 0xD4
-#define AT45DB_BUFFER_2_READ 0xD6
-#define AT45DB_B1_TO_MM_PAGE_PROG_WITH_ERASE 0x83
-#define AT45DB_B2_TO_MM_PAGE_PROG_WITH_ERASE 0x86
-#define AT45DB_MM_PAGE_TO_B1_XFER 0x53
-#define AT45DB_MM_PAGE_TO_B2_XFER 0x55
-#define AT45DB_PAGE_ERASE 0x81
-#define AT45DB_SECTOR_ERASE 0x7C
-#define AT45DB_READ_STATE_REGISTER 0xD7
-#define AT45DB_MM_PAGE_READ 0xD2
-#define AT45DB_MM_PAGE_PROG_THRU_BUFFER1 0x82
-#define AT45DB_CMD_JEDEC_ID 0x9F
-
-static struct spi_flash_at45dbxx spi_flash_at45dbxx;
-
-/*****************************************************************************/
-/*Status Register Format: */
-/* ------------------------------------------------------------------------- */
-/* | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | */
-/* |--------|--------|--------|--------|--------|--------|--------|--------| */
-/* |RDY/BUSY| COMP | device density | X | X | */
-/* ------------------------------------------------------------------------- */
-/* 0:busy | | AT45DB041:0111 | protect|page size */
-/* 1:ready | | AT45DB161:1011 | */
-/* --------------------------------------------------------------------------*/
-/*****************************************************************************/
-static uint8_t AT45DB_StatusRegisterRead(void)
-{
- return rt_spi_sendrecv8(spi_flash_at45dbxx.rt_spi_device, AT45DB_READ_STATE_REGISTER);
-}
-
-static void wait_busy(void)
-{
- uint16_t i = 0;
- while (i++ < 10000)
- {
- if (AT45DB_StatusRegisterRead() & 0x80)
- {
- return;
- }
- }
- FLASH_TRACE("\r\nSPI_FLASH timeout!!!\r\n");
-}
-
-/* RT-Thread Device Driver Interface */
-static rt_err_t AT45DB_flash_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t AT45DB_flash_open(rt_device_t dev, rt_uint16_t oflag)
-{
-
- return RT_EOK;
-}
-
-static rt_err_t AT45DB_flash_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t AT45DB_flash_control(rt_device_t dev, int cmd, void *args)
-{
- RT_ASSERT(dev != RT_NULL);
-
- if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
- {
- struct rt_device_blk_geometry *geometry;
-
- geometry = (struct rt_device_blk_geometry *)args;
- if (geometry == RT_NULL) return -RT_ERROR;
-
- geometry->bytes_per_sector = 512;
- geometry->sector_count = 4096;
- geometry->block_size = 4096; /* block erase: 4k */
- }
-
- return RT_EOK;
-}
-
-static rt_size_t AT45DB_flash_read_page_256(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
- uint32_t index, nr;
- uint8_t * read_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[8];
- uint32_t i;
-
- for(i=0; i<sizeof(send_buffer); i++)
- {
- send_buffer[i] = 0;
- }
-
- send_buffer[0] = AT45DB_MM_PAGE_READ;
- send_buffer[1] = (uint8_t)(page >> 7);
- send_buffer[2] = (uint8_t)(page << 1);
-
- rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, send_buffer, 8, read_buffer, 256);
- read_buffer += 256;
- page++;
- }
-
- return size;
-}
-
-static rt_size_t AT45DB_flash_read_page_512(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
- uint32_t index, nr;
- uint8_t * read_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[8];
- uint32_t i;
-
- for(i=0; i<sizeof(send_buffer); i++)
- {
- send_buffer[i] = 0;
- }
-
- send_buffer[0] = AT45DB_MM_PAGE_READ;
- send_buffer[1] = (uint8_t)(page >> 6);
- send_buffer[2] = (uint8_t)(page << 2);
-
- rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, send_buffer, 8, read_buffer, 512);
- read_buffer += 512;
- page++;
- }
-
- return size;
-}
-
-static rt_size_t AT45DB_flash_read_page_1024(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
- uint32_t index, nr;
- uint8_t * read_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[8];
- uint32_t i;
-
- for(i=0; i<sizeof(send_buffer); i++)
- {
- send_buffer[i] = 0;
- }
-
- send_buffer[0] = AT45DB_MM_PAGE_READ;
- send_buffer[1] = (uint8_t)(page >> 5);
- send_buffer[2] = (uint8_t)(page << 3);
-
- rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, send_buffer, 8, read_buffer, 1024);
- read_buffer += 1024;
- page++;
- }
-
- return size;
-}
-
-static rt_size_t AT45DB_flash_write_page_256(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
- rt_uint32_t index, nr;
- const uint8_t * write_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[4];
-
- send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
- send_buffer[1] = (uint8_t) (page >> 7);
- send_buffer[2] = (uint8_t) (page << 1);
- send_buffer[3] = 0;
-
- rt_spi_send_then_send(spi_flash_at45dbxx.rt_spi_device, send_buffer, 4, write_buffer, 256);
-
- write_buffer += 256;
- page++;
-
- wait_busy();
- }
-
- return size;
-}
-
-static rt_size_t AT45DB_flash_write_page_512(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
- rt_uint32_t index, nr;
- const uint8_t * write_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[4];
-
- send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
- send_buffer[1] = (uint8_t) (page >> 6);
- send_buffer[2] = (uint8_t) (page << 2);
- send_buffer[3] = 0;
-
- rt_spi_send_then_send(spi_flash_at45dbxx.rt_spi_device, send_buffer, 4, write_buffer, 512);
-
- write_buffer += 512;
- page++;
-
- wait_busy();
- }
-
- return size;
-}
-
-static rt_size_t AT45DB_flash_write_page_1024(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
- rt_uint32_t index, nr;
- const uint8_t * write_buffer = buffer;
- uint32_t page = pos;
-
- nr = size;
-
- for (index = 0; index < nr; index++)
- {
- uint8_t send_buffer[4];
-
- send_buffer[0] = AT45DB_MM_PAGE_PROG_THRU_BUFFER1;
- send_buffer[1] = (uint8_t) (page >> 5);
- send_buffer[2] = (uint8_t) (page << 3);
- send_buffer[3] = 0;
-
- rt_spi_send_then_send(spi_flash_at45dbxx.rt_spi_device, send_buffer, 4, write_buffer, 1024);
-
- write_buffer += 1024;
- page++;
-
- wait_busy();
- }
-
- return size;
-}
-
-rt_err_t at45dbxx_init(const char * flash_device_name, const char * spi_device_name)
-{
- struct rt_spi_device * rt_spi_device;
- struct JEDEC_ID * JEDEC_ID;
-
- rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
- if(rt_spi_device == RT_NULL)
- {
- FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
- return -RT_ENOSYS;
- }
- spi_flash_at45dbxx.rt_spi_device = rt_spi_device;
-
- /* config spi */
- {
- struct rt_spi_configuration cfg;
- cfg.data_width = 8;
- cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 and 3 */
- cfg.max_hz = 66000000; /* Atmel RapidS Serial Interface: 66MHz Maximum Clock Frequency */
- rt_spi_configure(spi_flash_at45dbxx.rt_spi_device, &cfg);
- }
-
- /* read JEDEC ID */
- {
- uint8_t cmd;
- uint8_t id_recv[6];
- JEDEC_ID = (struct JEDEC_ID *)id_recv;
-
- cmd = AT45DB_CMD_JEDEC_ID;
- rt_spi_send_then_recv(spi_flash_at45dbxx.rt_spi_device, &cmd, 1, id_recv, 6);
-
- /**< 1FH = Atmel */
- /**< 001 = Atmel DataFlash */
- if(JEDEC_ID->manufacturer_id != 0x1F || JEDEC_ID->family_code != 0x01)
- {
- FLASH_TRACE("Manufacturer’s ID or Memory Type error!\r\n");
- FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
- return -RT_ENOSYS;
- }
-
- if(JEDEC_ID->density_code == DENSITY_CODE_011D)
- {
- /**< AT45DB011D Density Code : 00010 = 1-Mbit */
- FLASH_TRACE("AT45DB011D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 512; /* 1-Mbit / 8 / 256 = 512 */
- spi_flash_at45dbxx.geometry.block_size = 1024*2; /* Block Erase (2-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_021D)
- {
- /**< AT45DB021D Density Code : 00011 = 2-Mbit */
- FLASH_TRACE("AT45DB021D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 512*2; /* 2-Mbit / 8 / 256 = 1024 */
- spi_flash_at45dbxx.geometry.block_size = 1024*2; /* Block Erase (2-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_041D)
- {
- /**< AT45DB041D Density Code : 00100 = 4-Mbit */
- FLASH_TRACE("AT45DB041D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 512*4; /* 4-Mbit / 8 / 256 = 2048 */
- spi_flash_at45dbxx.geometry.block_size = 1024*2; /* Block Erase (2-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_081D)
- {
- /**< AT45DB081D Density Code : 00101 = 8-Mbit */
- FLASH_TRACE("AT45DB081D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 256; /* Page Erase (256 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 512*8; /* 8-Mbit / 8 / 256 = 4096 */
- spi_flash_at45dbxx.geometry.block_size = 1024*2; /* Block Erase (2-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_161D)
- {
- /**< AT45DB161D Density Code : 00110 = 16-Mbit */
- FLASH_TRACE("AT45DB161D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 512; /* Page Erase (512 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 256*16; /* 16-Mbit / 8 / 512 = 4096 */
- spi_flash_at45dbxx.geometry.block_size = 1024*4; /* Block Erase (4-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_321D)
- {
- /**< AT45DB321D Density Code : 00111 = 32-Mbit */
- FLASH_TRACE("AT45DB321D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 512; /* Page Erase (512 Bytes) */
- spi_flash_at45dbxx.geometry.sector_count = 256*32; /* 32-Mbit / 8 / 512 = 8192 */
- spi_flash_at45dbxx.geometry.block_size = 1024*4; /* Block Erase (4-Kbytes) */
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_642D)
- {
- /**< AT45DB642D Density Code : 01000 = 64-Mbit */
- FLASH_TRACE("AT45DB642D detection\r\n");
- spi_flash_at45dbxx.geometry.bytes_per_sector = 1024; /* Page Erase (1 Kbyte) */
- spi_flash_at45dbxx.geometry.sector_count = 128*64; /* 64-Mbit / 8 / 1024 = 8192 */
- spi_flash_at45dbxx.geometry.block_size = 1024*8; /* Block Erase (8 Kbytes) */
- }
- else
- {
- FLASH_TRACE("Memory Capacity error!\r\n");
- return -RT_ENOSYS;
- }
- }
-
- /* register device */
- spi_flash_at45dbxx.flash_device.type = RT_Device_Class_Block;
- spi_flash_at45dbxx.flash_device.init = AT45DB_flash_init;
- spi_flash_at45dbxx.flash_device.open = AT45DB_flash_open;
- spi_flash_at45dbxx.flash_device.close = AT45DB_flash_close;
- spi_flash_at45dbxx.flash_device.control = AT45DB_flash_control;
-
- if(JEDEC_ID->density_code == DENSITY_CODE_642D)
- {
- spi_flash_at45dbxx.flash_device.read = AT45DB_flash_read_page_1024;
- spi_flash_at45dbxx.flash_device.write = AT45DB_flash_write_page_1024;
- }
- else if(JEDEC_ID->density_code == DENSITY_CODE_161D
- || JEDEC_ID->density_code == DENSITY_CODE_321D )
- {
- spi_flash_at45dbxx.flash_device.read = AT45DB_flash_read_page_512;
- spi_flash_at45dbxx.flash_device.write = AT45DB_flash_write_page_512;
- }
- else
- {
- spi_flash_at45dbxx.flash_device.read = AT45DB_flash_read_page_256;
- spi_flash_at45dbxx.flash_device.write = AT45DB_flash_write_page_256;
- }
-
- /* no private */
- spi_flash_at45dbxx.flash_device.user_data = RT_NULL;
-
- rt_device_register(&spi_flash_at45dbxx.flash_device, flash_device_name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
-
- return RT_EOK;
-}
diff --git a/components/drivers/spi/spi_flash_at45dbxx.h b/components/drivers/spi/spi_flash_at45dbxx.h
deleted file mode 100644
index d1bc1a2aeb..0000000000
--- a/components/drivers/spi/spi_flash_at45dbxx.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- */
-
-#ifndef SPI_FLASH_AT45DBXX_H_INCLUDED
-#define SPI_FLASH_AT45DBXX_H_INCLUDED
-
-#include <rtthread.h>
-#include <drivers/spi.h>
-
-struct spi_flash_at45dbxx
-{
- struct rt_device flash_device;
- struct rt_device_blk_geometry geometry;
- struct rt_spi_device * rt_spi_device;
-};
-
-extern rt_err_t at45dbxx_init(const char * flash_device_name, const char * spi_device_name);
-
-
-#endif // SPI_FLASH_AT45DBXX_H_INCLUDED
diff --git a/components/drivers/spi/spi_flash_gd.c b/components/drivers/spi/spi_flash_gd.c
deleted file mode 100644
index 3c52035372..0000000000
--- a/components/drivers/spi/spi_flash_gd.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2015-10-11 fullhan copy from winbond flash
- */
-
-#include <stdint.h>
-#include <rtthread.h>
-#include <rtdevice.h>
-
-#include "spi_flash.h"
-#include "spi_flash_gd.h"
-
-#define FLASH_DEBUG
-
-#ifdef FLASH_DEBUG
-#define FLASH_TRACE rt_kprintf
-#else
-#define FLASH_TRACE(...)
-#endif /* #ifdef FLASH_DEBUG */
-
-#define PAGE_SIZE 4096
-
-/* JEDEC Manufacturer's ID */
-#define MF_ID (0xC8)
-/* JEDEC Device ID: Memory type and Capacity */
-#define MTC_GD25Q128 (0x4018)
-
-/* command list */
-#define CMD_WRSR (0x01) /* Write Status Register */
-#define CMD_PP (0x02) /* Page Program */
-#define CMD_READ (0x03) /* Read Data */
-#define CMD_WRDI (0x04) /* Write Disable */
-#define CMD_RDSR1 (0x05) /* Read Status Register-1 */
-#define CMD_WREN (0x06) /* Write Enable */
-#define CMD_FAST_READ (0x0B) /* Fast Read */
-#define CMD_ERASE_4K (0x20) /* Sector Erase:4K */
-#define CMD_RDSR2 (0x35) /* Read Status Register-2 */
-#define CMD_ERASE_32K (0x52) /* 32KB Block Erase */
-#define CMD_JEDEC_ID (0x9F) /* Read JEDEC ID */
-#define CMD_ERASE_full (0xC7) /* Chip Erase */
-#define CMD_ERASE_64K (0xD8) /* 64KB Block Erase */
-
-#define DUMMY (0xFF)
-
-static struct spi_flash_device spi_flash_device;
-
-static void flash_lock(struct spi_flash_device * flash_device)
-{
- rt_mutex_take(&flash_device->lock, RT_WAITING_FOREVER);
-}
-
-static void flash_unlock(struct spi_flash_device * flash_device)
-{
- rt_mutex_release(&flash_device->lock);
-}
-
-static uint8_t w25qxx_read_status(void)
-{
- return rt_spi_sendrecv8(spi_flash_device.rt_spi_device, CMD_RDSR1);
-}
-
-static void w25qxx_wait_busy(void)
-{
- while( w25qxx_read_status() & (0x01));
-}
-
-/** \brief read [size] byte from [offset] to [buffer]
- *
- * \param offset uint32_t unit : byte
- * \param buffer uint8_t*
- * \param size uint32_t unit : byte
- * \return uint32_t byte for read
- *
- */
-static uint32_t w25qxx_read(uint32_t offset, uint8_t * buffer, uint32_t size)
-{
- uint8_t send_buffer[4];
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_READ;
- send_buffer[1] = (uint8_t)(offset>>16);
- send_buffer[2] = (uint8_t)(offset>>8);
- send_buffer[3] = (uint8_t)(offset);
-
- rt_spi_send_then_recv(spi_flash_device.rt_spi_device,
- send_buffer, 4,
- buffer, size);
-
- return size;
-}
-
-/** \brief write N page on [page]
- *
- * \param page_addr uint32_t unit : byte (4096 * N,1 page = 4096byte)
- * \param buffer const uint8_t*
- * \return uint32_t
- *
- */
-static uint32_t w25qxx_page_write(uint32_t page_addr, const uint8_t* buffer)
-{
- uint32_t index;
- uint8_t send_buffer[4];
-
- RT_ASSERT((page_addr&0xFF) == 0); /* page addr must align to 256byte. */
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_ERASE_4K;
- send_buffer[1] = (page_addr >> 16);
- send_buffer[2] = (page_addr >> 8);
- send_buffer[3] = (page_addr);
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 4);
-
- w25qxx_wait_busy(); // wait erase done.
-
- for(index=0; index < (PAGE_SIZE / 256); index++)
- {
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_PP;
- send_buffer[1] = (uint8_t)(page_addr >> 16);
- send_buffer[2] = (uint8_t)(page_addr >> 8);
- send_buffer[3] = (uint8_t)(page_addr);
-
- rt_spi_send_then_send(spi_flash_device.rt_spi_device,
- send_buffer,
- 4,
- buffer,
- 256);
-
- buffer += 256;
- page_addr += 256;
- w25qxx_wait_busy();
- }
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- return PAGE_SIZE;
-}
-
-/* RT-Thread device interface */
-static rt_err_t w25qxx_flash_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_open(rt_device_t dev, rt_uint16_t oflag)
-{
- uint8_t send_buffer[3];
-
- flash_lock((struct spi_flash_device *)dev);
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_WRSR;
- send_buffer[1] = 0;
- send_buffer[2] = 0;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 3);
-
- w25qxx_wait_busy();
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_control(rt_device_t dev, int cmd, void *args)
-{
- RT_ASSERT(dev != RT_NULL);
-
- if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
- {
- struct rt_device_blk_geometry *geometry;
-
- geometry = (struct rt_device_blk_geometry *)args;
- if (geometry == RT_NULL) return -RT_ERROR;
-
- geometry->bytes_per_sector = spi_flash_device.geometry.bytes_per_sector;
- geometry->sector_count = spi_flash_device.geometry.sector_count;
- geometry->block_size = spi_flash_device.geometry.block_size;
- }
-
- return RT_EOK;
-}
-
-static rt_size_t w25qxx_flash_read(rt_device_t dev,
- rt_off_t pos,
- void* buffer,
- rt_size_t size)
-{
- flash_lock((struct spi_flash_device *)dev);
-
- w25qxx_read(pos*spi_flash_device.geometry.bytes_per_sector,
- buffer,
- size*spi_flash_device.geometry.bytes_per_sector);
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return size;
-}
-
-static rt_size_t w25qxx_flash_write(rt_device_t dev,
- rt_off_t pos,
- const void* buffer,
- rt_size_t size)
-{
- rt_size_t i = 0;
- rt_size_t block = size;
- const uint8_t * ptr = buffer;
-
- flash_lock((struct spi_flash_device *)dev);
-
- while(block--)
- {
- w25qxx_page_write((pos + i)*spi_flash_device.geometry.bytes_per_sector,
- ptr);
- ptr += PAGE_SIZE;
- i++;
- }
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return size;
-}
-
-#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device_ops gd_device_ops =
-{
- w25qxx_flash_init,
- w25qxx_flash_open,
- w25qxx_flash_close,
- w25qxx_flash_read,
- w25qxx_flash_write,
- w25qxx_flash_control
-};
-#endif
-
-rt_err_t gd_init(const char * flash_device_name, const char * spi_device_name)
-{
- struct rt_spi_device * rt_spi_device;
-
- /* initialize mutex */
- if (rt_mutex_init(&spi_flash_device.lock, spi_device_name, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- rt_kprintf("init sd lock mutex failed\n");
- return -RT_ENOSYS;
- }
-
- rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
- if(rt_spi_device == RT_NULL)
- {
- FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
- return -RT_ENOSYS;
- }
- spi_flash_device.rt_spi_device = rt_spi_device;
-
- /* config spi */
- {
- struct rt_spi_configuration cfg;
- cfg.data_width = 8;
- cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
- cfg.max_hz = 50 * 1000 * 1000; /* 50M */
- rt_spi_configure(spi_flash_device.rt_spi_device, &cfg);
- }
-
- /* init flash */
- {
- rt_uint8_t cmd;
- rt_uint8_t id_recv[3];
- uint16_t memory_type_capacity;
-
- flash_lock(&spi_flash_device);
-
- cmd = 0xFF; /* reset SPI FLASH, cancel all cmd in processing. */
- rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
-
- cmd = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
-
- /* read flash id */
- cmd = CMD_JEDEC_ID;
- rt_spi_send_then_recv(spi_flash_device.rt_spi_device, &cmd, 1, id_recv, 3);
-
- flash_unlock(&spi_flash_device);
-
- if(id_recv[0] != MF_ID)
- {
- FLASH_TRACE("Manufacturers ID error!\r\n");
- FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
- return -RT_ENOSYS;
- }
-
- spi_flash_device.geometry.bytes_per_sector = 4096;
- spi_flash_device.geometry.block_size = 4096; /* block erase: 4k */
-
- /* get memory type and capacity */
- memory_type_capacity = id_recv[1];
- memory_type_capacity = (memory_type_capacity << 8) | id_recv[2];
-
- if(memory_type_capacity == MTC_GD25Q128)
- {
- FLASH_TRACE("GD128 detection\r\n");
- spi_flash_device.geometry.sector_count = 4096;
- }
- else
- {
- FLASH_TRACE("Memory Capacity error!\r\n");
- return -RT_ENOSYS;
- }
- }
-
- /* register device */
- spi_flash_device.flash_device.type = RT_Device_Class_Block;
-#ifdef RT_USING_DEVICE_OPS
- spi_flash_device.flash_device.ops = &gd_device_ops;
-#else
- spi_flash_device.flash_device.init = w25qxx_flash_init;
- spi_flash_device.flash_device.open = w25qxx_flash_open;
- spi_flash_device.flash_device.close = w25qxx_flash_close;
- spi_flash_device.flash_device.read = w25qxx_flash_read;
- spi_flash_device.flash_device.write = w25qxx_flash_write;
- spi_flash_device.flash_device.control = w25qxx_flash_control;
-#endif
- /* no private */
- spi_flash_device.flash_device.user_data = RT_NULL;
-
- rt_device_register(&spi_flash_device.flash_device, flash_device_name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
-
- return RT_EOK;
-}
diff --git a/components/drivers/spi/spi_flash_gd.h b/components/drivers/spi/spi_flash_gd.h
deleted file mode 100644
index 904d976ed0..0000000000
--- a/components/drivers/spi/spi_flash_gd.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2015-10-11 fullhan copy from winbond flash
- */
-
-#ifndef SPI_FLASH_GD_H_
-#define SPI_FLASH_GD_H_
-
-#include <rtthread.h>
-
-extern rt_err_t gd_init(const char * flash_device_name, const char * spi_device_name);
-
-#endif /* SPI_FLASH_GD_H_ */
diff --git a/components/drivers/spi/spi_flash_sfud.c b/components/drivers/spi/spi_flash_sfud.c
index c8ff8f1b3b..2333c9ccb3 100644
--- a/components/drivers/spi/spi_flash_sfud.c
+++ b/components/drivers/spi/spi_flash_sfud.c
@@ -15,21 +15,20 @@
#ifdef RT_USING_SFUD
-#ifdef RT_DEBUG_SFUD
-#define DEBUG_TRACE rt_kprintf("[SFUD] "); rt_kprintf
-#else
-#define DEBUG_TRACE(...)
-#endif /* RT_DEBUG_SFUD */
-
#ifndef RT_SFUD_DEFAULT_SPI_CFG
+
+#ifndef RT_SFUD_SPI_MAX_HZ
+#define RT_SFUD_SPI_MAX_HZ 50000000
+#endif
+
/* read the JEDEC SFDP command must run at 50 MHz or less */
#define RT_SFUD_DEFAULT_SPI_CFG \
{ \
.mode = RT_SPI_MODE_0 | RT_SPI_MSB, \
.data_width = 8, \
- .max_hz = 50 * 1000 * 1000, \
+ .max_hz = RT_SFUD_SPI_MAX_HZ, \
}
-#endif
+#endif /* RT_SFUD_DEFAULT_SPI_CFG */
#ifdef SFUD_USING_QSPI
#define RT_SFUD_DEFAULT_QSPI_CFG \
@@ -39,14 +38,10 @@
.ddr_mode = 0, \
.qspi_dl_width = 4, \
}
-#endif
-
-static char log_buf[RT_CONSOLEBUF_SIZE];
-
-void sfud_log_debug(const char *file, const long line, const char *format, ...);
+#endif /* SFUD_USING_QSPI */
static rt_err_t rt_sfud_control(rt_device_t dev, int cmd, void *args) {
- RT_ASSERT(dev != RT_NULL);
+ RT_ASSERT(dev);
switch (cmd) {
case RT_DEVICE_CTRL_BLK_GETGEOME: {
@@ -93,6 +88,10 @@ static rt_err_t rt_sfud_control(rt_device_t dev, int cmd, void *args) {
static rt_size_t rt_sfud_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) {
struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (dev->user_data);
sfud_flash *sfud_dev = (sfud_flash *) (rtt_dev->user_data);
+
+ RT_ASSERT(dev);
+ RT_ASSERT(rtt_dev);
+ RT_ASSERT(sfud_dev);
/* change the block device's logic address to physical address */
rt_off_t phy_pos = pos * rtt_dev->geometry.bytes_per_sector;
rt_size_t phy_size = size * rtt_dev->geometry.bytes_per_sector;
@@ -107,6 +106,10 @@ static rt_size_t rt_sfud_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_si
static rt_size_t rt_sfud_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) {
struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (dev->user_data);
sfud_flash *sfud_dev = (sfud_flash *) (rtt_dev->user_data);
+
+ RT_ASSERT(dev);
+ RT_ASSERT(rtt_dev);
+ RT_ASSERT(sfud_dev);
/* change the block device's logic address to physical address */
rt_off_t phy_pos = pos * rtt_dev->geometry.bytes_per_sector;
rt_size_t phy_size = size * rtt_dev->geometry.bytes_per_sector;
@@ -126,6 +129,10 @@ static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, si
sfud_err result = SFUD_SUCCESS;
sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data);
struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data);
+
+ RT_ASSERT(spi);
+ RT_ASSERT(sfud_dev);
+ RT_ASSERT(rtt_dev);
#ifdef SFUD_USING_QSPI
struct rt_qspi_device *qspi_dev = RT_NULL;
#endif
@@ -139,11 +146,11 @@ static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, si
if(rtt_dev->rt_spi_device->bus->mode & RT_SPI_BUS_MODE_QSPI) {
qspi_dev = (struct rt_qspi_device *) (rtt_dev->rt_spi_device);
if (write_size && read_size) {
- if (rt_qspi_send_then_recv(qspi_dev, write_buf, write_size, read_buf, read_size) == 0) {
+ if (rt_qspi_send_then_recv(qspi_dev, write_buf, write_size, read_buf, read_size) <= 0) {
result = SFUD_ERR_TIMEOUT;
}
} else if (write_size) {
- if (rt_qspi_send(qspi_dev, write_buf, write_size) == 0) {
+ if (rt_qspi_send(qspi_dev, write_buf, write_size) <= 0) {
result = SFUD_ERR_TIMEOUT;
}
}
@@ -156,11 +163,11 @@ static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, si
result = SFUD_ERR_TIMEOUT;
}
} else if (write_size) {
- if (rt_spi_send(rtt_dev->rt_spi_device, write_buf, write_size) == 0) {
+ if (rt_spi_send(rtt_dev->rt_spi_device, write_buf, write_size) <= 0) {
result = SFUD_ERR_TIMEOUT;
}
} else {
- if (rt_spi_recv(rtt_dev->rt_spi_device, read_buf, read_size) == 0) {
+ if (rt_spi_recv(rtt_dev->rt_spi_device, read_buf, read_size) <= 0) {
result = SFUD_ERR_TIMEOUT;
}
}
@@ -180,7 +187,12 @@ static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi
sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data);
struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data);
struct rt_qspi_device *qspi_dev = (struct rt_qspi_device *) (rtt_dev->rt_spi_device);
-
+
+ RT_ASSERT(spi);
+ RT_ASSERT(sfud_dev);
+ RT_ASSERT(rtt_dev);
+ RT_ASSERT(qspi_dev);
+
/* set message struct */
message.instruction.content = qspi_read_cmd_format->instruction;
message.instruction.qspi_lines = qspi_read_cmd_format->instruction_lines;
@@ -201,11 +213,11 @@ static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi
message.parent.cs_release = 1;
message.parent.cs_take = 1;
message.qspi_data_lines = qspi_read_cmd_format->data_lines;
-
+
if (rt_qspi_transfer_message(qspi_dev, &message) != read_size) {
result = SFUD_ERR_TIMEOUT;
}
-
+
return result;
}
#endif
@@ -214,6 +226,10 @@ static void spi_lock(const sfud_spi *spi) {
sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data);
struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data);
+ RT_ASSERT(spi);
+ RT_ASSERT(sfud_dev);
+ RT_ASSERT(rtt_dev);
+
rt_mutex_take(&(rtt_dev->lock), RT_WAITING_FOREVER);
}
@@ -221,6 +237,10 @@ static void spi_unlock(const sfud_spi *spi) {
sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data);
struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data);
+ RT_ASSERT(spi);
+ RT_ASSERT(sfud_dev);
+ RT_ASSERT(rtt_dev);
+
rt_mutex_release(&(rtt_dev->lock));
}
@@ -229,47 +249,11 @@ static void retry_delay_100us(void) {
rt_thread_delay((RT_TICK_PER_SECOND * 1 + 9999) / 10000);
}
-/**
- * This function is print debug info.
- *
- * @param file the file which has call this function
- * @param line the line number which has call this function
- * @param format output format
- * @param ... args
- */
-void sfud_log_debug(const char *file, const long line, const char *format, ...) {
- va_list args;
-
- /* args point to the first variable parameter */
- va_start(args, format);
- rt_kprintf("[SFUD] (%s:%ld) ", file, line);
- /* must use vprintf to print */
- rt_vsnprintf(log_buf, sizeof(log_buf), format, args);
- rt_kprintf("%s\n", log_buf);
- va_end(args);
-}
-
-/**
- * This function is print routine info.
- *
- * @param format output format
- * @param ... args
- */
-void sfud_log_info(const char *format, ...) {
- va_list args;
-
- /* args point to the first variable parameter */
- va_start(args, format);
- rt_kprintf("[SFUD] ");
- /* must use vprintf to print */
- rt_vsnprintf(log_buf, sizeof(log_buf), format, args);
- rt_kprintf("%s\n", log_buf);
- va_end(args);
-}
-
sfud_err sfud_spi_port_init(sfud_flash *flash) {
sfud_err result = SFUD_SUCCESS;
+ RT_ASSERT(flash);
+
/* port SPI device interface */
flash->spi.wr = spi_write_read;
#ifdef SFUD_USING_QSPI
@@ -279,18 +263,18 @@ sfud_err sfud_spi_port_init(sfud_flash *flash) {
flash->spi.unlock = spi_unlock;
flash->spi.user_data = flash;
if (RT_TICK_PER_SECOND < 1000) {
- rt_kprintf("[SFUD] Warning: The OS tick(%d) is less than 1000. So the flash write will take more time.\n", RT_TICK_PER_SECOND);
+ LOG_W("[SFUD] Warning: The OS tick(%d) is less than 1000. So the flash write will take more time.", RT_TICK_PER_SECOND);
}
/* 100 microsecond delay */
flash->retry.delay = retry_delay_100us;
/* 60 seconds timeout */
flash->retry.times = 60 * 10000;
-
+
return result;
}
#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device_ops flash_device_ops =
+const static struct rt_device_ops flash_device_ops =
{
RT_NULL,
RT_NULL,
@@ -302,23 +286,23 @@ const static struct rt_device_ops flash_device_ops =
#endif
/**
- * Probe SPI flash by SFUD(Serial Flash Universal Driver) driver library and though SPI device.
+ * Probe SPI flash by SFUD (Serial Flash Universal Driver) driver library and though SPI device by specified configuration.
*
* @param spi_flash_dev_name the name which will create SPI flash device
* @param spi_dev_name using SPI device name
+ * @param spi_cfg SPI device configuration
+ * @param qspi_cfg QSPI device configuration
*
* @return probed SPI flash device, probe failed will return RT_NULL
*/
-rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name) {
+rt_spi_flash_device_t rt_sfud_flash_probe_ex(const char *spi_flash_dev_name, const char *spi_dev_name,
+ struct rt_spi_configuration *spi_cfg, struct rt_qspi_configuration *qspi_cfg)
+{
rt_spi_flash_device_t rtt_dev = RT_NULL;
sfud_flash *sfud_dev = RT_NULL;
char *spi_flash_dev_name_bak = RT_NULL, *spi_dev_name_bak = RT_NULL;
- /* using default flash SPI configuration for initialize SPI Flash
- * @note you also can change the SPI to other configuration after initialized finish */
- struct rt_spi_configuration cfg = RT_SFUD_DEFAULT_SPI_CFG;
extern sfud_err sfud_device_init(sfud_flash *flash);
#ifdef SFUD_USING_QSPI
- struct rt_qspi_configuration qspi_cfg = RT_SFUD_DEFAULT_QSPI_CFG;
struct rt_qspi_device *qspi_dev = RT_NULL;
#endif
@@ -348,7 +332,7 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
/* RT-Thread SPI device initialize */
rtt_dev->rt_spi_device = (struct rt_spi_device *) rt_device_find(spi_dev_name);
if (rtt_dev->rt_spi_device == RT_NULL || rtt_dev->rt_spi_device->parent.type != RT_Device_Class_SPIDevice) {
- rt_kprintf("ERROR: SPI device %s not found!\n", spi_dev_name);
+ LOG_E("ERROR: SPI device %s not found!", spi_dev_name);
goto error;
}
sfud_dev->spi.name = spi_dev_name_bak;
@@ -357,12 +341,12 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
/* set the qspi line number and configure the QSPI bus */
if(rtt_dev->rt_spi_device->bus->mode &RT_SPI_BUS_MODE_QSPI) {
qspi_dev = (struct rt_qspi_device *)rtt_dev->rt_spi_device;
- qspi_cfg.qspi_dl_width = qspi_dev->config.qspi_dl_width;
- rt_qspi_configure(qspi_dev, &qspi_cfg);
+ qspi_cfg->qspi_dl_width = qspi_dev->config.qspi_dl_width;
+ rt_qspi_configure(qspi_dev, qspi_cfg);
}
else
-#endif
- rt_spi_configure(rtt_dev->rt_spi_device, &cfg);
+#endif
+ rt_spi_configure(rtt_dev->rt_spi_device, spi_cfg);
}
/* SFUD flash device initialize */
{
@@ -374,7 +358,7 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
sfud_dev->user_data = rtt_dev;
/* initialize SFUD device */
if (sfud_device_init(sfud_dev) != SFUD_SUCCESS) {
- rt_kprintf("ERROR: SPI flash probe failed by SPI device %s.\n", spi_dev_name);
+ LOG_E("ERROR: SPI flash probe failed by SPI device %s.", spi_dev_name);
goto error;
}
/* when initialize success, then copy SFUD flash device's geometry to RT-Thread SPI flash device */
@@ -384,13 +368,14 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
#ifdef SFUD_USING_QSPI
/* reconfigure the QSPI bus for medium size */
if(rtt_dev->rt_spi_device->bus->mode &RT_SPI_BUS_MODE_QSPI) {
- qspi_cfg.medium_size = sfud_dev->chip.capacity;
- rt_qspi_configure(qspi_dev, &qspi_cfg);
+ qspi_cfg->medium_size = sfud_dev->chip.capacity;
+ rt_qspi_configure(qspi_dev, qspi_cfg);
if(qspi_dev->enter_qspi_mode != RT_NULL)
qspi_dev->enter_qspi_mode(qspi_dev);
+
+ /* set data lines width */
+ sfud_qspi_fast_read_enable(sfud_dev, qspi_dev->config.qspi_dl_width);
}
- /* set data lines width */
- sfud_qspi_fast_read_enable(sfud_dev, qspi_dev->config.qspi_dl_width);
#endif /* SFUD_USING_QSPI */
}
@@ -409,10 +394,10 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
rt_device_register(&(rtt_dev->flash_device), spi_flash_dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
- DEBUG_TRACE("Probe SPI flash %s by SPI device %s success.\n",spi_flash_dev_name, spi_dev_name);
+ LOG_I("Probe SPI flash %s by SPI device %s success.",spi_flash_dev_name, spi_dev_name);
return rtt_dev;
} else {
- rt_kprintf("ERROR: Low memory.\n");
+ LOG_E("ERROR: Low memory.");
goto error;
}
@@ -431,6 +416,26 @@ error:
}
/**
+ * Probe SPI flash by SFUD(Serial Flash Universal Driver) driver library and though SPI device.
+ *
+ * @param spi_flash_dev_name the name which will create SPI flash device
+ * @param spi_dev_name using SPI device name
+ *
+ * @return probed SPI flash device, probe failed will return RT_NULL
+ */
+rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name)
+{
+ struct rt_spi_configuration cfg = RT_SFUD_DEFAULT_SPI_CFG;
+#ifndef SFUD_USING_QSPI
+ return rt_sfud_flash_probe_ex(spi_flash_dev_name, spi_dev_name, &cfg, RT_NULL);
+#else
+ struct rt_qspi_configuration qspi_cfg = RT_SFUD_DEFAULT_QSPI_CFG;
+
+ return rt_sfud_flash_probe_ex(spi_flash_dev_name, spi_dev_name, &cfg, &qspi_cfg);
+#endif
+}
+
+/**
* Delete SPI flash device
*
* @param spi_flash_dev SPI flash device
@@ -455,12 +460,62 @@ rt_err_t rt_sfud_flash_delete(rt_spi_flash_device_t spi_flash_dev) {
return RT_EOK;
}
+sfud_flash_t rt_sfud_flash_find(const char *spi_dev_name)
+{
+ rt_spi_flash_device_t rtt_dev = RT_NULL;
+ struct rt_spi_device *rt_spi_device = RT_NULL;
+ sfud_flash_t sfud_dev = RT_NULL;
+
+ rt_spi_device = (struct rt_spi_device *) rt_device_find(spi_dev_name);
+ if (rt_spi_device == RT_NULL || rt_spi_device->parent.type != RT_Device_Class_SPIDevice) {
+ LOG_E("ERROR: SPI device %s not found!", spi_dev_name);
+ goto __error;
+ }
+
+ rtt_dev = (rt_spi_flash_device_t) (rt_spi_device->user_data);
+ if (rtt_dev && rtt_dev->user_data) {
+ sfud_dev = (sfud_flash_t) (rtt_dev->user_data);
+ return sfud_dev;
+ } else {
+ LOG_E("ERROR: SFUD flash device not found!");
+ goto __error;
+ }
+
+__error:
+ return RT_NULL;
+}
+
+sfud_flash_t rt_sfud_flash_find_by_dev_name(const char *flash_dev_name)
+{
+ rt_spi_flash_device_t rtt_dev = RT_NULL;
+ sfud_flash_t sfud_dev = RT_NULL;
+
+ rtt_dev = (rt_spi_flash_device_t) rt_device_find(flash_dev_name);
+ if (rtt_dev == RT_NULL || rtt_dev->flash_device.type != RT_Device_Class_Block) {
+ LOG_E("ERROR: Flash device %s not found!", flash_dev_name);
+ goto __error;
+ }
+
+ if (rtt_dev->user_data) {
+ sfud_dev = (sfud_flash_t) (rtt_dev->user_data);
+ return sfud_dev;
+ } else {
+ LOG_E("ERROR: SFUD flash device not found!");
+ goto __error;
+ }
+
+__error:
+ return RT_NULL;
+}
+
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
#include <finsh.h>
static void sf(uint8_t argc, char **argv) {
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+#define HEXDUMP_WIDTH 16
#define CMD_PROBE_INDEX 0
#define CMD_READ_INDEX 1
#define CMD_WRITE_INDEX 2
@@ -471,7 +526,7 @@ static void sf(uint8_t argc, char **argv) {
sfud_err result = SFUD_SUCCESS;
static const sfud_flash *sfud_dev = NULL;
static rt_spi_flash_device_t rtt_dev = NULL, rtt_dev_bak = NULL;
- size_t i = 0;
+ size_t i = 0, j = 0;
const char* sf_help_info[] = {
[CMD_PROBE_INDEX] = "sf probe [spi_device] - probe and init SPI flash by given 'spi_device'",
@@ -498,12 +553,12 @@ static void sf(uint8_t argc, char **argv) {
} else {
char *spi_dev_name = argv[2];
rtt_dev_bak = rtt_dev;
-
+
/* delete the old SPI flash device */
if(rtt_dev_bak) {
rt_sfud_flash_delete(rtt_dev_bak);
}
-
+
rtt_dev = rt_sfud_flash_probe("sf_cmd", spi_dev_name);
if (!rtt_dev) {
return;
@@ -527,8 +582,8 @@ static void sf(uint8_t argc, char **argv) {
rt_kprintf("Usage: %s.\n", sf_help_info[CMD_READ_INDEX]);
return;
} else {
- addr = atol(argv[2]);
- size = atol(argv[3]);
+ addr = strtol(argv[2], NULL, 0);
+ size = strtol(argv[3], NULL, 0);
uint8_t *data = rt_malloc(size);
if (data) {
result = sfud_read(sfud_dev, addr, size, data);
@@ -536,14 +591,24 @@ static void sf(uint8_t argc, char **argv) {
rt_kprintf("Read the %s flash data success. Start from 0x%08X, size is %ld. The data is:\n",
sfud_dev->name, addr, size);
rt_kprintf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
- for (i = 0; i < size; i++) {
- if (i % 16 == 0) {
- rt_kprintf("[%08X] ", addr + i);
+ for (i = 0; i < size; i += HEXDUMP_WIDTH)
+ {
+ rt_kprintf("[%08X] ", addr + i);
+ /* dump hex */
+ for (j = 0; j < HEXDUMP_WIDTH; j++) {
+ if (i + j < size) {
+ rt_kprintf("%02X ", data[i + j]);
+ } else {
+ rt_kprintf(" ");
+ }
}
- rt_kprintf("%02X ", data[i]);
- if (((i + 1) % 16 == 0) || i == size - 1) {
- rt_kprintf("\n");
+ /* dump char for hex */
+ for (j = 0; j < HEXDUMP_WIDTH; j++) {
+ if (i + j < size) {
+ rt_kprintf("%c", __is_print(data[i + j]) ? data[i + j] : '.');
+ }
}
+ rt_kprintf("\n");
}
rt_kprintf("\n");
}
@@ -557,12 +622,12 @@ static void sf(uint8_t argc, char **argv) {
rt_kprintf("Usage: %s.\n", sf_help_info[CMD_WRITE_INDEX]);
return;
} else {
- addr = atol(argv[2]);
+ addr = strtol(argv[2], NULL, 0);
size = argc - 3;
uint8_t *data = rt_malloc(size);
if (data) {
for (i = 0; i < size; i++) {
- data[i] = atoi(argv[3 + i]);
+ data[i] = strtol(argv[3 + i], NULL, 0);
}
result = sfud_write(sfud_dev, addr, size, data);
if (result == SFUD_SUCCESS) {
@@ -584,8 +649,8 @@ static void sf(uint8_t argc, char **argv) {
rt_kprintf("Usage: %s.\n", sf_help_info[CMD_ERASE_INDEX]);
return;
} else {
- addr = atol(argv[2]);
- size = atol(argv[3]);
+ addr = strtol(argv[2], NULL, 0);
+ size = strtol(argv[3], NULL, 0);
result = sfud_erase(sfud_dev, addr, size);
if (result == SFUD_SUCCESS) {
rt_kprintf("Erase the %s flash data success. Start from 0x%08X, size is %ld.\n", sfud_dev->name,
@@ -600,8 +665,8 @@ static void sf(uint8_t argc, char **argv) {
rt_kprintf("The %s flash status register current value is 0x%02X.\n", sfud_dev->name, status);
}
} else if (argc == 4) {
- bool is_volatile = atoi(argv[2]);
- uint8_t status = atoi(argv[3]);
+ bool is_volatile = strtol(argv[2], NULL, 0);
+ uint8_t status = strtol(argv[3], NULL, 0);
result = sfud_write_status(sfud_dev, is_volatile, status);
if (result == SFUD_SUCCESS) {
rt_kprintf("Write the %s flash status register to 0x%02X success.\n", sfud_dev->name, status);
@@ -619,11 +684,13 @@ static void sf(uint8_t argc, char **argv) {
addr = 0;
size = sfud_dev->chip.capacity;
uint32_t start_time, time_cast;
- size_t write_size = SFUD_WRITE_MAX_PAGE_SIZE, read_size = SFUD_WRITE_MAX_PAGE_SIZE;
+ size_t write_size = SFUD_WRITE_MAX_PAGE_SIZE, read_size = SFUD_WRITE_MAX_PAGE_SIZE, cur_op_size;
uint8_t *write_data = rt_malloc(write_size), *read_data = rt_malloc(read_size);
if (write_data && read_data) {
- rt_memset(write_data, 0x55, write_size);
+ for (i = 0; i < write_size; i ++) {
+ write_data[i] = i & 0xFF;
+ }
/* benchmark testing */
rt_kprintf("Erasing the %s %ld bytes data, waiting...\n", sfud_dev->name, size);
start_time = rt_tick_get();
@@ -639,8 +706,14 @@ static void sf(uint8_t argc, char **argv) {
rt_kprintf("Writing the %s %ld bytes data, waiting...\n", sfud_dev->name, size);
start_time = rt_tick_get();
for (i = 0; i < size; i += write_size) {
- result = sfud_write(sfud_dev, addr + i, write_size, write_data);
+ if (i + write_size <= size) {
+ cur_op_size = write_size;
+ } else {
+ cur_op_size = size - i;
+ }
+ result = sfud_write(sfud_dev, addr + i, cur_op_size, write_data);
if (result != SFUD_SUCCESS) {
+ rt_kprintf("Writing %s failed, already wr for %lu bytes, write %d each time\n", sfud_dev->name, i, write_size);
break;
}
}
@@ -656,18 +729,20 @@ static void sf(uint8_t argc, char **argv) {
start_time = rt_tick_get();
for (i = 0; i < size; i += read_size) {
if (i + read_size <= size) {
- result = sfud_read(sfud_dev, addr + i, read_size, read_data);
+ cur_op_size = read_size;
} else {
- result = sfud_read(sfud_dev, addr + i, size - i, read_data);
+ cur_op_size = size - i;
}
+ result = sfud_read(sfud_dev, addr + i, cur_op_size, read_data);
/* data check */
- if (memcmp(write_data, read_data, read_size))
+ if (memcmp(write_data, read_data, cur_op_size))
{
rt_kprintf("Data check ERROR! Please check you flash by other command.\n");
result = SFUD_ERR_READ;
}
-
+
if (result != SFUD_SUCCESS) {
+ rt_kprintf("Read %s failed, already rd for %lu bytes, read %d each time\n", sfud_dev->name, i, read_size);
break;
}
}
@@ -698,36 +773,6 @@ static void sf(uint8_t argc, char **argv) {
}
}
MSH_CMD_EXPORT(sf, SPI Flash operate.);
-
-sfud_flash_t rt_sfud_flash_find(const char *spi_dev_name)
-{
- rt_spi_flash_device_t rtt_dev = RT_NULL;
- struct rt_spi_device *rt_spi_device = RT_NULL;
- sfud_flash_t sfud_dev = RT_NULL;
-
- rt_spi_device = (struct rt_spi_device *) rt_device_find(spi_dev_name);
- if (rt_spi_device == RT_NULL || rt_spi_device->parent.type != RT_Device_Class_SPIDevice)
- {
- rt_kprintf("ERROR: SPI device %s not found!\n", spi_dev_name);
- goto error;
- }
-
- rtt_dev = (rt_spi_flash_device_t)(rt_spi_device->user_data);
- if (rtt_dev && rtt_dev->user_data)
- {
- sfud_dev = (sfud_flash_t)(rtt_dev->user_data);
- return sfud_dev;
- }
- else
- {
- rt_kprintf("ERROR: SFUD flash device not found!\n");
- goto error;
- }
-
-error:
- return RT_NULL;
-}
-
#endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */
#endif /* RT_USING_SFUD */
diff --git a/components/drivers/spi/spi_flash_sfud.h b/components/drivers/spi/spi_flash_sfud.h
index af1ed58790..932b7f879c 100644
--- a/components/drivers/spi/spi_flash_sfud.h
+++ b/components/drivers/spi/spi_flash_sfud.h
@@ -27,6 +27,19 @@
rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name);
/**
+ * Probe SPI flash by SFUD (Serial Flash Universal Driver) driver library and though SPI device by specified configuration.
+ *
+ * @param spi_flash_dev_name the name which will create SPI flash device
+ * @param spi_dev_name using SPI device name
+ * @param spi_cfg SPI device configuration
+ * @param qspi_cfg QSPI device configuration
+ *
+ * @return probed SPI flash device, probe failed will return RT_NULL
+ */
+rt_spi_flash_device_t rt_sfud_flash_probe_ex(const char *spi_flash_dev_name, const char *spi_dev_name,
+ struct rt_spi_configuration *spi_cfg, struct rt_qspi_configuration *qspi_cfg);
+
+/**
* Delete SPI flash device
*
* @param spi_flash_dev SPI flash device
@@ -36,7 +49,7 @@ rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const
rt_err_t rt_sfud_flash_delete(rt_spi_flash_device_t spi_flash_dev);
/**
- * Find sfud flash device
+ * Find sfud flash device by SPI device name
*
* @param spi_dev_name using SPI device name
*
@@ -44,4 +57,13 @@ rt_err_t rt_sfud_flash_delete(rt_spi_flash_device_t spi_flash_dev);
*/
sfud_flash_t rt_sfud_flash_find(const char *spi_dev_name);
+/**
+ * Find sfud flash device by flash device name
+ *
+ * @param flash_dev_name using flash device name
+ *
+ * @return sfud flash device if success, otherwise return RT_NULL
+ */
+sfud_flash_t rt_sfud_flash_find_by_dev_name(const char *flash_dev_name);
+
#endif /* _SPI_FLASH_SFUD_H_ */
diff --git a/components/drivers/spi/spi_flash_sst25vfxx.c b/components/drivers/spi/spi_flash_sst25vfxx.c
deleted file mode 100644
index bd618a8e9b..0000000000
--- a/components/drivers/spi/spi_flash_sst25vfxx.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- */
-
-#include <stdint.h>
-#include "spi_flash_sst25vfxx.h"
-
-#define FLASH_DEBUG
-
-#ifdef FLASH_DEBUG
-#define FLASH_TRACE rt_kprintf
-#else
-#define FLASH_TRACE(...)
-#endif /* #ifdef FLASH_DEBUG */
-
-/* JEDEC Manufacturer’s ID */
-#define MF_ID (0xBF)
-/* JEDEC Device ID : Memory Type */
-#define MT_ID (0x25)
-/* JEDEC Device ID: Memory Capacity */
-#define MC_ID_SST25VF020B (0x8C) /* 2Mbit */
-#define MC_ID_SST25VF040B (0x8D) /* 4Mbit */
-#define MC_ID_SST25VF080B (0x8E) /* 8Mbit */
-#define MC_ID_SST25VF016B (0x41) /* 16Mbit */
-#define MC_ID_SST25VF032B (0x4A) /* 32Mbit */
-#define MC_ID_SST25VF064C (0x4B) /* 64Mbit */
-
-/* command list */
-#define CMD_RDSR (0x05)
-#define CMD_WRSR (0x01)
-#define CMD_EWSR (0x50)
-#define CMD_WRDI (0x04)
-#define CMD_WREN (0x06)
-#define CMD_READ (0x03)
-#define CMD_FAST_READ (0x0B)
-#define CMD_BP (0x02)
-#define CMD_AAIP (0xAD)
-#define CMD_ERASE_4K (0x20)
-#define CMD_ERASE_32K (0x52)
-#define CMD_ERASE_64K (0xD8)
-#define CMD_ERASE_full (0xC7)
-#define CMD_JEDEC_ID (0x9F)
-#define CMD_EBSY (0x70)
-#define CMD_DBSY (0x80)
-
-#define DUMMY (0xFF)
-
-static struct spi_flash_sst25vfxx spi_flash_sst25vfxx;
-
-static uint8_t sst25vfxx_read_status(struct spi_flash_sst25vfxx * spi_flash)
-{
- return rt_spi_sendrecv8(spi_flash->rt_spi_device, CMD_RDSR);
-}
-
-static void sst25vfxx_wait_busy(struct spi_flash_sst25vfxx * spi_flash)
-{
- while( sst25vfxx_read_status(spi_flash) & (0x01));
-}
-
-/** \brief write N page on [page]
- *
- * \param page uint32_t unit : byte (4096 * N,1 page = 4096byte)
- * \param buffer const uint8_t*
- * \param size uint32_t unit : byte ( 4096*N )
- * \return uint32_t
- *
- */
-static uint32_t sst25vfxx_page_write(struct spi_flash_sst25vfxx * spi_flash, uint32_t page, const uint8_t * buffer, uint32_t size)
-{
- uint32_t index;
- uint32_t need_wirte = size;
- uint8_t send_buffer[6];
-
- page &= ~0xFFF; // page size = 4096byte
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_ERASE_4K;
- send_buffer[1] = (page >> 16);
- send_buffer[2] = (page >> 8);
- send_buffer[3] = (page);
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 4);
-
- sst25vfxx_wait_busy(spi_flash); // wait erase done.
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_AAIP;
- send_buffer[1] = (uint8_t)(page >> 16);
- send_buffer[2] = (uint8_t)(page >> 8);
- send_buffer[3] = (uint8_t)(page);
- send_buffer[4] = *buffer++;
- send_buffer[5] = *buffer++;
- need_wirte -= 2;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 6);
-
- sst25vfxx_wait_busy(spi_flash);
-
- for(index=0; index < need_wirte/2; index++)
- {
- send_buffer[0] = CMD_AAIP;
- send_buffer[1] = *buffer++;
- send_buffer[2] = *buffer++;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 3);
- sst25vfxx_wait_busy(spi_flash);
- }
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- return size;
-}
-
-/* RT-Thread device interface */
-static rt_err_t sst25vfxx_flash_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t sst25vfxx_flash_open(rt_device_t dev, rt_uint16_t oflag)
-{
- rt_err_t result;
- uint8_t send_buffer[2];
- struct spi_flash_sst25vfxx * spi_flash = (struct spi_flash_sst25vfxx *)dev;
-
- /* lock spi flash */
- result = rt_mutex_take(&(spi_flash->lock), RT_WAITING_FOREVER);
- if(result != RT_EOK)
- {
- return result;
- }
-
- send_buffer[0] = CMD_DBSY;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_EWSR;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_WRSR;
- send_buffer[1] = 0;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 2);
-
- /* release lock */
- rt_mutex_release(&(spi_flash->lock));
-
- return RT_EOK;
-}
-
-static rt_err_t sst25vfxx_flash_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t sst25vfxx_flash_control(rt_device_t dev, int cmd, void *args)
-{
- struct spi_flash_sst25vfxx * spi_flash;
-
- spi_flash = (struct spi_flash_sst25vfxx *)dev;
-
- RT_ASSERT(dev != RT_NULL);
-
- if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
- {
- struct rt_device_blk_geometry *geometry;
-
- geometry = (struct rt_device_blk_geometry *)args;
- if (geometry == RT_NULL) return -RT_ERROR;
-
- geometry->bytes_per_sector = spi_flash->geometry.bytes_per_sector;
- geometry->sector_count = spi_flash->geometry.sector_count;
- geometry->block_size = spi_flash->geometry.block_size;
- }
-
- return RT_EOK;
-}
-
-static rt_size_t sst25vfxx_flash_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
-{
- rt_err_t result;
- uint8_t send_buffer[4];
- struct spi_flash_sst25vfxx * spi_flash = (struct spi_flash_sst25vfxx *)dev;
- uint32_t offset = pos * spi_flash->geometry.bytes_per_sector;
-
- /* lock spi flash */
- result = rt_mutex_take(&(spi_flash->lock), RT_WAITING_FOREVER);
- if(result != RT_EOK)
- {
- return 0;
- }
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_READ;
- send_buffer[1] = (uint8_t)(offset>>16);
- send_buffer[2] = (uint8_t)(offset>>8);
- send_buffer[3] = (uint8_t)(offset);
- rt_spi_send_then_recv(spi_flash->rt_spi_device, send_buffer, 4, buffer, size * spi_flash->geometry.bytes_per_sector);
-
- /* release lock */
- rt_mutex_release(&(spi_flash->lock));
-
- return size;
-}
-
-static rt_size_t sst25vfxx_flash_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
-{
- uint32_t i;
- rt_err_t result;
- const uint8_t * write_buffer = buffer;
- struct spi_flash_sst25vfxx * spi_flash = (struct spi_flash_sst25vfxx *)dev;
-
- /* lock spi flash */
- result = rt_mutex_take(&(spi_flash->lock), RT_WAITING_FOREVER);
- if(result != RT_EOK)
- {
- return 0;
- }
-
- for(i=0; i<size; i++)
- {
- sst25vfxx_page_write(spi_flash,
- (pos + i) * spi_flash->geometry.bytes_per_sector,
- write_buffer,
- spi_flash->geometry.bytes_per_sector);
- write_buffer += spi_flash->geometry.bytes_per_sector;
- }
-
- /* release lock */
- rt_mutex_release(&(spi_flash->lock));
-
- return size;
-}
-
-#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device_ops sst25vfxx_device_ops =
-{
- sst25vfxx_flash_init,
- sst25vfxx_flash_open,
- sst25vfxx_flash_close,
- sst25vfxx_flash_read,
- sst25vfxx_flash_write,
- sst25vfxx_flash_control
-};
-#endif
-
-rt_err_t sst25vfxx_init(const char * flash_device_name, const char * spi_device_name)
-{
- struct rt_spi_device * rt_spi_device;
- struct spi_flash_sst25vfxx * spi_flash = &spi_flash_sst25vfxx;
-
- rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
- if(rt_spi_device == RT_NULL)
- {
- FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
- return -RT_ENOSYS;
- }
- spi_flash->rt_spi_device = rt_spi_device;
-
- /* config spi */
- {
- struct rt_spi_configuration cfg;
- cfg.data_width = 8;
- cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
- cfg.max_hz = 50000000; /* 50M */
- rt_spi_configure(spi_flash->rt_spi_device, &cfg);
- }
-
- /* init flash */
- {
- rt_uint8_t cmd;
- rt_uint8_t id_recv[3];
-
- cmd = CMD_WRDI;
- rt_spi_send(spi_flash->rt_spi_device, &cmd, 1);
-
- /* read flash id */
- cmd = CMD_JEDEC_ID;
- rt_spi_send_then_recv(spi_flash->rt_spi_device, &cmd, 1, id_recv, 3);
-
- if(id_recv[0] != MF_ID || id_recv[1] != MT_ID)
- {
- FLASH_TRACE("Manufacturer’s ID or Memory Type error!\r\n");
- FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
- return -RT_ENOSYS;
- }
-
- spi_flash->geometry.bytes_per_sector = 4096;
- spi_flash->geometry.block_size = 4096; /* block erase: 4k */
-
- if(id_recv[2] == MC_ID_SST25VF020B)
- {
- FLASH_TRACE("SST25VF020B detection\r\n");
- spi_flash->geometry.sector_count = 64;
- }
- else if(id_recv[2] == MC_ID_SST25VF040B)
- {
- FLASH_TRACE("SST25VF040B detection\r\n");
- spi_flash->geometry.sector_count = 128;
- }
- else if(id_recv[2] == MC_ID_SST25VF080B)
- {
- FLASH_TRACE("SST25VF080B detection\r\n");
- spi_flash->geometry.sector_count = 256;
- }
- else if(id_recv[2] == MC_ID_SST25VF016B)
- {
- FLASH_TRACE("SST25VF016B detection\r\n");
- spi_flash->geometry.sector_count = 512;
- }
- else if(id_recv[2] == MC_ID_SST25VF032B)
- {
- FLASH_TRACE("SST25VF032B detection\r\n");
- spi_flash->geometry.sector_count = 1024;
- }
- else if(id_recv[2] == MC_ID_SST25VF064C)
- {
- FLASH_TRACE("SST25VF064C detection\r\n");
- spi_flash->geometry.sector_count = 2048;
- }
- else
- {
- FLASH_TRACE("Memory Capacity error!\r\n");
- return -RT_ENOSYS;
- }
- }
-
- /* initialize mutex lock */
- rt_mutex_init(&spi_flash->lock, flash_device_name, RT_IPC_FLAG_PRIO);
-
- /* register device */
- spi_flash->flash_device.type = RT_Device_Class_Block;
-#ifdef RT_USING_DEVICE_OPS
- spi_flash->flash_device.ops = &sst25vfxx_device_ops;
-#else
- spi_flash->flash_device.init = sst25vfxx_flash_init;
- spi_flash->flash_device.open = sst25vfxx_flash_open;
- spi_flash->flash_device.close = sst25vfxx_flash_close;
- spi_flash->flash_device.read = sst25vfxx_flash_read;
- spi_flash->flash_device.write = sst25vfxx_flash_write;
- spi_flash->flash_device.control = sst25vfxx_flash_control;
-#endif
- /* no private */
- spi_flash->flash_device.user_data = RT_NULL;
-
- rt_device_register(&spi_flash->flash_device, flash_device_name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
-
- return RT_EOK;
-}
diff --git a/components/drivers/spi/spi_flash_sst25vfxx.h b/components/drivers/spi/spi_flash_sst25vfxx.h
deleted file mode 100644
index 7a7283f753..0000000000
--- a/components/drivers/spi/spi_flash_sst25vfxx.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- */
-
-#ifndef SPI_FLASH_SST25VFXX_H_INCLUDED
-#define SPI_FLASH_SST25VFXX_H_INCLUDED
-
-#include <rtthread.h>
-#include <drivers/spi.h>
-
-struct spi_flash_sst25vfxx
-{
- struct rt_device flash_device;
- struct rt_device_blk_geometry geometry;
- struct rt_spi_device * rt_spi_device;
- struct rt_mutex lock;
-};
-
-extern rt_err_t sst25vfxx_init(const char * flash_device_name, const char * spi_device_name);
-
-
-#endif // SPI_FLASH_SST25VFXX_H_INCLUDED
diff --git a/components/drivers/spi/spi_flash_w25qxx.c b/components/drivers/spi/spi_flash_w25qxx.c
deleted file mode 100644
index bba9c0b5cc..0000000000
--- a/components/drivers/spi/spi_flash_w25qxx.c
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- * 2012-05-06 aozima can page write.
- * 2012-08-23 aozima add flash lock.
- * 2012-08-24 aozima fixed write status register BUG.
- */
-
-#include <stdint.h>
-#include <rtdevice.h>
-
-#include "spi_flash.h"
-#include "spi_flash_w25qxx.h"
-
-#define FLASH_DEBUG
-
-#ifdef FLASH_DEBUG
-#define FLASH_TRACE rt_kprintf
-#else
-#define FLASH_TRACE(...)
-#endif /* #ifdef FLASH_DEBUG */
-
-#define PAGE_SIZE 4096
-
-/* JEDEC Manufacturer ID */
-#define MF_ID (0xEF)
-
-/* JEDEC Device ID: Memory type and Capacity */
-#define MTC_W25Q80_BV (0x4014) /* W25Q80BV */
-#define MTC_W25Q16_BV_CL_CV (0x4015) /* W25Q16BV W25Q16CL W25Q16CV */
-#define MTC_W25Q16_DW (0x6015) /* W25Q16DW */
-#define MTC_W25Q32_BV (0x4016) /* W25Q32BV */
-#define MTC_W25Q32_DW (0x6016) /* W25Q32DW */
-#define MTC_W25Q64_BV_CV (0x4017) /* W25Q64BV W25Q64CV */
-#define MTC_W25Q64_DW (0x4017) /* W25Q64DW */
-#define MTC_W25Q128_BV (0x4018) /* W25Q128BV */
-#define MTC_W25Q256_FV (TBD) /* W25Q256FV */
-
-/* command list */
-#define CMD_WRSR (0x01) /* Write Status Register */
-#define CMD_PP (0x02) /* Page Program */
-#define CMD_READ (0x03) /* Read Data */
-#define CMD_WRDI (0x04) /* Write Disable */
-#define CMD_RDSR1 (0x05) /* Read Status Register-1 */
-#define CMD_WREN (0x06) /* Write Enable */
-#define CMD_FAST_READ (0x0B) /* Fast Read */
-#define CMD_ERASE_4K (0x20) /* Sector Erase:4K */
-#define CMD_RDSR2 (0x35) /* Read Status Register-2 */
-#define CMD_ERASE_32K (0x52) /* 32KB Block Erase */
-#define CMD_JEDEC_ID (0x9F) /* Read JEDEC ID */
-#define CMD_ERASE_full (0xC7) /* Chip Erase */
-#define CMD_ERASE_64K (0xD8) /* 64KB Block Erase */
-
-#define DUMMY (0xFF)
-
-static struct spi_flash_device spi_flash_device;
-
-static void flash_lock(struct spi_flash_device * flash_device)
-{
- rt_mutex_take(&flash_device->lock, RT_WAITING_FOREVER);
-}
-
-static void flash_unlock(struct spi_flash_device * flash_device)
-{
- rt_mutex_release(&flash_device->lock);
-}
-
-static uint8_t w25qxx_read_status(void)
-{
- return rt_spi_sendrecv8(spi_flash_device.rt_spi_device, CMD_RDSR1);
-}
-
-static void w25qxx_wait_busy(void)
-{
- while( w25qxx_read_status() & (0x01));
-}
-
-/** \brief read [size] byte from [offset] to [buffer]
- *
- * \param offset uint32_t unit : byte
- * \param buffer uint8_t*
- * \param size uint32_t unit : byte
- * \return uint32_t byte for read
- *
- */
-static uint32_t w25qxx_read(uint32_t offset, uint8_t * buffer, uint32_t size)
-{
- uint8_t send_buffer[4];
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_READ;
- send_buffer[1] = (uint8_t)(offset>>16);
- send_buffer[2] = (uint8_t)(offset>>8);
- send_buffer[3] = (uint8_t)(offset);
-
- rt_spi_send_then_recv(spi_flash_device.rt_spi_device,
- send_buffer, 4,
- buffer, size);
-
- return size;
-}
-
-/** \brief write N page on [page]
- *
- * \param page_addr uint32_t unit : byte (4096 * N,1 page = 4096byte)
- * \param buffer const uint8_t*
- * \return uint32_t
- *
- */
-uint32_t w25qxx_page_write(uint32_t page_addr, const uint8_t* buffer)
-{
- uint32_t index;
- uint8_t send_buffer[4];
-
- RT_ASSERT((page_addr&0xFF) == 0); /* page addr must align to 256byte. */
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_ERASE_4K;
- send_buffer[1] = (page_addr >> 16);
- send_buffer[2] = (page_addr >> 8);
- send_buffer[3] = (page_addr);
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 4);
-
- w25qxx_wait_busy(); // wait erase done.
-
- for(index=0; index < (PAGE_SIZE / 256); index++)
- {
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_PP;
- send_buffer[1] = (uint8_t)(page_addr >> 16);
- send_buffer[2] = (uint8_t)(page_addr >> 8);
- send_buffer[3] = (uint8_t)(page_addr);
-
- rt_spi_send_then_send(spi_flash_device.rt_spi_device,
- send_buffer,
- 4,
- buffer,
- 256);
-
- buffer += 256;
- page_addr += 256;
- w25qxx_wait_busy();
- }
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- return PAGE_SIZE;
-}
-
-/* RT-Thread device interface */
-static rt_err_t w25qxx_flash_init(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_open(rt_device_t dev, rt_uint16_t oflag)
-{
- uint8_t send_buffer[3];
-
- flash_lock((struct spi_flash_device *)dev);
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_WRSR;
- send_buffer[1] = 0;
- send_buffer[2] = 0;
- rt_spi_send(spi_flash_device.rt_spi_device, send_buffer, 3);
-
- w25qxx_wait_busy();
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_close(rt_device_t dev)
-{
- return RT_EOK;
-}
-
-static rt_err_t w25qxx_flash_control(rt_device_t dev, int cmd, void *args)
-{
- RT_ASSERT(dev != RT_NULL);
-
- if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
- {
- struct rt_device_blk_geometry *geometry;
-
- geometry = (struct rt_device_blk_geometry *)args;
- if (geometry == RT_NULL) return -RT_ERROR;
-
- geometry->bytes_per_sector = spi_flash_device.geometry.bytes_per_sector;
- geometry->sector_count = spi_flash_device.geometry.sector_count;
- geometry->block_size = spi_flash_device.geometry.block_size;
- }
-
- return RT_EOK;
-}
-
-static rt_size_t w25qxx_flash_read(rt_device_t dev,
- rt_off_t pos,
- void* buffer,
- rt_size_t size)
-{
- flash_lock((struct spi_flash_device *)dev);
-
- w25qxx_read(pos*spi_flash_device.geometry.bytes_per_sector,
- buffer,
- size*spi_flash_device.geometry.bytes_per_sector);
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return size;
-}
-
-static rt_size_t w25qxx_flash_write(rt_device_t dev,
- rt_off_t pos,
- const void* buffer,
- rt_size_t size)
-{
- rt_size_t i = 0;
- rt_size_t block = size;
- const uint8_t * ptr = buffer;
-
- flash_lock((struct spi_flash_device *)dev);
-
- while(block--)
- {
- w25qxx_page_write((pos + i)*spi_flash_device.geometry.bytes_per_sector,
- ptr);
- ptr += PAGE_SIZE;
- i++;
- }
-
- flash_unlock((struct spi_flash_device *)dev);
-
- return size;
-}
-
-#ifdef RT_USING_DEVICE_OPS
-const static struct rt_device_ops w25qxx_device_ops =
-{
- w25qxx_flash_init,
- w25qxx_flash_open,
- w25qxx_flash_close,
- w25qxx_flash_read,
- w25qxx_flash_write,
- w25qxx_flash_control
-};
-#endif
-
-rt_err_t w25qxx_init(const char * flash_device_name, const char * spi_device_name)
-{
- struct rt_spi_device * rt_spi_device;
-
- /* initialize mutex */
- if (rt_mutex_init(&spi_flash_device.lock, spi_device_name, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- rt_kprintf("init sd lock mutex failed\n");
- return -RT_ENOSYS;
- }
-
- rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
- if(rt_spi_device == RT_NULL)
- {
- FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
- return -RT_ENOSYS;
- }
- spi_flash_device.rt_spi_device = rt_spi_device;
-
- /* config spi */
- {
- struct rt_spi_configuration cfg;
- cfg.data_width = 8;
- cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
- cfg.max_hz = 50 * 1000 * 1000; /* 50M */
- rt_spi_configure(spi_flash_device.rt_spi_device, &cfg);
- }
-
- /* init flash */
- {
- rt_uint8_t cmd;
- rt_uint8_t id_recv[3];
- uint16_t memory_type_capacity;
-
- flash_lock(&spi_flash_device);
-
- cmd = 0xFF; /* reset SPI FLASH, cancel all cmd in processing. */
- rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
-
- cmd = CMD_WRDI;
- rt_spi_send(spi_flash_device.rt_spi_device, &cmd, 1);
-
- /* read flash id */
- cmd = CMD_JEDEC_ID;
- rt_spi_send_then_recv(spi_flash_device.rt_spi_device, &cmd, 1, id_recv, 3);
-
- flash_unlock(&spi_flash_device);
-
- if(id_recv[0] != MF_ID)
- {
- FLASH_TRACE("Manufacturers ID error!\r\n");
- FLASH_TRACE("JEDEC Read-ID Data : %02X %02X %02X\r\n", id_recv[0], id_recv[1], id_recv[2]);
- return -RT_ENOSYS;
- }
-
- spi_flash_device.geometry.bytes_per_sector = 4096;
- spi_flash_device.geometry.block_size = 4096; /* block erase: 4k */
-
- /* get memory type and capacity */
- memory_type_capacity = id_recv[1];
- memory_type_capacity = (memory_type_capacity << 8) | id_recv[2];
-
- if(memory_type_capacity == MTC_W25Q128_BV)
- {
- FLASH_TRACE("W25Q128BV detection\r\n");
- spi_flash_device.geometry.sector_count = 4096;
- }
- else if(memory_type_capacity == MTC_W25Q64_BV_CV)
- {
- FLASH_TRACE("W25Q64BV or W25Q64CV detection\r\n");
- spi_flash_device.geometry.sector_count = 2048;
- }
- else if(memory_type_capacity == MTC_W25Q64_DW)
- {
- FLASH_TRACE("W25Q64DW detection\r\n");
- spi_flash_device.geometry.sector_count = 2048;
- }
- else if(memory_type_capacity == MTC_W25Q32_BV)
- {
- FLASH_TRACE("W25Q32BV detection\r\n");
- spi_flash_device.geometry.sector_count = 1024;
- }
- else if(memory_type_capacity == MTC_W25Q32_DW)
- {
- FLASH_TRACE("W25Q32DW detection\r\n");
- spi_flash_device.geometry.sector_count = 1024;
- }
- else if(memory_type_capacity == MTC_W25Q16_BV_CL_CV)
- {
- FLASH_TRACE("W25Q16BV or W25Q16CL or W25Q16CV detection\r\n");
- spi_flash_device.geometry.sector_count = 512;
- }
- else if(memory_type_capacity == MTC_W25Q16_DW)
- {
- FLASH_TRACE("W25Q16DW detection\r\n");
- spi_flash_device.geometry.sector_count = 512;
- }
- else if(memory_type_capacity == MTC_W25Q80_BV)
- {
- FLASH_TRACE("W25Q80BV detection\r\n");
- spi_flash_device.geometry.sector_count = 256;
- }
- else
- {
- FLASH_TRACE("Memory Capacity error!\r\n");
- return -RT_ENOSYS;
- }
- }
-
- /* register device */
- spi_flash_device.flash_device.type = RT_Device_Class_Block;
-#ifdef RT_USING_DEVICE_OPS
- spi_flash_device.flash_device.ops = &w25qxx_device_ops;
-#else
- spi_flash_device.flash_device.init = w25qxx_flash_init;
- spi_flash_device.flash_device.open = w25qxx_flash_open;
- spi_flash_device.flash_device.close = w25qxx_flash_close;
- spi_flash_device.flash_device.read = w25qxx_flash_read;
- spi_flash_device.flash_device.write = w25qxx_flash_write;
- spi_flash_device.flash_device.control = w25qxx_flash_control;
-#endif
- /* no private */
- spi_flash_device.flash_device.user_data = RT_NULL;
-
- rt_device_register(&spi_flash_device.flash_device, flash_device_name,
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
-
- return RT_EOK;
-}
diff --git a/components/drivers/spi/spi_flash_w25qxx.h b/components/drivers/spi/spi_flash_w25qxx.h
deleted file mode 100644
index 14837bc87c..0000000000
--- a/components/drivers/spi/spi_flash_w25qxx.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- * 2012-08-23 aozima add flash lock.
- */
-
-#ifndef SPI_FLASH_W25QXX_H_INCLUDED
-#define SPI_FLASH_W25QXX_H_INCLUDED
-
-#include <rtthread.h>
-
-extern rt_err_t w25qxx_init(const char * flash_device_name,
- const char * spi_device_name);
-
-#endif // SPI_FLASH_W25QXX_H_INCLUDED
diff --git a/components/drivers/spi/spi_flash_w25qxx_mtd.c b/components/drivers/spi/spi_flash_w25qxx_mtd.c
deleted file mode 100644
index 9f1ef802f6..0000000000
--- a/components/drivers/spi/spi_flash_w25qxx_mtd.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- */
-#include <rtthread.h>
-#include <rtdevice.h>
-
-#include "spi_flash.h"
-#include "spi_flash_w25qxx_mtd.h"
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define FLASH_DEBUG
-
-#ifdef FLASH_DEBUG
-#define FLASH_TRACE printf
-#else
-#define FLASH_TRACE(...)
-#endif /* #ifdef FLASH_DEBUG */
-
-/* JEDEC Manufacturer’s ID */
-#define MF_ID (0xEF)
-/* JEDEC Device ID: Memory type and Capacity */
-#define MTC_W25Q80_BV (0x4014) /* W25Q80BV */
-#define MTC_W25Q16_BV_CL_CV (0x4015) /* W25Q16BV W25Q16CL W25Q16CV */
-#define MTC_W25Q16_DW (0x6015) /* W25Q16DW */
-#define MTC_W25Q32_BV (0x4016) /* W25Q32BV */
-#define MTC_W25Q32_DW (0x6016) /* W25Q32DW */
-#define MTC_W25Q64_BV_CV (0x4017) /* W25Q64BV W25Q64CV */
-#define MTC_W25Q64_DW (0x4017) /* W25Q64DW */
-#define MTC_W25Q128_BV (0x4018) /* W25Q128BV */
-#define MTC_W25Q256_FV (TBD) /* W25Q256FV */
-
-#define MTC_W25X80 (0x3014)
-
-/* command list */
-#define CMD_WRSR (0x01) /* Write Status Register */
-#define CMD_PP (0x02) /* Page Program */
-#define CMD_READ (0x03) /* Read Data */
-#define CMD_WRDI (0x04) /* Write Disable */
-#define CMD_RDSR1 (0x05) /* Read Status Register-1 */
-#define CMD_WREN (0x06) /* Write Enable */
-#define CMD_FAST_READ (0x0B) /* Fast Read */
-#define CMD_ERASE_4K (0x20) /* Sector Erase:4K */
-#define CMD_RDSR2 (0x35) /* Read Status Register-2 */
-#define CMD_ERASE_32K (0x52) /* 32KB Block Erase */
-#define CMD_JEDEC_ID (0x9F) /* Read JEDEC ID */
-#define CMD_ERASE_full (0xC7) /* Chip Erase */
-#define CMD_ERASE_64K (0xD8) /* 64KB Block Erase */
-#define CMD_MANU_ID (0x90)
-
-#define DUMMY (0xFF)
-
-#define FLASH_ERASE_CMD CMD_ERASE_4K
-#define FLASH_BLOCK_SIZE 4096
-#define FLASH_PAGE_SIZE 256
-
-static void w25qxx_lock(struct rt_mtd_nor_device *device)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- rt_mutex_take(&mtd->lock, RT_WAITING_FOREVER);
-}
-
-static void w25qxx_unlock(struct rt_mtd_nor_device *device)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- rt_mutex_release(&mtd->lock);
-}
-
-static rt_uint8_t w25qxx_read_status(struct rt_mtd_nor_device *device)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- return rt_spi_sendrecv8(mtd->rt_spi_device, CMD_RDSR1);
-}
-
-static void w25qxx_wait_busy(struct rt_mtd_nor_device *device)
-{
- while( w25qxx_read_status(device) & (0x01));
-}
-
-static rt_err_t w25qxx_read_id(struct rt_mtd_nor_device *device)
-{
- rt_uint8_t cmd;
- rt_uint8_t id_recv[3];
-
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
-
- w25qxx_lock(device);
-
- cmd = 0xFF; /* reset SPI FLASH, cancel all cmd in processing. */
- rt_spi_send(mtd->rt_spi_device, &cmd, 1);
-
- cmd = CMD_WRDI;
- rt_spi_send(mtd->rt_spi_device, &cmd, 1);
-
- /* read flash id */
- cmd = CMD_JEDEC_ID;
- rt_spi_send_then_recv(mtd->rt_spi_device, &cmd, 1, id_recv, 3);
-
- w25qxx_unlock(device);
-
- return (rt_uint32_t)(id_recv[0] << 16) | (id_recv[1] << 8) | id_recv[2];
-}
-
-static rt_size_t w25qxx_read(struct rt_mtd_nor_device *device, rt_off_t offset, rt_uint8_t *buffer, rt_size_t length)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- rt_uint8_t send_buffer[4];
-
- if((offset + length) > device->block_end * FLASH_BLOCK_SIZE)
- return 0;
-
-
- w25qxx_lock(device);
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
-
- send_buffer[0] = CMD_READ;
- send_buffer[1] = (rt_uint8_t)(offset>>16);
- send_buffer[2] = (rt_uint8_t)(offset>>8);
- send_buffer[3] = (rt_uint8_t)(offset);
- rt_spi_send_then_recv(mtd->rt_spi_device,
- send_buffer, 4,
- buffer, length);
-
- w25qxx_unlock(device);
- return length;
-}
-
-static rt_size_t w25qxx_write(struct rt_mtd_nor_device *device, rt_off_t offset, const rt_uint8_t *buffer, rt_size_t length)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- rt_uint8_t send_buffer[4];
- rt_uint8_t *write_ptr ;
- rt_size_t write_size,write_total;
-
- if((offset + length) > device->block_end * FLASH_BLOCK_SIZE)
- return 0;
-
- w25qxx_lock(device);
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
- w25qxx_wait_busy(device); // wait erase done.
-
- write_size = 0;
- write_total = 0;
- write_ptr = (rt_uint8_t *)buffer;
- while(write_total < length)
- {
- send_buffer[0] = CMD_WREN;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
-
- //write first page...
- send_buffer[0] = CMD_PP;
- send_buffer[1] = (rt_uint8_t)(offset >> 16);
- send_buffer[2] = (rt_uint8_t)(offset >> 8);
- send_buffer[3] = (rt_uint8_t)(offset);
-
- //address % FLASH_PAGE_SIZE + length
- if(((offset & (FLASH_PAGE_SIZE - 1)) + (length - write_total)) > FLASH_PAGE_SIZE)
- {
- write_size = FLASH_PAGE_SIZE - (offset & (FLASH_PAGE_SIZE - 1));
- }
- else
- {
- write_size = (length - write_total);
- }
-
- rt_spi_send_then_send(mtd->rt_spi_device,
- send_buffer, 4,
- write_ptr + write_total, write_size);
- w25qxx_wait_busy(device);
-
-
- offset += write_size;
- write_total += write_size;
- }
-
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
-
- w25qxx_unlock(device);
-
- return length;
-}
-
-static rt_err_t w25qxx_erase_block(struct rt_mtd_nor_device *device, rt_off_t offset, rt_uint32_t length)
-{
- struct spi_flash_mtd *mtd = (struct spi_flash_mtd *)device;
- rt_uint8_t send_buffer[4];
- rt_uint32_t erase_size = 0;
-
- //offset must be ALIGN_DOWN to BLOCKSIZE
- if(offset != RT_ALIGN_DOWN(offset,FLASH_BLOCK_SIZE))
- return 0;
-
- if((offset + length) > device->block_end * FLASH_BLOCK_SIZE)
- return 0;
-
- /* check length must align to block size */
- if(length % device->block_size != 0)
- {
- rt_kprintf("param length = %d ,error\n",length);
- return 0;
- }
-
- w25qxx_lock(device);
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
- w25qxx_wait_busy(device); // wait erase done.
- while (erase_size < length)
- {
- send_buffer[0] = CMD_ERASE_4K;
- send_buffer[1] = (rt_uint8_t) (offset >> 16);
- send_buffer[2] = (rt_uint8_t) (offset >> 8);
- send_buffer[3] = (rt_uint8_t) (offset);
- rt_spi_send(mtd->rt_spi_device, send_buffer, 4);
- w25qxx_wait_busy(device); // wait erase done.
-
- erase_size += 4096;
- offset += 4096;
- }
- send_buffer[0] = CMD_WRDI;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
-
- w25qxx_unlock(device);
- return RT_EOK;
-}
-
-const static struct rt_mtd_nor_driver_ops w25qxx_mtd_ops =
-{
- w25qxx_read_id,
- w25qxx_read,
- w25qxx_write,
- w25qxx_erase_block,
-};
-
-rt_err_t w25qxx_mtd_init(const char *mtd_name,const char * spi_device_name)
-{
- rt_err_t result = RT_EOK;
- rt_uint32_t id;
- rt_uint8_t send_buffer[3];
-
- struct rt_spi_device* rt_spi_device;
- struct spi_flash_mtd* mtd = (struct spi_flash_mtd *)rt_malloc(sizeof(struct spi_flash_mtd));
-
- RT_ASSERT(mtd != RT_NULL);
-
- /* initialize mutex */
- if (rt_mutex_init(&mtd->lock, mtd_name, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- FLASH_TRACE("init mtd lock mutex failed\n");
- result = -RT_ENOSYS;
-
- goto _error_exit;
- }
-
- rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
- if(rt_spi_device == RT_NULL)
- {
- FLASH_TRACE("spi device %s not found!\r\n", spi_device_name);
- result = -RT_ENOSYS;
-
- goto _error_exit;
- }
- mtd->rt_spi_device = rt_spi_device;
- /* config spi */
- {
- struct rt_spi_configuration cfg;
- cfg.data_width = 8;
- cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
- cfg.max_hz = 20 * 1000 * 1000; /* 20 */
- rt_spi_configure(rt_spi_device, &cfg);
- }
-
- /* Init Flash device */
- {
- w25qxx_lock(&mtd->mtd_device);
-
- send_buffer[0] = CMD_WREN;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 1);
- w25qxx_wait_busy(&mtd->mtd_device);
-
- send_buffer[0] = CMD_WRSR;
- send_buffer[1] = 0;
- send_buffer[2] = 0;
- rt_spi_send(mtd->rt_spi_device, send_buffer, 3);
- w25qxx_wait_busy(&mtd->mtd_device);
-
- w25qxx_unlock(&mtd->mtd_device);
- }
-
- id = w25qxx_read_id(&mtd->mtd_device);
-
- mtd->mtd_device.block_size = 4096;
- mtd->mtd_device.block_start = 0;
- switch(id & 0xFFFF)
- {
- case MTC_W25Q80_BV: /* W25Q80BV */
- mtd->mtd_device.block_end = 256;
- break;
- case MTC_W25Q16_BV_CL_CV: /* W25Q16BV W25Q16CL W25Q16CV */
- case MTC_W25Q16_DW: /* W25Q16DW */
- mtd->mtd_device.block_end = 512;
- break;
- case MTC_W25Q32_BV: /* W25Q32BV */
- case MTC_W25Q32_DW: /* W25Q32DW */
- mtd->mtd_device.block_end = 1024;
- break;
- case MTC_W25Q64_BV_CV: /* W25Q64BV W25Q64CV */
- mtd->mtd_device.block_end = 2048;
- break;
- case MTC_W25Q128_BV: /* W25Q128BV */
- mtd->mtd_device.block_end = 4086;
- break;
- }
- mtd->mtd_device.ops = &w25qxx_mtd_ops;
- rt_mtd_nor_register_device(mtd_name,&mtd->mtd_device);
-
- return RT_EOK;
-
-_error_exit:
- if(mtd != RT_NULL)
- rt_free(mtd);
- return result;
-}
diff --git a/components/drivers/spi/spi_flash_w25qxx_mtd.h b/components/drivers/spi/spi_flash_w25qxx_mtd.h
deleted file mode 100644
index 28f6828ffb..0000000000
--- a/components/drivers/spi/spi_flash_w25qxx_mtd.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2011-12-16 aozima the first version
- * 2012-08-23 aozima add flash lock.
- * 2017-02-11 urey add mtd fucntion
- */
-
-#ifndef SPI_FLASH_W25QXX_H_INCLUDED
-#define SPI_FLASH_W25QXX_H_INCLUDED
-
-#include <rtthread.h>
-
-extern rt_err_t w25qxx_mtd_init(const char *mtd_name,const char * spi_device_name);
-
-#endif // SPI_FLASH_W25QXX_H_INCLUDED
diff --git a/components/drivers/spi/spi_msd.c b/components/drivers/spi/spi_msd.c
index a109fd9488..191933e421 100644
--- a/components/drivers/spi/spi_msd.c
+++ b/components/drivers/spi/spi_msd.c
@@ -234,24 +234,30 @@ static rt_err_t _send_cmd(
else if (type == response_r2)
{
/* initial message */
+ /* Prevent non-aligned address access, use recv_buffer to receive data */
message.send_buf = RT_NULL;
- message.recv_buf = response + 1;
+ message.recv_buf = recv_buffer;
message.length = 1;
message.cs_take = message.cs_release = 0;
/* transfer message */
device->bus->ops->xfer(device, &message);
+ response[1] = recv_buffer[0];
}
else if ((type == response_r3) || (type == response_r7))
{
/* initial message */
message.send_buf = RT_NULL;
- message.recv_buf = response + 1;
+ message.recv_buf = recv_buffer;
message.length = 4;
message.cs_take = message.cs_release = 0;
/* transfer message */
device->bus->ops->xfer(device, &message);
+ response[1] = recv_buffer[0];
+ response[2] = recv_buffer[1];
+ response[3] = recv_buffer[2];
+ response[4] = recv_buffer[3];
}
else
{
diff --git a/components/drivers/src/dataqueue.c b/components/drivers/src/dataqueue.c
index 7553986b9f..bfe8e12573 100644
--- a/components/drivers/src/dataqueue.c
+++ b/components/drivers/src/dataqueue.c
@@ -13,6 +13,8 @@
#include <rtdevice.h>
#include <rthw.h>
+#define DATAQUEUE_MAGIC 0xbead0e0e
+
struct rt_data_item
{
const void *data_ptr;
@@ -26,14 +28,18 @@ rt_data_queue_init(struct rt_data_queue *queue,
void (*evt_notify)(struct rt_data_queue *queue, rt_uint32_t event))
{
RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(size > 0);
queue->evt_notify = evt_notify;
+ queue->magic = DATAQUEUE_MAGIC;
queue->size = size;
queue->lwm = lwm;
queue->get_index = 0;
queue->put_index = 0;
+ queue->is_empty = 1;
+ queue->is_full = 0;
rt_list_init(&(queue->suspended_push_list));
rt_list_init(&(queue->suspended_pop_list));
@@ -58,12 +64,13 @@ rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
rt_err_t result;
RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
result = RT_EOK;
thread = rt_thread_self();
level = rt_hw_interrupt_disable();
- while (queue->put_index - queue->get_index == queue->size)
+ while (queue->is_full)
{
/* queue is full */
if (timeout == 0)
@@ -104,9 +111,18 @@ rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
if (result != RT_EOK) goto __exit;
}
- queue->queue[queue->put_index % queue->size].data_ptr = data_ptr;
- queue->queue[queue->put_index % queue->size].data_size = data_size;
+ queue->queue[queue->put_index].data_ptr = data_ptr;
+ queue->queue[queue->put_index].data_size = data_size;
queue->put_index += 1;
+ if (queue->put_index == queue->size)
+ {
+ queue->put_index = 0;
+ }
+ queue->is_empty = 0;
+ if (queue->put_index == queue->get_index)
+ {
+ queue->is_full = 1;
+ }
/* there is at least one thread in suspended list */
if (!rt_list_isempty(&(queue->suspended_pop_list)))
@@ -145,8 +161,9 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
rt_ubase_t level;
rt_thread_t thread;
rt_err_t result;
-
+
RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
RT_ASSERT(data_ptr != RT_NULL);
RT_ASSERT(size != RT_NULL);
@@ -154,7 +171,7 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
thread = rt_thread_self();
level = rt_hw_interrupt_disable();
- while (queue->get_index == queue->put_index)
+ while (queue->is_empty)
{
/* queue is empty */
if (timeout == 0)
@@ -195,12 +212,20 @@ rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
goto __exit;
}
- *data_ptr = queue->queue[queue->get_index % queue->size].data_ptr;
- *size = queue->queue[queue->get_index % queue->size].data_size;
-
+ *data_ptr = queue->queue[queue->get_index].data_ptr;
+ *size = queue->queue[queue->get_index].data_size;
queue->get_index += 1;
+ if (queue->get_index == queue->size)
+ {
+ queue->get_index = 0;
+ }
+ queue->is_full = 0;
+ if (queue->put_index == queue->get_index)
+ {
+ queue->is_empty = 1;
+ }
- if ((queue->put_index - queue->get_index) <= queue->lwm)
+ if (rt_data_queue_len(queue) <= queue->lwm)
{
/* there is at least one thread in suspended list */
if (!rt_list_isempty(&(queue->suspended_push_list)))
@@ -244,20 +269,19 @@ rt_err_t rt_data_queue_peak(struct rt_data_queue *queue,
rt_size_t *size)
{
rt_ubase_t level;
-
+
RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
- level = rt_hw_interrupt_disable();
-
- if (queue->get_index == queue->put_index)
+ if (queue->is_empty)
{
- rt_hw_interrupt_enable(level);
-
return -RT_EEMPTY;
}
- *data_ptr = queue->queue[queue->get_index % queue->size].data_ptr;
- *size = queue->queue[queue->get_index % queue->size].data_size;
+ level = rt_hw_interrupt_disable();
+
+ *data_ptr = queue->queue[queue->get_index].data_ptr;
+ *size = queue->queue[queue->get_index].data_size;
rt_hw_interrupt_enable(level);
@@ -267,9 +291,21 @@ RTM_EXPORT(rt_data_queue_peak);
void rt_data_queue_reset(struct rt_data_queue *queue)
{
+ rt_ubase_t level;
struct rt_thread *thread;
- register rt_ubase_t temp;
+
+ RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
+
+ level = rt_hw_interrupt_disable();
+ queue->get_index = 0;
+ queue->put_index = 0;
+ queue->is_empty = 1;
+ queue->is_full = 0;
+
+ rt_hw_interrupt_enable(level);
+
rt_enter_critical();
/* wakeup all suspend threads */
@@ -277,7 +313,7 @@ void rt_data_queue_reset(struct rt_data_queue *queue)
while (!rt_list_isempty(&(queue->suspended_pop_list)))
{
/* disable interrupt */
- temp = rt_hw_interrupt_disable();
+ level = rt_hw_interrupt_disable();
/* get next suspend thread */
thread = rt_list_entry(queue->suspended_pop_list.next,
@@ -294,14 +330,14 @@ void rt_data_queue_reset(struct rt_data_queue *queue)
rt_thread_resume(thread);
/* enable interrupt */
- rt_hw_interrupt_enable(temp);
+ rt_hw_interrupt_enable(level);
}
/* resume on push list */
while (!rt_list_isempty(&(queue->suspended_push_list)))
{
/* disable interrupt */
- temp = rt_hw_interrupt_disable();
+ level = rt_hw_interrupt_disable();
/* get next suspend thread */
thread = rt_list_entry(queue->suspended_push_list.next,
@@ -318,10 +354,61 @@ void rt_data_queue_reset(struct rt_data_queue *queue)
rt_thread_resume(thread);
/* enable interrupt */
- rt_hw_interrupt_enable(temp);
+ rt_hw_interrupt_enable(level);
}
rt_exit_critical();
rt_schedule();
}
RTM_EXPORT(rt_data_queue_reset);
+
+rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue)
+{
+ rt_ubase_t level;
+
+ RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
+
+ /* wakeup all suspend threads */
+ rt_data_queue_reset(queue);
+
+ level = rt_hw_interrupt_disable();
+ queue->magic = 0;
+ rt_hw_interrupt_enable(level);
+
+ rt_free(queue->queue);
+
+ return RT_EOK;
+}
+RTM_EXPORT(rt_data_queue_deinit);
+
+rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue)
+{
+ rt_ubase_t level;
+ rt_int16_t len;
+
+ RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);
+
+ if (queue->is_empty)
+ {
+ return 0;
+ }
+
+ level = rt_hw_interrupt_disable();
+
+ if (queue->put_index > queue->get_index)
+ {
+ len = queue->put_index - queue->get_index;
+ }
+ else
+ {
+ len = queue->size + queue->put_index - queue->get_index;
+ }
+
+ rt_hw_interrupt_enable(level);
+
+ return len;
+}
+RTM_EXPORT(rt_data_queue_len);
+
diff --git a/components/drivers/src/pipe.c b/components/drivers/src/pipe.c
index 065fd21dc1..2a7e143f6c 100644
--- a/components/drivers/src/pipe.c
+++ b/components/drivers/src/pipe.c
@@ -19,6 +19,7 @@
static int pipe_fops_open(struct dfs_fd *fd)
{
+ int rc = 0;
rt_device_t device;
rt_pipe_t *pipe;
@@ -31,6 +32,11 @@ static int pipe_fops_open(struct dfs_fd *fd)
if (device->ref_count == 0)
{
pipe->fifo = rt_ringbuffer_create(pipe->bufsz);
+ if (pipe->fifo == RT_NULL)
+ {
+ rc = -RT_ENOMEM;
+ goto __exit;
+ }
}
switch (fd->flags & O_ACCMODE)
@@ -48,9 +54,10 @@ static int pipe_fops_open(struct dfs_fd *fd)
}
device->ref_count ++;
+__exit:
rt_mutex_release(&(pipe->lock));
- return 0;
+ return rc;
}
static int pipe_fops_close(struct dfs_fd *fd)
@@ -90,13 +97,20 @@ static int pipe_fops_close(struct dfs_fd *fd)
if (device->ref_count == 1)
{
- rt_ringbuffer_destroy(pipe->fifo);
+ if (pipe->fifo != RT_NULL)
+ rt_ringbuffer_destroy(pipe->fifo);
pipe->fifo = RT_NULL;
}
device->ref_count --;
rt_mutex_release(&(pipe->lock));
+ if (device->ref_count == 0 && pipe->is_named == RT_FALSE)
+ {
+ /* delete the unamed pipe */
+ rt_pipe_delete(device->parent.name);
+ }
+
return 0;
}
@@ -309,18 +323,29 @@ static const struct dfs_file_ops pipe_fops =
rt_err_t rt_pipe_open (rt_device_t device, rt_uint16_t oflag)
{
rt_pipe_t *pipe = (rt_pipe_t *)device;
+ rt_err_t ret = RT_EOK;
- if (device == RT_NULL) return -RT_EINVAL;
+ if (device == RT_NULL)
+ {
+ ret = -RT_EINVAL;
+ goto __exit;
+ }
+
rt_mutex_take(&(pipe->lock), RT_WAITING_FOREVER);
if (pipe->fifo == RT_NULL)
{
pipe->fifo = rt_ringbuffer_create(pipe->bufsz);
+ if (pipe->fifo == RT_NULL)
+ {
+ ret = -RT_ENOMEM;
+ }
}
rt_mutex_release(&(pipe->lock));
- return RT_EOK;
+__exit:
+ return ret;
}
rt_err_t rt_pipe_close (rt_device_t device)
@@ -419,10 +444,11 @@ rt_pipe_t *rt_pipe_create(const char *name, int bufsz)
rt_pipe_t *pipe;
rt_device_t dev;
- pipe = rt_malloc(sizeof(rt_pipe_t));
+ pipe = (rt_pipe_t *)rt_malloc(sizeof(rt_pipe_t));
if (pipe == RT_NULL) return RT_NULL;
rt_memset(pipe, 0, sizeof(rt_pipe_t));
+ pipe->is_named = RT_TRUE; /* initialize as a named pipe */
rt_mutex_init(&(pipe->lock), name, RT_IPC_FLAG_FIFO);
rt_wqueue_init(&(pipe->reader_queue));
rt_wqueue_init(&(pipe->writer_queue));
@@ -517,6 +543,7 @@ int pipe(int fildes[2])
return -1;
}
+ pipe->is_named = RT_FALSE; /* unamed pipe */
rt_snprintf(dev_name, sizeof(dev_name), "/dev/%s", dname);
fildes[0] = open(dev_name, O_RDONLY, 0);
if (fildes[0] < 0)
diff --git a/components/drivers/src/ringblk_buf.c b/components/drivers/src/ringblk_buf.c
index 74ced674fe..7d83149c5e 100644
--- a/components/drivers/src/ringblk_buf.c
+++ b/components/drivers/src/ringblk_buf.c
@@ -95,9 +95,9 @@ void rt_rbb_destroy(rt_rbb_t rbb)
{
RT_ASSERT(rbb);
- rt_free(rbb);
rt_free(rbb->buf);
rt_free(rbb->blk_set);
+ rt_free(rbb);
}
RTM_EXPORT(rt_rbb_destroy);
@@ -134,16 +134,16 @@ rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size)
{
rt_base_t level;
rt_size_t empty1 = 0, empty2 = 0;
- rt_rbb_blk_t head, tail, new = NULL;
+ rt_rbb_blk_t head, tail, new_rbb = NULL;
RT_ASSERT(rbb);
RT_ASSERT(blk_size < (1L << 24));
level = rt_hw_interrupt_disable();
- new = find_empty_blk_in_set(rbb);
+ new_rbb = find_empty_blk_in_set(rbb);
- if (rt_slist_len(&rbb->blk_list) < rbb->blk_max_num && new)
+ if (rt_slist_len(&rbb->blk_list) < rbb->blk_max_num && new_rbb)
{
if (rt_slist_len(&rbb->blk_list) > 0)
{
@@ -163,22 +163,22 @@ rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size)
if (empty1 >= blk_size)
{
- rt_slist_append(&rbb->blk_list, &new->list);
- new->status = RT_RBB_BLK_INITED;
- new->buf = tail->buf + tail->size;
- new->size = blk_size;
+ rt_slist_append(&rbb->blk_list, &new_rbb->list);
+ new_rbb->status = RT_RBB_BLK_INITED;
+ new_rbb->buf = tail->buf + tail->size;
+ new_rbb->size = blk_size;
}
else if (empty2 >= blk_size)
{
- rt_slist_append(&rbb->blk_list, &new->list);
- new->status = RT_RBB_BLK_INITED;
- new->buf = rbb->buf;
- new->size = blk_size;
+ rt_slist_append(&rbb->blk_list, &new_rbb->list);
+ new_rbb->status = RT_RBB_BLK_INITED;
+ new_rbb->buf = rbb->buf;
+ new_rbb->size = blk_size;
}
else
{
/* no space */
- new = NULL;
+ new_rbb = NULL;
}
}
else
@@ -194,35 +194,35 @@ rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size)
if (empty1 >= blk_size)
{
- rt_slist_append(&rbb->blk_list, &new->list);
- new->status = RT_RBB_BLK_INITED;
- new->buf = tail->buf + tail->size;
- new->size = blk_size;
+ rt_slist_append(&rbb->blk_list, &new_rbb->list);
+ new_rbb->status = RT_RBB_BLK_INITED;
+ new_rbb->buf = tail->buf + tail->size;
+ new_rbb->size = blk_size;
}
else
{
/* no space */
- new = NULL;
+ new_rbb = NULL;
}
}
}
else
{
/* the list is empty */
- rt_slist_append(&rbb->blk_list, &new->list);
- new->status = RT_RBB_BLK_INITED;
- new->buf = rbb->buf;
- new->size = blk_size;
+ rt_slist_append(&rbb->blk_list, &new_rbb->list);
+ new_rbb->status = RT_RBB_BLK_INITED;
+ new_rbb->buf = rbb->buf;
+ new_rbb->size = blk_size;
}
}
else
{
- new = NULL;
+ new_rbb = NULL;
}
rt_hw_interrupt_enable(level);
- return new;
+ return new_rbb;
}
RTM_EXPORT(rt_rbb_blk_alloc);
diff --git a/components/drivers/src/ringbuffer.c b/components/drivers/src/ringbuffer.c
index 2e078ae053..c6a491a7cc 100644
--- a/components/drivers/src/ringbuffer.c
+++ b/components/drivers/src/ringbuffer.c
@@ -332,14 +332,15 @@ struct rt_ringbuffer* rt_ringbuffer_create(rt_uint16_t size)
size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE);
- rb = rt_malloc(sizeof(struct rt_ringbuffer));
+ rb = (struct rt_ringbuffer *)rt_malloc(sizeof(struct rt_ringbuffer));
if (rb == RT_NULL)
goto exit;
- pool = rt_malloc(size);
+ pool = (rt_uint8_t *)rt_malloc(size);
if (pool == RT_NULL)
{
rt_free(rb);
+ rb = RT_NULL;
goto exit;
}
rt_ringbuffer_init(rb, pool, size);
diff --git a/components/drivers/src/workqueue.c b/components/drivers/src/workqueue.c
index 158ea8b69b..2e0280df3a 100644
--- a/components/drivers/src/workqueue.c
+++ b/components/drivers/src/workqueue.c
@@ -13,11 +13,14 @@
#include <rtdevice.h>
#ifdef RT_USING_HEAP
+
+static void _delayed_work_timeout_handler(void *parameter);
+
rt_inline rt_err_t _workqueue_work_completion(struct rt_workqueue *queue)
{
rt_err_t result;
-
- rt_enter_critical();
+
+ rt_enter_critical();
while (1)
{
/* try to take condition semaphore */
@@ -40,17 +43,17 @@ rt_inline rt_err_t _workqueue_work_completion(struct rt_workqueue *queue)
}
}
rt_exit_critical();
-
+
return result;
}
-static void _workqueue_thread_entry(void* parameter)
+static void _workqueue_thread_entry(void *parameter)
{
rt_base_t level;
- struct rt_work* work;
- struct rt_workqueue* queue;
+ struct rt_work *work;
+ struct rt_workqueue *queue;
- queue = (struct rt_workqueue*) parameter;
+ queue = (struct rt_workqueue *) parameter;
RT_ASSERT(queue != RT_NULL);
while (1)
@@ -67,6 +70,8 @@ static void _workqueue_thread_entry(void* parameter)
work = rt_list_entry(queue->work_list.next, struct rt_work, list);
rt_list_remove(&(work->list));
queue->work_current = work;
+ work->flags &= ~RT_WORK_STATE_PENDING;
+ work->workqueue = RT_NULL;
rt_hw_interrupt_enable(level);
/* do work */
@@ -81,11 +86,172 @@ static void _workqueue_thread_entry(void* parameter)
}
}
-struct rt_workqueue *rt_workqueue_create(const char* name, rt_uint16_t stack_size, rt_uint8_t priority)
+static rt_err_t _workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work)
+{
+ rt_base_t level;
+
+ level = rt_hw_interrupt_disable();
+ if (work->flags & RT_WORK_STATE_PENDING)
+ {
+ rt_hw_interrupt_enable(level);
+ return -RT_EBUSY;
+ }
+
+ if (queue->work_current == work)
+ {
+ rt_hw_interrupt_enable(level);
+ return -RT_EBUSY;
+ }
+
+ /* NOTE: the work MUST be initialized firstly */
+ rt_list_remove(&(work->list));
+
+ rt_list_insert_after(queue->work_list.prev, &(work->list));
+ work->flags |= RT_WORK_STATE_PENDING;
+
+ /* whether the workqueue is doing work */
+ if (queue->work_current == RT_NULL)
+ {
+ rt_hw_interrupt_enable(level);
+ /* resume work thread */
+ rt_thread_resume(queue->work_thread);
+ rt_schedule();
+ }
+ else
+ {
+ rt_hw_interrupt_enable(level);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work)
+{
+ rt_base_t level;
+
+ level = rt_hw_interrupt_disable();
+ if (queue->work_current == work)
+ {
+ rt_hw_interrupt_enable(level);
+ return -RT_EBUSY;
+ }
+ rt_list_remove(&(work->list));
+ work->flags &= ~RT_WORK_STATE_PENDING;
+ rt_hw_interrupt_enable(level);
+
+ return RT_EOK;
+}
+
+static rt_err_t _workqueue_cancel_delayed_work(struct rt_work *work)
+{
+ rt_base_t level;
+ int ret = RT_EOK;
+
+ if (!work->workqueue)
+ {
+ ret = -EINVAL;
+ goto __exit;
+ }
+
+ if (work->flags & RT_WORK_STATE_PENDING)
+ {
+ /* Remove from the queue if already submitted */
+ ret = _workqueue_cancel_work(work->workqueue, work);
+ if (ret)
+ {
+ goto __exit;
+ }
+ }
+ else
+ {
+ if (work->flags & RT_WORK_STATE_SUBMITTING)
+ {
+ level = rt_hw_interrupt_disable();
+ rt_timer_stop(&(work->timer));
+ rt_timer_detach(&(work->timer));
+ work->flags &= ~RT_WORK_STATE_SUBMITTING;
+ rt_hw_interrupt_enable(level);
+ }
+ }
+
+ level = rt_hw_interrupt_disable();
+ /* Detach from workqueue */
+ work->workqueue = RT_NULL;
+ work->flags &= ~(RT_WORK_STATE_PENDING);
+ rt_hw_interrupt_enable(level);
+
+__exit:
+ return ret;
+}
+
+static rt_err_t _workqueue_submit_delayed_work(struct rt_workqueue *queue,
+ struct rt_work *work, rt_tick_t ticks)
+{
+ rt_base_t level;
+ rt_err_t ret = RT_EOK;
+
+ /* Work cannot be active in multiple queues */
+ if (work->workqueue && work->workqueue != queue)
+ {
+ ret = -RT_EINVAL;
+ goto __exit;
+ }
+
+ /* Cancel if work has been submitted */
+ if (work->workqueue == queue)
+ {
+ ret = _workqueue_cancel_delayed_work(work);
+ if (ret < 0)
+ {
+ goto __exit;
+ }
+ }
+
+ level = rt_hw_interrupt_disable();
+ /* Attach workqueue so the timeout callback can submit it */
+ work->workqueue = queue;
+ rt_hw_interrupt_enable(level);
+
+ if (!ticks)
+ {
+ /* Submit work if no ticks is 0 */
+ ret = _workqueue_submit_work(work->workqueue, work);
+ }
+ else
+ {
+ level = rt_hw_interrupt_disable();
+ /* Add timeout */
+ work->flags |= RT_WORK_STATE_SUBMITTING;
+ rt_timer_init(&(work->timer), "work", _delayed_work_timeout_handler, work, ticks,
+ RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
+ rt_hw_interrupt_enable(level);
+ rt_timer_start(&(work->timer));
+ }
+
+__exit:
+ return ret;
+}
+
+static void _delayed_work_timeout_handler(void *parameter)
+{
+ struct rt_work *delayed_work;
+ rt_base_t level;
+
+ delayed_work = (struct rt_work *)parameter;
+ level = rt_hw_interrupt_disable();
+ rt_timer_stop(&(delayed_work->timer));
+ rt_timer_detach(&(delayed_work->timer));
+ delayed_work->flags &= ~RT_WORK_STATE_SUBMITTING;
+ delayed_work->type &= ~RT_WORK_TYPE_DELAYED;
+ rt_hw_interrupt_enable(level);
+ _workqueue_submit_work(delayed_work->workqueue, delayed_work);
+}
+
+struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_size, rt_uint8_t priority)
{
struct rt_workqueue *queue = RT_NULL;
- queue = (struct rt_workqueue*)RT_KERNEL_MALLOC(sizeof(struct rt_workqueue));
+ queue = (struct rt_workqueue *)RT_KERNEL_MALLOC(sizeof(struct rt_workqueue));
if (queue != RT_NULL)
{
/* initialize work list */
@@ -107,7 +273,7 @@ struct rt_workqueue *rt_workqueue_create(const char* name, rt_uint16_t stack_siz
return queue;
}
-rt_err_t rt_workqueue_destroy(struct rt_workqueue* queue)
+rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue)
{
RT_ASSERT(queue != RT_NULL);
@@ -117,37 +283,35 @@ rt_err_t rt_workqueue_destroy(struct rt_workqueue* queue)
return RT_EOK;
}
-rt_err_t rt_workqueue_dowork(struct rt_workqueue* queue, struct rt_work* work)
+rt_err_t rt_workqueue_dowork(struct rt_workqueue *queue, struct rt_work *work)
{
- rt_base_t level;
RT_ASSERT(queue != RT_NULL);
RT_ASSERT(work != RT_NULL);
- level = rt_hw_interrupt_disable();
- if (queue->work_current == work)
- {
- rt_hw_interrupt_enable(level);
- return -RT_EBUSY;
- }
+ return _workqueue_submit_work(queue, work);
+}
- /* NOTE: the work MUST be initialized firstly */
- rt_list_remove(&(work->list));
+rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work, rt_tick_t time)
+{
+ RT_ASSERT(queue != RT_NULL);
+ RT_ASSERT(work != RT_NULL);
- rt_list_insert_after(queue->work_list.prev, &(work->list));
- /* whether the workqueue is doing work */
- if (queue->work_current == RT_NULL)
+ if (time > 0)
{
- rt_hw_interrupt_enable(level);
- /* resume work thread */
- rt_thread_resume(queue->work_thread);
- rt_schedule();
+ work->type |= RT_WORK_TYPE_DELAYED;
}
- else rt_hw_interrupt_enable(level);
- return RT_EOK;
+ if (work->type & RT_WORK_TYPE_DELAYED)
+ {
+ return _workqueue_submit_delayed_work(queue, work, time);
+ }
+ else
+ {
+ return _workqueue_submit_work(queue, work);
+ }
}
-rt_err_t rt_workqueue_critical_work(struct rt_workqueue* queue, struct rt_work* work)
+rt_err_t rt_workqueue_critical_work(struct rt_workqueue *queue, struct rt_work *work)
{
rt_base_t level;
RT_ASSERT(queue != RT_NULL);
@@ -176,26 +340,22 @@ rt_err_t rt_workqueue_critical_work(struct rt_workqueue* queue, struct rt_work*
return RT_EOK;
}
-rt_err_t rt_workqueue_cancel_work(struct rt_workqueue* queue, struct rt_work* work)
+rt_err_t rt_workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work)
{
- rt_base_t level;
-
RT_ASSERT(queue != RT_NULL);
RT_ASSERT(work != RT_NULL);
- level = rt_hw_interrupt_disable();
- if (queue->work_current == work)
+ if (work->type & RT_WORK_TYPE_DELAYED)
{
- rt_hw_interrupt_enable(level);
- return -RT_EBUSY;
+ return _workqueue_cancel_delayed_work(work);
+ }
+ else
+ {
+ return _workqueue_cancel_work(queue, work);
}
- rt_list_remove(&(work->list));
- rt_hw_interrupt_enable(level);
-
- return RT_EOK;
}
-rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue* queue, struct rt_work* work)
+rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue *queue, struct rt_work *work)
{
rt_base_t level;
@@ -212,12 +372,13 @@ rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue* queue, struct rt_wor
{
rt_list_remove(&(work->list));
}
+ work->flags &= ~RT_WORK_STATE_PENDING;
rt_hw_interrupt_enable(level);
return RT_EOK;
}
-rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue* queue)
+rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue *queue)
{
struct rt_list_node *node, *next;
RT_ASSERT(queue != RT_NULL);
@@ -233,5 +394,36 @@ rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue* queue)
return RT_EOK;
}
-#endif
+void rt_delayed_work_init(struct rt_delayed_work *work, void (*work_func)(struct rt_work *work,
+ void *work_data), void *work_data)
+{
+ rt_work_init(&work->work, work_func, work_data);
+}
+
+#ifdef RT_USING_SYSTEM_WORKQUEUE
+static struct rt_workqueue *sys_workq;
+
+rt_err_t rt_work_submit(struct rt_work *work, rt_tick_t time)
+{
+ return rt_workqueue_submit_work(sys_workq, work, time);
+}
+
+rt_err_t rt_work_cancel(struct rt_work *work)
+{
+ return rt_workqueue_cancel_work(sys_workq, work);
+}
+
+int rt_work_sys_workqueue_init(void)
+{
+ if (sys_workq != RT_NULL)
+ return 0;
+
+ sys_workq = rt_workqueue_create("sys_work", RT_SYSTEM_WORKQUEUE_STACKSIZE,
+ RT_SYSTEM_WORKQUEUE_PRIORITY);
+ return RT_EOK;
+}
+
+INIT_DEVICE_EXPORT(rt_work_sys_workqueue_init);
+#endif
+#endif
diff --git a/components/drivers/touch/SConscript b/components/drivers/touch/SConscript
new file mode 100644
index 0000000000..f370b2aba6
--- /dev/null
+++ b/components/drivers/touch/SConscript
@@ -0,0 +1,11 @@
+# SConscript for touch framework
+
+from building import *
+
+cwd = GetCurrentDir()
+src = ['touch.c']
+CPPPATH = [cwd, cwd + '/../include']
+
+group = DefineGroup('Touch', src, depend = ['RT_USING_TOUCH', 'RT_USING_DEVICE'], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/components/drivers/touch/touch.c b/components/drivers/touch/touch.c
new file mode 100644
index 0000000000..80ba6378bb
--- /dev/null
+++ b/components/drivers/touch/touch.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-20 tyustli the first version
+ */
+
+#include "touch.h"
+#include <string.h>
+
+#define DBG_TAG "touch"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+/* ISR for touch interrupt */
+static void irq_callback(void *args)
+{
+ rt_touch_t touch;
+
+ touch = (rt_touch_t)args;
+
+ if (touch->parent.rx_indicate == RT_NULL)
+ {
+ return;
+ }
+
+ if (touch->irq_handle != RT_NULL)
+ {
+ touch->irq_handle(touch);
+ }
+
+ touch->parent.rx_indicate(&touch->parent, 1);
+}
+
+/* touch interrupt initialization function */
+static rt_err_t rt_touch_irq_init(rt_touch_t touch)
+{
+ if (touch->config.irq_pin.pin == RT_PIN_NONE)
+ {
+ return -RT_EINVAL;
+ }
+
+ rt_pin_mode(touch->config.irq_pin.pin, touch->config.irq_pin.mode);
+
+ if (touch->config.irq_pin.mode == PIN_MODE_INPUT_PULLDOWN)
+ {
+ rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_RISING, irq_callback, (void *)touch);
+ }
+ else if (touch->config.irq_pin.mode == PIN_MODE_INPUT_PULLUP)
+ {
+ rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_FALLING, irq_callback, (void *)touch);
+ }
+ else if (touch->config.irq_pin.mode == PIN_MODE_INPUT)
+ {
+ rt_pin_attach_irq(touch->config.irq_pin.pin, PIN_IRQ_MODE_RISING_FALLING, irq_callback, (void *)touch);
+ }
+
+ rt_pin_irq_enable(touch->config.irq_pin.pin, PIN_IRQ_ENABLE);
+
+ return RT_EOK;
+}
+
+/* touch interrupt enable */
+static void rt_touch_irq_enable(rt_touch_t touch)
+{
+ if (touch->config.irq_pin.pin != RT_PIN_NONE)
+ {
+ rt_pin_irq_enable(touch->config.irq_pin.pin, RT_TRUE);
+ }
+}
+
+/* touch interrupt disable */
+static void rt_touch_irq_disable(rt_touch_t touch)
+{
+ if (touch->config.irq_pin.pin != RT_PIN_NONE)
+ {
+ rt_pin_irq_enable(touch->config.irq_pin.pin, RT_FALSE);
+ }
+}
+
+static rt_err_t rt_touch_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ rt_touch_t touch;
+ RT_ASSERT(dev != RT_NULL);
+ touch = (rt_touch_t)dev;
+
+ if (oflag & RT_DEVICE_FLAG_INT_RX && dev->flag & RT_DEVICE_FLAG_INT_RX)
+ {
+ /* Initialization touch interrupt */
+ rt_touch_irq_init(touch);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_touch_close(rt_device_t dev)
+{
+ rt_touch_t touch;
+ RT_ASSERT(dev != RT_NULL);
+ touch = (rt_touch_t)dev;
+
+ /* touch disable interrupt */
+ rt_touch_irq_disable(touch);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_touch_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t len)
+{
+ rt_touch_t touch;
+ rt_size_t result = 0;
+ RT_ASSERT(dev != RT_NULL);
+ touch = (rt_touch_t)dev;
+
+ if (buf == NULL || len == 0)
+ {
+ return 0;
+ }
+
+ result = touch->ops->touch_readpoint(touch, buf, len);
+
+ return result;
+}
+
+static rt_err_t rt_touch_control(rt_device_t dev, int cmd, void *args)
+{
+ rt_touch_t touch;
+ rt_err_t result = RT_EOK;
+ RT_ASSERT(dev != RT_NULL);
+ touch = (rt_touch_t)dev;
+
+ switch (cmd)
+ {
+ case RT_TOUCH_CTRL_GET_ID:
+ if (args)
+ {
+ result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_GET_ID, args);
+ }
+ else
+ {
+ result = -RT_ERROR;
+ }
+
+ break;
+ case RT_TOUCH_CTRL_GET_INFO:
+ if (args)
+ {
+ result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_GET_INFO, args);
+ }
+ else
+ {
+ result = -RT_ERROR;
+ }
+
+ break;
+ case RT_TOUCH_CTRL_SET_MODE:
+ result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_SET_MODE, args);
+
+ if (result == RT_EOK)
+ {
+ rt_uint16_t mode;
+ mode = *(rt_uint16_t*)args;
+ if (mode == RT_DEVICE_FLAG_INT_RX)
+ {
+ rt_touch_irq_enable(touch); /* enable interrupt */
+ }
+ }
+
+ break;
+ case RT_TOUCH_CTRL_SET_X_RANGE:
+ result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_SET_X_RANGE, args);
+
+ if (result == RT_EOK)
+ {
+ touch->info.range_x = *(rt_int32_t *)args;
+ LOG_D("set x coordinate range :%d\n", touch->info.range_x);
+ }
+
+ break;
+ case RT_TOUCH_CTRL_SET_Y_RANGE:
+ result = touch->ops->touch_control(touch, RT_TOUCH_CTRL_SET_Y_RANGE, args);
+
+ if (result == RT_EOK)
+ {
+ touch->info.range_y = *(rt_uint32_t *)args;
+ LOG_D("set y coordinate range :%d \n", touch->info.range_x);
+ }
+
+ break;
+ case RT_TOUCH_CTRL_DISABLE_INT:
+ rt_touch_irq_disable(touch);
+ break;
+ case RT_TOUCH_CTRL_ENABLE_INT:
+ rt_touch_irq_enable(touch);
+ break;
+ default:
+ return -RT_ERROR;
+ }
+
+ return result;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops rt_touch_ops =
+{
+ RT_NULL,
+ rt_touch_open,
+ rt_touch_close,
+ rt_touch_read,
+ RT_NULL,
+ rt_touch_control
+};
+#endif
+
+/*
+ * touch register
+ */
+int rt_hw_touch_register(rt_touch_t touch,
+ const char *name,
+ rt_uint32_t flag,
+ void *data)
+{
+ rt_int8_t result;
+ rt_device_t device;
+ RT_ASSERT(touch != RT_NULL);
+
+ device = &touch->parent;
+
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = &rt_touch_ops;
+#else
+ device->init = RT_NULL;
+ device->open = rt_touch_open;
+ device->close = rt_touch_close;
+ device->read = rt_touch_read;
+ device->write = RT_NULL;
+ device->control = rt_touch_control;
+#endif
+ device->type = RT_Device_Class_Touch;
+ device->rx_indicate = RT_NULL;
+ device->tx_complete = RT_NULL;
+ device->user_data = data;
+
+ result = rt_device_register(device, name, flag | RT_DEVICE_FLAG_STANDALONE);
+
+ if (result != RT_EOK)
+ {
+ LOG_E("rt_touch register err code: %d", result);
+ return result;
+ }
+
+ LOG_I("rt_touch init success");
+
+ return RT_EOK;
+}
diff --git a/components/drivers/touch/touch.h b/components/drivers/touch/touch.h
new file mode 100644
index 0000000000..c33fe17520
--- /dev/null
+++ b/components/drivers/touch/touch.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-05-20 tyustli the first version
+ */
+
+#ifndef __TOUCH_H__
+#define __TOUCH_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef RT_USING_RTC
+#define rt_touch_get_ts() time(RT_NULL) /* API for the touch to get the timestamp */
+#else
+#define rt_touch_get_ts() rt_tick_get() /* API for the touch to get the timestamp */
+#endif
+
+#define RT_PIN_NONE 0xFFFF /* RT PIN NONE */
+
+/* Touch vendor types */
+#define RT_TOUCH_VENDOR_UNKNOWN (0) /* unknown */
+#define RT_TOUCH_VENDOR_GT (1) /* GTxx series */
+#define RT_TOUCH_VENDOR_FT (2) /* FTxx series */
+
+/* Touch ic type*/
+#define RT_TOUCH_TYPE_NONE (0) /* touch ic none */
+#define RT_TOUCH_TYPE_CAPACITANCE (1) /* capacitance ic */
+#define RT_TOUCH_TYPE_RESISTANCE (2) /* resistance ic */
+
+/* Touch control cmd types */
+#define RT_TOUCH_CTRL_GET_ID (0) /* Get device id */
+#define RT_TOUCH_CTRL_GET_INFO (1) /* Get touch info */
+#define RT_TOUCH_CTRL_SET_MODE (2) /* Set touch's work mode. ex. RT_TOUCH_MODE_POLLING,RT_TOUCH_MODE_INT */
+#define RT_TOUCH_CTRL_SET_X_RANGE (3) /* Set x coordinate range */
+#define RT_TOUCH_CTRL_SET_Y_RANGE (4) /* Set y coordinate range */
+#define RT_TOUCH_CTRL_SET_X_TO_Y (5) /* Set X Y coordinate exchange */
+#define RT_TOUCH_CTRL_DISABLE_INT (6) /* Disable interrupt */
+#define RT_TOUCH_CTRL_ENABLE_INT (7) /* Enable interrupt */
+#define RT_TOUCH_CTRL_POWER_ON (8) /* Touch Power On */
+#define RT_TOUCH_CTRL_POWER_OFF (9) /* Touch Power Off */
+#define RT_TOUCH_CTRL_GET_STATUS (10) /* Get Touch Power Status */
+
+/* Touch event */
+#define RT_TOUCH_EVENT_NONE (0) /* Touch none */
+#define RT_TOUCH_EVENT_UP (1) /* Touch up event */
+#define RT_TOUCH_EVENT_DOWN (2) /* Touch down event */
+#define RT_TOUCH_EVENT_MOVE (3) /* Touch move event */
+
+struct rt_touch_info
+{
+ rt_uint8_t type; /* The touch type */
+ rt_uint8_t vendor; /* Vendor of touchs */
+ rt_uint8_t point_num; /* Support point num */
+ rt_int32_t range_x; /* X coordinate range */
+ rt_int32_t range_y; /* Y coordinate range */
+};
+
+struct rt_touch_config
+{
+ struct rt_device_pin_mode irq_pin; /* Interrupt pin, The purpose of this pin is to notification read data */
+ char *dev_name; /* The name of the communication device */
+ void *user_data;
+};
+
+typedef struct rt_touch_device *rt_touch_t;
+struct rt_touch_device
+{
+ struct rt_device parent; /* The standard device */
+ struct rt_touch_info info; /* The touch info data */
+ struct rt_touch_config config; /* The touch config data */
+
+ const struct rt_touch_ops *ops; /* The touch ops */
+ rt_err_t (*irq_handle)(rt_touch_t touch); /* Called when an interrupt is generated, registered by the driver */
+};
+
+struct rt_touch_data
+{
+ rt_uint8_t event; /* The touch event of the data */
+ rt_uint8_t track_id; /* Track id of point */
+ rt_uint8_t width; /* Point of width */
+ rt_uint16_t x_coordinate; /* Point of x coordinate */
+ rt_uint16_t y_coordinate; /* Point of y coordinate */
+ rt_tick_t timestamp; /* The timestamp when the data was received */
+};
+
+struct rt_touch_ops
+{
+ rt_size_t (*touch_readpoint)(struct rt_touch_device *touch, void *buf, rt_size_t touch_num);
+ rt_err_t (*touch_control)(struct rt_touch_device *touch, int cmd, void *arg);
+};
+
+int rt_hw_touch_register(rt_touch_t touch,
+ const char *name,
+ rt_uint32_t flag,
+ void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TOUCH_H__ */
diff --git a/components/drivers/usb/usbdevice/SConscript b/components/drivers/usb/usbdevice/SConscript
index be0b0c7b50..b6dfa8da10 100644
--- a/components/drivers/usb/usbdevice/SConscript
+++ b/components/drivers/usb/usbdevice/SConscript
@@ -3,7 +3,7 @@ from building import *
cwd = GetCurrentDir()
src = Split("""
-core/core.c
+core/usbdevice_core.c
core/usbdevice.c
""")
@@ -24,6 +24,12 @@ if GetDepend('RT_USB_DEVICE_RNDIS'):
if GetDepend('RT_USB_DEVICE_WINUSB'):
src += Glob('class/winusb.c')
+
+if GetDepend('RT_USB_DEVICE_AUDIO_MIC'):
+ src += Glob('class/audio_mic.c')
+
+if GetDepend('RT_USB_DEVICE_AUDIO_SPEAKER'):
+ src += Glob('class/audio_speaker.c')
CPPPATH = [cwd]
diff --git a/components/drivers/usb/usbdevice/class/audio.h b/components/drivers/usb/usbdevice/class/audio.h
new file mode 100644
index 0000000000..4bb8994b47
--- /dev/null
+++ b/components/drivers/usb/usbdevice/class/audio.h
@@ -0,0 +1,676 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * <linux/usb/audio.h> -- USB Audio definitions.
+ *
+ * Copyright (C) 2006 Thumtronics Pty Ltd.
+ * Developed for Thumtronics by Grey Innovation
+ * Ben Williamson <[email protected]>
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * License ("GPL") version 2, as published by the Free Software Foundation.
+ *
+ * This file holds USB constants and structures defined
+ * by the USB Device Class Definition for Audio Devices.
+ * Comments below reference relevant sections of that document:
+ *
+ * http://www.usb.org/developers/devclass_docs/audio10.pdf
+ *
+ * Types and defines in this file are either specific to version 1.0 of
+ * this standard or common for newer versions.
+ */
+
+#ifndef _UAPI__LINUX_USB_AUDIO_H
+#define _UAPI__LINUX_USB_AUDIO_H
+
+//#include <linux/types.h>
+#include <rtthread.h>
+
+typedef int8_t __s8;
+typedef uint8_t __u8;
+typedef int16_t __s16;
+typedef uint16_t __u16;
+typedef int32_t __s32;
+typedef uint32_t __u32;
+typedef int64_t __s64;
+typedef uint64_t __u64;
+
+#define UAC_USE_FEATURE_UNIT 0 /* Feature unit does not support */
+
+/*
+ * Below are truly Linux-specific types that should never collide with
+ * any application/library that wants linux/types.h.
+ */
+
+#ifdef __CHECKER__
+#define __bitwise__ __attribute__((bitwise))
+#else
+#define __bitwise__
+#endif
+#ifdef __CHECK_ENDIAN__
+#define __bitwise __bitwise__
+#else
+#define __bitwise
+#endif
+
+typedef __u16 __bitwise __le16;
+typedef __u16 __bitwise __be16;
+typedef __u32 __bitwise __le32;
+typedef __u32 __bitwise __be32;
+typedef __u64 __bitwise __le64;
+typedef __u64 __bitwise __be64;
+
+typedef __u16 __bitwise __sum16;
+typedef __u32 __bitwise __wsum;
+
+/* bInterfaceProtocol values to denote the version of the standard used */
+#define UAC_VERSION_1 0x00
+#define UAC_VERSION_2 0x20
+#define UAC_VERSION_3 0x30
+
+/* A.2 Audio Interface Subclass Codes */
+#define USB_SUBCLASS_AUDIOCONTROL 0x01
+#define USB_SUBCLASS_AUDIOSTREAMING 0x02
+#define USB_SUBCLASS_MIDISTREAMING 0x03
+
+/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
+#define UAC_HEADER 0x01
+#define UAC_INPUT_TERMINAL 0x02
+#define UAC_OUTPUT_TERMINAL 0x03
+#define UAC_MIXER_UNIT 0x04
+#define UAC_SELECTOR_UNIT 0x05
+#define UAC_FEATURE_UNIT 0x06
+#define UAC1_PROCESSING_UNIT 0x07
+#define UAC1_EXTENSION_UNIT 0x08
+
+/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
+#define UAC_AS_GENERAL 0x01
+#define UAC_FORMAT_TYPE 0x02
+#define UAC_FORMAT_SPECIFIC 0x03
+
+/* A.7 Processing Unit Process Types */
+#define UAC_PROCESS_UNDEFINED 0x00
+#define UAC_PROCESS_UP_DOWNMIX 0x01
+#define UAC_PROCESS_DOLBY_PROLOGIC 0x02
+#define UAC_PROCESS_STEREO_EXTENDER 0x03
+#define UAC_PROCESS_REVERB 0x04
+#define UAC_PROCESS_CHORUS 0x05
+#define UAC_PROCESS_DYN_RANGE_COMP 0x06
+
+/* A.8 Audio Class-Specific Endpoint Descriptor Subtypes */
+#define UAC_EP_GENERAL 0x01
+
+/* A.9 Audio Class-Specific Request Codes */
+#define UAC_SET_ 0x00
+#define UAC_GET_ 0x80
+
+#define UAC__CUR 0x1
+#define UAC__MIN 0x2
+#define UAC__MAX 0x3
+#define UAC__RES 0x4
+#define UAC__MEM 0x5
+
+#define UAC_SET_CUR (UAC_SET_ | UAC__CUR)
+#define UAC_GET_CUR (UAC_GET_ | UAC__CUR)
+#define UAC_SET_MIN (UAC_SET_ | UAC__MIN)
+#define UAC_GET_MIN (UAC_GET_ | UAC__MIN)
+#define UAC_SET_MAX (UAC_SET_ | UAC__MAX)
+#define UAC_GET_MAX (UAC_GET_ | UAC__MAX)
+#define UAC_SET_RES (UAC_SET_ | UAC__RES)
+#define UAC_GET_RES (UAC_GET_ | UAC__RES)
+#define UAC_SET_MEM (UAC_SET_ | UAC__MEM)
+#define UAC_GET_MEM (UAC_GET_ | UAC__MEM)
+
+#define UAC_GET_STAT 0xff
+
+/* A.10 Control Selector Codes */
+
+/* A.10.1 Terminal Control Selectors */
+#define UAC_TERM_COPY_PROTECT 0x01
+
+/* A.10.2 Feature Unit Control Selectors */
+#define UAC_FU_MUTE 0x01
+#define UAC_FU_VOLUME 0x02
+#define UAC_FU_BASS 0x03
+#define UAC_FU_MID 0x04
+#define UAC_FU_TREBLE 0x05
+#define UAC_FU_GRAPHIC_EQUALIZER 0x06
+#define UAC_FU_AUTOMATIC_GAIN 0x07
+#define UAC_FU_DELAY 0x08
+#define UAC_FU_BASS_BOOST 0x09
+#define UAC_FU_LOUDNESS 0x0a
+
+#define UAC_CONTROL_BIT(CS) (1 << ((CS) - 1))
+
+/* A.10.3.1 Up/Down-mix Processing Unit Controls Selectors */
+#define UAC_UD_ENABLE 0x01
+#define UAC_UD_MODE_SELECT 0x02
+
+/* A.10.3.2 Dolby Prologic (tm) Processing Unit Controls Selectors */
+#define UAC_DP_ENABLE 0x01
+#define UAC_DP_MODE_SELECT 0x02
+
+/* A.10.3.3 3D Stereo Extender Processing Unit Control Selectors */
+#define UAC_3D_ENABLE 0x01
+#define UAC_3D_SPACE 0x02
+
+/* A.10.3.4 Reverberation Processing Unit Control Selectors */
+#define UAC_REVERB_ENABLE 0x01
+#define UAC_REVERB_LEVEL 0x02
+#define UAC_REVERB_TIME 0x03
+#define UAC_REVERB_FEEDBACK 0x04
+
+/* A.10.3.5 Chorus Processing Unit Control Selectors */
+#define UAC_CHORUS_ENABLE 0x01
+#define UAC_CHORUS_LEVEL 0x02
+#define UAC_CHORUS_RATE 0x03
+#define UAC_CHORUS_DEPTH 0x04
+
+/* A.10.3.6 Dynamic Range Compressor Unit Control Selectors */
+#define UAC_DCR_ENABLE 0x01
+#define UAC_DCR_RATE 0x02
+#define UAC_DCR_MAXAMPL 0x03
+#define UAC_DCR_THRESHOLD 0x04
+#define UAC_DCR_ATTACK_TIME 0x05
+#define UAC_DCR_RELEASE_TIME 0x06
+
+/* A.10.4 Extension Unit Control Selectors */
+#define UAC_XU_ENABLE 0x01
+
+/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */
+#define UAC_MS_HEADER 0x01
+#define UAC_MIDI_IN_JACK 0x02
+#define UAC_MIDI_OUT_JACK 0x03
+
+/* MIDI - A.1 MS Class-Specific Endpoint Descriptor Subtypes */
+#define UAC_MS_GENERAL 0x01
+
+/* Terminals - 2.1 USB Terminal Types */
+#define UAC_TERMINAL_UNDEFINED 0x100
+#define UAC_TERMINAL_STREAMING 0x101
+#define UAC_TERMINAL_VENDOR_SPEC 0x1FF
+
+/* Terminal Control Selectors */
+/* 4.3.2 Class-Specific AC Interface Descriptor */
+struct uac1_ac_header_descriptor {
+ __u8 bLength; /* 8 + n */
+ __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
+ __u8 bDescriptorSubtype; /* UAC_MS_HEADER */
+ __le16 bcdADC; /* 0x0100 */
+ __le16 wTotalLength; /* includes Unit and Terminal desc. */
+ __u8 bInCollection; /* n */
+ __u8 baInterfaceNr[]; /* [n] */
+} __attribute__ ((packed));
+
+#define UAC_DT_AC_HEADER_SIZE(n) (8 + (n))
+
+/* As above, but more useful for defining your own descriptors: */
+#define DECLARE_UAC_AC_HEADER_DESCRIPTOR(n) \
+struct uac1_ac_header_descriptor_##n { \
+ __u8 bLength; \
+ __u8 bDescriptorType; \
+ __u8 bDescriptorSubtype; \
+ __le16 bcdADC; \
+ __le16 wTotalLength; \
+ __u8 bInCollection; \
+ __u8 baInterfaceNr[n]; \
+} __attribute__ ((packed))
+
+/* 4.3.2.1 Input Terminal Descriptor */
+struct uac_input_terminal_descriptor {
+ __u8 bLength; /* in bytes: 12 */
+ __u8 bDescriptorType; /* CS_INTERFACE descriptor type */
+ __u8 bDescriptorSubtype; /* INPUT_TERMINAL descriptor subtype */
+ __u8 bTerminalID; /* Constant uniquely terminal ID */
+ __le16 wTerminalType; /* USB Audio Terminal Types */
+ __u8 bAssocTerminal; /* ID of the Output Terminal associated */
+ __u8 bNrChannels; /* Number of logical output channels */
+ __le16 wChannelConfig;
+ __u8 iChannelNames;
+ __u8 iTerminal;
+} __attribute__ ((packed));
+
+#define UAC_DT_INPUT_TERMINAL_SIZE 12
+
+/* Terminals - 2.2 Input Terminal Types */
+#define UAC_INPUT_TERMINAL_UNDEFINED 0x200
+#define UAC_INPUT_TERMINAL_MICROPHONE 0x201
+#define UAC_INPUT_TERMINAL_DESKTOP_MICROPHONE 0x202
+#define UAC_INPUT_TERMINAL_PERSONAL_MICROPHONE 0x203
+#define UAC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE 0x204
+#define UAC_INPUT_TERMINAL_MICROPHONE_ARRAY 0x205
+#define UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY 0x206
+
+/* Terminals - control selectors */
+
+#define UAC_TERMINAL_CS_COPY_PROTECT_CONTROL 0x01
+
+/* 4.3.2.2 Output Terminal Descriptor */
+struct uac1_output_terminal_descriptor {
+ __u8 bLength; /* in bytes: 9 */
+ __u8 bDescriptorType; /* CS_INTERFACE descriptor type */
+ __u8 bDescriptorSubtype; /* OUTPUT_TERMINAL descriptor subtype */
+ __u8 bTerminalID; /* Constant uniquely terminal ID */
+ __le16 wTerminalType; /* USB Audio Terminal Types */
+ __u8 bAssocTerminal; /* ID of the Input Terminal associated */
+ __u8 bSourceID; /* ID of the connected Unit or Terminal*/
+ __u8 iTerminal;
+} __attribute__ ((packed));
+
+#define UAC_DT_OUTPUT_TERMINAL_SIZE 9
+
+/* Terminals - 2.3 Output Terminal Types */
+#define UAC_OUTPUT_TERMINAL_UNDEFINED 0x300
+#define UAC_OUTPUT_TERMINAL_SPEAKER 0x301
+#define UAC_OUTPUT_TERMINAL_HEADPHONES 0x302
+#define UAC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO 0x303
+#define UAC_OUTPUT_TERMINAL_DESKTOP_SPEAKER 0x304
+#define UAC_OUTPUT_TERMINAL_ROOM_SPEAKER 0x305
+#define UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER 0x306
+#define UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x307
+
+/* Terminals - 2.4 Bi-directional Terminal Types */
+#define UAC_BIDIR_TERMINAL_UNDEFINED 0x400
+#define UAC_BIDIR_TERMINAL_HANDSET 0x401
+#define UAC_BIDIR_TERMINAL_HEADSET 0x402
+#define UAC_BIDIR_TERMINAL_SPEAKER_PHONE 0x403
+#define UAC_BIDIR_TERMINAL_ECHO_SUPPRESSING 0x404
+#define UAC_BIDIR_TERMINAL_ECHO_CANCELING 0x405
+
+/* Set bControlSize = 2 as default setting */
+#define UAC_DT_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 2)
+
+/* As above, but more useful for defining your own descriptors: */
+#define DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(ch) \
+struct uac_feature_unit_descriptor_##ch { \
+ __u8 bLength; \
+ __u8 bDescriptorType; \
+ __u8 bDescriptorSubtype; \
+ __u8 bUnitID; \
+ __u8 bSourceID; \
+ __u8 bControlSize; \
+ __le16 bmaControls[ch + 1]; \
+ __u8 iFeature; \
+} __attribute__ ((packed))
+
+/* 4.3.2.3 Mixer Unit Descriptor */
+struct uac_mixer_unit_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bUnitID;
+ __u8 bNrInPins;
+ __u8 baSourceID[];
+} __attribute__ ((packed));
+
+static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *desc)
+{
+ return desc->baSourceID[desc->bNrInPins];
+}
+
+static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc,
+ int protocol)
+{
+ if (protocol == UAC_VERSION_1)
+ return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
+ desc->baSourceID[desc->bNrInPins + 1];
+ else
+ return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
+ (desc->baSourceID[desc->bNrInPins + 3] << 16) |
+ (desc->baSourceID[desc->bNrInPins + 2] << 8) |
+ (desc->baSourceID[desc->bNrInPins + 1]);
+}
+
+static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc,
+ int protocol)
+{
+ return (protocol == UAC_VERSION_1) ?
+ desc->baSourceID[desc->bNrInPins + 3] :
+ desc->baSourceID[desc->bNrInPins + 5];
+}
+
+static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
+ int protocol)
+{
+ switch (protocol) {
+ case UAC_VERSION_1:
+ return &desc->baSourceID[desc->bNrInPins + 4];
+ case UAC_VERSION_2:
+ return &desc->baSourceID[desc->bNrInPins + 6];
+ case UAC_VERSION_3:
+ return &desc->baSourceID[desc->bNrInPins + 2];
+ default:
+ return NULL;
+ }
+}
+
+static inline __u16 uac3_mixer_unit_wClusterDescrID(struct uac_mixer_unit_descriptor *desc)
+{
+ return (desc->baSourceID[desc->bNrInPins + 1] << 8) |
+ desc->baSourceID[desc->bNrInPins];
+}
+
+static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
+{
+ __u8 *raw = (__u8 *) desc;
+ return raw[desc->bLength - 1];
+}
+
+/* 4.3.2.4 Selector Unit Descriptor */
+struct uac_selector_unit_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bUintID;
+ __u8 bNrInPins;
+ __u8 baSourceID[];
+} __attribute__ ((packed));
+
+static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc)
+{
+ __u8 *raw = (__u8 *) desc;
+ return raw[desc->bLength - 1];
+}
+#if UAC_USE_FEATURE_UNIT
+/* 4.3.2.5 Feature Unit Descriptor */
+struct uac_feature_unit_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bUnitID;
+ __u8 bSourceID;
+ __u8 bControlSize;
+ __u8 bmaControls[0]; /* variable length */
+} __attribute__((packed));
+
+static inline __u8 uac_feature_unit_iFeature(struct uac_feature_unit_descriptor *desc)
+{
+ __u8 *raw = (__u8 *) desc;
+ return raw[desc->bLength - 1];
+}
+#endif
+/* 4.3.2.6 Processing Unit Descriptors */
+struct uac_processing_unit_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bUnitID;
+ __le16 wProcessType;
+ __u8 bNrInPins;
+ __u8 baSourceID[];
+} __attribute__ ((packed));
+
+static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_descriptor *desc)
+{
+ return desc->baSourceID[desc->bNrInPins];
+}
+
+static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ if (protocol == UAC_VERSION_1)
+ return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
+ desc->baSourceID[desc->bNrInPins + 1];
+ else
+ return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
+ (desc->baSourceID[desc->bNrInPins + 3] << 16) |
+ (desc->baSourceID[desc->bNrInPins + 2] << 8) |
+ (desc->baSourceID[desc->bNrInPins + 1]);
+}
+
+static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ return (protocol == UAC_VERSION_1) ?
+ desc->baSourceID[desc->bNrInPins + 3] :
+ desc->baSourceID[desc->bNrInPins + 5];
+}
+
+static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ switch (protocol) {
+ case UAC_VERSION_1:
+ return desc->baSourceID[desc->bNrInPins + 4];
+ case UAC_VERSION_2:
+ return 2; /* in UAC2, this value is constant */
+ case UAC_VERSION_3:
+ return 4; /* in UAC3, this value is constant */
+ default:
+ return 1;
+ }
+}
+
+static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ switch (protocol) {
+ case UAC_VERSION_1:
+ return &desc->baSourceID[desc->bNrInPins + 5];
+ case UAC_VERSION_2:
+ return &desc->baSourceID[desc->bNrInPins + 6];
+ case UAC_VERSION_3:
+ return &desc->baSourceID[desc->bNrInPins + 2];
+ default:
+ return NULL;
+ }
+}
+
+static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
+
+ switch (protocol) {
+ case UAC_VERSION_1:
+ case UAC_VERSION_2:
+ default:
+ return *(uac_processing_unit_bmControls(desc, protocol)
+ + control_size);
+ case UAC_VERSION_3:
+ return 0; /* UAC3 does not have this field */
+ }
+}
+
+static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ __u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
+
+ switch (protocol) {
+ case UAC_VERSION_1:
+ case UAC_VERSION_2:
+ default:
+ return uac_processing_unit_bmControls(desc, protocol)
+ + control_size + 1;
+ case UAC_VERSION_3:
+ return uac_processing_unit_bmControls(desc, protocol)
+ + control_size;
+ }
+}
+
+/*
+ * Extension Unit (XU) has almost compatible layout with Processing Unit, but
+ * on UAC2, it has a different bmControls size (bControlSize); it's 1 byte for
+ * XU while 2 bytes for PU. The last iExtension field is a one-byte index as
+ * well as iProcessing field of PU.
+ */
+static inline __u8 uac_extension_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ switch (protocol) {
+ case UAC_VERSION_1:
+ return desc->baSourceID[desc->bNrInPins + 4];
+ case UAC_VERSION_2:
+ return 1; /* in UAC2, this value is constant */
+ case UAC_VERSION_3:
+ return 4; /* in UAC3, this value is constant */
+ default:
+ return 1;
+ }
+}
+
+static inline __u8 uac_extension_unit_iExtension(struct uac_processing_unit_descriptor *desc,
+ int protocol)
+{
+ __u8 control_size = uac_extension_unit_bControlSize(desc, protocol);
+
+ switch (protocol) {
+ case UAC_VERSION_1:
+ case UAC_VERSION_2:
+ default:
+ return *(uac_processing_unit_bmControls(desc, protocol)
+ + control_size);
+ case UAC_VERSION_3:
+ return 0; /* UAC3 does not have this field */
+ }
+}
+
+/* 4.5.2 Class-Specific AS Interface Descriptor */
+struct uac1_as_header_descriptor {
+ __u8 bLength; /* in bytes: 7 */
+ __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
+ __u8 bDescriptorSubtype; /* AS_GENERAL */
+ __u8 bTerminalLink; /* Terminal ID of connected Terminal */
+ __u8 bDelay; /* Delay introduced by the data path */
+ __le16 wFormatTag; /* The Audio Data Format */
+} __attribute__ ((packed));
+
+#define UAC_DT_AS_HEADER_SIZE 7
+
+/* Formats - A.1.1 Audio Data Format Type I Codes */
+#define UAC_FORMAT_TYPE_I_UNDEFINED 0x0
+#define UAC_FORMAT_TYPE_I_PCM 0x1
+#define UAC_FORMAT_TYPE_I_PCM8 0x2
+#define UAC_FORMAT_TYPE_I_IEEE_FLOAT 0x3
+#define UAC_FORMAT_TYPE_I_ALAW 0x4
+#define UAC_FORMAT_TYPE_I_MULAW 0x5
+
+struct uac_format_type_i_continuous_descriptor {
+ __u8 bLength; /* in bytes: 8 + (ns * 3) */
+ __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
+ __u8 bDescriptorSubtype; /* FORMAT_TYPE */
+ __u8 bFormatType; /* FORMAT_TYPE_1 */
+ __u8 bNrChannels; /* physical channels in the stream */
+ __u8 bSubframeSize; /* */
+ __u8 bBitResolution;
+ __u8 bSamFreqType;
+ __u8 tLowerSamFreq[3];
+ __u8 tUpperSamFreq[3];
+} __attribute__ ((packed));
+
+#define UAC_FORMAT_TYPE_I_CONTINUOUS_DESC_SIZE 14
+
+struct uac_format_type_i_discrete_descriptor {
+ __u8 bLength; /* in bytes: 8 + (ns * 3) */
+ __u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
+ __u8 bDescriptorSubtype; /* FORMAT_TYPE */
+ __u8 bFormatType; /* FORMAT_TYPE_1 */
+ __u8 bNrChannels; /* physical channels in the stream */
+ __u8 bSubframeSize; /* */
+ __u8 bBitResolution;
+ __u8 bSamFreqType;
+ __u8 tSamFreq[][3];
+} __attribute__ ((packed));
+
+#define DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(n) \
+struct uac_format_type_i_discrete_descriptor_##n { \
+ __u8 bLength; \
+ __u8 bDescriptorType; \
+ __u8 bDescriptorSubtype; \
+ __u8 bFormatType; \
+ __u8 bNrChannels; \
+ __u8 bSubframeSize; \
+ __u8 bBitResolution; \
+ __u8 bSamFreqType; \
+ __u8 tSamFreq[n][3]; \
+} __attribute__ ((packed))
+
+#define UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(n) (8 + (n * 3))
+
+struct uac_format_type_i_ext_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bFormatType;
+ __u8 bSubslotSize;
+ __u8 bBitResolution;
+ __u8 bHeaderLength;
+ __u8 bControlSize;
+ __u8 bSideBandProtocol;
+} __attribute__((packed));
+
+/* Formats - Audio Data Format Type I Codes */
+
+#define UAC_FORMAT_TYPE_II_MPEG 0x1001
+#define UAC_FORMAT_TYPE_II_AC3 0x1002
+
+struct uac_format_type_ii_discrete_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bFormatType;
+ __le16 wMaxBitRate;
+ __le16 wSamplesPerFrame;
+ __u8 bSamFreqType;
+ __u8 tSamFreq[][3];
+} __attribute__((packed));
+
+struct uac_format_type_ii_ext_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubtype;
+ __u8 bFormatType;
+ __le16 wMaxBitRate;
+ __le16 wSamplesPerFrame;
+ __u8 bHeaderLength;
+ __u8 bSideBandProtocol;
+} __attribute__((packed));
+
+/* type III */
+#define UAC_FORMAT_TYPE_III_IEC1937_AC3 0x2001
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG1_LAYER1 0x2002
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_NOEXT 0x2003
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_EXT 0x2004
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER1_LS 0x2005
+#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER23_LS 0x2006
+
+/* Formats - A.2 Format Type Codes */
+#define UAC_FORMAT_TYPE_UNDEFINED 0x0
+#define UAC_FORMAT_TYPE_I 0x1
+#define UAC_FORMAT_TYPE_II 0x2
+#define UAC_FORMAT_TYPE_III 0x3
+#define UAC_EXT_FORMAT_TYPE_I 0x81
+#define UAC_EXT_FORMAT_TYPE_II 0x82
+#define UAC_EXT_FORMAT_TYPE_III 0x83
+
+struct uac_iso_endpoint_descriptor {
+ __u8 bLength; /* in bytes: 7 */
+ __u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */
+ __u8 bDescriptorSubtype; /* EP_GENERAL */
+ __u8 bmAttributes;
+ __u8 bLockDelayUnits;
+ __le16 wLockDelay;
+} __attribute__((packed));
+#define UAC_ISO_ENDPOINT_DESC_SIZE 7
+
+#define UAC_EP_CS_ATTR_SAMPLE_RATE 0x01
+#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02
+#define UAC_EP_CS_ATTR_FILL_MAX 0x80
+
+/* status word format (3.7.1.1) */
+
+#define UAC1_STATUS_TYPE_ORIG_MASK 0x0f
+#define UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF 0x0
+#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_IF 0x1
+#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_EP 0x2
+
+#define UAC1_STATUS_TYPE_IRQ_PENDING (1 << 7)
+#define UAC1_STATUS_TYPE_MEM_CHANGED (1 << 6)
+
+struct uac1_status_word {
+ __u8 bStatusType;
+ __u8 bOriginator;
+} __attribute__((packed));
+
+
+#endif /* _UAPI__LINUX_USB_AUDIO_H */
diff --git a/components/drivers/usb/usbdevice/class/audio_mic.c b/components/drivers/usb/usbdevice/class/audio_mic.c
new file mode 100644
index 0000000000..4ac85711ad
--- /dev/null
+++ b/components/drivers/usb/usbdevice/class/audio_mic.c
@@ -0,0 +1,577 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-09-07 flybreak the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtservice.h>
+#include <rtdevice.h>
+
+#include "drivers/usb_device.h"
+#include "audio.h"
+
+#define DBG_TAG "usbd.audio.mic"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#define RECORD_SAMPLERATE 16000
+#define RECORD_CHANNEL 1
+#define RESOLUTION_BITS 16
+
+#define RESOLUTION_BYTE (RESOLUTION_BITS / 8)
+#define RECORD_PER_MS_SZ ((RECORD_SAMPLERATE * RECORD_CHANNEL * RESOLUTION_BYTE) / 1000)
+#define RECORD_BUFFER_SZ (RECORD_PER_MS_SZ * 20) /* 20ms */
+
+#if defined(RT_USBD_MIC_DEVICE_NAME)
+ #define MIC_DEVICE_NAME RT_USBD_MIC_DEVICE_NAME
+#else
+ #define MIC_DEVICE_NAME "mic0"
+#endif
+
+#define EVENT_RECORD_START (1 << 0)
+#define EVENT_RECORD_STOP (1 << 1)
+#define EVENT_RECORD_DATA (1 << 2)
+
+/*
+ * uac mic descriptor define
+ */
+
+#define UAC_CS_INTERFACE 0x24
+#define UAC_CS_ENDPOINT 0x25
+
+#define UAC_MAX_PACKET_SIZE 64
+#define UAC_EP_MAX_PACKET_SIZE 32
+#define UAC_CHANNEL_NUM RECORD_CHANNEL
+#define UAC_INTR_NUM 1
+#define UAC_CH_NUM 1
+#define UAC_FORMAT_NUM 1
+
+struct uac_ac_descriptor
+{
+#ifdef RT_USB_DEVICE_COMPOSITE
+ struct uiad_descriptor iad_desc;
+#endif
+ struct uinterface_descriptor intf_desc;
+ DECLARE_UAC_AC_HEADER_DESCRIPTOR(UAC_INTR_NUM) hdr_desc;
+ struct uac_input_terminal_descriptor it_desc;
+ struct uac1_output_terminal_descriptor ot_desc;
+#if UAC_USE_FEATURE_UNIT
+ DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(UAC_CH_NUM) feature_unit_desc;
+#endif
+};
+
+struct uac_as_descriptor
+{
+ struct uinterface_descriptor intf_desc;
+ struct uac1_as_header_descriptor hdr_desc;
+ DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(UAC_FORMAT_NUM) format_type_desc;
+ struct uendpoint_descriptor ep_desc;
+ struct uac_iso_endpoint_descriptor as_ep_desc;
+};
+
+/*
+ * uac mic device type
+ */
+
+struct uac_audio_mic
+{
+ rt_device_t dev;
+ rt_event_t event;
+ rt_uint8_t open_count;
+
+ rt_uint8_t *buffer;
+ rt_uint32_t buffer_index;
+
+ uep_t ep;
+};
+static struct uac_audio_mic mic;
+
+ALIGN(4)
+static struct udevice_descriptor dev_desc =
+{
+ USB_DESC_LENGTH_DEVICE, //bLength;
+ USB_DESC_TYPE_DEVICE, //type;
+ USB_BCD_VERSION, //bcdUSB;
+ USB_CLASS_DEVICE, //bDeviceClass;
+ 0x00, //bDeviceSubClass;
+ 0x00, //bDeviceProtocol;
+ UAC_MAX_PACKET_SIZE, //bMaxPacketSize0;
+ _VENDOR_ID, //idVendor;
+ _PRODUCT_ID, //idProduct;
+ USB_BCD_DEVICE, //bcdDevice;
+ USB_STRING_MANU_INDEX, //iManufacturer;
+ USB_STRING_PRODUCT_INDEX, //iProduct;
+ USB_STRING_SERIAL_INDEX, //iSerialNumber;Unused.
+ USB_DYNAMIC, //bNumConfigurations;
+};
+
+//FS and HS needed
+ALIGN(4)
+static struct usb_qualifier_descriptor dev_qualifier =
+{
+ sizeof(dev_qualifier), //bLength
+ USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType
+ 0x0200, //bcdUSB
+ USB_CLASS_AUDIO, //bDeviceClass
+ 0x00, //bDeviceSubClass
+ 0x00, //bDeviceProtocol
+ 64, //bMaxPacketSize0
+ 0x01, //bNumConfigurations
+ 0,
+};
+
+ALIGN(4)
+const static char *_ustring[] =
+{
+ "Language",
+ "RT-Thread Team.",
+ "Microphone",
+ "32021919830108",
+ "Configuration",
+ "Interface",
+};
+
+ALIGN(4)
+static struct uac_ac_descriptor ac_desc =
+{
+#ifdef RT_USB_DEVICE_COMPOSITE
+ /* Interface Association Descriptor */
+ {
+ USB_DESC_LENGTH_IAD,
+ USB_DESC_TYPE_IAD,
+ USB_DYNAMIC,
+ 0x02,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+ },
+#endif
+ /* Interface Descriptor */
+ {
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x00,
+ 0x00,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOCONTROL,
+ 0x00,
+ 0x00,
+ },
+ /* Header Descriptor */
+ {
+ UAC_DT_AC_HEADER_SIZE(UAC_INTR_NUM),
+ UAC_CS_INTERFACE,
+ UAC_HEADER,
+ 0x0100, /* Version: 1.00 */
+ 0x001E, /* Total length: 30 */
+ 0x01, /* Total number of interfaces: 1 */
+ {0x01}, /* Interface number: 1 */
+ },
+ /* Input Terminal Descriptor */
+ {
+ UAC_DT_INPUT_TERMINAL_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_INPUT_TERMINAL,
+ 0x01, /* Terminal ID: 1 */
+ 0x0201, /* Terminal Type: Microphone (0x0201) */
+ 0x00, /* Assoc Terminal: 0 */
+ 0x01, /* Number Channels: 1 */
+ 0x0000, /* Channel Config: 0x0000 */
+ 0x00, /* Channel Names: 0 */
+ 0x00, /* Terminal: 0 */
+ },
+ /* Output Terminal Descriptor */
+ {
+ UAC_DT_OUTPUT_TERMINAL_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_OUTPUT_TERMINAL,
+ 0x02, /* Terminal ID: 2 */
+ 0x0101, /* Terminal Type: USB Streaming (0x0101) */
+ 0x00, /* Assoc Terminal: 0 */
+ 0x01, /* Source ID: 1 */
+ 0x00, /* Terminal: 0 */
+ },
+#if UAC_USE_FEATURE_UNIT
+ /* Feature unit Descriptor */
+ {
+ UAC_DT_FEATURE_UNIT_SIZE(UAC_CH_NUM),
+ UAC_CS_INTERFACE,
+ UAC_FEATURE_UNIT,
+ 0x02,
+ 0x0101,
+ 0x00,
+ 0x01,
+ },
+#endif
+};
+
+ALIGN(4)
+static struct uinterface_descriptor as_desc0 =
+{
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x00,
+ 0x00,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+};
+
+ALIGN(4)
+static struct uac_as_descriptor as_desc =
+{
+ /* Interface Descriptor */
+ {
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x01,
+ 0x01,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+ },
+ /* General AS Descriptor */
+ {
+ UAC_DT_AS_HEADER_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_AS_GENERAL,
+ 0x02, /* Terminal ID: 2 */
+ 0x01, /* Interface delay in frames: 1 */
+ UAC_FORMAT_TYPE_I_PCM,
+ },
+ /* Format type i Descriptor */
+ {
+ UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(UAC_FORMAT_NUM),
+ UAC_CS_INTERFACE,
+ UAC_FORMAT_TYPE,
+ UAC_FORMAT_TYPE_I,
+ UAC_CHANNEL_NUM,
+ 2, /* Subframe Size: 2 */
+ RESOLUTION_BITS,
+ 0x01, /* Samples Frequence Type: 1 */
+ {0}, /* Samples Frequence */
+ },
+ /* Endpoint Descriptor */
+ {
+ USB_DESC_LENGTH_ENDPOINT,
+ USB_DESC_TYPE_ENDPOINT,
+ USB_DYNAMIC | USB_DIR_IN,
+ USB_EP_ATTR_ISOC,
+ UAC_EP_MAX_PACKET_SIZE,
+ 0x01,
+ },
+ /* AS Endpoint Descriptor */
+ {
+ UAC_ISO_ENDPOINT_DESC_SIZE,
+ UAC_CS_ENDPOINT,
+ UAC_MS_GENERAL,
+ },
+};
+
+void mic_entry(void *parameter)
+{
+ struct rt_audio_caps caps = {0};
+ rt_uint32_t e, index;
+
+ mic.buffer = rt_malloc(RECORD_BUFFER_SZ);
+ if (mic.buffer == RT_NULL)
+ {
+ LOG_E("malloc failed");
+ goto __exit;
+ }
+
+ mic.dev = rt_device_find(MIC_DEVICE_NAME);
+ if (mic.dev == RT_NULL)
+ {
+ LOG_E("can't find device:%s", MIC_DEVICE_NAME);
+ goto __exit;
+ }
+
+ while (1)
+ {
+ if (rt_event_recv(mic.event, EVENT_RECORD_START | EVENT_RECORD_STOP,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ 1000, &e) != RT_EOK)
+ {
+ continue;
+ }
+ if (mic.open_count == 0)
+ {
+ continue;
+ }
+ LOG_D("record start");
+
+ rt_device_open(mic.dev, RT_DEVICE_OFLAG_RDONLY);
+
+ caps.main_type = AUDIO_TYPE_INPUT;
+ caps.sub_type = AUDIO_DSP_PARAM;
+ caps.udata.config.samplerate = RECORD_SAMPLERATE;
+ caps.udata.config.channels = RECORD_CHANNEL;
+ caps.udata.config.samplebits = RESOLUTION_BITS;
+ rt_device_control(mic.dev, AUDIO_CTL_CONFIGURE, &caps);
+
+ while (1)
+ {
+ if (rt_event_recv(mic.event, EVENT_RECORD_DATA | EVENT_RECORD_STOP,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ 1000, &e) != RT_EOK)
+ {
+ if (mic.open_count > 0)
+ continue;
+ else
+ break;
+ }
+ if (e & EVENT_RECORD_DATA)
+ {
+ index = (mic.buffer_index >= RECORD_BUFFER_SZ / 2) ? 0 : (RECORD_BUFFER_SZ / 2);
+ rt_device_read(mic.dev, 0, mic.buffer + index, RECORD_BUFFER_SZ / 2);
+ }
+ else if (e & EVENT_RECORD_STOP)
+ {
+ break;
+ }
+ }
+ LOG_D("record stop");
+ rt_device_close(mic.dev);
+ }
+
+__exit:
+ if (mic.buffer)
+ rt_free(mic.buffer);
+}
+
+static rt_err_t _record_start(ufunction_t func)
+{
+ mic.ep->request.buffer = RT_NULL;
+ mic.ep->request.size = UAC_EP_MAX_PACKET_SIZE;
+ mic.ep->request.req_type = UIO_REQUEST_WRITE;
+ rt_usbd_io_request(func->device, mic.ep, &mic.ep->request);
+
+ mic.open_count ++;
+ rt_event_send(mic.event, EVENT_RECORD_START);
+ return 0;
+}
+
+static rt_err_t _record_stop(ufunction_t func)
+{
+ mic.open_count --;
+ rt_event_send(mic.event, EVENT_RECORD_STOP);
+ return 0;
+}
+
+static rt_err_t _ep_data_in_handler(ufunction_t func, rt_size_t size)
+{
+ RT_ASSERT(func != RT_NULL);
+ LOG_D("_ep_data_in_handler");
+
+ mic.ep->request.buffer = mic.buffer + mic.buffer_index;
+ mic.ep->request.size = UAC_EP_MAX_PACKET_SIZE;
+ mic.ep->request.req_type = UIO_REQUEST_WRITE;
+ rt_usbd_io_request(func->device, mic.ep, &mic.ep->request);
+
+ mic.buffer_index += UAC_EP_MAX_PACKET_SIZE;
+ if (mic.buffer_index >= RECORD_BUFFER_SZ)
+ {
+ mic.buffer_index = 0;
+ rt_event_send(mic.event, EVENT_RECORD_DATA);
+ }
+ else if (mic.buffer_index == RECORD_BUFFER_SZ / 2)
+ {
+ rt_event_send(mic.event, EVENT_RECORD_DATA);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _interface_as_handler(ufunction_t func, ureq_t setup)
+{
+ RT_ASSERT(func != RT_NULL);
+ RT_ASSERT(func->device != RT_NULL);
+ RT_ASSERT(setup != RT_NULL);
+
+ LOG_D("_interface_as_handler");
+
+ if ((setup->request_type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
+ {
+ switch (setup->bRequest)
+ {
+ case USB_REQ_GET_INTERFACE:
+ break;
+ case USB_REQ_SET_INTERFACE:
+ LOG_D("set interface handler");
+ if (setup->wValue == 1)
+ {
+ _record_start(func);
+ }
+ else if (setup->wValue == 0)
+ {
+ _record_stop(func);
+ }
+ break;
+ default:
+ LOG_D("unknown uac request 0x%x", setup->bRequest);
+ return -RT_ERROR;
+ }
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _function_enable(ufunction_t func)
+{
+ RT_ASSERT(func != RT_NULL);
+
+ LOG_D("uac function enable");
+
+ return RT_EOK;
+}
+
+static rt_err_t _function_disable(ufunction_t func)
+{
+ RT_ASSERT(func != RT_NULL);
+
+ LOG_D("uac function disable");
+ _record_stop(func);
+ return RT_EOK;
+}
+
+static struct ufunction_ops ops =
+{
+ _function_enable,
+ _function_disable,
+ RT_NULL,
+};
+/**
+ * This function will configure uac descriptor.
+ *
+ * @param comm the communication interface number.
+ * @param data the data interface number.
+ *
+ * @return RT_EOK on successful.
+ */
+static rt_err_t _uac_descriptor_config(struct uac_ac_descriptor *ac,
+ rt_uint8_t cintf_nr, struct uac_as_descriptor *as, rt_uint8_t sintf_nr)
+{
+ ac->hdr_desc.baInterfaceNr[0] = sintf_nr;
+#ifdef RT_USB_DEVICE_COMPOSITE
+ ac->iad_desc.bFirstInterface = cintf_nr;
+#endif
+
+ return RT_EOK;
+}
+
+static rt_err_t _uac_samplerate_config(struct uac_as_descriptor *as, rt_uint32_t samplerate)
+{
+ as->format_type_desc.tSamFreq[0][2] = samplerate >> 16 & 0xff;
+ as->format_type_desc.tSamFreq[0][1] = samplerate >> 8 & 0xff;
+ as->format_type_desc.tSamFreq[0][0] = samplerate & 0xff;
+ return RT_EOK;
+}
+
+/**
+ * This function will create a uac function instance.
+ *
+ * @param device the usb device object.
+ *
+ * @return RT_EOK on successful.
+ */
+ufunction_t rt_usbd_function_uac_mic_create(udevice_t device)
+{
+ ufunction_t func;
+ uintf_t intf_ac, intf_as;
+ ualtsetting_t setting_as0;
+ ualtsetting_t setting_ac, setting_as;
+ struct uac_as_descriptor *as_desc_t;
+
+ /* parameter check */
+ RT_ASSERT(device != RT_NULL);
+
+ /* set usb device string description */
+ rt_usbd_device_set_string(device, _ustring);
+
+ /* create a uac function */
+ func = rt_usbd_function_new(device, &dev_desc, &ops);
+ //not support HS
+ //rt_usbd_device_set_qualifier(device, &dev_qualifier);
+
+ /* create interface */
+ intf_ac = rt_usbd_interface_new(device, RT_NULL);
+ intf_as = rt_usbd_interface_new(device, _interface_as_handler);
+
+ /* create alternate setting */
+ setting_ac = rt_usbd_altsetting_new(sizeof(struct uac_ac_descriptor));
+ setting_as0 = rt_usbd_altsetting_new(sizeof(struct uinterface_descriptor));
+ setting_as = rt_usbd_altsetting_new(sizeof(struct uac_as_descriptor));
+ /* config desc in alternate setting */
+ rt_usbd_altsetting_config_descriptor(setting_ac, &ac_desc,
+ (rt_off_t) & ((struct uac_ac_descriptor *)0)->intf_desc);
+ rt_usbd_altsetting_config_descriptor(setting_as0, &as_desc0, 0);
+ rt_usbd_altsetting_config_descriptor(setting_as, &as_desc,
+ (rt_off_t) & ((struct uac_as_descriptor *)0)->intf_desc);
+ /* configure the uac interface descriptor */
+ _uac_descriptor_config(setting_ac->desc, intf_ac->intf_num, setting_as->desc, intf_as->intf_num);
+ _uac_samplerate_config(setting_as->desc, RECORD_SAMPLERATE);
+
+ /* create endpoint */
+ as_desc_t = (struct uac_as_descriptor *)setting_as->desc;
+ mic.ep = rt_usbd_endpoint_new(&as_desc_t->ep_desc, _ep_data_in_handler);
+
+ /* add the endpoint to the alternate setting */
+ rt_usbd_altsetting_add_endpoint(setting_as, mic.ep);
+
+ /* add the alternate setting to the interface, then set default setting of the interface */
+ rt_usbd_interface_add_altsetting(intf_ac, setting_ac);
+ rt_usbd_set_altsetting(intf_ac, 0);
+ rt_usbd_interface_add_altsetting(intf_as, setting_as0);
+ rt_usbd_interface_add_altsetting(intf_as, setting_as);
+ rt_usbd_set_altsetting(intf_as, 0);
+
+ /* add the interface to the uac function */
+ rt_usbd_function_add_interface(func, intf_ac);
+ rt_usbd_function_add_interface(func, intf_as);
+
+ return func;
+}
+
+int audio_mic_init(void)
+{
+ rt_thread_t mic_tid;
+ mic.event = rt_event_create("mic_event", RT_IPC_FLAG_FIFO);
+
+ mic_tid = rt_thread_create("mic_thread",
+ mic_entry, RT_NULL,
+ 1024,
+ 5, 10);
+
+ if (mic_tid != RT_NULL)
+ rt_thread_startup(mic_tid);
+ return RT_EOK;
+}
+INIT_COMPONENT_EXPORT(audio_mic_init);
+
+/*
+ * register uac class
+ */
+struct udclass uac_class =
+{
+ .rt_usbd_function_create = rt_usbd_function_uac_mic_create
+};
+
+int rt_usbd_uac_mic_class_register(void)
+{
+ rt_usbd_class_register(&uac_class);
+ return 0;
+}
+INIT_PREV_EXPORT(rt_usbd_uac_mic_class_register);
diff --git a/components/drivers/usb/usbdevice/class/audio_speaker.c b/components/drivers/usb/usbdevice/class/audio_speaker.c
new file mode 100644
index 0000000000..84c36d2053
--- /dev/null
+++ b/components/drivers/usb/usbdevice/class/audio_speaker.c
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-09-19 flybreak the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtservice.h>
+#include <rtdevice.h>
+
+#include "drivers/usb_device.h"
+#include "audio.h"
+
+#define DBG_TAG "usbd.audio.speaker"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#define AUDIO_SAMPLERATE 16000
+#define AUDIO_CHANNEL 1
+#define RESOLUTION_BITS 16
+
+#define RESOLUTION_BYTE (RESOLUTION_BITS / 8)
+#define AUDIO_PER_MS_SZ ((AUDIO_SAMPLERATE * AUDIO_CHANNEL * RESOLUTION_BYTE) / 1000)
+#define AUDIO_BUFFER_SZ (AUDIO_PER_MS_SZ * 20) /* 20ms */
+
+#if defined(RT_USBD_SPEAKER_DEVICE_NAME)
+ #define SPEAKER_DEVICE_NAME RT_USBD_SPEAKER_DEVICE_NAME
+#else
+ #define SPEAKER_DEVICE_NAME "sound0"
+#endif
+
+#define EVENT_AUDIO_START (1 << 0)
+#define EVENT_AUDIO_STOP (1 << 1)
+#define EVENT_AUDIO_DATA (1 << 2)
+
+/*
+ * uac speaker descriptor define
+ */
+
+#define UAC_CS_INTERFACE 0x24
+#define UAC_CS_ENDPOINT 0x25
+
+#define UAC_MAX_PACKET_SIZE 64
+#define UAC_EP_MAX_PACKET_SIZE 32
+#define UAC_CHANNEL_NUM AUDIO_CHANNEL
+#define UAC_INTR_NUM 1
+#define UAC_CH_NUM 1
+#define UAC_FORMAT_NUM 1
+
+struct uac_ac_descriptor
+{
+#ifdef RT_USB_DEVICE_COMPOSITE
+ struct uiad_descriptor iad_desc;
+#endif
+ struct uinterface_descriptor intf_desc;
+ DECLARE_UAC_AC_HEADER_DESCRIPTOR(UAC_INTR_NUM) hdr_desc;
+ struct uac_input_terminal_descriptor it_desc;
+ struct uac1_output_terminal_descriptor ot_desc;
+#if UAC_USE_FEATURE_UNIT
+ DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(UAC_CH_NUM) feature_unit_desc;
+#endif
+};
+
+struct uac_as_descriptor
+{
+ struct uinterface_descriptor intf_desc;
+ struct uac1_as_header_descriptor hdr_desc;
+ DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(UAC_FORMAT_NUM) format_type_desc;
+ struct uendpoint_descriptor ep_desc;
+ struct uac_iso_endpoint_descriptor as_ep_desc;
+};
+
+/*
+ * uac speaker device type
+ */
+
+struct uac_audio_speaker
+{
+ rt_device_t dev;
+ rt_event_t event;
+ rt_uint8_t open_count;
+
+ rt_uint8_t *buffer;
+ rt_uint32_t buffer_index;
+
+ uep_t ep;
+};
+static struct uac_audio_speaker speaker;
+
+ALIGN(4)
+static struct udevice_descriptor dev_desc =
+{
+ USB_DESC_LENGTH_DEVICE, //bLength;
+ USB_DESC_TYPE_DEVICE, //type;
+ USB_BCD_VERSION, //bcdUSB;
+ USB_CLASS_DEVICE, //bDeviceClass;
+ 0x00, //bDeviceSubClass;
+ 0x00, //bDeviceProtocol;
+ UAC_MAX_PACKET_SIZE, //bMaxPacketSize0;
+ _VENDOR_ID, //idVendor;
+ _PRODUCT_ID, //idProduct;
+ USB_BCD_DEVICE, //bcdDevice;
+ USB_STRING_MANU_INDEX, //iManufacturer;
+ USB_STRING_PRODUCT_INDEX, //iProduct;
+ USB_STRING_SERIAL_INDEX, //iSerialNumber;Unused.
+ USB_DYNAMIC, //bNumConfigurations;
+};
+
+//FS and HS needed
+ALIGN(4)
+static struct usb_qualifier_descriptor dev_qualifier =
+{
+ sizeof(dev_qualifier), //bLength
+ USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType
+ 0x0200, //bcdUSB
+ USB_CLASS_AUDIO, //bDeviceClass
+ 0x00, //bDeviceSubClass
+ 0x00, //bDeviceProtocol
+ 64, //bMaxPacketSize0
+ 0x01, //bNumConfigurations
+ 0,
+};
+
+ALIGN(4)
+const static char *_ustring[] =
+{
+ "Language",
+ "RT-Thread Team.",
+ "RT-Thread Speaker",
+ "32021919830108",
+ "Configuration",
+ "Interface",
+};
+
+ALIGN(4)
+static struct uac_ac_descriptor ac_desc =
+{
+#ifdef RT_USB_DEVICE_COMPOSITE
+ /* Interface Association Descriptor */
+ {
+ USB_DESC_LENGTH_IAD,
+ USB_DESC_TYPE_IAD,
+ USB_DYNAMIC,
+ 0x02,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+ },
+#endif
+ /* Interface Descriptor */
+ {
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x00,
+ 0x00,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOCONTROL,
+ 0x00,
+ 0x00,
+ },
+ /* Header Descriptor */
+ {
+ UAC_DT_AC_HEADER_SIZE(UAC_INTR_NUM),
+ UAC_CS_INTERFACE,
+ UAC_HEADER,
+ 0x0100, /* Version: 1.00 */
+ 0x0027, /* Total length: 39 */
+ 0x01, /* Total number of interfaces: 1 */
+ {0x01}, /* Interface number: 1 */
+ },
+ /* Input Terminal Descriptor */
+ {
+ UAC_DT_INPUT_TERMINAL_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_INPUT_TERMINAL,
+ 0x01, /* Terminal ID: 1 */
+ 0x0101, /* Terminal Type: USB Streaming (0x0101) */
+ 0x00, /* Assoc Terminal: 0 */
+ 0x01, /* Number Channels: 1 */
+ 0x0000, /* Channel Config: 0x0000 */
+ 0x00, /* Channel Names: 0 */
+ 0x00, /* Terminal: 0 */
+ },
+ /* Output Terminal Descriptor */
+ {
+ UAC_DT_OUTPUT_TERMINAL_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_OUTPUT_TERMINAL,
+ 0x02, /* Terminal ID: 2 */
+ 0x0302, /* Terminal Type: Headphones (0x0302) */
+ 0x00, /* Assoc Terminal: 0 */
+ 0x01, /* Source ID: 1 */
+ 0x00, /* Terminal: 0 */
+ },
+#if UAC_USE_FEATURE_UNIT
+ /* Feature unit Descriptor */
+ {
+ UAC_DT_FEATURE_UNIT_SIZE(UAC_CH_NUM),
+ UAC_CS_INTERFACE,
+ UAC_FEATURE_UNIT,
+ 0x02,
+ 0x0101,
+ 0x00,
+ 0x01,
+ },
+#endif
+};
+
+ALIGN(4)
+static struct uinterface_descriptor as_desc0 =
+{
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x00,
+ 0x00,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+};
+
+ALIGN(4)
+static struct uac_as_descriptor as_desc =
+{
+ /* Interface Descriptor */
+ {
+ USB_DESC_LENGTH_INTERFACE,
+ USB_DESC_TYPE_INTERFACE,
+ USB_DYNAMIC,
+ 0x01,
+ 0x01,
+ USB_CLASS_AUDIO,
+ USB_SUBCLASS_AUDIOSTREAMING,
+ 0x00,
+ 0x00,
+ },
+ /* General AS Descriptor */
+ {
+ UAC_DT_AS_HEADER_SIZE,
+ UAC_CS_INTERFACE,
+ UAC_AS_GENERAL,
+ 0x01, /* Terminal ID: 1 */
+ 0x01, /* Interface delay in frames: 1 */
+ UAC_FORMAT_TYPE_I_PCM,
+ },
+ /* Format type i Descriptor */
+ {
+ UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(UAC_FORMAT_NUM),
+ UAC_CS_INTERFACE,
+ UAC_FORMAT_TYPE,
+ UAC_FORMAT_TYPE_I,
+ UAC_CHANNEL_NUM,
+ 2, /* Subframe Size: 2 */
+ RESOLUTION_BITS,
+ 0x01, /* Samples Frequence Type: 1 */
+ {0}, /* Samples Frequence */
+ },
+ /* Endpoint Descriptor */
+ {
+ USB_DESC_LENGTH_ENDPOINT,
+ USB_DESC_TYPE_ENDPOINT,
+ USB_DYNAMIC | USB_DIR_OUT,
+ USB_EP_ATTR_ISOC,
+ UAC_EP_MAX_PACKET_SIZE,
+ 0x01,
+ },
+ /* AS Endpoint Descriptor */
+ {
+ UAC_ISO_ENDPOINT_DESC_SIZE,
+ UAC_CS_ENDPOINT,
+ UAC_MS_GENERAL,
+ },
+};
+
+void speaker_entry(void *parameter)
+{
+ struct rt_audio_caps caps = {0};
+ rt_uint32_t e, index;
+
+ speaker.buffer = rt_malloc(AUDIO_BUFFER_SZ);
+ if (speaker.buffer == RT_NULL)
+ {
+ LOG_E("malloc failed");
+ goto __exit;
+ }
+
+ speaker.dev = rt_device_find(SPEAKER_DEVICE_NAME);
+ if (speaker.dev == RT_NULL)
+ {
+ LOG_E("can't find device:%s", SPEAKER_DEVICE_NAME);
+ goto __exit;
+ }
+
+ while (1)
+ {
+ if (rt_event_recv(speaker.event, EVENT_AUDIO_START | EVENT_AUDIO_STOP,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ 1000, &e) != RT_EOK)
+ {
+ continue;
+ }
+ if (speaker.open_count == 0)
+ {
+ continue;
+ }
+ LOG_D("play start");
+
+ rt_device_open(speaker.dev, RT_DEVICE_OFLAG_WRONLY);
+
+ caps.main_type = AUDIO_TYPE_OUTPUT;
+ caps.sub_type = AUDIO_DSP_PARAM;
+ caps.udata.config.samplerate = AUDIO_SAMPLERATE;
+ caps.udata.config.channels = AUDIO_CHANNEL;
+ caps.udata.config.samplebits = RESOLUTION_BITS;
+ rt_device_control(speaker.dev, AUDIO_CTL_CONFIGURE, &caps);
+
+ while (1)
+ {
+ if (rt_event_recv(speaker.event, EVENT_AUDIO_DATA | EVENT_AUDIO_STOP,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ 1000, &e) != RT_EOK)
+ {
+ if (speaker.open_count > 0)
+ continue;
+ else
+ break;
+ }
+ if (e & EVENT_AUDIO_DATA)
+ {
+ index = (speaker.buffer_index >= AUDIO_BUFFER_SZ / 2) ? 0 : (AUDIO_BUFFER_SZ / 2);
+ rt_device_write(speaker.dev, 0, speaker.buffer + index, AUDIO_BUFFER_SZ / 2);
+ }
+ else if (e & EVENT_AUDIO_STOP)
+ {
+ break;
+ }
+ }
+ LOG_D("play stop");
+ rt_device_close(speaker.dev);
+ }
+
+__exit:
+ if (speaker.buffer)
+ rt_free(speaker.buffer);
+}
+
+static rt_err_t _audio_start(ufunction_t func)
+{
+ speaker.ep->request.buffer = speaker.buffer;
+ speaker.ep->request.size = UAC_EP_MAX_PACKET_SIZE;
+ speaker.ep->request.req_type = UIO_REQUEST_READ_FULL;
+ rt_usbd_io_request(func->device, speaker.ep, &speaker.ep->request);
+
+ speaker.open_count ++;
+ rt_event_send(speaker.event, EVENT_AUDIO_START);
+
+ return 0;
+}
+
+static rt_err_t _audio_stop(ufunction_t func)
+{
+ speaker.open_count --;
+ rt_event_send(speaker.event, EVENT_AUDIO_STOP);
+ return 0;
+}
+
+static rt_err_t _ep_data_handler(ufunction_t func, rt_size_t size)
+{
+ RT_ASSERT(func != RT_NULL);
+ LOG_D("_ep_data_handler");
+
+ speaker.ep->request.buffer = speaker.buffer + speaker.buffer_index;
+ speaker.ep->request.size = UAC_EP_MAX_PACKET_SIZE;
+ speaker.ep->request.req_type = UIO_REQUEST_READ_FULL;
+ rt_usbd_io_request(func->device, speaker.ep, &speaker.ep->request);
+
+ speaker.buffer_index += UAC_EP_MAX_PACKET_SIZE;
+ if (speaker.buffer_index >= AUDIO_BUFFER_SZ)
+ {
+ speaker.buffer_index = 0;
+ rt_event_send(speaker.event, EVENT_AUDIO_DATA);
+ }
+ else if (speaker.buffer_index == AUDIO_BUFFER_SZ / 2)
+ {
+ rt_event_send(speaker.event, EVENT_AUDIO_DATA);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _interface_as_handler(ufunction_t func, ureq_t setup)
+{
+ RT_ASSERT(func != RT_NULL);
+ RT_ASSERT(func->device != RT_NULL);
+ RT_ASSERT(setup != RT_NULL);
+
+ LOG_D("_interface_as_handler");
+
+ if ((setup->request_type & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD)
+ {
+ switch (setup->bRequest)
+ {
+ case USB_REQ_GET_INTERFACE:
+ break;
+ case USB_REQ_SET_INTERFACE:
+ LOG_D("set interface handler");
+ if (setup->wValue == 1)
+ {
+ _audio_start(func);
+ }
+ else if (setup->wValue == 0)
+ {
+ _audio_stop(func);
+ }
+ break;
+ default:
+ LOG_D("unknown uac request 0x%x", setup->bRequest);
+ return -RT_ERROR;
+ }
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _function_enable(ufunction_t func)
+{
+ RT_ASSERT(func != RT_NULL);
+
+ LOG_D("uac function enable");
+
+ return RT_EOK;
+}
+
+static rt_err_t _function_disable(ufunction_t func)
+{
+ RT_ASSERT(func != RT_NULL);
+
+ LOG_D("uac function disable");
+ _audio_stop(func);
+ return RT_EOK;
+}
+
+static struct ufunction_ops ops =
+{
+ _function_enable,
+ _function_disable,
+ RT_NULL,
+};
+/**
+ * This function will configure uac descriptor.
+ *
+ * @param comm the communication interface number.
+ * @param data the data interface number.
+ *
+ * @return RT_EOK on successful.
+ */
+static rt_err_t _uac_descriptor_config(struct uac_ac_descriptor *ac,
+ rt_uint8_t cintf_nr, struct uac_as_descriptor *as, rt_uint8_t sintf_nr)
+{
+ ac->hdr_desc.baInterfaceNr[0] = sintf_nr;
+#ifdef RT_USB_DEVICE_COMPOSITE
+ ac->iad_desc.bFirstInterface = cintf_nr;
+#endif
+
+ return RT_EOK;
+}
+
+static rt_err_t _uac_samplerate_config(struct uac_as_descriptor *as, rt_uint32_t samplerate)
+{
+ as->format_type_desc.tSamFreq[0][2] = samplerate >> 16 & 0xff;
+ as->format_type_desc.tSamFreq[0][1] = samplerate >> 8 & 0xff;
+ as->format_type_desc.tSamFreq[0][0] = samplerate & 0xff;
+ return RT_EOK;
+}
+
+/**
+ * This function will create a uac function instance.
+ *
+ * @param device the usb device object.
+ *
+ * @return RT_EOK on successful.
+ */
+ufunction_t rt_usbd_function_uac_speaker_create(udevice_t device)
+{
+ ufunction_t func;
+ uintf_t intf_ac, intf_as;
+ ualtsetting_t setting_as0;
+ ualtsetting_t setting_ac, setting_as;
+ struct uac_as_descriptor *as_desc_t;
+
+ /* parameter check */
+ RT_ASSERT(device != RT_NULL);
+
+ /* set usb device string description */
+ rt_usbd_device_set_string(device, _ustring);
+
+ /* create a uac function */
+ func = rt_usbd_function_new(device, &dev_desc, &ops);
+ //not support HS
+ //rt_usbd_device_set_qualifier(device, &dev_qualifier);
+
+ /* create interface */
+ intf_ac = rt_usbd_interface_new(device, RT_NULL);
+ intf_as = rt_usbd_interface_new(device, _interface_as_handler);
+
+ /* create alternate setting */
+ setting_ac = rt_usbd_altsetting_new(sizeof(struct uac_ac_descriptor));
+ setting_as0 = rt_usbd_altsetting_new(sizeof(struct uinterface_descriptor));
+ setting_as = rt_usbd_altsetting_new(sizeof(struct uac_as_descriptor));
+ /* config desc in alternate setting */
+ rt_usbd_altsetting_config_descriptor(setting_ac, &ac_desc,
+ (rt_off_t) & ((struct uac_ac_descriptor *)0)->intf_desc);
+ rt_usbd_altsetting_config_descriptor(setting_as0, &as_desc0, 0);
+ rt_usbd_altsetting_config_descriptor(setting_as, &as_desc,
+ (rt_off_t) & ((struct uac_as_descriptor *)0)->intf_desc);
+ /* configure the uac interface descriptor */
+ _uac_descriptor_config(setting_ac->desc, intf_ac->intf_num, setting_as->desc, intf_as->intf_num);
+ _uac_samplerate_config(setting_as->desc, AUDIO_SAMPLERATE);
+
+ /* create endpoint */
+ as_desc_t = (struct uac_as_descriptor *)setting_as->desc;
+ speaker.ep = rt_usbd_endpoint_new(&as_desc_t->ep_desc, _ep_data_handler);
+
+ /* add the endpoint to the alternate setting */
+ rt_usbd_altsetting_add_endpoint(setting_as, speaker.ep);
+
+ /* add the alternate setting to the interface, then set default setting of the interface */
+ rt_usbd_interface_add_altsetting(intf_ac, setting_ac);
+ rt_usbd_set_altsetting(intf_ac, 0);
+ rt_usbd_interface_add_altsetting(intf_as, setting_as0);
+ rt_usbd_interface_add_altsetting(intf_as, setting_as);
+ rt_usbd_set_altsetting(intf_as, 0);
+
+ /* add the interface to the uac function */
+ rt_usbd_function_add_interface(func, intf_ac);
+ rt_usbd_function_add_interface(func, intf_as);
+
+ return func;
+}
+
+int audio_speaker_init(void)
+{
+ rt_thread_t speaker_tid;
+ speaker.event = rt_event_create("speaker_event", RT_IPC_FLAG_FIFO);
+
+ speaker_tid = rt_thread_create("speaker_thread",
+ speaker_entry, RT_NULL,
+ 1024,
+ 5, 10);
+
+ if (speaker_tid != RT_NULL)
+ rt_thread_startup(speaker_tid);
+ return RT_EOK;
+}
+INIT_COMPONENT_EXPORT(audio_speaker_init);
+
+/*
+ * register uac class
+ */
+static struct udclass uac_speaker_class =
+{
+ .rt_usbd_function_create = rt_usbd_function_uac_speaker_create
+};
+
+int rt_usbd_uac_speaker_class_register(void)
+{
+ rt_usbd_class_register(&uac_speaker_class);
+ return 0;
+}
+INIT_PREV_EXPORT(rt_usbd_uac_speaker_class_register);
diff --git a/components/drivers/usb/usbdevice/class/cdc_vcom.c b/components/drivers/usb/usbdevice/class/cdc_vcom.c
index 336cfcb152..64230533ae 100644
--- a/components/drivers/usb/usbdevice/class/cdc_vcom.c
+++ b/components/drivers/usb/usbdevice/class/cdc_vcom.c
@@ -28,7 +28,11 @@
#define VCOM_TX_TIMEOUT 1000
#endif /*RT_VCOM_TX_TIMEOUT*/
+#ifdef RT_CDC_RX_BUFSIZE
+#define CDC_RX_BUFSIZE RT_CDC_RX_BUFSIZE
+#else
#define CDC_RX_BUFSIZE 128
+#endif
#define CDC_MAX_PACKET_SIZE 64
#define VCOM_DEVICE "vcom"
@@ -63,6 +67,7 @@ static struct ucdc_line_coding line_coding;
#define CDC_BULKIN_MAXSIZE (CDC_TX_BUFSIZE / 8)
#define CDC_TX_HAS_DATE 0x01
+#define CDC_TX_HAS_SPACE 0x02
struct vcom
{
@@ -488,6 +493,7 @@ static rt_err_t _function_enable(ufunction_t func)
data = (struct vcom*)func->user_data;
data->ep_out->buffer = rt_malloc(CDC_RX_BUFSIZE);
+ RT_ASSERT(data->ep_out->buffer != RT_NULL);
data->ep_out->request.buffer = data->ep_out->buffer;
data->ep_out->request.size = EP_MAXPACKET(data->ep_out);
@@ -583,11 +589,13 @@ ufunction_t rt_usbd_function_cdc_create(udevice_t device)
/* create a cdc function */
func = rt_usbd_function_new(device, &dev_desc, &ops);
- //not support HS
- //rt_usbd_device_set_qualifier(device, &dev_qualifier);
+
+ /* support HS */
+ rt_usbd_device_set_qualifier(device, &dev_qualifier);
/* allocate memory for cdc vcom data */
data = (struct vcom*)rt_malloc(sizeof(struct vcom));
+ RT_ASSERT(data != RT_NULL);
rt_memset(data, 0, sizeof(struct vcom));
func->user_data = (void*)data;
@@ -693,23 +701,48 @@ static int _vcom_getc(struct rt_serial_device *serial)
return result;
}
-static rt_size_t _vcom_tx(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size,int direction)
+
+static rt_size_t _vcom_rb_block_put(struct vcom *data, const rt_uint8_t *buf, rt_size_t size)
{
rt_uint32_t level;
+ rt_size_t put_len = 0;
+ rt_size_t w_ptr = 0;
+ rt_uint32_t res;
+ rt_size_t remain_size = size;
+
+ while (remain_size)
+ {
+ level = rt_hw_interrupt_disable();
+ put_len = rt_ringbuffer_put(&data->tx_ringbuffer, (const rt_uint8_t *)&buf[w_ptr], remain_size);
+ rt_hw_interrupt_enable(level);
+ w_ptr += put_len;
+ remain_size -= put_len;
+ if (put_len == 0)
+ {
+ rt_event_recv(&data->tx_event, CDC_TX_HAS_SPACE,
+ RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ VCOM_TX_TIMEOUT, &res);
+ }
+ else
+ {
+ rt_event_send(&data->tx_event, CDC_TX_HAS_DATE);
+ }
+ }
+
+ return size;
+}
+static rt_size_t _vcom_tx(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size,int direction)
+{
struct ufunction *func;
struct vcom *data;
- rt_uint32_t baksize;
+ rt_uint32_t send_size = 0;
rt_size_t ptr = 0;
- int empty = 0;
rt_uint8_t crlf[2] = {'\r', '\n',};
func = (struct ufunction*)serial->parent.user_data;
data = (struct vcom*)func->user_data;
- size = (size >= CDC_BULKIN_MAXSIZE) ? CDC_BULKIN_MAXSIZE : size;
- baksize = size;
-
RT_ASSERT(serial != RT_NULL);
RT_ASSERT(buf != RT_NULL);
@@ -717,64 +750,37 @@ static rt_size_t _vcom_tx(struct rt_serial_device *serial, rt_uint8_t *buf, rt_s
if (data->connected)
{
- size = 0;
if((serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
{
- empty = 0;
- while(ptr < baksize)
+ while(send_size < size)
{
- while(ptr < baksize && buf[ptr] != '\n')
+ while(ptr < size && buf[ptr] != '\n')
{
ptr++;
}
- if(ptr < baksize)
+ if(ptr < size)
{
- level = rt_hw_interrupt_disable();
- size += rt_ringbuffer_put_force(&data->tx_ringbuffer, (const rt_uint8_t *)&buf[size], ptr - size);
- rt_hw_interrupt_enable(level);
-
- /* no data was be ignored */
- if(size == ptr)
- {
- level = rt_hw_interrupt_disable();
- if(rt_ringbuffer_space_len(&data->tx_ringbuffer) >= 2)
- {
- rt_ringbuffer_put_force(&data->tx_ringbuffer, crlf, 2);
- size++;
- }
- rt_hw_interrupt_enable(level);
- }
- else
- {
- empty = 1;
- break;
- }
-
- /* ring buffer is full */
- if(size == ptr)
- {
- empty = 1;
- break;
- }
+ send_size += _vcom_rb_block_put(data, (const rt_uint8_t *)&buf[send_size], ptr - send_size);
+ _vcom_rb_block_put(data, crlf, 2);
+ send_size++;
ptr++;
}
+ else if (ptr == size)
+ {
+ send_size += _vcom_rb_block_put(data, (const rt_uint8_t *)&buf[send_size], ptr - send_size);
+ }
else
{
break;
}
}
}
-
- if(size < baksize && !empty)
+ else
{
- level = rt_hw_interrupt_disable();
- size += rt_ringbuffer_put_force(&data->tx_ringbuffer, (rt_uint8_t *)&buf[size], baksize - size);
- rt_hw_interrupt_enable(level);
- }
-
- if(size)
- {
- rt_event_send(&data->tx_event, CDC_TX_HAS_DATE);
+ while (send_size < size)
+ {
+ send_size += _vcom_rb_block_put(data, (rt_uint8_t *)&buf[send_size], size - send_size);
+ }
}
}
else
@@ -902,6 +908,7 @@ static void vcom_tx_thread_entry(void* parameter)
#else
rt_hw_serial_isr(&data->serial,RT_SERIAL_EVENT_TX_DMADONE);
#endif
+ rt_event_send(&data->tx_event, CDC_TX_HAS_SPACE);
}
}
diff --git a/components/drivers/usb/usbdevice/class/ecm.c b/components/drivers/usb/usbdevice/class/ecm.c
index cda1a8bf1b..36557dad74 100644
--- a/components/drivers/usb/usbdevice/class/ecm.c
+++ b/components/drivers/usb/usbdevice/class/ecm.c
@@ -6,17 +6,16 @@
* Change Logs:
* Date Author Notes
* 2017-11-19 ZYH first version
+ * 2019-06-10 ZYH fix hotplug
*/
#include <rtdevice.h>
+#ifdef RT_USB_DEVICE_ECM
#include "cdc.h"
-
-#ifdef ECM_DEBUG
-#define ECM_PRINTF rt_kprintf("[ECM] "); rt_kprintf
-#else
-#define ECM_PRINTF(...)
-#endif /* ECM_DEBUG */
+#define DBG_LEVEL DBG_WARNING
+#define DBG_SECTION_NAME "ECM"
+#include <rtdbg.h>
/* RT-Thread LWIP ethernet interface */
#include <netif/ethernetif.h>
@@ -216,15 +215,21 @@ static rt_err_t _cdc_send_notifi(ufunction_t func,ucdc_notification_code_t notif
return RT_EOK;
}
+
static rt_err_t _ecm_set_eth_packet_filter(ufunction_t func, ureq_t setup)
{
rt_ecm_eth_t _ecm_eth = (rt_ecm_eth_t)func->user_data;
dcd_ep0_send_status(func->device->dcd);
-
/* send link up. */
eth_device_linkchange(&_ecm_eth->parent, RT_TRUE);
- _cdc_send_notifi(func,UCDC_NOTIFI_NETWORK_CONNECTION,1,0);
+ _cdc_send_notifi(func, UCDC_NOTIFI_NETWORK_CONNECTION, 1, 0);
+
+#ifdef LWIP_USING_DHCPD
+ extern void dhcpd_start(const char *netif_name);
+ dhcpd_start("u0");
+#endif
+
return RT_EOK;
}
/**
@@ -243,10 +248,11 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
switch(setup->bRequest)
{
case CDC_SET_ETH_PACKET_FILTER:
+ LOG_D("CDC_SET_ETH_PACKET_FILTER");
_ecm_set_eth_packet_filter(func, setup);
break;
default:
- rt_kprintf("setup->bRequest:0x%02X",setup->bRequest);
+ LOG_E("Unknow setup->bRequest: 0x%02X", setup->bRequest);
break;
}
return RT_EOK;
@@ -402,22 +408,26 @@ rt_err_t rt_ecm_eth_tx(rt_device_t dev, struct pbuf* p)
if(!ecm_eth_dev->parent.link_status)
{
- ECM_PRINTF("linkdown, drop pkg\r\n");
+ LOG_D("linkdown, drop pkg");
return RT_EOK;
}
- // RT_ASSERT(p->tot_len < USB_ETH_MTU);
if(p->tot_len > USB_ETH_MTU)
{
- ECM_PRINTF("RNDIS MTU is:%d, but the send packet size is %d\r\n",
+ LOG_W("ECM MTU is:%d, but the send packet size is %d",
USB_ETH_MTU, p->tot_len);
p->tot_len = USB_ETH_MTU;
}
- result = rt_sem_take(&ecm_eth_dev->tx_buffer_free, RT_WAITING_FOREVER);
+
+ result = rt_sem_take(&ecm_eth_dev->tx_buffer_free, rt_tick_from_millisecond(1000));
if(result != RT_EOK)
{
+ LOG_W("wait for buffer free timeout");
+ /* if cost 1s to wait send done it said that connection is close . drop it */
+ rt_sem_release(&ecm_eth_dev->tx_buffer_free);
return result;
}
+
pbuffer = (char *)&ecm_eth_dev->tx_buffer;
for (q = p; q != NULL; q = q->next)
{
@@ -461,8 +471,13 @@ static rt_err_t _function_enable(ufunction_t func)
{
cdc_eps_t eps;
rt_ecm_eth_t ecm_device = (rt_ecm_eth_t)func->user_data;
+
+ LOG_D("plugged in");
+
eps = (cdc_eps_t)&ecm_device->eps;
eps->ep_out->buffer = ecm_device->rx_pool;
+
+ /* reset eth rx tx */
ecm_device->rx_size = 0;
ecm_device->rx_offset = 0;
@@ -482,7 +497,14 @@ static rt_err_t _function_enable(ufunction_t func)
*/
static rt_err_t _function_disable(ufunction_t func)
{
+ LOG_D("plugged out");
+
eth_device_linkchange(&((rt_ecm_eth_t)func->user_data)->parent, RT_FALSE);
+
+ /* reset eth rx tx */
+ ((rt_ecm_eth_t)func->user_data)->rx_size = 0;
+ ((rt_ecm_eth_t)func->user_data)->rx_offset = 0;
+
return RT_EOK;
}
@@ -543,7 +565,8 @@ ufunction_t rt_usbd_function_ecm_create(udevice_t device)
/* create a cdc class */
cdc = rt_usbd_function_new(device, &_dev_desc, &ops);
rt_usbd_device_set_qualifier(device, &dev_qualifier);
- _ecm_eth= rt_malloc(sizeof(struct rt_ecm_eth));
+ _ecm_eth= rt_malloc(sizeof(struct rt_ecm_eth));
+ RT_ASSERT(_ecm_eth != RT_NULL);
rt_memset(_ecm_eth, 0, sizeof(struct rt_ecm_eth));
cdc->user_data = _ecm_eth;
@@ -643,3 +666,5 @@ int rt_usbd_ecm_class_register(void)
return 0;
}
INIT_PREV_EXPORT(rt_usbd_ecm_class_register);
+
+#endif /* RT_USB_DEVICE_ECM */
diff --git a/components/drivers/usb/usbdevice/class/hid.c b/components/drivers/usb/usbdevice/class/hid.c
index aea6d802d1..a4acce75ea 100644
--- a/components/drivers/usb/usbdevice/class/hid.c
+++ b/components/drivers/usb/usbdevice/class/hid.c
@@ -29,7 +29,7 @@ struct hid_s
uep_t ep_in;
uep_t ep_out;
int status;
- rt_uint16_t protocol;
+ rt_uint8_t protocol;
rt_uint8_t report_buf[MAX_REPORT_SIZE];
struct rt_messagequeue hid_mq;
};
@@ -246,7 +246,7 @@ static struct udevice_descriptor _dev_desc =
USB_DESC_LENGTH_DEVICE, //bLength;
USB_DESC_TYPE_DEVICE, //type;
USB_BCD_VERSION, //bcdUSB;
- USB_CLASS_HID, //bDeviceClass;
+ 0x0, //bDeviceClass;
0x00, //bDeviceSubClass;
0x00, //bDeviceProtocol;
64, //bMaxPacketSize0;
@@ -266,8 +266,8 @@ static struct usb_qualifier_descriptor dev_qualifier =
sizeof(dev_qualifier), //bLength
USB_DESC_TYPE_DEVICEQUALIFIER, //bDescriptorType
0x0200, //bcdUSB
- USB_CLASS_MASS_STORAGE, //bDeviceClass
- 0x06, //bDeviceSubClass
+ 0x0, //bDeviceClass
+ 0x0, //bDeviceSubClass
0x50, //bDeviceProtocol
64, //bMaxPacketSize0
0x01, //bNumConfigurations
@@ -347,7 +347,7 @@ const static struct uhid_comm_descriptor _hid_comm_desc =
USB_DYNAMIC | USB_DIR_IN,
USB_EP_ATTR_INT,
0x40,
- 0x01,
+ 0x0A,
},
/* Endpoint Descriptor OUT */
@@ -372,7 +372,7 @@ const static char* _ustring[] =
"Interface",
};
-static void dump_data(uint8_t *data, rt_size_t size)
+static void dump_data(rt_uint8_t *data, rt_size_t size)
{
rt_size_t i;
for (i = 0; i < size; i++)
@@ -458,8 +458,6 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
struct hid_s *data = (struct hid_s *) func->user_data;
- if(setup->wIndex != 0)
- return -RT_EIO;
switch (setup->bRequest)
{
@@ -489,7 +487,7 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
dcd_ep0_send_status(func->device->dcd);
break;
case USB_HID_REQ_GET_PROTOCOL:
- rt_usbd_ep0_write(func->device, &data->protocol,2);
+ rt_usbd_ep0_write(func->device, &data->protocol,1);
break;
case USB_HID_REQ_SET_REPORT:
@@ -695,8 +693,9 @@ ufunction_t rt_usbd_function_hid_create(udevice_t device)
/* create a cdc function */
func = rt_usbd_function_new(device, &_dev_desc, &ops);
- //not support hs
- //rt_usbd_device_set_qualifier(device, &_dev_qualifier);
+
+ /* For high speed mode supporting */
+ rt_usbd_device_set_qualifier(device, &dev_qualifier);
/* allocate memory for cdc vcom data */
data = (struct hid_s*)rt_malloc(sizeof(struct hid_s));
diff --git a/components/drivers/usb/usbdevice/class/mstorage.c b/components/drivers/usb/usbdevice/class/mstorage.c
index 6a6e92415b..d0a2b7f736 100644
--- a/components/drivers/usb/usbdevice/class/mstorage.c
+++ b/components/drivers/usb/usbdevice/class/mstorage.c
@@ -16,6 +16,10 @@
#include "drivers/usb_device.h"
#include "mstorage.h"
+#ifdef RT_USING_DFS_MNTTABLE
+#include "dfs_fs.h"
+#endif
+
#ifdef RT_USB_DEVICE_MSTORAGE
enum STAT
@@ -422,7 +426,7 @@ static rt_size_t _read_capacity(ufunction_t func, ustorage_cbw_t cbw)
data = (struct mstorage*)func->user_data;
buf = data->ep_in->buffer;
- sector_count = data->geometry.sector_count;
+ sector_count = data->geometry.sector_count - 1; /* Last Logical Block Address */
sector_size = data->geometry.bytes_per_sector;
buf[0] = sector_count >> 24;
@@ -606,8 +610,11 @@ static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size)
rt_usbd_ep_set_stall(func->device, data->ep_out);
}
else
- {
- rt_usbd_ep_set_stall(func->device, data->ep_in);
+ {
+ //rt_kprintf("warning:in stall path but not stall\n");
+
+ /* FIXME: Disable the operation or the disk cannot work. */
+ //rt_usbd_ep_set_stall(func->device, data->ep_in);
}
data->csw_response.data_reside = 0;
}
@@ -715,9 +722,22 @@ static void _cb_len_calc(ufunction_t func, struct scsi_cmd* cmd,
break;
}
}
+
+ //workaround: for stability in full-speed mode
+ else if(cmd->cmd_len == 12)
+ {
+ switch(cmd->type)
+ {
+ case COUNT:
+ data->cb_data_size = cbw->cb[4];
+ break;
+ default:
+ break;
+ }
+ }
else
{
-// rt_kprintf("cmd_len error %d\n", cmd->cmd_len);
+ rt_kprintf("cmd_len error %d\n", cmd->cmd_len);
}
}
@@ -733,7 +753,7 @@ static rt_bool_t _cbw_verify(ufunction_t func, struct scsi_cmd* cmd,
data = (struct mstorage*)func->user_data;
if(cmd->cmd_len != cbw->cb_len)
{
- // rt_kprintf("cb_len error\n");
+ rt_kprintf("cb_len error\n");
cmd->cmd_len = cbw->cb_len;
}
@@ -764,7 +784,7 @@ static rt_bool_t _cbw_verify(ufunction_t func, struct scsi_cmd* cmd,
if(cbw->xfer_len < data->cb_data_size)
{
- // rt_kprintf("xfer_len < data_size\n");
+ rt_kprintf("xfer_len < data_size\n");
data->cb_data_size = cbw->xfer_len;
data->csw_response.status = 1;
}
@@ -955,7 +975,7 @@ static rt_err_t _function_enable(ufunction_t func)
struct mstorage *data;
RT_ASSERT(func != RT_NULL);
RT_DEBUG_LOG(RT_DEBUG_USB, ("Mass storage function enabled\n"));
- data = (struct mstorage*)func->user_data;
+ data = (struct mstorage*)func->user_data;
data->disk = rt_device_find(RT_USB_MSTORAGE_DISK_NAME);
if(data->disk == RT_NULL)
@@ -964,6 +984,10 @@ static rt_err_t _function_enable(ufunction_t func)
return -RT_ERROR;
}
+#ifdef RT_USING_DFS_MNTTABLE
+ dfs_unmount_device(data->disk);
+#endif
+
if(rt_device_open(data->disk, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
{
rt_kprintf("disk open error\n");
@@ -1029,6 +1053,9 @@ static rt_err_t _function_disable(ufunction_t func)
if(data->disk != RT_NULL)
{
rt_device_close(data->disk);
+#ifdef RT_USING_DFS_MNTTABLE
+ dfs_mount_device(data->disk);
+#endif
data->disk = RT_NULL;
}
diff --git a/components/drivers/usb/usbdevice/class/rndis.c b/components/drivers/usb/usbdevice/class/rndis.c
index 8996b728e6..93e0ba6ae2 100644
--- a/components/drivers/usb/usbdevice/class/rndis.c
+++ b/components/drivers/usb/usbdevice/class/rndis.c
@@ -13,21 +13,21 @@
* 2013-07-09 aozima support respone chain list.
* 2013-07-18 aozima re-initial respone chain list when RNDIS restart.
* 2017-11-25 ZYH fix it and add OS descriptor
+ * 2019-06-10 ZYH fix hot plug and delay linkup
*/
#include <rtdevice.h>
+#ifdef RT_USB_DEVICE_RNDIS
#include "cdc.h"
#include "rndis.h"
#include "ndis.h"
-//#define RNDIS_DEBUG
-//#define RNDIS_DELAY_LINK_UP
+/* define RNDIS_DELAY_LINK_UP by menuconfig for delay linkup */
+
+#define DBG_LEVEL DBG_WARNING
+#define DBG_SECTION_NAME "RNDIS"
+#include <rtdbg.h>
-#ifdef RNDIS_DEBUG
-#define RNDIS_PRINTF rt_kprintf("[RNDIS] "); rt_kprintf
-#else
-#define RNDIS_PRINTF(...)
-#endif /* RNDIS_DEBUG */
/* RT-Thread LWIP ethernet interface */
#include <netif/ethernetif.h>
@@ -314,7 +314,7 @@ static rt_err_t _rndis_init_response(ufunction_t func, rndis_init_msg_t msg)
if( (response == RT_NULL) || (resp == RT_NULL) )
{
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
if(response != RT_NULL)
rt_free(response);
@@ -360,7 +360,7 @@ static rndis_query_cmplt_t _create_resp(rt_size_t size)
if(resp == RT_NULL)
{
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
return RT_NULL;
}
@@ -421,7 +421,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
case OID_GEN_LINK_SPEED:
resp = _create_resp(4);
if(resp == RT_NULL) break;
- _set_resp(resp, func->device->dcd->device_is_hs ? (480UL * 1000 *1000) : (12UL * 1000 * 1000) / 100);
+ _set_resp(resp, (func->device->dcd->device_is_hs ? (480UL * 1000 *1000) : (12UL * 1000 * 1000)) / 100);
break;
case OID_GEN_MEDIA_CONNECT_STATUS:
@@ -510,7 +510,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
break;
default:
- RNDIS_PRINTF("OID %X\n", msg->Oid);
+ LOG_W("Not support OID %X", msg->Oid);
ret = -RT_ERROR;
break;
}
@@ -518,7 +518,7 @@ static rt_err_t _rndis_query_response(ufunction_t func,rndis_query_msg_t msg)
response = rt_malloc(sizeof(struct rt_rndis_response));
if( (response == RT_NULL) || (resp == RT_NULL) )
{
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
if(response != RT_NULL)
rt_free(response);
@@ -557,7 +557,7 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
if( (response == RT_NULL) || (resp == RT_NULL) )
{
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
if(response != RT_NULL)
rt_free(response);
@@ -577,8 +577,10 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
case OID_GEN_CURRENT_PACKET_FILTER:
oid_packet_filter = *((rt_uint32_t *)((rt_uint8_t *)&(msg->RequestId) + \
msg->InformationBufferOffset));
+ /* TODO: make complier happy */
oid_packet_filter = oid_packet_filter;
- RNDIS_PRINTF("OID_GEN_CURRENT_PACKET_FILTER\r\n");
+
+ LOG_D("OID_GEN_CURRENT_PACKET_FILTER");
#ifdef RNDIS_DELAY_LINK_UP
/* link up. */
@@ -592,6 +594,7 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
break;
default:
+ LOG_W("Unknow rndis set 0x%02X", msg->Oid);
resp->Status = RNDIS_STATUS_FAILURE;
return RT_EOK;
}
@@ -609,6 +612,56 @@ static rt_err_t _rndis_set_response(ufunction_t func,rndis_set_msg_t msg)
return RT_EOK;
}
+static rt_err_t _rndis_reset_response(ufunction_t func,rndis_set_msg_t msg)
+{
+ struct rndis_reset_cmplt * resp;
+ struct rt_rndis_response * response;
+
+ response = rt_malloc(sizeof(struct rt_rndis_response));
+ resp = rt_malloc(sizeof(struct rndis_reset_cmplt));
+
+ if( (response == RT_NULL) || (resp == RT_NULL) )
+ {
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
+
+ if(response != RT_NULL)
+ rt_free(response);
+
+ if(resp != RT_NULL)
+ rt_free(resp);
+
+ return -RT_ENOMEM;
+ }
+
+ /* reset packet filter */
+
+ oid_packet_filter = 0x0000000;
+
+ /* link down eth */
+
+ eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
+
+ /* reset eth rx tx */
+ ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
+ ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
+
+
+ resp->MessageType = REMOTE_NDIS_RESET_CMPLT;
+ resp->MessageLength = sizeof(struct rndis_reset_cmplt);
+ resp->Status = RNDIS_STATUS_SUCCESS;
+ resp->AddressingReset = 1;
+
+ response->buffer = resp;
+
+ {
+ rt_base_t level = rt_hw_interrupt_disable();
+ rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
+ rt_hw_interrupt_enable(level);
+ }
+
+ return RT_EOK;
+}
+
static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t msg)
{
rndis_keepalive_cmplt_t resp;
@@ -619,7 +672,7 @@ static rt_err_t _rndis_keepalive_response(ufunction_t func,rndis_keepalive_msg_t
if( (response == RT_NULL) || (resp == RT_NULL) )
{
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
if(response != RT_NULL)
rt_free(response);
@@ -652,34 +705,42 @@ static rt_err_t _rndis_msg_parser(ufunction_t func, rt_uint8_t *msg)
switch (((rndis_gen_msg_t) msg)->MessageType)
{
case REMOTE_NDIS_INITIALIZE_MSG:
+ LOG_D("REMOTE_NDIS_INITIALIZE_MSG");
ret = _rndis_init_response(func, (rndis_init_msg_t) msg);
break;
case REMOTE_NDIS_HALT_MSG:
- RNDIS_PRINTF("halt\n");
+ LOG_D("REMOTE_NDIS_HALT_MSG");
/* link down. */
eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
+
+ /* reset eth rx tx */
+ ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
+ ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
break;
case REMOTE_NDIS_QUERY_MSG:
+ LOG_D("REMOTE_NDIS_QUERY_MSG");
ret = _rndis_query_response(func,(rndis_query_msg_t) msg);
break;
case REMOTE_NDIS_SET_MSG:
+ LOG_D("REMOTE_NDIS_SET_MSG");
ret = _rndis_set_response(func,(rndis_set_msg_t) msg);
- RNDIS_PRINTF("set\n");
break;
case REMOTE_NDIS_RESET_MSG:
- RNDIS_PRINTF("reset\n");
+ LOG_D("REMOTE_NDIS_RESET_MSG");
+ ret = _rndis_reset_response(func,(rndis_set_msg_t) msg);
break;
case REMOTE_NDIS_KEEPALIVE_MSG:
+ LOG_D("REMOTE_NDIS_KEEPALIVE_MSG");
ret = _rndis_keepalive_response(func,(rndis_keepalive_msg_t) msg);
break;
default:
- RNDIS_PRINTF("msg %X\n", ((rndis_gen_msg_t) msg)->MessageType);
+ LOG_W("not support RNDIS msg %X", ((rndis_gen_msg_t) msg)->MessageType);
ret = -RT_ERROR;
break;
}
@@ -718,7 +779,7 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
if(rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
{
- RNDIS_PRINTF("response_list is empty!\r\n");
+ LOG_D("response_list is empty!");
((rt_rndis_eth_t)func->user_data)->need_notify = RT_TRUE;
return RT_EOK;
}
@@ -741,7 +802,7 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
{
rt_uint32_t * data;
- RNDIS_PRINTF("auto append next response!\r\n");
+ LOG_I("auto append next response!");
data = (rt_uint32_t *)((rt_rndis_eth_t)func->user_data)->eps.ep_cmd->buffer;
data[0] = RESPONSE_AVAILABLE;
data[1] = 0;
@@ -758,55 +819,6 @@ static rt_err_t _rndis_get_encapsulated_response(ufunction_t func, ureq_t setup)
return RT_EOK;
}
-#ifdef RNDIS_DELAY_LINK_UP
-/**
- * This function will set rndis connect status.
- *
- * @param device the usb device object.
- * @param status the connect status.
- *
- * @return RT_EOK on successful.
- */
-static rt_err_t _rndis_indicate_status_msg(ufunction_t func, rt_uint32_t status)
-{
- rndis_indicate_status_msg_t resp;
- struct rt_rndis_response * response;
-
- response = rt_malloc(sizeof(struct rt_rndis_response));
- resp = rt_malloc(sizeof(struct rndis_indicate_status_msg));
-
- if( (response == RT_NULL) || (resp == RT_NULL) )
- {
- RNDIS_PRINTF("%d: no memory!\r\n", __LINE__);
-
- if(response != RT_NULL)
- rt_free(response);
-
- if(resp != RT_NULL)
- rt_free(resp);
-
- return -RT_ENOMEM;
- }
-
- resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
- resp->MessageLength = 20; /* sizeof(struct rndis_indicate_status_msg) */
- resp->Status = status;
- resp->StatusBufferLength = 0;
- resp->StatusBufferOffset = 0;
-
- response->buffer = resp;
- {
- rt_base_t level = rt_hw_interrupt_disable();
- rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
- rt_hw_interrupt_enable(level);
- }
-
- _rndis_response_available(func);
-
- return RT_EOK;
-}
-#endif /* RNDIS_DELAY_LINK_UP */
-
/**
* This function will handle rndis interface request.
*
@@ -831,7 +843,7 @@ static rt_err_t _interface_handler(ufunction_t func, ureq_t setup)
break;
default:
- RNDIS_PRINTF("unkown setup->request!\r\n");
+ LOG_W("unkown setup->request 0x%02X !", setup->bRequest);
break;
}
@@ -933,6 +945,8 @@ static rt_err_t _function_enable(ufunction_t func)
{
cdc_eps_t eps;
+ LOG_I("plugged in");
+
eps = (cdc_eps_t)&((rt_rndis_eth_t)func->user_data)->eps;
eps->ep_in->buffer = ((rt_rndis_eth_t)func->user_data)->tx_pool;
eps->ep_out->buffer = ((rt_rndis_eth_t)func->user_data)->rx_pool;
@@ -945,6 +959,7 @@ static rt_err_t _function_enable(ufunction_t func)
((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
+ // eth_device_ready(&(((rt_rndis_eth_t)func->user_data)->parent));
#ifdef RNDIS_DELAY_LINK_UP
/* stop link up timer. */
@@ -981,7 +996,7 @@ static rt_err_t _function_enable(ufunction_t func)
*/
static rt_err_t _function_disable(ufunction_t func)
{
- RNDIS_PRINTF("plugged out\n");
+ LOG_I("plugged out");
#ifdef RNDIS_DELAY_LINK_UP
/* stop link up timer. */
@@ -996,7 +1011,7 @@ static rt_err_t _function_disable(ufunction_t func)
while(!rt_list_isempty(&((rt_rndis_eth_t)func->user_data)->response_list))
{
response = (struct rt_rndis_response *)((rt_rndis_eth_t)func->user_data)->response_list.next;
- RNDIS_PRINTF("remove resp chain list!\r\n");
+ LOG_D("remove resp chain list!");
rt_list_remove(&response->list);
rt_free((void *)response->buffer);
@@ -1007,8 +1022,14 @@ static rt_err_t _function_disable(ufunction_t func)
rt_hw_interrupt_enable(level);
}
+
/* link down. */
eth_device_linkchange(&((rt_rndis_eth_t)func->user_data)->parent, RT_FALSE);
+
+ /* reset eth rx tx */
+ ((rt_rndis_eth_t)func->user_data)->rx_frist = RT_TRUE;
+ ((rt_rndis_eth_t)func->user_data)->rx_flag = RT_FALSE;
+
return RT_EOK;
}
@@ -1141,22 +1162,25 @@ rt_err_t rt_rndis_eth_tx(rt_device_t dev, struct pbuf* p)
if(!device->parent.link_status)
{
- RNDIS_PRINTF("linkdown, drop pkg\r\n");
+ LOG_I("linkdown, drop pkg");
return RT_EOK;
}
- RT_ASSERT(p->tot_len < sizeof(device->tx_buffer));
+ //RT_ASSERT(p->tot_len < sizeof(device->tx_buffer));
if(p->tot_len > sizeof(device->tx_buffer))
{
- RNDIS_PRINTF("RNDIS MTU is:%d, but the send packet size is %d\r\n",
+ LOG_W("RNDIS MTU is:%d, but the send packet size is %d",
sizeof(device->tx_buffer), p->tot_len);
p->tot_len = sizeof(device->tx_buffer);
}
/* wait for buffer free. */
- result = rt_sem_take(&device->tx_buffer_free, RT_WAITING_FOREVER);
+ result = rt_sem_take(&device->tx_buffer_free, rt_tick_from_millisecond(1000));
if(result != RT_EOK)
{
+ LOG_W("wait for buffer free timeout");
+ /* if cost 1s to wait send done it said that connection is close . drop it */
+ rt_sem_release(&device->tx_buffer_free);
return result;
}
@@ -1215,11 +1239,59 @@ const static struct rt_device_ops rndis_device_ops =
#endif /* RT_USING_LWIP */
#ifdef RNDIS_DELAY_LINK_UP
+
+/**
+ * This function will set rndis connect status.
+ *
+ * @param device the usb device object.
+ * @param status the connect status.
+ *
+ * @return RT_EOK on successful.
+ */
+static rt_err_t _rndis_indicate_status_msg(ufunction_t func, rt_uint32_t status)
+{
+ rndis_indicate_status_msg_t resp;
+ struct rt_rndis_response * response;
+
+ response = rt_malloc(sizeof(struct rt_rndis_response));
+ resp = rt_malloc(sizeof(struct rndis_indicate_status_msg));
+
+ if( (response == RT_NULL) || (resp == RT_NULL) )
+ {
+ LOG_E("%s,%d: no memory!", __func__, __LINE__);
+
+ if(response != RT_NULL)
+ rt_free(response);
+
+ if(resp != RT_NULL)
+ rt_free(resp);
+
+ return -RT_ENOMEM;
+ }
+
+ resp->MessageType = REMOTE_NDIS_INDICATE_STATUS_MSG;
+ resp->MessageLength = 20; /* sizeof(struct rndis_indicate_status_msg) */
+ resp->Status = status;
+ resp->StatusBufferLength = 0;
+ resp->StatusBufferOffset = 0;
+
+ response->buffer = resp;
+ {
+ rt_base_t level = rt_hw_interrupt_disable();
+ rt_list_insert_before(&((rt_rndis_eth_t)func->user_data)->response_list, &response->list);
+ rt_hw_interrupt_enable(level);
+ }
+
+ _rndis_response_available(func);
+
+ return RT_EOK;
+}
+
/* the delay linkup timer handler. */
static void timer_timeout(void* parameter)
{
- RNDIS_PRINTF("delay link up!\r\n");
- _rndis_indicate_status_msg(((rt_rndis_eth_t)parameter)->parent.parent.user_data,
+ LOG_I("delay link up!");
+ _rndis_indicate_status_msg(((rt_rndis_eth_t)parameter)->func,
RNDIS_STATUS_MEDIA_CONNECT);
eth_device_linkchange(&((rt_rndis_eth_t)parameter)->parent, RT_TRUE);
}
@@ -1319,7 +1391,7 @@ ufunction_t rt_usbd_function_rndis_create(udevice_t device)
timer_timeout,
_rndis,
RT_TICK_PER_SECOND * 2,
- RT_TIMER_FLAG_ONE_SHOT);
+ RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER);
#endif /* RNDIS_DELAY_LINK_UP */
/* OUI 00-00-00, only for test. */
@@ -1372,4 +1444,6 @@ int rt_usbd_rndis_class_register(void)
rt_usbd_class_register(&rndis_class);
return 0;
}
-INIT_PREV_EXPORT(rt_usbd_rndis_class_register); \ No newline at end of file
+INIT_PREV_EXPORT(rt_usbd_rndis_class_register);
+
+#endif /* RT_USB_DEVICE_RNDIS */
diff --git a/components/drivers/usb/usbdevice/class/rndis.h b/components/drivers/usb/usbdevice/class/rndis.h
index 000ea62baf..fcdd249984 100644
--- a/components/drivers/usb/usbdevice/class/rndis.h
+++ b/components/drivers/usb/usbdevice/class/rndis.h
@@ -180,6 +180,15 @@ struct rndis_reset_msg
rt_uint32_t Reserved;
};
+/* Remote NDIS Soft Reset Response */
+struct rndis_reset_cmplt
+{
+ rt_uint32_t MessageType;
+ rt_uint32_t MessageLength;
+ rt_uint32_t Status;
+ rt_uint32_t AddressingReset;
+};
+
/* Remote NDIS Indicate Status Message */
struct rndis_indicate_status_msg
{
diff --git a/components/drivers/usb/usbdevice/class/winusb.c b/components/drivers/usb/usbdevice/class/winusb.c
index bf4b353d73..729e39f663 100644
--- a/components/drivers/usb/usbdevice/class/winusb.c
+++ b/components/drivers/usb/usbdevice/class/winusb.c
@@ -121,7 +121,7 @@ const static char* _ustring[] =
ALIGN(4)
struct usb_os_proerty winusb_proerty[] =
{
- USB_OS_PROERTY_DESC(USB_OS_PROERTY_TYPE_REG_SZ,"DeviceInterfaceGUID",RT_WINUSB_GUID),
+ USB_OS_PROPERTY_DESC(USB_OS_PROPERTY_TYPE_REG_SZ,"DeviceInterfaceGUID",RT_WINUSB_GUID),
};
ALIGN(4)
diff --git a/components/drivers/usb/usbdevice/core/core.c b/components/drivers/usb/usbdevice/core/usbdevice_core.c
index fb850d6d2b..ef569d7bf2 100644
--- a/components/drivers/usb/usbdevice/core/core.c
+++ b/components/drivers/usb/usbdevice/core/usbdevice_core.c
@@ -194,7 +194,18 @@ static rt_err_t _get_descriptor(struct udevice* device, ureq_t setup)
_get_string_descriptor(device, setup);
break;
case USB_DESC_TYPE_DEVICEQUALIFIER:
- _get_qualifier_descriptor(device, setup);
+ /* If a full-speed only device (with a device descriptor version number equal to 0200H) receives a
+ GetDescriptor() request for a device_qualifier, it must respond with a request error. The host must not make
+ a request for an other_speed_configuration descriptor unless it first successfully retrieves the
+ device_qualifier descriptor. */
+ if(device->dcd->device_is_hs)
+ {
+ _get_qualifier_descriptor(device, setup);
+ }
+ else
+ {
+ rt_usbd_ep0_set_stall(device);
+ }
break;
case USB_DESC_TYPE_OTHERSPEED:
_get_config_descriptor(device, setup);
@@ -226,7 +237,8 @@ static rt_err_t _get_interface(struct udevice* device, ureq_t setup)
{
rt_uint8_t value;
uintf_t intf;
-
+ ufunction_t func;
+
/* parameter check */
RT_ASSERT(device != RT_NULL);
RT_ASSERT(setup != RT_NULL);
@@ -240,12 +252,17 @@ static rt_err_t _get_interface(struct udevice* device, ureq_t setup)
}
/* find the specified interface and its alternate setting */
- intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, RT_NULL);
+ intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func);
value = intf->curr_setting->intf_desc->bAlternateSetting;
/* send the interface alternate setting to endpoint 0*/
rt_usbd_ep0_write(device, &value, 1);
+ if (intf->handler)
+ {
+ intf->handler(func, setup);
+ }
+
return RT_EOK;
}
@@ -259,6 +276,7 @@ static rt_err_t _get_interface(struct udevice* device, ureq_t setup)
*/
static rt_err_t _set_interface(struct udevice* device, ureq_t setup)
{
+ ufunction_t func;
uintf_t intf;
uep_t ep;
struct rt_list_node* i;
@@ -277,7 +295,7 @@ static rt_err_t _set_interface(struct udevice* device, ureq_t setup)
}
/* find the specified interface */
- intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, RT_NULL);
+ intf = rt_usbd_find_interface(device, setup->wIndex & 0xFF, &func);
/* set alternate setting to the interface */
rt_usbd_set_altsetting(intf, setup->wValue & 0xFF);
@@ -292,6 +310,11 @@ static rt_err_t _set_interface(struct udevice* device, ureq_t setup)
}
dcd_ep0_send_status(device->dcd);
+ if (intf->handler)
+ {
+ intf->handler(func, setup);
+ }
+
return RT_EOK;
}
@@ -984,10 +1007,10 @@ udevice_t rt_usbd_device_new(void)
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbd_device_new\n"));
/* allocate memory for the object */
- udevice = rt_malloc(sizeof(struct udevice));
+ udevice = (udevice_t)rt_malloc(sizeof(struct udevice));
if(udevice == RT_NULL)
{
- rt_kprintf("alloc memery failed\n");
+ rt_kprintf("alloc memory failed\n");
return RT_NULL;
}
rt_memset(udevice, 0, sizeof(struct udevice));
@@ -1098,10 +1121,10 @@ uconfig_t rt_usbd_config_new(void)
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbd_config_new\n"));
/* allocate memory for the object */
- cfg = rt_malloc(sizeof(struct uconfig));
+ cfg = (uconfig_t)rt_malloc(sizeof(struct uconfig));
if(cfg == RT_NULL)
{
- rt_kprintf("alloc memery failed\n");
+ rt_kprintf("alloc memory failed\n");
return RT_NULL;
}
rt_memset(cfg, 0, sizeof(struct uconfig));
@@ -1140,7 +1163,7 @@ uintf_t rt_usbd_interface_new(udevice_t device, uintf_handler_t handler)
intf = (uintf_t)rt_malloc(sizeof(struct uinterface));
if(intf == RT_NULL)
{
- rt_kprintf("alloc memery failed\n");
+ rt_kprintf("alloc memory failed\n");
return RT_NULL;
}
intf->intf_num = device->nr_intf;
@@ -1175,14 +1198,14 @@ ualtsetting_t rt_usbd_altsetting_new(rt_size_t desc_size)
setting = (ualtsetting_t)rt_malloc(sizeof(struct ualtsetting));
if(setting == RT_NULL)
{
- rt_kprintf("alloc memery failed\n");
+ rt_kprintf("alloc memory failed\n");
return RT_NULL;
}
/* allocate memory for the desc */
setting->desc = rt_malloc(desc_size);
if (setting->desc == RT_NULL)
{
- rt_kprintf("alloc desc memery failed\n");
+ rt_kprintf("alloc desc memory failed\n");
rt_free(setting);
return RT_NULL;
}
@@ -1240,7 +1263,7 @@ ufunction_t rt_usbd_function_new(udevice_t device, udev_desc_t dev_desc,
func = (ufunction_t)rt_malloc(sizeof(struct ufunction));
if(func == RT_NULL)
{
- rt_kprintf("alloc memery failed\n");
+ rt_kprintf("alloc memory failed\n");
return RT_NULL;
}
func->dev_desc = dev_desc;
@@ -1275,7 +1298,7 @@ uep_t rt_usbd_endpoint_new(uep_desc_t ep_desc, udep_handler_t handler)
ep = (uep_t)rt_malloc(sizeof(struct uendpoint));
if(ep == RT_NULL)
{
- rt_kprintf("alloc memery failed\n");
+ rt_kprintf("alloc memory failed\n");
return RT_NULL;
}
ep->ep_desc = ep_desc;
@@ -1477,9 +1500,10 @@ uep_t rt_usbd_find_endpoint(udevice_t device, ufunction_t* pfunc, rt_uint8_t ep_
*/
rt_err_t rt_usbd_device_add_config(udevice_t device, uconfig_t cfg)
{
- struct rt_list_node *i, *j, *k;
+ struct rt_list_node *i, *j, *k, *m;
ufunction_t func;
uintf_t intf;
+ ualtsetting_t altsetting;
uep_t ep;
RT_DEBUG_LOG(RT_DEBUG_USB, ("rt_usbd_device_add_config\n"));
@@ -1501,22 +1525,26 @@ rt_err_t rt_usbd_device_add_config(udevice_t device, uconfig_t cfg)
intf = (uintf_t)rt_list_entry(j, struct uinterface, list);
cfg->cfg_desc.bNumInterfaces++;
- /* allocate address for every endpoint in the interface alternate setting */
- for(k=intf->curr_setting->ep_list.next;
- k!=&intf->curr_setting->ep_list; k=k->next)
+ for(k=intf->setting_list.next; k!=&intf->setting_list;k=k->next)
{
- ep = (uep_t)rt_list_entry(k, struct uendpoint, list);
- if(rt_usbd_ep_assign(device, ep) != RT_EOK)
+ altsetting = (ualtsetting_t)rt_list_entry(k, struct ualtsetting, list);
+
+ /* allocate address for every endpoint in the interface alternate setting */
+ for(m=altsetting->ep_list.next; m!=&altsetting->ep_list; m=m->next)
{
- rt_kprintf("endpoint assign error\n");
+ ep = (uep_t)rt_list_entry(m, struct uendpoint, list);
+ if(rt_usbd_ep_assign(device, ep) != RT_EOK)
+ {
+ rt_kprintf("endpoint assign error\n");
+ }
}
- }
- /* construct complete configuration descriptor */
- rt_memcpy((void*)&cfg->cfg_desc.data[cfg->cfg_desc.wTotalLength - USB_DESC_LENGTH_CONFIG],
- (void*)intf->curr_setting->desc,
- intf->curr_setting->desc_size);
- cfg->cfg_desc.wTotalLength += intf->curr_setting->desc_size;
+ /* construct complete configuration descriptor */
+ rt_memcpy((void*)&cfg->cfg_desc.data[cfg->cfg_desc.wTotalLength - USB_DESC_LENGTH_CONFIG],
+ (void*)altsetting->desc,
+ altsetting->desc_size);
+ cfg->cfg_desc.wTotalLength += altsetting->desc_size;
+ }
}
}
@@ -2042,7 +2070,7 @@ rt_size_t rt_usbd_ep0_write(udevice_t device, void *buffer, rt_size_t size)
ep0 = &device->dcd->ep0;
ep0->request.size = size;
- ep0->request.buffer = buffer;
+ ep0->request.buffer = (rt_uint8_t *)buffer;
ep0->request.remain_size = size;
if(size >= ep0->id->maxpacket)
{
@@ -2068,7 +2096,7 @@ rt_size_t rt_usbd_ep0_read(udevice_t device, void *buffer, rt_size_t size,
RT_ASSERT(buffer != RT_NULL);
ep0 = &device->dcd->ep0;
- ep0->request.buffer = buffer;
+ ep0->request.buffer = (rt_uint8_t *)buffer;
ep0->request.remain_size = size;
ep0->rx_indicate = rx_ind;
if(size >= ep0->id->maxpacket)
@@ -2176,7 +2204,7 @@ static struct rt_thread usb_thread;
#define USBD_MQ_MAX_MSG 16
/* internal of the message queue: every message is associated with a pointer,
* so in order to recveive USBD_MQ_MAX_MSG messages, we have to allocate more
- * than USBD_MQ_MSG_SZ*USBD_MQ_MAX_MSG memery. */
+ * than USBD_MQ_MSG_SZ*USBD_MQ_MAX_MSG memory. */
static rt_uint8_t usb_mq_pool[(USBD_MQ_MSG_SZ+sizeof(void*))*USBD_MQ_MAX_MSG];
/**
diff --git a/components/drivers/usb/usbhost/SConscript b/components/drivers/usb/usbhost/SConscript
index b12adfc5ad..081c732819 100644
--- a/components/drivers/usb/usbhost/SConscript
+++ b/components/drivers/usb/usbhost/SConscript
@@ -3,7 +3,7 @@ from building import *
cwd = GetCurrentDir()
src = Split("""
-core/core.c
+core/usbhost_core.c
core/driver.c
core/usbhost.c
core/hub.c
diff --git a/components/drivers/usb/usbhost/class/adk.h b/components/drivers/usb/usbhost/class/adk.h
index 041d47c674..c582ad7f17 100644
--- a/components/drivers/usb/usbhost/class/adk.h
+++ b/components/drivers/usb/usbhost/class/adk.h
@@ -8,8 +8,8 @@
* 2011-12-12 Yi Qiu first version
*/
-#ifndef __HID_H__
-#define __HID_H__
+#ifndef __ADK_H__
+#define __ADK_H__
#include <rtthread.h>
diff --git a/components/drivers/usb/usbhost/class/udisk.c b/components/drivers/usb/usbhost/class/udisk.c
index 1509a26105..6c8030b29a 100644
--- a/components/drivers/usb/usbhost/class/udisk.c
+++ b/components/drivers/usb/usbhost/class/udisk.c
@@ -186,7 +186,7 @@ rt_err_t rt_udisk_run(struct uhintf* intf)
{
int i = 0;
rt_err_t ret;
- char dname[4];
+ char dname[8];
char sname[8];
rt_uint8_t max_lun, *sector, sense[18], inquiry[36];
struct dfs_partition part[MAX_PARTITION_COUNT];
diff --git a/components/drivers/usb/usbhost/core/hub.c b/components/drivers/usb/usbhost/core/hub.c
index 80ed9b4e3f..eefa571472 100644
--- a/components/drivers/usb/usbhost/core/hub.c
+++ b/components/drivers/usb/usbhost/core/hub.c
@@ -417,8 +417,13 @@ static rt_err_t rt_usbh_hub_port_change(uhub_t hub)
if(reconnect)
{
- if(hub->child[i] != RT_NULL && hub->child[i]->status != DEV_STATUS_IDLE)
+ if(hub->child[i] != RT_NULL && hub->child[i]->status != DEV_STATUS_IDLE)
+ {
rt_usbh_detach_instance(hub->child[i]);
+
+ /* Child device have been detach. Set hub->child[i] to NULL. */
+ hub->child[i] = RT_NULL;
+ }
ret = rt_usbh_hub_port_debounce(hub, i + 1);
if(ret != RT_EOK) continue;
@@ -508,6 +513,7 @@ static rt_err_t rt_usbh_hub_enable(void *arg)
/* create a hub instance */
hub = rt_malloc(sizeof(struct uhub));
+ RT_ASSERT(hub != RT_NULL);
rt_memset(hub, 0, sizeof(struct uhub));
/* make interface instance's user data point to hub instance */
@@ -531,7 +537,12 @@ static rt_err_t rt_usbh_hub_enable(void *arg)
}
/* get hub ports number */
- hub->num_ports = hub->hub_desc.num_ports;
+ /* If hub device supported ports over USB_HUB_PORT_NUM(Ex: 8 port hub). Set hub->num_ports to USB_HUB_PORT_NUM */
+ if(hub->hub_desc.num_ports > USB_HUB_PORT_NUM)
+ hub->num_ports = USB_HUB_PORT_NUM;
+ else
+ hub->num_ports = hub->hub_desc.num_ports;
+
hub->hcd = device->hcd;
hub->self = device;
@@ -606,7 +617,6 @@ static rt_err_t rt_usbh_hub_disable(void* arg)
}
if(hub != RT_NULL) rt_free(hub);
- if(intf != RT_NULL) rt_free(intf);
return RT_EOK;
}
diff --git a/components/drivers/usb/usbhost/core/core.c b/components/drivers/usb/usbhost/core/usbhost_core.c
index 71341a33c3..d72dca82f2 100644
--- a/components/drivers/usb/usbhost/core/core.c
+++ b/components/drivers/usb/usbhost/core/usbhost_core.c
@@ -162,6 +162,10 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
/* alloc memory for configuration descriptor */
device->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength);
+ if(device->cfg_desc == RT_NULL)
+ {
+ return RT_ENOMEM;
+ }
rt_memset(device->cfg_desc, 0, cfg_desc.wTotalLength);
/* get full configuration descriptor */
@@ -219,6 +223,10 @@ rt_err_t rt_usbh_attatch_instance(uinst_t device)
{
/* allocate memory for interface device */
device->intf[i] = (struct uhintf*)rt_malloc(sizeof(struct uhintf));
+ if(device->intf[i] == RT_NULL)
+ {
+ return RT_ENOMEM;
+ }
device->intf[i]->drv = drv;
device->intf[i]->device = device;
device->intf[i]->intf_desc = intf_desc;
diff --git a/components/drivers/watchdog/watchdog.c b/components/drivers/watchdog/watchdog.c
index 196f02039d..09a6bf4fad 100644
--- a/components/drivers/watchdog/watchdog.c
+++ b/components/drivers/watchdog/watchdog.c
@@ -14,7 +14,7 @@
/* RT-Thread Device Interface */
/*
- * This function initializes serial
+ * This function initializes watchdog
*/
static rt_err_t rt_watchdog_init(struct rt_device *dev)
{
diff --git a/components/drivers/wlan/SConscript b/components/drivers/wlan/SConscript
index 271ca66a80..f2a6bbdc82 100644
--- a/components/drivers/wlan/SConscript
+++ b/components/drivers/wlan/SConscript
@@ -1,8 +1,30 @@
from building import *
cwd = GetCurrentDir()
-src = Glob('*.c')
CPPPATH = [cwd]
+
+src = Split('''
+ wlan_dev.c
+ ''')
+
+if GetDepend(['RT_WLAN_MANAGE_ENABLE']):
+ src += ['wlan_mgnt.c']
+
+if GetDepend(['RT_WLAN_MSH_CMD_ENABLE']):
+ src += ['wlan_cmd.c']
+
+if GetDepend(['RT_WLAN_PROT_ENABLE']):
+ src += ['wlan_prot.c']
+
+if GetDepend(['RT_WLAN_PROT_LWIP_ENABLE']):
+ src += ['wlan_lwip.c']
+
+if GetDepend(['RT_WLAN_CFG_ENABLE']):
+ src += ['wlan_cfg.c']
+
+if GetDepend(['RT_WLAN_WORK_THREAD_ENABLE']):
+ src += ['wlan_workqueue.c']
+
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_WIFI'], CPPPATH = CPPPATH)
Return('group')
diff --git a/components/drivers/wlan/wlan_cfg.c b/components/drivers/wlan/wlan_cfg.c
index 27da9bc24e..7fa9ecb2da 100644
--- a/components/drivers/wlan/wlan_cfg.c
+++ b/components/drivers/wlan/wlan_cfg.c
@@ -11,16 +11,16 @@
#include <rtthread.h>
#include <wlan_cfg.h>
-#define DBG_ENABLE
+#define DBG_TAG "WLAN.cfg"
#ifdef RT_WLAN_CFG_DEBUG
-#define DBG_LEVEL DBG_LOG
+#define DBG_LVL DBG_LOG
#else
-#define DBG_LEVEL DBG_INFO
-#endif
-#define DBG_SECTION_NAME "WLAN.cfg"
-#define DBG_COLOR
+#define DBG_LVL DBG_INFO
+#endif /* RT_WLAN_CFG_DEBUG */
#include <rtdbg.h>
+#ifdef RT_WLAN_CFG_ENABLE
+
#define WLAN_CFG_LOCK() (rt_mutex_take(&cfg_mutex, RT_WAITING_FOREVER))
#define WLAN_CFG_UNLOCK() (rt_mutex_release(&cfg_mutex))
@@ -57,9 +57,12 @@ static rt_uint16_t rt_wlan_cal_crc(rt_uint8_t *buff, int len)
while (len--)
{
+ int i;
+
wChar = *(buff++);
wCRCin ^= (wChar << 8);
- for (int i = 0; i < 8; i++)
+
+ for (i = 0; i < 8; i++)
{
if (wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
@@ -461,3 +464,5 @@ void rt_wlan_cfg_dump(void)
rt_kprintf("%3d \n", info->channel);
}
}
+
+#endif
diff --git a/components/drivers/wlan/wlan_cmd.c b/components/drivers/wlan/wlan_cmd.c
index b962b63947..fead6a8bf2 100644
--- a/components/drivers/wlan/wlan_cmd.c
+++ b/components/drivers/wlan/wlan_cmd.c
@@ -13,6 +13,8 @@
#include <wlan_cfg.h>
#include <wlan_prot.h>
+#if defined(RT_WLAN_MANAGE_ENABLE) && defined(RT_WLAN_MSH_CMD_ENABLE)
+
struct wifi_cmd_des
{
const char *cmd;
@@ -75,7 +77,7 @@ static int wifi_help(int argc, char *argv[])
{
rt_kprintf("wifi\n");
rt_kprintf("wifi help\n");
- rt_kprintf("wifi scan\n");
+ rt_kprintf("wifi scan [SSID]\n");
rt_kprintf("wifi join [SSID] [PASSWORD]\n");
rt_kprintf("wifi ap SSID [PASSWORD]\n");
rt_kprintf("wifi disc\n");
@@ -143,12 +145,23 @@ static int wifi_status(int argc, char *argv[])
static int wifi_scan(int argc, char *argv[])
{
struct rt_wlan_scan_result *scan_result = RT_NULL;
+ struct rt_wlan_info *info = RT_NULL;
+ struct rt_wlan_info filter;
- if (argc > 2)
+ if (argc > 3)
return -1;
+ if (argc == 3)
+ {
+ INVALID_INFO(&filter);
+ SSID_SET(&filter, argv[2]);
+ info = &filter;
+ }
+
+ /* clean scan result */
+ rt_wlan_scan_result_clean();
/* scan ap info */
- scan_result = rt_wlan_scan_sync();
+ scan_result = rt_wlan_scan_with_info(info);
if (scan_result)
{
int index, num;
@@ -224,8 +237,10 @@ static int wifi_join(int argc, char *argv[])
const char *key = RT_NULL;
struct rt_wlan_cfg_info cfg_info;
+ rt_memset(&cfg_info, 0, sizeof(cfg_info));
if (argc == 2)
{
+#ifdef RT_WLAN_CFG_ENABLE
/* get info to connect */
if (rt_wlan_cfg_read_index(&cfg_info, 0) == 1)
{
@@ -234,8 +249,9 @@ static int wifi_join(int argc, char *argv[])
key = (char *)(&cfg_info.key.val[0]);
}
else
+#endif
{
- rt_kprintf("not find info\n");
+ rt_kprintf("not find connect info\n");
}
}
else if (argc == 3)
@@ -387,8 +403,9 @@ static int wifi_debug_save_cfg(int argc, char *argv[])
rt_memcpy(&cfg_info.key.val[0], password, len);
cfg_info.key.len = len;
}
-
+#ifdef RT_WLAN_CFG_ENABLE
rt_wlan_cfg_save(&cfg_info);
+#endif
return 0;
}
@@ -396,7 +413,9 @@ static int wifi_debug_dump_cfg(int argc, char *argv[])
{
if (argc == 1)
{
+#ifdef RT_WLAN_CFG_ENABLE
rt_wlan_cfg_dump();
+#endif
}
else
{
@@ -409,8 +428,10 @@ static int wifi_debug_clear_cfg(int argc, char *argv[])
{
if (argc == 1)
{
+#ifdef RT_WLAN_CFG_ENABLE
rt_wlan_cfg_delete_all();
rt_wlan_cfg_cache_save();
+#endif
}
else
{
@@ -447,6 +468,10 @@ static int wifi_debug_set_mode(int argc, char *argv[])
{
mode = RT_WLAN_AP;
}
+ else if (rt_strcmp("none", argv[1]) == 0)
+ {
+ mode = RT_WLAN_NONE;
+ }
else
return -1;
@@ -564,3 +589,5 @@ static int wifi_msh(int argc, char *argv[])
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
FINSH_FUNCTION_EXPORT_ALIAS(wifi_msh, __cmd_wifi, wifi command.);
#endif
+
+#endif
diff --git a/components/drivers/wlan/wlan_dev.c b/components/drivers/wlan/wlan_dev.c
index 387f65fde2..53b6138e99 100644
--- a/components/drivers/wlan/wlan_dev.c
+++ b/components/drivers/wlan/wlan_dev.c
@@ -13,16 +13,16 @@
#include <wlan_dev.h>
#include <wlan_prot.h>
-#define DBG_ENABLE
+#define DBG_TAG "WLAN.dev"
#ifdef RT_WLAN_DEV_DEBUG
-#define DBG_LEVEL DBG_LOG
+#define DBG_LVL DBG_LOG
#else
-#define DBG_LEVEL DBG_INFO
-#endif
-#define DBG_SECTION_NAME "WLAN.dev"
-#define DBG_COLOR
+#define DBG_LVL DBG_INFO
+#endif /* RT_WLAN_DEV_DEBUG */
#include <rtdbg.h>
+#if defined(RT_USING_WIFI) || defined(RT_USING_WLAN)
+
#ifndef RT_DEVICE
#define RT_DEVICE(__device) ((rt_device_t)__device)
#endif
@@ -58,6 +58,17 @@ rt_err_t rt_wlan_dev_init(struct rt_wlan_device *device, rt_wlan_mode_t mode)
return -RT_ERROR;
}
+ if (mode == RT_WLAN_AP && device->flags & RT_WLAN_FLAG_STA_ONLY)
+ {
+ LOG_E("F:%s L:%d This wlan device can only be set to sta mode!", __FUNCTION__, __LINE__);
+ return -RT_ERROR;
+ }
+ else if (mode == RT_WLAN_STATION && device->flags & RT_WLAN_FLAG_AP_ONLY)
+ {
+ LOG_E("F:%s L:%d This wlan device can only be set to ap mode!", __FUNCTION__, __LINE__);
+ return -RT_ERROR;
+ }
+
result = rt_device_init(RT_DEVICE(device));
if (result != RT_EOK)
{
@@ -91,7 +102,7 @@ rt_err_t rt_wlan_dev_connect(struct rt_wlan_device *device, struct rt_wlan_info
if ((password_len > RT_WLAN_PASSWORD_MAX_LENGTH) ||
(info->ssid.len > RT_WLAN_SSID_MAX_LENGTH))
{
- LOG_E("L:%d password or ssid is to long", __LINE__);
+ LOG_E("L:%d password or ssid is too long", __LINE__);
return -RT_ERROR;
}
rt_memset(&sta_info, 0, sizeof(struct rt_sta_info));
@@ -136,16 +147,19 @@ rt_err_t rt_wlan_dev_ap_start(struct rt_wlan_device *device, struct rt_wlan_info
return -RT_ERROR;
}
- if ((password_len >= RT_WLAN_PASSWORD_MAX_LENGTH) ||
- (info->ssid.len >= RT_WLAN_SSID_MAX_LENGTH))
+ if ((password_len > RT_WLAN_PASSWORD_MAX_LENGTH) ||
+ (info->ssid.len > RT_WLAN_SSID_MAX_LENGTH))
{
- LOG_E("L:%d password or ssid is to long", __LINE__);
+ LOG_E("L:%d password or ssid is too long", __LINE__);
return -RT_ERROR;
}
rt_memset(&ap_info, 0, sizeof(struct rt_ap_info));
rt_memcpy(&ap_info.ssid, &info->ssid, sizeof(rt_wlan_ssid_t));
- rt_memcpy(ap_info.key.val, password, password_len);
+ if (password != RT_NULL)
+ {
+ rt_memcpy(ap_info.key.val, password, password_len);
+ }
ap_info.key.len = password_len;
ap_info.hidden = info->hidden;
ap_info.channel = info->channel;
@@ -184,13 +198,21 @@ rt_err_t rt_wlan_dev_ap_deauth(struct rt_wlan_device *device, rt_uint8_t mac[6])
int rt_wlan_dev_get_rssi(struct rt_wlan_device *device)
{
int rssi = 0;
+ rt_err_t result = RT_EOK;
if (device == RT_NULL)
{
- return -RT_EIO;
+ rt_set_errno(-RT_EIO);
+ return 0;
+ }
+
+ result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_RSSI, &rssi);
+ if (result != RT_EOK)
+ {
+ rt_set_errno(result);
+ return 0;
}
- rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_RSSI, &rssi);
return rssi;
}
@@ -235,14 +257,20 @@ rt_err_t rt_wlan_dev_set_powersave(struct rt_wlan_device *device, int level)
int rt_wlan_dev_get_powersave(struct rt_wlan_device *device)
{
- int level = 0;
+ int level = -1;
+ rt_err_t result = RT_EOK;
if (device == RT_NULL)
{
+ rt_set_errno(-RT_EIO);
return -1;
}
- rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_POWERSAVE, &level);
+ result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_POWERSAVE, &level);
+ if (result != RT_EOK)
+ {
+ rt_set_errno(result);
+ }
return level;
}
@@ -432,19 +460,21 @@ rt_err_t rt_wlan_dev_set_channel(struct rt_wlan_device *device, int channel)
return result;
}
-rt_err_t rt_wlan_dev_get_channel(struct rt_wlan_device *device)
+int rt_wlan_dev_get_channel(struct rt_wlan_device *device)
{
rt_err_t result = RT_EOK;
- int channel;
+ int channel = -1;
if (device == RT_NULL)
{
- return -RT_EIO;
+ rt_set_errno(-RT_EIO);
+ return -1;
}
result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_CHANNEL, &channel);
if (result != RT_EOK)
{
+ rt_set_errno(result);
return -1;
}
@@ -466,17 +496,19 @@ rt_err_t rt_wlan_dev_set_country(struct rt_wlan_device *device, rt_country_code_
rt_country_code_t rt_wlan_dev_get_country(struct rt_wlan_device *device)
{
- int result = 0;
+ int result = RT_EOK;
rt_country_code_t country_code = RT_COUNTRY_UNKNOWN;
if (device == RT_NULL)
{
- return country_code;
+ rt_set_errno(-RT_EIO);
+ return RT_COUNTRY_UNKNOWN;
}
result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_GET_COUNTRY, &country_code);
if (result != RT_EOK)
{
+ rt_set_errno(result);
return RT_COUNTRY_UNKNOWN;
}
@@ -496,15 +528,24 @@ rt_err_t rt_wlan_dev_scan(struct rt_wlan_device *device, struct rt_wlan_info *in
if (info != RT_NULL)
{
- if (info->ssid.len >= RT_WLAN_SSID_MAX_LENGTH)
+ if (info->ssid.len > RT_WLAN_SSID_MAX_LENGTH)
{
- LOG_E("L:%d ssid is to long", __LINE__);
+ LOG_E("L:%d ssid is too long", __LINE__);
return -RT_EINVAL;
}
rt_memcpy(&scan_info.ssid, &info->ssid, sizeof(rt_wlan_ssid_t));
rt_memcpy(scan_info.bssid, info->bssid, RT_WLAN_BSSID_MAX_LENGTH);
- scan_info.channel_min = -1;
- scan_info.channel_max = -1;
+ if (info->channel > 0)
+ {
+ scan_info.channel_min = info->channel;
+ scan_info.channel_max = info->channel;
+ }
+ else
+ {
+ scan_info.channel_min = -1;
+ scan_info.channel_max = -1;
+ }
+ scan_info.passive = info->hidden ? RT_TRUE : RT_FALSE;
p_scan_info = &scan_info;
}
result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_SCAN, p_scan_info);
@@ -526,7 +567,82 @@ rt_err_t rt_wlan_dev_scan_stop(struct rt_wlan_device *device)
rt_err_t rt_wlan_dev_report_data(struct rt_wlan_device *device, void *buff, int len)
{
+#ifdef RT_WLAN_PROT_ENABLE
return rt_wlan_dev_transfer_prot(device, buff, len);
+#else
+ return -RT_ERROR;
+#endif
+}
+
+rt_err_t rt_wlan_dev_enter_mgnt_filter(struct rt_wlan_device *device)
+{
+ rt_err_t result = RT_EOK;
+ int enable = 1;
+
+ if (device == RT_NULL)
+ {
+ return -RT_EIO;
+ }
+
+ result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_CFG_MGNT_FILTER, &enable);
+ return result;
+}
+
+rt_err_t rt_wlan_dev_exit_mgnt_filter(struct rt_wlan_device *device)
+{
+ rt_err_t result = RT_EOK;
+ int enable = 0;
+
+ if (device == RT_NULL)
+ {
+ return -RT_EIO;
+ }
+
+ result = rt_device_control(RT_DEVICE(device), RT_WLAN_CMD_CFG_MGNT_FILTER, &enable);
+ return result;
+}
+
+rt_err_t rt_wlan_dev_set_mgnt_filter_callback(struct rt_wlan_device *device, rt_wlan_mgnt_filter_callback_t callback)
+{
+ if (device == RT_NULL)
+ {
+ return -RT_EIO;
+ }
+ device->mgnt_filter_callback = callback;
+
+ return RT_EOK;
+}
+
+void rt_wlan_dev_mgnt_filter_handler(struct rt_wlan_device *device, void *data, int len)
+{
+ rt_wlan_mgnt_filter_callback_t callback;
+
+ if (device == RT_NULL)
+ {
+ return;
+ }
+
+ callback = device->mgnt_filter_callback;
+
+ if (callback != RT_NULL)
+ {
+ callback(device, data, len);
+ }
+}
+
+int rt_wlan_dev_send_raw_frame(struct rt_wlan_device *device, void *buff, int len)
+{
+ if (device == RT_NULL)
+ {
+ return -RT_EIO;
+ }
+
+ if (device->ops->wlan_send_raw_frame)
+ {
+ return device->ops->wlan_send_raw_frame(device, buff, len);
+ }
+
+ return -RT_ERROR;
}
static rt_err_t _rt_wlan_dev_init(rt_device_t dev)
@@ -641,7 +757,7 @@ static rt_err_t _rt_wlan_dev_control(rt_device_t dev, int cmd, void *args)
LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SET_POWERSAVE, "RT_WLAN_CMD_SET_POWERSAVE");
if (wlan->ops->wlan_set_powersave)
- wlan->ops->wlan_set_powersave(wlan, level);
+ err = wlan->ops->wlan_set_powersave(wlan, level);
break;
}
case RT_WLAN_CMD_GET_POWERSAVE:
@@ -659,7 +775,7 @@ static rt_err_t _rt_wlan_dev_control(rt_device_t dev, int cmd, void *args)
LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_CFG_PROMISC, "RT_WLAN_CMD_CFG_PROMISC");
if (wlan->ops->wlan_cfg_promisc)
- wlan->ops->wlan_cfg_promisc(wlan, start);
+ err = wlan->ops->wlan_cfg_promisc(wlan, start);
break;
}
case RT_WLAN_CMD_CFG_FILTER:
@@ -668,7 +784,16 @@ static rt_err_t _rt_wlan_dev_control(rt_device_t dev, int cmd, void *args)
LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_CFG_FILTER, "RT_WLAN_CMD_CFG_FILTER");
if (wlan->ops->wlan_cfg_filter)
- wlan->ops->wlan_cfg_filter(wlan, filter);
+ err = wlan->ops->wlan_cfg_filter(wlan, filter);
+ break;
+ }
+ case RT_WLAN_CMD_CFG_MGNT_FILTER:
+ {
+ rt_bool_t start = *((rt_bool_t *)args);
+
+ LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_CFG_MGNT_FILTER, "RT_WLAN_CMD_CFG_MGNT_FILTER");
+ if (wlan->ops->wlan_cfg_mgnt_filter)
+ err = wlan->ops->wlan_cfg_mgnt_filter(wlan, start);
break;
}
case RT_WLAN_CMD_SET_CHANNEL:
@@ -676,7 +801,7 @@ static rt_err_t _rt_wlan_dev_control(rt_device_t dev, int cmd, void *args)
int channel = *(int *)args;
LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SET_CHANNEL, "RT_WLAN_CMD_SET_CHANNEL");
if (wlan->ops->wlan_set_channel)
- wlan->ops->wlan_set_channel(wlan, channel);
+ err = wlan->ops->wlan_set_channel(wlan, channel);
break;
}
case RT_WLAN_CMD_GET_CHANNEL:
@@ -694,7 +819,7 @@ static rt_err_t _rt_wlan_dev_control(rt_device_t dev, int cmd, void *args)
LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SET_COUNTRY, "RT_WLAN_CMD_SET_COUNTRY");
if (wlan->ops->wlan_set_country)
- wlan->ops->wlan_set_country(wlan, country);
+ err = wlan->ops->wlan_set_country(wlan, country);
break;
}
case RT_WLAN_CMD_GET_COUNTRY:
@@ -711,7 +836,7 @@ static rt_err_t _rt_wlan_dev_control(rt_device_t dev, int cmd, void *args)
LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_SET_MAC, "RT_WLAN_CMD_SET_MAC");
if (wlan->ops->wlan_set_mac)
- wlan->ops->wlan_set_mac(wlan, mac);
+ err = wlan->ops->wlan_set_mac(wlan, mac);
break;
}
case RT_WLAN_CMD_GET_MAC:
@@ -720,7 +845,7 @@ static rt_err_t _rt_wlan_dev_control(rt_device_t dev, int cmd, void *args)
LOG_D("%s %d cmd[%d]:%s run......", __FUNCTION__, __LINE__, RT_WLAN_CMD_GET_MAC, "RT_WLAN_CMD_GET_MAC");
if (wlan->ops->wlan_get_mac)
- wlan->ops->wlan_get_mac(wlan, mac);
+ err = wlan->ops->wlan_get_mac(wlan, mac);
break;
}
default:
@@ -733,11 +858,24 @@ static rt_err_t _rt_wlan_dev_control(rt_device_t dev, int cmd, void *args)
return err;
}
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops wlan_ops =
+{
+ _rt_wlan_dev_init,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ _rt_wlan_dev_control
+};
+#endif
+
rt_err_t rt_wlan_dev_register(struct rt_wlan_device *wlan, const char *name, const struct rt_wlan_dev_ops *ops, rt_uint32_t flag, void *user_data)
{
rt_err_t err = RT_EOK;
- if ((wlan == RT_NULL) || (name == RT_NULL) || (ops == RT_NULL))
+ if ((wlan == RT_NULL) || (name == RT_NULL) || (ops == RT_NULL) ||
+ (flag & RT_WLAN_FLAG_STA_ONLY && flag & RT_WLAN_FLAG_AP_ONLY))
{
LOG_E("F:%s L:%d parameter Wrongful", __FUNCTION__, __LINE__);
return RT_NULL;
@@ -745,12 +883,17 @@ rt_err_t rt_wlan_dev_register(struct rt_wlan_device *wlan, const char *name, con
rt_memset(wlan, 0, sizeof(struct rt_wlan_device));
+#ifdef RT_USING_DEVICE_OPS
+ wlan->device.ops = &wlan_ops;
+#else
wlan->device.init = _rt_wlan_dev_init;
wlan->device.open = RT_NULL;
wlan->device.close = RT_NULL;
wlan->device.read = RT_NULL;
wlan->device.write = RT_NULL;
wlan->device.control = _rt_wlan_dev_control;
+#endif
+
wlan->device.user_data = RT_NULL;
wlan->device.type = RT_Device_Class_NetIf;
@@ -765,3 +908,5 @@ rt_err_t rt_wlan_dev_register(struct rt_wlan_device *wlan, const char *name, con
return err;
}
+
+#endif
diff --git a/components/drivers/wlan/wlan_dev.h b/components/drivers/wlan/wlan_dev.h
index e3f0d3dc61..3019afb19d 100644
--- a/components/drivers/wlan/wlan_dev.h
+++ b/components/drivers/wlan/wlan_dev.h
@@ -37,7 +37,8 @@ typedef enum
RT_WLAN_CMD_SET_POWERSAVE,
RT_WLAN_CMD_GET_POWERSAVE,
RT_WLAN_CMD_CFG_PROMISC, /* start/stop minitor */
- RT_WLAN_CMD_CFG_FILTER,
+ RT_WLAN_CMD_CFG_FILTER, /* start/stop frame filter */
+ RT_WLAN_CMD_CFG_MGNT_FILTER, /* start/stop management frame filter */
RT_WLAN_CMD_SET_CHANNEL,
RT_WLAN_CMD_GET_CHANNEL,
RT_WLAN_CMD_SET_COUNTRY,
@@ -360,6 +361,8 @@ typedef void (*rt_wlan_dev_event_handler)(struct rt_wlan_device *device, rt_wlan
typedef void (*rt_wlan_pormisc_callback_t)(struct rt_wlan_device *device, void *data, int len);
+typedef void (*rt_wlan_mgnt_filter_callback_t)(struct rt_wlan_device *device, void *data, int len);
+
struct rt_wlan_ssid
{
rt_uint8_t len;
@@ -381,6 +384,11 @@ typedef struct rt_wlan_key rt_wlan_key_t;
(_info)->channel = -1; \
} while(0)
+#define SSID_SET(_info, _ssid) do { \
+ rt_strncpy((char *)(_info)->ssid.val, (_ssid), RT_WLAN_SSID_MAX_LENGTH); \
+ (_info)->ssid.len = rt_strlen((char *)(_info)->ssid.val); \
+ } while(0)
+
struct rt_wlan_info
{
/* security type */
@@ -440,8 +448,10 @@ struct rt_wlan_device
struct rt_mutex lock;
struct rt_wlan_dev_event_desc handler_table[RT_WLAN_DEV_EVT_MAX][RT_WLAN_DEV_EVENT_NUM];
rt_wlan_pormisc_callback_t pormisc_callback;
+ rt_wlan_mgnt_filter_callback_t mgnt_filter_callback;
const struct rt_wlan_dev_ops *ops;
rt_uint32_t flags;
+ struct netdev *netdev;
void *prot;
void *user_data;
};
@@ -470,6 +480,7 @@ struct rt_scan_info
rt_uint8_t bssid[6];
rt_int16_t channel_min;
rt_int16_t channel_max;
+ rt_bool_t passive;
};
struct rt_wlan_dev_ops
@@ -488,6 +499,7 @@ struct rt_wlan_dev_ops
int (*wlan_get_powersave)(struct rt_wlan_device *wlan);
rt_err_t (*wlan_cfg_promisc)(struct rt_wlan_device *wlan, rt_bool_t start);
rt_err_t (*wlan_cfg_filter)(struct rt_wlan_device *wlan, struct rt_wlan_filter *filter);
+ rt_err_t (*wlan_cfg_mgnt_filter)(struct rt_wlan_device *wlan, rt_bool_t start);
rt_err_t (*wlan_set_channel)(struct rt_wlan_device *wlan, int channel);
int (*wlan_get_channel)(struct rt_wlan_device *wlan);
rt_err_t (*wlan_set_country)(struct rt_wlan_device *wlan, rt_country_code_t country_code);
@@ -496,6 +508,7 @@ struct rt_wlan_dev_ops
rt_err_t (*wlan_get_mac)(struct rt_wlan_device *wlan, rt_uint8_t mac[]);
int (*wlan_recv)(struct rt_wlan_device *wlan, void *buff, int len);
int (*wlan_send)(struct rt_wlan_device *wlan, void *buff, int len);
+ int (*wlan_send_raw_frame)(struct rt_wlan_device *wlan, void *buff, int len);
};
/*
@@ -559,7 +572,7 @@ rt_err_t rt_wlan_dev_cfg_filter(struct rt_wlan_device *device, struct rt_wlan_fi
* wlan device channel interface
*/
rt_err_t rt_wlan_dev_set_channel(struct rt_wlan_device *device, int channel);
-rt_err_t rt_wlan_dev_get_channel(struct rt_wlan_device *device);
+int rt_wlan_dev_get_channel(struct rt_wlan_device *device);
/*
* wlan device country interface
diff --git a/components/drivers/wlan/wlan_lwip.c b/components/drivers/wlan/wlan_lwip.c
index ec6ca23845..3c4e4dd598 100644
--- a/components/drivers/wlan/wlan_lwip.c
+++ b/components/drivers/wlan/wlan_lwip.c
@@ -14,27 +14,34 @@
#include <wlan_prot.h>
#include <wlan_workqueue.h>
+#if defined(RT_WLAN_PROT_ENABLE) && defined(RT_WLAN_PROT_LWIP_ENABLE)
+
#ifdef RT_USING_LWIP
#include <netif/ethernetif.h>
#include <lwip/netifapi.h>
#ifdef LWIP_USING_DHCPD
#include <dhcp_server.h>
#endif
+#ifdef RT_USING_NETDEV
+#include <netdev.h>
+#endif
-#define DBG_ENABLE
+#define DBG_TAG "WLAN.lwip"
#ifdef RT_WLAN_LWIP_DEBUG
-#define DBG_LEVEL DBG_LOG
+#define DBG_LVL DBG_LOG
#else
-#define DBG_LEVEL DBG_INFO
-#endif
-#define DBG_SECTION_NAME "WLAN.lwip"
-#define DBG_COLOR
+#define DBG_LVL DBG_INFO
+#endif /* RT_WLAN_LWIP_DEBUG */
#include <rtdbg.h>
#ifndef IPADDR_STRLEN_MAX
#define IPADDR_STRLEN_MAX (32)
#endif
+#ifndef RT_WLAN_PROT_LWIP_NAME
+#define RT_WLAN_PROT_LWIP_NAME ("lwip")
+#endif
+
struct lwip_prot_des
{
struct rt_wlan_prot prot;
@@ -49,12 +56,16 @@ static void netif_is_ready(struct rt_work *work, void *parameter)
ip_addr_t ip_addr_zero = { 0 };
struct rt_wlan_device *wlan = parameter;
struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot;
- struct eth_device *eth_dev = &lwip_prot->eth;
+ struct eth_device *eth_dev;
rt_base_t level;
struct rt_wlan_buff buff;
rt_uint32_t ip_addr[4];
char str[IPADDR_STRLEN_MAX];
+ if (lwip_prot == RT_NULL)
+ return;
+
+ eth_dev = &lwip_prot->eth;
rt_timer_stop(&lwip_prot->timer);
if (ip_addr_cmp(&(eth_dev->netif->ip_addr), &ip_addr_zero) != 0)
{
@@ -102,18 +113,26 @@ static void netif_is_ready(struct rt_work *work, void *parameter)
LOG_I("Got IP address : %s", str);
exit:
level = rt_hw_interrupt_disable();
- rt_memset(work, 0, sizeof(struct rt_work));
+ if (work)
+ {
+ rt_memset(work, 0, sizeof(struct rt_work));
+ }
rt_hw_interrupt_enable(level);
}
static void timer_callback(void *parameter)
{
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
struct rt_workqueue *workqueue;
struct rt_wlan_device *wlan = parameter;
struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot;
- struct rt_work *work = &lwip_prot->work;
+ struct rt_work *work;
rt_base_t level;
+ if (lwip_prot == RT_NULL)
+ return;
+
+ work = &lwip_prot->work;
workqueue = rt_wlan_get_workqueue();
if (workqueue != RT_NULL)
{
@@ -127,13 +146,22 @@ static void timer_callback(void *parameter)
rt_hw_interrupt_enable(level);
}
}
+#else
+ netif_is_ready(RT_NULL, parameter);
+#endif
+
}
static void netif_set_connected(void *parameter)
{
struct rt_wlan_device *wlan = parameter;
struct lwip_prot_des *lwip_prot = wlan->prot;
- struct eth_device *eth_dev = &lwip_prot->eth;
+ struct eth_device *eth_dev;
+
+ if (lwip_prot == RT_NULL)
+ return;
+
+ eth_dev = &lwip_prot->eth;
if (lwip_prot->connected_flag)
{
@@ -153,14 +181,10 @@ static void netif_set_connected(void *parameter)
netifapi_netif_common(eth_dev->netif, netif_set_link_up, NULL);
#ifdef LWIP_USING_DHCPD
{
- char netif_name[8];
- int i;
+ char netif_name[RT_NAME_MAX];
rt_memset(netif_name, 0, sizeof(netif_name));
- for (i = 0; i < sizeof(eth_dev->netif->name); i++)
- {
- netif_name[i] = eth_dev->netif->name[i];
- }
+ rt_memcpy(netif_name, eth_dev->netif->name, sizeof(eth_dev->netif->name));
dhcpd_start(netif_name);
}
#endif
@@ -168,24 +192,24 @@ static void netif_set_connected(void *parameter)
}
else
{
- if (wlan->mode == RT_WLAN_STATION)
- {
- LOG_D("F:%s L:%d dhcp stop run", __FUNCTION__, __LINE__);
- netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL);
+ LOG_D("F:%s L:%d set linkdown", __FUNCTION__, __LINE__);
+ netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL);
+ rt_timer_stop(&lwip_prot->timer);
#ifdef RT_LWIP_DHCP
- {
- ip_addr_t ip_addr = { 0 };
- dhcp_stop(eth_dev->netif);
- netif_set_addr(eth_dev->netif, &ip_addr, &ip_addr, &ip_addr);
- }
-#endif
- rt_timer_stop(&lwip_prot->timer);
+ {
+ ip_addr_t ip_addr = { 0 };
+ dhcp_stop(eth_dev->netif);
+ netif_set_addr(eth_dev->netif, &ip_addr, &ip_addr, &ip_addr);
}
- else if (wlan->mode == RT_WLAN_AP)
+#endif
+#ifdef LWIP_USING_DHCPD
{
- LOG_D("F:%s L:%d dhcpd stop run", __FUNCTION__, __LINE__);
- netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL);
+ char netif_name[RT_NAME_MAX];
+ rt_memset(netif_name, 0, sizeof(netif_name));
+ rt_memcpy(netif_name, lwip_prot->eth.netif->name, sizeof(lwip_prot->eth.netif->name));
+ dhcpd_stop(netif_name);
}
+#endif
}
}
@@ -194,6 +218,9 @@ static void rt_wlan_lwip_event_handle(struct rt_wlan_prot *port, struct rt_wlan_
struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot;
rt_bool_t flag_old;
+ if (lwip_prot == RT_NULL)
+ return;
+
flag_old = lwip_prot->connected_flag;
switch (event)
@@ -240,8 +267,11 @@ static void rt_wlan_lwip_event_handle(struct rt_wlan_prot *port, struct rt_wlan_
}
if (flag_old != lwip_prot->connected_flag)
{
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
rt_wlan_workqueue_dowork(netif_set_connected, wlan);
- // netif_set_connected(wlan);
+#else
+ netif_set_connected(wlan);
+#endif
}
}
@@ -372,10 +402,22 @@ static rt_err_t rt_wlan_lwip_protocol_send(rt_device_t device, struct pbuf *p)
#endif
}
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops wlan_lwip_ops =
+{
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ RT_NULL,
+ rt_wlan_lwip_protocol_control
+};
+#endif
+
static struct rt_wlan_prot *rt_wlan_lwip_protocol_register(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan)
{
struct eth_device *eth = RT_NULL;
- static rt_uint8_t id = 0;
+ rt_uint8_t id = 0;
char eth_name[4], timer_name[16];
rt_device_t device = RT_NULL;
struct lwip_prot_des *lwip_prot;
@@ -417,12 +459,18 @@ static struct rt_wlan_prot *rt_wlan_lwip_protocol_register(struct rt_wlan_prot *
rt_memset(lwip_prot, 0, sizeof(struct lwip_prot_des));
eth = &lwip_prot->eth;
+
+#ifdef RT_USING_DEVICE_OPS
+ eth->parent.ops = &wlan_lwip_ops;
+#else
eth->parent.init = RT_NULL;
eth->parent.open = RT_NULL;
eth->parent.close = RT_NULL;
eth->parent.read = RT_NULL;
eth->parent.write = RT_NULL;
eth->parent.control = rt_wlan_lwip_protocol_control;
+#endif
+
eth->parent.user_data = wlan;
eth->eth_rx = RT_NULL;
eth->eth_tx = rt_wlan_lwip_protocol_send;
@@ -436,22 +484,43 @@ static struct rt_wlan_prot *rt_wlan_lwip_protocol_register(struct rt_wlan_prot *
return RT_NULL;
}
rt_memcpy(&lwip_prot->prot, prot, sizeof(struct rt_wlan_prot));
- if (wlan->mode == RT_WLAN_STATION)
- {
- rt_sprintf(timer_name, "timer_%s", eth_name);
- rt_timer_init(&lwip_prot->timer, timer_name, timer_callback, wlan, rt_tick_from_millisecond(1000),
- RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT);
- }
+ rt_sprintf(timer_name, "timer_%s", eth_name);
+ rt_timer_init(&lwip_prot->timer, timer_name, timer_callback, wlan, rt_tick_from_millisecond(1000),
+ RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT);
netif_set_up(eth->netif);
LOG_I("eth device init ok name:%s", eth_name);
-
+#ifdef RT_USING_NETDEV
+ wlan->netdev = netdev_get_by_name(eth_name);
+#endif
return &lwip_prot->prot;
}
static void rt_wlan_lwip_protocol_unregister(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan)
{
- /*TODO*/
+ struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)prot;
+
LOG_D("F:%s L:%d is run wlan:0x%08x", __FUNCTION__, __LINE__, wlan);
+#if !defined(RT_USING_LWIP141)
+ wlan->prot = RT_NULL;
+ if (lwip_prot == RT_NULL)
+ {
+ return;
+ }
+
+#ifdef LWIP_USING_DHCPD
+ {
+ char netif_name[RT_NAME_MAX];
+ rt_memset(netif_name, 0, sizeof(netif_name));
+ rt_memcpy(netif_name, lwip_prot->eth.netif->name, sizeof(lwip_prot->eth.netif->name));
+ dhcpd_stop(netif_name);
+ }
+#endif
+ eth_device_deinit(&lwip_prot->eth);
+ rt_device_close((rt_device_t)wlan);
+ rt_timer_detach(&lwip_prot->timer);
+ wlan->netdev = RT_NULL;
+ rt_free(lwip_prot);
+#endif
}
static struct rt_wlan_prot_ops ops =
@@ -467,7 +536,7 @@ int rt_wlan_lwip_init(void)
rt_wlan_prot_event_t event;
rt_memset(&prot, 0, sizeof(prot));
- rt_strncpy(&prot.name[0], RT_WLAN_PROT_LWIP, RT_WLAN_PROT_NAME_LEN);
+ rt_strncpy(&prot.name[0], RT_WLAN_PROT_LWIP_NAME, RT_WLAN_PROT_NAME_LEN);
prot.ops = &ops;
if (rt_wlan_prot_regisetr(&prot) != RT_EOK)
@@ -486,3 +555,4 @@ int rt_wlan_lwip_init(void)
INIT_PREV_EXPORT(rt_wlan_lwip_init);
#endif
+#endif
diff --git a/components/drivers/wlan/wlan_mgnt.c b/components/drivers/wlan/wlan_mgnt.c
index 1d0b0c4aa7..fefe700acc 100644
--- a/components/drivers/wlan/wlan_mgnt.c
+++ b/components/drivers/wlan/wlan_mgnt.c
@@ -16,16 +16,16 @@
#include <wlan_prot.h>
#include <wlan_workqueue.h>
-#define DBG_ENABLE
+#define DBG_TAG "WLAN.mgnt"
#ifdef RT_WLAN_MGNT_DEBUG
-#define DBG_LEVEL DBG_LOG
+#define DBG_LVL DBG_LOG
#else
-#define DBG_LEVEL DBG_INFO
-#endif
-#define DBG_SECTION_NAME "WLAN.mgnt"
-#define DBG_COLOR
+#define DBG_LVL DBG_INFO
+#endif /* RT_WLAN_MGNT_DEBUG */
#include <rtdbg.h>
+#ifdef RT_WLAN_MANAGE_ENABLE
+
#ifndef RT_WLAN_DEVICE
#define RT_WLAN_DEVICE(__device) ((struct rt_wlan_device *)__device)
#endif
@@ -50,13 +50,16 @@
#define COMPLETE_LOCK() (rt_mutex_take(&complete_mutex, RT_WAITING_FOREVER))
#define COMPLETE_UNLOCK() (rt_mutex_release(&complete_mutex))
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
#define TIME_STOP() (rt_timer_stop(&reconnect_time))
#define TIME_START() (rt_timer_start(&reconnect_time))
-
-#define DISCONNECT_RESPONSE_TICK (2000)
+#else
+#define TIME_STOP()
+#define TIME_START()
+#endif
#if RT_WLAN_EBOX_NUM < 1
-#error "event box num Too little"
+#error "event box num Too few"
#endif
struct rt_wlan_mgnt_des
@@ -115,8 +118,11 @@ static struct rt_wlan_event_desc event_tab[RT_WLAN_EVT_MAX];
static struct rt_wlan_complete_des *complete_tab[5];
static struct rt_mutex complete_mutex;
+static struct rt_wlan_info *scan_filter;
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
static struct rt_timer reconnect_time;
+#endif
rt_inline int _sta_is_null(void)
{
@@ -147,9 +153,97 @@ rt_inline rt_bool_t _is_do_connect(void)
return RT_TRUE;
}
-static void rt_wlan_mgnt_work(void *parameter);
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
+
+static rt_bool_t rt_wlan_info_isequ(struct rt_wlan_info *info1, struct rt_wlan_info *info2)
+{
+ rt_bool_t is_equ = 1;
+ rt_uint8_t bssid_zero[RT_WLAN_BSSID_MAX_LENGTH] = { 0 };
+
+ if (is_equ && (info1->security != SECURITY_UNKNOWN) && (info2->security != SECURITY_UNKNOWN))
+ {
+ is_equ &= info2->security == info1->security;
+ }
+ if (is_equ && ((info1->ssid.len > 0) && (info2->ssid.len > 0)))
+ {
+ is_equ &= info1->ssid.len == info2->ssid.len;
+ is_equ &= rt_memcmp(&info2->ssid.val[0], &info1->ssid.val[0], info1->ssid.len) == 0;
+ }
+ if (is_equ && (rt_memcmp(&info1->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)) &&
+ (rt_memcmp(&info2->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)))
+ {
+ is_equ &= rt_memcmp(&info1->bssid[0], &info2->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0;
+ }
+ if (is_equ && info1->datarate && info2->datarate)
+ {
+ is_equ &= info1->datarate == info2->datarate;
+ }
+ if (is_equ && (info1->channel >= 0) && (info2->channel >= 0))
+ {
+ is_equ &= info1->channel == info2->channel;
+ }
+ if (is_equ && (info1->rssi < 0) && (info2->rssi < 0))
+ {
+ is_equ &= info1->rssi == info2->rssi;
+ }
+ return is_equ;
+}
+
+static void rt_wlan_mgnt_work(void *parameter)
+{
+ struct rt_wlan_msg *msg = parameter;
+ void *user_parameter;
+ rt_wlan_event_handler handler = RT_NULL;
+ struct rt_wlan_buff user_buff = { 0 };
+ rt_base_t level;
+
+ /* Get user callback */
+ if (msg->event < RT_WLAN_EVT_MAX)
+ {
+ level = rt_hw_interrupt_disable();
+ handler = event_tab[msg->event].handler;
+ user_parameter = event_tab[msg->event].parameter;
+ rt_hw_interrupt_enable(level);
+ }
+
+ /* run user callback fun */
+ if (handler)
+ {
+ user_buff.data = msg->buff;
+ user_buff.len = msg->len;
+ RT_WLAN_LOG_D("wlan work thread run user callback, event:%d", msg->event);
+ handler(msg->event, &user_buff, user_parameter);
+ }
+
+ switch (msg->event)
+ {
+ case RT_WLAN_EVT_STA_CONNECTED:
+ {
+ struct rt_wlan_cfg_info cfg_info;
+
+ rt_memset(&cfg_info, 0, sizeof(cfg_info));
+ /* save config */
+ if (rt_wlan_is_connected() == RT_TRUE)
+ {
+ rt_enter_critical();
+ cfg_info.info = _sta_mgnt.info;
+ cfg_info.key = _sta_mgnt.key;
+ rt_exit_critical();
+ RT_WLAN_LOG_D("run save config! ssid:%s len%d", _sta_mgnt.info.ssid.val, _sta_mgnt.info.ssid.len);
+#ifdef RT_WLAN_CFG_ENABLE
+ rt_wlan_cfg_save(&cfg_info);
+#endif
+ }
+ break;
+ }
+ default :
+ break;
+ }
+
+ rt_free(msg);
+}
-static rt_err_t rt_wlan_send_msg(rt_wlan_dev_event_t event, void *buff, int len)
+static rt_err_t rt_wlan_send_to_thread(rt_wlan_event_t event, void *buff, int len)
{
struct rt_wlan_msg *msg;
@@ -166,7 +260,8 @@ static rt_err_t rt_wlan_send_msg(rt_wlan_dev_event_t event, void *buff, int len)
msg->event = event;
if (len != 0)
{
- msg->buff = ((char *)msg) + sizeof(struct rt_wlan_msg);
+ msg->buff = (void *)&msg[1];
+ rt_memcpy(msg->buff, buff, len);
msg->len = len;
}
@@ -179,14 +274,16 @@ static rt_err_t rt_wlan_send_msg(rt_wlan_dev_event_t event, void *buff, int len)
}
return RT_EOK;
}
+#endif
static rt_err_t rt_wlan_scan_result_cache(struct rt_wlan_info *info, int timeout)
{
struct rt_wlan_info *ptable;
rt_err_t err = RT_EOK;
int i, insert = -1;
+ rt_base_t level;
- if (_sta_is_null() || (info == RT_NULL)) return RT_EOK;
+ if (_sta_is_null() || (info == RT_NULL) || (info->ssid.len == 0)) return RT_EOK;
RT_WLAN_LOG_D("ssid:%s len:%d mac:%02x:%02x:%02x:%02x:%02x:%02x", info->ssid.val, info->ssid.len,
info->bssid[0], info->bssid[1], info->bssid[2], info->bssid[3], info->bssid[4], info->bssid[5]);
@@ -195,6 +292,23 @@ static rt_err_t rt_wlan_scan_result_cache(struct rt_wlan_info *info, int timeout
if (err != RT_EOK)
return err;
+ /* scanning result filtering */
+ level = rt_hw_interrupt_disable();
+ if (scan_filter)
+ {
+ struct rt_wlan_info _tmp_info = *scan_filter;
+ rt_hw_interrupt_enable(level);
+ if (rt_wlan_info_isequ(&_tmp_info, info) != RT_TRUE)
+ {
+ rt_mutex_release(&scan_result_mutex);
+ return RT_EOK;
+ }
+ }
+ else
+ {
+ rt_hw_interrupt_enable(level);
+ }
+
/* de-duplicatio */
for (i = 0; i < scan_result.num; i++)
{
@@ -383,7 +497,7 @@ static rt_err_t rt_wlan_sta_info_del_all(int timeout)
sta_info.node = RT_NULL;
return err;
}
-
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
static void rt_wlan_auto_connect_run(struct rt_work *work, void *parameter)
{
static rt_uint32_t id = 0;
@@ -415,12 +529,12 @@ static void rt_wlan_auto_connect_run(struct rt_work *work, void *parameter)
if (id >= rt_wlan_cfg_get_num()) id = 0;
- if ((cfg_info.key.len > 0) && (cfg_info.key.len < RT_WLAN_PASSWORD_MAX_LENGTH))
+ if ((cfg_info.key.len > 0) && (cfg_info.key.len <= RT_WLAN_PASSWORD_MAX_LENGTH))
{
cfg_info.key.val[cfg_info.key.len] = '\0';
password = (char *)(&cfg_info.key.val[0]);
}
- rt_wlan_connect_adv(&cfg_info.info, password);
+ rt_wlan_connect((char *)cfg_info.info.ssid.val, password);
exit:
rt_mutex_release(&mgnt_mutex);
level = rt_hw_interrupt_disable();
@@ -451,41 +565,10 @@ static void rt_wlan_cyclic_check(void *parameter)
}
}
}
-
-static void rt_wlan_mgnt_work(void *parameter)
-{
- struct rt_wlan_msg *msg = parameter;
-
- switch (msg->event)
- {
- case RT_WLAN_DEV_EVT_CONNECT:
- {
- struct rt_wlan_cfg_info cfg_info;
-
- /* save config */
- if (rt_wlan_is_connected() == RT_TRUE)
- {
- rt_enter_critical();
- cfg_info.info = _sta_mgnt.info;
- cfg_info.key = _sta_mgnt.key;
- rt_exit_critical();
- RT_WLAN_LOG_D("run save config! ssid:%s len%d", _sta_mgnt.info.ssid.val, _sta_mgnt.info.ssid.len);
- rt_wlan_cfg_save(&cfg_info);
- }
- break;
- }
- default :
- break;
- }
-
- rt_free(msg);
-}
+#endif
static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_event_t event, struct rt_wlan_buff *buff, void *parameter)
{
- rt_base_t level;
- void *user_parameter;
- rt_wlan_event_handler handler = RT_NULL;
rt_err_t err = RT_NULL;
rt_wlan_event_t user_event = RT_WLAN_EVT_MAX;
int i;
@@ -505,7 +588,6 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
_sta_mgnt.state &= ~RT_WLAN_STATE_CONNECTING;
user_event = RT_WLAN_EVT_STA_CONNECTED;
TIME_STOP();
- rt_wlan_send_msg(event, RT_NULL, 0);
user_buff.data = &_sta_mgnt.info;
user_buff.len = sizeof(struct rt_wlan_info);
RT_WLAN_LOG_I("wifi connect success ssid:%s", &_sta_mgnt.info.ssid.val[0]);
@@ -520,7 +602,10 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
user_event = RT_WLAN_EVT_STA_CONNECTED_FAIL;
user_buff.data = &_sta_mgnt.info;
user_buff.len = sizeof(struct rt_wlan_info);
- TIME_START();
+ if (rt_wlan_get_autoreconnect_mode())
+ {
+ TIME_START();
+ }
break;
}
case RT_WLAN_DEV_EVT_DISCONNECT:
@@ -531,7 +616,10 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
user_event = RT_WLAN_EVT_STA_DISCONNECTED;
user_buff.data = &_sta_mgnt.info;
user_buff.len = sizeof(struct rt_wlan_info);
- TIME_START();
+ if (rt_wlan_get_autoreconnect_mode())
+ {
+ TIME_START();
+ }
break;
}
case RT_WLAN_DEV_EVT_AP_START:
@@ -624,20 +712,30 @@ static void rt_wlan_event_dispatch(struct rt_wlan_device *device, rt_wlan_dev_ev
}
}
COMPLETE_UNLOCK();
- /* Get user callback */
- if (user_event < RT_WLAN_EVT_MAX)
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
+ rt_wlan_send_to_thread(user_event, user_buff.data, user_buff.len);
+#else
{
- level = rt_hw_interrupt_disable();
- handler = event_tab[user_event].handler;
- user_parameter = event_tab[user_event].parameter;
- rt_hw_interrupt_enable(level);
- }
+ void *user_parameter;
+ rt_wlan_event_handler handler = RT_NULL;
+ rt_base_t level;
+ /* Get user callback */
+ if (user_event < RT_WLAN_EVT_MAX)
+ {
+ level = rt_hw_interrupt_disable();
+ handler = event_tab[user_event].handler;
+ user_parameter = event_tab[user_event].parameter;
+ rt_hw_interrupt_enable(level);
+ }
- /* run user callback fun */
- if (handler)
- {
- handler(user_event, &user_buff, user_parameter);
+ /* run user callback fun */
+ if (handler)
+ {
+ RT_WLAN_LOG_D("unknown thread run user callback, event:%d", user_event);
+ handler(user_event, &user_buff, user_parameter);
+ }
}
+#endif
}
static struct rt_wlan_complete_des *rt_wlan_complete_create(const char *name)
@@ -822,14 +920,30 @@ rt_err_t rt_wlan_set_mode(const char *dev_name, rt_wlan_mode_t mode)
/* update dev event handle */
if (up_event_flag == 1)
{
- rt_wlan_dev_event_t event;
- for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event++)
+ if (handler)
{
- if (handler)
+ if (mode == RT_WLAN_STATION)
{
- rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), event, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_CONNECT, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_CONNECT_FAIL, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_DISCONNECT, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_SCAN_REPORT, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_SCAN_DONE, handler, RT_NULL);
}
- else
+ else if (mode == RT_WLAN_AP)
+ {
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_START, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_STOP, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_ASSOCIATED, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_DISASSOCIATED, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(RT_WLAN_DEVICE(device), RT_WLAN_DEV_EVT_AP_ASSOCIATE_FAILED, handler, RT_NULL);
+ }
+ }
+ else
+ {
+ rt_wlan_dev_event_t event;
+ handler = rt_wlan_event_dispatch;
+ for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event++)
{
rt_wlan_dev_unregister_event_handler(RT_WLAN_DEVICE(device), event, handler);
}
@@ -838,8 +952,11 @@ rt_err_t rt_wlan_set_mode(const char *dev_name, rt_wlan_mode_t mode)
MGNT_UNLOCK();
/* Mount protocol */
-#ifdef RT_WLAN_DEFAULT_PROT
- rt_wlan_prot_attach(dev_name, RT_WLAN_DEFAULT_PROT);
+#if defined(RT_WLAN_PROT_ENABLE) && defined(RT_WLAN_DEFAULT_PROT)
+ if (err == RT_EOK)
+ {
+ rt_wlan_prot_attach(dev_name, RT_WLAN_DEFAULT_PROT);
+ }
#endif
return err;
}
@@ -934,6 +1051,7 @@ rt_err_t rt_wlan_connect(const char *ssid, const char *password)
struct rt_wlan_info info;
struct rt_wlan_complete_des *complete;
rt_uint32_t set = 0, recved = 0;
+ rt_uint32_t scan_retry = RT_WLAN_SCAN_RETRY_CNT;
/* sta dev Can't be NULL */
if (_sta_is_null())
@@ -962,12 +1080,11 @@ rt_err_t rt_wlan_connect(const char *ssid, const char *password)
/* get info from cache */
INVALID_INFO(&info);
MGNT_LOCK();
- if (rt_wlan_find_best_by_cache(ssid, &info) != RT_TRUE)
+ while (scan_retry-- && rt_wlan_find_best_by_cache(ssid, &info) != RT_TRUE)
{
rt_wlan_scan_sync();
- rt_wlan_find_best_by_cache(ssid, &info);
- rt_wlan_scan_result_clean();
}
+ rt_wlan_scan_result_clean();
if (info.ssid.len <= 0)
{
@@ -1218,10 +1335,13 @@ rt_err_t rt_wlan_get_info(struct rt_wlan_info *info)
}
RT_WLAN_LOG_D("%s is run", __FUNCTION__);
- rt_enter_critical();
- *info = _sta_mgnt.info;
- rt_exit_critical();
- return RT_EOK;
+ if (rt_wlan_is_connected() == RT_TRUE)
+ {
+ *info = _sta_mgnt.info;
+ info->rssi = rt_wlan_get_rssi();
+ return RT_EOK;
+ }
+ return -RT_ERROR;
}
int rt_wlan_get_rssi(void)
@@ -1270,6 +1390,7 @@ rt_err_t rt_wlan_start_ap(const char *ssid, const char *password)
rt_memcpy(&info.ssid.val, ssid, ssid_len);
info.ssid.len = ssid_len;
info.channel = 6;
+ info.band = RT_802_11_BAND_2_4GHZ;
/* Initializing events that need to wait */
MGNT_LOCK();
@@ -1320,7 +1441,10 @@ rt_err_t rt_wlan_start_ap_adv(struct rt_wlan_info *info, const char *password)
return -RT_EIO;
}
RT_WLAN_LOG_D("%s is run", __FUNCTION__);
- password_len = rt_strlen(password);
+ if (password != RT_NULL)
+ {
+ password_len = rt_strlen(password);
+ }
if (password_len > RT_WLAN_PASSWORD_MAX_LENGTH)
{
RT_WLAN_LOG_E("key is to long! len:%d", password_len);
@@ -1358,16 +1482,16 @@ rt_err_t rt_wlan_start_ap_adv(struct rt_wlan_info *info, const char *password)
return err;
}
-int rt_wlan_ap_is_active(void)
+rt_bool_t rt_wlan_ap_is_active(void)
{
- int _active = 0;
+ rt_bool_t _active = RT_FALSE;
if (_ap_is_null())
{
- return 0;
+ return RT_FALSE;
}
- _active = _ap_mgnt.state & RT_WLAN_STATE_ACTIVE ? 1 : 0;
+ _active = _ap_mgnt.state & RT_WLAN_STATE_ACTIVE ? RT_TRUE : RT_FALSE;
RT_WLAN_LOG_D("%s is run active:%s", __FUNCTION__, _active ? "Active" : "Inactive");
return _active;
}
@@ -1426,8 +1550,12 @@ rt_err_t rt_wlan_ap_get_info(struct rt_wlan_info *info)
}
RT_WLAN_LOG_D("%s is run", __FUNCTION__);
- *info = _ap_mgnt.info;
- return RT_EOK;
+ if (rt_wlan_ap_is_active() == RT_TRUE)
+ {
+ *info = _ap_mgnt.info;
+ return RT_EOK;
+ }
+ return -RT_ERROR;
}
/* get sta number */
@@ -1554,27 +1682,35 @@ rt_country_code_t rt_wlan_ap_get_country(void)
void rt_wlan_config_autoreconnect(rt_bool_t enable)
{
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
RT_WLAN_LOG_D("%s is run enable:%d", __FUNCTION__, enable);
MGNT_LOCK();
if (enable)
{
+ TIME_START();
_sta_mgnt.flags |= RT_WLAN_STATE_AUTOEN;
}
else
{
+ TIME_STOP();
_sta_mgnt.flags &= ~RT_WLAN_STATE_AUTOEN;
}
MGNT_UNLOCK();
+#endif
}
rt_bool_t rt_wlan_get_autoreconnect_mode(void)
{
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
rt_bool_t enable = 0;
enable = _sta_mgnt.flags & RT_WLAN_STATE_AUTOEN ? 1 : 0;
RT_WLAN_LOG_D("%s is run enable:%d", __FUNCTION__, enable);
return enable;
+#else
+ return RT_FALSE;
+#endif
}
/* Call the underlying scan function, which is asynchronous.
@@ -1611,6 +1747,9 @@ struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
rt_err_t err = RT_EOK;
struct rt_wlan_complete_des *complete;
rt_uint32_t set = 0, recved = 0;
+ static struct rt_wlan_info scan_filter_info;
+ rt_base_t level;
+ struct rt_wlan_scan_result *result;
if (_sta_is_null())
{
@@ -1632,14 +1771,23 @@ struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
return &scan_result;
}
+ /* add scan info filter */
+ if (info)
+ {
+ scan_filter_info = *info;
+ level = rt_hw_interrupt_disable();
+ scan_filter = &scan_filter_info;
+ rt_hw_interrupt_enable(level);
+ }
+
/* run scan */
err = rt_wlan_dev_scan(STA_DEVICE(), info);
if (err != RT_EOK)
{
rt_wlan_complete_delete(complete);
RT_WLAN_LOG_E("scan sync fail");
- MGNT_UNLOCK();
- return RT_NULL;
+ result = RT_NULL;
+ goto scan_exit;
}
/* Initializing events that need to wait */
@@ -1652,12 +1800,17 @@ struct rt_wlan_scan_result *rt_wlan_scan_with_info(struct rt_wlan_info *info)
if (!(recved & set))
{
RT_WLAN_LOG_E("scan wait timeout!");
- MGNT_UNLOCK();
- return &scan_result;
+ result = &scan_result;
+ goto scan_exit;
}
+scan_exit:
MGNT_UNLOCK();
- return &scan_result;
+ level = rt_hw_interrupt_disable();
+ scan_filter = RT_NULL;
+ rt_hw_interrupt_enable(level);
+ result = &scan_result;
+ return result;
}
int rt_wlan_scan_get_info_num(void)
@@ -1708,8 +1861,7 @@ int rt_wlan_scan_find_cache(struct rt_wlan_info *info, struct rt_wlan_info *out_
{
int i = 0, count = 0;
struct rt_wlan_info *scan_info;
- rt_bool_t is_equ = 1;
- rt_uint8_t bssid_zero[RT_WLAN_BSSID_MAX_LENGTH] = { 0 };
+ rt_bool_t is_equ;
if ((out_info == RT_NULL) || (info == RT_NULL) || (num <= 0))
{
@@ -1720,31 +1872,7 @@ int rt_wlan_scan_find_cache(struct rt_wlan_info *info, struct rt_wlan_info *out_
for (i = 0; (i < scan_result.num) && (count < num); i++)
{
scan_info = &scan_result.info[i];
-
- if (is_equ && (info->security != SECURITY_UNKNOWN))
- {
- is_equ &= info->security == scan_info->security;
- }
- if (is_equ && ((info->ssid.len > 0) && (info->ssid.len == scan_info->ssid.len)))
- {
- is_equ &= rt_memcmp(&info->ssid.val[0], &scan_info->ssid.val[0], scan_info->ssid.len) == 0;
- }
- if (is_equ && (rt_memcmp(&info->bssid[0], bssid_zero, RT_WLAN_BSSID_MAX_LENGTH)))
- {
- is_equ &= rt_memcmp(&info->bssid[0], &scan_info->bssid[0], RT_WLAN_BSSID_MAX_LENGTH) == 0;
- }
- if (is_equ && info->datarate)
- {
- is_equ &= info->datarate == scan_info->datarate;
- }
- if (is_equ && (info->channel >= 0))
- {
- is_equ &= info->channel == scan_info->channel;
- }
- if (is_equ && (info->rssi < 0))
- {
- is_equ &= info->rssi == scan_info->rssi;
- }
+ is_equ = rt_wlan_info_isequ(scan_info, info);
/* Determine whether to find */
if (is_equ)
{
@@ -1797,7 +1925,7 @@ rt_err_t rt_wlan_register_event_handler(rt_wlan_event_t event, rt_wlan_event_han
}
RT_WLAN_LOG_D("%s is run event:%d", __FUNCTION__, event);
- MGNT_UNLOCK();
+ MGNT_LOCK();
/* Registering Callbacks */
level = rt_hw_interrupt_disable();
event_tab[event].handler = handler;
@@ -1839,8 +1967,6 @@ void rt_wlan_mgnt_unlock(void)
int rt_wlan_prot_ready_event(struct rt_wlan_device *wlan, struct rt_wlan_buff *buff)
{
rt_base_t level;
- void *user_parameter;
- rt_wlan_event_handler handler = RT_NULL;
if ((wlan == RT_NULL) || (_sta_mgnt.device != wlan) ||
(!(_sta_mgnt.state & RT_WLAN_STATE_CONNECT)))
@@ -1853,13 +1979,24 @@ int rt_wlan_prot_ready_event(struct rt_wlan_device *wlan, struct rt_wlan_buff *b
}
level = rt_hw_interrupt_disable();
_sta_mgnt.state |= RT_WLAN_STATE_READY;
- handler = event_tab[RT_WLAN_EVT_READY].handler;
- user_parameter = event_tab[RT_WLAN_EVT_READY].parameter;
rt_hw_interrupt_enable(level);
- if (handler)
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
+ rt_wlan_send_to_thread(RT_WLAN_EVT_READY, buff->data, buff->len);
+#else
{
- handler(RT_WLAN_EVT_READY, buff, user_parameter);
+ void *user_parameter;
+ rt_wlan_event_handler handler = RT_NULL;
+
+ level = rt_hw_interrupt_disable();
+ handler = event_tab[RT_WLAN_EVT_READY].handler;
+ user_parameter = event_tab[RT_WLAN_EVT_READY].parameter;
+ rt_hw_interrupt_enable(level);
+ if (handler)
+ {
+ handler(RT_WLAN_EVT_READY, buff, user_parameter);
+ }
}
+#endif
return 0;
}
@@ -1878,10 +2015,15 @@ int rt_wlan_init(void)
rt_mutex_init(&scan_result_mutex, "scan", RT_IPC_FLAG_FIFO);
rt_mutex_init(&sta_info_mutex, "sta", RT_IPC_FLAG_FIFO);
rt_mutex_init(&complete_mutex, "complete", RT_IPC_FLAG_FIFO);
- rt_timer_init(&reconnect_time, "wifi_tim", rt_wlan_cyclic_check, RT_NULL, DISCONNECT_RESPONSE_TICK, RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER);
- rt_timer_start(&reconnect_time);
+#ifdef RT_WLAN_AUTO_CONNECT_ENABLE
+ rt_timer_init(&reconnect_time, "wifi_tim", rt_wlan_cyclic_check, RT_NULL,
+ rt_tick_from_millisecond(AUTO_CONNECTION_PERIOD_MS),
+ RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER);
+#endif
_init_flag = 1;
}
return 0;
}
INIT_PREV_EXPORT(rt_wlan_init);
+
+#endif
diff --git a/components/drivers/wlan/wlan_mgnt.h b/components/drivers/wlan/wlan_mgnt.h
index d11d9ee347..df0827bb7b 100644
--- a/components/drivers/wlan/wlan_mgnt.h
+++ b/components/drivers/wlan/wlan_mgnt.h
@@ -37,6 +37,14 @@ extern "C" {
#define RT_WLAN_EBOX_NUM (10)
#endif
+#ifndef RT_WLAN_SCAN_RETRY_CNT
+#define RT_WLAN_SCAN_RETRY_CNT (3)
+#endif
+
+#ifndef AUTO_CONNECTION_PERIOD_MS
+#define AUTO_CONNECTION_PERIOD_MS (2000)
+#endif
+
/*state fot station*/
#define RT_WLAN_STATE_CONNECT (1UL << 0)
#define RT_WLAN_STATE_CONNECTING (1UL << 1)
@@ -97,7 +105,7 @@ int rt_wlan_get_rssi(void);
*/
rt_err_t rt_wlan_start_ap(const char *ssid, const char *password);
rt_err_t rt_wlan_start_ap_adv(struct rt_wlan_info *info, const char *password);
-int rt_wlan_ap_is_active(void);
+rt_bool_t rt_wlan_ap_is_active(void);
rt_err_t rt_wlan_ap_stop(void);
rt_err_t rt_wlan_ap_get_info(struct rt_wlan_info *info);
int rt_wlan_ap_get_sta_num(void);
diff --git a/components/drivers/wlan/wlan_prot.c b/components/drivers/wlan/wlan_prot.c
index ec5e419bc4..b1a1b5de99 100644
--- a/components/drivers/wlan/wlan_prot.c
+++ b/components/drivers/wlan/wlan_prot.c
@@ -13,16 +13,16 @@
#include <wlan_dev.h>
#include <wlan_prot.h>
-#define DBG_ENABLE
+#define DBG_TAG "WLAN.prot"
#ifdef RT_WLAN_PROT_DEBUG
-#define DBG_LEVEL DBG_LOG
+#define DBG_LVL DBG_LOG
#else
-#define DBG_LEVEL DBG_INFO
-#endif
-#define DBG_SECTION_NAME "WLAN.prot"
-#define DBG_COLOR
+#define DBG_LVL DBG_INFO
+#endif /* RT_WLAN_PROT_DEBUG */
#include <rtdbg.h>
+#ifdef RT_WLAN_PROT_ENABLE
+
#if RT_WLAN_PROT_NAME_LEN < 4
#error "The name is too short"
#endif
@@ -162,7 +162,7 @@ rt_err_t rt_wlan_prot_attach_dev(struct rt_wlan_device *wlan, const char *prot_n
{
int i = 0;
struct rt_wlan_prot *prot = wlan->prot;
- rt_wlan_dev_event_t event;
+ rt_wlan_dev_event_handler handler = rt_wlan_prot_event_handle;
if (wlan == RT_NULL)
{
@@ -182,7 +182,7 @@ rt_err_t rt_wlan_prot_attach_dev(struct rt_wlan_device *wlan, const char *prot_n
rt_wlan_prot_detach_dev(wlan);
#ifdef RT_WLAN_PROT_LWIP_PBUF_FORCE
- if (rt_strcmp(RT_WLAN_PROT_LWIP, prot_name) != 0)
+ if (rt_strcmp(RT_WLAN_PROT_LWIP_NAME, prot_name) != 0)
{
return -RT_ERROR;
}
@@ -204,13 +204,12 @@ rt_err_t rt_wlan_prot_attach_dev(struct rt_wlan_device *wlan, const char *prot_n
return -RT_ERROR;
}
- for (event = RT_WLAN_DEV_EVT_INIT_DONE; event < RT_WLAN_DEV_EVT_MAX; event ++)
- {
- if (rt_wlan_dev_register_event_handler(wlan, event, rt_wlan_prot_event_handle, RT_NULL) != RT_EOK)
- {
- LOG_E("prot register event filed:%d", event);
- }
- }
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_CONNECT, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_DISCONNECT, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_START, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_STOP, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_ASSOCIATED, handler, RT_NULL);
+ rt_wlan_dev_register_event_handler(wlan, RT_WLAN_DEV_EVT_AP_DISASSOCIATED, handler, RT_NULL);
return RT_EOK;
}
@@ -362,3 +361,4 @@ void rt_wlan_prot_dump(void)
}
}
}
+#endif
diff --git a/components/drivers/wlan/wlan_prot.h b/components/drivers/wlan/wlan_prot.h
index 34c5bae7fd..2df979270f 100644
--- a/components/drivers/wlan/wlan_prot.h
+++ b/components/drivers/wlan/wlan_prot.h
@@ -25,8 +25,6 @@ extern "C" {
#define RT_LWAN_ID_PREFIX (0x5054)
-#define RT_WLAN_PROT_LWIP ("lwip")
-
typedef enum
{
RT_WLAN_PROT_EVT_INIT_DONE = 0,
diff --git a/components/drivers/wlan/wlan_workqueue.c b/components/drivers/wlan/wlan_workqueue.c
index f65ac95d08..4cd98346d2 100644
--- a/components/drivers/wlan/wlan_workqueue.c
+++ b/components/drivers/wlan/wlan_workqueue.c
@@ -13,12 +13,12 @@
#include <wlan_workqueue.h>
#include <ipc/workqueue.h>
-#define DBG_ENABLE
-#define DBG_LEVEL DBG_INFO
-#define DBG_SECTION_NAME "WLAN.work"
-#define DBG_COLOR
+#define DBG_TAG "WLAN.work"
+#define DBG_LVL DBG_INFO
#include <rtdbg.h>
+#ifdef RT_WLAN_WORK_THREAD_ENABLE
+
struct rt_wlan_work
{
struct rt_work work;
@@ -97,3 +97,5 @@ int rt_wlan_workqueue_init(void)
return 0;
}
INIT_PREV_EXPORT(rt_wlan_workqueue_init);
+
+#endif