Compare commits
147 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1435548e7 | ||
|
|
a8d40eb706 | ||
|
|
aeffaea016 | ||
|
|
9ce7b0ceb7 | ||
|
|
1c31156a37 | ||
|
|
e795ab73a0 | ||
|
|
5e689dfe15 | ||
|
|
d10cbd5daf | ||
|
|
40a019e063 | ||
|
|
2080cf1206 | ||
|
|
ae521bf95c | ||
|
|
a2f7b67dc4 | ||
|
|
e79319cac9 | ||
|
|
7acb667e20 | ||
|
|
a04b1fa551 | ||
|
|
c37c60c7c7 | ||
|
|
0738c09a4d | ||
|
|
cf4dfde49d | ||
|
|
d4ba2eef57 | ||
|
|
3d96f64f94 | ||
|
|
a746eb4bb1 | ||
|
|
c84e769f78 | ||
|
|
d11260ef67 | ||
|
|
e6193bd131 | ||
|
|
dd1f1d3ba8 | ||
|
|
bc1e7c4bd5 | ||
|
|
7d76b4bae1 | ||
|
|
7c0ef50bb3 | ||
|
|
0f2cb9f900 | ||
|
|
7c1fae04b2 | ||
|
|
14f5dd2dd3 | ||
|
|
9029f8c5b1 | ||
|
|
b9915e0e1b | ||
|
|
1387790744 | ||
|
|
c5fc9f338e | ||
|
|
4d61e5e053 | ||
|
|
1a7259649b | ||
|
|
628e4ee928 | ||
|
|
749369b6fc | ||
|
|
89cd77374c | ||
|
|
3792ad4905 | ||
|
|
2789633b50 | ||
|
|
94505f9e41 | ||
|
|
c8b832e1a0 | ||
|
|
d3aa9449e1 | ||
|
|
4d7938e349 | ||
|
|
4777a65f54 | ||
|
|
96c0b655fd | ||
|
|
61da3794cf | ||
|
|
45ea9928bc | ||
|
|
64e2b8d480 | ||
|
|
fed6f26ebd | ||
|
|
513772a534 | ||
|
|
e45a2857df | ||
|
|
c8ecf31c99 | ||
|
|
4395c7f039 | ||
|
|
3057f41020 | ||
|
|
47c0255cdc | ||
|
|
d53e8a2adf | ||
|
|
3bdb3bbf84 | ||
|
|
3c1168d58c | ||
|
|
f672591d58 | ||
|
|
84598eed7c | ||
|
|
7574063e94 | ||
|
|
0d916af297 | ||
|
|
b90d6a727e | ||
|
|
d0d6f99c90 | ||
|
|
9673b2cf67 | ||
|
|
7061367484 | ||
|
|
faf90663a9 | ||
|
|
bb58348510 | ||
|
|
8253f074ce | ||
|
|
8a93ca4bce | ||
|
|
8968b7b3c9 | ||
|
|
2ca22deaad | ||
|
|
340fa4e024 | ||
|
|
822cd9d679 | ||
|
|
e061b8e784 | ||
|
|
8856361be0 | ||
|
|
1c7110bd86 | ||
|
|
48efbfe521 | ||
|
|
c540080c96 | ||
|
|
d970f88f06 | ||
|
|
2d1b4b8b82 | ||
|
|
9bac9537db | ||
|
|
f35b345680 | ||
|
|
56868b513a | ||
|
|
85a494326a | ||
|
|
ccf97b35e3 | ||
|
|
4dff5aac24 | ||
|
|
66e95c9d81 | ||
|
|
16180bfc8e | ||
|
|
9d24ae4725 | ||
|
|
8162a156d4 | ||
|
|
b59c1c6613 | ||
|
|
1c6f062bc9 | ||
|
|
c1fbb4ae56 | ||
|
|
e77657e723 | ||
|
|
00546b64b7 | ||
|
|
a26d8b602c | ||
|
|
0c36483b40 | ||
|
|
bfb8146699 | ||
|
|
77c3f17b7d | ||
|
|
01c6d60076 | ||
|
|
841cf83c22 | ||
|
|
dcbad9eebe | ||
|
|
3861728751 | ||
|
|
9172223fe6 | ||
|
|
0c21844166 | ||
|
|
f446a7e95b | ||
|
|
b439be2475 | ||
|
|
3aeadb3046 | ||
|
|
0bfa749333 | ||
|
|
b39c9b779a | ||
|
|
773cad823f | ||
|
|
8f56dbdff4 | ||
|
|
31a86ac578 | ||
|
|
ca5d2902f3 | ||
|
|
d35d5bc12f | ||
|
|
5657b2a028 | ||
|
|
dc4887aef1 | ||
|
|
4b59a1330e | ||
|
|
ef126eafa6 | ||
|
|
53fe0f2cd5 | ||
|
|
2bac932648 | ||
|
|
a51edd9231 | ||
|
|
5a06a85484 | ||
|
|
cc4c7727df | ||
|
|
bbdf098dfe | ||
|
|
c47b8dd3e1 | ||
|
|
25d14f3f89 | ||
|
|
d7c0add7ef | ||
|
|
e9ad3bdc21 | ||
|
|
9c5af19cb1 | ||
|
|
0322934cf4 | ||
|
|
2241098561 | ||
|
|
70a22c24c7 | ||
|
|
419622f4e4 | ||
|
|
19d509052a | ||
|
|
bb8cfe23de | ||
|
|
4cd9031d31 | ||
|
|
cda6e48fc1 | ||
|
|
854e633808 | ||
|
|
80f19f738c | ||
|
|
66c46a3eb2 | ||
|
|
79f0a1989e | ||
|
|
cbba334678 |
35
.readthedocs.yaml
Normal file
35
.readthedocs.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
# Read the Docs configuration file for Sphinx projects
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Set the OS, Python version and other tools you might need
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
# You can also specify other tool versions:
|
||||
# nodejs: "20"
|
||||
# rust: "1.70"
|
||||
# golang: "1.20"
|
||||
|
||||
# Build documentation in the "docs/" directory with Sphinx
|
||||
sphinx:
|
||||
configuration: docs/source/conf.py
|
||||
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
|
||||
# builder: "dirhtml"
|
||||
# Fail on all warnings to avoid broken references
|
||||
# fail_on_warning: true
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF and ePub
|
||||
# formats:
|
||||
# - pdf
|
||||
# - epub
|
||||
|
||||
# Optional but recommended, declare the Python requirements required
|
||||
# to build your documentation
|
||||
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
@@ -1,56 +1,57 @@
|
||||
## Script for hpmicro ##
|
||||
sdk_inc(common)
|
||||
sdk_inc(osal)
|
||||
sdk_inc(core)
|
||||
sdk_inc(class/cdc)
|
||||
sdk_inc(class/hid)
|
||||
sdk_inc(class/msc)
|
||||
sdk_inc(class/audio)
|
||||
sdk_inc(class/video)
|
||||
sdk_inc(class/hub)
|
||||
add_library(cherryusb STATIC)
|
||||
|
||||
target_include_directories(cherryusb PUBLIC
|
||||
common
|
||||
core
|
||||
osal
|
||||
class/cdc
|
||||
class/hid
|
||||
class/msc
|
||||
class/audio
|
||||
class/video
|
||||
class/hub
|
||||
class/wireless
|
||||
)
|
||||
|
||||
if(CONFIG_CHERRYUSB_DEVICE)
|
||||
sdk_src(core/usbd_core.c)
|
||||
sdk_src(port/hpm/usb_dc_hpm.c)
|
||||
sdk_compile_definitions(-DCONFIG_USB_HS)
|
||||
if(CONFIG_CHERRYUSB_DEVICE_CDC)
|
||||
sdk_src(class/cdc/usbd_cdc.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_DEVICE_HID)
|
||||
sdk_src(class/hid/usbd_hid.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_DEVICE_MSC)
|
||||
sdk_src(class/msc/usbd_msc.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_DEVICE_AUDIO)
|
||||
sdk_src(class/audio/usbd_audio.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_DEVICE_VIDEO)
|
||||
sdk_src(class/video/usbd_video.c)
|
||||
target_sources(cherryusb PRIVATE core/usbd_core.c)
|
||||
if(CONFIG_CHERRYUSB_DEVICE_CDC)
|
||||
target_sources(cherryusb PRIVATE class/cdc/usbd_cdc.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_DEVICE_HID)
|
||||
target_sources(cherryusb PRIVATE class/hid/usbd_hid.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_DEVICE_MSC)
|
||||
target_sources(cherryusb PRIVATE class/msc/usbd_msc.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_DEVICE_AUDIO)
|
||||
target_sources(cherryusb PRIVATE class/audio/usbd_audio.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_DEVICE_VIDEO)
|
||||
target_sources(cherryusb PRIVATE class/video/usbd_video.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_CHERRYUSB_DEVICE_DEMO_CDC)
|
||||
sdk_src(demo/cdc_acm_template.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_CHERRYUSB_DEVICE_DEMO_CDC_MSC)
|
||||
sdk_src(demo/cdc_acm_msc_template.c)
|
||||
endif()
|
||||
|
||||
elseif(CONFIG_CHERRYUSB_HOST)
|
||||
sdk_src(core/usbh_core.c)
|
||||
sdk_src(class/hub/usbh_hub.c)
|
||||
sdk_src(port/ehci/usb_hc_ehci.c)
|
||||
sdk_src(port/ehci/usb_glue_hpm.c)
|
||||
sdk_src(osal/usb_osal_freertos.c)
|
||||
sdk_src(class/cdc/usbh_cdc_acm.c)
|
||||
sdk_src(class/msc/usbh_msc.c)
|
||||
sdk_src(class/hid/usbh_hid.c)
|
||||
sdk_src(class/wireless/usbh_rndis.c)
|
||||
if(CONFIG_CHERRYUSB_HOST_DEMO)
|
||||
sdk_src(demo/usb_host.c)
|
||||
endif()
|
||||
if(CONFIG_CHERRYUSB_HOST)
|
||||
target_sources(cherryusb PRIVATE
|
||||
core/usbh_core.c
|
||||
class/hub/usbh_hub.c
|
||||
class/cdc/usbh_cdc_acm.c
|
||||
class/hid/usbh_hid.c
|
||||
class/msc/usbh_msc.c
|
||||
class/audio/usbh_audio.c
|
||||
class/video/usbh_video.c
|
||||
class/wireless/usbh_rndis.c
|
||||
)
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
if(DEFINED CONFIG_CHERRYUSB_OSAL)
|
||||
if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "freertos")
|
||||
target_sources(cherryusb PRIVATE osal/usb_osal_freertos.c)
|
||||
elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "rtthread")
|
||||
target_sources(cherryusb PRIVATE osal/usb_osal_rtthread.c)
|
||||
elseif("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "yoc")
|
||||
target_sources(cherryusb PRIVATE osal/usb_osal_yoc.c)
|
||||
endif()
|
||||
endif()
|
||||
124
README.md
124
README.md
@@ -2,19 +2,37 @@
|
||||
|
||||
[中文版](./README_zh.md)
|
||||
|
||||
CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB ip.
|
||||
CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP.
|
||||
|
||||

|
||||

|
||||
|
||||
## Why choose
|
||||
|
||||
- Streamlined code with small memory usage which also can be further trimmed
|
||||
- Comprehensive class drivers and all master and slave class drivers are templated,making it easy for users to add new class drivers and find patterns when learning
|
||||
- The APIs available to the users are very few and clearly categorised. Device: initialisation + registration apis, command callback apis, data sending and receiving apis; Host: initialisation + lookup apis, data sending and receiving apis
|
||||
- Tree-based programming with a hierarchy of code that makes it easy for the user to sort out function call relationships, enumerations and class-driven loading processes
|
||||
- Standardised porting interface, no need to rewrite the driver for the same ip, and porting drivers are templated to make it easier for users to add new ports
|
||||
- The use of the device or host transceiver apis are equivalent to the use of the uart tx/rx dma, and there is no limit to the length
|
||||
- Capable of achieving theoretical USB hardware bandwidth
|
||||
### Easy to study USB
|
||||
|
||||
In order to make it easier for users to learn USB basics, enumeration, driver loading and IP drivers, the code has been written with the following advantages:
|
||||
|
||||
- Lean code, simple logic, no complex C syntax
|
||||
- Tree-based programming with cascading code
|
||||
- Class-drivers and porting-drivers are templating and simplification
|
||||
- Clear API classification (slave: initialisation, registration api, command callback api, data sending and receiving api; host: initialisation, lookup api, data sending and receiving api)
|
||||
|
||||
### Easy to use USB
|
||||
|
||||
In order to facilitate the use of the USB interface and to take into account the fact that users have learned about uart and dma, the following advantages have been designed for the data sending and receiving class of interface:
|
||||
|
||||
- Equivalent to using uart tx dma/uart rx dma
|
||||
- There is no limit to the length of send and receive, the user does not need to care about the USB packetization process (the porting driver does the packetization process)
|
||||
|
||||
### Easy to bring out USB performance
|
||||
|
||||
Taking into account USB performance issues and trying to achieve the theoretical bandwidth of the USB hardware, the design of the data transceiver class interface has the following advantages:
|
||||
|
||||
- Porting drivers directly to registers, no abstraction layer encapsulation
|
||||
- Memory zero copy
|
||||
- If IP has DMA then uses DMA mode (DMA with hardware packetization)
|
||||
- Unlimited length make it easier to interface with hardware DMA and take advantage of DMA
|
||||
- Subcontracting function is handled in interrupt
|
||||
|
||||
## Directoy Structure
|
||||
|
||||
@@ -36,13 +54,12 @@ CherryUSB is a tiny, beautiful and portable USB host and device stack for embedd
|
||||
|:-------------:|:---------------------------:|
|
||||
|class | usb class driver |
|
||||
|common | usb spec macros and utils |
|
||||
|core | usb core implementation |
|
||||
|demo | different chips demo |
|
||||
|osal | os wrapper |
|
||||
|docs | doc for guiding |
|
||||
|packet capture | packet capture file |
|
||||
|port | usb dcd and hcd porting |
|
||||
|tools | tool used url |
|
||||
|core | usb core implementation |
|
||||
|demo | different chips demo |
|
||||
|osal | os wrapper |
|
||||
|docs | doc for guiding |
|
||||
|port | usb dcd and hcd porting |
|
||||
|tools | tool url |
|
||||
|
||||
## Device Stack Overview
|
||||
|
||||
@@ -50,7 +67,7 @@ CherryUSB Device Stack provides a unified framework of functions for standard de
|
||||
|
||||
CherryUSB Device Stack has the following functions:
|
||||
|
||||
- Support USB2.0 full and high speed
|
||||
- Support USB2.0 full and high speed, USB3.0 super speed
|
||||
- Support endpoint irq callback register by users, let users do whatever they wants in endpoint irq callback.
|
||||
- Support Composite Device
|
||||
- Support Communication Device Class (CDC)
|
||||
@@ -68,12 +85,13 @@ CherryUSB Device Stack resource usage (GCC 10.2 with -O2):
|
||||
|
||||
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|
||||
|:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:|
|
||||
|usbd_core.c | 3263 | 384 | 17 | 0 |
|
||||
|usbd_cdc.c | 490 | 0 | 0 | 0 |
|
||||
|usbd_msc.c | 2772 | 128 + 512(default) | 16 | 0 |
|
||||
|usbd_hid.c | 501 | 0 | 0 | 0 |
|
||||
|usbd_audio.c | 1208 | 0 | 4 | 0 |
|
||||
|usbd_video.c | 2272 | 0 | 82 | 0 |
|
||||
|usbd_core.c | 3516 | 256(default) + 320 | 0 | 0 |
|
||||
|usbd_cdc.c | 392 | 0 | 0 | 0 |
|
||||
|usbd_msc.c | 2839 | 128 + 512(default) | 16 | 0 |
|
||||
|usbd_hid.c | 364 | 0 | 0 | 0 |
|
||||
|usbd_audio.c | 1455 | 0 | 0 | 0 |
|
||||
|usbd_video.c | 2494 | 0 | 84 | 0 |
|
||||
|usbd_rndis.c | 2109 | 3340 | 76 | 0 |
|
||||
|
||||
## Host Stack Overview
|
||||
|
||||
@@ -99,13 +117,14 @@ CherryUSB Host Stack resource usage (GCC 10.2 with -O2):
|
||||
|
||||
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|
||||
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:-------------------------------:|
|
||||
|usbh_core.c | 4417 | 512 | 28 | sizeof(struct usbh_urb) |
|
||||
|usbh_hub.c | 4895 | 32 + 1* (1+n) | 16 + sizeof(struct usbh_hub) * (1+n) | 0 |
|
||||
|usbh_cdc_acm.c | 1064 | 7 | 4 | sizeof(struct usbh_cdc_acm) * x |
|
||||
|usbh_msc.c | 1776 | 32 | 4 | sizeof(struct usbh_msc) * x |
|
||||
|usbh_hid.c | 922 | 128 | 4 | sizeof(struct usbh_hid) * x |
|
||||
|usbh_video.c | 3592 | 128 | 4 | sizeof(struct usbh_video) * x |
|
||||
|usbh_audio.c | 3230 | 128 | 4 | sizeof(struct usbh_audio) * x |
|
||||
|usbh_core.c | 4237 | 512 + 8 * (1+x) *n | 28 | sizeof(struct usbh_urb) |
|
||||
|usbh_hub.c | 2919 | 32 + 4* (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 |
|
||||
|usbh_cdc_acm.c | 1099 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|
||||
|usbh_msc.c | 2502 | 32 | 4 + sizeof(struct usbh_msc) * x | 0 |
|
||||
|usbh_hid.c | 956 | 128 | 4 + sizeof(struct usbh_hid) * x | 0 |
|
||||
|usbh_video.c | 2330 | 128 | 4 + sizeof(struct usbh_video) * x | 0 |
|
||||
|usbh_audio.c | 3168 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 |
|
||||
|usbh_rndis.c | 3030 | 4096 | 4 + sizeof(struct usbh_rndis) * x | 0 |
|
||||
|
||||
Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affected by the following macros:
|
||||
|
||||
@@ -117,6 +136,18 @@ Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affe
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
```
|
||||
|
||||
x is affected by the following macros:
|
||||
|
||||
```
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_HID_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_MSC_CLASS 2
|
||||
#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1
|
||||
#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1
|
||||
#define CONFIG_USBHOST_MAX_RNDIS_CLASS 1
|
||||
|
||||
```
|
||||
|
||||
## Documentation Tutorial
|
||||
|
||||
Quickly start, USB basic concepts, API manual, Class basic concepts and examples, see [CherryUSB Documentation Tutorial](https://cherryusb.readthedocs.io/)
|
||||
@@ -131,25 +162,22 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr
|
||||
|
||||
## Demo Repo
|
||||
|
||||
Note: After version 0.4.1, the dcd drivers have been refactored and some repositories are not maintained for a long time, so if you use a higher version, you need to update it yourself.
|
||||
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url |Corresponds to master version|
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url |Current version|
|
||||
|:--------------------:|:------------------:|:-----:|:--------:|:---------------------------:|
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bl_mcu_sdk](https://github.com/CherryUSB/cherryusb_bouffalolab)| latest |
|
||||
|ST | STM32F103C8T6 | fsdev |[stm32f103_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32f103c8t6)|latest |
|
||||
|ST | STM32F4 | dwc2 |[stm32f429_device_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32f429igt6) [stm32f429_host_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_host/stm32f429igt6)|latest |
|
||||
|ST | STM32H7 | dwc2 |[stm32h743_device_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32h743vbt6) [stm32h743_host_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_host/stm32h743xih6)|latest |
|
||||
|HPMicro | HPM6750 | hpm/ehci |[hpm_repo](https://github.com/CherryUSB/cherryusb_hpmicro)|v0.6.0 |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/es32)|latest |
|
||||
|AllwinnerTech | F1C100S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|latest |
|
||||
|Phytium | e2000 | xhci |[phytium _repo](https://gitee.com/phytium_embedded/phytium-standalone-sdk)|latest |
|
||||
|Raspberry pi | rp2040 | rp2040 |[rp2040_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/rp2040)|latest |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|latest |
|
||||
|Nordicsemi | Nrf52840 | nrf5x |[nrf5x_repo](https://github.com/CherryUSB/cherryusb_nrf5x)|latest |
|
||||
|Nuvoton | Nuc442 | nuvoton |[nuc442_repo](https://github.com/CherryUSB/cherryusb_nuc442)|v0.4.1 |
|
||||
|Geehy | APM32E10x APM32F0xx| fsdev |[apm32_repo](https://github.com/CherryUSB/cherryusb_apm32)|v0.4.1 |
|
||||
|Espressif | esp32 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|v0.4.1 |
|
||||
|Mindmotion | MM32L3xx | mm32 |[mm32_repo](https://github.com/CherryUSB/cherryusb_mm32)|v0.4.1 |
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/cherryusb_bouffalolab)| v0.10.1 |
|
||||
|ST | STM32F1x | fsdev |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|≤ v0.10.1 |
|
||||
|ST | STM32F4/STM32H7 | dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|≤ v0.10.1 |
|
||||
|HPMicro | HPM6750 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/cherryusb_hpmicro)| v0.10.1 |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|≤ v0.10.1 |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|≤ v0.10.1 |
|
||||
|Phytium | e2000 | xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|v0.10.1 |
|
||||
|Phytium | PhytiumPI | pusb2 |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|v0.10.1 |
|
||||
|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|≤ v0.10.1 |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|≤ v0.10.1 |
|
||||
|Nordicsemi | Nrf52840 | nrf5x |[nrf5x_repo](https://github.com/CherryUSB/cherryusb_nrf5x)|≤ v0.10.1 |
|
||||
|Espressif | esp32s3 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|≤ v0.10.1 |
|
||||
|Bekencorp | BK72xx | musb |[armino](https://github.com/CherryUSB/armino)|v0.7.0 |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)|v0.7.0 |
|
||||
|
||||
## Contact
|
||||
|
||||
|
||||
123
README_zh.md
123
README_zh.md
@@ -2,19 +2,37 @@
|
||||
|
||||
[English](./README.md)
|
||||
|
||||
CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB ip)的 USB 主从协议栈。
|
||||
CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的 USB 主从协议栈。
|
||||
|
||||

|
||||

|
||||
|
||||
## 为什么选择
|
||||
|
||||
- 代码精简,并且内存占用极小,详细参考下面表格,而且还可进一步的裁剪
|
||||
- 全面的 class 驱动,并且主从 class 驱动全部模板化,方便用户增加新的 class 驱动以及学习的时候查找规律
|
||||
- 可供用户使用的 API 非常少,并且分类清晰。从机:初始化 + 注册类、命令回调类、数据收发类;主机:初始化 + 查找类、数据收发类
|
||||
- 树状化编程,代码层层递进,方便用户理清函数调用关系、枚举和 class 驱动加载过程
|
||||
- 标准化的 porting 接口,相同 ip 无需重写驱动,并且 porting 驱动也进行了模板化,方便用户新增 porting。
|
||||
- 主从收发接口的使用等价于 uart tx/rx dma 的使用,长度也没有限制
|
||||
- 能够达到 USB 硬件理论带宽
|
||||
### 易于学习 USB
|
||||
|
||||
为了方便用户学习 USB 基本知识、枚举、驱动加载、IP 驱动,因此,编写的代码具备以下优点:
|
||||
|
||||
- 代码精简,逻辑简单,无复杂 C 语言语法
|
||||
- 树状化编程,代码层层递进
|
||||
- Class 驱动和 porting 驱动模板化、精简化
|
||||
- API 分类清晰(从机:初始化、注册类、命令回调类、数据收发类;主机:初始化、查找类、数据收发类)
|
||||
|
||||
### 易于使用 USB
|
||||
|
||||
为了方便用户使用 USB 接口,考虑到用户学习过 uart 和 dma,因此,设计的数据收发类接口具备以下优点:
|
||||
|
||||
- 等价于使用 uart tx dma/uart rx dma
|
||||
- 收发长度没有限制,用户不需要关心 USB 分包过程(porting 驱动做分包过程)
|
||||
|
||||
### 易于发挥 USB 性能
|
||||
|
||||
考虑到 USB 性能问题,尽量达到 USB 硬件理论带宽,因此,设计的数据收发类接口具备以下优点:
|
||||
|
||||
- Porting 驱动直接对接寄存器,无抽象层封装
|
||||
- Memory zero copy
|
||||
- IP 如果带 DMA 则使用 DMA 模式(DMA 带硬件分包功能)
|
||||
- 长度无限制,方便对接硬件 DMA 并且发挥 DMA 的优势
|
||||
- 分包功能在中断中处理
|
||||
|
||||
## 目录结构
|
||||
|
||||
@@ -26,22 +44,20 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带
|
||||
├── demo
|
||||
├── docs
|
||||
├── osal
|
||||
├── packet capture
|
||||
└── port
|
||||
└── tools
|
||||
```
|
||||
|
||||
| 目录名 | 描述 |
|
||||
|:-------------:|:------------------------------:|
|
||||
|:-------------:|:-------------------------------:|
|
||||
|class | usb class 类主从驱动 |
|
||||
|common | usb spec 定义、常用宏、标准接口定义 |
|
||||
|core | usb 主从协议栈核心实现 |
|
||||
|demo | 示例 |
|
||||
|docs | 文档 |
|
||||
|core | usb 主从协议栈核心实现 |
|
||||
|demo | 示例 |
|
||||
|docs | 文档 |
|
||||
|osal | os 封装层 |
|
||||
|packet capture | 抓包文件(需要使用力科软件打开)|
|
||||
|port | usb 主从需要实现的 porting 接口 |
|
||||
|tools | 工具链接 |
|
||||
|tools | 工具链接 |
|
||||
|
||||
## Device 协议栈简介
|
||||
|
||||
@@ -49,7 +65,7 @@ CherryUSB Device 协议栈对标准设备请求、CLASS 请求、VENDOR 请求
|
||||
|
||||
CherryUSB Device 协议栈当前实现以下功能:
|
||||
|
||||
- 支持 USB2.0 全速和高速设备
|
||||
- 支持 USB2.0 全速和高速设备,USB3.0 超速设备
|
||||
- 支持端点中断注册功能,porting 给用户自己处理中断里的数据
|
||||
- 支持复合设备
|
||||
- 支持 Communication Device Class (CDC)
|
||||
@@ -67,12 +83,13 @@ CherryUSB Device 协议栈资源占用说明(GCC 10.2 with -O2):
|
||||
|
||||
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|
||||
|:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:|
|
||||
|usbd_core.c | 3263 | 384 | 17 | 0 |
|
||||
|usbd_cdc.c | 490 | 0 | 0 | 0 |
|
||||
|usbd_msc.c | 2772 | 128 + 512(default) | 16 | 0 |
|
||||
|usbd_hid.c | 501 | 0 | 0 | 0 |
|
||||
|usbd_audio.c | 1208 | 0 | 4 | 0 |
|
||||
|usbd_video.c | 2272 | 0 | 82 | 0 |
|
||||
|usbd_core.c | 3516 | 256(default) + 320 | 0 | 0 |
|
||||
|usbd_cdc.c | 392 | 0 | 0 | 0 |
|
||||
|usbd_msc.c | 2839 | 128 + 512(default) | 16 | 0 |
|
||||
|usbd_hid.c | 364 | 0 | 0 | 0 |
|
||||
|usbd_audio.c | 1455 | 0 | 0 | 0 |
|
||||
|usbd_video.c | 2494 | 0 | 84 | 0 |
|
||||
|usbd_rndis.c | 2109 | 3340 | 76 | 0 |
|
||||
|
||||
## Host 协议栈简介
|
||||
|
||||
@@ -98,13 +115,14 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2):
|
||||
|
||||
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|
||||
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:-------------------------------:|
|
||||
|usbh_core.c | 4417 | 512 | 28 | sizeof(struct usbh_urb) |
|
||||
|usbh_hub.c | 4895 | 32 + 1* (1+n) | 16 + sizeof(struct usbh_hub) * (1+n) | 0 |
|
||||
|usbh_cdc_acm.c | 1064 | 7 | 4 | sizeof(struct usbh_cdc_acm) * x |
|
||||
|usbh_msc.c | 1776 | 32 | 4 | sizeof(struct usbh_msc) * x |
|
||||
|usbh_hid.c | 922 | 128 | 4 | sizeof(struct usbh_hid) * x |
|
||||
|usbh_video.c | 3592 | 128 | 4 | sizeof(struct usbh_video) * x |
|
||||
|usbh_audio.c | 3230 | 128 | 4 | sizeof(struct usbh_audio) * x |
|
||||
|usbh_core.c | 4237 | 512 + 8 * (1+x) *n | 28 | sizeof(struct usbh_urb) |
|
||||
|usbh_hub.c | 2919 | 32 + 4* (1+x) | 12 + sizeof(struct usbh_hub) * (1+x) | 0 |
|
||||
|usbh_cdc_acm.c | 1099 | 7 | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|
||||
|usbh_msc.c | 2502 | 32 | 4 + sizeof(struct usbh_msc) * x | 0 |
|
||||
|usbh_hid.c | 956 | 128 | 4 + sizeof(struct usbh_hid) * x | 0 |
|
||||
|usbh_video.c | 2330 | 128 | 4 + sizeof(struct usbh_video) * x | 0 |
|
||||
|usbh_audio.c | 3168 | 128 | 4 + sizeof(struct usbh_audio) * x | 0 |
|
||||
|usbh_rndis.c | 3030 | 4096 | 4 + sizeof(struct usbh_rndis) * x | 0 |
|
||||
|
||||
其中,`sizeof(struct usbh_hub)` 和 `sizeof(struct usbh_hubport)` 受以下宏影响:
|
||||
|
||||
@@ -116,6 +134,18 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2):
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
```
|
||||
|
||||
x 受以下宏影响:
|
||||
|
||||
```
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_HID_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_MSC_CLASS 2
|
||||
#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1
|
||||
#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1
|
||||
#define CONFIG_USBHOST_MAX_RNDIS_CLASS 1
|
||||
|
||||
```
|
||||
|
||||
## 文档教程
|
||||
|
||||
CherryUSB 快速入门、USB 基本概念,API 手册,Class 基本概念和例程,参考 [CherryUSB 文档教程](https://cherryusb.readthedocs.io/)
|
||||
@@ -130,25 +160,22 @@ USB 基本知识点与 CherryUSB Device 协议栈是如何编写的,参考 [Ch
|
||||
|
||||
## 示例仓库
|
||||
|
||||
注意:0.4.1 版本以后 dcd 驱动进行了重构,部分仓库不做长期维护,所以如果使用高版本需要自行更新
|
||||
|
||||
| 厂商 | 芯片或者系列 | USB IP| 仓库链接 | 对应 master 版本 |
|
||||
| 厂商 | 芯片或者系列 | USB IP| 仓库链接 | 当前版本 |
|
||||
|:--------------------:|:------------------:|:-----:|:--------:|:---------------------------:|
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bl_mcu_sdk](https://github.com/CherryUSB/cherryusb_bouffalolab)| latest |
|
||||
|ST | STM32F103C8T6 | fsdev |[stm32f103_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32f103c8t6)|latest |
|
||||
|ST | STM32F4 | dwc2 |[stm32f429_device_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32f429igt6) [stm32f429_host_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_host/stm32f429igt6)|latest |
|
||||
|ST | STM32H7 | dwc2 |[stm32h743_device_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32h743vbt6) [stm32h743_host_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_host/stm32h743xih6)|latest |
|
||||
|HPMicro | HPM6750 | hpm/ehci |[hpm_repo](https://github.com/CherryUSB/cherryusb_hpmicro)|v0.6.0 |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/es32)|latest |
|
||||
|AllwinnerTech | F1C100S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|latest |
|
||||
|Phytium | e2000 | xhci |[phytium _repo](https://gitee.com/phytium_embedded/phytium-standalone-sdk)|latest |
|
||||
|Raspberry pi | rp2040 | rp2040 |[rp2040_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/rp2040)|latest |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|latest |
|
||||
|Nordicsemi | Nrf52840 | nrf5x |[nrf5x_repo](https://github.com/CherryUSB/cherryusb_nrf5x)|latest |
|
||||
|Nuvoton | Nuc442 | nuvoton |[nuc442_repo](https://github.com/CherryUSB/cherryusb_nuc442)|v0.4.1 |
|
||||
|Geehy | APM32E10x APM32F0xx| fsdev |[apm32_repo](https://github.com/CherryUSB/cherryusb_apm32)|v0.4.1 |
|
||||
|Espressif | esp32 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|v0.4.1 |
|
||||
|Mindmotion | MM32L3xx | mm32 |[mm32_repo](https://github.com/CherryUSB/cherryusb_mm32)|v0.4.1 |
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/cherryusb_bouffalolab)| v0.10.1 |
|
||||
|ST | STM32F1x | fsdev |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|≤ v0.10.1 |
|
||||
|ST | STM32F4/STM32H7 | dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|≤ v0.10.1 |
|
||||
|HPMicro | HPM6750 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/cherryusb_hpmicro)| v0.10.1 |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|≤ v0.10.1 |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|≤ v0.10.1 |
|
||||
|Phytium | e2000 | xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|v0.10.1 |
|
||||
|Phytium | e2000 | pusb2 |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|v0.10.1 |
|
||||
|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|≤ v0.10.1 |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|≤ v0.10.1 |
|
||||
|Nordicsemi | Nrf52840 | nrf5x |[nrf5x_repo](https://github.com/CherryUSB/cherryusb_nrf5x)|≤ v0.10.1 |
|
||||
|Espressif | esp32s3 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|≤ v0.10.1 |
|
||||
|Bekencorp | BK72xx | musb |[armino](https://github.com/CherryUSB/armino)|v0.7.0 |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)|v0.7.0 |
|
||||
|
||||
## Contact
|
||||
|
||||
|
||||
29
SConscript
29
SConscript
@@ -16,7 +16,9 @@ CPPDEFINES = []
|
||||
|
||||
# USB DEVICE
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
path += [cwd + '/osal']
|
||||
src += Glob('core/usbd_core.c')
|
||||
src += Glob('osal/usb_osal_rtthread.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_HS']):
|
||||
CPPDEFINES+=['CONFIG_USB_HS']
|
||||
@@ -44,6 +46,8 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
src += Glob('demo/hid_keyboard_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_MSC_TEMPLATE']):
|
||||
src += Glob('demo/msc_ram_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_MSC_STORAGE_TEMPLATE']):
|
||||
src += Glob('demo/msc_storage_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_AUDIO_V1_TEMPLATE']):
|
||||
src += Glob('demo/audio_v1_mic_speaker_multichan_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_AUDIO_V2_TEMPLATE']):
|
||||
@@ -81,6 +85,12 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
else:
|
||||
src += Glob('port/ch32/usb_dc_usbfs.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_PUSB2']):
|
||||
path += [cwd + '/port/pusb2/common']
|
||||
path += [cwd + '/port/pusb2/fpusb2']
|
||||
src += Glob('port/pusb2/fpusb2' + '/*.c')
|
||||
src += Glob('port/pusb2/usb_dc_pusb2.c')
|
||||
|
||||
# USB HOST
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
path += [cwd + '/osal']
|
||||
@@ -97,6 +107,7 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
src += Glob('class/msc/usbh_msc.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_RNDIS']):
|
||||
src += Glob('class/wireless/usbh_rndis.c')
|
||||
src += Glob('third_party/rt-thread-4.1.1/rndis_host/rndis_host.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_DWC2']):
|
||||
src += Glob('port/dwc2/usb_hc_dwc2.c')
|
||||
@@ -111,9 +122,27 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_EHCI_HPM']):
|
||||
src += Glob('port/ehci/usb_glue_hpm.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_XHCI']):
|
||||
src += Glob('port/xhci/usb_hc_xhci.c')
|
||||
src += Glob('port/xhci/xhci_dbg.c')
|
||||
src += Glob('port/xhci/xhci.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_PUSB2']):
|
||||
path += [cwd + '/port/pusb2/common']
|
||||
path += [cwd + '/port/pusb2/fpusb2']
|
||||
src += Glob('port/pusb2/fpusb2' + '/*.c')
|
||||
src += Glob('port/pusb2/usb_hc_pusb2.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_TEMPLATE']):
|
||||
src += Glob('demo/usb_host.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_CP210X']):
|
||||
path += [cwd + '/class/vendor/cp201x']
|
||||
src += Glob('class/vendor/cp201x/usbh_cp210x.c')
|
||||
src += Glob('third_party/rt-thread-4.1.1/dfs/drv_usbh_cp210x_rtt.c')
|
||||
|
||||
src += Glob('third_party/rt-thread-4.1.1/msh_cmd.c')
|
||||
|
||||
group = DefineGroup('CherryUSB', src, depend = ['PKG_USING_CHERRYUSB'], CPPPATH = path, CPPDEFINES = CPPDEFINES)
|
||||
|
||||
Return('group')
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifndef CHERRYUSB_CONFIG_H
|
||||
#define CHERRYUSB_CONFIG_H
|
||||
|
||||
#define CHERRYUSB_VERSION 0x000800
|
||||
#define CHERRYUSB_VERSION 0x001002
|
||||
|
||||
/* ================ USB common Configuration ================ */
|
||||
|
||||
@@ -44,27 +44,6 @@
|
||||
/* Enable test mode */
|
||||
// #define CONFIG_USBDEV_TEST_MODE
|
||||
|
||||
//#define CONFIG_USBDEV_TX_THREAD
|
||||
//#define CONFIG_USBDEV_RX_THREAD
|
||||
|
||||
#ifdef CONFIG_USBDEV_TX_THREAD
|
||||
#ifndef CONFIG_USBDEV_TX_PRIO
|
||||
#define CONFIG_USBDEV_TX_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_TX_STACKSIZE
|
||||
#define CONFIG_USBDEV_TX_STACKSIZE 2048
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_RX_THREAD
|
||||
#ifndef CONFIG_USBDEV_RX_PRIO
|
||||
#define CONFIG_USBDEV_RX_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_RX_STACKSIZE
|
||||
#define CONFIG_USBDEV_RX_STACKSIZE 2048
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
|
||||
#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
|
||||
#endif
|
||||
@@ -81,16 +60,18 @@
|
||||
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_AUDIO_VERSION
|
||||
#define CONFIG_USBDEV_AUDIO_VERSION 0x0100
|
||||
// #define CONFIG_USBDEV_MSC_THREAD
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRIO
|
||||
#define CONFIG_USBDEV_MSC_PRIO 4
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_AUDIO_MAX_CHANNEL
|
||||
#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8
|
||||
#ifndef CONFIG_USBDEV_MSC_STACKSIZE
|
||||
#define CONFIG_USBDEV_MSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
|
||||
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 128
|
||||
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
|
||||
@@ -116,6 +97,12 @@
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 1
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_HID_CLASS 4
|
||||
#define CONFIG_USBHOST_MAX_MSC_CLASS 2
|
||||
#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1
|
||||
#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1
|
||||
|
||||
#define CONFIG_USBHOST_DEV_NAMELEN 16
|
||||
|
||||
#ifndef CONFIG_USBHOST_PSC_PRIO
|
||||
@@ -127,6 +114,9 @@
|
||||
|
||||
//#define CONFIG_USBHOST_GET_STRING_DESC
|
||||
|
||||
// #define CONFIG_USBHOST_MSOS_ENABLE
|
||||
#define CONFIG_USBHOST_MSOS_VENDOR_CODE 0x00
|
||||
|
||||
/* Ep0 max transfer buffer */
|
||||
#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
|
||||
|
||||
@@ -154,7 +144,7 @@
|
||||
#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
|
||||
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
|
||||
// #define CONFIG_USB_EHCI_INFO_ENABLE
|
||||
// #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
|
||||
// #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE
|
||||
// #define CONFIG_USB_EHCI_CONFIGFLAG
|
||||
// #define CONFIG_USB_EHCI_PORT_POWER
|
||||
|
||||
|
||||
@@ -760,7 +760,7 @@ struct audio_cs_ep_ep_general_descriptor {
|
||||
__VA_ARGS__, /* bmaControls(0) Mute */ \
|
||||
0x00 /* iTerminal */
|
||||
|
||||
#define AUDIO_AS_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, wMaxPacketSize, bInterval, ...) \
|
||||
#define AUDIO_AS_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval, ...) \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber */ \
|
||||
@@ -797,7 +797,7 @@ struct audio_cs_ep_ep_general_descriptor {
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
bEndpointAddress, /* bEndpointAddress : IN endpoint 1 */ \
|
||||
0x01, /* bmAttributes */ \
|
||||
bmAttributes, /* bmAttributes */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
bInterval, /* bInterval : one packet per frame */ \
|
||||
0x00, /* bRefresh */ \
|
||||
@@ -812,6 +812,19 @@ struct audio_cs_ep_ep_general_descriptor {
|
||||
|
||||
#define AUDIO_AS_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07)
|
||||
|
||||
#define AUDIO_MS_STANDARD_DESCRIPTOR_INIT(bInterfaceNumber, bNumEndpoints) \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
bNumEndpoints, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
|
||||
AUDIO_SUBCLASS_MIDISTREAMING, /* bInterfaceSubClass */ \
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
|
||||
0x00 /* iInterface */
|
||||
|
||||
#define AUDIO_MS_STANDARD_DESCRIPTOR_INIT_LEN 0x09
|
||||
|
||||
struct audio_v2_channel_cluster_descriptor {
|
||||
uint8_t bNrChannels;
|
||||
uint32_t bmChannelConfig;
|
||||
@@ -1033,7 +1046,7 @@ struct audio_v2_control_range3_param_block {
|
||||
__VA_ARGS__, /* bmaControls(0) Mute */ \
|
||||
0x00 /* iTerminal */
|
||||
|
||||
#define AUDIO_V2_AS_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bmChannelConfig, bSubslotSize, bBitResolution, bEndpointAddress, wMaxPacketSize, bInterval) \
|
||||
#define AUDIO_V2_AS_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bmChannelConfig, bSubslotSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval) \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber */ \
|
||||
@@ -1071,8 +1084,8 @@ struct audio_v2_control_range3_param_block {
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
bEndpointAddress, /* bEndpointAddress 3 out endpoint for Audio */ \
|
||||
0x01, /* bmAttributes */ \
|
||||
WBVAL(wMaxPacketSize), /* XXXX wMaxPacketSize in Bytes (SampleRate * SlotByteSize * NumChannels) */ \
|
||||
bmAttributes, /* bmAttributes */ \
|
||||
WBVAL(wMaxPacketSize), /* XXXX wMaxPacketSize in Bytes (SampleRate * SlotByteSize * NumChannels) */ \
|
||||
bInterval, /* bInterval */ \
|
||||
0x08, /* bLength */ \
|
||||
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \
|
||||
@@ -1083,9 +1096,66 @@ struct audio_v2_control_range3_param_block {
|
||||
0x00, /* wLockDelay */ \
|
||||
0x00
|
||||
|
||||
#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bmChannelConfig, bSubslotSize, bBitResolution, bEndpointAddress, wMaxPacketSize, bInterval, bFeedbackEndpointAddress) \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x00, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
|
||||
AUDIO_PROTOCOLv20, /* bInterfaceProtocol */ \
|
||||
0x00, /* iInterface */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber */ \
|
||||
0x01, /* bAlternateSetting */ \
|
||||
0x02, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
|
||||
AUDIO_PROTOCOLv20, /* bInterfaceProtocol */ \
|
||||
0x00, /* iInterface */ \
|
||||
0x10, /* bLength */ \
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
|
||||
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \
|
||||
bTerminalLink, /* bTerminalLink : Unit ID of the Output or Input Terminal*/ \
|
||||
0x00, /* bmControls */ \
|
||||
AUDIO_FORMAT_TYPE_I, /* bFormatType : AUDIO_FORMAT_TYPE_I */ \
|
||||
DBVAL(AUDIO_V2_FORMAT_PCM), /* bmFormats PCM */ \
|
||||
bNrChannels, /* bNrChannels */ \
|
||||
DBVAL(bmChannelConfig), /* bmChannelConfig */ \
|
||||
0x00, /* iChannelNames */ \
|
||||
0x06, /* bLength */ \
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
|
||||
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \
|
||||
AUDIO_FORMAT_TYPE_I, /* bFormatType */ \
|
||||
bSubslotSize, /* bSubslotSize */ \
|
||||
bBitResolution, /* bBitResolution */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
bEndpointAddress, /* bEndpointAddress 3 out endpoint for Audio */ \
|
||||
0x05, /* bmAttributes: TransferType=Isochronous SyncType=Asynchronous EndpointType=Data*/ \
|
||||
WBVAL(wMaxPacketSize), /* XXXX wMaxPacketSize in Bytes (SampleRate * SlotByteSize * NumChannels) */ \
|
||||
bInterval, /* bInterval */ \
|
||||
0x08, /* bLength */ \
|
||||
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \
|
||||
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ \
|
||||
0x00, /* bmAttributes */ \
|
||||
0x00, /* bmControls */ \
|
||||
0x00, /* bLockDelayUnits */ \
|
||||
0x00, /* wLockDelay */ \
|
||||
0x00, \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
bFeedbackEndpointAddress, /* bFeedbackEndpointAddress Revise Dir to bEndpointAddress */ \
|
||||
0x11, /* bmAttributes: TransferType=Isochronous SyncType=None EndpointType=Feedback */ \
|
||||
WBVAL(4), /* XXXX wMaxPacketSize in Bytes */ \
|
||||
bInterval /* bInterval */ \
|
||||
|
||||
// clang-format on
|
||||
|
||||
#define AUDIO_V2_AS_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08)
|
||||
#define AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN (0x09 + 0x09 + 0x10 + 0x06 + 0x07 + 0x08 + 0x07)
|
||||
|
||||
#define AUDIO_SAMPLE_FREQ_NUM(num) (uint8_t)(num), (uint8_t)((num >> 8))
|
||||
#define AUDIO_SAMPLE_FREQ_3B(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
|
||||
|
||||
@@ -6,109 +6,71 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_audio.h"
|
||||
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
|
||||
struct usbd_audio_volume_info {
|
||||
uint16_t vol_min;
|
||||
uint16_t vol_max;
|
||||
uint16_t vol_res;
|
||||
uint16_t vol_current;
|
||||
struct audio_entity_param {
|
||||
uint32_t wCur;
|
||||
uint32_t wMin;
|
||||
uint32_t wMax;
|
||||
uint32_t wRes;
|
||||
};
|
||||
|
||||
struct usbd_audio_attribute_control {
|
||||
struct usbd_audio_volume_info volume[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
|
||||
uint8_t mute[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
|
||||
uint8_t automatic_gain[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
|
||||
};
|
||||
#else
|
||||
struct audio_v2_control_range2_param_block_default {
|
||||
uint16_t wNumSubRanges;
|
||||
struct
|
||||
{
|
||||
uint16_t wMin;
|
||||
uint16_t wMax;
|
||||
uint16_t wRes;
|
||||
} subrange[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
|
||||
} __PACKED;
|
||||
struct usbd_audio_priv {
|
||||
struct audio_entity_info *table;
|
||||
uint8_t num;
|
||||
uint16_t uac_version;
|
||||
} g_usbd_audio;
|
||||
|
||||
struct usbd_audio_attribute_control {
|
||||
uint32_t volume_bCUR;
|
||||
uint32_t mute_bCUR;
|
||||
struct audio_v2_control_range2_param_block_default volume;
|
||||
uint8_t mute[CONFIG_USBDEV_AUDIO_MAX_CHANNEL];
|
||||
};
|
||||
#endif
|
||||
struct audio_entity_info {
|
||||
usb_slist_t list;
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bEntityId;
|
||||
void *priv[2];
|
||||
};
|
||||
|
||||
static usb_slist_t usbd_audio_entity_info_head = USB_SLIST_OBJECT_INIT(usbd_audio_entity_info_head);
|
||||
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
|
||||
static int audio_class_endpoint_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint8_t control_selector;
|
||||
uint32_t sampling_freq = 0;
|
||||
uint8_t pitch_enable;
|
||||
uint8_t ep;
|
||||
|
||||
if ((setup->bmRequestType & USB_REQUEST_RECIPIENT_MASK) == USB_REQUEST_RECIPIENT_ENDPOINT) {
|
||||
control_selector = HI_BYTE(setup->wValue);
|
||||
ep = LO_BYTE(setup->wIndex);
|
||||
control_selector = HI_BYTE(setup->wValue);
|
||||
ep = LO_BYTE(setup->wIndex);
|
||||
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_SET_CUR:
|
||||
switch (control_selector) {
|
||||
case AUDIO_EP_CONTROL_SAMPLING_FEQ:
|
||||
memcpy((uint8_t *)&sampling_freq, *data, *len);
|
||||
USB_LOG_DBG("Set ep:%02x %d Hz\r\n", ep, (int)sampling_freq);
|
||||
usbd_audio_set_sampling_freq(0, ep, sampling_freq);
|
||||
break;
|
||||
case AUDIO_EP_CONTROL_PITCH:
|
||||
pitch_enable = (*data)[0];
|
||||
usbd_audio_set_pitch(ep, pitch_enable);
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_CUR:
|
||||
sampling_freq = 16000;
|
||||
memcpy(*data, &sampling_freq, 4);
|
||||
*len = 4;
|
||||
USB_LOG_DBG("Get ep:%02x %d Hz\r\n", ep, (int)sampling_freq);
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
switch (control_selector) {
|
||||
case AUDIO_EP_CONTROL_SAMPLING_FEQ:
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_SET_CUR:
|
||||
memcpy((uint8_t *)&sampling_freq, *data, *len);
|
||||
USB_LOG_DBG("Set ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq);
|
||||
usbd_audio_set_sampling_freq(ep, sampling_freq);
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_CUR:
|
||||
case AUDIO_REQUEST_GET_MIN:
|
||||
case AUDIO_REQUEST_GET_MAX:
|
||||
case AUDIO_REQUEST_GET_RES:
|
||||
sampling_freq = usbd_audio_get_sampling_freq(ep);
|
||||
memcpy(*data, &sampling_freq, 3);
|
||||
USB_LOG_DBG("Get ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq);
|
||||
*len = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int audio_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
USB_LOG_DBG("AUDIO Class request: "
|
||||
USB_LOG_DBG("Audio Class request: "
|
||||
"bRequest 0x%02x\r\n",
|
||||
setup->bRequest);
|
||||
|
||||
struct audio_entity_info *current_entity_info = NULL;
|
||||
struct usbd_audio_attribute_control *current_feature_control = NULL;
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200
|
||||
uint32_t *sampling_freq;
|
||||
#endif
|
||||
usb_slist_t *i;
|
||||
uint8_t entity_id;
|
||||
uint8_t ep;
|
||||
uint8_t subtype = 0x01;
|
||||
uint8_t control_selector;
|
||||
uint8_t ch;
|
||||
uint8_t mute;
|
||||
uint16_t volume;
|
||||
int volume_db = 0;
|
||||
uint32_t sampling_freq = 0;
|
||||
|
||||
const char *mute_string[2] = { "off", "on" };
|
||||
|
||||
entity_id = HI_BYTE(setup->wIndex);
|
||||
@@ -116,211 +78,189 @@ static int audio_class_interface_request_handler(struct usb_setup_packet *setup,
|
||||
ch = LO_BYTE(setup->wValue);
|
||||
|
||||
ARG_UNUSED(mute_string);
|
||||
if (ch > (CONFIG_USBDEV_AUDIO_MAX_CHANNEL - 1)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
usb_slist_for_each(i, &usbd_audio_entity_info_head)
|
||||
{
|
||||
struct audio_entity_info *tmp_entity_info = usb_slist_entry(i, struct audio_entity_info, list);
|
||||
if (tmp_entity_info->bEntityId == entity_id) {
|
||||
current_entity_info = tmp_entity_info;
|
||||
for (uint8_t i = 0; i < g_usbd_audio.num; i++) {
|
||||
if (g_usbd_audio.table[i].bEntityId == entity_id) {
|
||||
subtype = g_usbd_audio.table[i].bDescriptorSubtype;
|
||||
ep = g_usbd_audio.table[i].ep;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_entity_info == NULL) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
current_feature_control = (struct usbd_audio_attribute_control *)current_entity_info->priv[0];
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200
|
||||
sampling_freq = (uint32_t *)current_entity_info->priv[1];
|
||||
#endif
|
||||
if (current_entity_info->bDescriptorSubtype == AUDIO_CONTROL_FEATURE_UNIT) {
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
|
||||
float volume2db = 0.0;
|
||||
|
||||
switch (control_selector) {
|
||||
case AUDIO_FU_CONTROL_MUTE:
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_SET_CUR:
|
||||
mute = (*data)[0];
|
||||
current_feature_control->mute[ch] = mute;
|
||||
USB_LOG_DBG("Set UnitId:%d ch[%d] mute %s\r\n", entity_id, ch, mute_string[mute]);
|
||||
usbd_audio_set_mute(entity_id, ch, mute);
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_CUR:
|
||||
(*data)[0] = current_feature_control->mute[ch];
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
case AUDIO_FU_CONTROL_VOLUME:
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_SET_CUR:
|
||||
volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0]));
|
||||
current_feature_control->volume[ch].vol_current = volume;
|
||||
|
||||
if (volume < 0x8000) {
|
||||
volume2db = 0.00390625 * volume;
|
||||
} else if (volume > 0x8000) {
|
||||
volume2db = -0.00390625 * (0xffff - volume + 1);
|
||||
}
|
||||
|
||||
USB_LOG_DBG("Set UnitId:%d ch[%d] %0.4f dB\r\n", entity_id, ch, volume2db);
|
||||
usbd_audio_set_volume(entity_id, ch, volume2db);
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_CUR:
|
||||
memcpy(*data, ¤t_feature_control->volume[ch].vol_current, 2);
|
||||
*len = 2;
|
||||
break;
|
||||
|
||||
case AUDIO_REQUEST_GET_MIN:
|
||||
memcpy(*data, ¤t_feature_control->volume[ch].vol_min, 2);
|
||||
*len = 2;
|
||||
break;
|
||||
|
||||
case AUDIO_REQUEST_GET_MAX:
|
||||
memcpy(*data, ¤t_feature_control->volume[ch].vol_max, 2);
|
||||
*len = 2;
|
||||
break;
|
||||
|
||||
case AUDIO_REQUEST_GET_RES:
|
||||
memcpy(*data, ¤t_feature_control->volume[ch].vol_res, 2);
|
||||
*len = 2;
|
||||
break;
|
||||
|
||||
case AUDIO_REQUEST_SET_RES:
|
||||
memcpy(¤t_feature_control->volume[ch].vol_res, *data, 2);
|
||||
*len = 2;
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_CUR:
|
||||
switch (control_selector) {
|
||||
case AUDIO_FU_CONTROL_MUTE:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
(*data)[0] = current_feature_control->mute_bCUR;
|
||||
*len = 1;
|
||||
} else {
|
||||
mute = (*data)[0];
|
||||
current_feature_control->mute_bCUR = mute;
|
||||
USB_LOG_DBG("Set UnitId:%d ch[%d] mute %s\r\n", entity_id, ch, mute_string[mute]);
|
||||
usbd_audio_set_mute(entity_id, ch, mute);
|
||||
}
|
||||
break;
|
||||
case AUDIO_FU_CONTROL_VOLUME:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
(*data)[0] = current_feature_control->volume_bCUR & 0XFF;
|
||||
(*data)[1] = (current_feature_control->volume_bCUR >> 8) & 0xff;
|
||||
*len = 2;
|
||||
} else {
|
||||
volume = (((uint16_t)(*data)[1] << 8) | ((uint16_t)(*data)[0]));
|
||||
current_feature_control->volume_bCUR = volume;
|
||||
USB_LOG_DBG("Set UnitId:%d ch[%d] %d dB\r\n", entity_id, ch, volume);
|
||||
usbd_audio_set_volume(entity_id, ch, volume);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case AUDIO_REQUEST_RANGE:
|
||||
switch (control_selector) {
|
||||
case AUDIO_FU_CONTROL_VOLUME:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
*((uint16_t *)(*data + 0)) = current_feature_control->volume.wNumSubRanges;
|
||||
*((uint16_t *)(*data + 2)) = current_feature_control->volume.subrange[ch].wMin;
|
||||
*((uint16_t *)(*data + 4)) = current_feature_control->volume.subrange[ch].wMax;
|
||||
*((uint16_t *)(*data + 6)) = current_feature_control->volume.subrange[ch].wRes;
|
||||
*len = 8;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200
|
||||
else if (current_entity_info->bDescriptorSubtype == AUDIO_CONTROL_CLOCK_SOURCE) {
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_CUR:
|
||||
switch (control_selector) {
|
||||
case AUDIO_CS_CONTROL_SAM_FREQ:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
memcpy(*data, &sampling_freq[ch], sizeof(uint32_t));
|
||||
USB_LOG_DBG("Get ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq[ch]);
|
||||
*len = 4;
|
||||
} else {
|
||||
memcpy(&sampling_freq[ch], *data, setup->wLength);
|
||||
USB_LOG_DBG("Set ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq[ch]);
|
||||
usbd_audio_set_sampling_freq(entity_id, ch, sampling_freq[ch]);
|
||||
}
|
||||
break;
|
||||
case AUDIO_CS_CONTROL_CLOCK_VALID:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
(*data)[0] = 1;
|
||||
*len = 1;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case AUDIO_REQUEST_RANGE:
|
||||
switch (control_selector) {
|
||||
case AUDIO_CS_CONTROL_SAM_FREQ:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
uint8_t *sampling_freq_table = NULL;
|
||||
uint16_t num;
|
||||
|
||||
usbd_audio_get_sampling_freq_table(entity_id, &sampling_freq_table);
|
||||
num = (uint16_t)((uint16_t)(sampling_freq_table[1] << 8) | ((uint16_t)sampling_freq_table[0]));
|
||||
memcpy(*data, sampling_freq_table, (12 * num + 2));
|
||||
*len = (12 * num + 2);
|
||||
USB_LOG_DBG("Get sampling_freq_table entity_id:%d ch[%d] addr:%x\r\n", entity_id, ch, (uint32_t)sampling_freq_table);
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class control selector 0x%02x\r\n", control_selector);
|
||||
return -1;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
if (subtype == 0x01) {
|
||||
USB_LOG_ERR("Do not find subtype for 0x%02x\r\n", entity_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
USB_LOG_DBG("Audio entity_id:%02x, subtype:%02x, cs:%02x\r\n", entity_id, subtype, control_selector);
|
||||
|
||||
switch (subtype) {
|
||||
case AUDIO_CONTROL_FEATURE_UNIT:
|
||||
switch (control_selector) {
|
||||
case AUDIO_FU_CONTROL_MUTE:
|
||||
if (g_usbd_audio.uac_version < 0x0200) {
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_SET_CUR:
|
||||
mute = (*data)[0];
|
||||
usbd_audio_set_mute(ep, ch, mute);
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_CUR:
|
||||
(*data)[0] = usbd_audio_get_mute(ep, ch);
|
||||
*len = 1;
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_CUR:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
(*data)[0] = usbd_audio_get_mute(ep, ch);
|
||||
*len = 1;
|
||||
} else {
|
||||
mute = (*data)[0];
|
||||
usbd_audio_set_mute(ep, ch, mute);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AUDIO_FU_CONTROL_VOLUME:
|
||||
if (g_usbd_audio.uac_version < 0x0200) {
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_SET_CUR:
|
||||
memcpy(&volume, *data, *len);
|
||||
if (volume < 0x8000) {
|
||||
volume_db = volume / 256;
|
||||
} else if (volume > 0x8000) {
|
||||
volume_db = (0xffff - volume + 1) / -256;
|
||||
}
|
||||
volume_db += 128; /* 0 ~ 255 */
|
||||
USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%04x\r\n", ep, ch, volume);
|
||||
usbd_audio_set_volume(ep, ch, volume_db);
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_CUR:
|
||||
volume_db = usbd_audio_get_volume(ep, ch);
|
||||
volume_db -= 128;
|
||||
if (volume_db >= 0) {
|
||||
volume = volume_db * 256;
|
||||
} else {
|
||||
volume = volume_db * 256 + 0xffff + 1;
|
||||
}
|
||||
memcpy(*data, &volume, 2);
|
||||
*len = 2;
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_MIN:
|
||||
(*data)[0] = 0x00; /* -2560/256 dB */
|
||||
(*data)[1] = 0xdb;
|
||||
*len = 2;
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_MAX:
|
||||
(*data)[0] = 0x00; /* 0 dB */
|
||||
(*data)[1] = 0x00;
|
||||
*len = 2;
|
||||
break;
|
||||
case AUDIO_REQUEST_GET_RES:
|
||||
(*data)[0] = 0x00; /* -256/256 dB */
|
||||
(*data)[1] = 0x01;
|
||||
*len = 2;
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_CUR:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
volume_db = usbd_audio_get_volume(ep, ch);
|
||||
volume = volume_db;
|
||||
memcpy(*data, &volume, 2);
|
||||
*len = 2;
|
||||
} else {
|
||||
memcpy(&volume, *data, *len);
|
||||
volume_db = volume;
|
||||
USB_LOG_DBG("Set ep:0x%02x ch:%d volume:0x%02x\r\n", ep, ch, volume);
|
||||
usbd_audio_set_volume(ep, ch, volume_db);
|
||||
}
|
||||
break;
|
||||
case AUDIO_REQUEST_RANGE:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
*((uint16_t *)(*data + 0)) = 1;
|
||||
*((uint16_t *)(*data + 2)) = 0;
|
||||
*((uint16_t *)(*data + 4)) = 100;
|
||||
*((uint16_t *)(*data + 6)) = 1;
|
||||
*len = 8;
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class cs 0x%02x \r\n", control_selector);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case AUDIO_CONTROL_CLOCK_SOURCE:
|
||||
switch (control_selector) {
|
||||
case AUDIO_CS_CONTROL_SAM_FREQ:
|
||||
switch (setup->bRequest) {
|
||||
case AUDIO_REQUEST_CUR:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
sampling_freq = usbd_audio_get_sampling_freq(ep);
|
||||
memcpy(*data, &sampling_freq, 4);
|
||||
USB_LOG_DBG("Get ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq);
|
||||
*len = 4;
|
||||
} else {
|
||||
memcpy(&sampling_freq, *data, setup->wLength);
|
||||
USB_LOG_DBG("Set ep:0x%02x %d Hz\r\n", ep, (int)sampling_freq);
|
||||
usbd_audio_set_sampling_freq(ep, sampling_freq);
|
||||
}
|
||||
break;
|
||||
case AUDIO_REQUEST_RANGE:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
uint8_t *sampling_freq_table = NULL;
|
||||
uint16_t num;
|
||||
|
||||
usbd_audio_get_sampling_freq_table(ep, &sampling_freq_table);
|
||||
num = (uint16_t)((uint16_t)(sampling_freq_table[1] << 8) | ((uint16_t)sampling_freq_table[0]));
|
||||
memcpy(*data, sampling_freq_table, (12 * num + 2));
|
||||
*len = (12 * num + 2);
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x in cs 0x%02x\r\n", setup->bRequest, control_selector);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case AUDIO_CS_CONTROL_CLOCK_VALID:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
(*data)[0] = 1;
|
||||
*len = 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//USB_LOG_WRN("Unhandled Audio Class cs 0x%02x \r\n", control_selector);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -333,7 +273,7 @@ static void audio_notify_handler(uint8_t event, void *arg)
|
||||
|
||||
case USBD_EVENT_SET_INTERFACE: {
|
||||
struct usb_interface_descriptor *intf = (struct usb_interface_descriptor *)arg;
|
||||
if (intf->bAlternateSetting == 1) {
|
||||
if (intf->bAlternateSetting) {
|
||||
usbd_audio_open(intf->bInterfaceNumber);
|
||||
} else {
|
||||
usbd_audio_close(intf->bInterfaceNumber);
|
||||
@@ -347,86 +287,57 @@ static void audio_notify_handler(uint8_t event, void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_interface *usbd_audio_init_intf(struct usbd_interface *intf)
|
||||
struct usbd_interface *usbd_audio_init_intf(struct usbd_interface *intf,
|
||||
uint16_t uac_version,
|
||||
struct audio_entity_info *table,
|
||||
uint8_t num)
|
||||
{
|
||||
intf->class_interface_handler = audio_class_interface_request_handler;
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
|
||||
intf->class_endpoint_handler = audio_class_endpoint_request_handler;
|
||||
#else
|
||||
intf->class_endpoint_handler = NULL;
|
||||
#endif
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = audio_notify_handler;
|
||||
if (uac_version < 0x0200) {
|
||||
intf->class_interface_handler = audio_class_interface_request_handler;
|
||||
intf->class_endpoint_handler = audio_class_endpoint_request_handler;
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = audio_notify_handler;
|
||||
} else {
|
||||
intf->class_interface_handler = audio_class_interface_request_handler;
|
||||
intf->class_endpoint_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = audio_notify_handler;
|
||||
}
|
||||
|
||||
g_usbd_audio.uac_version = uac_version;
|
||||
g_usbd_audio.table = table;
|
||||
g_usbd_audio.num = num;
|
||||
|
||||
return intf;
|
||||
}
|
||||
|
||||
void usbd_audio_add_entity(uint8_t entity_id, uint16_t bDescriptorSubtype)
|
||||
{
|
||||
struct audio_entity_info *entity_info = usb_malloc(sizeof(struct audio_entity_info));
|
||||
memset(entity_info, 0, sizeof(struct audio_entity_info));
|
||||
entity_info->bEntityId = entity_id;
|
||||
entity_info->bDescriptorSubtype = bDescriptorSubtype;
|
||||
|
||||
if (bDescriptorSubtype == AUDIO_CONTROL_FEATURE_UNIT) {
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
|
||||
struct usbd_audio_attribute_control *control = usb_malloc(sizeof(struct usbd_audio_attribute_control));
|
||||
memset(control, 0, sizeof(struct usbd_audio_attribute_control));
|
||||
for (uint8_t ch = 0; ch < CONFIG_USBDEV_AUDIO_MAX_CHANNEL; ch++) {
|
||||
control->volume[ch].vol_min = 0xdb00;
|
||||
control->volume[ch].vol_max = 0x0000;
|
||||
control->volume[ch].vol_res = 0x0100;
|
||||
control->volume[ch].vol_current = 0xf600;
|
||||
control->mute[ch] = 0;
|
||||
control->automatic_gain[ch] = 0;
|
||||
}
|
||||
#else
|
||||
struct usbd_audio_attribute_control *control = usb_malloc(sizeof(struct usbd_audio_attribute_control));
|
||||
memset(control, 0, sizeof(struct usbd_audio_attribute_control));
|
||||
for (uint8_t ch = 0; ch < CONFIG_USBDEV_AUDIO_MAX_CHANNEL; ch++) {
|
||||
control->volume.wNumSubRanges = 1;
|
||||
control->volume.subrange[ch].wMin = 0;
|
||||
control->volume.subrange[ch].wMax = 100;
|
||||
control->volume.subrange[ch].wRes = 1;
|
||||
control->mute[ch] = 0;
|
||||
control->volume_bCUR = 0;
|
||||
control->mute_bCUR = 0;
|
||||
}
|
||||
#endif
|
||||
entity_info->priv[0] = control;
|
||||
} else if (bDescriptorSubtype == AUDIO_CONTROL_CLOCK_SOURCE) {
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200
|
||||
uint32_t *sampling_freq = usb_malloc(sizeof(uint32_t) * CONFIG_USBDEV_AUDIO_MAX_CHANNEL);
|
||||
for (size_t ch = 0; ch < CONFIG_USBDEV_AUDIO_MAX_CHANNEL; ch++) {
|
||||
sampling_freq[ch] = 16000;
|
||||
}
|
||||
entity_info->priv[1] = sampling_freq;
|
||||
#else
|
||||
entity_info->priv[1] = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
usb_slist_add_tail(&usbd_audio_entity_info_head, &entity_info->list);
|
||||
}
|
||||
|
||||
__WEAK void usbd_audio_set_volume(uint8_t entity_id, uint8_t ch, float dB)
|
||||
__WEAK void usbd_audio_set_volume(uint8_t ep, uint8_t ch, int volume)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbd_audio_set_mute(uint8_t entity_id, uint8_t ch, uint8_t enable)
|
||||
__WEAK int usbd_audio_get_volume(uint8_t ep, uint8_t ch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbd_audio_set_mute(uint8_t ep, uint8_t ch, bool mute)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq)
|
||||
__WEAK bool usbd_audio_get_mute(uint8_t ep, uint8_t ch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbd_audio_set_sampling_freq(uint8_t ep, uint32_t sampling_freq)
|
||||
{
|
||||
}
|
||||
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200
|
||||
__WEAK void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table)
|
||||
__WEAK uint32_t usbd_audio_get_sampling_freq(uint8_t ep)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
__WEAK void usbd_audio_set_pitch(uint8_t ep, bool enable)
|
||||
{
|
||||
}
|
||||
@@ -12,17 +12,29 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct audio_entity_info {
|
||||
uint8_t bDescriptorSubtype;
|
||||
uint8_t bEntityId;
|
||||
uint8_t ep;
|
||||
};
|
||||
|
||||
/* Init audio interface driver */
|
||||
struct usbd_interface *usbd_audio_init_intf(struct usbd_interface *intf);
|
||||
struct usbd_interface *usbd_audio_init_intf(struct usbd_interface *intf,
|
||||
uint16_t uac_version,
|
||||
struct audio_entity_info *table,
|
||||
uint8_t num);
|
||||
|
||||
void usbd_audio_open(uint8_t intf);
|
||||
void usbd_audio_close(uint8_t intf);
|
||||
void usbd_audio_add_entity(uint8_t entity_id, uint16_t bDescriptorSubtype);
|
||||
void usbd_audio_set_volume(uint8_t entity_id, uint8_t ch, float dB);
|
||||
void usbd_audio_set_mute(uint8_t entity_id, uint8_t ch, uint8_t enable);
|
||||
void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq);
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table);
|
||||
void usbd_audio_set_pitch(uint8_t ep, bool enable);
|
||||
|
||||
void usbd_audio_set_volume(uint8_t ep, uint8_t ch, int volume);
|
||||
int usbd_audio_get_volume(uint8_t ep, uint8_t ch);
|
||||
void usbd_audio_set_mute(uint8_t ep, uint8_t ch, bool mute);
|
||||
bool usbd_audio_get_mute(uint8_t ep, uint8_t ch);
|
||||
void usbd_audio_set_sampling_freq(uint8_t ep, uint32_t sampling_freq);
|
||||
uint32_t usbd_audio_get_sampling_freq(uint8_t ep);
|
||||
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -17,33 +17,38 @@
|
||||
#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
|
||||
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
|
||||
|
||||
static uint32_t g_devinuse = 0;
|
||||
#ifndef CONFIG_USBHOST_MAX_AUDIO_CLASS
|
||||
#define CONFIG_USBHOST_MAX_AUDIO_CLASS 4
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_audio_buf[128];
|
||||
|
||||
static int usbh_audio_devno_alloc(struct usbh_audio *audio_class)
|
||||
static struct usbh_audio g_audio_class[CONFIG_USBHOST_MAX_AUDIO_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
static struct usbh_audio *usbh_audio_class_alloc(void)
|
||||
{
|
||||
int devno;
|
||||
|
||||
for (devno = 0; devno < 32; devno++) {
|
||||
uint32_t bitno = 1 << devno;
|
||||
if ((g_devinuse & bitno) == 0) {
|
||||
g_devinuse |= bitno;
|
||||
audio_class->minor = devno;
|
||||
return 0;
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_AUDIO_CLASS; devno++) {
|
||||
if ((g_devinuse & (1 << devno)) == 0) {
|
||||
g_devinuse |= (1 << devno);
|
||||
memset(&g_audio_class[devno], 0, sizeof(struct usbh_audio));
|
||||
g_audio_class[devno].minor = devno;
|
||||
return &g_audio_class[devno];
|
||||
}
|
||||
}
|
||||
|
||||
return -EMFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_audio_devno_free(struct usbh_audio *audio_class)
|
||||
static void usbh_audio_class_free(struct usbh_audio *audio_class)
|
||||
{
|
||||
int devno = audio_class->minor;
|
||||
|
||||
if (devno >= 0 && devno < 32) {
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
memset(audio_class, 0, sizeof(struct usbh_audio));
|
||||
}
|
||||
|
||||
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq)
|
||||
@@ -159,10 +164,70 @@ int usbh_audio_close(struct usbh_audio *audio_class, const char *name)
|
||||
setup->wLength = 0;
|
||||
|
||||
ret = usbh_control_transfer(audio_class->hport->ep0, setup, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume)
|
||||
{
|
||||
struct usb_setup_packet *setup = audio_class->hport->setup;
|
||||
int ret;
|
||||
uint8_t intf = 0xff;
|
||||
uint8_t feature_id = 0xff;
|
||||
uint16_t volume_hex;
|
||||
|
||||
for (size_t i = 0; i < audio_class->module_num; i++) {
|
||||
if (strcmp(name, audio_class->module[i].name) == 0) {
|
||||
intf = audio_class->ctrl_intf;
|
||||
feature_id = audio_class->module[i].feature_unit_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (intf == 0xff) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = AUDIO_REQUEST_SET_CUR;
|
||||
setup->wValue = (AUDIO_FU_CONTROL_VOLUME << 8) | ch;
|
||||
setup->wIndex = (feature_id << 8) | intf;
|
||||
setup->wLength = 2;
|
||||
|
||||
volume_hex = -0xDB00 / 100 * volume + 0xdb00;
|
||||
|
||||
memcpy(g_audio_buf, &volume_hex, 2);
|
||||
ret = usbh_control_transfer(audio_class->hport->ep0, setup, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute)
|
||||
{
|
||||
struct usb_setup_packet *setup = audio_class->hport->setup;
|
||||
int ret;
|
||||
uint8_t intf = 0xff;
|
||||
uint8_t feature_id = 0xff;
|
||||
|
||||
for (size_t i = 0; i < audio_class->module_num; i++) {
|
||||
if (strcmp(name, audio_class->module[i].name) == 0) {
|
||||
intf = audio_class->ctrl_intf;
|
||||
feature_id = audio_class->module[i].feature_unit_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (intf == 0xff) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = AUDIO_REQUEST_SET_CUR;
|
||||
setup->wValue = (AUDIO_FU_CONTROL_MUTE << 8) | ch;
|
||||
setup->wIndex = (feature_id << 8) | intf;
|
||||
setup->wLength = 1;
|
||||
|
||||
memcpy(g_audio_buf, &mute, 1);
|
||||
ret = usbh_control_transfer(audio_class->hport->ep0, setup, g_audio_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -209,14 +274,12 @@ static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
uint8_t format_offset = 0;
|
||||
uint8_t *p;
|
||||
|
||||
struct usbh_audio *audio_class = usb_malloc(sizeof(struct usbh_audio));
|
||||
struct usbh_audio *audio_class = usbh_audio_class_alloc();
|
||||
if (audio_class == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc audio_class\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(audio_class, 0, sizeof(struct usbh_audio));
|
||||
usbh_audio_devno_alloc(audio_class);
|
||||
audio_class->hport = hport;
|
||||
audio_class->ctrl_intf = intf;
|
||||
audio_class->num_of_intf_altsettings = hport->config.intf[intf + 1].altsetting_num;
|
||||
@@ -352,8 +415,6 @@ static int usbh_audio_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
struct usbh_audio *audio_class = (struct usbh_audio *)hport->config.intf[intf].priv;
|
||||
|
||||
if (audio_class) {
|
||||
usbh_audio_devno_free(audio_class);
|
||||
|
||||
if (audio_class->isoin) {
|
||||
usbh_pipe_free(audio_class->isoin);
|
||||
}
|
||||
@@ -362,12 +423,12 @@ static int usbh_audio_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(audio_class->isoout);
|
||||
}
|
||||
|
||||
usbh_audio_stop(audio_class);
|
||||
memset(audio_class, 0, sizeof(struct usbh_audio));
|
||||
usb_free(audio_class);
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0')
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister Audio Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_audio_stop(audio_class);
|
||||
}
|
||||
|
||||
usbh_audio_class_free(audio_class);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -61,6 +61,8 @@ extern "C" {
|
||||
|
||||
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq);
|
||||
int usbh_audio_close(struct usbh_audio *audio_class, const char *name);
|
||||
int usbh_audio_set_volume(struct usbh_audio *audio_class, const char *name, uint8_t ch, uint8_t volume);
|
||||
int usbh_audio_set_mute(struct usbh_audio *audio_class, const char *name, uint8_t ch, bool mute);
|
||||
|
||||
void usbh_audio_run(struct usbh_audio *audio_class);
|
||||
void usbh_audio_stop(struct usbh_audio *audio_class);
|
||||
|
||||
@@ -212,6 +212,57 @@
|
||||
#define CDC_SERIAL_STATE_RX_CARRIER_Pos (0)
|
||||
#define CDC_SERIAL_STATE_RX_CARRIER_Msk (1 << CDC_SERIAL_STATE_RX_CARRIER_Pos)
|
||||
|
||||
#define CDC_ECM_XMIT_OK (1 << 0)
|
||||
#define CDC_ECM_RVC_OK (1 << 1)
|
||||
#define CDC_ECM_XMIT_ERROR (1 << 2)
|
||||
#define CDC_ECM_RCV_ERROR (1 << 3)
|
||||
#define CDC_ECM_RCV_NO_BUFFER (1 << 4)
|
||||
#define CDC_ECM_DIRECTED_BYTES_XMIT (1 << 5)
|
||||
#define CDC_ECM_DIRECTED_FRAMES_XMIT (1 << 6)
|
||||
#define CDC_ECM_MULTICAST_BYTES_XMIT (1 << 7)
|
||||
#define CDC_ECM_MULTICAST_FRAMES_XMIT (1 << 8)
|
||||
#define CDC_ECM_BROADCAST_BYTES_XMIT (1 << 9)
|
||||
#define CDC_ECM_BROADCAST_FRAMES_XMIT (1 << 10)
|
||||
#define CDC_ECM_DIRECTED_BYTES_RCV (1 << 11)
|
||||
#define CDC_ECM_DIRECTED_FRAMES_RCV (1 << 12)
|
||||
#define CDC_ECM_MULTICAST_BYTES_RCV (1 << 13)
|
||||
#define CDC_ECM_MULTICAST_FRAMES_RCV (1 << 14)
|
||||
#define CDC_ECM_BROADCAST_BYTES_RCV (1 << 15)
|
||||
#define CDC_ECM_BROADCAST_FRAMES_RCV (1 << 16)
|
||||
#define CDC_ECM_RCV_CRC_ERROR (1 << 17)
|
||||
#define CDC_ECM_TRANSMIT_QUEUE_LENGTH (1 << 18)
|
||||
#define CDC_ECM_RCV_ERROR_ALIGNMENT (1 << 19)
|
||||
#define CDC_ECM_XMIT_ONE_COLLISION (1 << 20)
|
||||
#define CDC_ECM_XMIT_MORE_COLLISIONS (1 << 21)
|
||||
#define CDC_ECM_XMIT_DEFERRED (1 << 22)
|
||||
#define CDC_ECM_XMIT_MAX_COLLISIONS (1 << 23)
|
||||
#define CDC_ECM_RCV_OVERRUN (1 << 24)
|
||||
#define CDC_ECM_XMIT_UNDERRUN (1 << 25)
|
||||
#define CDC_ECM_XMIT_HEARTBEAT_FAILURE (1 << 26)
|
||||
#define CDC_ECM_XMIT_TIMES_CRS_LOST (1 << 27)
|
||||
#define CDC_ECM_XMIT_LATE_COLLISIONS (1 << 28)
|
||||
|
||||
#define CDC_ECM_MAC_STR_DESC (uint8_t *)"010202030000"
|
||||
#define CDC_ECM_MAC_ADDR0 0x00U /* 01 */
|
||||
#define CDC_ECM_MAC_ADDR1 0x02U /* 02 */
|
||||
#define CDC_ECM_MAC_ADDR2 0x02U /* 03 */
|
||||
#define CDC_ECM_MAC_ADDR3 0x03U /* 00 */
|
||||
#define CDC_ECM_MAC_ADDR4 0x00U /* 00 */
|
||||
#define CDC_ECM_MAC_ADDR5 0x00U /* 00 */
|
||||
|
||||
#define CDC_ECM_NET_DISCONNECTED 0x00U
|
||||
#define CDC_ECM_NET_CONNECTED 0x01U
|
||||
|
||||
#define CDC_ECM_ETH_STATS_RESERVED 0xE0U
|
||||
#define CDC_ECM_BMREQUEST_TYPE_ECM 0xA1U
|
||||
|
||||
#define CDC_ECM_CONNECT_SPEED_UPSTREAM 0x004C4B40U /* 5Mbps */
|
||||
#define CDC_ECM_CONNECT_SPEED_DOWNSTREAM 0x004C4B40U /* 5Mbps */
|
||||
|
||||
#define CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION 0x00
|
||||
#define CDC_ECM_NOTIFY_CODE_RESPONSE_AVAILABLE 0x01
|
||||
#define CDC_ECM_NOTIFY_CODE_CONNECTION_SPEED_CHANGE 0x2A
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Structures based on usbcdc11.pdf (www.usb.org)
|
||||
*----------------------------------------------------------------------------*/
|
||||
@@ -299,11 +350,19 @@ struct cdc_ecm_descriptor {
|
||||
uint8_t bNumberPowerFilters;
|
||||
} __PACKED;
|
||||
|
||||
struct cdc_ecm_notification {
|
||||
uint8_t bmRequestType;
|
||||
uint8_t bNotificationType;
|
||||
uint16_t wValue;
|
||||
uint16_t wIndex;
|
||||
uint16_t wLength;
|
||||
uint8_t data[8];
|
||||
} __PACKED;
|
||||
|
||||
/*Length of template descriptor: 66 bytes*/
|
||||
#define CDC_ACM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 4 + 5 + 7 + 9 + 7 + 7)
|
||||
// clang-format off
|
||||
#ifndef CONFIG_USB_HS
|
||||
#define CDC_ACM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, str_idx) \
|
||||
#define CDC_ACM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, str_idx) \
|
||||
/* Interface Associate */ \
|
||||
0x08, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \
|
||||
@@ -359,24 +418,100 @@ struct cdc_ecm_descriptor {
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
out_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x40, 0x00, /* wMaxPacketSize */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x40, 0x00, /* wMaxPacketSize */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
0x00 /* bInterval */
|
||||
#else
|
||||
#define CDC_ACM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, str_idx) \
|
||||
// clang-format on
|
||||
|
||||
/*Length of template descriptor: 66 bytes*/
|
||||
#define CDC_RNDIS_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 4 + 5 + 7 + 9 + 7 + 7)
|
||||
// clang-format off
|
||||
#define CDC_RNDIS_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, str_idx) \
|
||||
/* Interface Associate */ \
|
||||
0x08, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bFirstInterface */ \
|
||||
0x02, /* bInterfaceCount */ \
|
||||
USB_DEVICE_CLASS_WIRELESS, /* bFunctionClass */ \
|
||||
CDC_DIRECT_LINE_CONTROL_MODEL, /* bFunctionSubClass */ \
|
||||
CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bFunctionProtocol */ \
|
||||
0x00, /* iFunction */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x01, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_WIRELESS, /* bInterfaceClass */ \
|
||||
CDC_DIRECT_LINE_CONTROL_MODEL, /* bInterfaceSubClass */ \
|
||||
CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bInterfaceProtocol */ \
|
||||
str_idx, /* iInterface */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_HEADER, /* bDescriptorSubtype */ \
|
||||
WBVAL(CDC_V1_10), /* bcdCDC */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_CALL_MANAGEMENT, /* bDescriptorSubtype */ \
|
||||
0x00, /* bmCapabilities */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bDataInterface */ \
|
||||
0x04, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype */ \
|
||||
0x00, /* bmCapabilities */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_UNION, /* bDescriptorSubtype */ \
|
||||
bFirstInterface, /* bMasterInterface */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bSlaveInterface0 */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
int_ep, /* bEndpointAddress */ \
|
||||
0x03, /* bmAttributes */ \
|
||||
0x08, 0x00, /* wMaxPacketSize */ \
|
||||
0x10, /* bInterval */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x02, /* bNumEndpoints */ \
|
||||
CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \
|
||||
0x00, /* bInterfaceSubClass */ \
|
||||
0x00, /* bInterfaceProtocol */ \
|
||||
0x00, /* iInterface */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
out_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
0x00 /* bInterval */
|
||||
// clang-format on
|
||||
|
||||
#define DBVAL_BE(x) ((x >> 24) & 0xFF), ((x >> 16) & 0xFF), ((x >> 8) & 0xFF), (x & 0xFF)
|
||||
|
||||
/*Length of template descriptor: 66 bytes*/
|
||||
#define CDC_ECM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 13 + 7 + 9 + 7 + 7)
|
||||
// clang-format off
|
||||
#define CDC_ECM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, wMaxPacketSize, \
|
||||
eth_statistics, wMaxSegmentSize, wNumberMCFilters, bNumberPowerFilters, str_idx) \
|
||||
/* Interface Associate */ \
|
||||
0x08, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bFirstInterface */ \
|
||||
0x02, /* bInterfaceCount */ \
|
||||
USB_DEVICE_CLASS_CDC, /* bFunctionClass */ \
|
||||
CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */ \
|
||||
CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bFunctionProtocol */ \
|
||||
CDC_ETHERNET_NETWORKING_CONTROL_MODEL, /* bFunctionSubClass */ \
|
||||
CDC_COMMON_PROTOCOL_NONE, /* bFunctionProtocol */ \
|
||||
0x00, /* iFunction */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
@@ -384,8 +519,8 @@ struct cdc_ecm_descriptor {
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x01, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_CDC, /* bInterfaceClass */ \
|
||||
CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */ \
|
||||
CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bInterfaceProtocol */ \
|
||||
CDC_ETHERNET_NETWORKING_CONTROL_MODEL, /* bInterfaceSubClass */ \
|
||||
CDC_COMMON_PROTOCOL_NONE, /* bInterfaceProtocol */ \
|
||||
str_idx, /* iInterface */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
@@ -393,23 +528,23 @@ struct cdc_ecm_descriptor {
|
||||
WBVAL(CDC_V1_10), /* bcdCDC */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_CALL_MANAGEMENT, /* bDescriptorSubtype */ \
|
||||
0x00, /* bmCapabilities */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bDataInterface */ \
|
||||
0x04, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype */ \
|
||||
0x02, /* bmCapabilities */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_UNION, /* bDescriptorSubtype */ \
|
||||
bFirstInterface, /* bMasterInterface */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bSlaveInterface0 */ \
|
||||
/* CDC_ECM Functional Descriptor */ \
|
||||
0x0D, /* bFunctionLength */\
|
||||
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */\
|
||||
CDC_FUNC_DESC_ETHERNET_NETWORKING, /* Ethernet Networking functional descriptor subtype */\
|
||||
str_idx, /* Device's MAC string index */\
|
||||
DBVAL_BE(eth_statistics), /* Ethernet statistics (bitmap) */\
|
||||
WBVAL(wMaxPacketSize),/* wMaxSegmentSize: Ethernet Maximum Segment size, typically 1514 bytes */\
|
||||
WBVAL(wNumberMCFilters), /* wNumberMCFilters: the number of multicast filters */\
|
||||
bNumberPowerFilters, /* bNumberPowerFilters: the number of wakeup power filters */\
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
int_ep, /* bEndpointAddress */ \
|
||||
0x03, /* bmAttributes */ \
|
||||
0x08, 0x00, /* wMaxPacketSize */ \
|
||||
0x10, 0x00, /* wMaxPacketSize */ \
|
||||
0x10, /* bInterval */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
@@ -424,151 +559,14 @@ struct cdc_ecm_descriptor {
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
out_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x00, 0x02, /* wMaxPacketSize */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x00, 0x02, /* wMaxPacketSize */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
0x00 /* bInterval */
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
/*Length of template descriptor: 66 bytes*/
|
||||
#define CDC_RNDIS_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 4 + 5 + 7 + 9 + 7 + 7)
|
||||
// clang-format off
|
||||
#ifndef CONFIG_USB_HS
|
||||
#define CDC_RNDIS_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, str_idx) \
|
||||
/* Interface Associate */ \
|
||||
0x08, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bFirstInterface */ \
|
||||
0x02, /* bInterfaceCount */ \
|
||||
USB_DEVICE_CLASS_WIRELESS, /* bFunctionClass */ \
|
||||
CDC_DIRECT_LINE_CONTROL_MODEL, /* bFunctionSubClass */ \
|
||||
CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bFunctionProtocol */ \
|
||||
0x00, /* iFunction */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x01, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_WIRELESS, /* bInterfaceClass */ \
|
||||
CDC_DIRECT_LINE_CONTROL_MODEL, /* bInterfaceSubClass */ \
|
||||
CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bInterfaceProtocol */ \
|
||||
str_idx, /* iInterface */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_HEADER, /* bDescriptorSubtype */ \
|
||||
WBVAL(CDC_V1_10), /* bcdCDC */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_CALL_MANAGEMENT, /* bDescriptorSubtype */ \
|
||||
0x00, /* bmCapabilities */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bDataInterface */ \
|
||||
0x04, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype */ \
|
||||
0x00, /* bmCapabilities */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_UNION, /* bDescriptorSubtype */ \
|
||||
bFirstInterface, /* bMasterInterface */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bSlaveInterface0 */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
int_ep, /* bEndpointAddress */ \
|
||||
0x03, /* bmAttributes */ \
|
||||
0x08, 0x00, /* wMaxPacketSize */ \
|
||||
0x10, /* bInterval */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x02, /* bNumEndpoints */ \
|
||||
CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \
|
||||
0x00, /* bInterfaceSubClass */ \
|
||||
0x00, /* bInterfaceProtocol */ \
|
||||
0x00, /* iInterface */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
out_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x40, 0x00, /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x40, 0x00, /* wMaxPacketSize */ \
|
||||
0x00 /* bInterval */
|
||||
#else
|
||||
#define CDC_RNDIS_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, str_idx) \
|
||||
/* Interface Associate */ \
|
||||
0x08, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bFirstInterface */ \
|
||||
0x02, /* bInterfaceCount */ \
|
||||
USB_DEVICE_CLASS_WIRELESS, /* bFunctionClass */ \
|
||||
CDC_DIRECT_LINE_CONTROL_MODEL, /* bFunctionSubClass */ \
|
||||
CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bFunctionProtocol */ \
|
||||
0x00, /* iFunction */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x01, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_WIRELESS, /* bInterfaceClass */ \
|
||||
CDC_DIRECT_LINE_CONTROL_MODEL, /* bInterfaceSubClass */ \
|
||||
CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO, /* bInterfaceProtocol */ \
|
||||
str_idx, /* iInterface */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_HEADER, /* bDescriptorSubtype */ \
|
||||
WBVAL(CDC_V1_10), /* bcdCDC */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_CALL_MANAGEMENT, /* bDescriptorSubtype */ \
|
||||
0x00, /* bmCapabilities */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bDataInterface */ \
|
||||
0x04, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype */ \
|
||||
0x00, /* bmCapabilities */ \
|
||||
0x05, /* bLength */ \
|
||||
CDC_CS_INTERFACE, /* bDescriptorType */ \
|
||||
CDC_FUNC_DESC_UNION, /* bDescriptorSubtype */ \
|
||||
bFirstInterface, /* bMasterInterface */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bSlaveInterface0 */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
int_ep, /* bEndpointAddress */ \
|
||||
0x03, /* bmAttributes */ \
|
||||
0x08, 0x00, /* wMaxPacketSize */ \
|
||||
0x10, /* bInterval */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
(uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x02, /* bNumEndpoints */ \
|
||||
CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \
|
||||
0x00, /* bInterfaceSubClass */ \
|
||||
0x00, /* bInterfaceProtocol */ \
|
||||
0x00, /* iInterface */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
out_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x00, 0x02, /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x00, 0x02, /* wMaxPacketSize */ \
|
||||
0x00 /* bInterval */
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
#endif /* USB_CDC_H */
|
||||
|
||||
@@ -46,10 +46,11 @@ static int cdc_acm_class_interface_request_handler(struct usb_setup_packet *setu
|
||||
line_coding.bDataBits,
|
||||
parity_name[line_coding.bParityType],
|
||||
stop_name[line_coding.bCharFormat]);
|
||||
|
||||
usbd_cdc_acm_set_line_coding(intf_num, &line_coding);
|
||||
break;
|
||||
|
||||
case CDC_REQUEST_SET_CONTROL_LINE_STATE: {
|
||||
case CDC_REQUEST_SET_CONTROL_LINE_STATE:
|
||||
dtr = (setup->wValue & 0x0001);
|
||||
rts = (setup->wValue & 0x0002);
|
||||
USB_LOG_DBG("Set intf:%d DTR 0x%x,RTS 0x%x\r\n",
|
||||
@@ -58,7 +59,7 @@ static int cdc_acm_class_interface_request_handler(struct usb_setup_packet *setu
|
||||
rts);
|
||||
usbd_cdc_acm_set_dtr(intf_num, dtr);
|
||||
usbd_cdc_acm_set_rts(intf_num, rts);
|
||||
} break;
|
||||
break;
|
||||
|
||||
case CDC_REQUEST_GET_LINE_CODING:
|
||||
usbd_cdc_acm_get_line_coding(intf_num, &line_coding);
|
||||
@@ -71,7 +72,9 @@ static int cdc_acm_class_interface_request_handler(struct usb_setup_packet *setu
|
||||
line_coding.bParityType,
|
||||
line_coding.bDataBits);
|
||||
break;
|
||||
|
||||
case CDC_REQUEST_SEND_BREAK:
|
||||
usbd_cdc_acm_send_break(intf_num);
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled CDC Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||
return -1;
|
||||
@@ -80,22 +83,12 @@ static int cdc_acm_class_interface_request_handler(struct usb_setup_packet *setu
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cdc_notify_handler(uint8_t event, void *arg)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_interface *usbd_cdc_acm_init_intf(struct usbd_interface *intf)
|
||||
{
|
||||
intf->class_interface_handler = cdc_acm_class_interface_request_handler;
|
||||
intf->class_endpoint_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = cdc_notify_handler;
|
||||
intf->notify_handler = NULL;
|
||||
|
||||
return intf;
|
||||
}
|
||||
@@ -118,4 +111,8 @@ __WEAK void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr)
|
||||
|
||||
__WEAK void usbd_cdc_acm_set_rts(uint8_t intf, bool rts)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
__WEAK void usbd_cdc_acm_send_break(uint8_t intf)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ void usbd_cdc_acm_set_line_coding(uint8_t intf, struct cdc_line_coding *line_cod
|
||||
void usbd_cdc_acm_get_line_coding(uint8_t intf, struct cdc_line_coding *line_coding);
|
||||
void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr);
|
||||
void usbd_cdc_acm_set_rts(uint8_t intf, bool rts);
|
||||
void usbd_cdc_acm_send_break(uint8_t intf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
237
class/cdc/usbd_cdc_ecm.c
Normal file
237
class/cdc/usbd_cdc_ecm.c
Normal file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2023, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_ecm.h"
|
||||
|
||||
#define CDC_ECM_OUT_EP_IDX 0
|
||||
#define CDC_ECM_IN_EP_IDX 1
|
||||
#define CDC_ECM_INT_EP_IDX 2
|
||||
|
||||
/* Describe EndPoints configuration */
|
||||
static struct usbd_endpoint cdc_ecm_ep_data[3];
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_ECM_MAX_PACKET_SIZE 512
|
||||
#else
|
||||
#define CDC_ECM_MAX_PACKET_SIZE 64
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_CDC_ECM_ETH_MAX_SEGSZE];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_notify_buf[16];
|
||||
|
||||
volatile uint8_t *g_cdc_ecm_rx_data_buffer = NULL;
|
||||
volatile uint32_t g_cdc_ecm_rx_data_length = 0;
|
||||
volatile uint32_t g_cdc_ecm_tx_data_length = 0;
|
||||
|
||||
static volatile uint8_t g_current_net_status = 0;
|
||||
static volatile uint8_t g_cmd_intf = 0;
|
||||
|
||||
static uint32_t g_connect_speed_table[2] = { CDC_ECM_CONNECT_SPEED_UPSTREAM,
|
||||
CDC_ECM_CONNECT_SPEED_DOWNSTREAM };
|
||||
|
||||
void usbd_cdc_ecm_send_notify(uint8_t notifycode, uint8_t value, uint32_t *speed)
|
||||
{
|
||||
struct cdc_ecm_notification *notify = (struct cdc_ecm_notification *)g_cdc_ecm_notify_buf;
|
||||
uint8_t bytes2send = 0;
|
||||
|
||||
notify->bmRequestType = CDC_ECM_BMREQUEST_TYPE_ECM;
|
||||
notify->bNotificationType = notifycode;
|
||||
|
||||
switch (notifycode) {
|
||||
case CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION:
|
||||
notify->wValue = value;
|
||||
notify->wIndex = g_cmd_intf;
|
||||
notify->wLength = 0U;
|
||||
|
||||
for (uint8_t i = 0U; i < 8U; i++) {
|
||||
notify->data[i] = 0U;
|
||||
}
|
||||
bytes2send = 8U;
|
||||
break;
|
||||
case CDC_ECM_NOTIFY_CODE_RESPONSE_AVAILABLE:
|
||||
notify->wValue = 0U;
|
||||
notify->wIndex = g_cmd_intf;
|
||||
notify->wLength = 0U;
|
||||
for (uint8_t i = 0U; i < 8U; i++) {
|
||||
notify->data[i] = 0U;
|
||||
}
|
||||
bytes2send = 8U;
|
||||
break;
|
||||
case CDC_ECM_NOTIFY_CODE_CONNECTION_SPEED_CHANGE:
|
||||
notify->wValue = 0U;
|
||||
notify->wIndex = g_cmd_intf;
|
||||
notify->wLength = 0x0008U;
|
||||
bytes2send = 16U;
|
||||
|
||||
memcpy(notify->data, speed, 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (bytes2send) {
|
||||
usbd_ep_start_write(cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_addr, g_cdc_ecm_notify_buf, bytes2send);
|
||||
}
|
||||
}
|
||||
|
||||
static int cdc_ecm_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
USB_LOG_DBG("CDC ECM Class request: "
|
||||
"bRequest 0x%02x\r\n",
|
||||
setup->bRequest);
|
||||
|
||||
g_cmd_intf = LO_BYTE(setup->wIndex);
|
||||
|
||||
switch (setup->bRequest) {
|
||||
case CDC_REQUEST_SET_ETHERNET_PACKET_FILTER:
|
||||
/* bit0 Promiscuous
|
||||
* bit1 ALL Multicast
|
||||
* bit2 Directed
|
||||
* bit3 Broadcast
|
||||
* bit4 Multicast
|
||||
*/
|
||||
if (g_current_net_status == 0) {
|
||||
g_current_net_status = 1;
|
||||
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, NULL);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled CDC ECM Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cdc_ecm_notify_handler(uint8_t event, void *arg)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
g_current_net_status = 0;
|
||||
g_cdc_ecm_rx_data_length = 0;
|
||||
g_cdc_ecm_tx_data_length = 0;
|
||||
g_cdc_ecm_rx_data_buffer = NULL;
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
usbd_ep_start_read(cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], CDC_ECM_MAX_PACKET_SIZE);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cdc_ecm_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
g_cdc_ecm_rx_data_length += nbytes;
|
||||
|
||||
if (nbytes < CDC_ECM_MAX_PACKET_SIZE) {
|
||||
g_cdc_ecm_rx_data_buffer = g_cdc_ecm_rx_buffer;
|
||||
usbd_cdc_ecm_data_recv_done();
|
||||
} else {
|
||||
usbd_ep_start_read(ep, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_data_length], CDC_ECM_MAX_PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void cdc_ecm_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if ((nbytes % CDC_ECM_MAX_PACKET_SIZE) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(ep, NULL, 0);
|
||||
} else {
|
||||
g_cdc_ecm_tx_data_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void cdc_ecm_int_in(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (g_current_net_status == 1) {
|
||||
g_current_net_status = 2;
|
||||
usbd_cdc_ecm_send_notify(CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION, CDC_ECM_NET_CONNECTED, g_connect_speed_table);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
struct pbuf *usbd_cdc_ecm_eth_rx(void)
|
||||
{
|
||||
struct pbuf *p;
|
||||
|
||||
if (g_cdc_ecm_rx_data_buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_data_length, PBUF_POOL);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_data_length);
|
||||
p->len = g_cdc_ecm_rx_data_length;
|
||||
|
||||
USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_data_length);
|
||||
g_cdc_ecm_rx_data_length = 0;
|
||||
g_cdc_ecm_rx_data_buffer = NULL;
|
||||
usbd_ep_start_read(cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr, g_cdc_ecm_rx_buffer, CDC_ECM_MAX_PACKET_SIZE);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int usbd_cdc_ecm_eth_tx(struct pbuf *p)
|
||||
{
|
||||
struct pbuf *q;
|
||||
uint8_t *buffer;
|
||||
|
||||
if (g_cdc_ecm_tx_data_length > 0) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (p->tot_len > sizeof(g_cdc_ecm_tx_buffer)) {
|
||||
p->tot_len = sizeof(g_cdc_ecm_tx_buffer);
|
||||
}
|
||||
|
||||
buffer = g_cdc_ecm_tx_buffer;
|
||||
for (q = p; q != NULL; q = q->next) {
|
||||
memcpy(buffer, q->payload, q->len);
|
||||
buffer += q->len;
|
||||
}
|
||||
|
||||
g_cdc_ecm_tx_data_length = p->tot_len;
|
||||
|
||||
USB_LOG_DBG("txlen:%d\r\n", g_cdc_ecm_tx_data_length);
|
||||
return usbd_ep_start_write(cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_addr, g_cdc_ecm_tx_buffer, g_cdc_ecm_tx_data_length);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const uint8_t int_ep, const uint8_t out_ep, const uint8_t in_ep)
|
||||
{
|
||||
intf->class_interface_handler = cdc_ecm_class_interface_request_handler;
|
||||
intf->class_endpoint_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = cdc_ecm_notify_handler;
|
||||
|
||||
cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_addr = out_ep;
|
||||
cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX].ep_cb = cdc_ecm_bulk_out;
|
||||
cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_addr = in_ep;
|
||||
cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX].ep_cb = cdc_ecm_bulk_in;
|
||||
cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_addr = int_ep;
|
||||
cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX].ep_cb = cdc_ecm_int_in;
|
||||
|
||||
usbd_add_endpoint(&cdc_ecm_ep_data[CDC_ECM_OUT_EP_IDX]);
|
||||
usbd_add_endpoint(&cdc_ecm_ep_data[CDC_ECM_IN_EP_IDX]);
|
||||
usbd_add_endpoint(&cdc_ecm_ep_data[CDC_ECM_INT_EP_IDX]);
|
||||
|
||||
return intf;
|
||||
}
|
||||
|
||||
void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2])
|
||||
{
|
||||
memcpy(g_connect_speed_table, speed, 8);
|
||||
}
|
||||
|
||||
__WEAK void usbd_cdc_ecm_data_recv_done(void)
|
||||
{
|
||||
}
|
||||
36
class/cdc/usbd_cdc_ecm.h
Normal file
36
class/cdc/usbd_cdc_ecm.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USBD_CDC_ECM_H
|
||||
#define USBD_CDC_ECM_H
|
||||
|
||||
#include "usb_cdc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Ethernet Maximum Segment size, typically 1514 bytes */
|
||||
#define CONFIG_CDC_ECM_ETH_MAX_SEGSZE 1514U
|
||||
#define CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
|
||||
/* Init cdc ecm interface driver */
|
||||
struct usbd_interface *usbd_cdc_ecm_init_intf(struct usbd_interface *intf, const uint8_t int_ep, const uint8_t out_ep, const uint8_t in_ep);
|
||||
|
||||
/* Setup request command callback api */
|
||||
void usbd_cdc_ecm_set_connect_speed(uint32_t speed[2]);
|
||||
void usbd_cdc_ecm_data_recv_done(void);
|
||||
|
||||
#ifdef CONFIG_USBDEV_CDC_ECM_USING_LWIP
|
||||
#include <lwip/pbuf.h>
|
||||
struct pbuf *usbd_cdc_ecm_eth_rx(void);
|
||||
int usbd_cdc_ecm_eth_tx(struct pbuf *p);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBD_CDC_ECM_H */
|
||||
@@ -8,32 +8,34 @@
|
||||
|
||||
#define DEV_FORMAT "/dev/ttyACM%d"
|
||||
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct cdc_line_coding g_cdc_line_coding;
|
||||
|
||||
static int usbh_cdc_acm_devno_alloc(struct usbh_cdc_acm *cdc_acm_class)
|
||||
static struct usbh_cdc_acm g_cdc_acm_class[CONFIG_USBHOST_MAX_CDC_ACM_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
static struct usbh_cdc_acm *usbh_cdc_acm_class_alloc(void)
|
||||
{
|
||||
int devno;
|
||||
|
||||
for (devno = 0; devno < 32; devno++) {
|
||||
uint32_t bitno = 1 << devno;
|
||||
if ((g_devinuse & bitno) == 0) {
|
||||
g_devinuse |= bitno;
|
||||
cdc_acm_class->minor = devno;
|
||||
return 0;
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_CDC_ACM_CLASS; devno++) {
|
||||
if ((g_devinuse & (1 << devno)) == 0) {
|
||||
g_devinuse |= (1 << devno);
|
||||
memset(&g_cdc_acm_class[devno], 0, sizeof(struct usbh_cdc_acm));
|
||||
g_cdc_acm_class[devno].minor = devno;
|
||||
return &g_cdc_acm_class[devno];
|
||||
}
|
||||
}
|
||||
return -EMFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_cdc_acm_devno_free(struct usbh_cdc_acm *cdc_acm_class)
|
||||
static void usbh_cdc_acm_class_free(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
int devno = cdc_acm_class->minor;
|
||||
|
||||
if (devno >= 0 && devno < 32) {
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm));
|
||||
}
|
||||
|
||||
int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding)
|
||||
@@ -91,14 +93,12 @@ static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
|
||||
struct usbh_cdc_acm *cdc_acm_class = usb_malloc(sizeof(struct usbh_cdc_acm));
|
||||
struct usbh_cdc_acm *cdc_acm_class = usbh_cdc_acm_class_alloc();
|
||||
if (cdc_acm_class == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc cdc_acm_class\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm));
|
||||
usbh_cdc_acm_devno_alloc(cdc_acm_class);
|
||||
cdc_acm_class->hport = hport;
|
||||
cdc_acm_class->ctrl_intf = intf;
|
||||
cdc_acm_class->data_intf = intf + 1;
|
||||
@@ -124,13 +124,7 @@ static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
#ifdef CONFIG_USBHOST_CDC_ACM_NOTIFY
|
||||
ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc;
|
||||
ep_cfg.ep_addr = ep_desc->bEndpointAddress;
|
||||
ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
|
||||
ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
|
||||
ep_cfg.ep_interval = ep_desc->bInterval;
|
||||
ep_cfg.hport = hport;
|
||||
usbh_pipe_alloc(&cdc_acm_class->intin, &ep_cfg);
|
||||
|
||||
usbh_hport_activate_epx(&cdc_acm_class->intin, hport, ep_desc);
|
||||
#endif
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf + 1].altsetting[0].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf + 1].altsetting[0].ep[i].ep_desc;
|
||||
@@ -157,8 +151,6 @@ static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)hport->config.intf[intf].priv;
|
||||
|
||||
if (cdc_acm_class) {
|
||||
usbh_cdc_acm_devno_free(cdc_acm_class);
|
||||
|
||||
if (cdc_acm_class->bulkin) {
|
||||
usbh_pipe_free(cdc_acm_class->bulkin);
|
||||
}
|
||||
@@ -167,12 +159,12 @@ static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(cdc_acm_class->bulkout);
|
||||
}
|
||||
|
||||
usbh_cdc_acm_stop(cdc_acm_class);
|
||||
memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm));
|
||||
usb_free(cdc_acm_class);
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0')
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister CDC ACM Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_cdc_acm_stop(cdc_acm_class);
|
||||
}
|
||||
|
||||
usbh_cdc_acm_class_free(cdc_acm_class);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -190,12 +182,10 @@ static int usbh_cdc_data_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
__WEAK void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__WEAK void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const struct usbh_class_driver cdc_acm_class_driver = {
|
||||
|
||||
330
class/cdc/usbh_cdc_ecm.c
Normal file
330
class/cdc/usbh_cdc_ecm.c
Normal file
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_cdc_ecm.h"
|
||||
|
||||
#define DEV_FORMAT "/dev/cdc_ether"
|
||||
|
||||
/* general descriptor field offsets */
|
||||
#define DESC_bLength 0 /** Length offset */
|
||||
#define DESC_bDescriptorType 1 /** Descriptor type offset */
|
||||
#define DESC_bDescriptorSubType 2 /** Descriptor subtype offset */
|
||||
|
||||
/* interface descriptor field offsets */
|
||||
#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
|
||||
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
|
||||
|
||||
#define CONFIG_USBHOST_CDC_ECM_PKT_FILTER 0x000C
|
||||
#define CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE 1514U
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_rx_buffer[CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_tx_buffer[CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_cdc_ecm_inttx_buffer[16];
|
||||
|
||||
static struct usbh_cdc_ecm g_cdc_ecm_class;
|
||||
|
||||
static int usbh_cdc_ecm_set_eth_packet_filter(struct usbh_cdc_ecm *cdc_ecm_class, uint16_t filter_value)
|
||||
{
|
||||
struct usb_setup_packet *setup = cdc_ecm_class->hport->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = CDC_REQUEST_SET_ETHERNET_PACKET_FILTER;
|
||||
setup->wValue = filter_value;
|
||||
setup->wIndex = cdc_ecm_class->ctrl_intf;
|
||||
setup->wLength = 0;
|
||||
|
||||
return usbh_control_transfer(cdc_ecm_class->hport->ep0, setup, NULL);
|
||||
}
|
||||
|
||||
int usbh_cdc_ecm_get_notification(struct usbh_cdc_ecm *cdc_ecm_class)
|
||||
{
|
||||
int ret;
|
||||
|
||||
usbh_int_urb_fill(&cdc_ecm_class->intin_urb, cdc_ecm_class->intin, g_cdc_ecm_inttx_buffer, 16, USB_OSAL_WAITING_FOREVER, NULL, NULL);
|
||||
ret = usbh_submit_urb(&cdc_ecm_class->intin_urb);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (g_cdc_ecm_inttx_buffer[1] == CDC_ECM_NOTIFY_CODE_NETWORK_CONNECTION) {
|
||||
cdc_ecm_class->connect_status = g_cdc_ecm_inttx_buffer[2];
|
||||
} else if (g_cdc_ecm_inttx_buffer[1] == CDC_ECM_NOTIFY_CODE_CONNECTION_SPEED_CHANGE) {
|
||||
memcpy(cdc_ecm_class->speed, &g_cdc_ecm_inttx_buffer[8], 8);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_cdc_ecm_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
uint8_t altsetting = 0;
|
||||
char mac_buffer[12];
|
||||
uint8_t *p;
|
||||
uint8_t cur_iface = 0xff;
|
||||
uint8_t mac_str_idx = 0xff;
|
||||
|
||||
struct usbh_cdc_ecm *cdc_ecm_class = &g_cdc_ecm_class;
|
||||
|
||||
cdc_ecm_class->hport = hport;
|
||||
cdc_ecm_class->ctrl_intf = intf;
|
||||
cdc_ecm_class->data_intf = intf + 1;
|
||||
|
||||
hport->config.intf[intf].priv = cdc_ecm_class;
|
||||
hport->config.intf[intf + 1].priv = NULL;
|
||||
|
||||
p = hport->raw_config_desc;
|
||||
while (p[DESC_bLength]) {
|
||||
switch (p[DESC_bDescriptorType]) {
|
||||
case USB_DESCRIPTOR_TYPE_INTERFACE:
|
||||
cur_iface = p[INTF_DESC_bInterfaceNumber];
|
||||
//cur_alt_setting = p[INTF_DESC_bAlternateSetting];
|
||||
break;
|
||||
case CDC_CS_INTERFACE:
|
||||
if ((cur_iface == cdc_ecm_class->ctrl_intf) && p[DESC_bDescriptorSubType] == CDC_FUNC_DESC_ETHERNET_NETWORKING) {
|
||||
struct cdc_ecm_descriptor *desc = (struct cdc_ecm_descriptor *)p;
|
||||
mac_str_idx = desc->iMACAddress;
|
||||
cdc_ecm_class->max_segment_size = desc->wMaxSegmentSize;
|
||||
goto get_mac;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* skip to next descriptor */
|
||||
p += p[DESC_bLength];
|
||||
}
|
||||
|
||||
get_mac:
|
||||
if (mac_str_idx == 0xff) {
|
||||
USB_LOG_ERR("Do not find cdc ecm mac string\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(mac_buffer, 0, 8);
|
||||
ret = usbh_get_string_desc(cdc_ecm_class->hport, mac_str_idx, (uint8_t *)mac_buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (int i = 0, j = 0; i < 12; i += 2, j++) {
|
||||
char byte_str[3];
|
||||
byte_str[0] = mac_buffer[i];
|
||||
byte_str[1] = mac_buffer[i + 1];
|
||||
byte_str[2] = '\0';
|
||||
|
||||
uint32_t byte = strtoul(byte_str, NULL, 16);
|
||||
cdc_ecm_class->mac[j] = (unsigned char)byte;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("CDC ECM MAC address %02x:%02x:%02x:%02x:%02x:%02x\r\n",
|
||||
cdc_ecm_class->mac[0],
|
||||
cdc_ecm_class->mac[1],
|
||||
cdc_ecm_class->mac[2],
|
||||
cdc_ecm_class->mac[3],
|
||||
cdc_ecm_class->mac[4],
|
||||
cdc_ecm_class->mac[5]);
|
||||
|
||||
if (cdc_ecm_class->max_segment_size > CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE) {
|
||||
USB_LOG_ERR("CDC ECM Max Segment Size is overflow, default is %u, but now %u\r\n", CONFIG_USBHOST_CDC_ECM_ETH_MAX_SEGSZE, cdc_ecm_class->max_segment_size);
|
||||
} else {
|
||||
USB_LOG_INFO("CDC ECM Max Segment Size:%u\r\n", cdc_ecm_class->max_segment_size);
|
||||
}
|
||||
|
||||
/* enable int ep */
|
||||
ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc;
|
||||
usbh_hport_activate_epx(&cdc_ecm_class->intin, hport, ep_desc);
|
||||
|
||||
if (hport->config.intf[intf + 1].altsetting_num > 1) {
|
||||
altsetting = hport->config.intf[intf + 1].altsetting_num - 1;
|
||||
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf + 1].altsetting[altsetting].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf + 1].altsetting[altsetting].ep[i].ep_desc;
|
||||
|
||||
if (ep_desc->bEndpointAddress & 0x80) {
|
||||
usbh_hport_activate_epx(&cdc_ecm_class->bulkin, hport, ep_desc);
|
||||
} else {
|
||||
usbh_hport_activate_epx(&cdc_ecm_class->bulkout, hport, ep_desc);
|
||||
}
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Select cdc ecm altsetting: %d\r\n", altsetting);
|
||||
usbh_set_interface(cdc_ecm_class->hport, cdc_ecm_class->data_intf, altsetting);
|
||||
} else {
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf + 1].altsetting[0].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf + 1].altsetting[0].ep[i].ep_desc;
|
||||
|
||||
if (ep_desc->bEndpointAddress & 0x80) {
|
||||
usbh_hport_activate_epx(&cdc_ecm_class->bulkin, hport, ep_desc);
|
||||
} else {
|
||||
usbh_hport_activate_epx(&cdc_ecm_class->bulkout, hport, ep_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* bit0 Promiscuous
|
||||
* bit1 ALL Multicast
|
||||
* bit2 Directed
|
||||
* bit3 Broadcast
|
||||
* bit4 Multicast
|
||||
*/
|
||||
ret = usbh_cdc_ecm_set_eth_packet_filter(cdc_ecm_class, CONFIG_USBHOST_CDC_ECM_PKT_FILTER);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
USB_LOG_INFO("Set CDC ECM packet filter:%04x\r\n", CONFIG_USBHOST_CDC_ECM_PKT_FILTER);
|
||||
|
||||
memcpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
|
||||
|
||||
USB_LOG_INFO("Register CDC ECM Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
usbh_cdc_ecm_run(cdc_ecm_class);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usbh_cdc_ecm_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
struct usbh_cdc_ecm *cdc_ecm_class = (struct usbh_cdc_ecm *)hport->config.intf[intf].priv;
|
||||
|
||||
if (cdc_ecm_class) {
|
||||
if (cdc_ecm_class->bulkin) {
|
||||
usbh_pipe_free(cdc_ecm_class->bulkin);
|
||||
}
|
||||
|
||||
if (cdc_ecm_class->bulkout) {
|
||||
usbh_pipe_free(cdc_ecm_class->bulkout);
|
||||
}
|
||||
|
||||
if (cdc_ecm_class->intin) {
|
||||
usbh_pipe_free(cdc_ecm_class->intin);
|
||||
}
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister CDC ECM Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_cdc_ecm_stop(cdc_ecm_class);
|
||||
}
|
||||
|
||||
memset(cdc_ecm_class, 0, sizeof(struct usbh_cdc_ecm));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void usbh_cdc_ecm_rx_thread(void *argument)
|
||||
{
|
||||
uint32_t g_cdc_ecm_rx_length;
|
||||
int ret;
|
||||
err_t err;
|
||||
struct pbuf *p;
|
||||
struct netif *netif = (struct netif *)argument;
|
||||
uint16_t ep_mps;
|
||||
|
||||
// clang-format off
|
||||
find_class:
|
||||
// clang-format on
|
||||
while (usbh_find_class_instance("/dev/cdc_ether") == NULL) {
|
||||
usb_osal_msleep(1000);
|
||||
}
|
||||
|
||||
while (g_cdc_ecm_class.connect_status == CDC_ECM_NET_DISCONNECTED) {
|
||||
ret = usbh_cdc_ecm_get_notification(&g_cdc_ecm_class);
|
||||
if (ret < 0) {
|
||||
goto find_class;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_cdc_ecm_class.hport->speed == USB_SPEED_FULL) {
|
||||
ep_mps = 64;
|
||||
} else {
|
||||
ep_mps = 512;
|
||||
}
|
||||
g_cdc_ecm_rx_length = 0;
|
||||
while (1) {
|
||||
usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkin_urb, g_cdc_ecm_class.bulkin, &g_cdc_ecm_rx_buffer[g_cdc_ecm_rx_length], ep_mps, USB_OSAL_WAITING_FOREVER, NULL, NULL);
|
||||
ret = usbh_submit_urb(&g_cdc_ecm_class.bulkin_urb);
|
||||
if (ret < 0) {
|
||||
goto find_class;
|
||||
}
|
||||
|
||||
g_cdc_ecm_rx_length += g_cdc_ecm_class.bulkin_urb.actual_length;
|
||||
|
||||
if (g_cdc_ecm_rx_length % ep_mps) {
|
||||
USB_LOG_DBG("rxlen:%d\r\n", g_cdc_ecm_rx_length);
|
||||
|
||||
p = pbuf_alloc(PBUF_RAW, g_cdc_ecm_rx_length, PBUF_POOL);
|
||||
if (p != NULL) {
|
||||
memcpy(p->payload, (uint8_t *)g_cdc_ecm_rx_buffer, g_cdc_ecm_rx_length);
|
||||
g_cdc_ecm_rx_length = 0;
|
||||
err = netif->input(p, netif);
|
||||
if (err != ERR_OK) {
|
||||
pbuf_free(p);
|
||||
}
|
||||
} else {
|
||||
g_cdc_ecm_rx_length = 0;
|
||||
USB_LOG_ERR("No memory to alloc pbuf for cdc ecm rx\r\n");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
int ret;
|
||||
struct pbuf *q;
|
||||
uint8_t *buffer = g_cdc_ecm_tx_buffer;
|
||||
|
||||
if (g_cdc_ecm_class.connect_status == CDC_ECM_NET_DISCONNECTED) {
|
||||
return ERR_BUF;
|
||||
}
|
||||
|
||||
for (q = p; q != NULL; q = q->next) {
|
||||
memcpy(buffer, q->payload, q->len);
|
||||
buffer += q->len;
|
||||
}
|
||||
|
||||
USB_LOG_DBG("txlen:%d\r\n", p->tot_len);
|
||||
|
||||
usbh_bulk_urb_fill(&g_cdc_ecm_class.bulkout_urb, g_cdc_ecm_class.bulkout, g_cdc_ecm_tx_buffer, p->tot_len, USB_OSAL_WAITING_FOREVER, NULL, NULL);
|
||||
ret = usbh_submit_urb(&g_cdc_ecm_class.bulkout_urb);
|
||||
if (ret < 0) {
|
||||
return ERR_BUF;
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void usbh_cdc_ecm_lwip_thread_init(struct netif *netif)
|
||||
{
|
||||
usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, netif);
|
||||
}
|
||||
|
||||
__WEAK void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
|
||||
{
|
||||
}
|
||||
|
||||
const struct usbh_class_driver cdc_ecm_class_driver = {
|
||||
.driver_name = "cdc_ecm",
|
||||
.connect = usbh_cdc_ecm_connect,
|
||||
.disconnect = usbh_cdc_ecm_disconnect
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info cdc_ecm_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_CDC,
|
||||
.subclass = CDC_ETHERNET_NETWORKING_CONTROL_MODEL,
|
||||
.protocol = CDC_COMMON_PROTOCOL_NONE,
|
||||
.vid = 0x00,
|
||||
.pid = 0x00,
|
||||
.class_driver = &cdc_ecm_class_driver
|
||||
};
|
||||
50
class/cdc/usbh_cdc_ecm.h
Normal file
50
class/cdc/usbh_cdc_ecm.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USBH_CDC_ECM_H
|
||||
#define USBH_CDC_ECM_H
|
||||
|
||||
#include "usb_cdc.h"
|
||||
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/pbuf.h"
|
||||
|
||||
struct usbh_cdc_ecm {
|
||||
struct usbh_hubport *hport;
|
||||
|
||||
uint8_t ctrl_intf; /* Control interface number */
|
||||
uint8_t data_intf; /* Data interface number */
|
||||
uint8_t minor;
|
||||
uint8_t mac[6];
|
||||
uint32_t max_segment_size;
|
||||
uint8_t connect_status;
|
||||
uint32_t speed[2];
|
||||
usbh_pipe_t bulkin; /* Bulk IN endpoint */
|
||||
usbh_pipe_t bulkout; /* Bulk OUT endpoint */
|
||||
usbh_pipe_t intin; /* Interrupt IN endpoint */
|
||||
struct usbh_urb bulkout_urb;
|
||||
struct usbh_urb bulkin_urb;
|
||||
struct usbh_urb intin_urb;
|
||||
|
||||
ip_addr_t ipaddr;
|
||||
ip_addr_t netmask;
|
||||
ip_addr_t gateway;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class);
|
||||
void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class);
|
||||
|
||||
err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p);
|
||||
void usbh_cdc_ecm_lwip_thread_init(struct netif *netif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBH_CDC_ACM_H */
|
||||
@@ -23,7 +23,7 @@
|
||||
#define FLASH_ERASE_TIME 50
|
||||
#endif
|
||||
|
||||
struct dfu_cfg_priv {
|
||||
struct usbd_dfu_priv {
|
||||
struct dfu_info info;
|
||||
union {
|
||||
uint32_t d32[USBD_DFU_XFER_SIZE / 4U];
|
||||
@@ -40,26 +40,26 @@ struct dfu_cfg_priv {
|
||||
uint8_t dev_state;
|
||||
uint8_t manif_state;
|
||||
uint8_t firmwar_flag;
|
||||
} usbd_dfu_cfg;
|
||||
} g_usbd_dfu;
|
||||
|
||||
static void dfu_reset(void)
|
||||
{
|
||||
memset(&usbd_dfu_cfg, 0, sizeof(usbd_dfu_cfg));
|
||||
memset(&g_usbd_dfu, 0, sizeof(g_usbd_dfu));
|
||||
|
||||
usbd_dfu_cfg.alt_setting = 0U;
|
||||
usbd_dfu_cfg.data_ptr = USBD_DFU_APP_DEFAULT_ADD;
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
g_usbd_dfu.alt_setting = 0U;
|
||||
g_usbd_dfu.data_ptr = USBD_DFU_APP_DEFAULT_ADD;
|
||||
g_usbd_dfu.wblock_num = 0U;
|
||||
g_usbd_dfu.wlength = 0U;
|
||||
|
||||
usbd_dfu_cfg.manif_state = DFU_MANIFEST_COMPLETE;
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
g_usbd_dfu.manif_state = DFU_MANIFEST_COMPLETE;
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[0] = DFU_STATUS_OK;
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = DFU_STATE_DFU_IDLE;
|
||||
usbd_dfu_cfg.dev_status[5] = 0U;
|
||||
g_usbd_dfu.dev_status[0] = DFU_STATUS_OK;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = DFU_STATE_DFU_IDLE;
|
||||
g_usbd_dfu.dev_status[5] = 0U;
|
||||
}
|
||||
|
||||
static uint16_t dfu_getstatus(uint32_t add, uint8_t cmd, uint8_t *buffer)
|
||||
@@ -84,21 +84,21 @@ static uint16_t dfu_getstatus(uint32_t add, uint8_t cmd, uint8_t *buffer)
|
||||
|
||||
static void dfu_request_detach(void)
|
||||
{
|
||||
if ((usbd_dfu_cfg.dev_state == DFU_STATE_DFU_IDLE) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_SYNC) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_MANIFEST_SYNC) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
|
||||
if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE) ||
|
||||
(g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_SYNC) ||
|
||||
(g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) ||
|
||||
(g_usbd_dfu.dev_state == DFU_STATE_DFU_MANIFEST_SYNC) ||
|
||||
(g_usbd_dfu.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
|
||||
/* Update the state machine */
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
usbd_dfu_cfg.dev_status[0] = DFU_STATUS_OK;
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U; /*bwPollTimeout=0ms*/
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
usbd_dfu_cfg.dev_status[5] = 0U; /*iString*/
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE;
|
||||
g_usbd_dfu.dev_status[0] = DFU_STATUS_OK;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U; /*bwPollTimeout=0ms*/
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
g_usbd_dfu.dev_status[5] = 0U; /*iString*/
|
||||
g_usbd_dfu.wblock_num = 0U;
|
||||
g_usbd_dfu.wlength = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,62 +109,62 @@ static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, u
|
||||
uint8_t *phaddr;
|
||||
/* Data setup request */
|
||||
if (req->wLength > 0U) {
|
||||
if ((usbd_dfu_cfg.dev_state == DFU_STATE_DFU_IDLE) || (usbd_dfu_cfg.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
|
||||
if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE) || (g_usbd_dfu.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
|
||||
/* Update the global length and block number */
|
||||
usbd_dfu_cfg.wblock_num = req->wValue;
|
||||
usbd_dfu_cfg.wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE);
|
||||
g_usbd_dfu.wblock_num = req->wValue;
|
||||
g_usbd_dfu.wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE);
|
||||
|
||||
/* DFU Get Command */
|
||||
if (usbd_dfu_cfg.wblock_num == 0U) {
|
||||
if (g_usbd_dfu.wblock_num == 0U) {
|
||||
/* Update the state machine */
|
||||
usbd_dfu_cfg.dev_state = (usbd_dfu_cfg.wlength > 3U) ? DFU_STATE_DFU_IDLE : DFU_STATE_DFU_UPLOAD_IDLE;
|
||||
g_usbd_dfu.dev_state = (g_usbd_dfu.wlength > 3U) ? DFU_STATE_DFU_IDLE : DFU_STATE_DFU_UPLOAD_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
|
||||
/* Store the values of all supported commands */
|
||||
usbd_dfu_cfg.buffer.d8[0] = DFU_CMD_GETCOMMANDS;
|
||||
usbd_dfu_cfg.buffer.d8[1] = DFU_CMD_SETADDRESSPOINTER;
|
||||
usbd_dfu_cfg.buffer.d8[2] = DFU_CMD_ERASE;
|
||||
g_usbd_dfu.buffer.d8[0] = DFU_CMD_GETCOMMANDS;
|
||||
g_usbd_dfu.buffer.d8[1] = DFU_CMD_SETADDRESSPOINTER;
|
||||
g_usbd_dfu.buffer.d8[2] = DFU_CMD_ERASE;
|
||||
|
||||
/* Send the status data over EP0 */
|
||||
memcpy(*data, usbd_dfu_cfg.buffer.d8, 3);
|
||||
memcpy(*data, g_usbd_dfu.buffer.d8, 3);
|
||||
*len = 3;
|
||||
} else if (usbd_dfu_cfg.wblock_num > 1U) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_UPLOAD_IDLE;
|
||||
} else if (g_usbd_dfu.wblock_num > 1U) {
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_UPLOAD_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
|
||||
addr = ((usbd_dfu_cfg.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + usbd_dfu_cfg.data_ptr;
|
||||
addr = ((g_usbd_dfu.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + g_usbd_dfu.data_ptr;
|
||||
|
||||
/* Return the physical address where data are stored */
|
||||
phaddr = dfu_read_flash((uint8_t *)addr, usbd_dfu_cfg.buffer.d8, usbd_dfu_cfg.wlength);
|
||||
phaddr = dfu_read_flash((uint8_t *)addr, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength);
|
||||
|
||||
/* Send the status data over EP0 */
|
||||
memcpy(*data, usbd_dfu_cfg.buffer.d8, usbd_dfu_cfg.wlength);
|
||||
*len = usbd_dfu_cfg.wlength;
|
||||
} else /* unsupported usbd_dfu_cfg.wblock_num */
|
||||
memcpy(*data, g_usbd_dfu.buffer.d8, g_usbd_dfu.wlength);
|
||||
*len = g_usbd_dfu.wlength;
|
||||
} else /* unsupported g_usbd_dfu.wblock_num */
|
||||
{
|
||||
usbd_dfu_cfg.dev_state = DFU_STATUS_ERR_STALLEDPKT;
|
||||
g_usbd_dfu.dev_state = DFU_STATUS_ERR_STALLEDPKT;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
|
||||
/* Call the error management function (command will be NAKed */
|
||||
USB_LOG_ERR("Dfu_request_upload unsupported usbd_dfu_cfg.wblock_num\r\n");
|
||||
USB_LOG_ERR("Dfu_request_upload unsupported g_usbd_dfu.wblock_num\r\n");
|
||||
}
|
||||
}
|
||||
/* Unsupported state */
|
||||
else {
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
g_usbd_dfu.wlength = 0U;
|
||||
g_usbd_dfu.wblock_num = 0U;
|
||||
|
||||
/* Call the error management function (command will be NAKed */
|
||||
USB_LOG_ERR("Dfu_request_upload unsupported state\r\n");
|
||||
@@ -172,12 +172,12 @@ static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, u
|
||||
}
|
||||
/* No Data setup request */
|
||||
else {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,19 +186,19 @@ static void dfu_request_dnload(struct usb_setup_packet *setup, uint8_t **data, u
|
||||
/* Data setup request */
|
||||
struct usb_setup_packet *req = setup;
|
||||
if (req->wLength > 0U) {
|
||||
if ((usbd_dfu_cfg.dev_state == DFU_STATE_DFU_IDLE) || (usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_IDLE)) {
|
||||
if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE) || (g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_IDLE)) {
|
||||
/* Update the global length and block number */
|
||||
usbd_dfu_cfg.wblock_num = req->wValue;
|
||||
usbd_dfu_cfg.wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE);
|
||||
g_usbd_dfu.wblock_num = req->wValue;
|
||||
g_usbd_dfu.wlength = MIN(req->wLength, USBD_DFU_XFER_SIZE);
|
||||
|
||||
/* Update the state machine */
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_DNLOAD_SYNC;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_DNLOAD_SYNC;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
|
||||
/*!< Data has received complete */
|
||||
memcpy((uint8_t *)usbd_dfu_cfg.buffer.d8, (uint8_t *)*data, usbd_dfu_cfg.wlength);
|
||||
memcpy((uint8_t *)g_usbd_dfu.buffer.d8, (uint8_t *)*data, g_usbd_dfu.wlength);
|
||||
/*!< Set flag = 1 Write the firmware to the flash in the next dfu_request_getstatus */
|
||||
usbd_dfu_cfg.firmwar_flag = 1;
|
||||
g_usbd_dfu.firmwar_flag = 1;
|
||||
}
|
||||
/* Unsupported state */
|
||||
else {
|
||||
@@ -208,16 +208,16 @@ static void dfu_request_dnload(struct usb_setup_packet *setup, uint8_t **data, u
|
||||
/* 0 Data DNLOAD request */
|
||||
else {
|
||||
/* End of DNLOAD operation*/
|
||||
if ((usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) || (usbd_dfu_cfg.dev_state == DFU_STATE_DFU_IDLE)) {
|
||||
usbd_dfu_cfg.manif_state = DFU_MANIFEST_IN_PROGRESS;
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_MANIFEST_SYNC;
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) || (g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE)) {
|
||||
g_usbd_dfu.manif_state = DFU_MANIFEST_IN_PROGRESS;
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_MANIFEST_SYNC;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
} else {
|
||||
/* Call the error management function (command will be NAKed */
|
||||
USB_LOG_ERR("Dfu_request_dnload End of DNLOAD operation but dev_state %02x \r\n", usbd_dfu_cfg.dev_state);
|
||||
USB_LOG_ERR("Dfu_request_dnload End of DNLOAD operation but dev_state %02x \r\n", g_usbd_dfu.dev_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,63 +225,63 @@ static void dfu_request_dnload(struct usb_setup_packet *setup, uint8_t **data, u
|
||||
static int8_t dfu_getstatus_special_handler(void)
|
||||
{
|
||||
uint32_t addr;
|
||||
if (usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_BUSY) {
|
||||
if (g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_BUSY) {
|
||||
/* Decode the Special Command */
|
||||
if (usbd_dfu_cfg.wblock_num == 0U) {
|
||||
if (usbd_dfu_cfg.wlength == 1U) {
|
||||
if (usbd_dfu_cfg.buffer.d8[0] == DFU_CMD_GETCOMMANDS) {
|
||||
if (g_usbd_dfu.wblock_num == 0U) {
|
||||
if (g_usbd_dfu.wlength == 1U) {
|
||||
if (g_usbd_dfu.buffer.d8[0] == DFU_CMD_GETCOMMANDS) {
|
||||
/* Nothing to do */
|
||||
}
|
||||
} else if (usbd_dfu_cfg.wlength == 5U) {
|
||||
if (usbd_dfu_cfg.buffer.d8[0] == DFU_CMD_SETADDRESSPOINTER) {
|
||||
usbd_dfu_cfg.data_ptr = usbd_dfu_cfg.buffer.d8[1];
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[2] << 8;
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[3] << 16;
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[4] << 24;
|
||||
} else if (usbd_dfu_cfg.buffer.d8[0] == DFU_CMD_ERASE) {
|
||||
usbd_dfu_cfg.data_ptr = usbd_dfu_cfg.buffer.d8[1];
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[2] << 8;
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[3] << 16;
|
||||
usbd_dfu_cfg.data_ptr += (uint32_t)usbd_dfu_cfg.buffer.d8[4] << 24;
|
||||
} else if (g_usbd_dfu.wlength == 5U) {
|
||||
if (g_usbd_dfu.buffer.d8[0] == DFU_CMD_SETADDRESSPOINTER) {
|
||||
g_usbd_dfu.data_ptr = g_usbd_dfu.buffer.d8[1];
|
||||
g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[2] << 8;
|
||||
g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[3] << 16;
|
||||
g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[4] << 24;
|
||||
} else if (g_usbd_dfu.buffer.d8[0] == DFU_CMD_ERASE) {
|
||||
g_usbd_dfu.data_ptr = g_usbd_dfu.buffer.d8[1];
|
||||
g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[2] << 8;
|
||||
g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[3] << 16;
|
||||
g_usbd_dfu.data_ptr += (uint32_t)g_usbd_dfu.buffer.d8[4] << 24;
|
||||
|
||||
USB_LOG_DBG("Erase start add %08x \r\n", usbd_dfu_cfg.data_ptr);
|
||||
USB_LOG_DBG("Erase start add %08x \r\n", g_usbd_dfu.data_ptr);
|
||||
/*!< Erase */
|
||||
dfu_erase_flash(usbd_dfu_cfg.data_ptr);
|
||||
dfu_erase_flash(g_usbd_dfu.data_ptr);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* Reset the global length and block number */
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
g_usbd_dfu.wlength = 0U;
|
||||
g_usbd_dfu.wblock_num = 0U;
|
||||
/* Call the error management function (command will be NAKed) */
|
||||
USB_LOG_ERR("Reset the global length and block number\r\n");
|
||||
}
|
||||
}
|
||||
/* Regular Download Command */
|
||||
else {
|
||||
if (usbd_dfu_cfg.wblock_num > 1U) {
|
||||
if (g_usbd_dfu.wblock_num > 1U) {
|
||||
/* Decode the required address */
|
||||
addr = ((usbd_dfu_cfg.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + usbd_dfu_cfg.data_ptr;
|
||||
addr = ((g_usbd_dfu.wblock_num - 2U) * USBD_DFU_XFER_SIZE) + g_usbd_dfu.data_ptr;
|
||||
|
||||
/* Perform the write operation */
|
||||
/* Write flash */
|
||||
USB_LOG_DBG("Write start add %08x length %d\r\n", addr, usbd_dfu_cfg.wlength);
|
||||
dfu_write_flash(usbd_dfu_cfg.buffer.d8, (uint8_t *)addr, usbd_dfu_cfg.wlength);
|
||||
USB_LOG_DBG("Write start add %08x length %d\r\n", addr, g_usbd_dfu.wlength);
|
||||
dfu_write_flash(g_usbd_dfu.buffer.d8, (uint8_t *)addr, g_usbd_dfu.wlength);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the global length and block number */
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
g_usbd_dfu.wlength = 0U;
|
||||
g_usbd_dfu.wblock_num = 0U;
|
||||
|
||||
/* Update the state machine */
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_DNLOAD_SYNC;
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_DNLOAD_SYNC;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -289,77 +289,77 @@ static int8_t dfu_getstatus_special_handler(void)
|
||||
static void dfu_request_getstatus(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
/*!< Determine whether to leave DFU mode */
|
||||
if (usbd_dfu_cfg.manif_state == DFU_MANIFEST_IN_PROGRESS &&
|
||||
usbd_dfu_cfg.dev_state == DFU_STATE_DFU_MANIFEST_SYNC &&
|
||||
usbd_dfu_cfg.dev_status[1] == 0U &&
|
||||
usbd_dfu_cfg.dev_status[2] == 0U &&
|
||||
usbd_dfu_cfg.dev_status[3] == 0U &&
|
||||
usbd_dfu_cfg.dev_status[4] == usbd_dfu_cfg.dev_state) {
|
||||
usbd_dfu_cfg.manif_state = DFU_MANIFEST_COMPLETE;
|
||||
if (g_usbd_dfu.manif_state == DFU_MANIFEST_IN_PROGRESS &&
|
||||
g_usbd_dfu.dev_state == DFU_STATE_DFU_MANIFEST_SYNC &&
|
||||
g_usbd_dfu.dev_status[1] == 0U &&
|
||||
g_usbd_dfu.dev_status[2] == 0U &&
|
||||
g_usbd_dfu.dev_status[3] == 0U &&
|
||||
g_usbd_dfu.dev_status[4] == g_usbd_dfu.dev_state) {
|
||||
g_usbd_dfu.manif_state = DFU_MANIFEST_COMPLETE;
|
||||
|
||||
if ((0x0B & DFU_MANIFEST_MASK) != 0U) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_MANIFEST_SYNC;
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_MANIFEST_SYNC;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
return;
|
||||
} else {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_MANIFEST_WAIT_RESET;
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_MANIFEST_WAIT_RESET;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
/* Generate system reset to allow jumping to the user code */
|
||||
dfu_leave();
|
||||
}
|
||||
}
|
||||
|
||||
switch (usbd_dfu_cfg.dev_state) {
|
||||
switch (g_usbd_dfu.dev_state) {
|
||||
case DFU_STATE_DFU_DNLOAD_SYNC:
|
||||
if (usbd_dfu_cfg.wlength != 0U) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_DNLOAD_BUSY;
|
||||
if (g_usbd_dfu.wlength != 0U) {
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_DNLOAD_BUSY;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
|
||||
if ((usbd_dfu_cfg.wblock_num == 0U) && (usbd_dfu_cfg.buffer.d8[0] == DFU_CMD_ERASE)) {
|
||||
dfu_getstatus(usbd_dfu_cfg.data_ptr, DFU_MEDIA_ERASE, usbd_dfu_cfg.dev_status);
|
||||
if ((g_usbd_dfu.wblock_num == 0U) && (g_usbd_dfu.buffer.d8[0] == DFU_CMD_ERASE)) {
|
||||
dfu_getstatus(g_usbd_dfu.data_ptr, DFU_MEDIA_ERASE, g_usbd_dfu.dev_status);
|
||||
} else {
|
||||
dfu_getstatus(usbd_dfu_cfg.data_ptr, DFU_MEDIA_PROGRAM, usbd_dfu_cfg.dev_status);
|
||||
dfu_getstatus(g_usbd_dfu.data_ptr, DFU_MEDIA_PROGRAM, g_usbd_dfu.dev_status);
|
||||
}
|
||||
} else /* (usbd_dfu_cfg.wlength==0)*/
|
||||
} else /* (g_usbd_dfu.wlength==0)*/
|
||||
{
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_DNLOAD_IDLE;
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_DNLOAD_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
}
|
||||
break;
|
||||
|
||||
case DFU_STATE_DFU_MANIFEST_SYNC:
|
||||
if (usbd_dfu_cfg.manif_state == DFU_MANIFEST_IN_PROGRESS) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_MANIFEST;
|
||||
if (g_usbd_dfu.manif_state == DFU_MANIFEST_IN_PROGRESS) {
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_MANIFEST;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 1U; /*bwPollTimeout = 1ms*/
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 1U; /*bwPollTimeout = 1ms*/
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
} else {
|
||||
if ((usbd_dfu_cfg.manif_state == DFU_MANIFEST_COMPLETE) &&
|
||||
if ((g_usbd_dfu.manif_state == DFU_MANIFEST_COMPLETE) &&
|
||||
((0x0B & DFU_MANIFEST_MASK) != 0U)) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE;
|
||||
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U;
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U;
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -369,62 +369,62 @@ static void dfu_request_getstatus(struct usb_setup_packet *setup, uint8_t **data
|
||||
}
|
||||
|
||||
/* Send the status data over EP0 */
|
||||
memcpy(*data, usbd_dfu_cfg.dev_status, 6);
|
||||
memcpy(*data, g_usbd_dfu.dev_status, 6);
|
||||
*len = 6;
|
||||
|
||||
if (usbd_dfu_cfg.firmwar_flag == 1) {
|
||||
if (g_usbd_dfu.firmwar_flag == 1) {
|
||||
if (dfu_getstatus_special_handler() != 0) {
|
||||
USB_LOG_ERR("dfu_getstatus_special_handler error \r\n");
|
||||
}
|
||||
usbd_dfu_cfg.firmwar_flag = 0;
|
||||
g_usbd_dfu.firmwar_flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void dfu_request_clrstatus(void)
|
||||
{
|
||||
if (usbd_dfu_cfg.dev_state == DFU_STATE_DFU_ERROR) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
usbd_dfu_cfg.dev_status[0] = DFU_STATUS_OK; /* bStatus */
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U; /* bwPollTimeout=0ms */
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state; /* bState */
|
||||
usbd_dfu_cfg.dev_status[5] = 0U; /* iString */
|
||||
if (g_usbd_dfu.dev_state == DFU_STATE_DFU_ERROR) {
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE;
|
||||
g_usbd_dfu.dev_status[0] = DFU_STATUS_OK; /* bStatus */
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U; /* bwPollTimeout=0ms */
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; /* bState */
|
||||
g_usbd_dfu.dev_status[5] = 0U; /* iString */
|
||||
} else {
|
||||
/* State Error */
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_ERROR;
|
||||
usbd_dfu_cfg.dev_status[0] = DFU_STATUS_ERR_UNKNOWN; /* bStatus */
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U; /* bwPollTimeout=0ms */
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state; /* bState */
|
||||
usbd_dfu_cfg.dev_status[5] = 0U; /* iString */
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_ERROR;
|
||||
g_usbd_dfu.dev_status[0] = DFU_STATUS_ERR_UNKNOWN; /* bStatus */
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U; /* bwPollTimeout=0ms */
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state; /* bState */
|
||||
g_usbd_dfu.dev_status[5] = 0U; /* iString */
|
||||
}
|
||||
}
|
||||
|
||||
static void dfu_request_getstate(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
/* Return the current state of the DFU interface */
|
||||
(*data)[0] = usbd_dfu_cfg.dev_state;
|
||||
(*data)[0] = g_usbd_dfu.dev_state;
|
||||
*len = 1;
|
||||
}
|
||||
|
||||
void dfu_request_abort(void)
|
||||
{
|
||||
if ((usbd_dfu_cfg.dev_state == DFU_STATE_DFU_IDLE) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_SYNC) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_MANIFEST_SYNC) ||
|
||||
(usbd_dfu_cfg.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_IDLE;
|
||||
usbd_dfu_cfg.dev_status[0] = DFU_STATUS_OK;
|
||||
usbd_dfu_cfg.dev_status[1] = 0U;
|
||||
usbd_dfu_cfg.dev_status[2] = 0U;
|
||||
usbd_dfu_cfg.dev_status[3] = 0U; /* bwPollTimeout=0ms */
|
||||
usbd_dfu_cfg.dev_status[4] = usbd_dfu_cfg.dev_state;
|
||||
usbd_dfu_cfg.dev_status[5] = 0U; /* iString */
|
||||
usbd_dfu_cfg.wblock_num = 0U;
|
||||
usbd_dfu_cfg.wlength = 0U;
|
||||
if ((g_usbd_dfu.dev_state == DFU_STATE_DFU_IDLE) ||
|
||||
(g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_SYNC) ||
|
||||
(g_usbd_dfu.dev_state == DFU_STATE_DFU_DNLOAD_IDLE) ||
|
||||
(g_usbd_dfu.dev_state == DFU_STATE_DFU_MANIFEST_SYNC) ||
|
||||
(g_usbd_dfu.dev_state == DFU_STATE_DFU_UPLOAD_IDLE)) {
|
||||
g_usbd_dfu.dev_state = DFU_STATE_DFU_IDLE;
|
||||
g_usbd_dfu.dev_status[0] = DFU_STATUS_OK;
|
||||
g_usbd_dfu.dev_status[1] = 0U;
|
||||
g_usbd_dfu.dev_status[2] = 0U;
|
||||
g_usbd_dfu.dev_status[3] = 0U; /* bwPollTimeout=0ms */
|
||||
g_usbd_dfu.dev_status[4] = g_usbd_dfu.dev_state;
|
||||
g_usbd_dfu.dev_status[5] = 0U; /* iString */
|
||||
g_usbd_dfu.wblock_num = 0U;
|
||||
g_usbd_dfu.wlength = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -387,7 +387,7 @@
|
||||
#define HID_KBD_USAGE_PAGEDOWN 0x4e /* Keyboard PageDown */
|
||||
#define HID_KBD_USAGE_RIGHT 0x4f /* eyboard RightArrow */
|
||||
#define HID_KBD_USAGE_LEFT 0x50 /* Keyboard LeftArrow */
|
||||
#define HID_KBD_USAGE_DOWN 0x5a /* Keyboard DownArrow */
|
||||
#define HID_KBD_USAGE_DOWN 0x51 /* Keyboard DownArrow */
|
||||
#define HID_KBD_USAGE_UP 0x52 /* Keyboard UpArrow */
|
||||
#define HID_KBD_USAGE_KPDNUMLOCK 0x53 /* Keypad Num Lock and Clear */
|
||||
#define HID_KBD_USAGE_KPDNUMLOCKCLEAR 0x53 /* Keypad Num Lock and Clear */
|
||||
|
||||
@@ -17,28 +17,27 @@ static int hid_class_interface_request_handler(struct usb_setup_packet *setup, u
|
||||
switch (setup->bRequest) {
|
||||
case HID_REQUEST_GET_REPORT:
|
||||
/* report id ,report type */
|
||||
(*data)[0] = usbh_hid_get_report(intf_num, LO_BYTE(setup->wValue), HI_BYTE(setup->wValue));
|
||||
*len = 1;
|
||||
usbd_hid_get_report(intf_num, LO_BYTE(setup->wValue), HI_BYTE(setup->wValue), data, len);
|
||||
break;
|
||||
case HID_REQUEST_GET_IDLE:
|
||||
(*data)[0] = usbh_hid_get_idle(intf_num, LO_BYTE(setup->wValue));
|
||||
(*data)[0] = usbd_hid_get_idle(intf_num, LO_BYTE(setup->wValue));
|
||||
*len = 1;
|
||||
break;
|
||||
case HID_REQUEST_GET_PROTOCOL:
|
||||
(*data)[0] = usbh_hid_get_protocol(intf_num);
|
||||
(*data)[0] = usbd_hid_get_protocol(intf_num);
|
||||
*len = 1;
|
||||
break;
|
||||
case HID_REQUEST_SET_REPORT:
|
||||
/* report id ,report type, report, report len */
|
||||
usbh_hid_set_report(intf_num, LO_BYTE(setup->wValue), HI_BYTE(setup->wValue), *data, *len);
|
||||
usbd_hid_set_report(intf_num, LO_BYTE(setup->wValue), HI_BYTE(setup->wValue), *data, *len);
|
||||
break;
|
||||
case HID_REQUEST_SET_IDLE:
|
||||
/* report id, duration */
|
||||
usbh_hid_set_idle(intf_num, LO_BYTE(setup->wValue), HI_BYTE(setup->wValue));
|
||||
usbd_hid_set_idle(intf_num, LO_BYTE(setup->wValue), HI_BYTE(setup->wValue));
|
||||
break;
|
||||
case HID_REQUEST_SET_PROTOCOL:
|
||||
/* protocol */
|
||||
usbh_hid_set_protocol(intf_num, LO_BYTE(setup->wValue));
|
||||
usbd_hid_set_protocol(intf_num, LO_BYTE(setup->wValue));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -61,29 +60,30 @@ struct usbd_interface *usbd_hid_init_intf(struct usbd_interface *intf, const uin
|
||||
return intf;
|
||||
}
|
||||
|
||||
__WEAK uint8_t usbh_hid_get_report(uint8_t intf, uint8_t report_id, uint8_t report_type)
|
||||
__WEAK void usbd_hid_get_report(uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
(*data[0]) = 0;
|
||||
*len = 1;
|
||||
}
|
||||
|
||||
__WEAK uint8_t usbd_hid_get_idle(uint8_t intf, uint8_t report_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK uint8_t usbh_hid_get_idle(uint8_t intf, uint8_t report_id)
|
||||
__WEAK uint8_t usbd_hid_get_protocol(uint8_t intf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK uint8_t usbh_hid_get_protocol(uint8_t intf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbh_hid_set_report(uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t *report, uint8_t report_len)
|
||||
__WEAK void usbd_hid_set_report(uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t *report, uint32_t report_len)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_hid_set_idle(uint8_t intf, uint8_t report_id, uint8_t duration)
|
||||
__WEAK void usbd_hid_set_idle(uint8_t intf, uint8_t report_id, uint8_t duration)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_hid_set_protocol(uint8_t intf, uint8_t protocol)
|
||||
__WEAK void usbd_hid_set_protocol(uint8_t intf, uint8_t protocol)
|
||||
{
|
||||
}
|
||||
@@ -20,12 +20,12 @@ void usbd_hid_descriptor_register(uint8_t intf_num, const uint8_t *desc);
|
||||
void usbd_hid_report_descriptor_register(uint8_t intf_num, const uint8_t *desc, uint32_t desc_len);
|
||||
|
||||
/* Setup request command callback api */
|
||||
uint8_t usbh_hid_get_report(uint8_t intf, uint8_t report_id, uint8_t report_type);
|
||||
uint8_t usbh_hid_get_idle(uint8_t intf, uint8_t report_id);
|
||||
uint8_t usbh_hid_get_protocol(uint8_t intf);
|
||||
void usbh_hid_set_report(uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t *report, uint8_t report_len);
|
||||
void usbh_hid_set_idle(uint8_t intf, uint8_t report_id, uint8_t duration);
|
||||
void usbh_hid_set_protocol(uint8_t intf, uint8_t protocol);
|
||||
void usbd_hid_get_report(uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t **data, uint32_t *len);
|
||||
uint8_t usbd_hid_get_idle(uint8_t intf, uint8_t report_id);
|
||||
uint8_t usbd_hid_get_protocol(uint8_t intf);
|
||||
void usbd_hid_set_report(uint8_t intf, uint8_t report_id, uint8_t report_type, uint8_t *report, uint32_t report_len);
|
||||
void usbd_hid_set_idle(uint8_t intf, uint8_t report_id, uint8_t duration);
|
||||
void usbd_hid_set_protocol(uint8_t intf, uint8_t protocol);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -8,33 +8,34 @@
|
||||
|
||||
#define DEV_FORMAT "/dev/input%d"
|
||||
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hid_buf[128];
|
||||
|
||||
static int usbh_hid_devno_alloc(struct usbh_hid *hid_class)
|
||||
static struct usbh_hid g_hid_class[CONFIG_USBHOST_MAX_HID_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
static struct usbh_hid *usbh_hid_class_alloc(void)
|
||||
{
|
||||
int devno;
|
||||
|
||||
for (devno = 0; devno < 32; devno++) {
|
||||
uint32_t bitno = 1 << devno;
|
||||
if ((g_devinuse & bitno) == 0) {
|
||||
g_devinuse |= bitno;
|
||||
hid_class->minor = devno;
|
||||
return 0;
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_HID_CLASS; devno++) {
|
||||
if ((g_devinuse & (1 << devno)) == 0) {
|
||||
g_devinuse |= (1 << devno);
|
||||
memset(&g_hid_class[devno], 0, sizeof(struct usbh_hid));
|
||||
g_hid_class[devno].minor = devno;
|
||||
return &g_hid_class[devno];
|
||||
}
|
||||
}
|
||||
|
||||
return -EMFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_hid_devno_free(struct usbh_hid *hid_class)
|
||||
static void usbh_hid_class_free(struct usbh_hid *hid_class)
|
||||
{
|
||||
int devno = hid_class->minor;
|
||||
|
||||
if (devno >= 0 && devno < 32) {
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
memset(hid_class, 0, sizeof(struct usbh_hid));
|
||||
}
|
||||
|
||||
static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer)
|
||||
@@ -106,14 +107,12 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
|
||||
struct usbh_hid *hid_class = usb_malloc(sizeof(struct usbh_hid));
|
||||
struct usbh_hid *hid_class = usbh_hid_class_alloc();
|
||||
if (hid_class == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc hid_class\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(hid_class, 0, sizeof(struct usbh_hid));
|
||||
usbh_hid_devno_alloc(hid_class);
|
||||
hid_class->hport = hport;
|
||||
hid_class->intf = intf;
|
||||
|
||||
@@ -159,8 +158,6 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
struct usbh_hid *hid_class = (struct usbh_hid *)hport->config.intf[intf].priv;
|
||||
|
||||
if (hid_class) {
|
||||
usbh_hid_devno_free(hid_class);
|
||||
|
||||
if (hid_class->intin) {
|
||||
usbh_pipe_free(hid_class->intin);
|
||||
}
|
||||
@@ -169,12 +166,12 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(hid_class->intout);
|
||||
}
|
||||
|
||||
usbh_hid_stop(hid_class);
|
||||
memset(hid_class, 0, sizeof(struct usbh_hid));
|
||||
usb_free(hid_class);
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0')
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister HID Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_hid_stop(hid_class);
|
||||
}
|
||||
|
||||
usbh_hid_class_free(hid_class);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -182,12 +179,10 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
__WEAK void usbh_hid_run(struct usbh_hid *hid_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__WEAK void usbh_hid_stop(struct usbh_hid *hid_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const struct usbh_class_driver hid_class_driver = {
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
#define USB_HUB_H
|
||||
|
||||
/* HUB Class Descriptor Types */
|
||||
#define HUB_DESCRIPTOR_TYPE_HUB 0x29
|
||||
#define HUB_DESCRIPTOR_TYPE_HUB 0x29
|
||||
#define HUB_DESCRIPTOR_TYPE_HUB3 0x2A
|
||||
|
||||
/* Hub class requests */
|
||||
#define HUB_REQUEST_GET_STATUS USB_REQUEST_GET_STATUS
|
||||
@@ -19,6 +20,7 @@
|
||||
#define HUB_REQUEST_RESET_TT (0x09)
|
||||
#define HUB_REQUEST_GET_TT_STATE (0x0a)
|
||||
#define HUB_REQUEST_STOP_TT (0x0b)
|
||||
#define HUB_REQUEST_SET_HUB_DEPTH (0x0C)
|
||||
|
||||
/* Hub class features */
|
||||
#define HUB_FEATURE_HUB_C_LOCALPOWER (0x0)
|
||||
|
||||
@@ -14,10 +14,8 @@
|
||||
|
||||
#define EXTHUB_FIRST_INDEX 2
|
||||
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_buf[32];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_EXTHUBS + 1][1];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USB_ALIGN_SIZE];
|
||||
|
||||
usb_slist_t hub_class_head = USB_SLIST_OBJECT_INIT(hub_class_head);
|
||||
|
||||
@@ -26,9 +24,6 @@ usb_osal_mq_t hub_mq;
|
||||
|
||||
struct usbh_hub roothub;
|
||||
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
struct usbh_hub exthub[CONFIG_USBHOST_MAX_EXTHUBS];
|
||||
#endif
|
||||
extern int usbh_hport_activate_ep0(struct usbh_hubport *hport);
|
||||
extern int usbh_hport_deactivate_ep0(struct usbh_hubport *hport);
|
||||
extern int usbh_enumerate(struct usbh_hubport *hport);
|
||||
@@ -36,27 +31,40 @@ static void usbh_hub_thread_wakeup(struct usbh_hub *hub);
|
||||
|
||||
static const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" };
|
||||
|
||||
#ifdef CONFIG_USBHOST_XHCI
|
||||
struct usbh_hubport *usbh_get_roothub_port(unsigned int port)
|
||||
{
|
||||
return &roothub.child[port - 1];
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
static int usbh_hub_devno_alloc(void)
|
||||
static struct usbh_hub g_hub_class[CONFIG_USBHOST_MAX_EXTHUBS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
static struct usbh_hub *usbh_hub_class_alloc(void)
|
||||
{
|
||||
int devno;
|
||||
|
||||
for (devno = EXTHUB_FIRST_INDEX; devno < 32; devno++) {
|
||||
uint32_t bitno = 1 << devno;
|
||||
if ((g_devinuse & bitno) == 0) {
|
||||
g_devinuse |= bitno;
|
||||
return devno;
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_EXTHUBS; devno++) {
|
||||
if ((g_devinuse & (1 << devno)) == 0) {
|
||||
g_devinuse |= (1 << devno);
|
||||
memset(&g_hub_class[devno], 0, sizeof(struct usbh_hub));
|
||||
g_hub_class[devno].index = EXTHUB_FIRST_INDEX + devno;
|
||||
return &g_hub_class[devno];
|
||||
}
|
||||
}
|
||||
|
||||
return -EMFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_hub_devno_free(uint8_t devno)
|
||||
static void usbh_hub_class_free(struct usbh_hub *hub_class)
|
||||
{
|
||||
if (devno >= EXTHUB_FIRST_INDEX && devno < 32) {
|
||||
int devno = hub_class->index - EXTHUB_FIRST_INDEX;
|
||||
|
||||
if (devno >= 0 && devno < 32) {
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
memset(hub_class, 0, sizeof(struct usbh_hub));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -65,6 +73,7 @@ static void usbh_hub_register(struct usbh_hub *hub)
|
||||
usb_slist_add_tail(&hub_class_head, &hub->list);
|
||||
}
|
||||
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
static void usbh_hub_unregister(struct usbh_hub *hub)
|
||||
{
|
||||
usb_slist_remove(&hub_class_head, &hub->list);
|
||||
@@ -79,7 +88,16 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||
setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8;
|
||||
|
||||
/* TODO: hub descriptor has some difference between USB 2.0 and USB 3.x,
|
||||
and we havn't handle the difference here */
|
||||
if ((hub->parent->speed == USB_SPEED_SUPER) ||
|
||||
(hub->parent->speed == USB_SPEED_SUPER_PLUS)) {
|
||||
setup->wValue = HUB_DESCRIPTOR_TYPE_HUB3 << 8;
|
||||
} else {
|
||||
setup->wValue = HUB_DESCRIPTOR_TYPE_HUB << 8;
|
||||
}
|
||||
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = USB_SIZEOF_HUB_DESC;
|
||||
|
||||
@@ -90,7 +108,7 @@ static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
|
||||
memcpy(buffer, g_hub_buf, USB_SIZEOF_HUB_DESC);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer)
|
||||
{
|
||||
struct usb_setup_packet *setup;
|
||||
@@ -111,6 +129,8 @@ static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer)
|
||||
memcpy(buffer, g_hub_buf, 2);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int _usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status)
|
||||
{
|
||||
@@ -163,6 +183,22 @@ static int _usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t f
|
||||
return usbh_control_transfer(hub->parent->ep0, setup, NULL);
|
||||
}
|
||||
|
||||
static int _usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth)
|
||||
{
|
||||
struct usb_setup_packet *setup;
|
||||
|
||||
setup = hub->parent->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = HUB_REQUEST_SET_HUB_DEPTH;
|
||||
setup->wValue = depth;
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = 0;
|
||||
|
||||
return usbh_control_transfer(hub->parent->ep0, setup, NULL);
|
||||
}
|
||||
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length)
|
||||
{
|
||||
if (desc->bLength != USB_SIZEOF_HUB_DESC) {
|
||||
@@ -184,6 +220,7 @@ static int parse_hub_descriptor(struct usb_hub_descriptor *desc, uint16_t length
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct hub_port_status *port_status)
|
||||
{
|
||||
@@ -239,12 +276,31 @@ static int usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t fe
|
||||
}
|
||||
}
|
||||
|
||||
static int usbh_hub_set_depth(struct usbh_hub *hub, uint16_t depth)
|
||||
{
|
||||
struct usb_setup_packet roothub_setup;
|
||||
struct usb_setup_packet *setup;
|
||||
|
||||
if (hub->is_roothub) {
|
||||
setup = &roothub_setup;
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = HUB_REQUEST_SET_HUB_DEPTH;
|
||||
setup->wValue = depth;
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = 0;
|
||||
return usbh_roothub_control(setup, NULL);
|
||||
} else {
|
||||
return _usbh_hub_set_depth(hub, depth);
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
static void hub_int_complete_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_hub *hub = (struct usbh_hub *)arg;
|
||||
|
||||
if (nbytes > 0) {
|
||||
if (nbytes > 0)
|
||||
{
|
||||
usbh_hub_thread_wakeup(hub);
|
||||
}
|
||||
}
|
||||
@@ -254,21 +310,15 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
struct hub_port_status port_status;
|
||||
int ret;
|
||||
int index;
|
||||
|
||||
index = usbh_hub_devno_alloc();
|
||||
if (index > (CONFIG_USBHOST_MAX_EXTHUBS + EXTHUB_FIRST_INDEX - 1)) {
|
||||
USB_LOG_ERR("No memory to alloc hub class\r\n");
|
||||
usbh_hub_devno_free(index);
|
||||
struct usbh_hub *hub = usbh_hub_class_alloc();
|
||||
if (hub == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc hub_class\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
struct usbh_hub *hub = &exthub[index - EXTHUB_FIRST_INDEX];
|
||||
|
||||
memset(hub, 0, sizeof(struct usbh_hub));
|
||||
hub->hub_addr = hport->dev_addr;
|
||||
hub->parent = hport;
|
||||
hub->index = index;
|
||||
|
||||
hport->config.intf[intf].priv = hub;
|
||||
|
||||
@@ -291,6 +341,20 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hport->speed == USB_SPEED_SUPER) {
|
||||
uint16_t depth = 0;
|
||||
struct usbh_hubport *parent = hport->parent->parent;
|
||||
while (parent) {
|
||||
depth++;
|
||||
parent = parent->parent->parent;
|
||||
}
|
||||
|
||||
ret = usbh_hub_set_depth(hub, depth);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
ret = usbh_hub_set_feature(hub, port + 1, HUB_PORT_FEATURE_POWER);
|
||||
if (ret < 0) {
|
||||
@@ -325,8 +389,6 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
struct usbh_hub *hub = (struct usbh_hub *)hport->config.intf[intf].priv;
|
||||
|
||||
if (hub) {
|
||||
usbh_hub_devno_free(hub->index);
|
||||
|
||||
if (hub->intin) {
|
||||
usbh_pipe_free(hub->intin);
|
||||
}
|
||||
@@ -344,11 +406,12 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
child->parent = NULL;
|
||||
}
|
||||
|
||||
usbh_hub_unregister(hub);
|
||||
memset(hub, 0, sizeof(struct usbh_hub));
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0')
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister HUB Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_hub_unregister(hub);
|
||||
}
|
||||
|
||||
usbh_hub_class_free(hub);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -368,6 +431,21 @@ static void usbh_hubport_release(struct usbh_hubport *child)
|
||||
}
|
||||
}
|
||||
|
||||
static void usbh_hubport_enumerate_thread(void *argument)
|
||||
{
|
||||
struct usbh_hubport *child = (struct usbh_hubport *)argument;
|
||||
|
||||
/* Configure EP0 with the default maximum packet size */
|
||||
usbh_hport_activate_ep0(child);
|
||||
|
||||
if (usbh_enumerate(child) < 0) {
|
||||
/** release child sources */
|
||||
usbh_hubport_release(child);
|
||||
USB_LOG_ERR("Port %u enumerate fail\r\n", child->port);
|
||||
}
|
||||
usb_osal_thread_delete(NULL);
|
||||
}
|
||||
|
||||
static void usbh_hub_events(struct usbh_hub *hub)
|
||||
{
|
||||
struct usbh_hubport *child;
|
||||
@@ -384,9 +462,10 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
portchange_index = hub->int_buffer[0];
|
||||
portchange_index = hub->int_buffer[0];
|
||||
hub->int_buffer[0] = 0;
|
||||
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
USB_LOG_DBG("Port change:0x%02x\r\n", portchange_index);
|
||||
|
||||
if (!(portchange_index & (1 << (port + 1)))) {
|
||||
@@ -496,9 +575,25 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
speed = USB_SPEED_HIGH;
|
||||
} else if (portstatus & HUB_PORT_STATUS_LOW_SPEED) {
|
||||
speed = USB_SPEED_LOW;
|
||||
} else {
|
||||
}
|
||||
#ifdef CONFIG_USBHOST_XHCI
|
||||
else {
|
||||
extern uint8_t usbh_get_port_speed(struct usbh_hub * hub, const uint8_t port);
|
||||
|
||||
/* USB3.0 speed cannot get from portstatus, checkout port speed instead */
|
||||
uint8_t super_speed = usbh_get_port_speed(hub, port + 1);
|
||||
if (super_speed > USB_SPEED_HIGH) {
|
||||
/* assert that when using USB 3.0 ports, attached device must also be USB 3.0 speed */
|
||||
speed = super_speed;
|
||||
} else {
|
||||
speed = USB_SPEED_FULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
else {
|
||||
speed = USB_SPEED_FULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
child = &hub->child[port];
|
||||
/** release child sources first */
|
||||
@@ -509,22 +604,18 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
child->connected = true;
|
||||
child->port = port + 1;
|
||||
child->speed = speed;
|
||||
|
||||
|
||||
USB_LOG_INFO("New %s device on Hub %u, Port %u connected\r\n", speed_table[speed], hub->index, port + 1);
|
||||
|
||||
/* Configure EP0 with the default maximum packet size */
|
||||
usbh_hport_activate_ep0(child);
|
||||
|
||||
if (usbh_enumerate(child) < 0) {
|
||||
/** release child sources */
|
||||
usbh_hubport_release(child);
|
||||
USB_LOG_ERR("Port %u enumerate fail\r\n", port + 1);
|
||||
}
|
||||
/* create disposable thread to enumerate device on current hport, do not block hub thread */
|
||||
child->thread = usb_osal_thread_create("usbh_enum", CONFIG_USBHOST_PSC_STACKSIZE, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hubport_enumerate_thread, (void *)child);
|
||||
} else {
|
||||
child = &hub->child[port];
|
||||
/** release child sources */
|
||||
usbh_hubport_release(child);
|
||||
USB_LOG_ERR("Failed to enable port %u\r\n", port + 1);
|
||||
|
||||
/** some USB 3.0 ip may failed to enable USB 2.0 port for USB 3.0 device */
|
||||
USB_LOG_WRN("Failed to enable port %u\r\n", port + 1);
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -537,7 +628,6 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
}
|
||||
}
|
||||
|
||||
hub->int_buffer[0] = 0;
|
||||
/* Start next hub int transfer */
|
||||
if (!hub->is_roothub && hub->connected) {
|
||||
usbh_submit_urb(&hub->intin_urb);
|
||||
@@ -551,7 +641,7 @@ static void usbh_hub_thread(void *argument)
|
||||
|
||||
usb_hc_init();
|
||||
while (1) {
|
||||
ret = usb_osal_mq_recv(hub_mq, (uint32_t *)&hub, 0xffffffff);
|
||||
ret = usb_osal_mq_recv(hub_mq, (uintptr_t *)&hub, USB_OSAL_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -574,7 +664,7 @@ static void usbh_roothub_register(void)
|
||||
|
||||
static void usbh_hub_thread_wakeup(struct usbh_hub *hub)
|
||||
{
|
||||
usb_osal_mq_send(hub_mq, (uint32_t)hub);
|
||||
usb_osal_mq_send(hub_mq, (uintptr_t)hub);
|
||||
}
|
||||
|
||||
void usbh_roothub_thread_wakeup(uint8_t port)
|
||||
|
||||
@@ -23,6 +23,26 @@
|
||||
#define MIDI_PITCHBEND_MIN -8192
|
||||
#define MIDI_PITCHBEND_MAX 8191
|
||||
|
||||
/*! Enumeration of MIDI code index number */
|
||||
enum MidiCodeIndexNumber {
|
||||
MIDI_CIN_MISC = 0,
|
||||
MIDI_CIN_CABLE_EVENT = 1,
|
||||
MIDI_CIN_SYSCOM_2BYTE = 2, ///< 2 byte system common message e.g MTC, SongSelect
|
||||
MIDI_CIN_SYSCOM_3BYTE = 3, ///< 3 byte system common message e.g SPP
|
||||
MIDI_CIN_SYSEX_START = 4, ///< SysEx starts or continue
|
||||
MIDI_CIN_SYSEX_END_1BYTE = 5, ///< SysEx ends with 1 data, or 1 byte system common message
|
||||
MIDI_CIN_SYSEX_END_2BYTE = 6, ///< SysEx ends with 2 data
|
||||
MIDI_CIN_SYSEX_END_3BYTE = 7, ///< SysEx ends with 3 data
|
||||
MIDI_CIN_NOTE_OFF = 8,
|
||||
MIDI_CIN_NOTE_ON = 9,
|
||||
MIDI_CIN_POLY_KEYPRESS = 10,
|
||||
MIDI_CIN_CONTROL_CHANGE = 11,
|
||||
MIDI_CIN_PROGRAM_CHANGE = 12,
|
||||
MIDI_CIN_CHANNEL_PRESSURE = 13,
|
||||
MIDI_CIN_PITCH_BEND_CHANGE = 14,
|
||||
MIDI_CIN_1BYTE_DATA = 15
|
||||
};
|
||||
|
||||
/*! Enumeration of MIDI types */
|
||||
enum MidiType {
|
||||
InvalidType = 0x00, ///< For notifying errors
|
||||
@@ -181,6 +201,13 @@ struct midi_cs_ep_ms_general_descriptor {
|
||||
#define MIDI_SIZEOF_MS_GENERAL_DESC(n) (4 + n)
|
||||
|
||||
// clang-format off
|
||||
#define MIDI_CS_HEADER_DESCRIPTOR_INIT(wTotalLength) \
|
||||
0x07, /* bLength */ \
|
||||
USB_CS_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
MIDI_MS_HEADER_DESCRIPTOR_SUBTYPE, /* bDescriptorSubtype */ \
|
||||
WBVAL(0x0100), /* bcdMSC */ \
|
||||
WBVAL(wTotalLength) /* wTotalLength */
|
||||
|
||||
#define MIDI_IN_JACK_DESCRIPTOR_INIT(bJackType, bJackID) \
|
||||
0x06, \
|
||||
0x24, \
|
||||
|
||||
@@ -61,8 +61,7 @@ struct CSW {
|
||||
/*Length of template descriptor: 23 bytes*/
|
||||
#define MSC_DESCRIPTOR_LEN (9 + 7 + 7)
|
||||
// clang-format off
|
||||
#ifndef CONFIG_USB_HS
|
||||
#define MSC_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep,str_idx) \
|
||||
#define MSC_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep, wMaxPacketSize, str_idx) \
|
||||
/* Interface */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
@@ -77,39 +76,14 @@ struct CSW {
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
out_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x40, 0x00, /* wMaxPacketSize */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x40, 0x00, /* wMaxPacketSize */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
0x00 /* bInterval */
|
||||
#else
|
||||
#define MSC_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep,str_idx) \
|
||||
/* Interface */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x02, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_MASS_STORAGE, /* bInterfaceClass */ \
|
||||
MSC_SUBCLASS_SCSI, /* bInterfaceSubClass */ \
|
||||
MSC_PROTOCOL_BULK_ONLY, /* bInterfaceProtocol */ \
|
||||
str_idx, /* iInterface */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
out_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x00, 0x02, /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x00, 0x02, /* wMaxPacketSize */ \
|
||||
0x00 /* bInterval */
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
#endif /* USB_MSC_H */
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_msc.h"
|
||||
#include "usb_scsi.h"
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
#include "usb_osal.h"
|
||||
#endif
|
||||
|
||||
#define MSD_OUT_EP_IDX 0
|
||||
#define MSD_IN_EP_IDX 1
|
||||
@@ -23,13 +26,14 @@ enum Stage {
|
||||
};
|
||||
|
||||
/* Device data structure */
|
||||
USB_NOCACHE_RAM_SECTION struct usbd_msc_cfg_priv {
|
||||
USB_NOCACHE_RAM_SECTION struct usbd_msc_priv {
|
||||
/* state of the bulk-only state machine */
|
||||
enum Stage stage;
|
||||
USB_MEM_ALIGNX struct CBW cbw;
|
||||
USB_MEM_ALIGNX struct CSW csw;
|
||||
|
||||
bool readonly;
|
||||
bool popup;
|
||||
uint8_t sKey; /* Sense key */
|
||||
uint8_t ASC; /* Additional Sense Code */
|
||||
uint8_t ASQ; /* Additional Sense Qualifier */
|
||||
@@ -39,13 +43,19 @@ USB_NOCACHE_RAM_SECTION struct usbd_msc_cfg_priv {
|
||||
uint16_t scsi_blk_size;
|
||||
uint32_t scsi_blk_nbr;
|
||||
|
||||
uint8_t block_buffer[CONFIG_USBDEV_MSC_BLOCK_SIZE];
|
||||
} usbd_msc_cfg;
|
||||
USB_MEM_ALIGNX uint8_t block_buffer[CONFIG_USBDEV_MSC_BLOCK_SIZE];
|
||||
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
usb_osal_mq_t usbd_msc_mq;
|
||||
usb_osal_thread_t usbd_msc_thread;
|
||||
uint32_t nbytes;
|
||||
#endif
|
||||
} g_usbd_msc;
|
||||
|
||||
static void usbd_msc_reset(void)
|
||||
{
|
||||
usbd_msc_cfg.stage = MSC_READ_CBW;
|
||||
usbd_msc_cfg.readonly = false;
|
||||
g_usbd_msc.stage = MSC_READ_CBW;
|
||||
g_usbd_msc.readonly = false;
|
||||
}
|
||||
|
||||
static int msc_storage_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
@@ -60,7 +70,7 @@ static int msc_storage_class_interface_request_handler(struct usb_setup_packet *
|
||||
break;
|
||||
|
||||
case MSC_REQUEST_GET_MAX_LUN:
|
||||
(*data)[0] = usbd_msc_cfg.max_lun;
|
||||
(*data)[0] = g_usbd_msc.max_lun;
|
||||
*len = 1;
|
||||
break;
|
||||
|
||||
@@ -80,7 +90,7 @@ void msc_storage_notify_handler(uint8_t event, void *arg)
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
USB_LOG_DBG("Start reading cbw\r\n");
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, (uint8_t *)&usbd_msc_cfg.cbw, USB_SIZEOF_MSC_CBW);
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, (uint8_t *)&g_usbd_msc.cbw, USB_SIZEOF_MSC_CBW);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -90,40 +100,40 @@ void msc_storage_notify_handler(uint8_t event, void *arg)
|
||||
|
||||
static void usbd_msc_bot_abort(void)
|
||||
{
|
||||
if ((usbd_msc_cfg.cbw.bmFlags == 0) && (usbd_msc_cfg.cbw.dDataLength != 0)) {
|
||||
if ((g_usbd_msc.cbw.bmFlags == 0) && (g_usbd_msc.cbw.dDataLength != 0)) {
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
|
||||
}
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_IN_EP_IDX].ep_addr);
|
||||
usbd_ep_start_read(mass_ep_data[0].ep_addr, (uint8_t *)&usbd_msc_cfg.cbw, USB_SIZEOF_MSC_CBW);
|
||||
usbd_ep_start_read(mass_ep_data[0].ep_addr, (uint8_t *)&g_usbd_msc.cbw, USB_SIZEOF_MSC_CBW);
|
||||
}
|
||||
|
||||
static void usbd_msc_send_csw(uint8_t CSW_Status)
|
||||
{
|
||||
usbd_msc_cfg.csw.dSignature = MSC_CSW_Signature;
|
||||
usbd_msc_cfg.csw.bStatus = CSW_Status;
|
||||
g_usbd_msc.csw.dSignature = MSC_CSW_Signature;
|
||||
g_usbd_msc.csw.bStatus = CSW_Status;
|
||||
|
||||
/* updating the State Machine , so that we wait CSW when this
|
||||
* transfer is complete, ie when we get a bulk in callback
|
||||
*/
|
||||
usbd_msc_cfg.stage = MSC_WAIT_CSW;
|
||||
g_usbd_msc.stage = MSC_WAIT_CSW;
|
||||
|
||||
USB_LOG_DBG("Send csw\r\n");
|
||||
usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, (uint8_t *)&usbd_msc_cfg.csw, sizeof(struct CSW));
|
||||
usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, (uint8_t *)&g_usbd_msc.csw, sizeof(struct CSW));
|
||||
}
|
||||
|
||||
static void usbd_msc_send_info(uint8_t *buffer, uint8_t size)
|
||||
{
|
||||
size = MIN(size, usbd_msc_cfg.cbw.dDataLength);
|
||||
size = MIN(size, g_usbd_msc.cbw.dDataLength);
|
||||
|
||||
/* updating the State Machine , so that we send CSW when this
|
||||
* transfer is complete, ie when we get a bulk in callback
|
||||
*/
|
||||
usbd_msc_cfg.stage = MSC_SEND_CSW;
|
||||
g_usbd_msc.stage = MSC_SEND_CSW;
|
||||
|
||||
usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, buffer, size);
|
||||
|
||||
usbd_msc_cfg.csw.dDataResidue -= size;
|
||||
usbd_msc_cfg.csw.bStatus = CSW_STATUS_CMD_PASSED;
|
||||
g_usbd_msc.csw.dDataResidue -= size;
|
||||
g_usbd_msc.csw.bStatus = CSW_STATUS_CMD_PASSED;
|
||||
}
|
||||
|
||||
static bool SCSI_processWrite(uint32_t nbytes);
|
||||
@@ -139,9 +149,9 @@ static bool SCSI_processRead(void);
|
||||
*/
|
||||
static void SCSI_SetSenseData(uint32_t KCQ)
|
||||
{
|
||||
usbd_msc_cfg.sKey = (uint8_t)(KCQ >> 16);
|
||||
usbd_msc_cfg.ASC = (uint8_t)(KCQ >> 8);
|
||||
usbd_msc_cfg.ASQ = (uint8_t)(KCQ);
|
||||
g_usbd_msc.sKey = (uint8_t)(KCQ >> 16);
|
||||
g_usbd_msc.ASC = (uint8_t)(KCQ >> 8);
|
||||
g_usbd_msc.ASQ = (uint8_t)(KCQ);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,7 +161,7 @@ static void SCSI_SetSenseData(uint32_t KCQ)
|
||||
|
||||
static bool SCSI_testUnitReady(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
if (usbd_msc_cfg.cbw.dDataLength != 0U) {
|
||||
if (g_usbd_msc.cbw.dDataLength != 0U) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
@@ -163,13 +173,13 @@ static bool SCSI_testUnitReady(uint8_t **data, uint32_t *len)
|
||||
static bool SCSI_requestSense(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint8_t data_len = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
|
||||
if (usbd_msc_cfg.cbw.dDataLength == 0U) {
|
||||
if (g_usbd_msc.cbw.dDataLength == 0U) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usbd_msc_cfg.cbw.CB[4] < SCSIRESP_FIXEDSENSEDATA_SIZEOF) {
|
||||
data_len = usbd_msc_cfg.cbw.CB[4];
|
||||
if (g_usbd_msc.cbw.CB[4] < SCSIRESP_FIXEDSENSEDATA_SIZEOF) {
|
||||
data_len = g_usbd_msc.cbw.CB[4];
|
||||
}
|
||||
|
||||
uint8_t request_sense[SCSIRESP_FIXEDSENSEDATA_SIZEOF] = {
|
||||
@@ -193,9 +203,9 @@ static bool SCSI_requestSense(uint8_t **data, uint32_t *len)
|
||||
0x00,
|
||||
};
|
||||
|
||||
request_sense[2] = usbd_msc_cfg.sKey;
|
||||
request_sense[12] = usbd_msc_cfg.ASC;
|
||||
request_sense[13] = usbd_msc_cfg.ASQ;
|
||||
request_sense[2] = g_usbd_msc.sKey;
|
||||
request_sense[12] = g_usbd_msc.ASC;
|
||||
request_sense[13] = g_usbd_msc.ASQ;
|
||||
#if 0
|
||||
request_sense[ 2] = 0x06; /* UNIT ATTENTION */
|
||||
request_sense[12] = 0x28; /* Additional Sense Code: Not ready to ready transition */
|
||||
@@ -269,16 +279,16 @@ static bool SCSI_inquiry(uint8_t **data, uint32_t *len)
|
||||
memcpy(&inquiry[16], CONFIG_USBDEV_MSC_PRODUCT_STRING, strlen(CONFIG_USBDEV_MSC_PRODUCT_STRING));
|
||||
memcpy(&inquiry[32], CONFIG_USBDEV_MSC_VERSION_STRING, strlen(CONFIG_USBDEV_MSC_VERSION_STRING));
|
||||
|
||||
if (usbd_msc_cfg.cbw.dDataLength == 0U) {
|
||||
if (g_usbd_msc.cbw.dDataLength == 0U) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((usbd_msc_cfg.cbw.CB[1] & 0x01U) != 0U) { /* Evpd is set */
|
||||
if (usbd_msc_cfg.cbw.CB[2] == 0U) { /* Request for Supported Vital Product Data Pages*/
|
||||
if ((g_usbd_msc.cbw.CB[1] & 0x01U) != 0U) { /* Evpd is set */
|
||||
if (g_usbd_msc.cbw.CB[2] == 0U) { /* Request for Supported Vital Product Data Pages*/
|
||||
data_len = 0x06;
|
||||
memcpy(*data, (uint8_t *)inquiry00, data_len);
|
||||
} else if (usbd_msc_cfg.cbw.CB[2] == 0x80U) { /* Request for VPD page 0x80 Unit Serial Number */
|
||||
} else if (g_usbd_msc.cbw.CB[2] == 0x80U) { /* Request for VPD page 0x80 Unit Serial Number */
|
||||
data_len = 0x08;
|
||||
memcpy(*data, (uint8_t *)inquiry80, data_len);
|
||||
} else { /* Request Not supported */
|
||||
@@ -286,8 +296,8 @@ static bool SCSI_inquiry(uint8_t **data, uint32_t *len)
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (usbd_msc_cfg.cbw.CB[4] < SCSIRESP_INQUIRY_SIZEOF) {
|
||||
data_len = usbd_msc_cfg.cbw.CB[4];
|
||||
if (g_usbd_msc.cbw.CB[4] < SCSIRESP_INQUIRY_SIZEOF) {
|
||||
data_len = g_usbd_msc.cbw.CB[4];
|
||||
}
|
||||
memcpy(*data, (uint8_t *)inquiry, data_len);
|
||||
}
|
||||
@@ -298,18 +308,19 @@ static bool SCSI_inquiry(uint8_t **data, uint32_t *len)
|
||||
|
||||
static bool SCSI_startStopUnit(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
if (usbd_msc_cfg.cbw.dDataLength != 0U) {
|
||||
if (g_usbd_msc.cbw.dDataLength != 0U) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((usbd_msc_cfg.cbw.CB[4] & 0x3U) == 0x1U) /* START=1 */
|
||||
if ((g_usbd_msc.cbw.CB[4] & 0x3U) == 0x1U) /* START=1 */
|
||||
{
|
||||
//SCSI_MEDIUM_UNLOCKED;
|
||||
} else if ((usbd_msc_cfg.cbw.CB[4] & 0x3U) == 0x2U) /* START=0 and LOEJ Load Eject=1 */
|
||||
} else if ((g_usbd_msc.cbw.CB[4] & 0x3U) == 0x2U) /* START=0 and LOEJ Load Eject=1 */
|
||||
{
|
||||
//SCSI_MEDIUM_EJECTED;
|
||||
} else if ((usbd_msc_cfg.cbw.CB[4] & 0x3U) == 0x3U) /* START=1 and LOEJ Load Eject=1 */
|
||||
g_usbd_msc.popup = true;
|
||||
} else if ((g_usbd_msc.cbw.CB[4] & 0x3U) == 0x3U) /* START=1 and LOEJ Load Eject=1 */
|
||||
{
|
||||
//SCSI_MEDIUM_UNLOCKED;
|
||||
} else {
|
||||
@@ -322,11 +333,11 @@ static bool SCSI_startStopUnit(uint8_t **data, uint32_t *len)
|
||||
|
||||
static bool SCSI_preventAllowMediaRemoval(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
if (usbd_msc_cfg.cbw.dDataLength != 0U) {
|
||||
if (g_usbd_msc.cbw.dDataLength != 0U) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
if (usbd_msc_cfg.cbw.CB[4] == 0U) {
|
||||
if (g_usbd_msc.cbw.CB[4] == 0U) {
|
||||
//SCSI_MEDIUM_UNLOCKED;
|
||||
} else {
|
||||
//SCSI_MEDIUM_LOCKED;
|
||||
@@ -339,17 +350,17 @@ static bool SCSI_preventAllowMediaRemoval(uint8_t **data, uint32_t *len)
|
||||
static bool SCSI_modeSense6(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint8_t data_len = 4;
|
||||
if (usbd_msc_cfg.cbw.dDataLength == 0U) {
|
||||
if (g_usbd_msc.cbw.dDataLength == 0U) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
if (usbd_msc_cfg.cbw.CB[4] < SCSIRESP_MODEPARAMETERHDR6_SIZEOF) {
|
||||
data_len = usbd_msc_cfg.cbw.CB[4];
|
||||
if (g_usbd_msc.cbw.CB[4] < SCSIRESP_MODEPARAMETERHDR6_SIZEOF) {
|
||||
data_len = g_usbd_msc.cbw.CB[4];
|
||||
}
|
||||
|
||||
uint8_t sense6[SCSIRESP_MODEPARAMETERHDR6_SIZEOF] = { 0x03, 0x00, 0x00, 0x00 };
|
||||
|
||||
if (usbd_msc_cfg.readonly) {
|
||||
if (g_usbd_msc.readonly) {
|
||||
sense6[2] = 0x80;
|
||||
}
|
||||
memcpy(*data, (uint8_t *)sense6, data_len);
|
||||
@@ -360,13 +371,13 @@ static bool SCSI_modeSense6(uint8_t **data, uint32_t *len)
|
||||
static bool SCSI_modeSense10(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint8_t data_len = 27;
|
||||
if (usbd_msc_cfg.cbw.dDataLength == 0U) {
|
||||
if (g_usbd_msc.cbw.dDataLength == 0U) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usbd_msc_cfg.cbw.CB[8] < 27) {
|
||||
data_len = usbd_msc_cfg.cbw.CB[8];
|
||||
if (g_usbd_msc.cbw.CB[8] < 27) {
|
||||
data_len = g_usbd_msc.cbw.CB[8];
|
||||
}
|
||||
|
||||
uint8_t sense10[27] = {
|
||||
@@ -406,7 +417,7 @@ static bool SCSI_modeSense10(uint8_t **data, uint32_t *len)
|
||||
|
||||
static bool SCSI_readFormatCapacity(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
if (usbd_msc_cfg.cbw.dDataLength == 0U) {
|
||||
if (g_usbd_msc.cbw.dDataLength == 0U) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
@@ -415,15 +426,15 @@ static bool SCSI_readFormatCapacity(uint8_t **data, uint32_t *len)
|
||||
0x00,
|
||||
0x00,
|
||||
0x08, /* Capacity List Length */
|
||||
(uint8_t)((usbd_msc_cfg.scsi_blk_nbr >> 24) & 0xff),
|
||||
(uint8_t)((usbd_msc_cfg.scsi_blk_nbr >> 16) & 0xff),
|
||||
(uint8_t)((usbd_msc_cfg.scsi_blk_nbr >> 8) & 0xff),
|
||||
(uint8_t)((usbd_msc_cfg.scsi_blk_nbr >> 0) & 0xff),
|
||||
(uint8_t)((g_usbd_msc.scsi_blk_nbr >> 24) & 0xff),
|
||||
(uint8_t)((g_usbd_msc.scsi_blk_nbr >> 16) & 0xff),
|
||||
(uint8_t)((g_usbd_msc.scsi_blk_nbr >> 8) & 0xff),
|
||||
(uint8_t)((g_usbd_msc.scsi_blk_nbr >> 0) & 0xff),
|
||||
|
||||
0x02, /* Descriptor Code: Formatted Media */
|
||||
0x00,
|
||||
(uint8_t)((usbd_msc_cfg.scsi_blk_size >> 8) & 0xff),
|
||||
(uint8_t)((usbd_msc_cfg.scsi_blk_size >> 0) & 0xff),
|
||||
(uint8_t)((g_usbd_msc.scsi_blk_size >> 8) & 0xff),
|
||||
(uint8_t)((g_usbd_msc.scsi_blk_size >> 0) & 0xff),
|
||||
};
|
||||
|
||||
memcpy(*data, (uint8_t *)format_capacity, SCSIRESP_READFORMATCAPACITIES_SIZEOF);
|
||||
@@ -433,21 +444,21 @@ static bool SCSI_readFormatCapacity(uint8_t **data, uint32_t *len)
|
||||
|
||||
static bool SCSI_readCapacity10(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
if (usbd_msc_cfg.cbw.dDataLength == 0U) {
|
||||
if (g_usbd_msc.cbw.dDataLength == 0U) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t capacity10[SCSIRESP_READCAPACITY10_SIZEOF] = {
|
||||
(uint8_t)(((usbd_msc_cfg.scsi_blk_nbr - 1) >> 24) & 0xff),
|
||||
(uint8_t)(((usbd_msc_cfg.scsi_blk_nbr - 1) >> 16) & 0xff),
|
||||
(uint8_t)(((usbd_msc_cfg.scsi_blk_nbr - 1) >> 8) & 0xff),
|
||||
(uint8_t)(((usbd_msc_cfg.scsi_blk_nbr - 1) >> 0) & 0xff),
|
||||
(uint8_t)(((g_usbd_msc.scsi_blk_nbr - 1) >> 24) & 0xff),
|
||||
(uint8_t)(((g_usbd_msc.scsi_blk_nbr - 1) >> 16) & 0xff),
|
||||
(uint8_t)(((g_usbd_msc.scsi_blk_nbr - 1) >> 8) & 0xff),
|
||||
(uint8_t)(((g_usbd_msc.scsi_blk_nbr - 1) >> 0) & 0xff),
|
||||
|
||||
(uint8_t)((usbd_msc_cfg.scsi_blk_size >> 24) & 0xff),
|
||||
(uint8_t)((usbd_msc_cfg.scsi_blk_size >> 16) & 0xff),
|
||||
(uint8_t)((usbd_msc_cfg.scsi_blk_size >> 8) & 0xff),
|
||||
(uint8_t)((usbd_msc_cfg.scsi_blk_size >> 0) & 0xff),
|
||||
(uint8_t)((g_usbd_msc.scsi_blk_size >> 24) & 0xff),
|
||||
(uint8_t)((g_usbd_msc.scsi_blk_size >> 16) & 0xff),
|
||||
(uint8_t)((g_usbd_msc.scsi_blk_size >> 8) & 0xff),
|
||||
(uint8_t)((g_usbd_msc.scsi_blk_size >> 0) & 0xff),
|
||||
};
|
||||
|
||||
memcpy(*data, (uint8_t *)capacity10, SCSIRESP_READCAPACITY10_SIZEOF);
|
||||
@@ -457,113 +468,123 @@ static bool SCSI_readCapacity10(uint8_t **data, uint32_t *len)
|
||||
|
||||
static bool SCSI_read10(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
if (((usbd_msc_cfg.cbw.bmFlags & 0x80U) != 0x80U) || (usbd_msc_cfg.cbw.dDataLength == 0U)) {
|
||||
if (((g_usbd_msc.cbw.bmFlags & 0x80U) != 0x80U) || (g_usbd_msc.cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_msc_cfg.start_sector = GET_BE32(&usbd_msc_cfg.cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", usbd_msc_cfg.start_sector);
|
||||
g_usbd_msc.start_sector = GET_BE32(&g_usbd_msc.cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc.start_sector);
|
||||
|
||||
usbd_msc_cfg.nsectors = GET_BE16(&usbd_msc_cfg.cbw.CB[7]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", usbd_msc_cfg.nsectors);
|
||||
g_usbd_msc.nsectors = GET_BE16(&g_usbd_msc.cbw.CB[7]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc.nsectors);
|
||||
|
||||
if ((usbd_msc_cfg.start_sector + usbd_msc_cfg.nsectors) > usbd_msc_cfg.scsi_blk_nbr) {
|
||||
if ((g_usbd_msc.start_sector + g_usbd_msc.nsectors) > g_usbd_msc.scsi_blk_nbr) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_LBAOUTOFRANGE);
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usbd_msc_cfg.cbw.dDataLength != (usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size)) {
|
||||
if (g_usbd_msc.cbw.dDataLength != (g_usbd_msc.nsectors * g_usbd_msc.scsi_blk_size)) {
|
||||
USB_LOG_ERR("scsi_blk_len does not match with dDataLength\r\n");
|
||||
return false;
|
||||
}
|
||||
usbd_msc_cfg.stage = MSC_DATA_IN;
|
||||
g_usbd_msc.stage = MSC_DATA_IN;
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
usb_osal_mq_send(g_usbd_msc.usbd_msc_mq, MSC_DATA_IN);
|
||||
return true;
|
||||
#else
|
||||
return SCSI_processRead();
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool SCSI_read12(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
if (((usbd_msc_cfg.cbw.bmFlags & 0x80U) != 0x80U) || (usbd_msc_cfg.cbw.dDataLength == 0U)) {
|
||||
if (((g_usbd_msc.cbw.bmFlags & 0x80U) != 0x80U) || (g_usbd_msc.cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_msc_cfg.start_sector = GET_BE32(&usbd_msc_cfg.cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", usbd_msc_cfg.start_sector);
|
||||
g_usbd_msc.start_sector = GET_BE32(&g_usbd_msc.cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc.start_sector);
|
||||
|
||||
usbd_msc_cfg.nsectors = GET_BE32(&usbd_msc_cfg.cbw.CB[6]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", usbd_msc_cfg.nsectors);
|
||||
g_usbd_msc.nsectors = GET_BE32(&g_usbd_msc.cbw.CB[6]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc.nsectors);
|
||||
|
||||
if ((usbd_msc_cfg.start_sector + usbd_msc_cfg.nsectors) > usbd_msc_cfg.scsi_blk_nbr) {
|
||||
if ((g_usbd_msc.start_sector + g_usbd_msc.nsectors) > g_usbd_msc.scsi_blk_nbr) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_LBAOUTOFRANGE);
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usbd_msc_cfg.cbw.dDataLength != (usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size)) {
|
||||
if (g_usbd_msc.cbw.dDataLength != (g_usbd_msc.nsectors * g_usbd_msc.scsi_blk_size)) {
|
||||
USB_LOG_ERR("scsi_blk_len does not match with dDataLength\r\n");
|
||||
return false;
|
||||
}
|
||||
usbd_msc_cfg.stage = MSC_DATA_IN;
|
||||
g_usbd_msc.stage = MSC_DATA_IN;
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
usb_osal_mq_send(g_usbd_msc.usbd_msc_mq, MSC_DATA_IN);
|
||||
return true;
|
||||
#else
|
||||
return SCSI_processRead();
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool SCSI_write10(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint32_t data_len = 0;
|
||||
if (((usbd_msc_cfg.cbw.bmFlags & 0x80U) != 0x00U) || (usbd_msc_cfg.cbw.dDataLength == 0U)) {
|
||||
if (((g_usbd_msc.cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc.cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_msc_cfg.start_sector = GET_BE32(&usbd_msc_cfg.cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", usbd_msc_cfg.start_sector);
|
||||
g_usbd_msc.start_sector = GET_BE32(&g_usbd_msc.cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc.start_sector);
|
||||
|
||||
usbd_msc_cfg.nsectors = GET_BE16(&usbd_msc_cfg.cbw.CB[7]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", usbd_msc_cfg.nsectors);
|
||||
g_usbd_msc.nsectors = GET_BE16(&g_usbd_msc.cbw.CB[7]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc.nsectors);
|
||||
|
||||
data_len = usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size;
|
||||
if ((usbd_msc_cfg.start_sector + usbd_msc_cfg.nsectors) > usbd_msc_cfg.scsi_blk_nbr) {
|
||||
data_len = g_usbd_msc.nsectors * g_usbd_msc.scsi_blk_size;
|
||||
if ((g_usbd_msc.start_sector + g_usbd_msc.nsectors) > g_usbd_msc.scsi_blk_nbr) {
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usbd_msc_cfg.cbw.dDataLength != data_len) {
|
||||
if (g_usbd_msc.cbw.dDataLength != data_len) {
|
||||
return false;
|
||||
}
|
||||
usbd_msc_cfg.stage = MSC_DATA_OUT;
|
||||
g_usbd_msc.stage = MSC_DATA_OUT;
|
||||
data_len = MIN(data_len, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, usbd_msc_cfg.block_buffer, data_len);
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, g_usbd_msc.block_buffer, data_len);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SCSI_write12(uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint32_t data_len = 0;
|
||||
if (((usbd_msc_cfg.cbw.bmFlags & 0x80U) != 0x00U) || (usbd_msc_cfg.cbw.dDataLength == 0U)) {
|
||||
if (((g_usbd_msc.cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc.cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_msc_cfg.start_sector = GET_BE32(&usbd_msc_cfg.cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", usbd_msc_cfg.start_sector);
|
||||
g_usbd_msc.start_sector = GET_BE32(&g_usbd_msc.cbw.CB[2]); /* Logical Block Address of First Block */
|
||||
USB_LOG_DBG("lba: 0x%04x\r\n", g_usbd_msc.start_sector);
|
||||
|
||||
usbd_msc_cfg.nsectors = GET_BE32(&usbd_msc_cfg.cbw.CB[6]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", usbd_msc_cfg.nsectors);
|
||||
g_usbd_msc.nsectors = GET_BE32(&g_usbd_msc.cbw.CB[6]); /* Number of Blocks to transfer */
|
||||
USB_LOG_DBG("nsectors: 0x%02x\r\n", g_usbd_msc.nsectors);
|
||||
|
||||
data_len = usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size;
|
||||
if ((usbd_msc_cfg.start_sector + usbd_msc_cfg.nsectors) > usbd_msc_cfg.scsi_blk_nbr) {
|
||||
data_len = g_usbd_msc.nsectors * g_usbd_msc.scsi_blk_size;
|
||||
if ((g_usbd_msc.start_sector + g_usbd_msc.nsectors) > g_usbd_msc.scsi_blk_nbr) {
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usbd_msc_cfg.cbw.dDataLength != data_len) {
|
||||
if (g_usbd_msc.cbw.dDataLength != data_len) {
|
||||
return false;
|
||||
}
|
||||
usbd_msc_cfg.stage = MSC_DATA_OUT;
|
||||
g_usbd_msc.stage = MSC_DATA_OUT;
|
||||
data_len = MIN(data_len, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, usbd_msc_cfg.block_buffer, data_len);
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, g_usbd_msc.block_buffer, data_len);
|
||||
return true;
|
||||
}
|
||||
/* do not use verify to reduce code size */
|
||||
@@ -574,41 +595,41 @@ static bool SCSI_verify10(uint8_t **data, uint32_t *len)
|
||||
uint32_t lba = 0;
|
||||
uint32_t blk_num = 0;
|
||||
|
||||
if ((usbd_msc_cfg.cbw.CB[1] & 0x02U) == 0x00U) {
|
||||
if ((g_usbd_msc.cbw.CB[1] & 0x02U) == 0x00U) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((usbd_msc_cfg.cbw.bmFlags & 0x80U) != 0x00U) || (usbd_msc_cfg.cbw.dDataLength == 0U)) {
|
||||
if (((g_usbd_msc.cbw.bmFlags & 0x80U) != 0x00U) || (g_usbd_msc.cbw.dDataLength == 0U)) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((usbd_msc_cfg.cbw.CB[1] & 0x02U) == 0x02U) {
|
||||
if ((g_usbd_msc.cbw.CB[1] & 0x02U) == 0x02U) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDFIELDINCBA);
|
||||
return false; /* Error, Verify Mode Not supported*/
|
||||
}
|
||||
|
||||
lba = GET_BE32(&usbd_msc_cfg.cbw.CB[2]);
|
||||
lba = GET_BE32(&g_usbd_msc.cbw.CB[2]);
|
||||
USB_LOG_DBG("lba: 0x%x\r\n", lba);
|
||||
|
||||
usbd_msc_cfg.scsi_blk_addr = lba * usbd_msc_cfg.scsi_blk_size;
|
||||
g_usbd_msc.scsi_blk_addr = lba * g_usbd_msc.scsi_blk_size;
|
||||
|
||||
/* Number of Blocks to transfer */
|
||||
blk_num = GET_BE16(&usbd_msc_cfg.cbw.CB[7]);
|
||||
blk_num = GET_BE16(&g_usbd_msc.cbw.CB[7]);
|
||||
|
||||
USB_LOG_DBG("num (block) : 0x%x\r\n", blk_num);
|
||||
usbd_msc_cfg.scsi_blk_len = blk_num * usbd_msc_cfg.scsi_blk_size;
|
||||
g_usbd_msc.scsi_blk_len = blk_num * g_usbd_msc.scsi_blk_size;
|
||||
|
||||
if ((lba + blk_num) > usbd_msc_cfg.scsi_blk_nbr) {
|
||||
if ((lba + blk_num) > g_usbd_msc.scsi_blk_nbr) {
|
||||
USB_LOG_ERR("LBA out of range\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usbd_msc_cfg.cbw.dDataLength != usbd_msc_cfg.scsi_blk_len) {
|
||||
if (g_usbd_msc.cbw.dDataLength != g_usbd_msc.scsi_blk_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_msc_cfg.stage = MSC_DATA_OUT;
|
||||
g_usbd_msc.stage = MSC_DATA_OUT;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -617,23 +638,23 @@ static bool SCSI_processRead(void)
|
||||
{
|
||||
uint32_t transfer_len;
|
||||
|
||||
USB_LOG_DBG("read lba:%d\r\n", usbd_msc_cfg.start_sector);
|
||||
USB_LOG_DBG("read lba:%d\r\n", g_usbd_msc.start_sector);
|
||||
|
||||
transfer_len = MIN(usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
transfer_len = MIN(g_usbd_msc.nsectors * g_usbd_msc.scsi_blk_size, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
|
||||
if (usbd_msc_sector_read(usbd_msc_cfg.start_sector, usbd_msc_cfg.block_buffer, transfer_len) != 0) {
|
||||
if (usbd_msc_sector_read(g_usbd_msc.start_sector, g_usbd_msc.block_buffer, transfer_len) != 0) {
|
||||
SCSI_SetSenseData(SCSI_KCQHE_UREINRESERVEDAREA);
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, usbd_msc_cfg.block_buffer, transfer_len);
|
||||
usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, g_usbd_msc.block_buffer, transfer_len);
|
||||
|
||||
usbd_msc_cfg.start_sector += (transfer_len / usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_cfg.nsectors -= (transfer_len / usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_cfg.csw.dDataResidue -= transfer_len;
|
||||
g_usbd_msc.start_sector += (transfer_len / g_usbd_msc.scsi_blk_size);
|
||||
g_usbd_msc.nsectors -= (transfer_len / g_usbd_msc.scsi_blk_size);
|
||||
g_usbd_msc.csw.dDataResidue -= transfer_len;
|
||||
|
||||
if (usbd_msc_cfg.nsectors == 0) {
|
||||
usbd_msc_cfg.stage = MSC_SEND_CSW;
|
||||
if (g_usbd_msc.nsectors == 0) {
|
||||
g_usbd_msc.stage = MSC_SEND_CSW;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -642,22 +663,22 @@ static bool SCSI_processRead(void)
|
||||
static bool SCSI_processWrite(uint32_t nbytes)
|
||||
{
|
||||
uint32_t data_len = 0;
|
||||
USB_LOG_DBG("write lba:%d\r\n", usbd_msc_cfg.start_sector);
|
||||
USB_LOG_DBG("write lba:%d\r\n", g_usbd_msc.start_sector);
|
||||
|
||||
if (usbd_msc_sector_write(usbd_msc_cfg.start_sector, usbd_msc_cfg.block_buffer, nbytes) != 0) {
|
||||
if (usbd_msc_sector_write(g_usbd_msc.start_sector, g_usbd_msc.block_buffer, nbytes) != 0) {
|
||||
SCSI_SetSenseData(SCSI_KCQHE_WRITEFAULT);
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_msc_cfg.start_sector += (nbytes / usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_cfg.nsectors -= (nbytes / usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_cfg.csw.dDataResidue -= nbytes;
|
||||
g_usbd_msc.start_sector += (nbytes / g_usbd_msc.scsi_blk_size);
|
||||
g_usbd_msc.nsectors -= (nbytes / g_usbd_msc.scsi_blk_size);
|
||||
g_usbd_msc.csw.dDataResidue -= nbytes;
|
||||
|
||||
if (usbd_msc_cfg.nsectors == 0) {
|
||||
if (g_usbd_msc.nsectors == 0) {
|
||||
usbd_msc_send_csw(CSW_STATUS_CMD_PASSED);
|
||||
} else {
|
||||
data_len = MIN(usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, usbd_msc_cfg.block_buffer, data_len);
|
||||
data_len = MIN(g_usbd_msc.nsectors * g_usbd_msc.scsi_blk_size, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, g_usbd_msc.block_buffer, data_len);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -665,7 +686,7 @@ static bool SCSI_processWrite(uint32_t nbytes)
|
||||
|
||||
static bool SCSI_CBWDecode(uint32_t nbytes)
|
||||
{
|
||||
uint8_t *buf2send = usbd_msc_cfg.block_buffer;
|
||||
uint8_t *buf2send = g_usbd_msc.block_buffer;
|
||||
uint32_t len2send = 0;
|
||||
bool ret = false;
|
||||
|
||||
@@ -675,15 +696,15 @@ static bool SCSI_CBWDecode(uint32_t nbytes)
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_msc_cfg.csw.dTag = usbd_msc_cfg.cbw.dTag;
|
||||
usbd_msc_cfg.csw.dDataResidue = usbd_msc_cfg.cbw.dDataLength;
|
||||
g_usbd_msc.csw.dTag = g_usbd_msc.cbw.dTag;
|
||||
g_usbd_msc.csw.dDataResidue = g_usbd_msc.cbw.dDataLength;
|
||||
|
||||
if ((usbd_msc_cfg.cbw.bLUN > 1) || (usbd_msc_cfg.cbw.dSignature != MSC_CBW_Signature) || (usbd_msc_cfg.cbw.bCBLength < 1) || (usbd_msc_cfg.cbw.bCBLength > 16)) {
|
||||
if ((g_usbd_msc.cbw.bLUN > 1) || (g_usbd_msc.cbw.dSignature != MSC_CBW_Signature) || (g_usbd_msc.cbw.bCBLength < 1) || (g_usbd_msc.cbw.bCBLength > 16)) {
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
return false;
|
||||
} else {
|
||||
USB_LOG_DBG("Decode CB:0x%02x\r\n", usbd_msc_cfg.cbw.CB[0]);
|
||||
switch (usbd_msc_cfg.cbw.CB[0]) {
|
||||
USB_LOG_DBG("Decode CB:0x%02x\r\n", g_usbd_msc.cbw.CB[0]);
|
||||
switch (g_usbd_msc.cbw.CB[0]) {
|
||||
case SCSI_CMD_TESTUNITREADY:
|
||||
ret = SCSI_testUnitReady(&buf2send, &len2send);
|
||||
break;
|
||||
@@ -730,13 +751,13 @@ static bool SCSI_CBWDecode(uint32_t nbytes)
|
||||
|
||||
default:
|
||||
SCSI_SetSenseData(SCSI_KCQIR_INVALIDCOMMAND);
|
||||
USB_LOG_WRN("unsupported cmd:0x%02x\r\n", usbd_msc_cfg.cbw.CB[0]);
|
||||
USB_LOG_WRN("unsupported cmd:0x%02x\r\n", g_usbd_msc.cbw.CB[0]);
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret) {
|
||||
if (usbd_msc_cfg.stage == MSC_READ_CBW) {
|
||||
if (g_usbd_msc.stage == MSC_READ_CBW) {
|
||||
if (len2send) {
|
||||
USB_LOG_DBG("Send info len:%d\r\n", len2send);
|
||||
usbd_msc_send_info(buf2send, len2send);
|
||||
@@ -750,21 +771,26 @@ static bool SCSI_CBWDecode(uint32_t nbytes)
|
||||
|
||||
void mass_storage_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
switch (usbd_msc_cfg.stage) {
|
||||
switch (g_usbd_msc.stage) {
|
||||
case MSC_READ_CBW:
|
||||
if (SCSI_CBWDecode(nbytes) == false) {
|
||||
USB_LOG_ERR("Command:0x%02x decode err\r\n", usbd_msc_cfg.cbw.CB[0]);
|
||||
USB_LOG_ERR("Command:0x%02x decode err\r\n", g_usbd_msc.cbw.CB[0]);
|
||||
usbd_msc_bot_abort();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case MSC_DATA_OUT:
|
||||
switch (usbd_msc_cfg.cbw.CB[0]) {
|
||||
switch (g_usbd_msc.cbw.CB[0]) {
|
||||
case SCSI_CMD_WRITE10:
|
||||
case SCSI_CMD_WRITE12:
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
g_usbd_msc.nbytes = nbytes;
|
||||
usb_osal_mq_send(g_usbd_msc.usbd_msc_mq, MSC_DATA_OUT);
|
||||
#else
|
||||
if (SCSI_processWrite(nbytes) == false) {
|
||||
usbd_msc_send_csw(CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -777,15 +803,19 @@ void mass_storage_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
|
||||
void mass_storage_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
switch (usbd_msc_cfg.stage) {
|
||||
switch (g_usbd_msc.stage) {
|
||||
case MSC_DATA_IN:
|
||||
switch (usbd_msc_cfg.cbw.CB[0]) {
|
||||
switch (g_usbd_msc.cbw.CB[0]) {
|
||||
case SCSI_CMD_READ10:
|
||||
case SCSI_CMD_READ12:
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
usb_osal_mq_send(g_usbd_msc.usbd_msc_mq, MSC_DATA_IN);
|
||||
#else
|
||||
if (SCSI_processRead() == false) {
|
||||
usbd_msc_send_csw(CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -798,9 +828,9 @@ void mass_storage_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
|
||||
/*the host has received the CSW*/
|
||||
case MSC_WAIT_CSW:
|
||||
usbd_msc_cfg.stage = MSC_READ_CBW;
|
||||
g_usbd_msc.stage = MSC_READ_CBW;
|
||||
USB_LOG_DBG("Start reading cbw\r\n");
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, (uint8_t *)&usbd_msc_cfg.cbw, USB_SIZEOF_MSC_CBW);
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, (uint8_t *)&g_usbd_msc.cbw, USB_SIZEOF_MSC_CBW);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -808,6 +838,32 @@ void mass_storage_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
static void usbdev_msc_thread(void *argument)
|
||||
{
|
||||
uintptr_t event;
|
||||
int ret;
|
||||
|
||||
while (1) {
|
||||
ret = usb_osal_mq_recv(g_usbd_msc.usbd_msc_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
USB_LOG_DBG("%d\r\n", event);
|
||||
if (event == MSC_DATA_OUT) {
|
||||
if (SCSI_processWrite(g_usbd_msc.nbytes) == false) {
|
||||
usbd_msc_send_csw(CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
}
|
||||
} else if (event == MSC_DATA_IN) {
|
||||
if (SCSI_processRead() == false) {
|
||||
usbd_msc_send_csw(CSW_STATUS_CMD_FAILED); /* send fail status to host,and the host will retry*/
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct usbd_interface *usbd_msc_init_intf(struct usbd_interface *intf, const uint8_t out_ep, const uint8_t in_ep)
|
||||
{
|
||||
intf->class_interface_handler = msc_storage_class_interface_request_handler;
|
||||
@@ -823,19 +879,34 @@ struct usbd_interface *usbd_msc_init_intf(struct usbd_interface *intf, const uin
|
||||
usbd_add_endpoint(&mass_ep_data[MSD_OUT_EP_IDX]);
|
||||
usbd_add_endpoint(&mass_ep_data[MSD_IN_EP_IDX]);
|
||||
|
||||
memset((uint8_t *)&usbd_msc_cfg, 0, sizeof(struct usbd_msc_cfg_priv));
|
||||
memset((uint8_t *)&g_usbd_msc, 0, sizeof(struct usbd_msc_priv));
|
||||
|
||||
usbd_msc_get_cap(0, &usbd_msc_cfg.scsi_blk_nbr, &usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_get_cap(0, &g_usbd_msc.scsi_blk_nbr, &g_usbd_msc.scsi_blk_size);
|
||||
|
||||
if (usbd_msc_cfg.scsi_blk_size > CONFIG_USBDEV_MSC_BLOCK_SIZE) {
|
||||
if (g_usbd_msc.scsi_blk_size > CONFIG_USBDEV_MSC_BLOCK_SIZE) {
|
||||
USB_LOG_ERR("msc block buffer overflow\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
g_usbd_msc.usbd_msc_mq = usb_osal_mq_create(1);
|
||||
if (g_usbd_msc.usbd_msc_mq == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
g_usbd_msc.usbd_msc_thread = usb_osal_thread_create("usbd_msc", CONFIG_USBDEV_MSC_STACKSIZE, CONFIG_USBDEV_MSC_PRIO, usbdev_msc_thread, NULL);
|
||||
if (g_usbd_msc.usbd_msc_thread == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return intf;
|
||||
}
|
||||
|
||||
void usbd_msc_set_readonly(bool readonly)
|
||||
{
|
||||
usbd_msc_cfg.readonly = readonly;
|
||||
}
|
||||
g_usbd_msc.readonly = readonly;
|
||||
}
|
||||
|
||||
bool usbd_msc_set_popup(void)
|
||||
{
|
||||
return g_usbd_msc.popup;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ int usbd_msc_sector_read(uint32_t sector, uint8_t *buffer, uint32_t length);
|
||||
int usbd_msc_sector_write(uint32_t sector, uint8_t *buffer, uint32_t length);
|
||||
|
||||
void usbd_msc_set_readonly(bool readonly);
|
||||
bool usbd_msc_set_popup(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -9,33 +9,35 @@
|
||||
|
||||
#define DEV_FORMAT "/dev/sd%c"
|
||||
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[32];
|
||||
|
||||
static int usbh_msc_devno_alloc(struct usbh_msc *msc_class)
|
||||
static struct usbh_msc g_msc_class[CONFIG_USBHOST_MAX_MSC_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
static struct usbh_msc_modeswitch_config *g_msc_modeswitch_config = NULL;
|
||||
|
||||
static struct usbh_msc *usbh_msc_class_alloc(void)
|
||||
{
|
||||
int devno;
|
||||
|
||||
for (devno = 0; devno < 26; devno++) {
|
||||
uint32_t bitno = 1 << devno;
|
||||
if ((g_devinuse & bitno) == 0) {
|
||||
g_devinuse |= bitno;
|
||||
msc_class->sdchar = 'a' + devno;
|
||||
return 0;
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_MSC_CLASS; devno++) {
|
||||
if ((g_devinuse & (1 << devno)) == 0) {
|
||||
g_devinuse |= (1 << devno);
|
||||
memset(&g_msc_class[devno], 0, sizeof(struct usbh_msc));
|
||||
g_msc_class[devno].sdchar = 'a' + devno;
|
||||
return &g_msc_class[devno];
|
||||
}
|
||||
}
|
||||
|
||||
return -EMFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_msc_devno_free(struct usbh_msc *msc_class)
|
||||
static void usbh_msc_class_free(struct usbh_msc *msc_class)
|
||||
{
|
||||
int devno = msc_class->sdchar - 'a';
|
||||
|
||||
if (devno >= 0 && devno < 26) {
|
||||
if (devno >= 0 && devno < 32) {
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
memset(msc_class, 0, sizeof(struct usbh_msc));
|
||||
}
|
||||
|
||||
static int usbh_msc_get_maxlun(struct usbh_msc *msc_class, uint8_t *buffer)
|
||||
@@ -53,36 +55,32 @@ static int usbh_msc_get_maxlun(struct usbh_msc *msc_class, uint8_t *buffer)
|
||||
|
||||
static void usbh_msc_cbw_dump(struct CBW *cbw)
|
||||
{
|
||||
#if 0
|
||||
int i;
|
||||
|
||||
USB_LOG_INFO("CBW:\r\n");
|
||||
USB_LOG_INFO(" signature: 0x%08x\r\n", (unsigned int)cbw->dSignature);
|
||||
USB_LOG_INFO(" tag: 0x%08x\r\n", (unsigned int)cbw->dTag);
|
||||
USB_LOG_INFO(" datlen: 0x%08x\r\n", (unsigned int)cbw->dDataLength);
|
||||
USB_LOG_INFO(" flags: 0x%02x\r\n", cbw->bmFlags);
|
||||
USB_LOG_INFO(" lun: 0x%02x\r\n", cbw->bLUN);
|
||||
USB_LOG_INFO(" cblen: 0x%02x\r\n", cbw->bCBLength);
|
||||
USB_LOG_DBG("CBW:\r\n");
|
||||
USB_LOG_DBG(" signature: 0x%08x\r\n", (unsigned int)cbw->dSignature);
|
||||
USB_LOG_DBG(" tag: 0x%08x\r\n", (unsigned int)cbw->dTag);
|
||||
USB_LOG_DBG(" datlen: 0x%08x\r\n", (unsigned int)cbw->dDataLength);
|
||||
USB_LOG_DBG(" flags: 0x%02x\r\n", cbw->bmFlags);
|
||||
USB_LOG_DBG(" lun: 0x%02x\r\n", cbw->bLUN);
|
||||
USB_LOG_DBG(" cblen: 0x%02x\r\n", cbw->bCBLength);
|
||||
|
||||
USB_LOG_INFO("CB:\r\n");
|
||||
USB_LOG_DBG("CB:\r\n");
|
||||
for (i = 0; i < cbw->bCBLength; i += 8) {
|
||||
USB_LOG_INFO(" 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\r\n",
|
||||
cbw->CB[i], cbw->CB[i + 1], cbw->CB[i + 2],
|
||||
cbw->CB[i + 3], cbw->CB[i + 4], cbw->CB[i + 5],
|
||||
cbw->CB[i + 6], cbw->CB[i + 7]);
|
||||
USB_LOG_DBG(" 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\r\n",
|
||||
cbw->CB[i], cbw->CB[i + 1], cbw->CB[i + 2],
|
||||
cbw->CB[i + 3], cbw->CB[i + 4], cbw->CB[i + 5],
|
||||
cbw->CB[i + 6], cbw->CB[i + 7]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void usbh_msc_csw_dump(struct CSW *csw)
|
||||
{
|
||||
#if 0
|
||||
USB_LOG_INFO("CSW:\r\n");
|
||||
USB_LOG_INFO(" signature: 0x%08x\r\n", (unsigned int)csw->dSignature);
|
||||
USB_LOG_INFO(" tag: 0x%08x\r\n", (unsigned int)csw->dTag);
|
||||
USB_LOG_INFO(" residue: 0x%08x\r\n", (unsigned int)csw->dDataResidue);
|
||||
USB_LOG_INFO(" status: 0x%02x\r\n", csw->bStatus);
|
||||
#endif
|
||||
USB_LOG_DBG("CSW:\r\n");
|
||||
USB_LOG_DBG(" signature: 0x%08x\r\n", (unsigned int)csw->dSignature);
|
||||
USB_LOG_DBG(" tag: 0x%08x\r\n", (unsigned int)csw->dTag);
|
||||
USB_LOG_DBG(" residue: 0x%08x\r\n", (unsigned int)csw->dDataResidue);
|
||||
USB_LOG_DBG(" status: 0x%02x\r\n", csw->bStatus);
|
||||
}
|
||||
|
||||
static inline int usbh_msc_bulk_in_transfer(struct usbh_msc *msc_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
|
||||
@@ -113,9 +111,65 @@ static inline int usbh_msc_bulk_out_transfer(struct usbh_msc *msc_class, uint8_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class)
|
||||
int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, struct CSW *csw, uint8_t *buffer)
|
||||
{
|
||||
int nbytes;
|
||||
|
||||
usbh_msc_cbw_dump(cbw);
|
||||
|
||||
/* Send the CBW */
|
||||
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes < 0) {
|
||||
USB_LOG_ERR("cbw transfer error\r\n");
|
||||
goto __err_exit;
|
||||
}
|
||||
|
||||
if (cbw->dDataLength != 0) {
|
||||
if (cbw->CB[0] == SCSI_CMD_WRITE10) {
|
||||
nbytes = usbh_msc_bulk_out_transfer(msc_class, buffer, cbw->dDataLength, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
} else if (cbw->CB[0] == SCSI_CMD_READCAPACITY10) {
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, buffer, cbw->dDataLength, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Save the capacity information */
|
||||
msc_class->blocknum = GET_BE32(&buffer[0]) + 1;
|
||||
msc_class->blocksize = GET_BE32(&buffer[4]);
|
||||
}
|
||||
} else {
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, buffer, cbw->dDataLength, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
}
|
||||
|
||||
if (nbytes < 0) {
|
||||
USB_LOG_ERR("msc data transfer error\r\n");
|
||||
goto __err_exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Receive the CSW */
|
||||
memset(csw, 0, USB_SIZEOF_MSC_CSW);
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, (uint8_t *)csw, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes < 0) {
|
||||
USB_LOG_ERR("csw transfer error\r\n");
|
||||
goto __err_exit;
|
||||
}
|
||||
|
||||
usbh_msc_csw_dump(csw);
|
||||
|
||||
/* check csw status */
|
||||
if (csw->dSignature != MSC_CSW_Signature) {
|
||||
USB_LOG_ERR("csw signature error\r\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (csw->bStatus != 0) {
|
||||
USB_LOG_ERR("csw bStatus %d\r\n", csw->bStatus);
|
||||
return -EINVAL;
|
||||
}
|
||||
__err_exit:
|
||||
return nbytes < 0 ? (int)nbytes : 0;
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class)
|
||||
{
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
@@ -126,22 +180,11 @@ static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class)
|
||||
cbw->bCBLength = SCSICMD_TESTUNITREADY_SIZEOF;
|
||||
cbw->CB[0] = SCSI_CMD_TESTUNITREADY;
|
||||
|
||||
usbh_msc_cbw_dump(cbw);
|
||||
/* Send the CBW */
|
||||
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Receive the CSW */
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
usbh_msc_csw_dump((struct CSW *)g_msc_buf);
|
||||
}
|
||||
}
|
||||
return nbytes < 0 ? (int)nbytes : 0;
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, NULL);
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
|
||||
{
|
||||
int nbytes;
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
@@ -150,31 +193,16 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
cbw->bmFlags = 0x80;
|
||||
cbw->bCBLength = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
|
||||
cbw->dDataLength = SCSICMD_REQUESTSENSE_SIZEOF;
|
||||
cbw->dDataLength = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
|
||||
cbw->bCBLength = SCSICMD_REQUESTSENSE_SIZEOF;
|
||||
cbw->CB[0] = SCSI_CMD_REQUESTSENSE;
|
||||
cbw->CB[4] = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
|
||||
|
||||
usbh_msc_cbw_dump(cbw);
|
||||
/* Send the CBW */
|
||||
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Receive the sense data response */
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, g_msc_buf, SCSIRESP_FIXEDSENSEDATA_SIZEOF, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Receive the CSW */
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
usbh_msc_csw_dump((struct CSW *)g_msc_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nbytes < 0 ? (int)nbytes : 0;
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf);
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
|
||||
{
|
||||
int nbytes;
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
@@ -188,26 +216,11 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
|
||||
cbw->CB[0] = SCSI_CMD_INQUIRY;
|
||||
cbw->CB[4] = SCSIRESP_INQUIRY_SIZEOF;
|
||||
|
||||
usbh_msc_cbw_dump(cbw);
|
||||
/* Send the CBW */
|
||||
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Receive the sense data response */
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, g_msc_buf, SCSIRESP_INQUIRY_SIZEOF, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Receive the CSW */
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
usbh_msc_csw_dump((struct CSW *)g_msc_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nbytes < 0 ? (int)nbytes : 0;
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf);
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
|
||||
{
|
||||
int nbytes;
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
@@ -220,29 +233,11 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
|
||||
cbw->bCBLength = SCSICMD_READCAPACITY10_SIZEOF;
|
||||
cbw->CB[0] = SCSI_CMD_READCAPACITY10;
|
||||
|
||||
usbh_msc_cbw_dump(cbw);
|
||||
/* Send the CBW */
|
||||
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Receive the sense data response */
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, g_msc_buf, SCSIRESP_READCAPACITY10_SIZEOF, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Save the capacity information */
|
||||
msc_class->blocknum = GET_BE32(&g_msc_buf[0]) + 1;
|
||||
msc_class->blocksize = GET_BE32(&g_msc_buf[4]);
|
||||
/* Receive the CSW */
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
usbh_msc_csw_dump((struct CSW *)g_msc_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nbytes < 0 ? (int)nbytes : 0;
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, g_msc_buf);
|
||||
}
|
||||
|
||||
int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors)
|
||||
{
|
||||
int nbytes;
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
@@ -257,26 +252,11 @@ int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, con
|
||||
SET_BE32(&cbw->CB[2], start_sector);
|
||||
SET_BE16(&cbw->CB[7], nsectors);
|
||||
|
||||
usbh_msc_cbw_dump(cbw);
|
||||
/* Send the CBW */
|
||||
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Send the user data */
|
||||
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)buffer, msc_class->blocksize * nsectors, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Receive the CSW */
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
usbh_msc_csw_dump((struct CSW *)g_msc_buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nbytes < 0 ? (int)nbytes : 0;
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer);
|
||||
}
|
||||
|
||||
int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors)
|
||||
{
|
||||
int nbytes;
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
@@ -292,36 +272,42 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
|
||||
SET_BE32(&cbw->CB[2], start_sector);
|
||||
SET_BE16(&cbw->CB[7], nsectors);
|
||||
|
||||
usbh_msc_cbw_dump(cbw);
|
||||
/* Send the CBW */
|
||||
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Receive the user data */
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, (uint8_t *)buffer, msc_class->blocksize * nsectors, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
/* Receive the CSW */
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, g_msc_buf, USB_SIZEOF_MSC_CSW, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
if (nbytes >= 0) {
|
||||
usbh_msc_csw_dump((struct CSW *)g_msc_buf);
|
||||
}
|
||||
}
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, (uint8_t *)buffer);
|
||||
}
|
||||
|
||||
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config)
|
||||
{
|
||||
if (config) {
|
||||
g_msc_modeswitch_config = config;
|
||||
} else {
|
||||
g_msc_modeswitch_config = NULL;
|
||||
}
|
||||
return nbytes < 0 ? (int)nbytes : 0;
|
||||
}
|
||||
|
||||
void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t *message)
|
||||
{
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf;
|
||||
|
||||
memcpy(g_msc_buf, message, 31);
|
||||
|
||||
usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf, NULL);
|
||||
}
|
||||
|
||||
static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
struct usbh_msc_modeswitch_config *config;
|
||||
|
||||
struct usbh_msc *msc_class = usb_malloc(sizeof(struct usbh_msc));
|
||||
struct usbh_msc *msc_class = usbh_msc_class_alloc();
|
||||
if (msc_class == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc msc_class\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(msc_class, 0, sizeof(struct usbh_msc));
|
||||
usbh_msc_devno_alloc(msc_class);
|
||||
msc_class->hport = hport;
|
||||
msc_class->intf = intf;
|
||||
|
||||
@@ -343,11 +329,32 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
}
|
||||
}
|
||||
|
||||
if (g_msc_modeswitch_config) {
|
||||
uint8_t num = 0;
|
||||
while (1) {
|
||||
config = &g_msc_modeswitch_config[num];
|
||||
if (config) {
|
||||
if ((hport->device_desc.idVendor == config->vid) &&
|
||||
(hport->device_desc.idProduct == config->pid)) {
|
||||
USB_LOG_INFO("%s usb_modeswitch enable\r\n", config->name);
|
||||
usbh_msc_modeswitch(msc_class, config->message_content);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = usbh_msc_scsi_testunitready(msc_class);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to scsi_testunitready\r\n");
|
||||
return ret;
|
||||
ret = usbh_msc_scsi_requestsense(msc_class);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to scsi_testunitready\r\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = usbh_msc_scsi_inquiry(msc_class);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to scsi_inquiry\r\n");
|
||||
@@ -382,8 +389,6 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)hport->config.intf[intf].priv;
|
||||
|
||||
if (msc_class) {
|
||||
usbh_msc_devno_free(msc_class);
|
||||
|
||||
if (msc_class->bulkin) {
|
||||
usbh_pipe_free(msc_class->bulkin);
|
||||
}
|
||||
@@ -392,12 +397,12 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(msc_class->bulkout);
|
||||
}
|
||||
|
||||
usbh_msc_stop(msc_class);
|
||||
memset(msc_class, 0, sizeof(struct usbh_msc));
|
||||
usb_free(msc_class);
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0')
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister MSC Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_msc_stop(msc_class);
|
||||
}
|
||||
|
||||
usbh_msc_class_free(msc_class);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -405,12 +410,10 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
__WEAK void usbh_msc_run(struct usbh_msc *msc_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__WEAK void usbh_msc_stop(struct usbh_msc *msc_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const struct usbh_class_driver msc_class_driver = {
|
||||
|
||||
@@ -22,6 +22,14 @@ struct usbh_msc {
|
||||
uint16_t blocksize; /* Block size of USB mass storage device */
|
||||
};
|
||||
|
||||
struct usbh_msc_modeswitch_config {
|
||||
const char *name;
|
||||
uint16_t vid; /* Vendor ID (for vendor/product specific devices) */
|
||||
uint16_t pid; /* Product ID (for vendor/product specific devices) */
|
||||
const uint8_t *message_content;
|
||||
};
|
||||
|
||||
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config);
|
||||
int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors);
|
||||
int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors);
|
||||
|
||||
|
||||
@@ -437,9 +437,8 @@ struct mtp_container_response {
|
||||
#define MTP_DESCRIPTOR_LEN (9 + 7 + 7 + 7)
|
||||
|
||||
// clang-format off
|
||||
#ifndef CONFIG_USB_HS
|
||||
#define MTP_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep, int_ep, str_idx) \
|
||||
/* Interface */ \
|
||||
#define MTP_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep, int_ep, wMaxPacketSize, str_idx) \
|
||||
/* Interface */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bInterfaceNumber */ \
|
||||
@@ -453,13 +452,13 @@ struct mtp_container_response {
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
out_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x40, 0x00, /* wMaxPacketSize */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x40, 0x00, /* wMaxPacketSize */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
@@ -467,37 +466,6 @@ struct mtp_container_response {
|
||||
0x03, /* bmAttributes */ \
|
||||
0x1c, 0x00, /* wMaxPacketSize */ \
|
||||
0x06 /* bInterval */
|
||||
#else
|
||||
#define MTP_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep, int_ep, str_idx) \
|
||||
/* Interface */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x03, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_MASS_STORAGE, /* bInterfaceClass */ \
|
||||
USB_MTP_SUB_CLASS, /* bInterfaceSubClass */ \
|
||||
USB_MTP_PROTOCOL, /* bInterfaceProtocol */ \
|
||||
str_idx, /* iInterface */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
out_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x00, 0x02, /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x00, 0x02, /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
int_ep, /* bEndpointAddress */ \
|
||||
0x03, /* bmAttributes */ \
|
||||
0x1c, 0x00, /* wMaxPacketSize */ \
|
||||
0x06 /* bInterval */
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
#endif /* USB_MTP_H */
|
||||
|
||||
@@ -16,7 +16,7 @@ enum Stage {
|
||||
MTP_WAIT_RESPONSE = 4,
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION struct usbd_mtp {
|
||||
USB_NOCACHE_RAM_SECTION struct usbd_mtp_priv {
|
||||
USB_MEM_ALIGNX struct mtp_container_command con_command;
|
||||
USB_MEM_ALIGNX struct mtp_container_data con_data;
|
||||
USB_MEM_ALIGNX struct mtp_container_response con_response;
|
||||
|
||||
@@ -21,37 +21,22 @@ static int usbh_mtp_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
}
|
||||
|
||||
memset(mtp_class, 0, sizeof(struct usbh_mtp));
|
||||
|
||||
mtp_class->hport = hport;
|
||||
mtp_class->ctrl_intf = intf;
|
||||
mtp_class->data_intf = intf + 1;
|
||||
mtp_class->intf = intf;
|
||||
|
||||
hport->config.intf[intf].priv = mtp_class;
|
||||
hport->config.intf[intf + 1].priv = NULL;
|
||||
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
|
||||
|
||||
#ifdef CONFIG_USBHOST_MTP_NOTIFY
|
||||
ep_desc = &hport->config.intf[intf].ep[0].ep_desc;
|
||||
ep_cfg.ep_addr = ep_desc->bEndpointAddress;
|
||||
ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
|
||||
ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
|
||||
ep_cfg.ep_interval = ep_desc->bInterval;
|
||||
ep_cfg.hport = hport;
|
||||
usbh_pipe_alloc(&mtp_class->intin, &ep_cfg);
|
||||
|
||||
ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc;
|
||||
usbh_hport_activate_epx(&mtp_class->intin, hport, ep_desc);
|
||||
#endif
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf + 1].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf + 1].ep[i].ep_desc;
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf + 1].altsetting[0].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf + 1].altsetting[0].ep[i].ep_desc;
|
||||
|
||||
ep_cfg.ep_addr = ep_desc->bEndpointAddress;
|
||||
ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
|
||||
ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;;
|
||||
ep_cfg.ep_interval = ep_desc->bInterval;
|
||||
ep_cfg.hport = hport;
|
||||
if (ep_desc->bEndpointAddress & 0x80) {
|
||||
usbh_pipe_alloc(&mtp_class->bulkin, &ep_cfg);
|
||||
usbh_hport_activate_epx(&mtp_class->bulkin, hport, ep_desc);
|
||||
} else {
|
||||
usbh_pipe_alloc(&mtp_class->bulkout, &ep_cfg);
|
||||
usbh_hport_activate_epx(&mtp_class->bulkout, hport, ep_desc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,14 +62,12 @@ static int usbh_mtp_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(mtp_class->bulkout);
|
||||
}
|
||||
|
||||
usb_free(mtp_class);
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0')
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister MTP Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
}
|
||||
|
||||
memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN);
|
||||
hport->config.intf[intf].priv = NULL;
|
||||
hport->config.intf[intf + 1].priv = NULL;
|
||||
memset(mtp_class, 0, sizeof(struct usbh_mtp));
|
||||
usb_free(mtp_class);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_printer.h"
|
||||
|
||||
struct printer_cfg_priv {
|
||||
uint8_t *device_id;
|
||||
struct usbd_printer_priv {
|
||||
const uint8_t *device_id;
|
||||
uint8_t device_id_len;
|
||||
uint8_t port_status;
|
||||
} usbd_printer_cfg;
|
||||
} g_usbd_printer;
|
||||
|
||||
static int printer_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
@@ -19,7 +20,8 @@ static int printer_class_interface_request_handler(struct usb_setup_packet *setu
|
||||
|
||||
switch (setup->bRequest) {
|
||||
case PRINTER_REQUEST_GET_DEVICE_ID:
|
||||
|
||||
memcpy(*data, g_usbd_printer.device_id, g_usbd_printer.device_id_len);
|
||||
*len = g_usbd_printer.device_id_len;
|
||||
break;
|
||||
case PRINTER_REQUEST_GET_PORT_SATTUS:
|
||||
|
||||
@@ -46,18 +48,14 @@ static void printer_notify_handler(uint8_t event, void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_interface *usbd_printer_alloc_intf(void)
|
||||
struct usbd_interface *usbd_printer_init_intf(struct usbd_interface *intf, const uint8_t *device_id, uint8_t device_id_len)
|
||||
{
|
||||
struct usbd_interface *intf = usb_malloc(sizeof(struct usbd_interface));
|
||||
if (intf == NULL) {
|
||||
USB_LOG_ERR("no mem to alloc intf\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
intf->class_interface_handler = printer_class_interface_request_handler;
|
||||
intf->class_endpoint_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = printer_notify_handler;
|
||||
|
||||
g_usbd_printer.device_id = device_id;
|
||||
g_usbd_printer.device_id_len = device_id_len;
|
||||
return intf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Alloc printer interface driver */
|
||||
struct usbd_interface *usbd_printer_alloc_intf(void);
|
||||
/* Init printer interface driver */
|
||||
struct usbd_interface *usbd_printer_init_intf(struct usbd_interface *intf, const uint8_t *device_id, uint8_t device_id_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -8,6 +8,34 @@
|
||||
|
||||
#define DEV_FORMAT "/dev/printer"
|
||||
|
||||
static struct usbh_printer g_printer_class[CONFIG_USBHOST_MAX_PRINTER_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
static struct usbh_printer *usbh_printer_class_alloc(void)
|
||||
{
|
||||
int devno;
|
||||
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_PRINTER_CLASS; devno++) {
|
||||
if ((g_devinuse & (1 << devno)) == 0) {
|
||||
g_devinuse |= (1 << devno);
|
||||
memset(&g_printer_class[devno], 0, sizeof(struct usbh_printer));
|
||||
g_printer_class[devno].minor = devno;
|
||||
return &g_printer_class[devno];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_printer_class_free(struct usbh_printer *printer_class)
|
||||
{
|
||||
int devno = printer_class->minor;
|
||||
|
||||
if (devno >= 0 && devno < 32) {
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
memset(printer_class, 0, sizeof(struct usbh_printer));
|
||||
}
|
||||
|
||||
static int usbh_printer_get_device_id(struct usbh_printer *printer_class, uint8_t *buffer)
|
||||
{
|
||||
struct usb_setup_packet *setup = &printer_class->hport->setup;
|
||||
@@ -56,31 +84,24 @@ static int usbh_printer_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
|
||||
struct usbh_printer *printer_class = usb_malloc(sizeof(struct usbh_printer));
|
||||
struct usbh_printer *printer_class = usbh_printer_class_alloc();
|
||||
if (printer_class == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc printer_class\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(printer_class, 0, sizeof(struct usbh_printer));
|
||||
|
||||
printer_class->hport = hport;
|
||||
printer_class->intf = intf;
|
||||
|
||||
hport->config.intf[intf].priv = printer_class;
|
||||
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf + 1].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf + 1].ep[i].ep_desc;
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf + 1].altsetting[0].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf + 1].altsetting[0].ep[i].ep_desc;
|
||||
|
||||
ep_cfg.ep_addr = ep_desc->bEndpointAddress;
|
||||
ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
|
||||
ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
|
||||
ep_cfg.ep_interval = ep_desc->bInterval;
|
||||
ep_cfg.hport = hport;
|
||||
if (ep_desc->bEndpointAddress & 0x80) {
|
||||
usbh_pipe_alloc(&printer_class->bulkin, &ep_cfg);
|
||||
usbh_hport_activate_epx(&printer_class->bulkin, hport, ep_desc);
|
||||
} else {
|
||||
usbh_pipe_alloc(&printer_class->bulkout, &ep_cfg);
|
||||
usbh_hport_activate_epx(&printer_class->bulkout, hport, ep_desc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +111,7 @@ static int usbh_printer_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
USB_LOG_INFO("Register Printer Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_printer_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
@@ -108,13 +129,11 @@ static int usbh_printer_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(printer_class->bulkout);
|
||||
}
|
||||
|
||||
usb_free(printer_class);
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0')
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister Printer Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
}
|
||||
|
||||
memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN);
|
||||
hport->config.intf[intf].priv = NULL;
|
||||
usbh_printer_class_free(printer_class);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -12,6 +12,7 @@ struct usbh_printer {
|
||||
struct usbh_hubport *hport;
|
||||
|
||||
uint8_t intf; /* interface number */
|
||||
uint8_t minor;
|
||||
usbh_pipe_t bulkin; /* BULK IN endpoint */
|
||||
usbh_pipe_t bulkout; /* BULK OUT endpoint */
|
||||
};
|
||||
|
||||
@@ -3,43 +3,47 @@
|
||||
|
||||
#define DEV_FORMAT "/dev/xxx"
|
||||
|
||||
static struct usbh_xxx g_xxx_class[CONFIG_USBHOST_MAX_CUSTOM_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
static struct usbh_xxx *usbh_xxx_class_alloc(void)
|
||||
{
|
||||
int devno;
|
||||
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_CUSTOM_CLASS; devno++) {
|
||||
if ((g_devinuse & (1 << devno)) == 0) {
|
||||
g_devinuse |= (1 << devno);
|
||||
memset(&g_xxx_class[devno], 0, sizeof(struct usbh_xxx));
|
||||
g_xxx_class[devno].minor = devno;
|
||||
return &g_xxx_class[devno];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_xxx_class_free(struct usbh_xxx *xxx_class)
|
||||
{
|
||||
int devno = xxx_class->minor;
|
||||
|
||||
if (devno >= 0 && devno < 32) {
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
memset(xxx_class, 0, sizeof(struct usbh_xxx));
|
||||
}
|
||||
|
||||
static int usbh_xxx_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
struct usbh_endpoint_cfg ep_cfg = { 0 };
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
|
||||
struct usbh_xxx *xxx_class = usb_malloc(sizeof(struct usbh_xxx));
|
||||
struct usbh_xxx *xxx_class = usbh_xxx_class_alloc();
|
||||
if (xxx_class == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc xxx_class\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(xxx_class, 0, sizeof(struct usbh_xxx));
|
||||
|
||||
xxx_class->hport = hport;
|
||||
xxx_class->intf = intf;
|
||||
|
||||
hport->config.intf[intf].priv = xxx_class;
|
||||
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
|
||||
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf + 1].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf + 1].ep[i].ep_desc;
|
||||
|
||||
ep_cfg.ep_addr = ep_desc->bEndpointAddress;
|
||||
ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
|
||||
ep_cfg.ep_mps = ep_desc->wMaxPacketSize;
|
||||
ep_cfg.ep_interval = ep_desc->bInterval;
|
||||
ep_cfg.hport = hport;
|
||||
if (ep_desc->bEndpointAddress & 0x80) {
|
||||
usbh_pipe_alloc(&rndis_class->bulkin, &ep_cfg);
|
||||
} else {
|
||||
usbh_pipe_alloc(&rndis_class->bulkout, &ep_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -58,17 +62,24 @@ static int usbh_xxx_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(xxx_class->bulkout);
|
||||
}
|
||||
|
||||
usb_free(xxx_class);
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister xxx Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_xxx_stop(xxx_class);
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Unregister xxx Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
memset(hport->config.intf[intf].devname, 0, CONFIG_USBHOST_DEV_NAMELEN);
|
||||
|
||||
hport->config.intf[intf].priv = NULL;
|
||||
usbh_xxx_class_free(xxx_class);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
__WEAK void usbh_xxx_run(struct usbh_xxx *xxx_class)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_xxx_stop(struct usbh_xxx *xxx_class)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct usbh_class_driver xxx_class_driver = {
|
||||
.driver_name = "xxx",
|
||||
|
||||
@@ -7,8 +7,9 @@ struct usbh_xxx {
|
||||
struct usbh_hubport *hport;
|
||||
|
||||
uint8_t intf; /* interface number */
|
||||
usbh_pipe_t intin; /* INTR IN endpoint */
|
||||
usbh_pipe_t intout; /* INTR OUT endpoint */
|
||||
uint8_t minor;
|
||||
usbh_pipe_t bulkin; /* bulk IN endpoint */
|
||||
usbh_pipe_t bulkout; /* bulk OUT endpoint */
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -16,6 +16,8 @@ struct usbh_cdc_custom_air724 {
|
||||
struct usbh_urb bulkout_urb; /* Bulk OUT urb */
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_air724_buf[32];
|
||||
|
||||
static inline int usbh_air724_bulk_out_transfer(struct usbh_cdc_custom_air724 *cdc_custom_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
|
||||
{
|
||||
int ret;
|
||||
@@ -30,12 +32,26 @@ static inline int usbh_air724_bulk_out_transfer(struct usbh_cdc_custom_air724 *c
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int usbh_air724_bulk_in_transfer(struct usbh_cdc_custom_air724 *cdc_custom_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_urb *urb = &cdc_custom_class->bulkin_urb;
|
||||
memset(urb, 0, sizeof(struct usbh_urb));
|
||||
|
||||
usbh_bulk_urb_fill(urb, cdc_custom_class->bulkin, buffer, buflen, timeout, NULL, NULL);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret == 0) {
|
||||
ret = urb->actual_length;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_air724_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
struct usbh_endpoint_cfg ep_cfg = { 0 };
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
|
||||
/* interface 3 is AT command */
|
||||
if (intf != 3) {
|
||||
USB_LOG_WRN("ignore intf:%d\r\n", intf);
|
||||
return 0;
|
||||
@@ -65,20 +81,22 @@ int usbh_air724_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
USB_LOG_INFO("Register air724 Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
uint8_t cdc_buffer[32] = { 0x41, 0x54, 0x0d, 0x0a };
|
||||
ret = usbh_air724_bulk_out_transfer(cdc_custom_class->bulkout, cdc_buffer, 4, 3000);
|
||||
const uint8_t AT[4] = { 0x41, 0x54, 0x0d, 0x0a };
|
||||
|
||||
memcpy(g_air724_buf, AT, 4);
|
||||
ret = usbh_air724_bulk_out_transfer(cdc_custom_class, g_air724_buf, 4, 3000);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("bulk out error,ret:%d\r\n", ret);
|
||||
} else {
|
||||
USB_LOG_RAW("send over:%d\r\n", ret);
|
||||
}
|
||||
ret = usbh_air724_bulk_out_transfer(cdc_custom_class->bulkin, cdc_buffer, 10, 3000);
|
||||
ret = usbh_air724_bulk_in_transfer(cdc_custom_class, g_air724_buf, 10, 3000);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("bulk in error,ret:%d\r\n", ret);
|
||||
} else {
|
||||
USB_LOG_RAW("recv over:%d\r\n", ret);
|
||||
for (size_t i = 0; i < ret; i++) {
|
||||
USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
|
||||
USB_LOG_RAW("0x%02x ", g_air724_buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
1763
class/vendor/cp201x/usbh_cp210x.c
vendored
Normal file
1763
class/vendor/cp201x/usbh_cp210x.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
99
class/vendor/cp201x/usbh_cp210x.h
vendored
Normal file
99
class/vendor/cp201x/usbh_cp210x.h
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
|
||||
#ifndef USBH_CP210X_H
|
||||
#define USBH_CP210X_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "usbh_core.h"
|
||||
|
||||
typedef int32_t speed_t;
|
||||
typedef int32_t tcflag_t;
|
||||
|
||||
#define DRIVER_DESC "Silicon Labs CP210x RS232 serial adaptor driver"
|
||||
|
||||
struct usb_serial_port{
|
||||
uint8_t partnum;
|
||||
uint8_t ctrlpipe_rx;
|
||||
uint8_t ctrlpipe_tx;
|
||||
int32_t max_speed;
|
||||
speed_t use_actual_rate;
|
||||
uint8_t bInterfaceNumber;
|
||||
int has_swapped_line_ctl;
|
||||
};
|
||||
|
||||
|
||||
typedef unsigned char cc_t;
|
||||
|
||||
#define NCCS 19
|
||||
struct termios {
|
||||
tcflag_t c_iflag; /* input mode flags */
|
||||
tcflag_t c_oflag; /* output mode flags */
|
||||
tcflag_t c_cflag; /* control mode flags */
|
||||
tcflag_t c_lflag; /* local mode flags */
|
||||
cc_t c_cc[NCCS]; /* control characters */
|
||||
cc_t c_line; /* line discipline (== c_cc[19]) */
|
||||
speed_t c_ispeed; /* input speed */
|
||||
speed_t c_ospeed; /* output speed */
|
||||
};
|
||||
|
||||
/* Alpha has identical termios and termios2 */
|
||||
|
||||
struct termios2 {
|
||||
tcflag_t c_iflag; /* input mode flags */
|
||||
tcflag_t c_oflag; /* output mode flags */
|
||||
tcflag_t c_cflag; /* control mode flags */
|
||||
tcflag_t c_lflag; /* local mode flags */
|
||||
cc_t c_cc[NCCS]; /* control characters */
|
||||
cc_t c_line; /* line discipline (== c_cc[19]) */
|
||||
speed_t c_ispeed; /* input speed */
|
||||
speed_t c_ospeed; /* output speed */
|
||||
};
|
||||
|
||||
/* Alpha has matching termios and ktermios */
|
||||
|
||||
struct ktermios {
|
||||
tcflag_t c_iflag; /* input mode flags */
|
||||
tcflag_t c_oflag; /* output mode flags */
|
||||
tcflag_t c_cflag; /* control mode flags */
|
||||
tcflag_t c_lflag; /* local mode flags */
|
||||
cc_t c_cc[NCCS]; /* control characters */
|
||||
cc_t c_line; /* line discipline (== c_cc[19]) */
|
||||
speed_t c_ispeed; /* input speed */
|
||||
speed_t c_ospeed; /* output speed */
|
||||
};
|
||||
|
||||
|
||||
struct tty_struct{
|
||||
struct usb_serial_port driver_data;
|
||||
struct termios termios;
|
||||
};
|
||||
|
||||
int cp210x_attach(struct usb_serial_port *port);
|
||||
int cp210x_port_probe(struct usb_serial_port *port);
|
||||
void cp210x_break_ctl(struct tty_struct *tty, int break_state);
|
||||
int cp210x_open(struct tty_struct *tty);
|
||||
int cp210x_tiocmget(struct tty_struct *tty);
|
||||
void cp210x_set_termios(struct tty_struct *tty);
|
||||
void cp210x_change_speed(struct tty_struct *tty);
|
||||
void cp210x_dtr_rts(struct usb_serial_port *port, int on);
|
||||
|
||||
struct usbh_cp210x
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
|
||||
uint8_t intf;
|
||||
usbh_pipe_t bulkin;
|
||||
usbh_pipe_t bulkout;
|
||||
struct usbh_urb bulkin_urb;
|
||||
struct usbh_urb bulkout_urb;
|
||||
|
||||
struct tty_struct drv_data;
|
||||
int index;
|
||||
};
|
||||
|
||||
|
||||
/* weak defined function */
|
||||
void drv_usbh_cp210x_run(struct usbh_cp210x *p_device);
|
||||
void drv_usbh_cp210x_stop(struct usbh_cp210x *p_device);
|
||||
|
||||
#endif
|
||||
@@ -12,17 +12,13 @@ struct video_entity_info {
|
||||
uint16_t wTerminalType;
|
||||
};
|
||||
|
||||
struct usbd_video_cfg_priv {
|
||||
struct usbd_video_priv {
|
||||
struct video_probe_and_commit_controls probe;
|
||||
struct video_probe_and_commit_controls commit;
|
||||
uint8_t power_mode;
|
||||
uint8_t error_code;
|
||||
struct video_entity_info info[3];
|
||||
} usbd_video_cfg = {
|
||||
.info[0] = { .bDescriptorSubtype = VIDEO_VC_INPUT_TERMINAL_DESCRIPTOR_SUBTYPE, .bEntityId = 0x01, .wTerminalType = VIDEO_ITT_CAMERA },
|
||||
.info[1] = { .bDescriptorSubtype = VIDEO_VC_OUTPUT_TERMINAL_DESCRIPTOR_SUBTYPE, .bEntityId = 0x03, .wTerminalType = 0x00 },
|
||||
.info[2] = { .bDescriptorSubtype = VIDEO_VC_PROCESSING_UNIT_DESCRIPTOR_SUBTYPE, .bEntityId = 0x02, .wTerminalType = 0x00 },
|
||||
};
|
||||
} g_usbd_video;
|
||||
|
||||
static int usbd_video_control_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
@@ -70,7 +66,7 @@ static int usbd_video_control_unit_terminal_request_handler(struct usb_setup_pac
|
||||
uint8_t control_selector = (uint8_t)(setup->wValue >> 8);
|
||||
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
struct video_entity_info *entity_info = &usbd_video_cfg.info[i];
|
||||
struct video_entity_info *entity_info = &g_usbd_video.info[i];
|
||||
if (entity_info->bEntityId == entity_id) {
|
||||
switch (entity_info->bDescriptorSubtype) {
|
||||
case VIDEO_VC_HEADER_DESCRIPTOR_SUBTYPE:
|
||||
@@ -550,7 +546,7 @@ static int usbd_video_control_unit_terminal_request_handler(struct usb_setup_pac
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usbd_video_cfg.error_code = 0x06;
|
||||
g_usbd_video.error_code = 0x06;
|
||||
USB_LOG_WRN("Unhandled Video Class control selector 0x%02x\r\n", control_selector);
|
||||
return -1;
|
||||
}
|
||||
@@ -576,10 +572,10 @@ static int usbd_video_stream_request_handler(struct usb_setup_packet *setup, uin
|
||||
case VIDEO_VS_PROBE_CONTROL:
|
||||
switch (setup->bRequest) {
|
||||
case VIDEO_REQUEST_SET_CUR:
|
||||
//memcpy((uint8_t *)usbd_video_cfg.probe, *data, setup->wLength);
|
||||
//memcpy((uint8_t *)&g_usbd_video.probe, *data, setup->wLength);
|
||||
break;
|
||||
case VIDEO_REQUEST_GET_CUR:
|
||||
*data = (uint8_t *)&usbd_video_cfg.probe;
|
||||
memcpy(*data, (uint8_t *)&g_usbd_video.probe, setup->wLength);
|
||||
*len = sizeof(struct video_probe_and_commit_controls);
|
||||
break;
|
||||
|
||||
@@ -587,7 +583,7 @@ static int usbd_video_stream_request_handler(struct usb_setup_packet *setup, uin
|
||||
case VIDEO_REQUEST_GET_MAX:
|
||||
case VIDEO_REQUEST_GET_RES:
|
||||
case VIDEO_REQUEST_GET_DEF:
|
||||
*data = (uint8_t *)&usbd_video_cfg.probe;
|
||||
memcpy(*data, (uint8_t *)&g_usbd_video.probe, setup->wLength);
|
||||
*len = sizeof(struct video_probe_and_commit_controls);
|
||||
break;
|
||||
case VIDEO_REQUEST_GET_LEN:
|
||||
@@ -608,17 +604,17 @@ static int usbd_video_stream_request_handler(struct usb_setup_packet *setup, uin
|
||||
case VIDEO_VS_COMMIT_CONTROL:
|
||||
switch (setup->bRequest) {
|
||||
case VIDEO_REQUEST_SET_CUR:
|
||||
//memcpy((uint8_t *)usbd_video_cfg.commit, *data, setup->wLength);
|
||||
//memcpy((uint8_t *)&g_usbd_video.commit, *data, setup->wLength);
|
||||
break;
|
||||
case VIDEO_REQUEST_GET_CUR:
|
||||
*data = (uint8_t *)&usbd_video_cfg.commit;
|
||||
memcpy(*data, (uint8_t *)&g_usbd_video.commit, setup->wLength);
|
||||
*len = sizeof(struct video_probe_and_commit_controls);
|
||||
break;
|
||||
case VIDEO_REQUEST_GET_MIN:
|
||||
case VIDEO_REQUEST_GET_MAX:
|
||||
case VIDEO_REQUEST_GET_RES:
|
||||
case VIDEO_REQUEST_GET_DEF:
|
||||
*data = (uint8_t *)&usbd_video_cfg.commit;
|
||||
memcpy(*data, (uint8_t *)&g_usbd_video.commit, setup->wLength);
|
||||
*len = sizeof(struct video_probe_and_commit_controls);
|
||||
break;
|
||||
|
||||
@@ -640,7 +636,7 @@ static int usbd_video_stream_request_handler(struct usb_setup_packet *setup, uin
|
||||
case VIDEO_VS_STREAM_ERROR_CODE_CONTROL:
|
||||
switch (setup->bRequest) {
|
||||
case VIDEO_REQUEST_GET_CUR:
|
||||
*data = &usbd_video_cfg.error_code;
|
||||
(*data)[0] = g_usbd_video.error_code;
|
||||
*len = 1;
|
||||
break;
|
||||
case VIDEO_REQUEST_GET_INFO:
|
||||
@@ -684,8 +680,8 @@ static void video_notify_handler(uint8_t event, void *arg)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
usbd_video_cfg.error_code = 0;
|
||||
usbd_video_cfg.power_mode = 0;
|
||||
g_usbd_video.error_code = 0;
|
||||
g_usbd_video.power_mode = 0;
|
||||
break;
|
||||
|
||||
case USBD_EVENT_SET_INTERFACE: {
|
||||
@@ -705,41 +701,41 @@ static void video_notify_handler(uint8_t event, void *arg)
|
||||
|
||||
void usbd_video_probe_and_commit_controls_init(uint32_t dwFrameInterval, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize)
|
||||
{
|
||||
usbd_video_cfg.probe.hintUnion.bmHint = 0x01;
|
||||
usbd_video_cfg.probe.hintUnion1.bmHint = 0;
|
||||
usbd_video_cfg.probe.bFormatIndex = 1;
|
||||
usbd_video_cfg.probe.bFrameIndex = 1;
|
||||
usbd_video_cfg.probe.dwFrameInterval = dwFrameInterval;
|
||||
usbd_video_cfg.probe.wKeyFrameRate = 0;
|
||||
usbd_video_cfg.probe.wPFrameRate = 0;
|
||||
usbd_video_cfg.probe.wCompQuality = 0;
|
||||
usbd_video_cfg.probe.wCompWindowSize = 0;
|
||||
usbd_video_cfg.probe.wDelay = 0;
|
||||
usbd_video_cfg.probe.dwMaxVideoFrameSize = dwMaxVideoFrameSize;
|
||||
usbd_video_cfg.probe.dwMaxPayloadTransferSize = dwMaxPayloadTransferSize;
|
||||
usbd_video_cfg.probe.dwClockFrequency = 0;
|
||||
usbd_video_cfg.probe.bmFramingInfo = 0;
|
||||
usbd_video_cfg.probe.bPreferedVersion = 0;
|
||||
usbd_video_cfg.probe.bMinVersion = 0;
|
||||
usbd_video_cfg.probe.bMaxVersion = 0;
|
||||
g_usbd_video.probe.hintUnion.bmHint = 0x01;
|
||||
g_usbd_video.probe.hintUnion1.bmHint = 0;
|
||||
g_usbd_video.probe.bFormatIndex = 1;
|
||||
g_usbd_video.probe.bFrameIndex = 1;
|
||||
g_usbd_video.probe.dwFrameInterval = dwFrameInterval;
|
||||
g_usbd_video.probe.wKeyFrameRate = 0;
|
||||
g_usbd_video.probe.wPFrameRate = 0;
|
||||
g_usbd_video.probe.wCompQuality = 0;
|
||||
g_usbd_video.probe.wCompWindowSize = 0;
|
||||
g_usbd_video.probe.wDelay = 0;
|
||||
g_usbd_video.probe.dwMaxVideoFrameSize = dwMaxVideoFrameSize;
|
||||
g_usbd_video.probe.dwMaxPayloadTransferSize = dwMaxPayloadTransferSize;
|
||||
g_usbd_video.probe.dwClockFrequency = 0;
|
||||
g_usbd_video.probe.bmFramingInfo = 0;
|
||||
g_usbd_video.probe.bPreferedVersion = 0;
|
||||
g_usbd_video.probe.bMinVersion = 0;
|
||||
g_usbd_video.probe.bMaxVersion = 0;
|
||||
|
||||
usbd_video_cfg.commit.hintUnion.bmHint = 0x01;
|
||||
usbd_video_cfg.commit.hintUnion1.bmHint = 0;
|
||||
usbd_video_cfg.commit.bFormatIndex = 1;
|
||||
usbd_video_cfg.commit.bFrameIndex = 1;
|
||||
usbd_video_cfg.commit.dwFrameInterval = dwFrameInterval;
|
||||
usbd_video_cfg.commit.wKeyFrameRate = 0;
|
||||
usbd_video_cfg.commit.wPFrameRate = 0;
|
||||
usbd_video_cfg.commit.wCompQuality = 0;
|
||||
usbd_video_cfg.commit.wCompWindowSize = 0;
|
||||
usbd_video_cfg.commit.wDelay = 0;
|
||||
usbd_video_cfg.commit.dwMaxVideoFrameSize = dwMaxVideoFrameSize;
|
||||
usbd_video_cfg.commit.dwMaxPayloadTransferSize = dwMaxPayloadTransferSize;
|
||||
usbd_video_cfg.commit.dwClockFrequency = 0;
|
||||
usbd_video_cfg.commit.bmFramingInfo = 0;
|
||||
usbd_video_cfg.commit.bPreferedVersion = 0;
|
||||
usbd_video_cfg.commit.bMinVersion = 0;
|
||||
usbd_video_cfg.commit.bMaxVersion = 0;
|
||||
g_usbd_video.commit.hintUnion.bmHint = 0x01;
|
||||
g_usbd_video.commit.hintUnion1.bmHint = 0;
|
||||
g_usbd_video.commit.bFormatIndex = 1;
|
||||
g_usbd_video.commit.bFrameIndex = 1;
|
||||
g_usbd_video.commit.dwFrameInterval = dwFrameInterval;
|
||||
g_usbd_video.commit.wKeyFrameRate = 0;
|
||||
g_usbd_video.commit.wPFrameRate = 0;
|
||||
g_usbd_video.commit.wCompQuality = 0;
|
||||
g_usbd_video.commit.wCompWindowSize = 0;
|
||||
g_usbd_video.commit.wDelay = 0;
|
||||
g_usbd_video.commit.dwMaxVideoFrameSize = dwMaxVideoFrameSize;
|
||||
g_usbd_video.commit.dwMaxPayloadTransferSize = dwMaxPayloadTransferSize;
|
||||
g_usbd_video.commit.dwClockFrequency = 0;
|
||||
g_usbd_video.commit.bmFramingInfo = 0;
|
||||
g_usbd_video.commit.bPreferedVersion = 0;
|
||||
g_usbd_video.commit.bMinVersion = 0;
|
||||
g_usbd_video.commit.bMaxVersion = 0;
|
||||
}
|
||||
|
||||
struct usbd_interface *usbd_video_init_intf(struct usbd_interface *intf,
|
||||
@@ -752,6 +748,16 @@ struct usbd_interface *usbd_video_init_intf(struct usbd_interface *intf,
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = video_notify_handler;
|
||||
|
||||
g_usbd_video.info[0].bDescriptorSubtype = VIDEO_VC_INPUT_TERMINAL_DESCRIPTOR_SUBTYPE;
|
||||
g_usbd_video.info[0].bEntityId = 0x01;
|
||||
g_usbd_video.info[0].wTerminalType = VIDEO_ITT_CAMERA;
|
||||
g_usbd_video.info[1].bDescriptorSubtype = VIDEO_VC_OUTPUT_TERMINAL_DESCRIPTOR_SUBTYPE;
|
||||
g_usbd_video.info[1].bEntityId = 0x03;
|
||||
g_usbd_video.info[1].wTerminalType = 0x00;
|
||||
g_usbd_video.info[2].bDescriptorSubtype = VIDEO_VC_PROCESSING_UNIT_DESCRIPTOR_SUBTYPE;
|
||||
g_usbd_video.info[2].bEntityId = 0x02;
|
||||
g_usbd_video.info[2].wTerminalType = 0x00;
|
||||
|
||||
usbd_video_probe_and_commit_controls_init(dwFrameInterval, dwMaxVideoFrameSize, dwMaxPayloadTransferSize);
|
||||
return intf;
|
||||
}
|
||||
@@ -763,18 +769,18 @@ uint32_t usbd_video_mjpeg_payload_fill(uint8_t *input, uint32_t input_len, uint8
|
||||
uint32_t picture_pos = 0;
|
||||
static uint8_t uvc_header[2] = { 0x02, 0x80 };
|
||||
|
||||
packets = input_len / usbd_video_cfg.probe.dwMaxPayloadTransferSize + 1;
|
||||
last_packet_size = input_len - ((packets - 1) * (usbd_video_cfg.probe.dwMaxPayloadTransferSize - 2)) + 2;
|
||||
packets = (input_len + (g_usbd_video.probe.dwMaxPayloadTransferSize - 2) ) / (g_usbd_video.probe.dwMaxPayloadTransferSize - 2);
|
||||
last_packet_size = input_len - ((packets - 1) * (g_usbd_video.probe.dwMaxPayloadTransferSize - 2));
|
||||
|
||||
for (size_t i = 0; i < packets; i++) {
|
||||
output[usbd_video_cfg.probe.dwMaxPayloadTransferSize * i] = uvc_header[0];
|
||||
output[usbd_video_cfg.probe.dwMaxPayloadTransferSize * i + 1] = uvc_header[1];
|
||||
output[g_usbd_video.probe.dwMaxPayloadTransferSize * i] = uvc_header[0];
|
||||
output[g_usbd_video.probe.dwMaxPayloadTransferSize * i + 1] = uvc_header[1];
|
||||
if (i == (packets - 1)) {
|
||||
memcpy(&output[2 + usbd_video_cfg.probe.dwMaxPayloadTransferSize * i], &input[picture_pos], last_packet_size - 2);
|
||||
output[usbd_video_cfg.probe.dwMaxPayloadTransferSize * i + 1] |= (1 << 1);
|
||||
memcpy(&output[2 + g_usbd_video.probe.dwMaxPayloadTransferSize * i], &input[picture_pos], last_packet_size);
|
||||
output[g_usbd_video.probe.dwMaxPayloadTransferSize * i + 1] |= (1 << 1);
|
||||
} else {
|
||||
memcpy(&output[2 + usbd_video_cfg.probe.dwMaxPayloadTransferSize * i], &input[picture_pos], usbd_video_cfg.probe.dwMaxPayloadTransferSize - 2);
|
||||
picture_pos += usbd_video_cfg.probe.dwMaxPayloadTransferSize - 2;
|
||||
memcpy(&output[2 + g_usbd_video.probe.dwMaxPayloadTransferSize * i], &input[picture_pos], g_usbd_video.probe.dwMaxPayloadTransferSize - 2);
|
||||
picture_pos += g_usbd_video.probe.dwMaxPayloadTransferSize - 2;
|
||||
}
|
||||
}
|
||||
uvc_header[1] ^= 1;
|
||||
|
||||
@@ -21,117 +21,91 @@
|
||||
#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
|
||||
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
|
||||
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_video_buf[128];
|
||||
|
||||
static const char *format_type[] = { "uncompressed", "mjpeg" };
|
||||
|
||||
static int __s_r_1370705v[256] = { 0 };
|
||||
static int __s_b_1732446u[256] = { 0 };
|
||||
static int __s_g_337633u[256] = { 0 };
|
||||
static int __s_g_698001v[256] = { 0 };
|
||||
static struct usbh_video g_video_class[CONFIG_USBHOST_MAX_VIDEO_CLASS];
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
void usbh_video_inityuyv2rgb_table(void)
|
||||
{
|
||||
for (int i = 0; i < 256; i++) {
|
||||
__s_r_1370705v[i] = (1.370705 * (i - 128));
|
||||
__s_b_1732446u[i] = (1.732446 * (i - 128));
|
||||
__s_g_337633u[i] = (0.337633 * (i - 128));
|
||||
__s_g_698001v[i] = (0.698001 * (i - 128));
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_video_yuyv2rgb565(void *input, void *output, uint32_t len)
|
||||
{
|
||||
int y0, u, y1, v;
|
||||
uint8_t r, g, b;
|
||||
int val;
|
||||
|
||||
for (uint32_t i = 0; i < len / 4; i++) {
|
||||
y0 = (int)(((uint8_t *)input)[i * 4 + 0]);
|
||||
u = (int)(((uint8_t *)input)[i * 4 + 1]);
|
||||
y1 = (int)(((uint8_t *)input)[i * 4 + 2]);
|
||||
v = (int)(((uint8_t *)input)[i * 4 + 3]);
|
||||
val = y0 + __s_r_1370705v[v];
|
||||
r = (val < 0) ? 0 : ((val > 255) ? 255 : (uint8_t)val);
|
||||
val = y0 - __s_g_337633u[u] - __s_g_698001v[v];
|
||||
g = (val < 0) ? 0 : ((val > 255) ? 255 : (uint8_t)val);
|
||||
val = y0 + __s_b_1732446u[u];
|
||||
b = (val < 0) ? 0 : ((val > 255) ? 255 : (uint8_t)val);
|
||||
((uint16_t *)output)[i * 2] = (uint16_t)(b >> 3) | ((uint16_t)(g >> 2) << 5) | ((uint16_t)(r >> 3) << 11);
|
||||
val = y1 + __s_r_1370705v[v];
|
||||
r = (val < 0) ? 0 : ((val > 255) ? 255 : (uint8_t)val);
|
||||
val = y1 - __s_g_337633u[u] - __s_g_698001v[v];
|
||||
g = (val < 0) ? 0 : ((val > 255) ? 255 : (uint8_t)val);
|
||||
val = y1 + __s_b_1732446u[u];
|
||||
b = (val < 0) ? 0 : ((val > 255) ? 255 : (uint8_t)val);
|
||||
((uint16_t *)output)[i * 2 + 1] = (uint16_t)(b >> 3) | ((uint16_t)(g >> 2) << 5) | ((uint16_t)(r >> 3) << 11);
|
||||
}
|
||||
}
|
||||
|
||||
static int usbh_video_devno_alloc(struct usbh_video *video_class)
|
||||
static struct usbh_video *usbh_video_class_alloc(void)
|
||||
{
|
||||
int devno;
|
||||
|
||||
for (devno = 0; devno < 32; devno++) {
|
||||
uint32_t bitno = 1 << devno;
|
||||
if ((g_devinuse & bitno) == 0) {
|
||||
g_devinuse |= bitno;
|
||||
video_class->minor = devno;
|
||||
return 0;
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_VIDEO_CLASS; devno++) {
|
||||
if ((g_devinuse & (1 << devno)) == 0) {
|
||||
g_devinuse |= (1 << devno);
|
||||
memset(&g_video_class[devno], 0, sizeof(struct usbh_video));
|
||||
g_video_class[devno].minor = devno;
|
||||
return &g_video_class[devno];
|
||||
}
|
||||
}
|
||||
|
||||
return -EMFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_video_devno_free(struct usbh_video *video_class)
|
||||
static void usbh_video_class_free(struct usbh_video *video_class)
|
||||
{
|
||||
int devno = video_class->minor;
|
||||
|
||||
if (devno >= 0 && devno < 32) {
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
memset(video_class, 0, sizeof(struct usbh_video));
|
||||
}
|
||||
|
||||
int usbh_video_get_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
|
||||
int usbh_video_get(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
struct usb_setup_packet *setup = video_class->hport->setup;
|
||||
int ret;
|
||||
uint8_t retry;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = VIDEO_REQUEST_GET_CUR;
|
||||
setup->bRequest = request;
|
||||
setup->wValue = cs << 8;
|
||||
setup->wIndex = (entity_id << 8) | intf;
|
||||
setup->wLength = len;
|
||||
|
||||
ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
retry = 0;
|
||||
while (1) {
|
||||
ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf);
|
||||
if (ret > 0) {
|
||||
break;
|
||||
}
|
||||
retry++;
|
||||
|
||||
if (retry == 3) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
memcpy(buf, g_video_buf, len);
|
||||
|
||||
if (buf) {
|
||||
memcpy(buf, g_video_buf, len);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_video_set_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
|
||||
int usbh_video_set(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
struct usb_setup_packet *setup = video_class->hport->setup;
|
||||
int ret;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = VIDEO_REQUEST_SET_CUR;
|
||||
setup->bRequest = request;
|
||||
setup->wValue = cs << 8;
|
||||
setup->wIndex = (entity_id << 8) | intf;
|
||||
setup->wLength = len;
|
||||
|
||||
memcpy(g_video_buf, buf, len);
|
||||
|
||||
return usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf);
|
||||
ret = usbh_control_transfer(video_class->hport->ep0, setup, g_video_buf);
|
||||
usb_osal_msleep(50);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class)
|
||||
{
|
||||
return usbh_video_get_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
|
||||
return usbh_video_get(video_class, VIDEO_REQUEST_GET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
|
||||
}
|
||||
|
||||
int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex)
|
||||
@@ -139,7 +113,8 @@ int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t fo
|
||||
video_class->probe.bFormatIndex = formatindex;
|
||||
video_class->probe.bFrameIndex = frameindex;
|
||||
video_class->probe.dwMaxPayloadTransferSize = 0;
|
||||
return usbh_video_set_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
|
||||
video_class->probe.dwFrameInterval = 333333;
|
||||
return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
|
||||
}
|
||||
|
||||
int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex)
|
||||
@@ -147,7 +122,8 @@ int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t f
|
||||
memcpy(&video_class->commit, &video_class->probe, sizeof(struct video_probe_and_commit_controls));
|
||||
video_class->commit.bFormatIndex = formatindex;
|
||||
video_class->commit.bFrameIndex = frameindex;
|
||||
return usbh_video_set_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_COMMIT_CONTROL, (uint8_t *)&video_class->commit, 26);
|
||||
video_class->commit.dwFrameInterval = 333333;
|
||||
return usbh_video_set(video_class, VIDEO_REQUEST_SET_CUR, video_class->data_intf, 0x00, VIDEO_VS_COMMIT_CONTROL, (uint8_t *)&video_class->commit, 26);
|
||||
}
|
||||
|
||||
int usbh_video_open(struct usbh_video *video_class,
|
||||
@@ -164,6 +140,7 @@ int usbh_video_open(struct usbh_video *video_class,
|
||||
bool found = false;
|
||||
uint8_t formatidx = 0;
|
||||
uint8_t frameidx = 0;
|
||||
uint8_t step;
|
||||
|
||||
if (video_class->is_opened) {
|
||||
return -EMFILE;
|
||||
@@ -191,31 +168,65 @@ int usbh_video_open(struct usbh_video *video_class,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Open video step:
|
||||
* Get CUR request (probe)
|
||||
* Set CUR request (probe)
|
||||
* Get CUR request (probe)
|
||||
* Get MAX request (probe)
|
||||
* Get MIN request (probe)
|
||||
* Get CUR request (probe)
|
||||
* Set CUR request (commit)
|
||||
*
|
||||
*/
|
||||
step = 0;
|
||||
ret = usbh_videostreaming_get_cur_probe(video_class);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_videostreaming_get_cur_probe(video_class);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_videostreaming_get_cur_probe(video_class);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_videostreaming_set_cur_commit(video_class, formatidx, frameidx);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
step = 1;
|
||||
ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
|
||||
if (ret < 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
step = 2;
|
||||
ret = usbh_videostreaming_get_cur_probe(video_class);
|
||||
if (ret < 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
step = 3;
|
||||
ret = usbh_video_get(video_class, VIDEO_REQUEST_GET_MAX, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, NULL, 26);
|
||||
if (ret < 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
step = 4;
|
||||
ret = usbh_video_get(video_class, VIDEO_REQUEST_GET_MIN, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, NULL, 26);
|
||||
if (ret < 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
step = 5;
|
||||
ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
|
||||
if (ret < 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
step = 6;
|
||||
ret = usbh_videostreaming_get_cur_probe(video_class);
|
||||
if (ret < 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
step = 7;
|
||||
ret = usbh_videostreaming_set_cur_commit(video_class, formatidx, frameidx);
|
||||
if (ret < 0) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
step = 8;
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = USB_REQUEST_SET_INTERFACE;
|
||||
setup->wValue = altsetting;
|
||||
@@ -224,7 +235,7 @@ int usbh_video_open(struct usbh_video *video_class,
|
||||
|
||||
ret = usbh_control_transfer(video_class->hport->ep0, setup, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[altsetting].ep[0].ep_desc;
|
||||
@@ -242,6 +253,10 @@ int usbh_video_open(struct usbh_video *video_class,
|
||||
video_class->is_opened = true;
|
||||
video_class->current_format = format_type;
|
||||
return ret;
|
||||
|
||||
errout:
|
||||
USB_LOG_ERR("Fail to open video in step %u\r\n", step);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_video_close(struct usbh_video *video_class)
|
||||
@@ -332,14 +347,12 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
uint8_t num_of_frames = 0xff;
|
||||
uint8_t *p;
|
||||
|
||||
struct usbh_video *video_class = usb_malloc(sizeof(struct usbh_video));
|
||||
struct usbh_video *video_class = usbh_video_class_alloc();
|
||||
if (video_class == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc video_class\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(video_class, 0, sizeof(struct usbh_video));
|
||||
usbh_video_devno_alloc(video_class);
|
||||
video_class->hport = hport;
|
||||
video_class->ctrl_intf = intf;
|
||||
video_class->data_intf = intf + 1;
|
||||
@@ -427,9 +440,7 @@ static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_video_list_info(video_class);
|
||||
|
||||
snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, video_class->minor);
|
||||
#ifdef CONFIG_USBHOST_UVC_YUV2RGB
|
||||
inityuyv2rgb_table();
|
||||
#endif
|
||||
|
||||
USB_LOG_INFO("Register Video Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
usbh_video_run(video_class);
|
||||
@@ -443,8 +454,6 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
struct usbh_video *video_class = (struct usbh_video *)hport->config.intf[intf].priv;
|
||||
|
||||
if (video_class) {
|
||||
usbh_video_devno_free(video_class);
|
||||
|
||||
if (video_class->isoin) {
|
||||
usbh_pipe_free(video_class->isoin);
|
||||
}
|
||||
@@ -453,12 +462,12 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(video_class->isoout);
|
||||
}
|
||||
|
||||
usbh_video_stop(video_class);
|
||||
memset(video_class, 0, sizeof(struct usbh_video));
|
||||
usb_free(video_class);
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0')
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister Video Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_video_stop(video_class);
|
||||
}
|
||||
|
||||
usbh_video_class_free(video_class);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -474,121 +483,6 @@ static int usbh_video_streaming_disconnect(struct usbh_hubport *hport, uint8_t i
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usbh_videostreaming_parse_mjpeg(struct usbh_urb *urb, struct usbh_videostreaming *stream)
|
||||
{
|
||||
struct usbh_iso_frame_packet *iso_packet;
|
||||
uint32_t num_of_iso_packets;
|
||||
uint8_t data_offset;
|
||||
uint32_t data_len;
|
||||
uint8_t header_len = 0;
|
||||
|
||||
num_of_iso_packets = urb->num_of_iso_packets;
|
||||
iso_packet = urb->iso_packet;
|
||||
|
||||
for (uint32_t i = 0; i < num_of_iso_packets; i++) {
|
||||
/*
|
||||
uint8_t frameIdentifier : 1U;
|
||||
uint8_t endOfFrame : 1U;
|
||||
uint8_t presentationTimeStamp : 1U;
|
||||
uint8_t sourceClockReference : 1U;
|
||||
uint8_t reserved : 1U;
|
||||
uint8_t stillImage : 1U;
|
||||
uint8_t errorBit : 1U;
|
||||
uint8_t endOfHeader : 1U;
|
||||
*/
|
||||
if (iso_packet[i].actual_length == 0) { /* skip no data */
|
||||
continue;
|
||||
}
|
||||
|
||||
header_len = iso_packet[i].transfer_buffer[0];
|
||||
|
||||
if ((header_len > 12) || (header_len == 0)) { /* do not be illegal */
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
if (iso_packet[i].transfer_buffer[1] & (1 << 6)) { /* error bit, re-receive */
|
||||
stream->bufoffset = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((stream->bufoffset == 0) && (iso_packet[i].transfer_buffer[header_len] != 0xff) && (iso_packet[i].transfer_buffer[header_len + 1] != 0xd8)) {
|
||||
stream->bufoffset = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
data_offset = iso_packet[i].transfer_buffer[0];
|
||||
data_len = iso_packet[i].actual_length - iso_packet[i].transfer_buffer[0];
|
||||
|
||||
usbh_videostreaming_output(&iso_packet[i].transfer_buffer[data_offset], data_len);
|
||||
|
||||
stream->bufoffset += data_len;
|
||||
|
||||
if (iso_packet[i].transfer_buffer[1] & (1 << 1)) {
|
||||
if ((iso_packet[i].transfer_buffer[iso_packet[i].actual_length - 2] != 0xff) && (iso_packet[i].transfer_buffer[iso_packet[i].actual_length - 1] != 0xd9)) {
|
||||
stream->bufoffset = 0;
|
||||
continue;
|
||||
}
|
||||
if (stream->video_one_frame_callback) {
|
||||
stream->video_one_frame_callback(stream);
|
||||
}
|
||||
stream->bufoffset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_videostreaming_parse_yuyv2(struct usbh_urb *urb, struct usbh_videostreaming *stream)
|
||||
{
|
||||
struct usbh_iso_frame_packet *iso_packet;
|
||||
uint32_t num_of_iso_packets;
|
||||
uint8_t data_offset;
|
||||
uint32_t data_len;
|
||||
uint8_t header_len = 0;
|
||||
|
||||
num_of_iso_packets = urb->num_of_iso_packets;
|
||||
iso_packet = urb->iso_packet;
|
||||
|
||||
for (uint32_t i = 0; i < num_of_iso_packets; i++) {
|
||||
/*
|
||||
uint8_t frameIdentifier : 1U;
|
||||
uint8_t endOfFrame : 1U;
|
||||
uint8_t presentationTimeStamp : 1U;
|
||||
uint8_t sourceClockReference : 1U;
|
||||
uint8_t reserved : 1U;
|
||||
uint8_t stillImage : 1U;
|
||||
uint8_t errorBit : 1U;
|
||||
uint8_t endOfHeader : 1U;
|
||||
*/
|
||||
|
||||
if (iso_packet[i].actual_length == 0) { /* skip no data */
|
||||
continue;
|
||||
}
|
||||
|
||||
header_len = iso_packet[i].transfer_buffer[0];
|
||||
|
||||
if ((header_len > 12) || (header_len == 0)) { /* do not be illegal */
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
if (iso_packet[i].transfer_buffer[1] & (1 << 6)) { /* error bit, re-receive */
|
||||
stream->bufoffset = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
data_offset = iso_packet[i].transfer_buffer[0];
|
||||
data_len = iso_packet[i].actual_length - iso_packet[i].transfer_buffer[0];
|
||||
|
||||
usbh_videostreaming_output(&iso_packet[i].transfer_buffer[data_offset], data_len);
|
||||
stream->bufoffset += data_len;
|
||||
|
||||
if (iso_packet[i].transfer_buffer[1] & (1 << 1)) {
|
||||
if (stream->video_one_frame_callback) {
|
||||
stream->video_one_frame_callback(stream);
|
||||
}
|
||||
stream->bufoffset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__WEAK void usbh_video_run(struct usbh_video *video_class)
|
||||
{
|
||||
}
|
||||
@@ -597,10 +491,6 @@ __WEAK void usbh_video_stop(struct usbh_video *video_class)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_videostreaming_output(uint8_t *input, uint32_t input_len)
|
||||
{
|
||||
}
|
||||
|
||||
const struct usbh_class_driver video_ctrl_class_driver = {
|
||||
.driver_name = "video_ctrl",
|
||||
.connect = usbh_video_ctrl_connect,
|
||||
|
||||
@@ -17,14 +17,16 @@ struct usbh_video_resolution {
|
||||
};
|
||||
|
||||
struct usbh_video_format {
|
||||
struct usbh_video_resolution frame[8];
|
||||
struct usbh_video_resolution frame[12];
|
||||
uint8_t format_type;
|
||||
uint8_t num_of_frames;
|
||||
};
|
||||
|
||||
struct usbh_videostreaming {
|
||||
uint8_t *bufbase;
|
||||
uint32_t bufoffset;
|
||||
uint32_t buflen;
|
||||
uint16_t width;
|
||||
uint16_t heigth;
|
||||
void (*video_one_frame_callback)(struct usbh_videostreaming *stream);
|
||||
};
|
||||
|
||||
@@ -52,14 +54,8 @@ struct usbh_video {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void usbh_video_inityuyv2rgb_table(void);
|
||||
void usbh_video_yuyv2rgb565(void *input, void *output, uint32_t len);
|
||||
|
||||
int usbh_video_get_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len);
|
||||
int usbh_video_set_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len);
|
||||
int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class);
|
||||
int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex);
|
||||
int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex);
|
||||
int usbh_video_get(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len);
|
||||
int usbh_video_set(struct usbh_video *video_class, uint8_t request, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len);
|
||||
|
||||
int usbh_video_open(struct usbh_video *video_class,
|
||||
uint8_t format_type,
|
||||
@@ -70,10 +66,6 @@ int usbh_video_close(struct usbh_video *video_class);
|
||||
|
||||
void usbh_video_list_info(struct usbh_video *video_class);
|
||||
|
||||
void usbh_videostreaming_parse_mjpeg(struct usbh_urb *urb, struct usbh_videostreaming *stream);
|
||||
void usbh_videostreaming_parse_yuyv2(struct usbh_urb *urb, struct usbh_videostreaming *stream);
|
||||
void usbh_videostreaming_output(uint8_t *input, uint32_t input_len);
|
||||
|
||||
void usbh_video_run(struct usbh_video *video_class);
|
||||
void usbh_video_stop(struct usbh_video *video_class);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ static struct usbd_endpoint rndis_ep_data[3];
|
||||
#endif
|
||||
|
||||
/* Device data structure */
|
||||
struct usbd_rndis_cfg_priv {
|
||||
struct usbd_rndis_priv {
|
||||
uint32_t drv_version;
|
||||
uint32_t link_status;
|
||||
uint32_t speed;
|
||||
@@ -38,11 +38,12 @@ struct usbd_rndis_cfg_priv {
|
||||
usb_eth_stat_t eth_state;
|
||||
rndis_state_t init_state;
|
||||
uint8_t mac[6];
|
||||
} usbd_rndis_cfg = { .drv_version = 0x0001,
|
||||
.link_status = NDIS_MEDIA_STATE_DISCONNECTED,
|
||||
.speed = RNDIS_LINK_SPEED,
|
||||
.init_state = rndis_uninitialized,
|
||||
.mac = { 0x00, 0x00, 0x5E, 0x00, 0x53, 0x01 } };
|
||||
} g_usbd_rndis;
|
||||
|
||||
#if CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE < 140
|
||||
#undef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
|
||||
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44];
|
||||
@@ -174,7 +175,7 @@ static int rndis_init_cmd_handler(uint8_t *data, uint32_t len)
|
||||
resp->AfListOffset = 0;
|
||||
resp->AfListSize = 0;
|
||||
|
||||
usbd_rndis_cfg.init_state = rndis_initialized;
|
||||
g_usbd_rndis.init_state = rndis_initialized;
|
||||
|
||||
rndis_notify_rsp();
|
||||
return 0;
|
||||
@@ -187,7 +188,7 @@ static int rndis_halt_cmd_handler(uint8_t *data, uint32_t len)
|
||||
resp = ((rndis_halt_msg_t *)rndis_encapsulated_resp_buffer);
|
||||
resp->MessageLength = 0;
|
||||
|
||||
usbd_rndis_cfg.init_state = rndis_uninitialized;
|
||||
g_usbd_rndis.init_state = rndis_uninitialized;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -241,7 +242,7 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len)
|
||||
break;
|
||||
case OID_802_3_CURRENT_ADDRESS:
|
||||
case OID_802_3_PERMANENT_ADDRESS:
|
||||
RNDIS_INQUIRY_PUT(usbd_rndis_cfg.mac, 6);
|
||||
RNDIS_INQUIRY_PUT(g_usbd_rndis.mac, 6);
|
||||
infomation_len = 6;
|
||||
break;
|
||||
case OID_GEN_PHYSICAL_MEDIUM:
|
||||
@@ -253,7 +254,7 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len)
|
||||
infomation_len = 4;
|
||||
break;
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.net_filter);
|
||||
RNDIS_INQUIRY_PUT_LE32(g_usbd_rndis.net_filter);
|
||||
infomation_len = 4;
|
||||
break;
|
||||
case OID_GEN_MAXIMUM_TOTAL_SIZE:
|
||||
@@ -261,7 +262,7 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len)
|
||||
infomation_len = 4;
|
||||
break;
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.link_status);
|
||||
RNDIS_INQUIRY_PUT_LE32(g_usbd_rndis.link_status);
|
||||
infomation_len = 4;
|
||||
break;
|
||||
case OID_GEN_RNDIS_CONFIG_PARAMETER:
|
||||
@@ -301,19 +302,19 @@ static int rndis_query_cmd_handler(uint8_t *data, uint32_t len)
|
||||
infomation_len = 4;
|
||||
break;
|
||||
case OID_GEN_XMIT_OK:
|
||||
RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.eth_state.txok);
|
||||
RNDIS_INQUIRY_PUT_LE32(g_usbd_rndis.eth_state.txok);
|
||||
infomation_len = 4;
|
||||
break;
|
||||
case OID_GEN_RCV_OK:
|
||||
RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.eth_state.rxok);
|
||||
RNDIS_INQUIRY_PUT_LE32(g_usbd_rndis.eth_state.rxok);
|
||||
infomation_len = 4;
|
||||
break;
|
||||
case OID_GEN_RCV_ERROR:
|
||||
RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.eth_state.rxbad);
|
||||
RNDIS_INQUIRY_PUT_LE32(g_usbd_rndis.eth_state.rxbad);
|
||||
infomation_len = 4;
|
||||
break;
|
||||
case OID_GEN_XMIT_ERROR:
|
||||
RNDIS_INQUIRY_PUT_LE32(usbd_rndis_cfg.eth_state.txbad);
|
||||
RNDIS_INQUIRY_PUT_LE32(g_usbd_rndis.eth_state.txbad);
|
||||
infomation_len = 4;
|
||||
break;
|
||||
case OID_GEN_RCV_NO_BUFFER:
|
||||
@@ -354,7 +355,7 @@ static int rndis_set_cmd_handler(uint8_t *data, uint32_t len)
|
||||
param->ParameterValueOffset, param->ParameterValueLength);
|
||||
break;
|
||||
case OID_GEN_CURRENT_PACKET_FILTER:
|
||||
if (cmd->InformationBufferLength < sizeof(usbd_rndis_cfg.net_filter)) {
|
||||
if (cmd->InformationBufferLength < sizeof(g_usbd_rndis.net_filter)) {
|
||||
USB_LOG_WRN("PACKET_FILTER!\r\n");
|
||||
resp->Status = RNDIS_STATUS_INVALID_DATA;
|
||||
} else {
|
||||
@@ -362,12 +363,12 @@ static int rndis_set_cmd_handler(uint8_t *data, uint32_t len)
|
||||
/* Parameter starts at offset buf_offset of the req_id field */
|
||||
filter = (uint32_t *)((uint8_t *)&(cmd->RequestId) + cmd->InformationBufferOffset);
|
||||
|
||||
//usbd_rndis_cfg.net_filter = param->ParameterNameOffset;
|
||||
usbd_rndis_cfg.net_filter = *(uint32_t *)filter;
|
||||
if (usbd_rndis_cfg.net_filter) {
|
||||
usbd_rndis_cfg.init_state = rndis_data_initialized;
|
||||
//g_usbd_rndis.net_filter = param->ParameterNameOffset;
|
||||
g_usbd_rndis.net_filter = *(uint32_t *)filter;
|
||||
if (g_usbd_rndis.net_filter) {
|
||||
g_usbd_rndis.init_state = rndis_data_initialized;
|
||||
} else {
|
||||
usbd_rndis_cfg.init_state = rndis_initialized;
|
||||
g_usbd_rndis.init_state = rndis_initialized;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -393,7 +394,7 @@ static int rndis_set_cmd_handler(uint8_t *data, uint32_t len)
|
||||
|
||||
static int rndis_reset_cmd_handler(uint8_t *data, uint32_t len)
|
||||
{
|
||||
rndis_reset_msg_t *cmd = (rndis_reset_msg_t *)data;
|
||||
// rndis_reset_msg_t *cmd = (rndis_reset_msg_t *)data;
|
||||
rndis_reset_cmplt_t *resp;
|
||||
|
||||
resp = ((rndis_reset_cmplt_t *)rndis_encapsulated_resp_buffer);
|
||||
@@ -402,7 +403,7 @@ static int rndis_reset_cmd_handler(uint8_t *data, uint32_t len)
|
||||
resp->Status = RNDIS_STATUS_SUCCESS;
|
||||
resp->AddressingReset = 1;
|
||||
|
||||
usbd_rndis_cfg.init_state = rndis_uninitialized;
|
||||
g_usbd_rndis.init_state = rndis_uninitialized;
|
||||
|
||||
rndis_notify_rsp();
|
||||
|
||||
@@ -429,12 +430,12 @@ static void rndis_notify_handler(uint8_t event, void *arg)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
usbd_rndis_cfg.link_status = NDIS_MEDIA_STATE_DISCONNECTED;
|
||||
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_DISCONNECTED;
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
g_rndis_rx_data_length = 0;
|
||||
g_rndis_tx_data_length = 0;
|
||||
usbd_rndis_cfg.link_status = NDIS_MEDIA_STATE_CONNECTED;
|
||||
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_CONNECTED;
|
||||
usbd_ep_start_read(rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
|
||||
break;
|
||||
|
||||
@@ -458,7 +459,7 @@ void rndis_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
g_rndis_rx_data_buffer += hdr->DataOffset + sizeof(rndis_generic_msg_t);
|
||||
g_rndis_rx_data_length = hdr->DataLength;
|
||||
|
||||
usbd_rndis_data_recv((uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_data_length);
|
||||
usbd_rndis_data_recv_done();
|
||||
}
|
||||
|
||||
void rndis_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
@@ -506,7 +507,7 @@ int usbd_rndis_eth_tx(struct pbuf *p)
|
||||
uint8_t *buffer;
|
||||
rndis_data_packet_t *hdr;
|
||||
|
||||
if (usbd_rndis_cfg.link_status == NDIS_MEDIA_STATE_DISCONNECTED) {
|
||||
if (g_usbd_rndis.link_status == NDIS_MEDIA_STATE_DISCONNECTED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -543,7 +544,11 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
|
||||
const uint8_t in_ep,
|
||||
const uint8_t int_ep, uint8_t mac[6])
|
||||
{
|
||||
memcpy(usbd_rndis_cfg.mac, mac, 6);
|
||||
memcpy(g_usbd_rndis.mac, mac, 6);
|
||||
|
||||
g_usbd_rndis.drv_version = 0x0001;
|
||||
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_DISCONNECTED;
|
||||
g_usbd_rndis.speed = RNDIS_LINK_SPEED;
|
||||
|
||||
rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr = out_ep;
|
||||
rndis_ep_data[RNDIS_OUT_EP_IDX].ep_cb = rndis_bulk_out;
|
||||
|
||||
@@ -18,6 +18,8 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
|
||||
const uint8_t in_ep,
|
||||
const uint8_t int_ep, uint8_t mac[6]);
|
||||
|
||||
void usbd_rndis_data_recv_done(void);
|
||||
|
||||
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
struct pbuf *usbd_rndis_eth_rx(void);
|
||||
int usbd_rndis_eth_tx(struct pbuf *p);
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
#define DEV_FORMAT "/dev/rndis"
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[1024];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[4096];
|
||||
|
||||
static struct usbh_rndis g_rndis_class;
|
||||
|
||||
static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
@@ -79,9 +81,9 @@ int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid,
|
||||
setup->bRequest = CDC_REQUEST_SEND_ENCAPSULATED_COMMAND;
|
||||
setup->wValue = 0;
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = sizeof(rndis_query_msg_t);
|
||||
setup->wLength = query_len + sizeof(rndis_query_msg_t);
|
||||
|
||||
ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)&cmd);
|
||||
ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)cmd);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("oid:%08x send error, ret: %d\r\n", (unsigned int)oid, ret);
|
||||
return ret;
|
||||
@@ -131,7 +133,7 @@ static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t
|
||||
setup->bRequest = CDC_REQUEST_SEND_ENCAPSULATED_COMMAND;
|
||||
setup->wValue = 0;
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = sizeof(rndis_set_msg_t);
|
||||
setup->wLength = info_len + sizeof(rndis_set_msg_t);
|
||||
|
||||
ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)cmd);
|
||||
if (ret < 0) {
|
||||
@@ -205,7 +207,7 @@ int usbh_rndis_keepalive(struct usbh_rndis *rndis_class)
|
||||
setup->wIndex = 0;
|
||||
setup->wLength = sizeof(rndis_keepalive_msg_t);
|
||||
|
||||
ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)&cmd);
|
||||
ret = usbh_control_transfer(rndis_class->hport->ep0, setup, (uint8_t *)cmd);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("keepalive send error, ret: %d\r\n", ret);
|
||||
return ret;
|
||||
@@ -232,7 +234,6 @@ int usbh_rndis_keepalive(struct usbh_rndis *rndis_class)
|
||||
|
||||
static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
struct usbh_endpoint_cfg ep_cfg = { 0 };
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
uint32_t *oid_support_list;
|
||||
@@ -242,11 +243,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
uint8_t tmp_buffer[512];
|
||||
uint8_t data[32];
|
||||
|
||||
struct usbh_rndis *rndis_class = usb_malloc(sizeof(struct usbh_rndis));
|
||||
if (rndis_class == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc rndis_class\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
struct usbh_rndis *rndis_class = &g_rndis_class;
|
||||
|
||||
memset(rndis_class, 0, sizeof(struct usbh_rndis));
|
||||
|
||||
@@ -259,14 +256,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
#ifdef CONFIG_USBHOST_RNDIS_NOTIFY
|
||||
ep_desc = &hport->config.intf[intf].altsetting[0].ep[0].ep_desc;
|
||||
ep_cfg.ep_addr = ep_desc->bEndpointAddress;
|
||||
ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
|
||||
ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
|
||||
|
||||
ep_cfg.ep_interval = ep_desc->bInterval;
|
||||
ep_cfg.hport = hport;
|
||||
usbh_pipe_alloc(&rndis_class->intin, &ep_cfg);
|
||||
|
||||
usbh_hport_activate_epx(&rndis_class->intin, hport, ep_desc);
|
||||
#endif
|
||||
for (uint8_t i = 0; i < hport->config.intf[intf + 1].altsetting[0].intf_desc.bNumEndpoints; i++) {
|
||||
ep_desc = &hport->config.intf[intf + 1].altsetting[0].ep[i].ep_desc;
|
||||
@@ -370,7 +360,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
}
|
||||
USB_LOG_INFO("rndis set OID_802_3_MULTICAST_LIST success\r\n");
|
||||
|
||||
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
|
||||
memcpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
|
||||
|
||||
USB_LOG_INFO("Register RNDIS Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_rndis_run(rndis_class);
|
||||
@@ -395,12 +385,12 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(rndis_class->bulkout);
|
||||
}
|
||||
|
||||
usbh_rndis_stop(rndis_class);
|
||||
memset(rndis_class, 0, sizeof(struct usbh_rndis));
|
||||
usb_free(rndis_class);
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0')
|
||||
if (hport->config.intf[intf].devname[0] != '\0') {
|
||||
USB_LOG_INFO("Unregister RNDIS Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_rndis_stop(rndis_class);
|
||||
}
|
||||
|
||||
memset(rndis_class, 0, sizeof(struct usbh_rndis));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -13,7 +13,7 @@ struct usbh_rndis {
|
||||
|
||||
uint8_t ctrl_intf; /* Control interface number */
|
||||
uint8_t data_intf; /* Data interface number */
|
||||
|
||||
uint8_t minor;
|
||||
usbh_pipe_t bulkin; /* Bulk IN endpoint */
|
||||
usbh_pipe_t bulkout; /* Bulk OUT endpoint */
|
||||
usbh_pipe_t intin; /* Notify endpoint */
|
||||
|
||||
@@ -143,15 +143,37 @@ int usbd_ep_start_read(const uint8_t ep, uint8_t *data, uint32_t data_len);
|
||||
|
||||
/* usb dcd irq callback */
|
||||
|
||||
/**
|
||||
* @brief Usb connect irq callback.
|
||||
*/
|
||||
void usbd_event_connect_handler(void);
|
||||
|
||||
/**
|
||||
* @brief Usb disconnect irq callback.
|
||||
*/
|
||||
void usbd_event_disconnect_handler(void);
|
||||
|
||||
/**
|
||||
* @brief Usb resume irq callback.
|
||||
*/
|
||||
void usbd_event_resume_handler(void);
|
||||
|
||||
/**
|
||||
* @brief Usb suspend irq callback.
|
||||
*/
|
||||
void usbd_event_suspend_handler(void);
|
||||
|
||||
/**
|
||||
* @brief Usb reset irq callback.
|
||||
*/
|
||||
void usbd_event_reset_handler(void);
|
||||
|
||||
/**
|
||||
* @brief Usb setup packet recv irq callback.
|
||||
* @param[in] psetup setup packet.
|
||||
*/
|
||||
void usbd_event_ep0_setup_complete_handler(uint8_t *psetup);
|
||||
|
||||
/**
|
||||
* @brief In ep transfer complete irq callback.
|
||||
* @param[in] ep Endpoint address corresponding to the one
|
||||
@@ -159,6 +181,7 @@ void usbd_event_ep0_setup_complete_handler(uint8_t *psetup);
|
||||
* @param[in] nbytes How many nbytes have transferred.
|
||||
*/
|
||||
void usbd_event_ep_in_complete_handler(uint8_t ep, uint32_t nbytes);
|
||||
|
||||
/**
|
||||
* @brief Out ep transfer complete irq callback.
|
||||
* @param[in] ep Endpoint address corresponding to the one
|
||||
@@ -167,10 +190,6 @@ void usbd_event_ep_in_complete_handler(uint8_t ep, uint32_t nbytes);
|
||||
*/
|
||||
void usbd_event_ep_out_complete_handler(uint8_t ep, uint32_t nbytes);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#define USB_2_0 0x0200
|
||||
/* Set USB version to 2.1 so that the host will request the BOS descriptor */
|
||||
#define USB_2_1 0x0210
|
||||
#define USB_3_0 0x0300
|
||||
#define USB_3_1 0x0310
|
||||
#define USB_3_2 0x0320
|
||||
|
||||
/* Device speeds */
|
||||
#define USB_SPEED_UNKNOWN 0 /* Transfer rate not yet set */
|
||||
@@ -481,13 +484,10 @@ struct usb_msosv1_comp_id_function_descriptor {
|
||||
};
|
||||
|
||||
struct usb_msosv1_descriptor {
|
||||
uint8_t *string;
|
||||
uint8_t string_len;
|
||||
const uint8_t *string;
|
||||
uint8_t vendor_code;
|
||||
uint8_t *compat_id;
|
||||
uint16_t compat_id_len;
|
||||
uint8_t *comp_id_property;
|
||||
uint16_t comp_id_property_len;
|
||||
const uint8_t *compat_id;
|
||||
const uint8_t **comp_id_property;
|
||||
};
|
||||
|
||||
/* MS OS 2.0 Header descriptor */
|
||||
|
||||
@@ -59,7 +59,11 @@ struct usbh_urb {
|
||||
uint32_t start_frame;
|
||||
usbh_complete_callback_t complete;
|
||||
void *arg;
|
||||
#if defined(__ICCARM__) || defined(__ICCRISCV__) || defined(__ICCRX__)
|
||||
struct usbh_iso_frame_packet *iso_packet;
|
||||
#else
|
||||
struct usbh_iso_frame_packet iso_packet[0];
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -85,15 +89,15 @@ uint16_t usbh_get_frame_number(void);
|
||||
int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf);
|
||||
|
||||
/**
|
||||
* @brief reconfig control endpoint pipe.
|
||||
* @brief reconfig endpoint pipe.
|
||||
*
|
||||
* @param pipe A memory allocated for pipe.
|
||||
* @param dev_addr device address.
|
||||
* @param ep_mps control endpoint max packet size.
|
||||
* @param speed port speed
|
||||
* @param ep_mps endpoint max packet size.
|
||||
* @param mult endpoint additional transcation
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usbh_ep0_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t ep_mps, uint8_t speed);
|
||||
int usbh_ep_pipe_reconfigure(usbh_pipe_t pipe, uint8_t dev_addr, uint8_t ep_mps, uint8_t mult);
|
||||
|
||||
/**
|
||||
* @brief Allocate pipe for endpoint
|
||||
|
||||
@@ -52,25 +52,25 @@
|
||||
#if (CONFIG_USB_DBG_LEVEL >= USB_DBG_LOG)
|
||||
#define USB_LOG_DBG(fmt, ...) usb_dbg_log_line("D", 0, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define USB_LOG_DBG(...)
|
||||
#define USB_LOG_DBG(...) {}
|
||||
#endif
|
||||
|
||||
#if (CONFIG_USB_DBG_LEVEL >= USB_DBG_INFO)
|
||||
#define USB_LOG_INFO(fmt, ...) usb_dbg_log_line("I", 32, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define USB_LOG_INFO(...)
|
||||
#define USB_LOG_INFO(...) {}
|
||||
#endif
|
||||
|
||||
#if (CONFIG_USB_DBG_LEVEL >= USB_DBG_WARNING)
|
||||
#define USB_LOG_WRN(fmt, ...) usb_dbg_log_line("W", 33, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define USB_LOG_WRN(...)
|
||||
#define USB_LOG_WRN(...) {}
|
||||
#endif
|
||||
|
||||
#if (CONFIG_USB_DBG_LEVEL >= USB_DBG_ERROR)
|
||||
#define USB_LOG_ERR(fmt, ...) usb_dbg_log_line("E", 31, fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define USB_LOG_ERR(...)
|
||||
#define USB_LOG_ERR(...) {}
|
||||
#endif
|
||||
|
||||
#define USB_LOG_RAW(...) CONFIG_USB_PRINTF(__VA_ARGS__)
|
||||
@@ -82,4 +82,4 @@ void usb_assert(const char *filename, int linenum);
|
||||
usb_assert(__FILE__, __LINE__); \
|
||||
} while (0)
|
||||
|
||||
#endif /* USB_LOG_H */
|
||||
#endif /* USB_LOG_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
* Copyright (c) 2022-2023, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -44,9 +44,9 @@
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#elif defined(__ICCARM__) || defined(__ICCRX__)
|
||||
#elif defined(__ICCARM__) || defined(__ICCRX__) || defined(__ICCRISCV__)
|
||||
#ifndef __USED
|
||||
#if __ICCARM_V8
|
||||
#if defined(__ICCARM_V8) || defined (__ICCRISCV__)
|
||||
#define __USED __attribute__((used))
|
||||
#else
|
||||
#define __USED __root
|
||||
@@ -54,7 +54,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef __WEAK
|
||||
#if __ICCARM_V8
|
||||
#if defined(__ICCARM_V8) || defined (__ICCRISCV__)
|
||||
#define __WEAK __attribute__((weak))
|
||||
#else
|
||||
#define __WEAK _Pragma("__weak")
|
||||
@@ -62,7 +62,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED
|
||||
#if __ICCARM_V8
|
||||
#if defined(__ICCARM_V8) || defined (__ICCRISCV__)
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
@@ -71,7 +71,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_STRUCT
|
||||
#if __ICCARM_V8
|
||||
#if defined(__ICCARM_V8) || defined (__ICCRISCV__)
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
@@ -80,7 +80,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_UNION
|
||||
#if __ICCARM_V8
|
||||
#if defined(__ICCARM_V8) || defined (__ICCRISCV__)
|
||||
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
@@ -89,7 +89,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef __ALIGNED
|
||||
#if __ICCARM_V8
|
||||
#if defined(__ICCARM_V8) || defined (__ICCRISCV__)
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#elif (__VER__ >= 7080000)
|
||||
/* Needs IAR language extensions */
|
||||
|
||||
511
core/usbd_core.c
511
core/usbd_core.c
@@ -6,9 +6,6 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#if defined(CONFIG_USBDEV_TX_THREAD) || defined(CONFIG_USBDEV_RX_THREAD)
|
||||
#include "usb_osal.h"
|
||||
#endif
|
||||
|
||||
/* general descriptor field offsets */
|
||||
#define DESC_bLength 0 /** Length offset */
|
||||
@@ -32,7 +29,7 @@ struct usbd_tx_rx_msg {
|
||||
usbd_endpoint_callback cb;
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION struct usbd_core_cfg_priv {
|
||||
USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
|
||||
/** Setup packet */
|
||||
USB_MEM_ALIGNX struct usb_setup_packet setup;
|
||||
/** Pointer to data buffer */
|
||||
@@ -45,41 +42,28 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_cfg_priv {
|
||||
bool zlp_flag;
|
||||
/** Pointer to registered descriptors */
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
struct usb_descriptor *descriptors;
|
||||
const struct usb_descriptor *descriptors;
|
||||
#else
|
||||
const uint8_t *descriptors;
|
||||
#endif
|
||||
struct usb_msosv1_descriptor *msosv1_desc;
|
||||
struct usb_msosv2_descriptor *msosv2_desc;
|
||||
struct usb_bos_descriptor *bos_desc;
|
||||
/* Buffer used for storing standard, class and vendor request data */
|
||||
USB_MEM_ALIGNX uint8_t req_data[CONFIG_USBDEV_REQUEST_BUFFER_LEN];
|
||||
|
||||
/** Variable to check whether the usb has been configured */
|
||||
bool configured;
|
||||
/** Currently selected configuration */
|
||||
uint8_t configuration;
|
||||
uint8_t speed;
|
||||
#ifdef CONFIG_USBDEV_TEST_MODE
|
||||
bool test_mode;
|
||||
#endif
|
||||
struct usbd_interface *intf[8];
|
||||
uint8_t intf_offset;
|
||||
} usbd_core_cfg;
|
||||
|
||||
usb_slist_t usbd_intf_head = USB_SLIST_OBJECT_INIT(usbd_intf_head);
|
||||
|
||||
static struct usb_msosv1_descriptor *msosv1_desc;
|
||||
static struct usb_msosv2_descriptor *msosv2_desc;
|
||||
static struct usb_bos_descriptor *bos_desc;
|
||||
|
||||
struct usbd_tx_rx_msg tx_msg[USB_EP_IN_NUM];
|
||||
struct usbd_tx_rx_msg rx_msg[USB_EP_OUT_NUM];
|
||||
|
||||
#if defined(CONFIG_USBDEV_TX_THREAD)
|
||||
usb_osal_mq_t usbd_tx_mq;
|
||||
usb_osal_thread_t usbd_tx_thread;
|
||||
#endif
|
||||
#if defined(CONFIG_USBDEV_RX_THREAD)
|
||||
usb_osal_mq_t usbd_rx_mq;
|
||||
usb_osal_thread_t usbd_rx_thread;
|
||||
#endif
|
||||
struct usbd_tx_rx_msg tx_msg[USB_EP_IN_NUM];
|
||||
struct usbd_tx_rx_msg rx_msg[USB_EP_OUT_NUM];
|
||||
} g_usbd_core;
|
||||
|
||||
static void usbd_class_event_notify_handler(uint8_t event, void *arg);
|
||||
|
||||
@@ -96,7 +80,7 @@ static void usbd_print_setup(struct usb_setup_packet *setup)
|
||||
|
||||
static bool is_device_configured(void)
|
||||
{
|
||||
return (usbd_core_cfg.configuration != 0);
|
||||
return (g_usbd_core.configuration != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -171,24 +155,24 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l
|
||||
|
||||
switch (type) {
|
||||
case USB_DESCRIPTOR_TYPE_DEVICE:
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->device_descriptor;
|
||||
*len = usbd_core_cfg.descriptors->device_descriptor[0];
|
||||
*data = (uint8_t *)g_usbd_core.descriptors->device_descriptor;
|
||||
*len = g_usbd_core.descriptors->device_descriptor[0];
|
||||
break;
|
||||
case USB_DESCRIPTOR_TYPE_CONFIGURATION:
|
||||
usbd_core_cfg.speed = usbd_get_port_speed(0);
|
||||
if (usbd_core_cfg.speed == USB_SPEED_HIGH) {
|
||||
if (usbd_core_cfg.descriptors->hs_config_descriptor) {
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->hs_config_descriptor;
|
||||
*len = (usbd_core_cfg.descriptors->hs_config_descriptor[CONF_DESC_wTotalLength] |
|
||||
(usbd_core_cfg.descriptors->hs_config_descriptor[CONF_DESC_wTotalLength + 1] << 8));
|
||||
g_usbd_core.speed = usbd_get_port_speed(0);
|
||||
if (g_usbd_core.speed == USB_SPEED_HIGH) {
|
||||
if (g_usbd_core.descriptors->hs_config_descriptor) {
|
||||
*data = (uint8_t *)g_usbd_core.descriptors->hs_config_descriptor;
|
||||
*len = (g_usbd_core.descriptors->hs_config_descriptor[CONF_DESC_wTotalLength] |
|
||||
(g_usbd_core.descriptors->hs_config_descriptor[CONF_DESC_wTotalLength + 1] << 8));
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
} else {
|
||||
if (usbd_core_cfg.descriptors->fs_config_descriptor) {
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->fs_config_descriptor;
|
||||
*len = (usbd_core_cfg.descriptors->fs_config_descriptor[CONF_DESC_wTotalLength] |
|
||||
(usbd_core_cfg.descriptors->fs_config_descriptor[CONF_DESC_wTotalLength + 1] << 8));
|
||||
if (g_usbd_core.descriptors->fs_config_descriptor) {
|
||||
*data = (uint8_t *)g_usbd_core.descriptors->fs_config_descriptor;
|
||||
*len = (g_usbd_core.descriptors->fs_config_descriptor[CONF_DESC_wTotalLength] |
|
||||
(g_usbd_core.descriptors->fs_config_descriptor[CONF_DESC_wTotalLength + 1] << 8));
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
@@ -203,20 +187,20 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l
|
||||
(*data)[3] = 0x04;
|
||||
*len = 4;
|
||||
} else if (index == USB_OSDESC_STRING_DESC_INDEX) {
|
||||
if (usbd_core_cfg.descriptors->msosv1_descriptor) {
|
||||
if (g_usbd_core.descriptors->msosv1_descriptor) {
|
||||
USB_LOG_INFO("read MS OS 1.0 descriptor string\r\n");
|
||||
*data = usbd_core_cfg.descriptors->msosv1_descriptor->string;
|
||||
*len = usbd_core_cfg.descriptors->msosv1_descriptor->string_len;
|
||||
*data = g_usbd_core.descriptors->msosv1_descriptor->string;
|
||||
*len = g_usbd_core.descriptors->msosv1_descriptor->string_len;
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
if (usbd_core_cfg.descriptors->string_descriptor[index - 1]) {
|
||||
str_len = strlen((const char *)usbd_core_cfg.descriptors->string_descriptor[index - 1]);
|
||||
if (g_usbd_core.descriptors->string_descriptor[index - 1]) {
|
||||
str_len = strlen((const char *)g_usbd_core.descriptors->string_descriptor[index - 1]);
|
||||
|
||||
(*data)[0] = str_len * 2 + 2;
|
||||
(*data)[1] = 0x03;
|
||||
for (uint16_t i = 0; i < str_len; i++) {
|
||||
(*data)[i * 2 + 2] = usbd_core_cfg.descriptors->string_descriptor[index - 1][i];
|
||||
(*data)[i * 2 + 2] = g_usbd_core.descriptors->string_descriptor[index - 1][i];
|
||||
(*data)[i * 2 + 3] = 0;
|
||||
}
|
||||
|
||||
@@ -227,28 +211,28 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l
|
||||
}
|
||||
break;
|
||||
case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
|
||||
if (usbd_core_cfg.descriptors->device_quality_descriptor) {
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->device_quality_descriptor;
|
||||
*len = usbd_core_cfg.descriptors->device_quality_descriptor[0];
|
||||
if (g_usbd_core.descriptors->device_quality_descriptor) {
|
||||
*data = (uint8_t *)g_usbd_core.descriptors->device_quality_descriptor;
|
||||
*len = g_usbd_core.descriptors->device_quality_descriptor[0];
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
|
||||
break;
|
||||
case USB_DESCRIPTOR_TYPE_OTHER_SPEED:
|
||||
if (usbd_core_cfg.speed == USB_SPEED_HIGH) {
|
||||
if (usbd_core_cfg.descriptors->fs_other_speed_descriptor) {
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->fs_other_speed_descriptor;
|
||||
*len = (usbd_core_cfg.descriptors->fs_other_speed_descriptor[CONF_DESC_wTotalLength] |
|
||||
(usbd_core_cfg.descriptors->fs_other_speed_descriptor[CONF_DESC_wTotalLength] << 8));
|
||||
if (g_usbd_core.speed == USB_SPEED_HIGH) {
|
||||
if (g_usbd_core.descriptors->fs_other_speed_descriptor) {
|
||||
*data = (uint8_t *)g_usbd_core.descriptors->fs_other_speed_descriptor;
|
||||
*len = (g_usbd_core.descriptors->fs_other_speed_descriptor[CONF_DESC_wTotalLength] |
|
||||
(g_usbd_core.descriptors->fs_other_speed_descriptor[CONF_DESC_wTotalLength] << 8));
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
} else {
|
||||
if (usbd_core_cfg.descriptors->hs_other_speed_descriptor) {
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->hs_other_speed_descriptor;
|
||||
*len = (usbd_core_cfg.descriptors->hs_other_speed_descriptor[CONF_DESC_wTotalLength] |
|
||||
(usbd_core_cfg.descriptors->hs_other_speed_descriptor[CONF_DESC_wTotalLength] << 8));
|
||||
if (g_usbd_core.descriptors->hs_other_speed_descriptor) {
|
||||
*data = (uint8_t *)g_usbd_core.descriptors->hs_other_speed_descriptor;
|
||||
*len = (g_usbd_core.descriptors->hs_other_speed_descriptor[CONF_DESC_wTotalLength] |
|
||||
(g_usbd_core.descriptors->hs_other_speed_descriptor[CONF_DESC_wTotalLength] << 8));
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
@@ -285,23 +269,25 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l
|
||||
if ((type == USB_DESCRIPTOR_TYPE_STRING) && (index == USB_OSDESC_STRING_DESC_INDEX)) {
|
||||
USB_LOG_INFO("read MS OS 2.0 descriptor string\r\n");
|
||||
|
||||
if (!msosv1_desc) {
|
||||
if (!g_usbd_core.msosv1_desc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*data = (uint8_t *)msosv1_desc->string;
|
||||
*len = msosv1_desc->string_len;
|
||||
//*data = (uint8_t *)g_usbd_core.msosv1_desc->string;
|
||||
memcpy(*data, (uint8_t *)g_usbd_core.msosv1_desc->string, g_usbd_core.msosv1_desc->string[0]);
|
||||
*len = g_usbd_core.msosv1_desc->string[0];
|
||||
|
||||
return true;
|
||||
} else if (type == USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE) {
|
||||
USB_LOG_INFO("read BOS descriptor string\r\n");
|
||||
|
||||
if (!bos_desc) {
|
||||
if (!g_usbd_core.bos_desc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*data = bos_desc->string;
|
||||
*len = bos_desc->string_len;
|
||||
//*data = g_usbd_core.bos_desc->string;
|
||||
memcpy(*data, (uint8_t *)g_usbd_core.bos_desc->string, g_usbd_core.bos_desc->string_len);
|
||||
*len = g_usbd_core.bos_desc->string_len;
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
@@ -317,7 +303,7 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l
|
||||
return false;
|
||||
}
|
||||
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors;
|
||||
p = (uint8_t *)g_usbd_core.descriptors;
|
||||
|
||||
cur_index = 0U;
|
||||
|
||||
@@ -349,7 +335,7 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l
|
||||
memcpy(*data, p, *len);
|
||||
} else {
|
||||
/* nothing found */
|
||||
USB_LOG_ERR("descriptor <type:%x,index:%x> not found!\r\n", type, index);
|
||||
USB_LOG_ERR("descriptor <type:0x%02x,index:0x%02x> not found!\r\n", type, index);
|
||||
}
|
||||
|
||||
return found;
|
||||
@@ -375,13 +361,13 @@ static bool usbd_set_configuration(uint8_t config_index, uint8_t alt_setting)
|
||||
bool found = false;
|
||||
uint8_t *p;
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
if (usbd_core_cfg.speed == USB_SPEED_HIGH) {
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors->hs_config_descriptor;
|
||||
if (g_usbd_core.speed == USB_SPEED_HIGH) {
|
||||
p = (uint8_t *)g_usbd_core.descriptors->hs_config_descriptor;
|
||||
} else {
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors->fs_config_descriptor;
|
||||
p = (uint8_t *)g_usbd_core.descriptors->fs_config_descriptor;
|
||||
}
|
||||
#else
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors;
|
||||
p = (uint8_t *)g_usbd_core.descriptors;
|
||||
#endif
|
||||
/* configure endpoints for this configuration/altsetting */
|
||||
while (p[DESC_bLength] != 0U) {
|
||||
@@ -439,13 +425,13 @@ static bool usbd_set_interface(uint8_t iface, uint8_t alt_setting)
|
||||
bool ret = false;
|
||||
uint8_t *p;
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
if (usbd_core_cfg.speed == USB_SPEED_HIGH) {
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors->hs_config_descriptor;
|
||||
if (g_usbd_core.speed == USB_SPEED_HIGH) {
|
||||
p = (uint8_t *)g_usbd_core.descriptors->hs_config_descriptor;
|
||||
} else {
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors->fs_config_descriptor;
|
||||
p = (uint8_t *)g_usbd_core.descriptors->fs_config_descriptor;
|
||||
}
|
||||
#else
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors;
|
||||
p = (uint8_t *)g_usbd_core.descriptors;
|
||||
#endif
|
||||
USB_LOG_DBG("iface %u alt_setting %u\r\n", iface, alt_setting);
|
||||
|
||||
@@ -517,9 +503,14 @@ static bool usbd_std_device_req_handler(struct usb_setup_packet *setup, uint8_t
|
||||
case USB_REQUEST_CLEAR_FEATURE:
|
||||
case USB_REQUEST_SET_FEATURE:
|
||||
if (value == USB_FEATURE_REMOTE_WAKEUP) {
|
||||
if (setup->bRequest == USB_REQUEST_SET_FEATURE) {
|
||||
usbd_event_handler(USBD_EVENT_SET_REMOTE_WAKEUP);
|
||||
} else {
|
||||
usbd_event_handler(USBD_EVENT_CLR_REMOTE_WAKEUP);
|
||||
}
|
||||
} else if (value == USB_FEATURE_TEST_MODE) {
|
||||
#ifdef CONFIG_USBDEV_TEST_MODE
|
||||
usbd_core_cfg.test_mode = true;
|
||||
g_usbd_core.test_mode = true;
|
||||
usbd_execute_test_mode(setup);
|
||||
#endif
|
||||
}
|
||||
@@ -540,7 +531,7 @@ static bool usbd_std_device_req_handler(struct usb_setup_packet *setup, uint8_t
|
||||
break;
|
||||
|
||||
case USB_REQUEST_GET_CONFIGURATION:
|
||||
*data = (uint8_t *)&usbd_core_cfg.configuration;
|
||||
*data = (uint8_t *)&g_usbd_core.configuration;
|
||||
*len = 1;
|
||||
break;
|
||||
|
||||
@@ -550,10 +541,9 @@ static bool usbd_std_device_req_handler(struct usb_setup_packet *setup, uint8_t
|
||||
if (!usbd_set_configuration(value, 0)) {
|
||||
ret = false;
|
||||
} else {
|
||||
usbd_core_cfg.configuration = value;
|
||||
usbd_core_cfg.configured = true;
|
||||
g_usbd_core.configuration = value;
|
||||
usbd_class_event_notify_handler(USBD_EVENT_CONFIGURED, NULL);
|
||||
usbd_configure_done_callback();
|
||||
usbd_event_handler(USBD_EVENT_CONFIGURED);
|
||||
}
|
||||
*len = 0;
|
||||
break;
|
||||
@@ -602,14 +592,13 @@ static bool usbd_std_interface_req_handler(struct usb_setup_packet *setup,
|
||||
case USB_REQUEST_GET_DESCRIPTOR:
|
||||
if (type == 0x22) { /* HID_DESCRIPTOR_TYPE_HID_REPORT */
|
||||
USB_LOG_INFO("read hid report descriptor\r\n");
|
||||
usb_slist_t *i;
|
||||
|
||||
usb_slist_for_each(i, &usbd_intf_head)
|
||||
{
|
||||
struct usbd_interface *intf = usb_slist_entry(i, struct usbd_interface, list);
|
||||
for (uint8_t i = 0; i < g_usbd_core.intf_offset; i++) {
|
||||
struct usbd_interface *intf = g_usbd_core.intf[i];
|
||||
|
||||
if (intf->intf_num == intf_num) {
|
||||
*data = (uint8_t *)intf->hid_report_descriptor;
|
||||
if (intf && (intf->intf_num == intf_num)) {
|
||||
//*data = (uint8_t *)intf->hid_report_descriptor;
|
||||
memcpy(*data, intf->hid_report_descriptor, intf->hid_report_descriptor_len);
|
||||
*len = intf->hid_report_descriptor_len;
|
||||
return true;
|
||||
}
|
||||
@@ -753,22 +742,19 @@ static int usbd_standard_request_handler(struct usb_setup_packet *setup, uint8_t
|
||||
*/
|
||||
static int usbd_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
usb_slist_t *i;
|
||||
if ((setup->bmRequestType & USB_REQUEST_RECIPIENT_MASK) == USB_REQUEST_RECIPIENT_INTERFACE) {
|
||||
usb_slist_for_each(i, &usbd_intf_head)
|
||||
{
|
||||
struct usbd_interface *intf = usb_slist_entry(i, struct usbd_interface, list);
|
||||
for (uint8_t i = 0; i < g_usbd_core.intf_offset; i++) {
|
||||
struct usbd_interface *intf = g_usbd_core.intf[i];
|
||||
|
||||
if (intf->class_interface_handler && (intf->intf_num == (setup->wIndex & 0xFF))) {
|
||||
if (intf && intf->class_interface_handler && (intf->intf_num == (setup->wIndex & 0xFF))) {
|
||||
return intf->class_interface_handler(setup, data, len);
|
||||
}
|
||||
}
|
||||
} else if ((setup->bmRequestType & USB_REQUEST_RECIPIENT_MASK) == USB_REQUEST_RECIPIENT_ENDPOINT) {
|
||||
usb_slist_for_each(i, &usbd_intf_head)
|
||||
{
|
||||
struct usbd_interface *intf = usb_slist_entry(i, struct usbd_interface, list);
|
||||
for (uint8_t i = 0; i < g_usbd_core.intf_offset; i++) {
|
||||
struct usbd_interface *intf = g_usbd_core.intf[i];
|
||||
|
||||
if (intf->class_endpoint_handler && (intf->intf_num == ((setup->wIndex >> 8) & 0xFF))) {
|
||||
if (intf && intf->class_endpoint_handler) {
|
||||
return intf->class_endpoint_handler(setup, data, len);
|
||||
}
|
||||
}
|
||||
@@ -789,45 +775,56 @@ static int usbd_class_request_handler(struct usb_setup_packet *setup, uint8_t **
|
||||
*/
|
||||
static int usbd_vendor_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint32_t desclen;
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
if (usbd_core_cfg.descriptors->msosv1_descriptor) {
|
||||
if (setup->bRequest == usbd_core_cfg.descriptors->msosv1_descriptor->vendor_code) {
|
||||
if (g_usbd_core.descriptors->msosv1_descriptor) {
|
||||
if (setup->bRequest == g_usbd_core.descriptors->msosv1_descriptor->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
case 0x04:
|
||||
USB_LOG_INFO("get Compat ID\r\n");
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->msosv1_descriptor->compat_id;
|
||||
*len = usbd_core_cfg.descriptors->msosv1_descriptor->compat_id_len;
|
||||
desclen = g_usbd_core.msosv1_desc->compat_id[0] +
|
||||
(g_usbd_core.msosv1_desc->compat_id[1] << 8) +
|
||||
(g_usbd_core.msosv1_desc->compat_id[2] << 16) +
|
||||
(g_usbd_core.msosv1_desc->compat_id[3] << 24);
|
||||
|
||||
*data = (uint8_t *)g_usbd_core.descriptors->msosv1_descriptor->compat_id;
|
||||
*len = desclen;
|
||||
return 0;
|
||||
case 0x05:
|
||||
USB_LOG_INFO("get Compat id properties\r\n");
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->msosv1_descriptor->comp_id_property;
|
||||
*len = usbd_core_cfg.descriptors->msosv1_descriptor->comp_id_property_len;
|
||||
desclen = g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][0] +
|
||||
(g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][1] << 8) +
|
||||
(g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][2] << 16) +
|
||||
(g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][3] << 24);
|
||||
|
||||
*data = (uint8_t *)g_usbd_core.descriptors->msosv1_descriptor->comp_id_property[setup->wValue];
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (usbd_core_cfg.descriptors->msosv2_descriptor) {
|
||||
if (setup->bRequest == usbd_core_cfg.descriptors->msosv2_descriptor->vendor_code) {
|
||||
} else if (g_usbd_core.descriptors->msosv2_descriptor) {
|
||||
if (setup->bRequest == g_usbd_core.descriptors->msosv2_descriptor->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
|
||||
USB_LOG_INFO("GET MS OS 2.0 Descriptor\r\n");
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->msosv2_descriptor->compat_id;
|
||||
*len = usbd_core_cfg.descriptors->msosv2_descriptor->compat_id_len;
|
||||
*data = (uint8_t *)g_usbd_core.descriptors->msosv2_descriptor->compat_id;
|
||||
*len = g_usbd_core.descriptors->msosv2_descriptor->compat_id_len;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (usbd_core_cfg.descriptors->webusb_url_descriptor) {
|
||||
if (setup->bRequest == usbd_core_cfg.descriptors->webusb_url_descriptor->vendor_code) {
|
||||
} else if (g_usbd_core.descriptors->webusb_url_descriptor) {
|
||||
if (setup->bRequest == g_usbd_core.descriptors->webusb_url_descriptor->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
|
||||
USB_LOG_INFO("GET Webusb url Descriptor\r\n");
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->webusb_url_descriptor->string;
|
||||
*len = usbd_core_cfg.descriptors->webusb_url_descriptor->string_len;
|
||||
*data = (uint8_t *)g_usbd_core.descriptors->webusb_url_descriptor->string;
|
||||
*len = g_usbd_core.descriptors->webusb_url_descriptor->string_len;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
@@ -836,33 +833,42 @@ static int usbd_vendor_request_handler(struct usb_setup_packet *setup, uint8_t *
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (msosv1_desc) {
|
||||
if (setup->bRequest == msosv1_desc->vendor_code) {
|
||||
if (g_usbd_core.msosv1_desc) {
|
||||
if (setup->bRequest == g_usbd_core.msosv1_desc->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
case 0x04:
|
||||
USB_LOG_INFO("get Compat ID\r\n");
|
||||
*data = (uint8_t *)msosv1_desc->compat_id;
|
||||
*len = msosv1_desc->compat_id_len;
|
||||
|
||||
//*data = (uint8_t *)msosv1_desc->compat_id;
|
||||
desclen = g_usbd_core.msosv1_desc->compat_id[0] +
|
||||
(g_usbd_core.msosv1_desc->compat_id[1] << 8) +
|
||||
(g_usbd_core.msosv1_desc->compat_id[2] << 16) +
|
||||
(g_usbd_core.msosv1_desc->compat_id[3] << 24);
|
||||
memcpy(*data, g_usbd_core.msosv1_desc->compat_id, desclen);
|
||||
*len = desclen;
|
||||
return 0;
|
||||
case 0x05:
|
||||
USB_LOG_INFO("get Compat id properties\r\n");
|
||||
*data = (uint8_t *)msosv1_desc->comp_id_property;
|
||||
*len = msosv1_desc->comp_id_property_len;
|
||||
|
||||
//*data = (uint8_t *)msosv1_desc->comp_id_property[setup->wValue];
|
||||
desclen = g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][0] +
|
||||
(g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][1] << 8) +
|
||||
(g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][2] << 16) +
|
||||
(g_usbd_core.msosv1_desc->comp_id_property[setup->wValue][3] << 24);
|
||||
memcpy(*data, g_usbd_core.msosv1_desc->comp_id_property[setup->wValue], desclen);
|
||||
*len = desclen;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (msosv2_desc) {
|
||||
if (setup->bRequest == msosv2_desc->vendor_code) {
|
||||
} else if (g_usbd_core.msosv2_desc) {
|
||||
if (setup->bRequest == g_usbd_core.msosv2_desc->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
|
||||
USB_LOG_INFO("GET MS OS 2.0 Descriptor\r\n");
|
||||
*data = (uint8_t *)msosv2_desc->compat_id;
|
||||
*len = msosv2_desc->compat_id_len;
|
||||
//*data = (uint8_t *)msosv2_desc->compat_id;
|
||||
memcpy(*data, g_usbd_core.msosv2_desc->compat_id, g_usbd_core.msosv2_desc->compat_id_len);
|
||||
*len = g_usbd_core.msosv2_desc->compat_id_len;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
@@ -871,13 +877,10 @@ static int usbd_vendor_request_handler(struct usb_setup_packet *setup, uint8_t *
|
||||
}
|
||||
}
|
||||
#endif
|
||||
usb_slist_t *i;
|
||||
for (uint8_t i = 0; i < g_usbd_core.intf_offset; i++) {
|
||||
struct usbd_interface *intf = g_usbd_core.intf[i];
|
||||
|
||||
usb_slist_for_each(i, &usbd_intf_head)
|
||||
{
|
||||
struct usbd_interface *intf = usb_slist_entry(i, struct usbd_interface, list);
|
||||
|
||||
if (intf->vendor_handler && !intf->vendor_handler(setup, data, len)) {
|
||||
if (intf && intf->vendor_handler && (intf->vendor_handler(setup, data, len) == 0)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -899,11 +902,20 @@ static bool usbd_setup_request_handler(struct usb_setup_packet *setup, uint8_t *
|
||||
switch (setup->bmRequestType & USB_REQUEST_TYPE_MASK) {
|
||||
case USB_REQUEST_STANDARD:
|
||||
if (usbd_standard_request_handler(setup, data, len) < 0) {
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
if (g_usbd_core.speed == USB_SPEED_FULL) {
|
||||
if ((setup->bRequest == 0x06) && (setup->wValue == 0x0600)) {
|
||||
USB_LOG_WRN("Ignore DQD in fs\r\n"); /* Device Qualifier Descriptor */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifndef CONFIG_USB_HS
|
||||
if ((setup->bRequest == 0x06) && (setup->wValue = 0x0600)) {
|
||||
if ((setup->bRequest == 0x06) && (setup->wValue == 0x0600)) {
|
||||
USB_LOG_WRN("Ignore DQD in fs\r\n"); /* Device Qualifier Descriptor */
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
USB_LOG_ERR("standard request error\r\n");
|
||||
usbd_print_setup(setup);
|
||||
@@ -934,45 +946,49 @@ static bool usbd_setup_request_handler(struct usb_setup_packet *setup, uint8_t *
|
||||
|
||||
static void usbd_class_event_notify_handler(uint8_t event, void *arg)
|
||||
{
|
||||
usb_slist_t *i;
|
||||
usb_slist_for_each(i, &usbd_intf_head)
|
||||
{
|
||||
struct usbd_interface *intf = usb_slist_entry(i, struct usbd_interface, list);
|
||||
for (uint8_t i = 0; i < g_usbd_core.intf_offset; i++) {
|
||||
struct usbd_interface *intf = g_usbd_core.intf[i];
|
||||
|
||||
if (intf->notify_handler) {
|
||||
intf->notify_handler(event, arg);
|
||||
if (arg) {
|
||||
struct usb_interface_descriptor *desc = (struct usb_interface_descriptor *)arg;
|
||||
if (intf && intf->notify_handler && (desc->bInterfaceNumber == (intf->intf_num))) {
|
||||
intf->notify_handler(event, arg);
|
||||
}
|
||||
} else {
|
||||
if (intf && intf->notify_handler) {
|
||||
intf->notify_handler(event, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_event_connect_handler(void)
|
||||
{
|
||||
usbd_class_event_notify_handler(USBD_EVENT_CONNECTED, NULL);
|
||||
usbd_event_handler(USBD_EVENT_CONNECTED);
|
||||
}
|
||||
|
||||
void usbd_event_disconnect_handler(void)
|
||||
{
|
||||
usbd_class_event_notify_handler(USBD_EVENT_DISCONNECTED, NULL);
|
||||
usbd_event_handler(USBD_EVENT_DISCONNECTED);
|
||||
}
|
||||
|
||||
void usbd_event_resume_handler(void)
|
||||
{
|
||||
usbd_class_event_notify_handler(USBD_EVENT_RESUME, NULL);
|
||||
usbd_event_handler(USBD_EVENT_RESUME);
|
||||
}
|
||||
|
||||
void usbd_event_suspend_handler(void)
|
||||
{
|
||||
usbd_class_event_notify_handler(USBD_EVENT_SUSPEND, NULL);
|
||||
usbd_event_handler(USBD_EVENT_SUSPEND);
|
||||
}
|
||||
|
||||
void usbd_event_reset_handler(void)
|
||||
{
|
||||
usbd_set_address(0);
|
||||
usbd_core_cfg.configured = 0;
|
||||
usbd_core_cfg.configuration = 0;
|
||||
g_usbd_core.configuration = 0;
|
||||
|
||||
#ifdef CONFIG_USBDEV_TEST_MODE
|
||||
usbd_core_cfg.test_mode = false;
|
||||
g_usbd_core.test_mode = false;
|
||||
#endif
|
||||
struct usbd_endpoint_cfg ep0_cfg;
|
||||
|
||||
@@ -985,11 +1001,12 @@ void usbd_event_reset_handler(void)
|
||||
usbd_ep_open(&ep0_cfg);
|
||||
|
||||
usbd_class_event_notify_handler(USBD_EVENT_RESET, NULL);
|
||||
usbd_event_handler(USBD_EVENT_RESET);
|
||||
}
|
||||
|
||||
void usbd_event_ep0_setup_complete_handler(uint8_t *psetup)
|
||||
{
|
||||
struct usb_setup_packet *setup = &usbd_core_cfg.setup;
|
||||
struct usb_setup_packet *setup = &g_usbd_core.setup;
|
||||
|
||||
memcpy(setup, psetup, 8);
|
||||
#ifdef CONFIG_USBDEV_SETUP_LOG_PRINT
|
||||
@@ -1003,65 +1020,65 @@ void usbd_event_ep0_setup_complete_handler(uint8_t *psetup)
|
||||
}
|
||||
}
|
||||
|
||||
usbd_core_cfg.ep0_data_buf = usbd_core_cfg.req_data;
|
||||
usbd_core_cfg.ep0_data_buf_residue = setup->wLength;
|
||||
usbd_core_cfg.ep0_data_buf_len = setup->wLength;
|
||||
usbd_core_cfg.zlp_flag = false;
|
||||
g_usbd_core.ep0_data_buf = g_usbd_core.req_data;
|
||||
g_usbd_core.ep0_data_buf_residue = setup->wLength;
|
||||
g_usbd_core.ep0_data_buf_len = setup->wLength;
|
||||
g_usbd_core.zlp_flag = false;
|
||||
|
||||
/* handle class request when all the data is received */
|
||||
if (setup->wLength && ((setup->bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) {
|
||||
USB_LOG_DBG("Start reading %d bytes from ep0\r\n", setup->wLength);
|
||||
usbd_ep_start_read(USB_CONTROL_OUT_EP0, usbd_core_cfg.ep0_data_buf, setup->wLength);
|
||||
usbd_ep_start_read(USB_CONTROL_OUT_EP0, g_usbd_core.ep0_data_buf, setup->wLength);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ask installed handler to process request */
|
||||
if (!usbd_setup_request_handler(setup, &usbd_core_cfg.ep0_data_buf, &usbd_core_cfg.ep0_data_buf_len)) {
|
||||
if (!usbd_setup_request_handler(setup, &g_usbd_core.ep0_data_buf, &g_usbd_core.ep0_data_buf_len)) {
|
||||
usbd_ep_set_stall(USB_CONTROL_IN_EP0);
|
||||
return;
|
||||
}
|
||||
#ifdef CONFIG_USBDEV_TEST_MODE
|
||||
/* send status in test mode, so do not execute downward, just return */
|
||||
if (usbd_core_cfg.test_mode) {
|
||||
usbd_core_cfg.test_mode = false;
|
||||
if (g_usbd_core.test_mode) {
|
||||
g_usbd_core.test_mode = false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* Send smallest of requested and offered length */
|
||||
usbd_core_cfg.ep0_data_buf_residue = MIN(usbd_core_cfg.ep0_data_buf_len, setup->wLength);
|
||||
if (usbd_core_cfg.ep0_data_buf_residue > CONFIG_USBDEV_REQUEST_BUFFER_LEN) {
|
||||
g_usbd_core.ep0_data_buf_residue = MIN(g_usbd_core.ep0_data_buf_len, setup->wLength);
|
||||
if (g_usbd_core.ep0_data_buf_residue > CONFIG_USBDEV_REQUEST_BUFFER_LEN) {
|
||||
USB_LOG_ERR("Request buffer too small\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send data or status to host */
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue);
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, g_usbd_core.ep0_data_buf, g_usbd_core.ep0_data_buf_residue);
|
||||
/*
|
||||
* Set ZLP flag when host asks for a bigger length and the data size is
|
||||
* multiplier of USB_CTRL_EP_MPS, to indicate the transfer done after zlp
|
||||
* sent.
|
||||
*/
|
||||
if ((setup->wLength > usbd_core_cfg.ep0_data_buf_len) && (!(usbd_core_cfg.ep0_data_buf_len % USB_CTRL_EP_MPS))) {
|
||||
usbd_core_cfg.zlp_flag = true;
|
||||
if ((setup->wLength > g_usbd_core.ep0_data_buf_len) && (!(g_usbd_core.ep0_data_buf_len % USB_CTRL_EP_MPS))) {
|
||||
g_usbd_core.zlp_flag = true;
|
||||
USB_LOG_DBG("EP0 Set zlp\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_event_ep0_in_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
struct usb_setup_packet *setup = &usbd_core_cfg.setup;
|
||||
struct usb_setup_packet *setup = &g_usbd_core.setup;
|
||||
|
||||
usbd_core_cfg.ep0_data_buf += nbytes;
|
||||
usbd_core_cfg.ep0_data_buf_residue -= nbytes;
|
||||
g_usbd_core.ep0_data_buf += nbytes;
|
||||
g_usbd_core.ep0_data_buf_residue -= nbytes;
|
||||
|
||||
USB_LOG_DBG("EP0 send %d bytes, %d remained\r\n", nbytes, usbd_core_cfg.ep0_data_buf_residue);
|
||||
USB_LOG_DBG("EP0 send %d bytes, %d remained\r\n", nbytes, g_usbd_core.ep0_data_buf_residue);
|
||||
|
||||
if (usbd_core_cfg.ep0_data_buf_residue != 0) {
|
||||
if (g_usbd_core.ep0_data_buf_residue != 0) {
|
||||
/* Start sending the remain data */
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue);
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, g_usbd_core.ep0_data_buf, g_usbd_core.ep0_data_buf_residue);
|
||||
} else {
|
||||
if (usbd_core_cfg.zlp_flag == true) {
|
||||
usbd_core_cfg.zlp_flag = false;
|
||||
if (g_usbd_core.zlp_flag == true) {
|
||||
g_usbd_core.zlp_flag = false;
|
||||
/* Send zlp to host */
|
||||
USB_LOG_DBG("EP0 Send zlp\r\n");
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, NULL, 0);
|
||||
@@ -1081,18 +1098,18 @@ void usbd_event_ep0_in_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
|
||||
void usbd_event_ep0_out_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
struct usb_setup_packet *setup = &usbd_core_cfg.setup;
|
||||
struct usb_setup_packet *setup = &g_usbd_core.setup;
|
||||
|
||||
if (nbytes > 0) {
|
||||
usbd_core_cfg.ep0_data_buf += nbytes;
|
||||
usbd_core_cfg.ep0_data_buf_residue -= nbytes;
|
||||
g_usbd_core.ep0_data_buf += nbytes;
|
||||
g_usbd_core.ep0_data_buf_residue -= nbytes;
|
||||
|
||||
USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", nbytes, usbd_core_cfg.ep0_data_buf_residue);
|
||||
USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", nbytes, g_usbd_core.ep0_data_buf_residue);
|
||||
|
||||
if (usbd_core_cfg.ep0_data_buf_residue == 0) {
|
||||
if (g_usbd_core.ep0_data_buf_residue == 0) {
|
||||
/* Received all, send data to handler */
|
||||
usbd_core_cfg.ep0_data_buf = usbd_core_cfg.req_data;
|
||||
if (!usbd_setup_request_handler(setup, &usbd_core_cfg.ep0_data_buf, &usbd_core_cfg.ep0_data_buf_len)) {
|
||||
g_usbd_core.ep0_data_buf = g_usbd_core.req_data;
|
||||
if (!usbd_setup_request_handler(setup, &g_usbd_core.ep0_data_buf, &g_usbd_core.ep0_data_buf_len)) {
|
||||
usbd_ep_set_stall(USB_CONTROL_IN_EP0);
|
||||
return;
|
||||
}
|
||||
@@ -1101,7 +1118,7 @@ void usbd_event_ep0_out_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, NULL, 0);
|
||||
} else {
|
||||
/* Start reading the remain data */
|
||||
usbd_ep_start_read(USB_CONTROL_OUT_EP0, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue);
|
||||
usbd_ep_start_read(USB_CONTROL_OUT_EP0, g_usbd_core.ep0_data_buf, g_usbd_core.ep0_data_buf_residue);
|
||||
}
|
||||
} else {
|
||||
/* Read out status completely, do nothing */
|
||||
@@ -1111,159 +1128,119 @@ void usbd_event_ep0_out_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
|
||||
void usbd_event_ep_in_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
#ifndef CONFIG_USBDEV_TX_THREAD
|
||||
if (tx_msg[ep & 0x7f].cb) {
|
||||
tx_msg[ep & 0x7f].cb(ep, nbytes);
|
||||
if (g_usbd_core.tx_msg[ep & 0x7f].cb) {
|
||||
g_usbd_core.tx_msg[ep & 0x7f].cb(ep, nbytes);
|
||||
}
|
||||
#else
|
||||
tx_msg[ep & 0x7f].nbytes = nbytes;
|
||||
usb_osal_mq_send(usbd_tx_mq, (uint32_t)&tx_msg[ep & 0x7f]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void usbd_event_ep_out_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
#ifndef CONFIG_USBDEV_RX_THREAD
|
||||
if (rx_msg[ep & 0x7f].cb) {
|
||||
rx_msg[ep & 0x7f].cb(ep, nbytes);
|
||||
}
|
||||
#else
|
||||
rx_msg[ep & 0x7f].nbytes = nbytes;
|
||||
usb_osal_mq_send(usbd_rx_mq, (uint32_t)&rx_msg[ep & 0x7f]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_TX_THREAD
|
||||
static void usbdev_tx_thread(void *argument)
|
||||
{
|
||||
struct usbd_tx_rx_msg *msg;
|
||||
int ret;
|
||||
|
||||
while (1) {
|
||||
ret = usb_osal_mq_recv(usbd_tx_mq, (uint32_t *)&msg, 0xffffffff);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (msg->cb) {
|
||||
msg->cb(msg->ep, msg->nbytes);
|
||||
}
|
||||
if (g_usbd_core.rx_msg[ep & 0x7f].cb) {
|
||||
g_usbd_core.rx_msg[ep & 0x7f].cb(ep, nbytes);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_RX_THREAD
|
||||
static void usbdev_rx_thread(void *argument)
|
||||
{
|
||||
struct usbd_tx_rx_msg *msg;
|
||||
int ret;
|
||||
|
||||
while (1) {
|
||||
ret = usb_osal_mq_recv(usbd_rx_mq, (uint32_t *)&msg, 0xffffffff);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (msg->cb) {
|
||||
msg->cb(msg->ep, msg->nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
void usbd_desc_register(struct usb_descriptor *desc)
|
||||
{
|
||||
usbd_core_cfg.descriptors = desc;
|
||||
usbd_core_cfg.intf_offset = 0;
|
||||
tx_msg[0].ep = 0x80;
|
||||
tx_msg[0].cb = usbd_event_ep0_in_complete_handler;
|
||||
rx_msg[0].ep = 0x00;
|
||||
rx_msg[0].cb = usbd_event_ep0_out_complete_handler;
|
||||
memset(&g_usbd_core, 0, sizeof(struct usbd_core_priv));
|
||||
|
||||
g_usbd_core.descriptors = desc;
|
||||
g_usbd_core.intf_offset = 0;
|
||||
|
||||
g_usbd_core.tx_msg[0].ep = 0x80;
|
||||
g_usbd_core.tx_msg[0].cb = usbd_event_ep0_in_complete_handler;
|
||||
g_usbd_core.rx_msg[0].ep = 0x00;
|
||||
g_usbd_core.rx_msg[0].cb = usbd_event_ep0_out_complete_handler;
|
||||
}
|
||||
#else
|
||||
void usbd_desc_register(const uint8_t *desc)
|
||||
{
|
||||
usbd_core_cfg.descriptors = desc;
|
||||
usbd_core_cfg.intf_offset = 0;
|
||||
tx_msg[0].ep = 0x80;
|
||||
tx_msg[0].cb = usbd_event_ep0_in_complete_handler;
|
||||
rx_msg[0].ep = 0x00;
|
||||
rx_msg[0].cb = usbd_event_ep0_out_complete_handler;
|
||||
memset(&g_usbd_core, 0, sizeof(struct usbd_core_priv));
|
||||
|
||||
g_usbd_core.descriptors = desc;
|
||||
g_usbd_core.intf_offset = 0;
|
||||
|
||||
g_usbd_core.tx_msg[0].ep = 0x80;
|
||||
g_usbd_core.tx_msg[0].cb = usbd_event_ep0_in_complete_handler;
|
||||
g_usbd_core.rx_msg[0].ep = 0x00;
|
||||
g_usbd_core.rx_msg[0].cb = usbd_event_ep0_out_complete_handler;
|
||||
}
|
||||
|
||||
/* Register MS OS Descriptors version 1 */
|
||||
void usbd_msosv1_desc_register(struct usb_msosv1_descriptor *desc)
|
||||
{
|
||||
msosv1_desc = desc;
|
||||
g_usbd_core.msosv1_desc = desc;
|
||||
}
|
||||
|
||||
/* Register MS OS Descriptors version 2 */
|
||||
void usbd_msosv2_desc_register(struct usb_msosv2_descriptor *desc)
|
||||
{
|
||||
msosv2_desc = desc;
|
||||
g_usbd_core.msosv2_desc = desc;
|
||||
}
|
||||
|
||||
void usbd_bos_desc_register(struct usb_bos_descriptor *desc)
|
||||
{
|
||||
bos_desc = desc;
|
||||
g_usbd_core.bos_desc = desc;
|
||||
}
|
||||
#endif
|
||||
|
||||
void usbd_add_interface(struct usbd_interface *intf)
|
||||
{
|
||||
intf->intf_num = usbd_core_cfg.intf_offset;
|
||||
usb_slist_add_tail(&usbd_intf_head, &intf->list);
|
||||
usbd_core_cfg.intf_offset++;
|
||||
intf->intf_num = g_usbd_core.intf_offset;
|
||||
g_usbd_core.intf[g_usbd_core.intf_offset] = intf;
|
||||
g_usbd_core.intf_offset++;
|
||||
}
|
||||
|
||||
void usbd_add_endpoint(struct usbd_endpoint *ep)
|
||||
{
|
||||
if (ep->ep_addr & 0x80) {
|
||||
tx_msg[ep->ep_addr & 0x7f].ep = ep->ep_addr;
|
||||
tx_msg[ep->ep_addr & 0x7f].cb = ep->ep_cb;
|
||||
g_usbd_core.tx_msg[ep->ep_addr & 0x7f].ep = ep->ep_addr;
|
||||
g_usbd_core.tx_msg[ep->ep_addr & 0x7f].cb = ep->ep_cb;
|
||||
} else {
|
||||
rx_msg[ep->ep_addr & 0x7f].ep = ep->ep_addr;
|
||||
rx_msg[ep->ep_addr & 0x7f].cb = ep->ep_cb;
|
||||
g_usbd_core.rx_msg[ep->ep_addr & 0x7f].ep = ep->ep_addr;
|
||||
g_usbd_core.rx_msg[ep->ep_addr & 0x7f].cb = ep->ep_cb;
|
||||
}
|
||||
}
|
||||
|
||||
bool usb_device_is_configured(void)
|
||||
{
|
||||
return usbd_core_cfg.configured;
|
||||
return g_usbd_core.configuration;
|
||||
}
|
||||
|
||||
int usbd_initialize(void)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_TX_THREAD
|
||||
usbd_tx_mq = usb_osal_mq_create(16);
|
||||
if (usbd_tx_mq == NULL) {
|
||||
return -1;
|
||||
}
|
||||
usbd_tx_thread = usb_osal_thread_create("usbd_tx", CONFIG_USBDEV_TX_STACKSIZE, CONFIG_USBDEV_TX_PRIO, usbdev_tx_thread, NULL);
|
||||
if (usbd_tx_thread == NULL) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_USBDEV_RX_THREAD
|
||||
usbd_rx_mq = usb_osal_mq_create(16);
|
||||
if (usbd_rx_mq == NULL) {
|
||||
return -1;
|
||||
}
|
||||
usbd_rx_thread = usb_osal_thread_create("usbd_rx", CONFIG_USBDEV_RX_STACKSIZE, CONFIG_USBDEV_RX_PRIO, usbdev_rx_thread, NULL);
|
||||
if (usbd_rx_thread == NULL) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return usb_dc_init();
|
||||
}
|
||||
|
||||
int usbd_deinitialize(void)
|
||||
{
|
||||
usbd_core_cfg.intf_offset = 0;
|
||||
usb_slist_init(&usbd_intf_head);
|
||||
g_usbd_core.intf_offset = 0;
|
||||
usb_dc_deinit();
|
||||
#if defined(CONFIG_USBDEV_TX_THREAD) || defined(CONFIG_USBDEV_RX_THREAD)
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,10 @@ enum usbd_event_type {
|
||||
USBD_EVENT_RESUME, /** USB connection resumed by the HOST */
|
||||
|
||||
/* USB DEVICE STATUS */
|
||||
USBD_EVENT_CONFIGURED, /** USB configuration done */
|
||||
USBD_EVENT_SET_INTERFACE, /** USB interface selected */
|
||||
USBD_EVENT_CONFIGURED, /** USB configuration done */
|
||||
USBD_EVENT_SET_INTERFACE, /** USB interface selected */
|
||||
USBD_EVENT_SET_REMOTE_WAKEUP, /** USB set remote wakeup */
|
||||
USBD_EVENT_CLR_REMOTE_WAKEUP, /** USB clear remote wakeup */
|
||||
USBD_EVENT_UNKNOWN
|
||||
};
|
||||
|
||||
@@ -44,15 +46,12 @@ typedef int (*usbd_request_handler)(struct usb_setup_packet *setup, uint8_t **da
|
||||
typedef void (*usbd_endpoint_callback)(uint8_t ep, uint32_t nbytes);
|
||||
typedef void (*usbd_notify_handler)(uint8_t event, void *arg);
|
||||
|
||||
extern usb_slist_t usbd_intf_head;
|
||||
|
||||
struct usbd_endpoint {
|
||||
uint8_t ep_addr;
|
||||
usbd_endpoint_callback ep_cb;
|
||||
};
|
||||
|
||||
struct usbd_interface {
|
||||
usb_slist_t list;
|
||||
usbd_request_handler class_interface_handler;
|
||||
usbd_request_handler class_endpoint_handler;
|
||||
usbd_request_handler vendor_handler;
|
||||
@@ -89,10 +88,11 @@ void usbd_add_interface(struct usbd_interface *intf);
|
||||
void usbd_add_endpoint(struct usbd_endpoint *ep);
|
||||
|
||||
bool usb_device_is_configured(void);
|
||||
void usbd_configure_done_callback(void);
|
||||
int usbd_initialize(void);
|
||||
int usbd_deinitialize(void);
|
||||
|
||||
void usbd_event_handler(uint8_t event);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
158
core/usbh_core.c
158
core/usbh_core.c
@@ -13,8 +13,8 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t ep0_request_buffer[CONFIG_USBHOST
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct usb_setup_packet g_setup[CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USBHOST_MAX_EHPORTS];
|
||||
|
||||
/* general descriptor field offsets */
|
||||
#define DESC_bLength 0 /** Length offset */
|
||||
#define DESC_bDescriptorType 1 /** Descriptor type offset */
|
||||
#define DESC_bLength 0 /** Length offset */
|
||||
#define DESC_bDescriptorType 1 /** Descriptor type offset */
|
||||
|
||||
#define USB_DEV_ADDR_MAX 0x7f
|
||||
#define USB_DEV_ADDR_MARK_OFFSET 5
|
||||
@@ -270,23 +270,6 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBHOST_GET_STRING_DESC
|
||||
void usbh_print_string(char *lead, uint8_t *str)
|
||||
{
|
||||
uint8_t string[64 + 1] = { 0 };
|
||||
|
||||
int len, i = 2, j = 0;
|
||||
|
||||
len = str[0];
|
||||
while (i < len) {
|
||||
string[j] = str[i];
|
||||
i += 2;
|
||||
j++;
|
||||
}
|
||||
USB_LOG_RAW("%s%s\r\n", lead, string);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void usbh_print_hubport_info(struct usbh_hubport *hport)
|
||||
{
|
||||
USB_LOG_RAW("Device Descriptor:\r\n");
|
||||
@@ -408,10 +391,59 @@ int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struc
|
||||
return usbh_pipe_alloc(pipe, &ep_cfg);
|
||||
}
|
||||
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output)
|
||||
{
|
||||
struct usb_setup_packet *setup = hport->setup;
|
||||
int ret;
|
||||
uint8_t *src;
|
||||
uint8_t *dst;
|
||||
uint16_t len;
|
||||
uint16_t i = 2;
|
||||
uint16_t j = 0;
|
||||
|
||||
/* Get Manufacturer string */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||
setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | index);
|
||||
setup->wIndex = 0x0409;
|
||||
setup->wLength = 255;
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
src = ep0_request_buffer;
|
||||
dst = output;
|
||||
len = src[0];
|
||||
|
||||
while (i < len) {
|
||||
dst[j] = src[i];
|
||||
i += 2;
|
||||
j++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting)
|
||||
{
|
||||
struct usb_setup_packet *setup = hport->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = USB_REQUEST_SET_INTERFACE;
|
||||
setup->wValue = intf;
|
||||
setup->wIndex = altsetting;
|
||||
setup->wLength = 0;
|
||||
|
||||
return usbh_control_transfer(hport->ep0, setup, NULL);
|
||||
}
|
||||
|
||||
int usbh_enumerate(struct usbh_hubport *hport)
|
||||
{
|
||||
struct usb_interface_descriptor *intf_desc;
|
||||
struct usb_setup_packet *setup;
|
||||
struct usb_device_descriptor *dev_desc;
|
||||
int dev_addr;
|
||||
uint16_t ep_mps;
|
||||
int ret;
|
||||
@@ -435,10 +467,19 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
parse_device_descriptor(hport, (struct usb_device_descriptor *)ep0_request_buffer, 8);
|
||||
|
||||
/* Extract the correct max packetsize from the device descriptor */
|
||||
ep_mps = ((struct usb_device_descriptor *)ep0_request_buffer)->bMaxPacketSize0;
|
||||
dev_desc = (struct usb_device_descriptor *)ep0_request_buffer;
|
||||
if (dev_desc->bcdUSB >= USB_3_0) {
|
||||
ep_mps = 1 << dev_desc->bMaxPacketSize0;
|
||||
} else {
|
||||
ep_mps = dev_desc->bMaxPacketSize0;
|
||||
}
|
||||
|
||||
USB_LOG_DBG("Device rev=%04x cls=%02x sub=%02x proto=%02x size=%d\r\n",
|
||||
dev_desc->bcdUSB, dev_desc->bDeviceClass, dev_desc->bDeviceSubClass,
|
||||
dev_desc->bDeviceProtocol, ep_mps);
|
||||
|
||||
/* Reconfigure EP0 with the correct maximum packet size */
|
||||
usbh_ep0_pipe_reconfigure(hport->ep0, 0, ep_mps, hport->speed);
|
||||
usbh_ep_pipe_reconfigure(hport->ep0, 0, ep_mps, 0);
|
||||
|
||||
#ifdef CONFIG_USBHOST_XHCI
|
||||
extern int usbh_get_xhci_devaddr(usbh_pipe_t * pipe);
|
||||
@@ -478,7 +519,7 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
hport->dev_addr = dev_addr;
|
||||
|
||||
/* And reconfigure EP0 with the correct address */
|
||||
usbh_ep0_pipe_reconfigure(hport->ep0, dev_addr, ep_mps, hport->speed);
|
||||
usbh_ep_pipe_reconfigure(hport->ep0, dev_addr, ep_mps, 0);
|
||||
|
||||
/* Read the full device descriptor */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
@@ -543,50 +584,37 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
}
|
||||
memcpy(hport->raw_config_desc, ep0_request_buffer, wTotalLength);
|
||||
#ifdef CONFIG_USBHOST_GET_STRING_DESC
|
||||
/* Get Manufacturer string */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||
setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | USB_STRING_MFC_INDEX);
|
||||
setup->wIndex = 0x0409;
|
||||
setup->wLength = 255;
|
||||
uint8_t string_buffer[128];
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
|
||||
/* Get Manufacturer string */
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_MFC_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get Manufacturer string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
usbh_print_string("Manufacturer: ", ep0_request_buffer);
|
||||
USB_LOG_INFO("Manufacturer: %s\r\n", string_buffer);
|
||||
|
||||
/* Get Product string */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||
setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | USB_STRING_PRODUCT_INDEX);
|
||||
setup->wIndex = 0x0409;
|
||||
setup->wLength = 255;
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_PRODUCT_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get get Product string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
usbh_print_string("Product: ", ep0_request_buffer);
|
||||
USB_LOG_INFO("Product: %s\r\n", string_buffer);
|
||||
|
||||
/* Get SerialNumber string */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||
setup->wValue = (uint16_t)((USB_DESCRIPTOR_TYPE_STRING << 8) | USB_STRING_SERIAL_INDEX);
|
||||
setup->wIndex = 0x0409;
|
||||
setup->wLength = 255;
|
||||
|
||||
ret = usbh_control_transfer(hport->ep0, setup, ep0_request_buffer);
|
||||
memset(string_buffer, 0, 128);
|
||||
ret = usbh_get_string_desc(hport, USB_STRING_SERIAL_INDEX, string_buffer);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Failed to get get SerialNumber string,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
usbh_print_string("SerialNumber: ", ep0_request_buffer);
|
||||
USB_LOG_INFO("SerialNumber: %s\r\n", string_buffer);
|
||||
#endif
|
||||
/* Select device configuration 1 */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
@@ -601,6 +629,19 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBHOST_MSOS_ENABLE
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_VENDOR | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = CONFIG_USBHOST_MSOS_VENDOR_CODE;
|
||||
setup->wValue = 0;
|
||||
setup->wIndex = 0x0004;
|
||||
setup->wLength = 16;
|
||||
|
||||
ret = usbh_control_transfer(hport, setup, ep0_request_buffer);
|
||||
if (ret < 0 && (ret != -EPERM)) {
|
||||
USB_LOG_ERR("Failed to get msosv1 compat id,errorcode:%d\r\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
#endif
|
||||
USB_LOG_INFO("Enumeration success, start loading class driver\r\n");
|
||||
/*search supported class driver*/
|
||||
for (uint8_t i = 0; i < hport->config.config_desc.bNumInterfaces; i++) {
|
||||
@@ -619,10 +660,6 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
hport->config.intf[i].class_driver = class_driver;
|
||||
USB_LOG_INFO("Loading %s class driver\r\n", class_driver->driver_name);
|
||||
ret = CLASS_CONNECT(hport, i);
|
||||
if (ret < 0) {
|
||||
CLASS_DISCONNECT(hport, i);
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
errout:
|
||||
@@ -633,25 +670,6 @@ errout:
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct usbh_hubport *usbh_find_hubport(uint8_t dev_addr)
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
usb_slist_t *hub_list;
|
||||
usb_slist_for_each(hub_list, &hub_class_head)
|
||||
{
|
||||
struct usbh_hub *hub = usb_slist_entry(hub_list, struct usbh_hub, list);
|
||||
for (uint8_t port = 0; port < hub->hub_desc.bNbrPorts; port++) {
|
||||
hport = &hub->child[port];
|
||||
if (hport->connected) {
|
||||
if (hport->dev_addr == dev_addr) {
|
||||
return &hub->child[port];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *usbh_find_class_instance(const char *devname)
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
@@ -795,4 +813,4 @@ int lsusb(int argc, char **argv)
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +149,10 @@ struct usbh_hubport {
|
||||
uint8_t *raw_config_desc;
|
||||
struct usb_setup_packet *setup;
|
||||
struct usbh_hub *parent;
|
||||
#ifdef CONFIG_USBHOST_XHCI
|
||||
uint32_t protocol; /* port protocol, for xhci, some ports are USB2.0, others are USB3.0 */
|
||||
#endif
|
||||
usb_osal_thread_t thread;
|
||||
};
|
||||
|
||||
struct usbh_hub {
|
||||
@@ -165,6 +169,16 @@ struct usbh_hub {
|
||||
struct usbh_hubport *parent;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Activates an endpoint for a USB host pipe on a specific hub port.
|
||||
*
|
||||
* This function is responsible for activating the specified endpoint
|
||||
* described by the given endpoint descriptor on the USB host pipe.
|
||||
* @param pipe Pointer to the USB host pipe structure.
|
||||
* @param hport Pointer to the USB hub port structure.
|
||||
* @param ep_desc Pointer to the USB endpoint descriptor.
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc);
|
||||
|
||||
/**
|
||||
@@ -179,8 +193,35 @@ int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struc
|
||||
*/
|
||||
int usbh_control_transfer(usbh_pipe_t pipe, struct usb_setup_packet *setup, uint8_t *buffer);
|
||||
|
||||
/**
|
||||
* @brief Retrieves a USB string descriptor from a specific hub port.
|
||||
*
|
||||
* This function is responsible for retrieving the USB string descriptor
|
||||
* with the specified index from the USB device connected to the given hub port.
|
||||
* The retrieved descriptor is stored in the output buffer provided.
|
||||
*
|
||||
* @param hport Pointer to the USB hub port structure.
|
||||
* @param index Index of the string descriptor to retrieve.
|
||||
* @param output Pointer to the buffer where the retrieved descriptor will be stored.
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usbh_get_string_desc(struct usbh_hubport *hport, uint8_t index, uint8_t *output);
|
||||
|
||||
/**
|
||||
* @brief Sets the alternate setting for a USB interface on a specific hub port.
|
||||
*
|
||||
* This function is responsible for setting the alternate setting of the
|
||||
* specified USB interface on the USB device connected to the given hub port.
|
||||
* The interface and alternate setting are identified by the respective parameters.
|
||||
*
|
||||
* @param hport Pointer to the USB hub port structure.
|
||||
* @param intf Interface number to set the alternate setting for.
|
||||
* @param altsetting Alternate setting value to set for the interface.
|
||||
* @return On success will return 0, and others indicate fail.
|
||||
*/
|
||||
int usbh_set_interface(struct usbh_hubport *hport, uint8_t intf, uint8_t altsetting);
|
||||
|
||||
int usbh_initialize(void);
|
||||
struct usbh_hubport *usbh_find_hubport(uint8_t dev_addr);
|
||||
void *usbh_find_class_instance(const char *devname);
|
||||
|
||||
int lsusb(int argc, char **argv);
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#define AUDIO_IN_EP 0x81
|
||||
|
||||
#define AUDIO_IN_FU_ID 0x02
|
||||
|
||||
/* AUDIO Class Config */
|
||||
#define AUDIO_FREQ 16000U
|
||||
|
||||
@@ -61,14 +63,14 @@
|
||||
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
|
||||
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
const uint8_t audio_descriptor[] = {
|
||||
const uint8_t audio_v1_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01),
|
||||
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE),
|
||||
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, INPUT_CTRL),
|
||||
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 2, 16, AUDIO_IN_EP, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ)),
|
||||
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x01, 0x01, INPUT_CTRL),
|
||||
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 2, 16, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ)),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -143,19 +145,40 @@ const uint8_t audio_descriptor[] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
/* no out ep, do nothing */
|
||||
}
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_open(uint8_t intf)
|
||||
{
|
||||
tx_flag = 1;
|
||||
USB_LOG_RAW("OPEN\r\n");
|
||||
}
|
||||
|
||||
void usbd_audio_close(uint8_t intf)
|
||||
{
|
||||
USB_LOG_RAW("CLOSE\r\n");
|
||||
@@ -176,28 +199,35 @@ static struct usbd_endpoint audio_in_ep = {
|
||||
struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
|
||||
void audio_init()
|
||||
{
|
||||
usbd_desc_register(audio_descriptor);
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf0));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf1));
|
||||
usbd_add_endpoint(&audio_in_ep);
|
||||
struct audio_entity_info audio_entity_table[] = {
|
||||
{ .bEntityId = AUDIO_IN_FU_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT,
|
||||
.ep = AUDIO_IN_EP },
|
||||
};
|
||||
|
||||
usbd_audio_add_entity(0x02, AUDIO_CONTROL_FEATURE_UNIT);
|
||||
void audio_v1_init(void)
|
||||
{
|
||||
usbd_desc_register(audio_v1_descriptor);
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf0, 0x0100, audio_entity_table, 1));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf1, 0x0100, audio_entity_table, 1));
|
||||
usbd_add_endpoint(&audio_in_ep);
|
||||
|
||||
usbd_initialize();
|
||||
}
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
|
||||
|
||||
void audio_test()
|
||||
{
|
||||
while (1) {
|
||||
if (tx_flag) {
|
||||
memset(write_buffer, 'a', 2048);
|
||||
memset(write_buffer, 'a', AUDIO_IN_PACKET);
|
||||
ep_tx_busy_flag = true;
|
||||
usbd_ep_start_write(AUDIO_IN_EP, write_buffer, 2048);
|
||||
usbd_ep_start_write(AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET);
|
||||
while (ep_tx_busy_flag) {
|
||||
if (tx_flag == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
#define AUDIO_IN_EP 0x81
|
||||
#define AUDIO_OUT_EP 0x02
|
||||
|
||||
#define AUDIO_IN_FU_ID 0x02
|
||||
#define AUDIO_OUT_FU_ID 0x05
|
||||
|
||||
/* AUDIO Class Config */
|
||||
#define AUDIO_SPEAKER_FREQ 16000U
|
||||
#define AUDIO_SPEAKER_FRAME_SIZE_BYTE 2u
|
||||
@@ -49,7 +52,7 @@
|
||||
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
|
||||
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
const uint8_t audio_descriptor[] = {
|
||||
const uint8_t audio_v1_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, 0x00, 0x01, 0x02),
|
||||
@@ -59,9 +62,9 @@ const uint8_t audio_descriptor[] = {
|
||||
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003),
|
||||
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00),
|
||||
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET,\
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
|
||||
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, AUDIO_IN_PACKET,\
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
|
||||
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
@@ -137,24 +140,51 @@ const uint8_t audio_descriptor[] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_PACKET];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool rx_flag = 0;
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_open(uint8_t intf)
|
||||
{
|
||||
if (intf == 1) {
|
||||
rx_flag = 1;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET);
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
|
||||
printf("OPEN1\r\n");
|
||||
} else {
|
||||
tx_flag = 1;
|
||||
printf("OPEN2\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_close(uint8_t intf)
|
||||
{
|
||||
if (intf == 1) {
|
||||
@@ -166,22 +196,10 @@ void usbd_audio_close(uint8_t intf)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define AUDIO_OUT_EP_MPS 512
|
||||
#else
|
||||
#define AUDIO_OUT_EP_MPS 64
|
||||
#endif
|
||||
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
}
|
||||
|
||||
void usbd_audio_out_callback(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET);
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
|
||||
}
|
||||
|
||||
void usbd_audio_in_callback(uint8_t ep, uint32_t nbytes)
|
||||
@@ -204,30 +222,37 @@ struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
struct usbd_interface intf2;
|
||||
|
||||
void audio_init()
|
||||
struct audio_entity_info audio_entity_table[] = {
|
||||
{ .bEntityId = AUDIO_IN_FU_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT,
|
||||
.ep = AUDIO_IN_EP },
|
||||
{ .bEntityId = AUDIO_OUT_FU_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT,
|
||||
.ep = AUDIO_OUT_EP },
|
||||
};
|
||||
|
||||
void audio_v1_init(void)
|
||||
{
|
||||
usbd_desc_register(audio_descriptor);
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf0));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf1));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf2));
|
||||
usbd_desc_register(audio_v1_descriptor);
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf0, 0x0100, audio_entity_table, 2));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf1, 0x0100, audio_entity_table, 2));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf2, 0x0100, audio_entity_table, 2));
|
||||
usbd_add_endpoint(&audio_in_ep);
|
||||
usbd_add_endpoint(&audio_out_ep);
|
||||
|
||||
usbd_audio_add_entity(0x02, AUDIO_CONTROL_FEATURE_UNIT);
|
||||
usbd_audio_add_entity(0x05, AUDIO_CONTROL_FEATURE_UNIT);
|
||||
|
||||
usbd_initialize();
|
||||
}
|
||||
|
||||
void audio_test()
|
||||
void audio_v1_test(void)
|
||||
{
|
||||
while (1) {
|
||||
if (tx_flag) {
|
||||
// memset(write_buffer, 'a', 2048);
|
||||
// ep_tx_busy_flag = true;
|
||||
// usbd_ep_start_write(AUDIO_IN_EP, write_buffer, 2048);
|
||||
// while (ep_tx_busy_flag) {
|
||||
// }
|
||||
if (tx_flag) {
|
||||
memset(write_buffer, 'a', AUDIO_IN_PACKET);
|
||||
ep_tx_busy_flag = true;
|
||||
usbd_ep_start_write(AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET);
|
||||
while (ep_tx_busy_flag) {
|
||||
if (tx_flag == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,16 @@
|
||||
|
||||
#define AUDIO_IN_EP 0x81
|
||||
|
||||
#define AUDIO_IN_CLOCK_ID 0x01
|
||||
#define AUDIO_IN_FU_ID 0x03
|
||||
|
||||
#define AUDIO_FREQ 48000
|
||||
#define HALF_WORD_BYTES 2 //2 half word (one channel)
|
||||
#define SAMPLE_BITS 16 //16 bit per channel
|
||||
|
||||
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
|
||||
|
||||
#define IN_CHANNEL_NUM 2
|
||||
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
|
||||
|
||||
#if IN_CHANNEL_NUM == 1
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
@@ -49,7 +53,6 @@
|
||||
|
||||
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000))
|
||||
|
||||
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \
|
||||
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
|
||||
@@ -64,7 +67,7 @@
|
||||
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
|
||||
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
const uint8_t audio_descriptor[] = {
|
||||
const uint8_t audio_v2_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_MICROPHONE, 0x00, 0x00),
|
||||
@@ -72,7 +75,7 @@ const uint8_t audio_descriptor[] = {
|
||||
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, 0x01, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
|
||||
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, INPUT_CTRL),
|
||||
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x03, 0x01, 0x0000),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -156,29 +159,50 @@ static const uint8_t mic_default_sampling_freq_table[] = {
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_open(uint8_t intf)
|
||||
{
|
||||
tx_flag = 1;
|
||||
USB_LOG_RAW("OPEN\r\n");
|
||||
}
|
||||
|
||||
void usbd_audio_close(uint8_t intf)
|
||||
{
|
||||
USB_LOG_RAW("CLOSE\r\n");
|
||||
tx_flag = 0;
|
||||
}
|
||||
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table)
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table)
|
||||
{
|
||||
if (entity_id == 0x01) {
|
||||
if (ep == AUDIO_IN_EP) {
|
||||
*sampling_freq_table = (uint8_t *)mic_default_sampling_freq_table;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
/* no out ep, do nothing */
|
||||
}
|
||||
|
||||
void usbd_audio_iso_in_callback(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
}
|
||||
@@ -191,23 +215,27 @@ static struct usbd_endpoint audio_in_ep = {
|
||||
struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
|
||||
void audio_init()
|
||||
{
|
||||
usbd_desc_register(audio_descriptor);
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf0));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf1));
|
||||
usbd_add_endpoint(&audio_in_ep);
|
||||
struct audio_entity_info audio_entity_table[] = {
|
||||
{ .bEntityId = AUDIO_IN_CLOCK_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_CLOCK_SOURCE,
|
||||
.ep = AUDIO_IN_EP },
|
||||
{ .bEntityId = AUDIO_IN_FU_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT,
|
||||
.ep = AUDIO_IN_EP },
|
||||
};
|
||||
|
||||
usbd_audio_add_entity(0x01, AUDIO_CONTROL_CLOCK_SOURCE);
|
||||
usbd_audio_add_entity(0x03, AUDIO_CONTROL_FEATURE_UNIT);
|
||||
void audio_v2_init(void)
|
||||
{
|
||||
usbd_desc_register(audio_v2_descriptor);
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf0, 0x0200, audio_entity_table, 2));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf1, 0x0200, audio_entity_table, 2));
|
||||
usbd_add_endpoint(&audio_in_ep);
|
||||
|
||||
usbd_initialize();
|
||||
}
|
||||
|
||||
void audio_test()
|
||||
void audio_v2_test(void)
|
||||
{
|
||||
while (1) {
|
||||
if (tx_flag) {
|
||||
}
|
||||
if (tx_flag) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,17 @@
|
||||
#define AUDIO_OUT_EP 0x02
|
||||
#define AUDIO_IN_EP 0x81
|
||||
|
||||
#define AUDIO_OUT_CLOCK_ID 0x01
|
||||
#define AUDIO_OUT_FU_ID 0x03
|
||||
#define AUDIO_IN_CLOCK_ID 0x05
|
||||
#define AUDIO_IN_FU_ID 0x07
|
||||
|
||||
#define AUDIO_FREQ 48000
|
||||
#define HALF_WORD_BYTES 2 //2 half word (one channel)
|
||||
#define SAMPLE_BITS 16 //16 bit per channel
|
||||
|
||||
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
|
||||
|
||||
#define IN_CHANNEL_NUM 2
|
||||
|
||||
#if IN_CHANNEL_NUM == 1
|
||||
@@ -47,42 +54,38 @@
|
||||
#define INPUT_CH_ENABLE 0x000000ff
|
||||
#endif
|
||||
|
||||
|
||||
#define OUT_CHANNEL_NUM 2
|
||||
|
||||
#if OUT_CHANNEL_NUM == 1
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000000
|
||||
#elif OUT_CHANNEL_NUM == 2
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000003
|
||||
#elif OUT_CHANNEL_NUM == 3
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000007
|
||||
#elif OUT_CHANNEL_NUM == 4
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000000f
|
||||
#elif OUT_CHANNEL_NUM == 5
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000001f
|
||||
#elif OUT_CHANNEL_NUM == 6
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000003F
|
||||
#elif OUT_CHANNEL_NUM == 7
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000007f
|
||||
#elif OUT_CHANNEL_NUM == 8
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x000000ff
|
||||
#endif
|
||||
|
||||
|
||||
/* AudioFreq * DataSize (2 bytes) * NumChannels */
|
||||
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000))
|
||||
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000))
|
||||
|
||||
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
|
||||
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \
|
||||
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
|
||||
@@ -106,7 +109,7 @@
|
||||
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
|
||||
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
uint8_t audio_descriptor[] = {
|
||||
uint8_t audio_v2_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, AUDIO_CATEGORY_UNDEF, 0x00, 0x00),
|
||||
@@ -118,8 +121,8 @@ uint8_t audio_descriptor[] = {
|
||||
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, 0x05, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
|
||||
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x07, 0x06, INPUT_CTRL),
|
||||
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, 0x07, 0x05, 0x0000),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -220,23 +223,50 @@ static const uint8_t mic_default_sampling_freq_table[] = {
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00)
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_PACKET];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool rx_flag = 0;
|
||||
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_open(uint8_t intf)
|
||||
{
|
||||
if (intf == 1) {
|
||||
rx_flag = 1;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET);
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
|
||||
USB_LOG_RAW("OPEN1\r\n");
|
||||
} else {
|
||||
tx_flag = 1;
|
||||
USB_LOG_RAW("OPEN2\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_close(uint8_t intf)
|
||||
{
|
||||
if (intf == 1) {
|
||||
@@ -248,36 +278,34 @@ void usbd_audio_close(uint8_t intf)
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table)
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table)
|
||||
{
|
||||
if (entity_id == 0x01) {
|
||||
if (ep == AUDIO_OUT_EP) {
|
||||
*sampling_freq_table = (uint8_t *)speaker_default_sampling_freq_table;
|
||||
} else if (entity_id == 0x05) {
|
||||
} else if (ep == AUDIO_IN_EP) {
|
||||
*sampling_freq_table = (uint8_t *)mic_default_sampling_freq_table;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq)
|
||||
void usbd_audio_set_sampling_freq(uint8_t ep, uint32_t sampling_freq)
|
||||
{
|
||||
uint16_t packet_size = 0;
|
||||
if (entity_id == 1) {
|
||||
if (ep == AUDIO_OUT_EP) {
|
||||
packet_size = ((sampling_freq * 2 * OUT_CHANNEL_NUM) / 1000);
|
||||
audio_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 11] = packet_size;
|
||||
audio_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 10] = packet_size >> 8;
|
||||
} else if (entity_id == 5) {
|
||||
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 11] = packet_size;
|
||||
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 10] = packet_size >> 8;
|
||||
} else if (ep == AUDIO_IN_EP) {
|
||||
packet_size = ((sampling_freq * 2 * IN_CHANNEL_NUM) / 1000);
|
||||
audio_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 11] = packet_size;
|
||||
audio_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 10] = packet_size >> 8;
|
||||
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 11] = packet_size;
|
||||
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 10] = packet_size >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
}
|
||||
|
||||
void usbd_audio_iso_out_callback(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
|
||||
}
|
||||
|
||||
void usbd_audio_iso_in_callback(uint8_t ep, uint32_t nbytes)
|
||||
@@ -298,27 +326,37 @@ struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
struct usbd_interface intf2;
|
||||
|
||||
void audio_init()
|
||||
struct audio_entity_info audio_entity_table[] = {
|
||||
{ .bEntityId = AUDIO_OUT_CLOCK_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_CLOCK_SOURCE,
|
||||
.ep = AUDIO_OUT_EP },
|
||||
{ .bEntityId = AUDIO_OUT_FU_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT,
|
||||
.ep = AUDIO_OUT_EP },
|
||||
{ .bEntityId = AUDIO_IN_CLOCK_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_CLOCK_SOURCE,
|
||||
.ep = AUDIO_IN_EP },
|
||||
{ .bEntityId = AUDIO_IN_FU_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT,
|
||||
.ep = AUDIO_IN_EP },
|
||||
};
|
||||
|
||||
void audio_v2_init(void)
|
||||
{
|
||||
usbd_desc_register(audio_descriptor);
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf0));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf1));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf2));
|
||||
usbd_desc_register(audio_v2_descriptor);
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf0, 0x0200, audio_entity_table, 4));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf1, 0x0200, audio_entity_table, 4));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf2, 0x0200, audio_entity_table, 4));
|
||||
usbd_add_endpoint(&audio_in_ep);
|
||||
usbd_add_endpoint(&audio_out_ep);
|
||||
|
||||
usbd_audio_add_entity(0x01, AUDIO_CONTROL_CLOCK_SOURCE);
|
||||
usbd_audio_add_entity(0x03, AUDIO_CONTROL_FEATURE_UNIT);
|
||||
usbd_audio_add_entity(0x05, AUDIO_CONTROL_CLOCK_SOURCE);
|
||||
usbd_audio_add_entity(0x07, AUDIO_CONTROL_FEATURE_UNIT);
|
||||
|
||||
usbd_initialize();
|
||||
}
|
||||
|
||||
void audio_test()
|
||||
void audio_v2_test(void)
|
||||
{
|
||||
while (1) {
|
||||
if (tx_flag) {
|
||||
}
|
||||
if (tx_flag) {
|
||||
}
|
||||
if (rx_flag) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,42 +14,45 @@
|
||||
|
||||
#define AUDIO_OUT_EP 0x01
|
||||
|
||||
#define AUDIO_OUT_CLOCK_ID 0x01
|
||||
#define AUDIO_OUT_FU_ID 0x03
|
||||
|
||||
#define AUDIO_FREQ 48000
|
||||
#define HALF_WORD_BYTES 2 //2 half word (one channel)
|
||||
#define SAMPLE_BITS 16 //16 bit per channel
|
||||
|
||||
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
|
||||
|
||||
#define OUT_CHANNEL_NUM 2
|
||||
|
||||
#if OUT_CHANNEL_NUM == 1
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000000
|
||||
#elif OUT_CHANNEL_NUM == 2
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000003
|
||||
#elif OUT_CHANNEL_NUM == 3
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000007
|
||||
#elif OUT_CHANNEL_NUM == 4
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000000f
|
||||
#elif OUT_CHANNEL_NUM == 5
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000001f
|
||||
#elif OUT_CHANNEL_NUM == 6
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000003F
|
||||
#elif OUT_CHANNEL_NUM == 7
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000007f
|
||||
#elif OUT_CHANNEL_NUM == 8
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x000000ff
|
||||
#endif
|
||||
|
||||
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000))
|
||||
|
||||
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
|
||||
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \
|
||||
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
|
||||
@@ -64,15 +67,15 @@
|
||||
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
|
||||
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
const uint8_t audio_descriptor[] = {
|
||||
const uint8_t audio_v2_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_SPEAKER, 0x00, 0x00),
|
||||
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
|
||||
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03),
|
||||
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
|
||||
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, OUTPUT_CTRL),
|
||||
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL),
|
||||
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -166,36 +169,60 @@ static const uint8_t default_sampling_freq_table[] = {
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_PACKET];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
|
||||
|
||||
volatile bool rx_flag = 0;
|
||||
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_open(uint8_t intf)
|
||||
{
|
||||
rx_flag = 1;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET);
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
|
||||
USB_LOG_RAW("OPEN\r\n");
|
||||
}
|
||||
|
||||
void usbd_audio_close(uint8_t intf)
|
||||
{
|
||||
USB_LOG_RAW("CLOSE\r\n");
|
||||
rx_flag = 0;
|
||||
}
|
||||
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table)
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t ep, uint8_t **sampling_freq_table)
|
||||
{
|
||||
if (entity_id == 0x01) {
|
||||
if (ep == AUDIO_OUT_EP) {
|
||||
*sampling_freq_table = (uint8_t *)default_sampling_freq_table;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
}
|
||||
|
||||
void usbd_audio_iso_out_callback(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
|
||||
}
|
||||
|
||||
static struct usbd_endpoint audio_out_ep = {
|
||||
@@ -206,23 +233,27 @@ static struct usbd_endpoint audio_out_ep = {
|
||||
struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
|
||||
void audio_init()
|
||||
{
|
||||
usbd_desc_register(audio_descriptor);
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf0));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf1));
|
||||
usbd_add_endpoint(&audio_out_ep);
|
||||
struct audio_entity_info audio_entity_table[] = {
|
||||
{ .bEntityId = AUDIO_OUT_CLOCK_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_CLOCK_SOURCE,
|
||||
.ep = AUDIO_OUT_EP },
|
||||
{ .bEntityId = AUDIO_OUT_FU_ID,
|
||||
.bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT,
|
||||
.ep = AUDIO_OUT_EP },
|
||||
};
|
||||
|
||||
usbd_audio_add_entity(0x01, AUDIO_CONTROL_CLOCK_SOURCE);
|
||||
usbd_audio_add_entity(0x03, AUDIO_CONTROL_FEATURE_UNIT);
|
||||
void audio_v2_init(void)
|
||||
{
|
||||
usbd_desc_register(audio_v2_descriptor);
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf0, 0x0200, audio_entity_table, 2));
|
||||
usbd_add_interface(usbd_audio_init_intf(&intf1, 0x0200, audio_entity_table, 2));
|
||||
usbd_add_endpoint(&audio_out_ep);
|
||||
|
||||
usbd_initialize();
|
||||
}
|
||||
|
||||
void audio_test()
|
||||
void audio_v2_test(void)
|
||||
{
|
||||
while (1) {
|
||||
if (rx_flag) {
|
||||
}
|
||||
if (rx_flag) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,11 +26,23 @@
|
||||
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN + MSC_DESCRIPTOR_LEN + 25)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define MSC_MAX_MPS 512
|
||||
#else
|
||||
#define MSC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
const uint8_t cdc_acm_hid_msc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, 0x02),
|
||||
MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
@@ -136,35 +148,6 @@ const uint8_t cdc_acm_hid_msc_descriptor[] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
#define BLOCK_SIZE 512
|
||||
#define BLOCK_COUNT 10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t BlockSpace[BLOCK_SIZE];
|
||||
} BLOCK_TYPE;
|
||||
|
||||
BLOCK_TYPE mass_block[BLOCK_COUNT];
|
||||
|
||||
void usbd_msc_get_cap(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
|
||||
{
|
||||
*block_num = 1000; //Pretend having so many buffer,not has actually.
|
||||
*block_size = BLOCK_SIZE;
|
||||
}
|
||||
int usbd_msc_sector_read(uint32_t sector, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
if (sector < 10)
|
||||
memcpy(buffer, mass_block[sector].BlockSpace, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_msc_sector_write(uint32_t sector, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
if (sector < 10)
|
||||
memcpy(mass_block[sector].BlockSpace, buffer, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!< hid mouse report descriptor */
|
||||
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
@@ -255,10 +238,31 @@ volatile bool ep_tx_busy_flag = false;
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
@@ -360,3 +364,32 @@ void cdc_acm_data_send_with_dtr_test(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define BLOCK_SIZE 512
|
||||
#define BLOCK_COUNT 10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t BlockSpace[BLOCK_SIZE];
|
||||
} BLOCK_TYPE;
|
||||
|
||||
BLOCK_TYPE mass_block[BLOCK_COUNT];
|
||||
|
||||
void usbd_msc_get_cap(uint8_t lun, uint32_t *block_num, uint16_t *block_size)
|
||||
{
|
||||
*block_num = 1000; //Pretend having so many buffer,not has actually.
|
||||
*block_size = BLOCK_SIZE;
|
||||
}
|
||||
int usbd_msc_sector_read(uint32_t sector, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
if (sector < 10)
|
||||
memcpy(buffer, mass_block[sector].BlockSpace, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_msc_sector_write(uint32_t sector, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
if (sector < 10)
|
||||
memcpy(mass_block[sector].BlockSpace, buffer, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -18,12 +18,24 @@
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN + MSC_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define MSC_MAX_MPS 512
|
||||
#else
|
||||
#define MSC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_msc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, 0x02),
|
||||
MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, 0x00),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x00),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -109,10 +121,31 @@ volatile bool ep_tx_busy_flag = false;
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
|
||||
@@ -26,14 +26,20 @@
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN * 4)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x08, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x02, CDC_INT_EP2, CDC_OUT_EP2, CDC_IN_EP2, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x04, CDC_INT_EP3, CDC_OUT_EP3, CDC_IN_EP3, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x06, CDC_INT_EP4, CDC_OUT_EP4, CDC_IN_EP4, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x02, CDC_INT_EP2, CDC_OUT_EP2, CDC_IN_EP2, CDC_MAX_MPS, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x04, CDC_INT_EP3, CDC_OUT_EP3, CDC_IN_EP3, CDC_MAX_MPS, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x06, CDC_INT_EP4, CDC_OUT_EP4, CDC_IN_EP4, CDC_MAX_MPS, 0x02),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -119,13 +125,34 @@ volatile bool ep_tx_busy_flag = false;
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
usbd_ep_start_read(CDC_OUT_EP2, read_buffer, 2048);
|
||||
usbd_ep_start_read(CDC_OUT_EP3, read_buffer, 2048);
|
||||
usbd_ep_start_read(CDC_OUT_EP4, read_buffer, 2048);
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
usbd_ep_start_read(CDC_OUT_EP2, read_buffer, 2048);
|
||||
usbd_ep_start_read(CDC_OUT_EP3, read_buffer, 2048);
|
||||
usbd_ep_start_read(CDC_OUT_EP4, read_buffer, 2048);
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
|
||||
@@ -14,11 +14,17 @@
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -104,10 +110,31 @@ volatile bool ep_tx_busy_flag = false;
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
@@ -144,8 +171,8 @@ struct usbd_endpoint cdc_in_ep = {
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
|
||||
struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
static struct usbd_interface intf0;
|
||||
static struct usbd_interface intf1;
|
||||
|
||||
void cdc_acm_init(void)
|
||||
{
|
||||
|
||||
274
demo/cdc_ecm_template.c
Normal file
274
demo/cdc_ecm_template.c
Normal file
@@ -0,0 +1,274 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_ecm.h"
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
#define CDC_INT_EP 0x83
|
||||
|
||||
#define USBD_VID 0xFFFF
|
||||
#define USBD_PID 0xFFFF
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ECM_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#define CDC_ECM_ETH_STATISTICS_BITMAP 0x00000000
|
||||
|
||||
/* str idx = 4 is for mac address: aa:bb:cc:dd:ee:ff*/
|
||||
#define CDC_ECM_MAC_STRING_INDEX 4
|
||||
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_ecm_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_ETH_STATISTICS_BITMAP, CONFIG_CDC_ECM_ETH_MAX_SEGSZE, 0, 0, CDC_ECM_MAC_STRING_INDEX),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||
///////////////////////////////////////
|
||||
/// string1 descriptor
|
||||
///////////////////////////////////////
|
||||
0x14, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x2E, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
' ', 0x00, /* wcChar9 */
|
||||
'C', 0x00, /* wcChar10 */
|
||||
'D', 0x00, /* wcChar11 */
|
||||
'C', 0x00, /* wcChar12 */
|
||||
' ', 0x00, /* wcChar13 */
|
||||
'E', 0x00, /* wcChar14 */
|
||||
'C', 0x00, /* wcChar15 */
|
||||
'M', 0x00, /* wcChar16 */
|
||||
' ', 0x00, /* wcChar17 */
|
||||
'D', 0x00, /* wcChar18 */
|
||||
'E', 0x00, /* wcChar19 */
|
||||
'M', 0x00, /* wcChar20 */
|
||||
'O', 0x00, /* wcChar21 */
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
///////////////////////////////////////
|
||||
/// string4 descriptor
|
||||
///////////////////////////////////////
|
||||
0x1A, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'a', 0x00, /* wcChar0 */
|
||||
'a', 0x00, /* wcChar1 */
|
||||
'b', 0x00, /* wcChar2 */
|
||||
'b', 0x00, /* wcChar3 */
|
||||
'c', 0x00, /* wcChar4 */
|
||||
'c', 0x00, /* wcChar5 */
|
||||
'd', 0x00, /* wcChar6 */
|
||||
'd', 0x00, /* wcChar7 */
|
||||
'e', 0x00, /* wcChar8 */
|
||||
'e', 0x00, /* wcChar9 */
|
||||
'f', 0x00, /* wcChar10 */
|
||||
'f', 0x00, /* wcChar11 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
|
||||
const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
|
||||
|
||||
/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */
|
||||
#define IP_ADDR0 (uint8_t)192
|
||||
#define IP_ADDR1 (uint8_t)168
|
||||
#define IP_ADDR2 (uint8_t)123
|
||||
#define IP_ADDR3 (uint8_t)100
|
||||
|
||||
/*NETMASK*/
|
||||
#define NETMASK_ADDR0 (uint8_t)255
|
||||
#define NETMASK_ADDR1 (uint8_t)255
|
||||
#define NETMASK_ADDR2 (uint8_t)255
|
||||
#define NETMASK_ADDR3 (uint8_t)0
|
||||
|
||||
/*Gateway Address*/
|
||||
#define GW_ADDR0 (uint8_t)192
|
||||
#define GW_ADDR1 (uint8_t)168
|
||||
#define GW_ADDR2 (uint8_t)123
|
||||
#define GW_ADDR3 (uint8_t)1
|
||||
|
||||
#include "netif/etharp.h"
|
||||
#include "lwip/init.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/pbuf.h"
|
||||
|
||||
const ip_addr_t ipaddr = IPADDR4_INIT_BYTES(IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
|
||||
const ip_addr_t netmask = IPADDR4_INIT_BYTES(NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
|
||||
const ip_addr_t gateway = IPADDR4_INIT_BYTES(GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
|
||||
|
||||
static struct netif cdc_ecm_netif; //network interface
|
||||
|
||||
/* Network interface name */
|
||||
#define IFNAME0 'E'
|
||||
#define IFNAME1 'X'
|
||||
|
||||
static err_t linkoutput_fn(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
static int ret;
|
||||
|
||||
ret = usbd_cdc_ecm_eth_tx(p);
|
||||
if (ret == 0)
|
||||
return ERR_OK;
|
||||
else
|
||||
return ERR_BUF;
|
||||
}
|
||||
|
||||
err_t cdc_ecm_if_init(struct netif *netif)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
|
||||
netif->mtu = 1500;
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
|
||||
netif->state = NULL;
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
netif->output = etharp_output;
|
||||
netif->linkoutput = linkoutput_fn;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t cdc_ecm_if_input(struct netif *netif)
|
||||
{
|
||||
static err_t err;
|
||||
static struct pbuf *p;
|
||||
|
||||
p = usbd_cdc_ecm_eth_rx();
|
||||
if (p != NULL) {
|
||||
err = netif->input(p, netif);
|
||||
if (err != ERR_OK) {
|
||||
pbuf_free(p);
|
||||
}
|
||||
} else {
|
||||
return ERR_BUF;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void cdc_ecm_lwip_init(void)
|
||||
{
|
||||
struct netif *netif = &cdc_ecm_netif;
|
||||
|
||||
lwip_init();
|
||||
|
||||
netif->hwaddr_len = 6;
|
||||
memcpy(netif->hwaddr, mac, 6);
|
||||
|
||||
netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, cdc_ecm_if_init, netif_input);
|
||||
netif_set_default(netif);
|
||||
while (!netif_is_up(netif)) {
|
||||
}
|
||||
|
||||
// while (dhserv_init(&dhcp_config)) {}
|
||||
|
||||
// while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
|
||||
}
|
||||
|
||||
void usbd_cdc_ecm_data_recv_done(void)
|
||||
{
|
||||
}
|
||||
|
||||
void cdc_ecm_input_poll(void)
|
||||
{
|
||||
cdc_ecm_if_input(&cdc_ecm_netif);
|
||||
}
|
||||
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
|
||||
/* ecm only supports in linux, and you should input the following command
|
||||
*
|
||||
* sudo ifconfig enxaabbccddeeff up
|
||||
* sudo dhcpclient enxaabbccddeeff
|
||||
*/
|
||||
void cdc_ecm_init(void)
|
||||
{
|
||||
cdc_ecm_lwip_init();
|
||||
|
||||
usbd_desc_register(cdc_ecm_descriptor);
|
||||
usbd_add_interface(usbd_cdc_ecm_init_intf(&intf0, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP));
|
||||
usbd_add_interface(usbd_cdc_ecm_init_intf(&intf1, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP));
|
||||
usbd_initialize();
|
||||
}
|
||||
@@ -14,11 +14,17 @@
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_RNDIS_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, 0x02),
|
||||
CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -95,20 +101,36 @@ static const uint8_t cdc_descriptor[] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
|
||||
/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */
|
||||
#define IP_ADDR0 (uint8_t)192
|
||||
#define IP_ADDR1 (uint8_t)168
|
||||
#define IP_ADDR2 (uint8_t)123
|
||||
#define IP_ADDR3 (uint8_t)100
|
||||
|
||||
/*NETMASK*/
|
||||
#define NETMASK_ADDR0 (uint8_t)255
|
||||
#define NETMASK_ADDR1 (uint8_t)255
|
||||
#define NETMASK_ADDR2 (uint8_t)255
|
||||
#define NETMASK_ADDR3 (uint8_t)0
|
||||
|
||||
/*Gateway Address*/
|
||||
#define GW_ADDR0 (uint8_t)192
|
||||
#define GW_ADDR1 (uint8_t)168
|
||||
#define GW_ADDR2 (uint8_t)123
|
||||
#define GW_ADDR3 (uint8_t)1
|
||||
|
||||
#ifdef RT_USING_LWIP
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
#include <netif/ethernetif.h>
|
||||
|
||||
const ip_addr_t ipaddr = IPADDR4_INIT_BYTES(IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
|
||||
const ip_addr_t netmask = IPADDR4_INIT_BYTES(NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
|
||||
const ip_addr_t gateway = IPADDR4_INIT_BYTES(GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
|
||||
|
||||
struct eth_device rndis_dev;
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
eth_device_linkchange(&rndis_dev, RT_TRUE);
|
||||
}
|
||||
|
||||
uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
|
||||
|
||||
static rt_err_t rt_usbd_rndis_control(rt_device_t dev, int cmd, void *args)
|
||||
{
|
||||
switch (cmd) {
|
||||
@@ -139,7 +161,7 @@ rt_err_t rt_usbd_rndis_eth_tx(rt_device_t dev, struct pbuf *p)
|
||||
return usbd_rndis_eth_tx(p);
|
||||
}
|
||||
|
||||
void usbd_rndis_data_recv(uint8_t *data, uint32_t len)
|
||||
void usbd_rndis_data_recv_done(void)
|
||||
{
|
||||
eth_device_ready(&rndis_dev);
|
||||
}
|
||||
@@ -155,12 +177,120 @@ void rt_usbd_rndis_init(void)
|
||||
eth_device_linkchange(&rndis_dev, RT_FALSE);
|
||||
}
|
||||
#else
|
||||
void usbd_configure_done_callback(void)
|
||||
#include "netif/etharp.h"
|
||||
#include "lwip/init.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/pbuf.h"
|
||||
|
||||
const ip_addr_t ipaddr = IPADDR4_INIT_BYTES(IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
|
||||
const ip_addr_t netmask = IPADDR4_INIT_BYTES(NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
|
||||
const ip_addr_t gateway = IPADDR4_INIT_BYTES(GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
|
||||
|
||||
static struct netif rndis_netif; //network interface
|
||||
|
||||
/* Network interface name */
|
||||
#define IFNAME0 'E'
|
||||
#define IFNAME1 'X'
|
||||
|
||||
err_t linkoutput_fn(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
static int ret;
|
||||
|
||||
ret = usbd_rndis_eth_tx(p);
|
||||
if (ret == 0)
|
||||
return ERR_OK;
|
||||
else
|
||||
return ERR_BUF;
|
||||
}
|
||||
|
||||
err_t rndisif_init(struct netif *netif)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
|
||||
netif->mtu = 1500;
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
|
||||
netif->state = NULL;
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
netif->output = etharp_output;
|
||||
netif->linkoutput = linkoutput_fn;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t rndisif_input(struct netif *netif)
|
||||
{
|
||||
static err_t err;
|
||||
static struct pbuf *p;
|
||||
|
||||
p = usbd_rndis_eth_rx();
|
||||
if (p != NULL) {
|
||||
err = netif->input(p, netif);
|
||||
if (err != ERR_OK) {
|
||||
pbuf_free(p);
|
||||
}
|
||||
} else {
|
||||
return ERR_BUF;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void rndis_lwip_init(void)
|
||||
{
|
||||
struct netif *netif = &rndis_netif;
|
||||
|
||||
lwip_init();
|
||||
|
||||
netif->hwaddr_len = 6;
|
||||
memcpy(netif->hwaddr, mac, 6);
|
||||
|
||||
netif = netif_add(netif, &ipaddr, &netmask, &gateway, NULL, rndisif_init, netif_input);
|
||||
netif_set_default(netif);
|
||||
while (!netif_is_up(netif)) {
|
||||
}
|
||||
|
||||
// while (dhserv_init(&dhcp_config)) {}
|
||||
|
||||
// while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
|
||||
}
|
||||
|
||||
void usbd_rndis_data_recv_done(void)
|
||||
{
|
||||
}
|
||||
|
||||
void rndis_input_poll(void)
|
||||
{
|
||||
rndisif_input(&rndis_netif);
|
||||
}
|
||||
#endif /* RT_USING_LWIP */
|
||||
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
#ifdef RT_USING_LWIP
|
||||
eth_device_linkchange(&rndis_dev, RT_TRUE);
|
||||
#endif
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
|
||||
@@ -168,6 +298,8 @@ void cdc_rndis_init(void)
|
||||
{
|
||||
#ifdef RT_USING_LWIP
|
||||
rt_usbd_rndis_init();
|
||||
#else
|
||||
rndis_lwip_init();
|
||||
#endif
|
||||
usbd_desc_register(cdc_descriptor);
|
||||
usbd_add_interface(usbd_rndis_init_intf(&intf0, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
|
||||
|
||||
@@ -1,284 +0,0 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc.h"
|
||||
#include "DAP_config.h"
|
||||
#include "DAP.h"
|
||||
|
||||
#define DAP_IN_EP 0x81
|
||||
#define DAP_OUT_EP 0x02
|
||||
|
||||
#define CDC_IN_EP 0x83
|
||||
#define CDC_OUT_EP 0x04
|
||||
#define CDC_INT_EP 0x85
|
||||
|
||||
#define USBD_VID 0xd6e7
|
||||
#define USBD_PID 0x3507
|
||||
#define USBD_MAX_POWER 500
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
#define CMSIS_DAP_INTERFACE_SIZE (9 + 7 + 7)
|
||||
#define USB_CONFIG_SIZE (9 + CMSIS_DAP_INTERFACE_SIZE + CDC_ACM_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#define WCID_VENDOR_CODE 0x01
|
||||
|
||||
__ALIGN_BEGIN const uint8_t WCID_StringDescriptor_MSOS[18] __ALIGN_END = {
|
||||
///////////////////////////////////////
|
||||
/// MS OS string descriptor
|
||||
///////////////////////////////////////
|
||||
0x12, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
/* MSFT100 */
|
||||
'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, /* wcChar_7 */
|
||||
'1', 0x00, '0', 0x00, '0', 0x00, /* wcChar_7 */
|
||||
WCID_VENDOR_CODE, /* bVendorCode */
|
||||
0x00, /* bReserved */
|
||||
};
|
||||
|
||||
__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[40] __ALIGN_END = {
|
||||
///////////////////////////////////////
|
||||
/// WCID descriptor
|
||||
///////////////////////////////////////
|
||||
0x28, 0x00, 0x00, 0x00, /* dwLength */
|
||||
0x00, 0x01, /* bcdVersion */
|
||||
0x04, 0x00, /* wIndex */
|
||||
0x01, /* bCount */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
|
||||
|
||||
///////////////////////////////////////
|
||||
/// WCID function descriptor
|
||||
///////////////////////////////////////
|
||||
0x00, /* bFirstInterfaceNumber */
|
||||
0x01, /* bReserved */
|
||||
/* WINUSB */
|
||||
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8 */
|
||||
/* */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
|
||||
};
|
||||
|
||||
__ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties[142] __ALIGN_END = {
|
||||
///////////////////////////////////////
|
||||
/// WCID property descriptor
|
||||
///////////////////////////////////////
|
||||
0x8e, 0x00, 0x00, 0x00, /* dwLength */
|
||||
0x00, 0x01, /* bcdVersion */
|
||||
0x05, 0x00, /* wIndex */
|
||||
0x01, 0x00, /* wCount */
|
||||
|
||||
///////////////////////////////////////
|
||||
/// registry propter descriptor
|
||||
///////////////////////////////////////
|
||||
0x84, 0x00, 0x00, 0x00, /* dwSize */
|
||||
0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
|
||||
0x28, 0x00, /* wPropertyNameLength */
|
||||
/* DeviceInterfaceGUID */
|
||||
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
|
||||
'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
|
||||
't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
|
||||
'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
|
||||
'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
|
||||
0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
|
||||
/* {CDB3B5AD-293B-4663-AA36-1AAE46463776} */
|
||||
'{', 0x00, 'C', 0x00, 'D', 0x00, 'B', 0x00, /* wcData_39 */
|
||||
'3', 0x00, 'B', 0x00, '5', 0x00, 'A', 0x00, /* wcData_39 */
|
||||
'D', 0x00, '-', 0x00, '2', 0x00, '9', 0x00, /* wcData_39 */
|
||||
'3', 0x00, 'B', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
|
||||
'6', 0x00, '6', 0x00, '3', 0x00, '-', 0x00, /* wcData_39 */
|
||||
'A', 0x00, 'A', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
|
||||
'-', 0x00, '1', 0x00, 'A', 0x00, 'A', 0x00, /* wcData_39 */
|
||||
'E', 0x00, '4', 0x00, '6', 0x00, '4', 0x00, /* wcData_39 */
|
||||
'6', 0x00, '3', 0x00, '7', 0x00, '7', 0x00, /* wcData_39 */
|
||||
'6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
|
||||
};
|
||||
|
||||
struct usb_msosv1_descriptor msosv1_desc = {
|
||||
.string = (uint8_t *)WCID_StringDescriptor_MSOS,
|
||||
.string_len = 18,
|
||||
.vendor_code = WCID_VENDOR_CODE,
|
||||
.compat_id = (uint8_t *)WINUSB_WCIDDescriptor,
|
||||
.compat_id_len = sizeof(WINUSB_WCIDDescriptor),
|
||||
.comp_id_property = (uint8_t *)WINUSB_IF0_WCIDProperties,
|
||||
.comp_id_property_len = sizeof(WINUSB_IF0_WCIDProperties),
|
||||
};
|
||||
|
||||
const uint8_t daplink_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
/* Configuration 0 */
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
/* Interface 0 */
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
|
||||
/* Endpoint OUT 1 */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(DAP_IN_EP, USB_ENDPOINT_TYPE_BULK, CDC_MAX_MPS, 0x00),
|
||||
/* Endpoint IN 2 */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(DAP_OUT_EP, USB_ENDPOINT_TYPE_BULK, CDC_MAX_MPS, 0x00),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, 0x00),
|
||||
/* String 0 (LANGID) */
|
||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||
/* String 1 (Manufacturer) */
|
||||
0x14, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
/* String 2 (Product) */
|
||||
0x28, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'C', 0x00, // wcChar0
|
||||
'h', 0x00, // wcChar1
|
||||
'e', 0x00, // wcChar2
|
||||
'r', 0x00, // wcChar3
|
||||
'r', 0x00, // wcChar4
|
||||
'y', 0x00, // wcChar5
|
||||
'U', 0x00, // wcChar6
|
||||
'S', 0x00, // wcChar7
|
||||
'B', 0x00, // wcChar8
|
||||
' ', 0x00, // wcChar9
|
||||
'C', 0x00, // wcChar10
|
||||
'M', 0x00, // wcChar11
|
||||
'S', 0x00, // wcChar12
|
||||
'I', 0x00, // wcChar13
|
||||
'S', 0x00, // wcChar14
|
||||
'-', 0x00, // wcChar15
|
||||
'D', 0x00, // wcChar16
|
||||
'A', 0x00, // wcChar17
|
||||
'P', 0x00, // wcChar18
|
||||
/* String 3 (Serial Number) */
|
||||
0x1A, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'0', 0, // wcChar0
|
||||
'1', 0, // wcChar1
|
||||
'2', 0, // wcChar2
|
||||
'3', 0, // wcChar3
|
||||
'4', 0, // wcChar4
|
||||
'5', 0, // wcChar5
|
||||
'A', 0, // wcChar6
|
||||
'B', 0, // wcChar7
|
||||
'C', 0, // wcChar8
|
||||
'D', 0, // wcChar9
|
||||
'E', 0, // wcChar10
|
||||
'F', 0, // wcChar11
|
||||
#ifdef CONFIG_USB_HS
|
||||
/* Device Qualifier */
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x10,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
#endif
|
||||
/* End */
|
||||
0x00
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_read_buffer[CDC_MAX_MPS];
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t USB_Request[DAP_PACKET_SIZE];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t USB_Response[DAP_PACKET_SIZE];
|
||||
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, cdc_read_buffer, CDC_MAX_MPS);
|
||||
usbd_ep_start_read(DAP_OUT_EP, USB_Request, DAP_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
/* setup next out ep read transfer */
|
||||
if (1) {
|
||||
usbd_ep_start_read(CDC_OUT_EP, cdc_read_buffer, CDC_MAX_MPS);
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(CDC_IN_EP, NULL, 0);
|
||||
} else {
|
||||
ep_tx_busy_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
void usb_dap_recv_callback(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
uint32_t actual_len;
|
||||
if (USB_Request[0] == ID_DAP_TransferAbort) {
|
||||
usbd_ep_start_read(ep, USB_Request, DAP_PACKET_SIZE);
|
||||
DAP_TransferAbort = 1;
|
||||
return;
|
||||
}
|
||||
actual_len = DAP_ProcessCommand(USB_Request, USB_Response);
|
||||
|
||||
usbd_ep_start_write(DAP_IN_EP, USB_Response, actual_len);
|
||||
usbd_ep_start_read(ep, USB_Request, DAP_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void usb_dap_send_callback(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(DAP_IN_EP, NULL, 0);
|
||||
} else {
|
||||
ep_tx_busy_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
static struct usbd_endpoint cdc_out_ep = {
|
||||
.ep_addr = CDC_OUT_EP,
|
||||
.ep_cb = usbd_cdc_acm_bulk_out
|
||||
};
|
||||
|
||||
static struct usbd_endpoint cdc_in_ep = {
|
||||
.ep_addr = CDC_IN_EP,
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
|
||||
static struct usbd_endpoint dap_out_ep = {
|
||||
.ep_addr = DAP_OUT_EP,
|
||||
.ep_cb = usb_dap_recv_callback
|
||||
};
|
||||
static struct usbd_endpoint dap_in_ep = {
|
||||
.ep_addr = DAP_IN_EP,
|
||||
.ep_cb = usb_dap_send_callback
|
||||
};
|
||||
|
||||
struct usbd_interface dap_interface;
|
||||
struct usbd_interface intf1;
|
||||
struct usbd_interface intf2;
|
||||
|
||||
void daplink_init(void)
|
||||
{
|
||||
usbd_desc_register(daplink_descriptor);
|
||||
usbd_msosv1_desc_register(&msosv1_desc);
|
||||
|
||||
/*!< winusb */
|
||||
usbd_add_interface(&dap_interface);
|
||||
usbd_add_endpoint(&dap_out_ep);
|
||||
usbd_add_endpoint(&dap_in_ep);
|
||||
|
||||
/*!< cdc acm */
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf1));
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf2));
|
||||
usbd_add_endpoint(&cdc_out_ep);
|
||||
usbd_add_endpoint(&cdc_in_ep);
|
||||
|
||||
usbd_initialize();
|
||||
}
|
||||
@@ -137,9 +137,29 @@ const uint8_t dfu_flash_descriptor[] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
void usbd_event_handler(uint8_t event)
|
||||
{
|
||||
/* no out ep, do nothing */
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_interface intf0;
|
||||
|
||||
@@ -1,317 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_acmp.h
|
||||
* @brief Header file of ACMP module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 26 Jun 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 26 Jun 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_ACMP_H__
|
||||
#define __ALD_ACMP_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup ACMP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup ACMP_Public_Types ACMP Public Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief ACMP interrupt
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_IT_EDGE = (1U << 0), /**< Edge interrupt bit */
|
||||
ACMP_IT_WARMUP = (1U << 1), /**< Warm up interrupt bit */
|
||||
} acmp_it_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP interrupt flag
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_FLAG_EDGE = (1U << 0), /**< Edge interrupt flag */
|
||||
ACMP_FLAG_WARMUP = (1U << 1), /**< Warm up interrupt flag */
|
||||
} acmp_flag_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP status flag
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_STATUS_ACT = (1U << 0), /**< Edge status flag */
|
||||
ACMP_STATUS_OUT = (1U << 1), /**< Warm up status flag */
|
||||
} acmp_status_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP positive input
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_POS_CH0 = 0x0U, /**< Channel 0 as positive input */
|
||||
ACMP_POS_CH1 = 0x1U, /**< Channel 1 as positive input */
|
||||
ACMP_POS_CH2 = 0x2U, /**< Channel 2 as positive input */
|
||||
ACMP_POS_CH3 = 0x3U, /**< Channel 3 as positive input */
|
||||
ACMP_POS_CH4 = 0x4U, /**< Channel 4 as positive input */
|
||||
ACMP_POS_CH5 = 0x5U, /**< Channel 5 as positive input */
|
||||
ACMP_POS_CH6 = 0x6U, /**< Channel 6 as positive input */
|
||||
ACMP_POS_CH7 = 0x7U, /**< Channel 7 as positive input */
|
||||
} acmp_pos_input_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP negative input
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_NEG_CH0 = 0x0U, /**< Channel 0 as negative input */
|
||||
ACMP_NEG_CH1 = 0x1U, /**< Channel 1 as negative input */
|
||||
ACMP_NEG_CH2 = 0x2U, /**< Channel 2 as negative input */
|
||||
ACMP_NEG_CH3 = 0x3U, /**< Channel 3 as negative input */
|
||||
ACMP_NEG_CH4 = 0x4U, /**< Channel 4 as negative input */
|
||||
ACMP_NEG_CH5 = 0x5U, /**< Channel 5 as negative input */
|
||||
ACMP_NEG_CH6 = 0x6U, /**< Channel 6 as negative input */
|
||||
ACMP_NEG_CH7 = 0x7U, /**< Channel 7 as negative input */
|
||||
ACMP_NEG_1V25 = 0x8U, /**< 1.25v as negative input */
|
||||
ACMP_NEG_2V5 = 0x9U, /**< 2.5v as negative input */
|
||||
ACMP_NEG_VDD = 0xAU, /**< VDD as negative input */
|
||||
} acmp_neg_input_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP mode
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_ULTRA_LOW_POWER = 0x0U, /**< Ultra low power mode */
|
||||
ACMP_LOW_POWER = 0x1U, /**< Low power mode */
|
||||
ACMP_MIDDLE_POWER = 0x2U, /**< Middle power mode */
|
||||
ACMP_HIGH_POWER = 0x3U, /**< High power mode */
|
||||
} acmp_mode_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP warm-up time
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_4_PCLK = 0x0U, /**< 4 hfperclk cycles */
|
||||
ACMP_8_PCLK = 0x1U, /**< 4 hfperclk cycles */
|
||||
ACMP_16_PCLK = 0x2U, /**< 4 hfperclk cycles */
|
||||
ACMP_32_PCLK = 0x3U, /**< 4 hfperclk cycles */
|
||||
ACMP_64_PCLK = 0x4U, /**< 4 hfperclk cycles */
|
||||
ACMP_128_PCLK = 0x5U, /**< 4 hfperclk cycles */
|
||||
ACMP_256_PCLK = 0x6U, /**< 4 hfperclk cycles */
|
||||
ACMP_512_PCLK = 0x7U, /**< 4 hfperclk cycles */
|
||||
} acmp_warm_time_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP hysteresis level
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_HYST_0 = 0x0U, /**< No hysteresis */
|
||||
ACMP_HYST_15 = 0x1U, /**< 15mV hysteresis */
|
||||
ACMP_HYST_22 = 0x2U, /**< 22mV hysteresis */
|
||||
ACMP_HYST_29 = 0x3U, /**< 29mV hysteresis */
|
||||
ACMP_HYST_36 = 0x4U, /**< 36mV hysteresis */
|
||||
ACMP_HYST_43 = 0x5U, /**< 43mV hysteresis */
|
||||
ACMP_HYST_50 = 0x6U, /**< 50mV hysteresis */
|
||||
ACMP_HYST_57 = 0x7U, /**< 57mV hysteresis */
|
||||
} acmp_hystsel_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP inactive state
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_INACTVAL_LOW = 0x0U, /**< The inactive value is 0 */
|
||||
ACMP_INACTVAL_HIGH = 0x1U, /**< The inactive value is 1 */
|
||||
} acmp_inactval_t;
|
||||
|
||||
/**
|
||||
* @brief which edges set up interrupt
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_EDGE_NONE = 0x0U, /**< Disable EDGE interrupt */
|
||||
ACMP_EDGE_FALL = 0x1U, /**< Falling edges set EDGE interrupt */
|
||||
ACMP_EDGE_RISE = 0x2U, /**< rise edges set EDGE interrupt */
|
||||
ACMP_EDGE_ALL = 0x3U, /**< Falling edges and rise edges set EDGE interrupt */
|
||||
} acmp_edge_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP output function
|
||||
*/
|
||||
typedef enum {
|
||||
ACMP_OUT_DISABLE = 0x0U, /**< Disable acmp output */
|
||||
ACMP_OUT_ENABLE = 0x1U, /**< Enable acmp output */
|
||||
} acmp_out_func_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP init structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
acmp_mode_t mode; /**< ACMP operation mode */
|
||||
acmp_warm_time_t warm_time; /**< ACMP warm up time */
|
||||
acmp_hystsel_t hystsel; /**< ACMP hysteresis level */
|
||||
acmp_pos_input_t p_port; /**< ACMP positive port select */
|
||||
acmp_neg_input_t n_port; /**< ACMP negative port select */
|
||||
acmp_inactval_t inactval; /**< ACMP inavtive output value */
|
||||
type_func_t out_inv; /**< ACMP output inverse */
|
||||
acmp_edge_t edge; /**< Select edges to set interrupt flag */
|
||||
uint8_t vdd_level; /**< Select scaling factor for CDD reference level, MAX is 63 */
|
||||
} acmp_init_t;
|
||||
|
||||
/**
|
||||
* @brief ACMP Handle Structure definition
|
||||
*/
|
||||
typedef struct acmp_handle_s {
|
||||
ACMP_TypeDef *perh; /**< Register base address */
|
||||
acmp_init_t init; /**< ACMP required parameters */
|
||||
lock_state_t lock; /**< Locking object */
|
||||
|
||||
void (*acmp_warmup_cplt_cbk)(struct acmp_handle_s *arg); /**< ACMP warm-up complete callback */
|
||||
void (*acmp_edge_cplt_cbk)(struct acmp_handle_s *arg); /**< ACMP edge trigger callback */
|
||||
} acmp_handle_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup ACMP_Public_Macros ACMP Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define ACMP_ENABLE(handle) (SET_BIT((handle)->perh->CON, ACMP_CON_EN_MSK))
|
||||
#define ACMP_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, ACMP_CON_EN_MSK))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup ACMP_Private_Macros ACMP Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_ACMP_TYPE(x) (((x) == ACMP0) || \
|
||||
((x) == ACMP1) || \
|
||||
((x) == ACMP2))
|
||||
#define IS_ACMP_MODE_TYPE(x) (((x) == ACMP_ULTRA_LOW_POWER) || \
|
||||
((x) == ACMP_LOW_POWER) || \
|
||||
((x) == ACMP_MIDDLE_POWER) || \
|
||||
((x) == ACMP_HIGH_POWER))
|
||||
#define IS_ACMP_IT_TYPE(x) (((x) == ACMP_IT_EDGE) || \
|
||||
((x) == ACMP_IT_WARMUP))
|
||||
#define IS_ACMP_FLAG_TYPE(x) (((x) == ACMP_FLAG_EDGE) || \
|
||||
((x) == ACMP_FLAG_WARMUP))
|
||||
#define IS_ACMP_STATUS_TYPE(x) (((x) == ACMP_STATUS_ACT) || \
|
||||
((x) == ACMP_STATUS_OUT))
|
||||
#define IS_ACMP_POS_INPUT_TYPE(x) (((x) == ACMP_POS_CH0) || \
|
||||
((x) == ACMP_POS_CH1) || \
|
||||
((x) == ACMP_POS_CH2) || \
|
||||
((x) == ACMP_POS_CH3) || \
|
||||
((x) == ACMP_POS_CH4) || \
|
||||
((x) == ACMP_POS_CH5) || \
|
||||
((x) == ACMP_POS_CH6) || \
|
||||
((x) == ACMP_POS_CH7))
|
||||
#define IS_ACMP_NEG_INPUT_TYPE(x) (((x) == ACMP_NEG_CH0) || \
|
||||
((x) == ACMP_NEG_CH1) || \
|
||||
((x) == ACMP_NEG_CH2) || \
|
||||
((x) == ACMP_NEG_CH3) || \
|
||||
((x) == ACMP_NEG_CH4) || \
|
||||
((x) == ACMP_NEG_CH5) || \
|
||||
((x) == ACMP_NEG_CH6) || \
|
||||
((x) == ACMP_NEG_CH7) || \
|
||||
((x) == ACMP_NEG_1V25) || \
|
||||
((x) == ACMP_NEG_2V5) || \
|
||||
((x) == ACMP_NEG_VDD))
|
||||
#define IS_ACMP_WARM_UP_TIME_TYPE(x) (((x) == ACMP_4_PCLK) || \
|
||||
((x) == ACMP_8_PCLK) || \
|
||||
((x) == ACMP_16_PCLK) || \
|
||||
((x) == ACMP_32_PCLK) || \
|
||||
((x) == ACMP_64_PCLK) || \
|
||||
((x) == ACMP_128_PCLK) || \
|
||||
((x) == ACMP_256_PCLK) || \
|
||||
((x) == ACMP_512_PCLK))
|
||||
#define IS_ACMP_HYSTSEL_TYPE(x) (((x) == ACMP_HYST_0) || \
|
||||
((x) == ACMP_HYST_15) || \
|
||||
((x) == ACMP_HYST_22) || \
|
||||
((x) == ACMP_HYST_29) || \
|
||||
((x) == ACMP_HYST_36) || \
|
||||
((x) == ACMP_HYST_43) || \
|
||||
((x) == ACMP_HYST_50) || \
|
||||
((x) == ACMP_HYST_57))
|
||||
#define IS_ACMP_INACTVAL_TYPE(x) (((x) == ACMP_INACTVAL_LOW) || \
|
||||
((x) == ACMP_INACTVAL_HIGH))
|
||||
#define IS_ACMP_EDGE_TYPE(x) (((x) == ACMP_EDGE_NONE) || \
|
||||
((x) == ACMP_EDGE_FALL) || \
|
||||
((x) == ACMP_EDGE_RISE) || \
|
||||
((x) == ACMP_EDGE_ALL))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup ACMP_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup ACMP_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_acmp_init(acmp_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup ACMP_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
void ald_acmp_interrupt_config(acmp_handle_t *hperh, acmp_it_t it, type_func_t state);
|
||||
it_status_t ald_acmp_get_it_status(acmp_handle_t *hperh, acmp_it_t it);
|
||||
flag_status_t ald_acmp_get_flag_status(acmp_handle_t *hperh, acmp_flag_t flag);
|
||||
flag_status_t ald_acmp_get_mask_flag_status(acmp_handle_t *hperh, acmp_flag_t flag);
|
||||
void ald_acmp_clear_flag_status(acmp_handle_t *hperh, acmp_flag_t flag);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup ACMP_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
void ald_acmp_irq_handler(acmp_handle_t *hperh);
|
||||
void ald_acmp_out_config(acmp_handle_t *hperh, type_func_t state);
|
||||
uint8_t ald_acmp_out_result(acmp_handle_t *hperh);
|
||||
flag_status_t ald_acmp_get_status(acmp_handle_t *hperh, acmp_status_t status);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" }
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,579 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file ald_adc.h
|
||||
* @brief Header file of ADC Module library.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 28 Jun 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 28 Jun 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_ADC_H__
|
||||
#define __ALD_ADC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "ald_dma.h"
|
||||
#include "ald_pis.h"
|
||||
#include "ald_timer.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup ADC_Pubulic_Types ADC Pubulic Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief ADC State structures definition
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_STATE_RESET = 0x0U, /**< ADC not yet initialized or disabled */
|
||||
ADC_STATE_READY = 0x1U, /**< ADC peripheral ready for use */
|
||||
ADC_STATE_BUSY = 0x2U, /**< ADC is busy to internal process */
|
||||
ADC_STATE_TIMEOUT = 0x4U, /**< TimeOut occurrence */
|
||||
ADC_STATE_ERROR = 0x8U, /**< Internal error occurrence */
|
||||
ADC_STATE_BUSY_N = 0x10U, /**< Normal channel busy */
|
||||
ADC_STATE_BUSY_I = 0x20U, /**< Insert channel busy */
|
||||
ADC_STATE_BUSY_WDG = 0x40U, /**< Insert channel busy */
|
||||
} adc_state_t;
|
||||
|
||||
/**
|
||||
*@brief ADC Error Code
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ERROR_NONE = 0x0U, /**< No error */
|
||||
ADC_ERROR_INTERNAL = 0x1U, /**< ADC IP internal error*/
|
||||
ADC_ERROR_OVR = 0x2U, /**< Overrun error */
|
||||
ADC_ERROR_DMA = 0x4U, /**< DMA transfer error */
|
||||
} adc_error_t;
|
||||
|
||||
/**
|
||||
*@brief ADC data alignment
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_DATAALIGN_RIGHT = 0x0U, /**< ADC data alignment right */
|
||||
ADC_DATAALIGN_LEFT = 0x1U, /**< ADC data alignment left */
|
||||
} adc_align_t;
|
||||
|
||||
/**
|
||||
*@brief ADC config hannal trigger the EOC IT mode
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_NCHESEL_MODE_ALL = 0x0U, /**< ADC set RCHE after convert sequence finish */
|
||||
ADC_NCHESEL_MODE_ONE = 0x1U, /**< ADC set RCHE after one convert finish */
|
||||
} adc_nchesel_t;
|
||||
|
||||
/**
|
||||
*@brief ADC channels
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_CHANNEL_0 = 0x0U, /**< ADC channel 0 */
|
||||
ADC_CHANNEL_1 = 0x1U, /**< ADC channel 1 */
|
||||
ADC_CHANNEL_2 = 0x2U, /**< ADC channel 2 */
|
||||
ADC_CHANNEL_3 = 0x3U, /**< ADC channel 3 */
|
||||
ADC_CHANNEL_4 = 0x4U, /**< ADC channel 4 */
|
||||
ADC_CHANNEL_5 = 0x5U, /**< ADC channel 5 */
|
||||
ADC_CHANNEL_6 = 0x6U, /**< ADC channel 6 */
|
||||
ADC_CHANNEL_7 = 0x7U, /**< ADC channel 7 */
|
||||
ADC_CHANNEL_8 = 0x8U, /**< ADC channel 8 */
|
||||
ADC_CHANNEL_9 = 0x9U, /**< ADC channel 9 */
|
||||
ADC_CHANNEL_10 = 0xAU, /**< ADC channel 10 */
|
||||
ADC_CHANNEL_11 = 0xBU, /**< ADC channel 11 */
|
||||
ADC_CHANNEL_12 = 0xCU, /**< ADC channel 12 */
|
||||
ADC_CHANNEL_13 = 0xDU, /**< ADC channel 13 */
|
||||
ADC_CHANNEL_14 = 0xEU, /**< ADC channel 14 */
|
||||
ADC_CHANNEL_15 = 0xFU, /**< ADC channel 15 */
|
||||
ADC_CHANNEL_16 = 0x10U, /**< ADC channel 16 */
|
||||
ADC_CHANNEL_17 = 0x11U, /**< ADC channel 17 */
|
||||
ADC_CHANNEL_18 = 0x12U, /**< ADC channel 18 */
|
||||
} adc_channel_t;
|
||||
|
||||
/**
|
||||
*@brief ADC sampling times
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_SAMPLETIME_1 = 0x0U, /**< ADC sampling times 1 clk */
|
||||
ADC_SAMPLETIME_2 = 0x1U, /**< ADC sampling times 2 clk */
|
||||
ADC_SAMPLETIME_4 = 0x2U, /**< ADC sampling times 4 clk */
|
||||
ADC_SAMPLETIME_15 = 0x3U, /**< ADC sampling times 15 clk */
|
||||
} adc_samp_t;
|
||||
|
||||
/**
|
||||
*@brief ADC index channel in normal group
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_NCH_IDX_1 = 0x1U, /**< ADC normal channel index 1 */
|
||||
ADC_NCH_IDX_2 = 0x2U, /**< ADC normal channel index 2 */
|
||||
ADC_NCH_IDX_3 = 0x3U, /**< ADC normal channel index 3 */
|
||||
ADC_NCH_IDX_4 = 0x4U, /**< ADC normal channel index 4 */
|
||||
ADC_NCH_IDX_5 = 0x5U, /**< ADC normal channel index 5 */
|
||||
ADC_NCH_IDX_6 = 0x6U, /**< ADC normal channel index 6 */
|
||||
ADC_NCH_IDX_7 = 0x7U, /**< ADC normal channel index 7 */
|
||||
ADC_NCH_IDX_8 = 0x8U, /**< ADC normal channel index 8 */
|
||||
ADC_NCH_IDX_9 = 0x9U, /**< ADC normal channel index 9 */
|
||||
ADC_NCH_IDX_10 = 0xAU, /**< ADC normal channel index 10 */
|
||||
ADC_NCH_IDX_11 = 0xBU, /**< ADC normal channel index 11 */
|
||||
ADC_NCH_IDX_12 = 0xCU, /**< ADC normal channel index 12 */
|
||||
ADC_NCH_IDX_13 = 0xDU, /**< ADC normal channel index 13 */
|
||||
ADC_NCH_IDX_14 = 0xEU, /**< ADC normal channel index 14 */
|
||||
ADC_NCH_IDX_15 = 0xFU, /**< ADC normal channel index 15 */
|
||||
ADC_NCH_IDX_16 = 0x10U, /**< ADC normal channel index 16 */
|
||||
} adc_nch_idx_t;
|
||||
|
||||
/**
|
||||
* @brief ADC index channel in insert group
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ICH_IDX_1 = 0x1U, /**< ADC insert channel index 1 */
|
||||
ADC_ICH_IDX_2 = 0x2U, /**< ADC insert channel index 2 */
|
||||
ADC_ICH_IDX_3 = 0x3U, /**< ADC insert channel index 3 */
|
||||
ADC_ICH_IDX_4 = 0x4U, /**< ADC insert channel index 4 */
|
||||
} adc_ich_idx_t;
|
||||
|
||||
/**
|
||||
* @brief ADC analog watchdog mode
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ANAWTD_NONE = 0x0U, /**< No watch dog */
|
||||
ADC_ANAWTD_SING_NM = 0x800200U, /**< One normal channel watch dog */
|
||||
ADC_ANAWTD_SING_IST = 0x400200U, /**< One insert channel Injec watch dog */
|
||||
ADC_ANAWTD_SING_NMIST = 0xC00200U, /**< One normal and insert channel watch dog */
|
||||
ADC_ANAWTD_ALL_NM = 0x800000U, /**< All normal channel watch dog */
|
||||
ADC_ANAWTD_ALL_IST = 0x400000U, /**< All insert channel watch dog */
|
||||
ADC_ANAWTD_ALL_NMIST = 0xC00000U, /**< All normal and insert channel watch dog */
|
||||
} adc_ana_wdg_t;
|
||||
|
||||
/**
|
||||
* @brief ADC Event type
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_AWD_EVENT = (1U << 0), /**< ADC analog watch dog event */
|
||||
} adc_event_type_t;
|
||||
|
||||
/**
|
||||
* @brief ADC interrupts definition
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_IT_NCH = (1U << 5), /**< ADC it normal */
|
||||
ADC_IT_AWD = (1U << 6), /**< ADC it awd */
|
||||
ADC_IT_ICH = (1U << 7), /**< ADC it insert */
|
||||
ADC_IT_OVR = (1U << 26), /**< ADC it overring */
|
||||
} adc_it_t;
|
||||
|
||||
/**
|
||||
* @brief ADC flags definition
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_FLAG_AWD = (1U << 0), /**<ADC flag awd */
|
||||
ADC_FLAG_NCH = (1U << 1), /**<ADC flag normal mode complete */
|
||||
ADC_FLAG_ICH = (1U << 2), /**<ADC flag insert mode complete*/
|
||||
ADC_FLAG_OVR = (1U << 3), /**<ADC flag ovr */
|
||||
ADC_FLAG_NCHS = (1U << 8), /**<ADC flag normal start */
|
||||
ADC_FLAG_ICHS = (1U << 9), /**<ADC flag insert start */
|
||||
} adc_flag_t;
|
||||
|
||||
/**
|
||||
* @brief ADC CLD DIV definition
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_CKDIV_1 = 0x0U, /**< ADC CLK DIV 1 */
|
||||
ADC_CKDIV_2 = 0x1U, /**< ADC CLK DIV 2 */
|
||||
ADC_CKDIV_4 = 0x2U, /**< ADC CLK DIV 4 */
|
||||
ADC_CKDIV_8 = 0x3U, /**< ADC CLK DIV 8 */
|
||||
ADC_CKDIV_16 = 0x4U, /**< ADC CLK DIV 16 */
|
||||
ADC_CKDIV_32 = 0x5U, /**< ADC CLK DIV 32 */
|
||||
ADC_CKDIV_64 = 0x6U, /**< ADC CLK DIV 64 */
|
||||
ADC_CKDIV_128 = 0x7U, /**< ADC CLK DIV 128 */
|
||||
} adc_clk_div_t;
|
||||
|
||||
/**
|
||||
* @brief ADC negative reference voltage definition
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_NEG_REF_VSS = 0x0U, /**< ADC negative regerence voltage vss */
|
||||
ADC_NEG_REF_VREFN = 0x1U, /**< ADC negative regerence voltage vrefn */
|
||||
} adc_neg_ref_t;
|
||||
|
||||
/**
|
||||
* @brief ADC positive reference voltage definition
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_POS_REF_VDD = 0x0U, /**< ADC positive reference is VDD */
|
||||
ADC_POS_REF_2V = 0x1U, /**< ADC positive reference is 2V internal voltage */
|
||||
ADC_POS_REF_VREEFP = 0x2U, /**< ADC positive reference is VREEFP */
|
||||
ADC_POS_REF_VREEFP_BUF = 0x3U, /**< ADC positive reference is VREEFP BUFFER */
|
||||
} adc_pos_ref_t;
|
||||
|
||||
/**
|
||||
* @brief ADC numbers of normal conversion channals
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_NCH_NR_1 = 0x0U, /**< ADC number of normal conversion 1 */
|
||||
ADC_NCH_NR_2 = 0x1U, /**< ADC number of normal conversion 2 */
|
||||
ADC_NCH_NR_3 = 0x2U, /**< ADC number of normal conversion 3 */
|
||||
ADC_NCH_NR_4 = 0x3U, /**< ADC number of normal conversion 4 */
|
||||
ADC_NCH_NR_5 = 0x4U, /**< ADC number of normal conversion 5 */
|
||||
ADC_NCH_NR_6 = 0x5U, /**< ADC number of normal conversion 6 */
|
||||
ADC_NCH_NR_7 = 0x6U, /**< ADC number of normal conversion 7 */
|
||||
ADC_NCH_NR_8 = 0x7U, /**< ADC number of normal conversion 8 */
|
||||
ADC_NCH_NR_9 = 0x8U, /**< ADC number of normal conversion 9 */
|
||||
ADC_NCH_NR_10 = 0x9U, /**< ADC number of normal conversion 10 */
|
||||
ADC_NCH_NR_11 = 0xAU, /**< ADC number of normal conversion 11 */
|
||||
ADC_NCH_NR_12 = 0xBU, /**< ADC number of normal conversion 12 */
|
||||
ADC_NCH_NR_13 = 0xCU, /**< ADC number of normal conversion 13 */
|
||||
ADC_NCH_NR_14 = 0xDU, /**< ADC number of normal conversion 14 */
|
||||
ADC_NCH_NR_15 = 0xEU, /**< ADC number of normal conversion 15 */
|
||||
ADC_NCH_NR_16 = 0xFU, /**< ADC number of normal conversion 16 */
|
||||
} adc_nch_nr_t;
|
||||
|
||||
/**
|
||||
* @brief ADC numbers of insert conversion channals
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ICH_NR_1 = 0x0U, /**< ADC number of insert conversion 1 */
|
||||
ADC_ICH_NR_2 = 0x1U, /**< ADC number of insert conversion 2 */
|
||||
ADC_ICH_NR_3 = 0x2U, /**< ADC number of insert conversion 3 */
|
||||
ADC_ICH_NR_4 = 0x3U, /**< ADC number of insert conversion 4 */
|
||||
} adc_ich_nr_t;
|
||||
|
||||
/**
|
||||
* @brief ADC discontinuous mode choose
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ALL_DISABLE = 0x0U, /**< ADC discontinuous mode all disable */
|
||||
ADC_NCH_DISC_EN = 0x1U, /**< ADC normal channel discontinuous mode enable */
|
||||
ADC_ICH_DISC_EN = 0x2U, /**< ADC insert channel discontinuous mode enable */
|
||||
} adc_disc_mode_t;
|
||||
|
||||
/**
|
||||
* @brief ADC numbers of channals in discontinuous conversion mode
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_DISC_NR_1 = 0x0U, /**< ADC number of discontinuous conversion 1 */
|
||||
ADC_DISC_NR_2 = 0x1U, /**< ADC number of discontinuous conversion 2 */
|
||||
ADC_DISC_NR_3 = 0x2U, /**< ADC number of discontinuous conversion 3 */
|
||||
ADC_DISC_NR_4 = 0x3U, /**< ADC number of discontinuous conversion 4 */
|
||||
ADC_DISC_NR_5 = 0x4U, /**< ADC number of discontinuous conversion 5 */
|
||||
ADC_DISC_NR_6 = 0x5U, /**< ADC number of discontinuous conversion 6 */
|
||||
ADC_DISC_NR_7 = 0x6U, /**< ADC number of discontinuous conversion 7 */
|
||||
ADC_DISC_NR_8 = 0x7U, /**< ADC number of discontinuous conversion 8 */
|
||||
} adc_disc_nr_t;
|
||||
|
||||
/**
|
||||
* @brief ADC resolution of conversion
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_CONV_BIT_6 = 0x0U, /**< ADC resolution of conversion 6 */
|
||||
ADC_CONV_BIT_8 = 0x1U, /**< ADC resolution of conversion 8 */
|
||||
ADC_CONV_BIT_10 = 0x2U, /**< ADC resolution of conversion 10 */
|
||||
ADC_CONV_BIT_12 = 0x3U, /**< ADC resolution of conversion 12 */
|
||||
} adc_conv_bit_t;
|
||||
|
||||
/**
|
||||
* @brief ADC external trigger mode choose
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ETS_DISABLE = 0x0U, /**< ADC external trigger function disable */
|
||||
ADC_ETS_RISE = 0x1U, /**< rise edge trigger ADC */
|
||||
ADC_ETS_FALL = 0x2U, /**< fall edge trigger ADC */
|
||||
ADC_ETS_RISE_FALL = 0x3U, /**< both rise and fall edge trigger ADC */
|
||||
} adc_ets_t;
|
||||
|
||||
/**
|
||||
* @brief ADC trigger conversion mode
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Structure definition of ADC and normal group initialization
|
||||
*/
|
||||
typedef struct {
|
||||
adc_align_t align; /**< Specifies ADC data alignment */
|
||||
type_func_t scan; /**< Choose scan mode enable or not */
|
||||
type_func_t cont; /**< Choose continuous mode enable or not */
|
||||
adc_nch_nr_t nch_nr; /**< Length of normal ranks will be converted */
|
||||
adc_ich_nr_t ich_nr; /**< Length of insert ranks will be converted */
|
||||
adc_disc_mode_t disc; /**< Discontinuous mode enable or not */
|
||||
adc_disc_nr_t disc_nr; /**< Number of discontinuous conversions channel */
|
||||
adc_conv_bit_t data_bit; /**< The precision of conversion */
|
||||
adc_clk_div_t div; /**< ADCCLK divider */
|
||||
adc_nchesel_t nche_sel; /**< Trigger the NCHE FALG mode */
|
||||
adc_neg_ref_t n_ref; /**< The negative reference voltage*/
|
||||
adc_pos_ref_t p_ref; /**< The positive reference voltage*/
|
||||
} adc_init_t;
|
||||
|
||||
/**
|
||||
* @brief Structure definition of ADC channel for normal group
|
||||
*/
|
||||
typedef struct {
|
||||
adc_channel_t ch; /**< The channel to configure into ADC normal group */
|
||||
adc_nch_idx_t idx; /**< The rank in the normal group sequencer */
|
||||
adc_samp_t samp; /**< Sampling time value to be set */
|
||||
} adc_nch_conf_t;
|
||||
|
||||
/**
|
||||
* @brief ADC Configuration analog watchdog definition
|
||||
*/
|
||||
typedef struct {
|
||||
adc_ana_wdg_t mode; /**< Configures the ADC analog watchdog mode*/
|
||||
adc_channel_t ch; /**< Selects which ADC channel to monitor by analog watchdog */
|
||||
type_func_t interrupt; /**< Whether the analog watchdog is configured in interrupt */
|
||||
uint32_t high_thrd; /**< The ADC analog watchdog High threshold value. */
|
||||
uint32_t low_thrd; /**< The ADC analog watchdog Low threshold value. */
|
||||
} adc_analog_wdg_conf_t;
|
||||
|
||||
/**
|
||||
* @brief ADC Configuration insert Channel structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
adc_channel_t ch; /**< Selection of ADC channel to configure */
|
||||
adc_ich_idx_t idx; /**< Rank in the insert group sequencer */
|
||||
adc_samp_t samp; /**< Sampling time value for selected channel */
|
||||
uint32_t offset; /**< The offset about converted data */
|
||||
adc_ich_nr_t nr; /**< The number of insert ranks */
|
||||
type_func_t auto_m; /**< insert sequence's auto function */
|
||||
} adc_ich_conf_t;
|
||||
|
||||
/**
|
||||
* @brief ADC handle Structure definition
|
||||
*/
|
||||
typedef struct adc_handle_s {
|
||||
ADC_TypeDef *perh; /**< Register base address */
|
||||
adc_init_t init; /**< ADC required parameters */
|
||||
|
||||
dma_handle_t hdma; /**< Pointer DMA Handler */
|
||||
pis_handle_t hpis; /**< Pointer PIS Handler for connect adc and dma */
|
||||
|
||||
lock_state_t lock; /**< ADC locking object */
|
||||
adc_state_t state; /**< ADC communication state */
|
||||
adc_error_t error_code; /**< ADC Error code */
|
||||
|
||||
void (*normal_cplt_cbk)( struct adc_handle_s *arg); /**< Regluar Conversion complete callback */
|
||||
void (*insert_cplt_cbk)( struct adc_handle_s *arg); /**< insert Conversion complete callback */
|
||||
void (*wdg_cbk)( struct adc_handle_s *arg); /**< Level out of window callback */
|
||||
void (*error_cbk)(struct adc_handle_s *arg); /**< adc error callback */
|
||||
void (*ovr_cbk)(struct adc_handle_s *arg); /**< adc ovr callback */
|
||||
} adc_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Timer trigger adc config structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t time; /**< Timer period time uint: us */
|
||||
uint16_t size; /**< Adc convert times */
|
||||
uint16_t *buf; /**< Convert data buffer */
|
||||
adc_neg_ref_t n_ref; /**< The negative reference voltage for adc*/
|
||||
adc_pos_ref_t p_ref; /**< The positive reference voltage for adc*/
|
||||
adc_channel_t adc_ch; /**< Adc channel */
|
||||
uint8_t dma_ch; /**< Dma channel */
|
||||
TIMER_TypeDef *p_timer; /**< Timer peripheral */
|
||||
ADC_TypeDef *p_adc; /**< Adc peripheral */
|
||||
void (*cplt_cbk)( struct adc_handle_s *arg); /**< Conversion complete callback */
|
||||
|
||||
/* private variable */
|
||||
lock_state_t lock; /**< Locking object */
|
||||
pis_handle_t h_pis; /**< Handle of PIS module */
|
||||
dma_handle_t h_dma; /**< Handle of DMA module */
|
||||
timer_handle_t h_timer; /**< Handle of TIMER module */
|
||||
adc_handle_t h_adc; /**< Handle of ADC module */
|
||||
adc_nch_conf_t config; /**< Struct for chanel configure */
|
||||
adc_ich_conf_t i_config;/**< Struct for insert channel configuration */
|
||||
} adc_timer_config_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup ADC_Public_Macros ADC Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define ADC_ENABLE(handle) (SET_BIT((handle)->perh->CON1, ADC_CON1_ADCEN_MSK))
|
||||
#define ADC_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON1, ADC_CON1_ADCEN_MSK))
|
||||
#define ADC_NH_TRIG_BY_SOFT(handle) (SET_BIT((handle)->perh->CON1, ADC_CON1_NCHTRG_MSK))
|
||||
#define ADC_IH_TRIG_BY_SOFT(handle) (SET_BIT((handle)->perh->CON1, ADC_CON1_ICHTRG_MSK))
|
||||
#define ADC_RESET_HANDLE_STATE(handle) ((handle)->state = ADC_STATE_RESET)
|
||||
#define ADC_VREF_OUT_ENABLE(handle) (SET_BIT((handle)->perh->CCR, ADC_CCR_VREFOEN_MSK))
|
||||
#define ADC_VREF_OUT_DISABLE(handle) (CLEAR_BIT((handle)->perh->CCR, ADC_CCR_VREFOEN_MSK))
|
||||
#define ADC_NETS_ENABLE(handle, mode) (MODIFY_REG((handle)->perh->CON1, ADC_CON1_NETS_MSK, (mode) << ADC_CON1_NETS_POSS))
|
||||
#define ADC_IETS_ENABLE(handle, mode) (MODIFY_REG((handle)->perh->CON1, ADC_CON1_IETS_MSK, (mode) << ADC_CON1_IETS_POSS))
|
||||
#define ADC_NETS_DISABLE(handle) (MODIFY_REG((handle)->perh->CON1, ADC_CON1_NETS_MSK, 0 << ADC_CON1_NETS_POSS))
|
||||
#define ADC_IETS_DISABLE(handle) (MODIFY_REG((handle)->perh->CON1, ADC_CON1_IETS_MSK, 0 << ADC_CON1_IETS_POSS))
|
||||
#define ADC_SPEED_HIGH_ENABLE(handle) (SET_BIT((handle)->perh->CCR, ADC_CCR_PWRMODSEL_MSK))
|
||||
#define ADC_SPEED_HIGH_DISABLE(handle) (CLEAR_BIT((handle)->perh->CCR, ADC_CCR_PWRMODSEL_MSK))
|
||||
#define ADC_CALIBRATE_ENABLE(handle) (SET_BIT((handle)->perh->CCR, ADC_CCR_TRMEN_MSK))
|
||||
#define ADC_CALIBRATE_DISABLE(handle) (CLEAR_BIT((handle)->perh->CCR, ADC_CCR_TRMEN_MSK))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup ADC_Private_Macros ADC Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_ADC_ICH_IDX_TYPE(x) ((x) <= ADC_ICH_IDX_4)
|
||||
#define IS_ADC_NCH_IDX_TYPE(x) ((x) <= ADC_NCH_IDX_16)
|
||||
#define IS_ADC_SAMPLING_TIMES_TYPE(x) (((x) == ADC_SAMPLETIME_1) || \
|
||||
((x) == ADC_SAMPLETIME_2) || \
|
||||
((x) == ADC_SAMPLETIME_4) || \
|
||||
((x) == ADC_SAMPLETIME_15))
|
||||
#define IS_ADC_CHANNELS_TYPE(x) ((x) <= ADC_CHANNEL_18)
|
||||
#define IS_ADC_DATA_ALIGN_TYPE(x) (((x) == ADC_DATAALIGN_RIGHT) || \
|
||||
((x) == ADC_DATAALIGN_LEFT))
|
||||
#define IS_ADC_ANALOG_WTD_MODE_TYPE(x) (((x) == ADC_ANAWTD_NONE) || \
|
||||
((x) == ADC_ANAWTD_SING_NM) || \
|
||||
((x) == ADC_ANAWTD_SING_IST) || \
|
||||
((x) == ADC_ANAWTD_SING_NMIST) || \
|
||||
((x) == ADC_ANAWTD_ALL_NM) || \
|
||||
((x) == ADC_ANAWTD_ALL_IST) || \
|
||||
((x) == ADC_ANAWTD_ALL_NMIST))
|
||||
#define IS_ADC_IT_TYPE(x) (((x) == ADC_IT_NCH) || \
|
||||
((x) == ADC_IT_AWD) || \
|
||||
((x) == ADC_IT_ICH) || \
|
||||
((x) == ADC_IT_OVR ))
|
||||
#define IS_ADC_FLAGS_TYPE(x) (((x) == ADC_FLAG_AWD) || \
|
||||
((x) == ADC_FLAG_NCH) || \
|
||||
((x) == ADC_FLAG_ICH) || \
|
||||
((x) == ADC_FLAG_OVR) || \
|
||||
((x) == ADC_FLAG_NCHS) || \
|
||||
((x) == ADC_FLAG_ICHS))
|
||||
#define IS_ADC_CLK_DIV_TYPE(x) (((x) == ADC_CKDIV_1) || \
|
||||
((x) == ADC_CKDIV_2) || \
|
||||
((x) == ADC_CKDIV_4) || \
|
||||
((x) == ADC_CKDIV_8) || \
|
||||
((x) == ADC_CKDIV_16) || \
|
||||
((x) == ADC_CKDIV_32) || \
|
||||
((x) == ADC_CKDIV_64) || \
|
||||
((x) == ADC_CKDIV_128))
|
||||
#define IS_ADC_NEG_REF_VOLTAGE_TYPE(x) (((x) == ADC_NEG_REF_VSS ) || \
|
||||
((x) == ADC_NEG_REF_VREFN ))
|
||||
#define IS_POS_REF_VOLTAGE_TYPE(x) (((x) == ADC_POS_REF_VDD) || \
|
||||
((x) == ADC_POS_REF_2V) || \
|
||||
((x) == ADC_POS_REF_VREEFP) || \
|
||||
((x) == ADC_POS_REF_VREEFP_BUF))
|
||||
#define IS_ADC_NCH_NR_TYPE(x) ((x) <= ADC_NCH_NR_16)
|
||||
#define IS_ADC_ICH_NR_TYPE(x) ((x) <= ADC_ICH_NR_4)
|
||||
#define IS_ADC_DISC_NR_TYPE(x) ((x) <= ADC_DISC_NR_8)
|
||||
#define IS_ADC_CONV_BIT_TYPE(x) (((x) == ADC_CONV_BIT_12) || \
|
||||
((x) == ADC_CONV_BIT_6) || \
|
||||
((x) == ADC_CONV_BIT_8) || \
|
||||
((x) == ADC_CONV_BIT_10))
|
||||
#define IS_ADC_TYPE(x) (((x) == ADC0) || \
|
||||
((x) == ADC1))
|
||||
#define IS_ADC_NCHESEL_MODE_TYPE(x) (((x) == ADC_NCHESEL_MODE_ALL) || \
|
||||
((x) == ADC_NCHESEL_MODE_ONE))
|
||||
#define IS_ADC_EVENT_TYPE(x) ((x) == ADC_AWD_EVENT)
|
||||
#define IS_ADC_IST_OFFSET_TYPE(x) ((x) <= 0xfff)
|
||||
#define IS_HTR_TYPE(x) ((x) <= 0xfff)
|
||||
#define IS_LTR_TYPE(x) ((x) <= 0xfff)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup ADC_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup ADC_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_adc_init(adc_handle_t *hperh);
|
||||
ald_status_t ald_adc_reset(adc_handle_t *hperh);
|
||||
void ald_adc_offset_adjust(uint32_t refmv);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup ADC_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_adc_normal_start(adc_handle_t *hperh);
|
||||
ald_status_t ald_adc_normal_stop(adc_handle_t *hperh);
|
||||
ald_status_t ald_adc_normal_poll_for_conversion(adc_handle_t *hperh, uint32_t timeout);
|
||||
ald_status_t ald_adc_poll_for_event(adc_handle_t *hperh, adc_event_type_t event_type, uint32_t timeout);
|
||||
ald_status_t ald_adc_normal_start_by_it(adc_handle_t *hperh);
|
||||
ald_status_t ald_adc_normal_stop_by_it(adc_handle_t *hperh);
|
||||
#ifdef ALD_DMA
|
||||
ald_status_t ald_adc_start_by_dma(adc_handle_t *hperh, uint16_t *buf, uint16_t size, uint8_t channel);
|
||||
ald_status_t ald_adc_stop_by_dma(adc_handle_t *hperh, uint8_t channel);
|
||||
ald_status_t ald_adc_timer_trigger_adc_by_dma(adc_timer_config_t *config);
|
||||
ald_status_t ald_adc_timer_trigger_insert(adc_timer_config_t *config);
|
||||
#endif
|
||||
uint32_t ald_adc_normal_get_value(adc_handle_t *hperh);
|
||||
ald_status_t ald_adc_insert_start(adc_handle_t *hperh);
|
||||
ald_status_t ald_adc_insert_stop(adc_handle_t *hperh);
|
||||
ald_status_t ald_adc_insert_poll_for_conversion(adc_handle_t *hperh, uint32_t timeout);
|
||||
ald_status_t ald_adc_insert_start_by_it(adc_handle_t *hperh);
|
||||
ald_status_t ald_adc_insert_stop_by_it(adc_handle_t *hperh);
|
||||
uint32_t ald_adc_insert_get_value(adc_handle_t *hperh, adc_ich_idx_t ih_rank);
|
||||
void ald_adc_irq_handler(adc_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup ADC_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_adc_normal_channel_config(adc_handle_t *hperh, adc_nch_conf_t *config);
|
||||
ald_status_t ald_adc_insert_channel_config(adc_handle_t *hperh, adc_ich_conf_t *config);
|
||||
ald_status_t ald_adc_analog_wdg_config(adc_handle_t *hperh, adc_analog_wdg_conf_t *config);
|
||||
void ald_adc_interrupt_config(adc_handle_t *hperh, adc_it_t it, type_func_t state);
|
||||
it_status_t ald_adc_get_it_status(adc_handle_t *hperh, adc_it_t it);
|
||||
flag_status_t ald_adc_get_flag_status(adc_handle_t *hperh, adc_flag_t flag);
|
||||
void ald_adc_clear_flag_status(adc_handle_t *hperh, adc_flag_t flag);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup ADC_Public_Functions_Group4
|
||||
* @{
|
||||
*/
|
||||
uint32_t ald_adc_get_state(adc_handle_t *hperh);
|
||||
uint32_t ald_adc_get_error(adc_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" }
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_ADC_H */
|
||||
@@ -1,212 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_bkpc.h
|
||||
* @brief Header file of BKPC module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 15 Dec 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 15 Dec 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_BKPC_H__
|
||||
#define __ALD_BKPC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup BKPC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup BKPC_Public_Macros BKPC Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define BKPC_LOCK() (WRITE_REG(BKPC->PROT, 0U))
|
||||
#define BKPC_UNLOCK() (WRITE_REG(BKPC->PROT, 0x9669AA55U))
|
||||
#define BKPC_LRC_ENABLE() \
|
||||
do { \
|
||||
BKPC_UNLOCK(); \
|
||||
SET_BIT(BKPC->CR, BKPC_CR_LRCEN_MSK); \
|
||||
BKPC_LOCK(); \
|
||||
} while (0)
|
||||
#define BKPC_LRC_DISABLE() \
|
||||
do { \
|
||||
BKPC_UNLOCK(); \
|
||||
CLEAR_BIT(BKPC->CR, BKPC_CR_LRCEN_MSK); \
|
||||
BKPC_LOCK(); \
|
||||
} while (0)
|
||||
#define BKPC_LOSM_ENABLE() \
|
||||
do { \
|
||||
BKPC_UNLOCK(); \
|
||||
SET_BIT(BKPC->CR, BKPC_CR_LOSMEN_MSK); \
|
||||
BKPC_LOCK(); \
|
||||
} while (0)
|
||||
#define BKPC_LOSM_DISABLE() \
|
||||
do { \
|
||||
BKPC_UNLOCK(); \
|
||||
CLEAR_BIT(BKPC->CR, BKPC_CR_LOSMEN_MSK);\
|
||||
BKPC_LOCK(); \
|
||||
} while (0)
|
||||
#define BKPC_LOSC_ENABLE() \
|
||||
do { \
|
||||
BKPC_UNLOCK(); \
|
||||
SET_BIT(BKPC->CR, BKPC_CR_LOSCEN_MSK); \
|
||||
BKPC_LOCK(); \
|
||||
} while (0)
|
||||
#define BKPC_LOSC_DISABLE() \
|
||||
do { \
|
||||
BKPC_UNLOCK(); \
|
||||
CLEAR_BIT(BKPC->CR, BKPC_CR_LOSCEN_MSK);\
|
||||
BKPC_LOCK(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define BKPC_MRST_WAKEUP_ENABLE() \
|
||||
do { \
|
||||
BKPC_UNLOCK(); \
|
||||
SET_BIT(BKPC->CR, BKPC_CR_MRST_WKPEN_MSK); \
|
||||
BKPC_LOCK(); \
|
||||
} while (0)
|
||||
#define BKPC_MRST_WAKEUP_DISABLE() \
|
||||
do { \
|
||||
BKPC_UNLOCK(); \
|
||||
CLEAR_BIT(BKPC->CR, BKPC_CR_MRST_WKPEN_MSK); \
|
||||
BKPC_LOCK(); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup BKPC_Public_Types BKPC Public Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief BKPC preipheral clock select.
|
||||
*/
|
||||
typedef enum {
|
||||
BKPC_PREH_CLK_LOSM = 0x0U, /**< LOSM */
|
||||
BKPC_PREH_CLK_LRC = 0x1U, /**< LRC */
|
||||
BKPC_PREH_CLK_HRC_1M = 0x2U, /**< HRC down to 1MHz */
|
||||
BKPC_PREH_CLK_HOSC_1M = 0x3U, /**< HOSC down to 1MHz */
|
||||
} bkpc_preh_clk_t;
|
||||
|
||||
/**
|
||||
* @brief Standby wakeup port select
|
||||
*/
|
||||
typedef enum {
|
||||
PMU_STANDBY_PORT_SEL_PA0 = 0x0U, /**< Wakeup by PA0 */
|
||||
PMU_STANDBY_PORT_SEL_PA1 = 0x1U, /**< Wakeup by PA1 */
|
||||
PMU_STANDBY_PORT_SEL_PA2 = 0x2U, /**< Wakeup by PA2 */
|
||||
PMU_STANDBY_PORT_SEL_PA3 = 0x3U, /**< Wakeup by PA3 */
|
||||
PMU_STANDBY_PORT_SEL_PA4 = 0x4U, /**< Wakeup by PA4 */
|
||||
PMU_STANDBY_PORT_SEL_PA5 = 0x5U, /**< Wakeup by PA5 */
|
||||
PMU_STANDBY_PORT_SEL_PA6 = 0x6U, /**< Wakeup by PA6 */
|
||||
PMU_STANDBY_PORT_SEL_PA7 = 0x7U, /**< Wakeup by PA7 */
|
||||
PMU_STANDBY_PORT_SEL_NONE = 0xFU, /**< Wakeup by other source */
|
||||
} bkpc_wakeup_port_t;
|
||||
|
||||
/**
|
||||
* @brief Standby wakeup level
|
||||
*/
|
||||
typedef enum {
|
||||
PMU_STANDBY_LEVEL_HIGH = 0x0U, /**< High level */
|
||||
PMU_STANDBY_LEVEL_LOW = 0x1U, /**< Low level */
|
||||
} bkpc_wakeup_level_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup BKPC_Private_Macros BKPC Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_BKPC_WAKEUP_PORT(x) (((x) == PMU_STANDBY_PORT_SEL_PA0) || \
|
||||
((x) == PMU_STANDBY_PORT_SEL_PA1) || \
|
||||
((x) == PMU_STANDBY_PORT_SEL_PA2) || \
|
||||
((x) == PMU_STANDBY_PORT_SEL_PA3) || \
|
||||
((x) == PMU_STANDBY_PORT_SEL_PA4) || \
|
||||
((x) == PMU_STANDBY_PORT_SEL_PA5) || \
|
||||
((x) == PMU_STANDBY_PORT_SEL_PA6) || \
|
||||
((x) == PMU_STANDBY_PORT_SEL_PA7) || \
|
||||
((x) == PMU_STANDBY_PORT_SEL_NONE))
|
||||
#define IS_BKPC_WAKEUP_LEVEL(x) (((x) == PMU_STANDBY_LEVEL_HIGH) || \
|
||||
((x) == PMU_STANDBY_LEVEL_LOW))
|
||||
#define IS_BKPC_PREH_CLOCK(x) (((x) == BKPC_PREH_CLK_LOSM) || \
|
||||
((x) == BKPC_PREH_CLK_LRC) || \
|
||||
((x) == BKPC_PREH_CLK_HRC_1M) || \
|
||||
((x) == BKPC_PREH_CLK_HOSC_1M))
|
||||
#define IS_BKPC_RAM_IDX(x) ((x) < 32)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup BKPC_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
/** @addtogroup BKPC_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
/* control functions */
|
||||
extern void ald_bkpc_standby_wakeup_config(bkpc_wakeup_port_t port, bkpc_wakeup_level_t level);
|
||||
extern void ald_bkpc_rtc_clock_config(bkpc_preh_clk_t clock);
|
||||
extern void ald_bkpc_tsense_clock_config(bkpc_preh_clk_t clock);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup BKPC_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
/* IO operation functions */
|
||||
extern void ald_bkpc_write_ram(uint8_t idx, uint32_t value);
|
||||
extern uint32_t ald_bkpc_read_ram(uint8_t idx);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_BKPC_H__ */
|
||||
@@ -1,68 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_calc.h
|
||||
* @brief Header file of CALC module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 26 Jun 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 26 Jun 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_CALC_H__
|
||||
#define __ALD_CALC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CALC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CALC_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
extern uint32_t ald_calc_sqrt(uint32_t data);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_CALC_H__ */
|
||||
@@ -1,492 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file ald_can.h
|
||||
* @brief Header file of CAN Module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 16 Apr 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 16 Apr 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_CAN_H
|
||||
#define __ALD_CAN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Public_Types CAN Public Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief ALD State structures definition
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_STATE_RESET = 0x00U, /**< CAN not yet initialized or disabled */
|
||||
CAN_STATE_READY = 0x01U, /**< CAN initialized and ready for use */
|
||||
CAN_STATE_BUSY = 0x02U, /**< CAN process is ongoing */
|
||||
CAN_STATE_BUSY_TX = 0x11U, /**< CAN process is ongoing */
|
||||
CAN_STATE_BUSY_RX0 = 0x21U, /**< CAN process is ongoing */
|
||||
CAN_STATE_BUSY_RX1 = 0x41U, /**< CAN process is ongoing */
|
||||
CAN_STATE_BUSY_TX_RX0 = 0x31U, /**< CAN process is ongoing */
|
||||
CAN_STATE_BUSY_TX_RX1 = 0x51U, /**< CAN process is ongoing */
|
||||
CAN_STATE_BUSY_RX0_RX1 = 0x61U, /**< CAN process is ongoing */
|
||||
CAN_STATE_BUSY_TX_RX0_RX1 = 0x71U, /**< CAN process is ongoing */
|
||||
CAN_STATE_TIMEOUT = 0x04U, /**< CAN in Timeout state */
|
||||
CAN_STATE_ERROR = 0x08U, /**< CAN error state */
|
||||
} can_state_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Error Code
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_ERROR_NONE = 0x00U, /**< No error */
|
||||
CAN_ERROR_EWG = 0x01U, /**< EWG error */
|
||||
CAN_ERROR_EPV = 0x02U, /**< EPV error */
|
||||
CAN_ERROR_BOF = 0x04U, /**< BOF error */
|
||||
CAN_ERROR_STF = 0x08U, /**< Stuff error */
|
||||
CAN_ERROR_FOR = 0x10U, /**< Form error */
|
||||
CAN_ERROR_ACK = 0x20U, /**< Acknowledgment error */
|
||||
CAN_ERROR_BR = 0x40U, /**< Bit recessive */
|
||||
CAN_ERROR_BD = 0x80U, /**< LEC dominant */
|
||||
CAN_ERROR_CRC = 0x100U, /**< LEC transfer error */
|
||||
CAN_ERROR_UNK = 0x200U, /**< Unknown error */
|
||||
} can_error_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Operating Mode
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_MODE_NORMAL = 0x00U, /**< Normal mode */
|
||||
CAN_MODE_LOOPBACK = 0x01U, /**< Loopback mode */
|
||||
CAN_MODE_SILENT = 0x02U, /**< Silent mode */
|
||||
CAN_MODE_SILENT_LOOPBACK = 0x03U, /**< Loopback combined with silent mode */
|
||||
} can_operate_mode_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Synchronization Jump Width
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_SJW_1 = 0x0U, /**< 1 time quantum */
|
||||
CAN_SJW_2 = 0x1U, /**< 2 time quantum */
|
||||
CAN_SJW_3 = 0x2U, /**< 3 time quantum */
|
||||
CAN_SJW_4 = 0x3U, /**< 4 time quantum */
|
||||
} can_sjw_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Time Quantum in Bit Segment 1
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_SEG1_1 = 0x0U, /**< 1 time quantum */
|
||||
CAN_SEG1_2 = 0x1U, /**< 2 time quantum */
|
||||
CAN_SEG1_3 = 0x2U, /**< 3 time quantum */
|
||||
CAN_SEG1_4 = 0x3U, /**< 4 time quantum */
|
||||
CAN_SEG1_5 = 0x4U, /**< 5 time quantum */
|
||||
CAN_SEG1_6 = 0x5U, /**< 6 time quantum */
|
||||
CAN_SEG1_7 = 0x6U, /**< 7 time quantum */
|
||||
CAN_SEG1_8 = 0x7U, /**< 8 time quantum */
|
||||
CAN_SEG1_9 = 0x8U, /**< 9 time quantum */
|
||||
CAN_SEG1_10 = 0x9U, /**< 10 time quantum */
|
||||
CAN_SEG1_11 = 0xAU, /**< 11 time quantum */
|
||||
CAN_SEG1_12 = 0xBU, /**< 12 time quantum */
|
||||
CAN_SEG1_13 = 0xCU, /**< 13 time quantum */
|
||||
CAN_SEG1_14 = 0xDU, /**< 14 time quantum */
|
||||
CAN_SEG1_15 = 0xEU, /**< 15 time quantum */
|
||||
CAN_SEG1_16 = 0xFU, /**< 16 time quantum */
|
||||
} can_seg1_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Time Quantum in Bit Segment 2
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_SEG2_1 = 0x0U, /**< 1 time quantum */
|
||||
CAN_SEG2_2 = 0x1U, /**< 2 time quantum */
|
||||
CAN_SEG2_3 = 0x2U, /**< 3 time quantum */
|
||||
CAN_SEG2_4 = 0x3U, /**< 4 time quantum */
|
||||
CAN_SEG2_5 = 0x4U, /**< 5 time quantum */
|
||||
CAN_SEG2_6 = 0x5U, /**< 6 time quantum */
|
||||
CAN_SEG2_7 = 0x6U, /**< 7 time quantum */
|
||||
CAN_SEG2_8 = 0x7U, /**< 8 time quantum */
|
||||
} can_seg2_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Filter Mode
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_FILTER_MODE_MASK = 0x0U, /**< Identifier mask mode */
|
||||
CAN_FILTER_MODE_LIST = 0x1U, /**< Identifier list mode */
|
||||
} can_filter_mode_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Filter Scale
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_FILTER_SCALE_16 = 0x0U, /**< Two 16-bit filters */
|
||||
CAN_FILTER_SCALE_32 = 0x1U, /**< One 32-bit filter */
|
||||
} can_filter_scale_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Filter fifo
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_FILTER_FIFO0 = 0x0U, /**< FIFO 0 assignment for filter */
|
||||
CAN_FILTER_FIFO1 = 0x1U, /**< FIFO 1 assignment for filter */
|
||||
} can_filter_fifo_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Identifier Type
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_ID_STD = 0x0U, /**< Standard Id */
|
||||
CAN_ID_EXT = 0x1U, /**< Extended Id */
|
||||
} can_id_type_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Remote Transmission Request
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_RTR_DATA = 0x0U, /**< Data frame */
|
||||
CAN_RTR_REMOTE = 0x1U, /**< Remote frame */
|
||||
} can_remote_req_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Transmit Constants
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_TX_MAILBOX_0 = 0x0U, /**< TX mailbox index 0 */
|
||||
CAN_TX_MAILBOX_1 = 0x1U, /**< TX mailbox index 1 */
|
||||
CAN_TX_MAILBOX_2 = 0x2U, /**< TX mailbox index 2 */
|
||||
CAN_TX_MAILBOX_NONE = 0x3U, /**< MailBox can't be used */
|
||||
} can_tx_mailbox_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Receive fifo Number
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_RX_FIFO0 = 0x0U, /**< CAN fifo 0 used to receive */
|
||||
CAN_RX_FIFO1 = 0x1U, /**< CAN fifo 1 used to receive */
|
||||
} can_rx_fifo_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Flags
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_FLAG_SLPS = (1U << 1), /**< Sleep acknowledge flag */
|
||||
CAN_FLAG_ERR = (1U << 2), /**< Error flag*/
|
||||
CAN_FLAG_WK = (1U << 3), /**< Wake up flag */
|
||||
CAN_FLAG_SLP = (1U << 4), /**< Sleep acknowledge flag */
|
||||
CAN_FLAG_M0REQC = (1U << 20) | (1U << 0), /**< Request MailBox0 flag */
|
||||
CAN_FLAG_M0TXC = (1U << 20) | (1U << 1), /**< Transmission OK MailBox0 flag */
|
||||
CAN_FLAG_M1REQC = (1U << 20) | (1U << 8), /**< Request MailBox1 flag */
|
||||
CAN_FLAG_M1TXC = (1U << 20) | (1U << 9), /**< Transmission OK MailBox1 flag */
|
||||
CAN_FLAG_M2REQC = (1U << 20) | (1U << 16), /**< Request MailBox2 flag */
|
||||
CAN_FLAG_M2TXC = (1U << 20) | (1U << 17), /**< Transmission OK MailBox2 flag */
|
||||
CAN_FLAG_TXM0 = (1U << 20) | (1U << 26), /**< Transmit mailbox 0 empty flag */
|
||||
CAN_FLAG_TXM1 = (1U << 20) | (1U << 27), /**< Transmit mailbox 1 empty flag */
|
||||
CAN_FLAG_TXM2 = (1U << 20) | (1U << 28), /**< Transmit mailbox 2 empty flag */
|
||||
CAN_FLAG_FF0 = (2U << 20) | (1U << 3), /**< FIFO 0 Full flag */
|
||||
CAN_FLAG_FOV0 = (2U << 20) | (1U << 4), /**< FIFO 0 Overrun flag */
|
||||
CAN_FLAG_FF1 = (3U << 20) | (1U << 3), /**< FIFO 1 Full flag */
|
||||
CAN_FLAG_FOV1 = (3U << 20) | (1U << 4), /**< FIFO 1 Overrun flag */
|
||||
CAN_FLAG_WARN = (4U << 20) | (1U << 0), /**< Error warning flag */
|
||||
CAN_FLAG_PERR = (4U << 20) | (1U << 1), /**< Error passive flag */
|
||||
CAN_FLAG_BOF = (4U << 20) | (1U << 2), /**< Bus-Off flag */
|
||||
} can_flag_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Interrupts
|
||||
*/
|
||||
typedef enum {
|
||||
CAN_IT_TXM = (1U << 0), /**< Transmit mailbox empty interrupt bit */
|
||||
CAN_IT_FP0 = (1U << 1), /**< FIFO0 message pending interrupt bit */
|
||||
CAN_IT_FF0 = (1U << 2), /**< FIFO0 full interrupt bit */
|
||||
CAN_IT_FOV0 = (1U << 3), /**< FIFO0 overrun interrupt bit */
|
||||
CAN_IT_FP1 = (1U << 4), /**< FIFO1 message pending interrupt bit */
|
||||
CAN_IT_FF1 = (1U << 5), /**< FIFO1 full interrupt bit */
|
||||
CAN_IT_FOV1 = (1U << 6), /**< FIFO1 overrun interrupt bit */
|
||||
CAN_IT_WARN = (1U << 8), /**< Error warning interrupt bit */
|
||||
CAN_IT_PERR = (1U << 9), /**< Error passive interrupt bit */
|
||||
CAN_IT_BOF = (1U << 10), /**< Bus-off interrupt bit */
|
||||
CAN_IT_PRERR = (1U << 11), /**< Last error code interrupt bit */
|
||||
CAN_IT_ERR = (1U << 15), /**< Error interrupt bit */
|
||||
CAN_IT_WK = (1U << 16), /**< wake-up interrupt bit */
|
||||
CAN_IT_SLP = (1U << 17), /**< sleep interrupt bit */
|
||||
} can_it_t;
|
||||
|
||||
/**
|
||||
* @brief CAN filter configuration structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t id_high; /**< Specifies the filter identification number */
|
||||
uint32_t id_low; /**< Specifies the filter identification number */
|
||||
uint32_t mask_id_high; /**< Specifies the filter mask number or identification number */
|
||||
uint32_t mask_id_low; /**< Specifies the filter mask number or identification number */
|
||||
can_filter_fifo_t fifo; /**< Specifies the fifo (0 or 1) which will be assigned to the filter. */
|
||||
uint32_t number; /**< Specifies the filter which will be initialized. */
|
||||
can_filter_mode_t mode; /**< Specifies the filter mode to be initialized. */
|
||||
can_filter_scale_t scale; /**< Specifies the filter scale. */
|
||||
type_func_t active; /**< Enable or disable the filter. */
|
||||
} can_filter_t;
|
||||
|
||||
/**
|
||||
* @brief CAN init structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t psc; /**< Specifies the length of a time quantum. */
|
||||
can_operate_mode_t mode; /**< Specifies the CAN operating mode. */
|
||||
can_sjw_t sjw; /**< Specifies the maximum number of time quanta the CAN hardware is
|
||||
allowed to lengthen or shorten a bit to perform resynchronization. */
|
||||
can_seg1_t seg1; /**< Specifies the number of time quanta in Bit Segment 1. */
|
||||
can_seg2_t seg2; /**< Specifies the number of time quanta in Bit Segment 2. */
|
||||
type_func_t ttcm; /**< Enable or disable the time triggered communication mode. */
|
||||
type_func_t abom; /**< Enable or disable the automatic bus-off management. */
|
||||
type_func_t awk; /**< Enable or disable the automatic wake-up mode. */
|
||||
type_func_t artx; /**< Enable or disable the non-automatic retransmission mode. */
|
||||
type_func_t rfom; /**< Enable or disable the Receive fifo Locked mode. */
|
||||
type_func_t txmp; /**< Enable or disable the transmit fifo priority. */
|
||||
} can_init_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Tx message structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t std; /**< Specifies the standard identifier. */
|
||||
uint32_t ext; /**< Specifies the extended identifier. */
|
||||
can_id_type_t type; /**< Specifies the type of identifier for the message that will be transmitted. */
|
||||
can_remote_req_t rtr; /**< Specifies the type of frame for the message that will be transmitted. */
|
||||
uint32_t len; /**< Specifies the length of the frame that will be transmitted. */
|
||||
uint8_t data[8]; /**< Contains the data to be transmitted. */
|
||||
} can_tx_msg_t;
|
||||
|
||||
/**
|
||||
* @brief CAN Rx message structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t std; /**< Specifies the standard identifier. */
|
||||
uint32_t ext; /**< Specifies the extended identifier. */
|
||||
can_id_type_t type; /**< Specifies the type of identifier for the message that will be received. */
|
||||
can_remote_req_t rtr; /**< Specifies the type of frame for the received message. */
|
||||
uint32_t len; /**< Specifies the length of the frame that will be received. */
|
||||
uint8_t data[8]; /**< Contains the data to be received. */
|
||||
uint32_t fmi; /**< Specifies the index of the filter the message stored in the mailbox passes through. */
|
||||
can_rx_fifo_t num; /**< Specifies the receive fifo number. */
|
||||
} can_rx_msg_t;
|
||||
|
||||
/**
|
||||
* @brief CAN handle Structure definition
|
||||
*/
|
||||
typedef struct can_handle_s {
|
||||
CAN_TypeDef *perh; /**< Register base address */
|
||||
can_init_t init; /**< CAN required parameters */
|
||||
can_rx_msg_t *rx0_msg; /**< Pointer to receive message from FIFO0 */
|
||||
can_rx_msg_t *rx1_msg; /**< Pointer to receive message from FIFO1 */
|
||||
lock_state_t lock; /**< CAN locking object */
|
||||
can_state_t state; /**< CAN communication state */
|
||||
can_error_t err; /**< CAN Error code */
|
||||
|
||||
void (*tx_cplt_cbk)(struct can_handle_s *arg); /**< Tx completed callback */
|
||||
void (*rx_cplt_cbk)(struct can_handle_s *arg, can_rx_fifo_t num); /**< Rx completed callback */
|
||||
void (*error_cbk)(struct can_handle_s *arg); /**< error callback */
|
||||
} can_handle_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Public_Macro CAN Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define CAN_RESET_HANDLE_STATE(x) ((x)->state = CAN_STATE_RESET)
|
||||
#define CAN_RX_MSG_PENDING(x, y) (((y) == CAN_RX_FIFO0) ? \
|
||||
(READ_BIT((x)->perh->RXF0, CAN_RXF0_PEND_MSK)) : (READ_BIT((x)->perh->RXF1, CAN_RXF1_PEND_MSK)))
|
||||
#define CAN_DBG_FREEZE(x, y) (MODIFY_REG((x)->perh->CON, CAN_CON_DBGSTP_MSK, (y) << CAN_CON_DBGSTP_POS))
|
||||
#define CAN_TX_STAMP_ENABLE(x, y) (SET_BIT((x)->perh->TxMailBox[(y)].TXFCON, CAN_TXFCON0_TXGT_MSK))
|
||||
#define CAN_TX_STAMP_DISABLE(x, y) (CLEAR_BIT((x)->perh->TxMailBox[(y)].TXFCON, CAN_TXFCON0_TXGT_MSK))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Private_Macros CAN Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_CAN_ALL(x) ((x) == CAN0)
|
||||
#define IS_CAN_FILTER_NUMBER(x) ((x) <= 13)
|
||||
#define IS_CAN_MODE(x) (((x) == CAN_MODE_NORMAL) || \
|
||||
((x) == CAN_MODE_LOOPBACK) || \
|
||||
((x) == CAN_MODE_SILENT) || \
|
||||
((x) == CAN_MODE_SILENT_LOOPBACK))
|
||||
#define IS_CAN_SJW(x) (((x) == CAN_SJW_1) || \
|
||||
((x) == CAN_SJW_2) || \
|
||||
((x) == CAN_SJW_3) || \
|
||||
((x) == CAN_SJW_4))
|
||||
#define IS_CAN_BS1(x) ((x) <= CAN_SEG1_16)
|
||||
#define IS_CAN_BS2(x) ((x) <= CAN_SEG2_8)
|
||||
#define IS_CAN_FILTER_MODE(x) (((x) == CAN_FILTER_MODE_MASK) || \
|
||||
((x) == CAN_FILTER_MODE_LIST))
|
||||
#define IS_CAN_FILTER_SCALE(x) (((x) == CAN_FILTER_SCALE_16) || \
|
||||
((x) == CAN_FILTER_SCALE_32))
|
||||
#define IS_CAN_FILTER_FIFO(x) (((x) == CAN_FILTER_FIFO0) || \
|
||||
((x) == CAN_FILTER_FIFO1))
|
||||
#define IS_CAN_IDTYPE(x) (((x) == CAN_ID_STD) || \
|
||||
((x) == CAN_ID_EXT))
|
||||
#define IS_CAN_RTR(x) (((x) == CAN_RTR_DATA) || ((x) == CAN_RTR_REMOTE))
|
||||
#define IS_CAN_FIFO(x) (((x) == CAN_RX_FIFO0) || ((x) == CAN_RX_FIFO1))
|
||||
#define IS_CAN_TX_MAILBOX(x) ((x) <= CAN_TX_MAILBOX_NONE)
|
||||
#define IS_CAN_STDID(x) ((x) <= ((uint32_t)0x7FF))
|
||||
#define IS_CAN_EXTID(x) ((x) <= ((uint32_t)0x1FFFFFFF))
|
||||
#define IS_CAN_DATA_LEN(x) ((x) <= ((uint8_t)0x08))
|
||||
#define IS_CAN_PRESCALER(x) (((x) >= 1) && ((x) <= 1024))
|
||||
#define IS_CAN_GET_FLAG(x) (((x) == CAN_FLAG_SLPS) || \
|
||||
((x) == CAN_FLAG_ERR) || \
|
||||
((x) == CAN_FLAG_WK) || \
|
||||
((x) == CAN_FLAG_SLP) || \
|
||||
((x) == CAN_FLAG_M0REQC) || \
|
||||
((x) == CAN_FLAG_M0TXC) || \
|
||||
((x) == CAN_FLAG_M1REQC) || \
|
||||
((x) == CAN_FLAG_M1TXC) || \
|
||||
((x) == CAN_FLAG_M2REQC) || \
|
||||
((x) == CAN_FLAG_M2TXC) || \
|
||||
((x) == CAN_FLAG_TXM0) || \
|
||||
((x) == CAN_FLAG_TXM1) || \
|
||||
((x) == CAN_FLAG_TXM2) || \
|
||||
((x) == CAN_FLAG_FF0) || \
|
||||
((x) == CAN_FLAG_FOV0) || \
|
||||
((x) == CAN_FLAG_FF1) || \
|
||||
((x) == CAN_FLAG_FOV1) || \
|
||||
((x) == CAN_FLAG_WARN) || \
|
||||
((x) == CAN_FLAG_PERR) || \
|
||||
((x) == CAN_FLAG_BOF))
|
||||
#define IS_CAN_CLEAR_FLAG(x) (((x) == CAN_FLAG_ERR) || \
|
||||
((x) == CAN_FLAG_WK) || \
|
||||
((x) == CAN_FLAG_SLP) || \
|
||||
((x) == CAN_FLAG_M0REQC) || \
|
||||
((x) == CAN_FLAG_M1REQC) || \
|
||||
((x) == CAN_FLAG_M2REQC) || \
|
||||
((x) == CAN_FLAG_FF0) || \
|
||||
((x) == CAN_FLAG_FOV0) || \
|
||||
((x) == CAN_FLAG_FF1) || \
|
||||
((x) == CAN_FLAG_FOV1))
|
||||
#define IS_CAN_IT(x) (((x) == CAN_IT_TXM) || \
|
||||
((x) == CAN_IT_FP0) || \
|
||||
((x) == CAN_IT_FF0) || \
|
||||
((x) == CAN_IT_FOV0) || \
|
||||
((x) == CAN_IT_FP1) || \
|
||||
((x) == CAN_IT_FF1) || \
|
||||
((x) == CAN_IT_FOV1) || \
|
||||
((x) == CAN_IT_WARN) || \
|
||||
((x) == CAN_IT_PERR) || \
|
||||
((x) == CAN_IT_BOF) || \
|
||||
((x) == CAN_IT_PRERR) || \
|
||||
((x) == CAN_IT_ERR) || \
|
||||
((x) == CAN_IT_WK) || \
|
||||
((x) == CAN_IT_SLP))
|
||||
#define CAN_TIMEOUT_VALUE 100
|
||||
#define CAN_STATE_TX_MASK (1U << 4)
|
||||
#define CAN_STATE_RX0_MASK (1U << 5)
|
||||
#define CAN_STATE_RX1_MASK (1U << 6)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
/* Initialization functions */
|
||||
void ald_can_reset(can_handle_t *hperh);
|
||||
ald_status_t ald_can_init(can_handle_t *hperh);
|
||||
ald_status_t ald_can_filter_config(can_handle_t *hperh, can_filter_t *config);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
/* IO operation functions */
|
||||
ald_status_t ald_can_send(can_handle_t *hperh, can_tx_msg_t *msg, uint32_t timeout);
|
||||
ald_status_t ald_can_send_by_it(can_handle_t *hperh, can_tx_msg_t *msg);
|
||||
ald_status_t ald_can_recv(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg, uint32_t timeout);
|
||||
ald_status_t ald_can_recv_by_it(can_handle_t *hperh, can_rx_fifo_t num, can_rx_msg_t *msg);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
/* Control function */
|
||||
ald_status_t ald_can_sleep(can_handle_t *hperh);
|
||||
ald_status_t ald_can_wake_up(can_handle_t *hperh);
|
||||
void ald_can_cancel_send(can_handle_t *hperh, can_tx_mailbox_t box);
|
||||
void ald_can_irq_handler(can_handle_t *hperh);
|
||||
type_bool_t ald_can_get_tx_status(can_handle_t *hperh, can_tx_mailbox_t box);
|
||||
void ald_can_interrupt_config(can_handle_t *hperh, can_it_t it, type_func_t state);
|
||||
it_status_t ald_can_get_it_status(can_handle_t *hperh, can_it_t it);
|
||||
flag_status_t ald_can_get_flag_status(can_handle_t *hperh, can_flag_t flag);
|
||||
void ald_can_clear_flag_status(can_handle_t *hperh, can_flag_t flag);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CAN_Public_Functions_Group4
|
||||
* @{
|
||||
*/
|
||||
/* State and Error functions */
|
||||
can_state_t ald_can_get_state(can_handle_t *hperh);
|
||||
can_error_t ald_can_get_error(can_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_CAN_H */
|
||||
@@ -1,805 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_cmu.h
|
||||
* @brief Header file of CMU module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 22 Nov 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 22 Nov 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_CMU_H__
|
||||
#define __ALD_CMU_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "ald_syscfg.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CMU
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CMU_Public_Macros CMU Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define CMU_HRC_SEL_BY_SW() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(CMU->CFGR, CMU_CFGR_HRCFCS_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_HRC_SEL_BY_CFGW() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(CMU->CFGR, CMU_CFGR_HRCFCS_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_HRC_DIV_1MHZ_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(CMU->CLKENR, CMU_CLKENR_HRC1MEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_HRC_DIV_1MHZ_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_HRC1MEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_HOSC_DIV_1MHZ_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(CMU->CLKENR, CMU_CLKENR_HOSC1MEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_HOSC_DIV_1MHZ_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_HOSC1MEN_MSK);\
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LOSC_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LOSC_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LOSCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LRC_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LRC_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_LRCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_ULRC_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(CMU->CLKENR, CMU_CLKENR_ULRCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_ULRC_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(CMU->CLKENR, CMU_CLKENR_ULRCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
|
||||
/* Low power mode control */
|
||||
#define CMU_LP_LRC_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(CMU->LPENR, CMU_LPENR_LRCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LP_LRC_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(CMU->LPENR, CMU_LPENR_LRCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LP_LOSC_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(CMU->LPENR, CMU_LPENR_LOSCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LP_LOSC_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(CMU->LPENR, CMU_LPENR_LOSCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LP_HRC_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(CMU->LPENR, CMU_LPENR_HRCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LP_HRC_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(CMU->LPENR, CMU_LPENR_HRCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LP_HOSC_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(CMU->LPENR, CMU_LPENR_HOSCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define CMU_LP_HOSC_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(CMU->LPENR, CMU_LPENR_HOSCEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup CMU_Public_Types CMU Public Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief CMU state structure definition
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_CLOCK_HRC = 0x1U, /**< HRC */
|
||||
CMU_CLOCK_LRC = 0x2U, /**< LRC */
|
||||
CMU_CLOCK_LOSC = 0x3U, /**< LOSC */
|
||||
CMU_CLOCK_PLL1 = 0x4U, /**< PLL1 */
|
||||
CMU_CLOCK_HOSC = 0x5U, /**< HOSC */
|
||||
} cmu_clock_t;
|
||||
|
||||
/**
|
||||
* @brief PLL1 output clock
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_PLL1_OUTPUT_36M = 0x0U, /**< x9 (36MHz) */
|
||||
CMU_PLL1_OUTPUT_48M = 0x1U, /**< x12 (48MHz) */
|
||||
#if defined(ES32F36xx) || defined(ES32F39xx)
|
||||
CMU_PLL1_OUTPUT_72M = 0x2U, /**< x18 (72MHz) */
|
||||
CMU_PLL1_OUTPUT_96M = 0x3U, /**< x24 (96MHz) */
|
||||
#endif
|
||||
} cmu_pll1_output_t;
|
||||
|
||||
/**
|
||||
* @brief PLL1 referance clock
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_PLL1_INPUT_HRC_6 = 0x0U, /**< HRC / 6 */
|
||||
CMU_PLL1_INPUT_PLL2 = 0x1U, /**< PLL2 */
|
||||
CMU_PLL1_INPUT_HOSC = 0x2U, /**< HOSC / 1 */
|
||||
CMU_PLL1_INPUT_HOSC_2 = 0x3U, /**< HOSC / 2 */
|
||||
CMU_PLL1_INPUT_HOSC_3 = 0x4U, /**< HOSC / 3 */
|
||||
CMU_PLL1_INPUT_HOSC_4 = 0x5U, /**< HOSC / 4 */
|
||||
CMU_PLL1_INPUT_HOSC_5 = 0x6U, /**< HOSC / 5 */
|
||||
CMU_PLL1_INPUT_HOSC_6 = 0x7U, /**< HOSC / 6 */
|
||||
} cmu_pll1_input_t;
|
||||
|
||||
/**
|
||||
* @brief HOSC range
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_HOSC_2M = 0x0U, /**< 0~2MHz */
|
||||
CMU_HOSC_4M = 0x1U, /**< 2~4MHz */
|
||||
CMU_HOSC_8M = 0x2U, /**< 4~8MHz */
|
||||
CMU_HOSC_16M = 0x3U, /**< 8~16MHz */
|
||||
CMU_HOSC_24M = 0x4U, /**< 16~24MHz */
|
||||
} cmu_hosc_range_t;
|
||||
|
||||
/**
|
||||
* @brief Safe clock source type
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_SAFE_CLK_HOSC = 0x0U, /**< HOSC */
|
||||
CMU_SAFE_CLK_LOSC = 0x1U, /**< LOSC */
|
||||
CMU_SAFE_CLK_PLL = 0x2U, /**< PLL */
|
||||
} cmu_clock_safe_type_t;
|
||||
|
||||
/**
|
||||
* @brief Frequency division select bit
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_DIV_1 = 0x0U, /**< Division by 1 */
|
||||
CMU_DIV_2 = 0x1U, /**< Division by 2 */
|
||||
CMU_DIV_4 = 0x2U, /**< Division by 4 */
|
||||
CMU_DIV_8 = 0x3U, /**< Division by 8 */
|
||||
CMU_DIV_16 = 0x4U, /**< Division by 16 */
|
||||
CMU_DIV_32 = 0x5U, /**< Division by 32 */
|
||||
CMU_DIV_64 = 0x6U, /**< Division by 64 */
|
||||
CMU_DIV_128 = 0x7U, /**< Division by 128 */
|
||||
CMU_DIV_256 = 0x8U, /**< Division by 256 */
|
||||
CMU_DIV_512 = 0x9U, /**< Division by 512 */
|
||||
CMU_DIV_1024 = 0xAU, /**< Division by 1024 */
|
||||
CMU_DIV_2048 = 0xBU, /**< Division by 2048 */
|
||||
CMU_DIV_4096 = 0xCU, /**< Division by 4096 */
|
||||
} cmu_div_t;
|
||||
|
||||
/**
|
||||
* @brief Bus type
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_HCLK_1 = 0x0U, /**< AHB1 bus */
|
||||
CMU_HCLK_2 = 0x1U, /**< AHB2 bus */
|
||||
CMU_SYS = 0x2U, /**< SYS bus */
|
||||
CMU_PCLK_1 = 0x3U, /**< APB1 bus */
|
||||
CMU_PCLK_2 = 0x4U, /**< APB2 bus */
|
||||
} cmu_bus_t;
|
||||
|
||||
/**
|
||||
* @brief Output high clock select
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_OUTPUT_HIGH_SEL_HOSC = 0x0U, /**< Select HOSC */
|
||||
CMU_OUTPUT_HIGH_SEL_LOSC = 0x1U, /**< Select LOSC */
|
||||
CMU_OUTPUT_HIGH_SEL_HRC = 0x2U, /**< Select HRC */
|
||||
CMU_OUTPUT_HIGH_SEL_LRC = 0x3U, /**< Select LRC */
|
||||
CMU_OUTPUT_HIGH_SEL_HOSM = 0x4U, /**< Select HOSM */
|
||||
CMU_OUTPUT_HIGH_SEL_PLL1 = 0x5U, /**< Select PLL1 */
|
||||
CMU_OUTPUT_HIGH_SEL_PLL2 = 0x6U, /**< Select PLL2 */
|
||||
CMU_OUTPUT_HIGH_SEL_SYSCLK = 0x7U, /**< Select SYSCLK */
|
||||
} cmu_output_high_sel_t;
|
||||
|
||||
/**
|
||||
* @brief Output frequency division
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_OUTPUT_DIV_1 = 0x0U, /**< Division by 1 */
|
||||
CMU_OUTPUT_DIV_2 = 0x1U, /**< Division by 2 */
|
||||
CMU_OUTPUT_DIV_4 = 0x2U, /**< Division by 4 */
|
||||
CMU_OUTPUT_DIV_8 = 0x3U, /**< Division by 8 */
|
||||
CMU_OUTPUT_DIV_16 = 0x4U, /**< Division by 16 */
|
||||
CMU_OUTPUT_DIV_32 = 0x5U, /**< Division by 32 */
|
||||
CMU_OUTPUT_DIV_64 = 0x6U, /**< Division by 64 */
|
||||
CMU_OUTPUT_DIV_128 = 0x7U, /**< Division by 128 */
|
||||
} cmu_output_high_div_t;
|
||||
|
||||
/**
|
||||
* @brief Output low clock select
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_OUTPUT_LOW_SEL_LOSC = 0x0U, /**< Select LOSC */
|
||||
CMU_OUTPUT_LOW_SEL_LRC = 0x1U, /**< Select LRC */
|
||||
CMU_OUTPUT_LOW_SEL_LOSM = 0x2U, /**< Select LOSM */
|
||||
CMU_OUTPUT_LOW_SEL_BUZZ = 0x3U, /**< Select BUZZ */
|
||||
CMU_OUTPUT_LOW_SEL_ULRC = 0x4U, /**< Select ULRC */
|
||||
} cmu_output_low_sel_t;
|
||||
|
||||
/**
|
||||
* @brief BUZZ frequency division
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_BUZZ_DIV_2 = 0x0U, /**< Division by 2 */
|
||||
CMU_BUZZ_DIV_4 = 0x1U, /**< Division by 4 */
|
||||
CMU_BUZZ_DIV_8 = 0x2U, /**< Division by 8 */
|
||||
CMU_BUZZ_DIV_16 = 0x3U, /**< Division by 16 */
|
||||
CMU_BUZZ_DIV_32 = 0x4U, /**< Division by 32 */
|
||||
CMU_BUZZ_DIV_64 = 0x5U, /**< Division by 64 */
|
||||
CMU_BUZZ_DIV_128 = 0x6U, /**< Division by 128 */
|
||||
CMU_BUZZ_DIV_256 = 0x7U, /**< Division by 256 */
|
||||
} cmu_buzz_div_t;
|
||||
|
||||
/**
|
||||
* @brief Low power peripheral clock select
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_LP_PERH_CLOCK_SEL_PCLK2 = 0x0U, /**< Select PCLK2 */
|
||||
CMU_LP_PERH_CLOCK_SEL_PLL1 = 0x1U, /**< Select PLL1 */
|
||||
CMU_LP_PERH_CLOCK_SEL_PLL2 = 0x2U, /**< Select PLL2 */
|
||||
CMU_LP_PERH_CLOCK_SEL_HRC = 0x3U, /**< Select HRC */
|
||||
CMU_LP_PERH_CLOCK_SEL_HOSC = 0x4U, /**< Select HOSC */
|
||||
CMU_LP_PERH_CLOCK_SEL_LRC = 0x5U, /**< Select LRC */
|
||||
CMU_LP_PERH_CLOCK_SEL_LOSC = 0x6U, /**< Select LOSC */
|
||||
CMU_LP_PERH_CLOCK_SEL_ULRC = 0x7U, /**< Select ULRC */
|
||||
CMU_LP_PERH_CLOCK_SEL_HRC_1M = 0x8U, /**< Select HRC down to 1MHz */
|
||||
CMU_LP_PERH_CLOCK_SEL_HOSC_1M = 0x9U, /**< Select HOSC down to 1MHz */
|
||||
CMU_LP_PERH_CLOCK_SEL_LOSM = 0xAU, /**< Select LOSM */
|
||||
CMU_LP_PERH_CLOCK_SEL_HOSM = 0xBU, /**< Select HOSM */
|
||||
} cmu_lp_perh_clock_sel_t;
|
||||
|
||||
/**
|
||||
* @brief LCD clock select
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_LCD_SEL_LOSM = 0x0U, /**< Select LOSM */
|
||||
CMU_LCD_SEL_LOSC = 0x1U, /**< Select LOSC */
|
||||
CMU_LCD_SEL_LRC = 0x2U, /**< Select LRC */
|
||||
CMU_LCD_SEL_ULRC = 0x3U, /**< Select ULRC */
|
||||
CMU_LCD_SEL_HRC_1M = 0x4U, /**< Select HRC down to 1MHz */
|
||||
CMU_LCD_SEL_HOSC_1M = 0x5U, /**< Select HOSC down to 1MHz */
|
||||
} cmu_lcd_clock_sel_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI clock select
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_QSPI_CLOCK_SEL_PCLK1 = 0x0U, /**< Select PCLK1 */
|
||||
CMU_QSPI_CLOCK_SEL_HCLK2 = 0x1U, /**< Select HCLK2 */
|
||||
CMU_QSPI_CLOCK_SEL_HRC = 0x2U, /**< Select HRC */
|
||||
CMU_QSPI_CLOCK_SEL_HOSC = 0x3U, /**< Select HOSC */
|
||||
CMU_QSPI_CLOCK_SEL_PLL1 = 0x4U, /**< Select PLL1 */
|
||||
CMU_QSPI_CLOCK_SEL_HOSM = 0x5U, /**< Select HOSC security management */
|
||||
} cmu_qspi_clock_sel_t;
|
||||
|
||||
/**
|
||||
* @brief USB clock select
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_USB_CLOCK_SEL_HOSC = 0x0U, /**< Select HOSC */
|
||||
CMU_USB_CLOCK_SEL_HRC = 0x1U, /**< Select HRC */
|
||||
CMU_USB_CLOCK_SEL_PCLK1 = 0x2U, /**< Select PCLK1 */
|
||||
CMU_USB_CLOCK_SEL_PLL1 = 0x3U, /**< Select PLL1 */
|
||||
CMU_USB_CLOCK_SEL_HOSM = 0x4U, /**< Select HOSC security management */
|
||||
} cmu_usb_clock_sel_t;
|
||||
|
||||
/**
|
||||
* @brief USB clock division
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_USB_DIV_1 = 0x0U, /**< Division by 1 */
|
||||
CMU_USB_DIV_2 = 0x1U, /**< Division by 2 */
|
||||
CMU_USB_DIV_4 = 0x2U, /**< Division by 4 */
|
||||
CMU_USB_DIV_8 = 0x3U, /**< Division by 8 */
|
||||
CMU_USB_DIV_16 = 0x4U, /**< Division by 16 */
|
||||
CMU_USB_DIV_32 = 0x5U, /**< Division by 32 */
|
||||
CMU_USB_DIV_64 = 0x6U, /**< Division by 64 */
|
||||
CMU_USB_DIV_128 = 0x7U, /**< Division by 128 */
|
||||
CMU_USB_DIV_256 = 0x8U, /**< Division by 256 */
|
||||
CMU_USB_DIV_512 = 0x9U, /**< Division by 512 */
|
||||
CMU_USB_DIV_1024 = 0xAU, /**< Division by 1024 */
|
||||
CMU_USB_DIV_2048 = 0xBU, /**< Division by 2048 */
|
||||
CMU_USB_DIV_4096 = 0xCU, /**< Division by 4096 */
|
||||
} cmu_usb_div_t;
|
||||
|
||||
/**
|
||||
* @brief Peripheral clock enable/disable
|
||||
* @verbatim
|
||||
In this module, for the convenience of code maintenance,
|
||||
TIMERx is used to indicate the sequence of the timer peripheral.
|
||||
Different product series TIMERx represent different meanings:
|
||||
1. For ES32F36xx series:
|
||||
TIMER0 ----> AD16C4T0
|
||||
TIMER1 ----> AD16C4T1
|
||||
TIMER2 ----> GP32C4T0
|
||||
TIMER3 ----> GP32C4T1
|
||||
TIMER4 ----> BS16T0
|
||||
TIMER5 ----> BS16T1
|
||||
TIMER6 ----> GP16C4T0
|
||||
TIMER7 ----> GP16C4T1
|
||||
|
||||
2. For ES32F393x/ES32F336x/ES32F392x series:
|
||||
TIMER0 ----> GP16C4T0
|
||||
TIMER1 ----> GP16C4T1
|
||||
TIMER2 ----> GP32C4T0
|
||||
TIMER3 ----> GP32C4T1
|
||||
TIMER4 ----> BS16T0
|
||||
TIMER5 ----> BS16T1
|
||||
TIMER6 ----> GP16C4T2
|
||||
TIMER7 ----> GP16C4T3
|
||||
@endverbatim
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_PERH_GPIO = (1U << 0), /**< GPIO */
|
||||
CMU_PERH_CRC = (1U << 1), /**< CRC */
|
||||
CMU_PERH_CALC = (1U << 2), /**< CALC */
|
||||
CMU_PERH_CRYPT = (1U << 3), /**< CRYPT */
|
||||
CMU_PERH_TRNG = (1U << 4), /**< TRNG */
|
||||
CMU_PERH_PIS = (1U << 5), /**< PIS */
|
||||
CMU_PERH_EBI = (1U << 6), /**< EBI */
|
||||
CMU_PERH_QSPI_H = (1U << 7), /**< QSPI AHB */
|
||||
CMU_PERH_DMA = (1U << 8), /**< DMA */
|
||||
CMU_PERH_USB = (1U << 10), /**< USB */
|
||||
CMU_PERH_ECC = (1U << 11), /**< ECC */
|
||||
CMU_PERH_TIMER0 = (1U << 0) | (1U << 27), /**< TIMER0 */
|
||||
CMU_PERH_TIMER1 = (1U << 1) | (1U << 27), /**< TIMER1 */
|
||||
CMU_PERH_TIMER2 = (1U << 2) | (1U << 27), /**< TIMER2 */
|
||||
CMU_PERH_TIMER3 = (1U << 3) | (1U << 27), /**< TIMER3 */
|
||||
CMU_PERH_TIMER4 = (1U << 4) | (1U << 27), /**< TIMER4 */
|
||||
CMU_PERH_TIMER5 = (1U << 5) | (1U << 27), /**< TIMER5 */
|
||||
CMU_PERH_TIMER6 = (1U << 6) | (1U << 27), /**< TIMER6 */
|
||||
CMU_PERH_TIMER7 = (1U << 7) | (1U << 27), /**< TIMER7 */
|
||||
CMU_PERH_UART0 = (1U << 8) | (1U << 27), /**< UART0 */
|
||||
CMU_PERH_UART1 = (1U << 9) | (1U << 27), /**< UART1 */
|
||||
CMU_PERH_UART2 = (1U << 10) | (1U << 27), /**< UART2 */
|
||||
CMU_PERH_UART3 = (1U << 11) | (1U << 27), /**< UART3 */
|
||||
CMU_PERH_UART4 = (1U << 12) | (1U << 27), /**< UART4 */
|
||||
CMU_PERH_UART5 = (1U << 13) | (1U << 27), /**< UART5 */
|
||||
CMU_PERH_SPI0 = (1U << 16) | (1U << 27), /**< SPI0 */
|
||||
CMU_PERH_SPI1 = (1U << 17) | (1U << 27), /**< SPI1 */
|
||||
CMU_PERH_SPI2 = (1U << 18) | (1U << 27), /**< SPI2 */
|
||||
CMU_PERH_I2C0 = (1U << 20) | (1U << 27), /**< I2C0 */
|
||||
CMU_PERH_I2C1 = (1U << 21) | (1U << 27), /**< I2C1 */
|
||||
CMU_PERH_CAN = (1U << 24) | (1U << 27), /**< CAN */
|
||||
CMU_PERH_QSPI_P = (1U << 25) | (1U << 27), /**< QSPI APB */
|
||||
CMU_PERH_LPTIM0 = (1U << 0) | (1U << 28), /**< LPTIM0 */
|
||||
CMU_PERH_LPUART0 = (1U << 2) | (1U << 28), /**< LPUART0 */
|
||||
CMU_PERH_ADC0 = (1U << 4) | (1U << 28), /**< ADC0 */
|
||||
CMU_PERH_ADC1 = (1U << 5) | (1U << 28), /**< ADC1 */
|
||||
CMU_PERH_ACMP0 = (1U << 6) | (1U << 28), /**< ACMP0 */
|
||||
CMU_PERH_ACMP1 = (1U << 7) | (1U << 28), /**< ACMP1 */
|
||||
CMU_PERH_OPAMP = (1U << 8) | (1U << 28), /**< OPAMP */
|
||||
CMU_PERH_DAC0 = (1U << 9) | (1U << 28), /**< DAC0 */
|
||||
CMU_PERH_ACMP2 = (1U << 11) | (1U << 28), /**< ACMP2 */
|
||||
CMU_PERH_WWDT = (1U << 12) | (1U << 28), /**< WWDT */
|
||||
CMU_PERH_LCD = (1U << 13) | (1U << 28), /**< LCD */
|
||||
CMU_PERH_IWDT = (1U << 14) | (1U << 28), /**< IWDT */
|
||||
CMU_PERH_RTC = (1U << 15) | (1U << 28), /**< RTC */
|
||||
CMU_PERH_TSENSE = (1U << 16) | (1U << 28), /**< TSENSE */
|
||||
CMU_PERH_BKPC = (1U << 17) | (1U << 28), /**< BKPC */
|
||||
CMU_PERH_DBGC = (1U << 19) | (1U << 28), /**< DBGC */
|
||||
CMU_PERH_ALL = (0x7FFFFFFFU), /**< ALL */
|
||||
} cmu_perh_t;
|
||||
|
||||
/**
|
||||
* @brief CMU interrupt type
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_LOSC_STOP = 0x0U, /**< LOSC STOP INTERRUPT */
|
||||
CMU_HOSC_STOP = 0x1U, /**< HOSC STOP INTERRUPT */
|
||||
CMU_PLL1_UNLOCK = 0x2U, /**< PLL1 UNLOCK INTERRUPT */
|
||||
CMU_LOSC_START = 0x3U, /**< LOSC START INTERRUPT */
|
||||
CMU_HOSC_START = 0x4U, /**< HOSC START INTERRUPT */
|
||||
} cmu_security_t;
|
||||
|
||||
/**
|
||||
* @brief CMU clock state type
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_CLOCK_STATE_HOSCACT = (1U << 0), /**< HOSC active */
|
||||
CMU_CLOCK_STATE_LOSCACT = (1U << 1), /**< LOSC active */
|
||||
CMU_CLOCK_STATE_HRCACT = (1U << 2), /**< HRC active */
|
||||
CMU_CLOCK_STATE_LRCACT = (1U << 3), /**< LRC active */
|
||||
CMU_CLOCK_STATE_ULRCACT = (1U << 4), /**< ULRC active */
|
||||
CMU_CLOCK_STATE_PLL1ACT = (1U << 8), /**< PLL1 active */
|
||||
CMU_CLOCK_STATE_PLL2ACT = (1U << 9), /**< PLL2 active */
|
||||
CMU_CLOCK_STATE_HOSCRDY = (1U << 16), /**< HOSC ready */
|
||||
CMU_CLOCK_STATE_LOSCRDY = (1U << 17), /**< LOSC ready */
|
||||
CMU_CLOCK_STATE_HRCRDY = (1U << 18), /**< HRC ready */
|
||||
CMU_CLOCK_STATE_LRCRDY = (1U << 19), /**< LRC ready */
|
||||
CMU_CLOCK_STATE_PLL1RDY = (1U << 24), /**< PLL1 ready */
|
||||
CMU_CLOCK_STATE_PLL2RDY = (1U << 25), /**< PLL2 ready */
|
||||
} cmu_clock_state_t;
|
||||
|
||||
/**
|
||||
* @brief Stop1 clock select type
|
||||
*/
|
||||
typedef enum {
|
||||
CMU_STOP1_CLOCK_LRC = 0x0U, /**< LRC */
|
||||
CMU_STOP1_CLOCK_HRC_24M = 0x1U, /**< HRC 24MHz */
|
||||
CMU_STOP1_CLOCK_HRC_2M = 0x2U, /**< HRC 2MHz */
|
||||
CMU_STOP1_CLOCK_HRC_1M = 0x3U, /**< HRC divides to 1MHz */
|
||||
CMU_STOP1_CLOCK_HOSC = 0x4U, /**< HOSC */
|
||||
CMU_STOP1_CLOCK_HOSC_1M = 0x5U, /**< HOSC divides to 1MHz */
|
||||
CMU_STOP1_CLOCK_HOSCM = 0x6U, /**< HOSC security management */
|
||||
} cmu_stop1_clock_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup CMU_Private_Macros CMU Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_CMU_CLOCK(x) (((x) == CMU_CLOCK_HRC) || \
|
||||
((x) == CMU_CLOCK_LRC) || \
|
||||
((x) == CMU_CLOCK_LOSC) || \
|
||||
((x) == CMU_CLOCK_PLL1) || \
|
||||
((x) == CMU_CLOCK_HOSC))
|
||||
#if defined(ES32F36xx) || defined(ES32F39xx)
|
||||
#define IS_CMU_PLL1_OUTPUT(x) (((x) == CMU_PLL1_OUTPUT_36M) || \
|
||||
((x) == CMU_PLL1_OUTPUT_48M) || \
|
||||
((x) == CMU_PLL1_OUTPUT_72M) || \
|
||||
((x) == CMU_PLL1_OUTPUT_96M))
|
||||
#endif
|
||||
#ifdef ES32F336x
|
||||
#define IS_CMU_PLL1_OUTPUT(x) (((x) == CMU_PLL1_OUTPUT_36M) || \
|
||||
((x) == CMU_PLL1_OUTPUT_48M))
|
||||
#endif
|
||||
#define IS_CMU_PLL1_INPUT(x) (((x) == CMU_PLL1_INPUT_HRC_6) || \
|
||||
((x) == CMU_PLL1_INPUT_PLL2) || \
|
||||
((x) == CMU_PLL1_INPUT_HOSC) || \
|
||||
((x) == CMU_PLL1_INPUT_HOSC_2) || \
|
||||
((x) == CMU_PLL1_INPUT_HOSC_3) || \
|
||||
((x) == CMU_PLL1_INPUT_HOSC_4) || \
|
||||
((x) == CMU_PLL1_INPUT_HOSC_5) || \
|
||||
((x) == CMU_PLL1_INPUT_HOSC_6))
|
||||
#define IS_CMU_HOSC_RANGE(x) (((x) == CMU_HOSC_2M) || \
|
||||
((x) == CMU_HOSC_4M) || \
|
||||
((x) == CMU_HOSC_8M) || \
|
||||
((x) == CMU_HOSC_16M) || \
|
||||
((x) == CMU_HOSC_24M))
|
||||
#define IS_CMU_DIV(x) (((x) == CMU_DIV_1) || \
|
||||
((x) == CMU_DIV_2) || \
|
||||
((x) == CMU_DIV_4) || \
|
||||
((x) == CMU_DIV_8) || \
|
||||
((x) == CMU_DIV_16) || \
|
||||
((x) == CMU_DIV_32) || \
|
||||
((x) == CMU_DIV_64) || \
|
||||
((x) == CMU_DIV_128) || \
|
||||
((x) == CMU_DIV_256) || \
|
||||
((x) == CMU_DIV_512) || \
|
||||
((x) == CMU_DIV_1024) || \
|
||||
((x) == CMU_DIV_2048) || \
|
||||
((x) == CMU_DIV_4096))
|
||||
#define IS_CMU_BUS(x) (((x) == CMU_HCLK_1) || \
|
||||
((x) == CMU_HCLK_2) || \
|
||||
((x) == CMU_SYS) || \
|
||||
((x) == CMU_PCLK_1) || \
|
||||
((x) == CMU_PCLK_2))
|
||||
#define IS_CMU_OUTPUT_HIGH_SEL(x) (((x) == CMU_OUTPUT_HIGH_SEL_HOSC) || \
|
||||
((x) == CMU_OUTPUT_HIGH_SEL_LOSC) || \
|
||||
((x) == CMU_OUTPUT_HIGH_SEL_HRC) || \
|
||||
((x) == CMU_OUTPUT_HIGH_SEL_LRC) || \
|
||||
((x) == CMU_OUTPUT_HIGH_SEL_HOSM) || \
|
||||
((x) == CMU_OUTPUT_HIGH_SEL_PLL1) || \
|
||||
((x) == CMU_OUTPUT_HIGH_SEL_PLL2) || \
|
||||
((x) == CMU_OUTPUT_HIGH_SEL_SYSCLK))
|
||||
#define IS_CMU_OUTPUT_HIGH_DIV(x) (((x) == CMU_OUTPUT_DIV_1) || \
|
||||
((x) == CMU_OUTPUT_DIV_2) || \
|
||||
((x) == CMU_OUTPUT_DIV_4) || \
|
||||
((x) == CMU_OUTPUT_DIV_8) || \
|
||||
((x) == CMU_OUTPUT_DIV_16) || \
|
||||
((x) == CMU_OUTPUT_DIV_32) || \
|
||||
((x) == CMU_OUTPUT_DIV_64) || \
|
||||
((x) == CMU_OUTPUT_DIV_128))
|
||||
#define IS_CMU_OUTPUT_LOW_SEL(x) (((x) == CMU_OUTPUT_LOW_SEL_LOSC) || \
|
||||
((x) == CMU_OUTPUT_LOW_SEL_LRC ) || \
|
||||
((x) == CMU_OUTPUT_LOW_SEL_LOSM) || \
|
||||
((x) == CMU_OUTPUT_LOW_SEL_BUZZ) || \
|
||||
((x) == CMU_OUTPUT_LOW_SEL_ULRC))
|
||||
#define IS_CMU_SAFE_CLOCK_TYPE(x) (((x) == CMU_SAFE_CLK_HOSC) || \
|
||||
((x) == CMU_SAFE_CLK_LOSC) || \
|
||||
((x) == CMU_SAFE_CLK_PLL))
|
||||
#define IS_CMU_BUZZ_DIV(x) (((x) == CMU_BUZZ_DIV_2) || \
|
||||
((x) == CMU_BUZZ_DIV_4) || \
|
||||
((x) == CMU_BUZZ_DIV_8) || \
|
||||
((x) == CMU_BUZZ_DIV_16) || \
|
||||
((x) == CMU_BUZZ_DIV_32) || \
|
||||
((x) == CMU_BUZZ_DIV_64) || \
|
||||
((x) == CMU_BUZZ_DIV_128) || \
|
||||
((x) == CMU_BUZZ_DIV_256))
|
||||
#define IS_CMU_LP_PERH_CLOCK_SEL(x) (((x) == CMU_LP_PERH_CLOCK_SEL_PCLK2) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_PLL1) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_PLL2) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_HRC) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_HOSC) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_LRC) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_LOSC) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_ULRC) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_HRC_1M) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_HOSC_1M) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_LOSM) || \
|
||||
((x) == CMU_LP_PERH_CLOCK_SEL_HOSM))
|
||||
#define IS_CMU_LCD_CLOCK_SEL(x) (((x) == CMU_LCD_SEL_LOSM) || \
|
||||
((x) == CMU_LCD_SEL_LOSC) || \
|
||||
((x) == CMU_LCD_SEL_LRC) || \
|
||||
((x) == CMU_LCD_SEL_ULRC) || \
|
||||
((x) == CMU_LCD_SEL_HRC_1M) || \
|
||||
((x) == CMU_LCD_SEL_HOSC_1M))
|
||||
#define IS_CMU_QSPI_CLOCK_SEL(x) (((x) == CMU_QSPI_CLOCK_SEL_PCLK1) || \
|
||||
((x) == CMU_QSPI_CLOCK_SEL_HCLK2) || \
|
||||
((x) == CMU_QSPI_CLOCK_SEL_HRC) || \
|
||||
((x) == CMU_QSPI_CLOCK_SEL_HOSC) || \
|
||||
((x) == CMU_QSPI_CLOCK_SEL_PLL1) || \
|
||||
((x) == CMU_QSPI_CLOCK_SEL_HOSM))
|
||||
#define IS_CMU_USB_CLOCK_SEL(x) (((x) == CMU_USB_CLOCK_SEL_HOSC) || \
|
||||
((x) == CMU_USB_CLOCK_SEL_HRC) || \
|
||||
((x) == CMU_USB_CLOCK_SEL_PCLK1) || \
|
||||
((x) == CMU_USB_CLOCK_SEL_PLL1) || \
|
||||
((x) == CMU_USB_CLOCK_SEL_HOSM))
|
||||
#define IS_CMU_USB_DIV(x) (((x) == CMU_USB_DIV_1) || \
|
||||
((x) == CMU_USB_DIV_2) || \
|
||||
((x) == CMU_USB_DIV_4) || \
|
||||
((x) == CMU_USB_DIV_8) || \
|
||||
((x) == CMU_USB_DIV_16) || \
|
||||
((x) == CMU_USB_DIV_32) || \
|
||||
((x) == CMU_USB_DIV_64) || \
|
||||
((x) == CMU_USB_DIV_128) || \
|
||||
((x) == CMU_USB_DIV_256) || \
|
||||
((x) == CMU_USB_DIV_512) || \
|
||||
((x) == CMU_USB_DIV_1024) || \
|
||||
((x) == CMU_USB_DIV_2048) || \
|
||||
((x) == CMU_USB_DIV_4096))
|
||||
#define IS_CMU_PERH(x) (((x) == CMU_PERH_GPIO) || \
|
||||
((x) == CMU_PERH_CRC) || \
|
||||
((x) == CMU_PERH_CALC) || \
|
||||
((x) == CMU_PERH_CRYPT) || \
|
||||
((x) == CMU_PERH_TRNG) || \
|
||||
((x) == CMU_PERH_PIS) || \
|
||||
((x) == CMU_PERH_EBI) || \
|
||||
((x) == CMU_PERH_QSPI_H) || \
|
||||
((x) == CMU_PERH_DMA) || \
|
||||
((x) == CMU_PERH_USB) || \
|
||||
((x) == CMU_PERH_ECC) || \
|
||||
((x) == CMU_PERH_TIMER0) || \
|
||||
((x) == CMU_PERH_TIMER1) || \
|
||||
((x) == CMU_PERH_TIMER2) || \
|
||||
((x) == CMU_PERH_TIMER3) || \
|
||||
((x) == CMU_PERH_TIMER4) || \
|
||||
((x) == CMU_PERH_TIMER5) || \
|
||||
((x) == CMU_PERH_TIMER6) || \
|
||||
((x) == CMU_PERH_TIMER7) || \
|
||||
((x) == CMU_PERH_UART0) || \
|
||||
((x) == CMU_PERH_UART1) || \
|
||||
((x) == CMU_PERH_UART2) || \
|
||||
((x) == CMU_PERH_UART3) || \
|
||||
((x) == CMU_PERH_UART4) || \
|
||||
((x) == CMU_PERH_UART5) || \
|
||||
((x) == CMU_PERH_SPI0) || \
|
||||
((x) == CMU_PERH_SPI1) || \
|
||||
((x) == CMU_PERH_SPI2) || \
|
||||
((x) == CMU_PERH_I2C0) || \
|
||||
((x) == CMU_PERH_I2C1) || \
|
||||
((x) == CMU_PERH_CAN) || \
|
||||
((x) == CMU_PERH_QSPI_P) || \
|
||||
((x) == CMU_PERH_LPTIM0) || \
|
||||
((x) == CMU_PERH_LPUART0) || \
|
||||
((x) == CMU_PERH_ADC0) || \
|
||||
((x) == CMU_PERH_ADC1) || \
|
||||
((x) == CMU_PERH_ACMP0) || \
|
||||
((x) == CMU_PERH_ACMP1) || \
|
||||
((x) == CMU_PERH_OPAMP) || \
|
||||
((x) == CMU_PERH_DAC0) || \
|
||||
((x) == CMU_PERH_ACMP2) || \
|
||||
((x) == CMU_PERH_WWDT) || \
|
||||
((x) == CMU_PERH_LCD) || \
|
||||
((x) == CMU_PERH_IWDT) || \
|
||||
((x) == CMU_PERH_RTC) || \
|
||||
((x) == CMU_PERH_TSENSE) || \
|
||||
((x) == CMU_PERH_BKPC) || \
|
||||
((x) == CMU_PERH_DBGC) || \
|
||||
((x) == CMU_PERH_ALL))
|
||||
#define IS_CMU_CLOCK_STATE(x) (((x) == CMU_CLOCK_STATE_HOSCACT) || \
|
||||
((x) == CMU_CLOCK_STATE_LOSCACT) || \
|
||||
((x) == CMU_CLOCK_STATE_HRCACT) || \
|
||||
((x) == CMU_CLOCK_STATE_LRCACT) || \
|
||||
((x) == CMU_CLOCK_STATE_ULRCACT) || \
|
||||
((x) == CMU_CLOCK_STATE_PLL1ACT) || \
|
||||
((x) == CMU_CLOCK_STATE_PLL2ACT) || \
|
||||
((x) == CMU_CLOCK_STATE_HOSCRDY) || \
|
||||
((x) == CMU_CLOCK_STATE_LOSCRDY) || \
|
||||
((x) == CMU_CLOCK_STATE_HRCRDY) || \
|
||||
((x) == CMU_CLOCK_STATE_LRCRDY) || \
|
||||
((x) == CMU_CLOCK_STATE_PLL1RDY) || \
|
||||
((x) == CMU_CLOCK_STATE_PLL2RDY))
|
||||
#define IS_CMU_STOP1_CLOCK(x) (((x) == CMU_STOP1_CLOCK_LRC) || \
|
||||
((x) == CMU_STOP1_CLOCK_HRC_24M) || \
|
||||
((x) == CMU_STOP1_CLOCK_HRC_2M) || \
|
||||
((x) == CMU_STOP1_CLOCK_HRC_1M) || \
|
||||
((x) == CMU_STOP1_CLOCK_HOSC) || \
|
||||
((x) == CMU_STOP1_CLOCK_HOSC_1M) || \
|
||||
((x) == CMU_STOP1_CLOCK_HOSCM))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CMU_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
/** @addtogroup CMU_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
/* System clock configure */
|
||||
ald_status_t ald_cmu_clock_config_default(void);
|
||||
ald_status_t ald_cmu_clock_config(cmu_clock_t clk, uint32_t clock);
|
||||
void ald_cmu_pll1_config(cmu_pll1_input_t input, cmu_pll1_output_t output);
|
||||
uint32_t ald_cmu_get_clock(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CMU_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
/* BUS division control */
|
||||
void ald_cmu_div_config(cmu_bus_t bus, cmu_div_t div);
|
||||
uint32_t ald_cmu_get_hclk1_clock(void);
|
||||
uint32_t ald_cmu_get_hclk2_clock(void);
|
||||
uint32_t ald_cmu_get_sys_clock(void);
|
||||
uint32_t ald_cmu_get_pclk1_clock(void);
|
||||
uint32_t ald_cmu_get_pclk2_clock(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CMU_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
/* Clock safe configure */
|
||||
void ald_cmu_hosc_safe_config(cmu_hosc_range_t clock, type_func_t status);
|
||||
void ald_cmu_losc_safe_config(type_func_t status);
|
||||
void ald_cmu_pll_safe_config(type_func_t status);
|
||||
uint32_t ald_cmu_current_clock_source_get(cmu_clock_safe_type_t type);
|
||||
flag_status_t ald_cmu_get_clock_state(cmu_clock_state_t sr);
|
||||
void ald_cmu_irq_handler(void);
|
||||
void ald_cmu_irq_cbk(cmu_security_t se);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CMU_Public_Functions_Group4
|
||||
* @{
|
||||
*/
|
||||
/* Clock output configure */
|
||||
void ald_cmu_output_high_clock_config(cmu_output_high_sel_t sel,
|
||||
cmu_output_high_div_t div, type_func_t status);
|
||||
void ald_cmu_output_low_clock_config(cmu_output_low_sel_t sel, type_func_t status);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CMU_Public_Functions_Group5
|
||||
* @{
|
||||
*/
|
||||
/* Peripheral Clock configure */
|
||||
void ald_cmu_buzz_config(cmu_buzz_div_t div, uint16_t dat, type_func_t status);
|
||||
void ald_cmu_lptim0_clock_select(cmu_lp_perh_clock_sel_t clock);
|
||||
void ald_cmu_lpuart0_clock_select(cmu_lp_perh_clock_sel_t clock);
|
||||
void ald_cmu_lcd_clock_select(cmu_lcd_clock_sel_t clock);
|
||||
void ald_cmu_qspi_clock_select(cmu_qspi_clock_sel_t clock);
|
||||
void ald_cmu_usb_clock_config(cmu_usb_clock_sel_t clock, cmu_usb_div_t div);
|
||||
void ald_cmu_perh_clock_config(cmu_perh_t perh, type_func_t status);
|
||||
void ald_cmu_stop1_clock_sel(cmu_stop1_clock_t clock);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_CMU_H__ */
|
||||
@@ -1,212 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_crc.h
|
||||
* @brief Header file of CRC module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 18 Jun 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 18 Jun 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_CRC_H__
|
||||
#define __ALD_CRC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "ald_dma.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CRC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_Public_Types CRC Public Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief CRC mode
|
||||
*/
|
||||
typedef enum {
|
||||
CRC_MODE_CCITT = 0U, /**< Ccitt */
|
||||
CRC_MODE_8 = 1U, /**< Crc8 */
|
||||
CRC_MODE_16 = 2U, /**< Crc16 */
|
||||
CRC_MODE_32 = 3U, /**< Crc32 */
|
||||
} crc_mode_t;
|
||||
|
||||
/**
|
||||
* @brief CRC input length
|
||||
*/
|
||||
typedef enum {
|
||||
CRC_LEN_AUTO = 0U, /**< Auto */
|
||||
CRC_DATASIZE_8 = 1U, /**< Byte */
|
||||
CRC_DATASIZE_16 = 2U, /**< Half word */
|
||||
CRC_DATASIZE_32 = 3U, /**< Word */
|
||||
} crc_datasize_t;
|
||||
|
||||
/**
|
||||
* @brief CRC whether write error or no
|
||||
*/
|
||||
typedef enum {
|
||||
CRC_WERR_NO = 0U, /**< No error */
|
||||
CRC_WERR_ERR = 1U, /**< Error */
|
||||
} crc_werr_t;
|
||||
|
||||
/**
|
||||
* @brief CRC state structures definition
|
||||
*/
|
||||
typedef enum {
|
||||
CRC_STATE_RESET = 0x0U, /**< Peripheral is not initialized */
|
||||
CRC_STATE_READY = 0x1U, /**< Peripheral Initialized and ready for use */
|
||||
CRC_STATE_BUSY = 0x2U, /**< An internal process is ongoing */
|
||||
CRC_STATE_ERROR = 0x4U, /**< Error */
|
||||
} crc_state_t;
|
||||
|
||||
/**
|
||||
* @brief CRC init structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
crc_mode_t mode; /**< CRC mode */
|
||||
type_func_t data_rev; /**< CRC data reverse or no */
|
||||
type_func_t data_inv; /**< CRC data inverse or no */
|
||||
type_func_t chs_rev; /**< CRC check sum reverse or no */
|
||||
type_func_t chs_inv; /**< CRC check sum inverse or no */
|
||||
uint32_t seed; /**< CRC seed */
|
||||
} crc_init_t;
|
||||
|
||||
/**
|
||||
* @brief CRC Handle Structure definition
|
||||
*/
|
||||
typedef struct crc_handle_s {
|
||||
CRC_TypeDef *perh; /**< Register base address */
|
||||
crc_init_t init; /**< CRC required parameters */
|
||||
uint8_t *cal_buf; /**< The pointer of preparing buffer */
|
||||
uint32_t *cal_res; /**< The pointer of result */
|
||||
|
||||
dma_handle_t hdma; /**< CRC DMA handle parameters */
|
||||
|
||||
lock_state_t lock; /**< Locking object */
|
||||
crc_state_t state; /**< CRC operation state */
|
||||
|
||||
void (*cal_cplt_cbk)(struct crc_handle_s *arg); /**< Calculate completed callback */
|
||||
void (*err_cplt_cbk)(struct crc_handle_s *arg); /**< Calculate error callback */
|
||||
} crc_handle_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_Public_Macros CRC Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define CRC_ENABLE(handle) (SET_BIT((handle)->perh->CR, CRC_CR_EN_MSK))
|
||||
#define CRC_DISABLE(handle) (CLEAR_BIT((handle)->perh->CR, CRC_CR_EN_MSK))
|
||||
#define CRC_RESET(handle) (SET_BIT((handle)->perh->CR, CRC_CR_RST_MSK))
|
||||
#define CRC_DMA_ENABLE(handle) (SET_BIT((handle)->perh->CR, CRC_CR_DMAEN_MSK))
|
||||
#define CRC_DMA_DISABLE(handle) (CLEAR_BIT((handle)->perh->CR, CRC_CR_DMAEN_MSK))
|
||||
#define CRC_CLEAR_ERROR_FLAG(handle) (SET_BIT((handle)->perh->CR, CRC_CR_WERR_MSK))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_Private_Macros CRC Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_CRC(x) ((x) == CRC)
|
||||
#define IS_CRC_MODE(x) (((x) == CRC_MODE_CCITT) || \
|
||||
((x) == CRC_MODE_8) || \
|
||||
((x) == CRC_MODE_16) || \
|
||||
((x) == CRC_MODE_32))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CRC_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CRC_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_crc_init(crc_handle_t *hperh);
|
||||
void ald_crc_reset(crc_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CRC_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
uint32_t ald_crc_calculate(crc_handle_t *hperh, uint8_t *buf, uint32_t size);
|
||||
uint32_t ald_crc_calculate_halfword(crc_handle_t *hperh, uint16_t *buf, uint32_t size);
|
||||
uint32_t ald_crc_calculate_word(crc_handle_t *hperh, uint32_t *buf, uint32_t size);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup CRC_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_crc_calculate_by_dma(crc_handle_t *hperh, uint8_t *buf, uint32_t *res, uint16_t size, uint8_t channel);
|
||||
ald_status_t ald_crc_calculate_halfword_by_dma(crc_handle_t *hperh, uint16_t *buf, uint32_t *res, uint16_t size, uint8_t channel);
|
||||
ald_status_t ald_crc_calculate_word_by_dma(crc_handle_t *hperh, uint32_t *buf, uint32_t *res, uint16_t size, uint8_t channel);
|
||||
ald_status_t ald_crc_dma_pause(crc_handle_t *hperh);
|
||||
ald_status_t ald_crc_dma_resume(crc_handle_t *hperh);
|
||||
ald_status_t ald_crc_dma_stop(crc_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CRC_Public_Functions_Group4
|
||||
* @{
|
||||
*/
|
||||
crc_state_t ald_crc_get_state(crc_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_CRC_H__ */
|
||||
@@ -1,341 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_crypt.h
|
||||
* @brief Header file of CRYPT module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 19 Jun 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 19 Jun 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_CRYPT_H__
|
||||
#define __ALD_CRYPT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CRYPT
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CRYPT_Public_Types CRYPT Public Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief CRYPT encrypt or decrypt select
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_DECRYPT = 0U, /**< Decrypt */
|
||||
CRYPT_ENCRYPT = 1U, /**< Encrypt */
|
||||
} crypt_encs_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT aes key select
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_BITS_128 = 0U, /**< 128bit key for aes */
|
||||
CRYPT_BITS_192 = 1U, /**< 192bit key for aes */
|
||||
CRYPT_BITS_256 = 2U, /**< 256bit key for aes */
|
||||
} crypt_aesks_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT mode select
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_MODE_ECB = 0U, /**< ECB */
|
||||
CRYPT_MODE_CBC = 1U, /**< CBC */
|
||||
CRYPT_MODE_CTR = 2U, /**< CTR */
|
||||
} crypt_mode_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT data type
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_DATA_CHANGE_NO = 0U, /**< No exchange */
|
||||
CRYPT_DATA_CHANGE_16 = 1U, /**< 16bit exchange */
|
||||
CRYPT_DATA_CHANGE_8 = 2U, /**< 8bit exchange */
|
||||
CRYPT_DATA_CHANGE_1 = 3U, /**< 1bit exchange */
|
||||
} crypt_datatype_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT des key select
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_KEYS_2 = 0U, /**< 2 key for des */
|
||||
CRYPT_KEYS_3 = 1U, /**< 3 key for des */
|
||||
CRYPT_KEYS_1 = 2U, /**< 1 key for des */
|
||||
} crypt_desks_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT crypt select
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_CRYSEL_AES = 0U, /**< AES */
|
||||
CRYPT_CRYSEL_DES = 1U, /**< DES */
|
||||
} crypt_crysel_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT interrupt
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_IT_IT = 0x80U, /**< Interrupt */
|
||||
} crypt_it_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT interrupt flag
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_FLAG_AESIF = 0x1U, /**< Aes flag */
|
||||
CRYPT_FLAG_DESIF = 0x2U, /**< Des flag */
|
||||
CRYPT_FLAG_DONE = 0x100U, /**< Complete flag */
|
||||
} crypt_flag_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT key select
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_AES_BITS_128 = 0x4U, /**< 128bit key of aes */
|
||||
CRYPT_AES_BITS_192 = 0x6U, /**< 192bit key of aes */
|
||||
CRYPT_AES_BITS_256 = 0x8U, /**< 192bit key of ase */
|
||||
CRYPT_DES_KEYS_1 = 0x12U, /**< 1 key of des */
|
||||
CRYPT_DES_KEYS_2 = 0x14U, /**< 2 key of des */
|
||||
CRYPT_DES_KEYS_3 = 0x16U, /**< 3 key of des */
|
||||
} crypt_ks_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT state structures definition
|
||||
*/
|
||||
typedef enum {
|
||||
CRYPT_STATE_RESET = 0x0U, /**< Peripheral is not initialized */
|
||||
CRYPT_STATE_READY = 0x1U, /**< Peripheral Initialized and ready for use */
|
||||
CRYPT_STATE_BUSY = 0x2U, /**< An internal process is ongoing */
|
||||
CRYPT_STATE_ERROR = 0x4U, /**< Error */
|
||||
} crypt_state_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT key length
|
||||
*/
|
||||
typedef enum {
|
||||
KEY_2_LEN = 2U, /**< Key's lenth is 2 */
|
||||
KEY_4_LEN = 4U, /**< Key's lenth is 4 */
|
||||
KEY_6_LEN = 6U, /**< Key's lenth is 6 */
|
||||
KEY_8_LEN = 8U, /**< Key's lenth is 8 */
|
||||
} crypt_key_len_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT iv length
|
||||
*/
|
||||
typedef enum {
|
||||
IV_2_LEN = 2U, /**< iv's lenth is 2 */
|
||||
IV_4_LEN = 4U, /**< iv's lenth is 4 */
|
||||
} crypt_ivr_len_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT data type
|
||||
*/
|
||||
typedef enum {
|
||||
DATA_32_BIT = 0U, /**< 32 bit data,don't swap */
|
||||
DATA_16_BIT = 1U, /**< 16 bit data,swap */
|
||||
DATA_8_BIT = 2U, /**< 8 bit data,swap */
|
||||
DATA_1_BIT = 3U, /**< 1 bit data, swap */
|
||||
} crypt_data_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT init structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
crypt_mode_t mode; /**< Crypt mode */
|
||||
crypt_data_t type; /**< Data type select */
|
||||
crypt_ks_t key; /**< Key select */
|
||||
} crypt_init_t;
|
||||
|
||||
/**
|
||||
* @brief CRYPT Handle Structure definition
|
||||
*/
|
||||
typedef struct crypt_handle_s {
|
||||
CRYPT_TypeDef *perh; /**< Register base address */
|
||||
crypt_init_t init; /**< CRYPT required parameters */
|
||||
|
||||
dma_handle_t hdma_m2p; /**< CRYPT DMA handle parameters memory to crypt module */
|
||||
dma_handle_t hdma_p2m; /**< CRYPT DMA handle parameters crypt module to memory */
|
||||
|
||||
uint8_t *plain_text; /**< Pointer to plain text */
|
||||
uint8_t *cipher_text; /**< Pointer to cipher text */
|
||||
uint32_t size; /**< The size of crypt data buf */
|
||||
uint32_t count; /**< The count of crypt data buf */
|
||||
uint32_t step; /**< The step of once crypt 2(des) or 4(aes) */
|
||||
uint32_t dir; /**< ENCRYPT or DECRYPT */
|
||||
uint32_t iv[4]; /**< The iv of crypt */
|
||||
uint32_t iv_size; /**< The iv size */
|
||||
uint32_t key[8]; /**< The key of crypt */
|
||||
uint32_t key_size; /**< The key size */
|
||||
lock_state_t lock; /**< Locking object */
|
||||
crypt_state_t state; /**< CRYPT operation state */
|
||||
|
||||
void (*crypt_cplt_cbk)(struct crypt_handle_s *arg); /**< Crypt completed callback */
|
||||
void (*err_cplt_cbk)(struct crypt_handle_s *arg); /**< Crypt error callback */
|
||||
} crypt_handle_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CRYPT_Public_Macros CRYPT Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define CRYPT_GO(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_GO_MSK))
|
||||
#define CRYPT_FIFOEN_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_FIFOEN_MSK))
|
||||
#define CRYPT_FIFOEN_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, CRYPT_CON_FIFOEN_MSK))
|
||||
#define CRYPT_IVEN_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_IVEN_MSK))
|
||||
#define CRYPT_IVEN_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, CRYPT_CON_IVEN_MSK))
|
||||
#define CRYPT_IE_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_IE_MSK))
|
||||
#define CRYPT_IE_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, CRYPT_CON_IE_MSK))
|
||||
#define CRYPT_DMA_ENABLE(handle) (SET_BIT((handle)->perh->CON, CRYPT_CON_DMAEN_MSK))
|
||||
#define CRYPT_DMA_DISABLE(handle) (CLEAR_BIT((handle)->perh->CON, CRYPT_CON_DMAEN_MSK))
|
||||
#define CRYPT_SETDIR(handle, dir) do {(handle)->perh->CON &= ~(0x1 << CRYPT_CON_ENCS_POS); \
|
||||
(handle)->perh->CON |= (dir << CRYPT_CON_ENCS_POS);} while (0)
|
||||
#define CRYPT_WRITE_FIFO(handle, data) ((handle)->perh->FIFO = (data))
|
||||
#define CRYPT_READ_FIFO(handle) ((handle)->perh->FIFO)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CRYPT_Private_Macros CRYPT Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_CRYPT(x) ((x) == CRYPT)
|
||||
#define IS_CRYPT_MODE(x) (((x) == CRYPT_MODE_ECB) || \
|
||||
((x) == CRYPT_MODE_CBC) || \
|
||||
((x) == CRYPT_MODE_CTR))
|
||||
#define IS_CRYPT_KS(x) (((x) == CRYPT_AES_BITS_128) || \
|
||||
((x) == CRYPT_AES_BITS_192) || \
|
||||
((x) == CRYPT_AES_BITS_256) || \
|
||||
((x) == CRYPT_DES_KEYS_1) || \
|
||||
((x) == CRYPT_DES_KEYS_2) || \
|
||||
((x) == CRYPT_DES_KEYS_3))
|
||||
#define IS_CRYPT_IT(x) ((x) == CRYPT_IT_IT)
|
||||
#define IS_CRYPT_FLAG(x) (((x) == CRYPT_FLAG_AESIF) || \
|
||||
((x) == CRYPT_FLAG_DESIF) || \
|
||||
((x) == CRYPT_FLAG_DONE))
|
||||
#define IS_CRYPT_IV_LEN(x) (((x) == IV_2_LEN) || \
|
||||
((x) == IV_4_LEN))
|
||||
#define IS_CRYPT_KEY_LEN(x) (((x) == KEY_2_LEN) || \
|
||||
((x) == KEY_4_LEN) || \
|
||||
((x) == KEY_6_LEN) || \
|
||||
((x) == KEY_8_LEN))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CRYPT_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CRYPT_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
extern ald_status_t ald_crypt_init(crypt_handle_t *hperh);
|
||||
extern ald_status_t ald_crypt_write_key(crypt_handle_t *hperh, uint32_t * key, crypt_key_len_t len);
|
||||
extern ald_status_t ald_crypt_read_key(crypt_handle_t *hperh, uint32_t * key, crypt_key_len_t len);
|
||||
extern ald_status_t ald_crypt_write_ivr(crypt_handle_t *hperh, uint32_t * iv, crypt_ivr_len_t len);
|
||||
extern ald_status_t ald_crypt_read_ivr(crypt_handle_t *hperh, uint32_t * iv, crypt_ivr_len_t len);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CRYPT_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
extern ald_status_t ald_crypt_encrypt(crypt_handle_t *hperh, uint8_t * plain_text, uint8_t * cipher_text, uint32_t size);
|
||||
extern ald_status_t ald_crypt_decrypt(crypt_handle_t *hperh, uint8_t * cipher_text, uint8_t * plain_text, uint32_t size);
|
||||
extern ald_status_t ald_crypt_gcm_verify(crypt_handle_t *hperh, uint8_t *cipher_text, uint32_t size, uint8_t *aadata, uint32_t alen, uint8_t *tag);
|
||||
extern ald_status_t ald_crypt_encrypt_by_it(crypt_handle_t *hperh, uint8_t *plain_text, uint8_t *cipher_text, uint32_t size);
|
||||
extern ald_status_t ald_crypt_decrypt_by_it(crypt_handle_t *hperh, uint8_t *cipher_text, uint8_t *plain_text, uint32_t size);
|
||||
|
||||
extern ald_status_t ald_crypt_encrypt_by_dma(crypt_handle_t *hperh, uint8_t * plain_text,
|
||||
uint8_t *cipher_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m);
|
||||
extern ald_status_t ald_crypt_decrypt_by_dma(crypt_handle_t *hperh, uint8_t * cipher_text,
|
||||
uint8_t *plain_text, uint32_t size, uint8_t channel_m2p, uint8_t channel_p2m);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CRYPT_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern ald_status_t ald_crypt_dma_pause(crypt_handle_t *hperh);
|
||||
extern ald_status_t ald_crypt_dma_resume(crypt_handle_t *hperh);
|
||||
extern ald_status_t ald_crypt_dma_stop(crypt_handle_t *hperh);
|
||||
|
||||
extern void ald_crypt_irq_handler(crypt_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CRYPT_Public_Functions_Group4
|
||||
* @{
|
||||
*/
|
||||
extern void ald_crypt_interrupt_config(crypt_handle_t *hperh, crypt_it_t it, type_func_t state);
|
||||
extern flag_status_t ald_crypt_get_flag_status(crypt_handle_t *hperh, crypt_flag_t flag);
|
||||
extern void ald_crypt_clear_flag_status(crypt_handle_t *hperh, crypt_flag_t flag);
|
||||
extern it_status_t ald_crypt_get_it_status(crypt_handle_t *hperh, crypt_it_t it);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CRYPT_Public_Functions_Group5
|
||||
* @{
|
||||
*/
|
||||
extern crypt_state_t ald_crypt_get_state(crypt_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,321 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file ald_dac.h
|
||||
* @brief Header file of DAC Module library.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 28 Jun 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 28 Jun 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_DAC_H__
|
||||
#define __ALD_DAC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup DAC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup DAC_Pubulic_Types DAC Pubulic Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief DAC channel
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_CHANNEL_0 = 1U, /**< DAC channel 0 */
|
||||
DAC_CHANNEL_1 = 2U, /**< DAC channel 1 */
|
||||
DAC_CHANNEL_COMB = 3U, /**< DAC channel 0 and 1 */
|
||||
} dac_channel_t;
|
||||
|
||||
/**
|
||||
* @brief DAC convert mode
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_CONV_MODE_CONTINUOUS = 0U, /**< DAC set in continuous mode */
|
||||
DAC_CONV_MODE_SAMPLEHOLD = 1U, /**< DAC set in sample/hold mode */
|
||||
DAC_CONV_MODE_SAMPLEOFF = 2U, /**< DAC set in sample/shut off mode */
|
||||
} dac_conv_mode_t;
|
||||
|
||||
/**
|
||||
* @brief DAC out mode
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_OUTPUT_DISABLE = 0U, /**< DAC output disable */
|
||||
DAC_OUTPUT_PIN = 1U, /**< DAC output to pin enable */
|
||||
DAC_OUTPUT_ADC = 2U, /**< DAC output to adc and acmp enable */
|
||||
DAC_OUTPUT_PIN_ADC = 3U, /**< DAC output to pin, adc and acmp enable */
|
||||
} dac_out_mode_t;
|
||||
|
||||
/**
|
||||
* @brief DAC pis input channel
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_PIS_CH_0 = 0U, /**< PIS channel 0 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_1 = 1U, /**< PIS channel 1 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_2 = 2U, /**< PIS channel 2 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_3 = 3U, /**< PIS channel 3 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_4 = 4U, /**< PIS channel 4 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_5 = 5U, /**< PIS channel 5 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_6 = 6U, /**< PIS channel 6 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_7 = 7U, /**< PIS channel 7 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_8 = 8U, /**< PIS channel 8 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_9 = 9U, /**< PIS channel 9 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_10 = 10U, /**< PIS channel 10 triggers DAC channel conversion */
|
||||
DAC_PIS_CH_11 = 11U, /**< PIS channel 11 triggers DAC channel conversion */
|
||||
} dac_pissel_t;
|
||||
|
||||
/**
|
||||
* @brief DAC negative reference voltage definition
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_NEG_REF_VSS = 0x0U, /**< DAC negative regerence voltage vss */
|
||||
DAC_NEG_REF_VREFN = 0x1U, /**< DAC negative regerence voltage vrefn */
|
||||
} dac_neg_ref_t;
|
||||
|
||||
/**
|
||||
* @brief DAC positive reference voltage definition
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_POS_REF_VDD = 0x0U, /**< DAC posotove reference is VDD */
|
||||
DAC_POS_REF_2V = 0x1U, /**< DAC posotove reference is internal 2V */
|
||||
DAC_POS_REF_VREEFP = 0x2U, /**< DAC posotove reference is VREEFP */
|
||||
DAC_POS_REF_VREEFP_BUF = 0x3U, /**< DAC posotove reference is VREEFP BUFFER */
|
||||
} dac_pos_ref_t;
|
||||
|
||||
/**
|
||||
* @brief Refresh interval select
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_REFRESH_8 = 0U, /**< Channel refreshed every 8 cycles */
|
||||
DAC_REFRESH_16 = 1U, /**< Channel refreshed every 16 cycles */
|
||||
DAC_REFRESH_32 = 2U, /**< Channel refreshed every 32 cycles */
|
||||
DAC_REFRESH_64 = 3U, /**< Channel refreshed every 64 cycles */
|
||||
} dac_refresh_t;
|
||||
|
||||
/**
|
||||
* @brief DAC prescale
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_PRES_DIV_1 = 0U, /**< No division */
|
||||
DAC_PRES_DIV_2 = 1U, /**< 2 clock division */
|
||||
DAC_PRES_DIV_4 = 2U, /**< 4 clock division */
|
||||
DAC_PRES_DIV_8 = 3U, /**< 8 clock division */
|
||||
DAC_PRES_DIV_16 = 4U, /**< 16 clock division */
|
||||
DAC_PRES_DIV_32 = 5U, /**< 32 clock division */
|
||||
DAC_PRES_DIV_64 = 6U, /**< 64 clock division */
|
||||
DAC_PRES_DIV_128 = 7U, /**< 128 clock division */
|
||||
} dac_prescale_div_t;
|
||||
|
||||
/**
|
||||
* @brief DAC output trigger select
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_TRIGGER_BY_DATA = 0U, /**< Channel is triggered by CHxDATA or COMBDATA write */
|
||||
DAC_TRIGGER_BY_PIS = 1U, /**< Channel is triggered by PIS input */
|
||||
} dac_trigger_t;
|
||||
|
||||
/**
|
||||
* @brief DAC interrupt type
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_IT_CH0 = (1U << 0), /**< Channel 0 conversion complete interrupt */
|
||||
DAC_IT_CH1 = (1U << 1), /**< Channel 1 conversion complete interrupt */
|
||||
DAC_IT_CH0_UF = (1U << 4), /**< Channel 0 data underflow interrupt */
|
||||
DAC_IT_CH1_UF = (1U << 5), /**< Channel 1 data underflow interrupt */
|
||||
} dac_it_t;
|
||||
|
||||
/**
|
||||
* @brief DAC interrupt flag type
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_FLAG_CH0 = (1U << 0), /**< Channel 0 conversion complete interrupt flag */
|
||||
DAC_FLAG_CH1 = (1U << 1), /**< Channel 1 conversion complete interrupt flag */
|
||||
DAC_FLAG_CH0_UF = (1U << 4), /**< Channel 0 data underflow interrupt flag */
|
||||
DAC_FLAG_CH1_UF = (1U << 5), /**< Channel 1 data underflow interrupt flag */
|
||||
} dac_flag_t;
|
||||
|
||||
/**
|
||||
* @brief DAC state flag
|
||||
*/
|
||||
typedef enum {
|
||||
DAC_CH0_BSY = (1U << 0), /**< Channel_0 is BUSY */
|
||||
DAC_CH1_BSY = (1U << 1), /**< Channel_1 is BUSY */
|
||||
} dac_status_t;
|
||||
|
||||
/**
|
||||
* @brief DAC init structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
dac_conv_mode_t conv_mode; /**< Conversion mode */
|
||||
dac_out_mode_t out_mode; /**< Select output mode */
|
||||
dac_refresh_t refresh; /**< Refresh interval select */
|
||||
dac_prescale_div_t div; /**< Prescaler setting */
|
||||
type_func_t ch0_reset; /**< Select if prescaler is reset on channel 0 start */
|
||||
type_func_t o_ctrl_pis; /**< Enable pis control of dac output enable */
|
||||
type_func_t sine; /**< Sine mode enable/disable */
|
||||
type_func_t diff; /**< Differential mode enable/disable */
|
||||
dac_neg_ref_t n_ref; /**< The negative reference voltage select */
|
||||
dac_pos_ref_t p_ref; /**< The positive reference voltage select */
|
||||
} dac_init_t;
|
||||
|
||||
/**
|
||||
* @brief DAC channel initialize structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
type_func_t enable; /**< DAC channel output enable/disable */
|
||||
dac_trigger_t trigger; /**< Select channel conversion trigger */
|
||||
type_func_t refresh_en; /**< Set automatic refresh of channel function */
|
||||
dac_pissel_t pis_ch; /**< Select channel pis input channel */
|
||||
} dac_channel_config_t;
|
||||
|
||||
/**
|
||||
* @brief DAC handle Structure definition
|
||||
*/
|
||||
typedef struct dac_handle_s {
|
||||
DAC_TypeDef *perh; /**< Register base address */
|
||||
dac_init_t init; /**< DAC initialize parameters */
|
||||
lock_state_t lock; /**< Locking object */
|
||||
|
||||
void (*cbk)(struct dac_handle_s *arg, uint32_t event); /**< DAC event callback */
|
||||
} dac_handle_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DAC_Public_Macros DAC Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define DAC_CH0_ENABLE() (SET_BIT(DAC0->CH0CTRL, DAC_CH0CTRL_EN_MSK))
|
||||
#define DAC_CH1_ENABLE() (SET_BIT(DAC0->CH1CTRL, DAC_CH1CTRL_EN_MSK))
|
||||
#define DAC_CH0_DISABLE() (CLEAR_BIT(DAC0->CH0CTRL, DAC_CH0CTRL_EN_MSK))
|
||||
#define DAC_CH1_DISABLE() (CLEAR_BIT(DAC0->CH1CTRL, DAC_CH1CTRL_EN_MSK))
|
||||
|
||||
#define DAC_EVENT_CH0_CPLT 0x0
|
||||
#define DAC_EVENT_CH1_CPLT 0x1
|
||||
#define DAC_EVENT_CH0_UF 0x2
|
||||
#define DAC_EVENT_CH1_UF 0x3
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DAC_Private_Macros DAC Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_DAC_TYPE(x) ((x) == DAC0)
|
||||
#define IS_DAC_CONVERT_TYPE(x) (((x) == DAC_CONV_MODE_CONTINUOUS) || \
|
||||
((x) == DAC_CONV_MODE_SAMPLEHOLD) || \
|
||||
((x) == DAC_CONV_MODE_SAMPLEOFF))
|
||||
#define IS_DAC_OUTPUT_TYPE(x) (((x) == DAC_OUTPUT_DISABLE) || \
|
||||
((x) == DAC_OUTPUT_PIN) || \
|
||||
((x) == DAC_OUTPUT_ADC) || \
|
||||
((x) == DAC_OUTPUT_PIN_ADC))
|
||||
#define IS_DAC_NEG_REFRESH_TYPE(x) (((x) == DAC_NEG_REF_VSS) || \
|
||||
((x) == DAC_NEG_REF_VREFN))
|
||||
#define IS_DAC_POS_REFRESH_TYPE(x) (((x) == DAC_POS_REF_VDD) || \
|
||||
((x) == DAC_POS_REF_2V) || \
|
||||
((x) == DAC_POS_REF_VREEFP) || \
|
||||
((x) == DAC_POS_REF_VREEFP_BUF))
|
||||
#define IS_DAC_REFRESH_TYPE(x) (((x) == DAC_REFRESH_8) || \
|
||||
((x) == DAC_REFRESH_16) || \
|
||||
((x) == DAC_REFRESH_32) || \
|
||||
((x) == DAC_REFRESH_64))
|
||||
#define IS_DAC_CHANNEL_TYPE(x) (((x) == DAC_CHANNEL_0) || \
|
||||
((x) == DAC_CHANNEL_1) || \
|
||||
((x) == DAC_CHANNEL_COMB))
|
||||
#define IS_DAC_PRESCALE_TYPE(x) (((x) == DAC_PRES_DIV_1) || \
|
||||
((x) == DAC_PRES_DIV_2) || \
|
||||
((x) == DAC_PRES_DIV_4) || \
|
||||
((x) == DAC_PRES_DIV_8) || \
|
||||
((x) == DAC_PRES_DIV_16) || \
|
||||
((x) == DAC_PRES_DIV_32) || \
|
||||
((x) == DAC_PRES_DIV_64) || \
|
||||
((x) == DAC_PRES_DIV_128))
|
||||
#define IS_DAC_INTERRUPT_TYPE(x) (((x) == DAC_IT_CH0) || \
|
||||
((x) == DAC_IT_CH1) || \
|
||||
((x) == DAC_IT_CH0_UF) || \
|
||||
((x) == DAC_IT_CH1_UF))
|
||||
#define IS_DAC_FLAG_TYPE(x) (((x) == DAC_FLAG_CH0) || \
|
||||
((x) == DAC_FLAG_CH1) || \
|
||||
((x) == DAC_FLAG_CH0_UF) || \
|
||||
((x) == DAC_FLAG_CH1_UF))
|
||||
#define IS_DAC_PISSEL_CH_TYPE(x) (((x) == DAC_PIS_CH_0) || \
|
||||
((x) == DAC_PIS_CH_1) || \
|
||||
((x) == DAC_PIS_CH_2) || \
|
||||
((x) == DAC_PIS_CH_3) || \
|
||||
((x) == DAC_PIS_CH_4) || \
|
||||
((x) == DAC_PIS_CH_5) || \
|
||||
((x) == DAC_PIS_CH_6) || \
|
||||
((x) == DAC_PIS_CH_7) || \
|
||||
((x) == DAC_PIS_CH_8) || \
|
||||
((x) == DAC_PIS_CH_9) || \
|
||||
((x) == DAC_PIS_CH_10) || \
|
||||
((x) == DAC_PIS_CH_11))
|
||||
#define IS_DAC_STATUS_TYPE(x) (((x) == DAC_CH0_BSY) || \
|
||||
((x) == DAC_CH1_BSY))
|
||||
#define IS_DAC_TRIGGER_TYPE(x) (((x) == DAC_TRIGGER_BY_DATA) || \
|
||||
((x) == DAC_TRIGGER_BY_PIS))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup DAC_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_dac_reset(dac_handle_t *hperh);
|
||||
ald_status_t ald_dac_init(dac_handle_t *hperh);
|
||||
ald_status_t ald_dac_channel_config(dac_handle_t *hperh, dac_channel_config_t *config, dac_channel_t ch);
|
||||
void ald_dac_output_set(dac_handle_t *hperh, dac_channel_t ch, uint32_t value);
|
||||
flag_status_t ald_dac_get_status(dac_handle_t *hperh, dac_status_t status);
|
||||
void ald_dac_interrupt_config(dac_handle_t *hperh, dac_it_t it, type_func_t state);
|
||||
it_status_t ald_dac_get_it_status(dac_handle_t *hperh, dac_it_t it);
|
||||
flag_status_t ald_dac_get_flag_status(dac_handle_t *hperh, dac_flag_t flag);
|
||||
flag_status_t ald_dac_get_mask_flag_status(dac_handle_t *hperh, dac_flag_t flag);
|
||||
void ald_dac_clear_flag_status(dac_handle_t *hperh, dac_flag_t flag);
|
||||
void ald_dac_irq_handler(dac_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" }
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_DAC_H */
|
||||
@@ -1,172 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_dbgc.h
|
||||
* @brief DEBUGCON module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 04 Jun 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 04 Jun 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_DBGC_H__
|
||||
#define __ALD_DBGC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup DBGC DBGC
|
||||
* @brief DBGC module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup DBGC_Public_Types DBGC Public Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Debug mode select
|
||||
*/
|
||||
typedef enum {
|
||||
DEBC_MODE_SLEEP = (1U << 0), /**< Sleep mode */
|
||||
DEBC_MODE_STOP1 = (1U << 1), /**< STOP1 mode */
|
||||
DEBC_MODE_STOP2 = (1U << 2), /**< STOP2 mode */
|
||||
DEBC_MODE_STANDBY = (1U << 3), /**< Standby mode */
|
||||
} dbgc_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Debug peripheral select
|
||||
*/
|
||||
typedef enum {
|
||||
DEBC_PERH_TIMER0 = (1U << 0), /**< AD16C4T0 */
|
||||
DEBC_PERH_TIMER1 = (1U << 1), /**< BS16T0 */
|
||||
DEBC_PERH_TIMER2 = (1U << 2), /**< GP16C2T0 */
|
||||
DEBC_PERH_TIMER3 = (1U << 3), /**< GP16C2T1 */
|
||||
DEBC_PERH_TIMER4 = (1U << 4), /**< BS16T1 */
|
||||
DEBC_PERH_TIMER5 = (1U << 5), /**< BS16T2 */
|
||||
DEBC_PERH_TIMER6 = (1U << 6), /**< GP16C4T0 */
|
||||
DEBC_PERH_TIMER7 = (1U << 7), /**< BS16T3 */
|
||||
DEBC_PERH_I2C0 = (1U << 8), /**< I2C0 SMBUS */
|
||||
DEBC_PERH_I2C1 = (1U << 9), /**< I2C1 SMBUS */
|
||||
DEBC_PERH_CAN = (1U << 12), /**< CAN */
|
||||
DEBC_PERH_LPTIM0 = (1U << 0) | (1U << 16), /**< LPTIM0 */
|
||||
DEBC_PERH_IWDT = (1U << 8) | (1U << 16), /**< IWDT */
|
||||
DEBC_PERH_WWDT = (1U << 9) | (1U << 16), /**< WWDT */
|
||||
DEBC_PERH_RTC = (1U << 10) | (1U << 16), /**< RTC */
|
||||
} dbgc_perh_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DBGC_Public_Functions DBGC Public Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Gets version.
|
||||
* @retval Version
|
||||
*/
|
||||
__INLINE uint32_t ald_dbgc_get_rev_id(void)
|
||||
{
|
||||
return (DBGC->IDCODE >> 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets core id.
|
||||
* @retval Core id
|
||||
*/
|
||||
__INLINE uint32_t ald_dbgc_get_core_id(void)
|
||||
{
|
||||
return (DBGC->IDCODE >> 12) & 0xF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets device id
|
||||
* @retval device id
|
||||
*/
|
||||
__INLINE uint32_t ald_dbgc_get_device_id(void)
|
||||
{
|
||||
return DBGC->IDCODE & 0xFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures low power debug mode
|
||||
* @param mode: The mode of low power.
|
||||
* @param state: ENABLE/DISABLE
|
||||
* @retval None
|
||||
*/
|
||||
__INLINE void ald_dbgc_mode_config(dbgc_mode_t mode, type_func_t state)
|
||||
{
|
||||
if (state)
|
||||
SET_BIT(DBGC->CR, mode);
|
||||
else
|
||||
CLEAR_BIT(DBGC->CR, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures peripheral debug mode
|
||||
* @param perh: The peripheral.
|
||||
* @param state: ENABLE/DISABLE
|
||||
* @retval None
|
||||
*/
|
||||
__INLINE void ald_dbgc_perh_config(dbgc_perh_t perh, type_func_t state)
|
||||
{
|
||||
if ((perh >> 16) & 0x1) {
|
||||
if (state)
|
||||
SET_BIT(DBGC->APB2FZ, perh);
|
||||
else
|
||||
CLEAR_BIT(DBGC->APB2FZ, perh);
|
||||
}
|
||||
else {
|
||||
if (state)
|
||||
SET_BIT(DBGC->APB1FZ, perh);
|
||||
else
|
||||
CLEAR_BIT(DBGC->APB1FZ, perh);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,446 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_dma.h
|
||||
* @brief DMA module Library.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 09 Nov 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 09 Nov 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_DMA_H__
|
||||
#define __ALD_DMA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup DMA
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup DMA_Public_Macros DMA Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define DMA_CH_COUNT 12U
|
||||
#define DMA_ERR 31U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup DMA_Public_Types DMA Public Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Input source to DMA channel
|
||||
* @verbatim
|
||||
In this module, for the convenience of code maintenance,
|
||||
TIMERx is used to indicate the sequence of the timer peripheral.
|
||||
Different product series TIMERx represent different meanings:
|
||||
1. For ES32F36xx series:
|
||||
TIMER0 ----> AD16C4T0
|
||||
TIMER1 ----> AD16C4T1
|
||||
TIMER2 ----> GP32C4T0
|
||||
TIMER3 ----> GP32C4T1
|
||||
TIMER4 ----> BS16T0
|
||||
TIMER5 ----> BS16T1
|
||||
TIMER6 ----> GP16C4T0
|
||||
TIMER7 ----> GP16C4T1
|
||||
|
||||
2. For ES32F393x/ES32F336x/ES32F392x series:
|
||||
TIMER0 ----> GP16C4T0
|
||||
TIMER1 ----> GP16C4T1
|
||||
TIMER2 ----> GP32C4T0
|
||||
TIMER3 ----> GP32C4T1
|
||||
TIMER4 ----> BS16T0
|
||||
TIMER5 ----> BS16T1
|
||||
TIMER6 ----> GP16C4T2
|
||||
TIMER7 ----> GP16C4T3
|
||||
@endverbatim
|
||||
*/
|
||||
typedef enum {
|
||||
DMA_MSEL_NONE = 0x0U, /**< NONE */
|
||||
DMA_MSEL_GPIO = 0x1U, /**< GPIO */
|
||||
DMA_MSEL_CRYPT = 0x2U, /**< CRYPT */
|
||||
DMA_MSEL_DAC0 = 0x4U, /**< DAC0 */
|
||||
DMA_MSEL_ADC0 = 0x6U, /**< ADC0 */
|
||||
DMA_MSEL_CRC = 0x7U, /**< CRC */
|
||||
DMA_MSEL_UART0 = 0x8U, /**< UART0 */
|
||||
DMA_MSEL_UART1 = 0x9U, /**< UART1 */
|
||||
DMA_MSEL_UART2 = 0xAU, /**< UART2 */
|
||||
DMA_MSEL_UART3 = 0xBU, /**< UART3 */
|
||||
DMA_MSEL_UART4 = 0xCU, /**< UART4 */
|
||||
DMA_MSEL_UART5 = 0xDU, /**< UART5 */
|
||||
DMA_MSEL_SPI0 = 0xEU, /**< SPI0 */
|
||||
DMA_MSEL_SPI1 = 0xFU, /**< SPI1 */
|
||||
DMA_MSEL_I2C0 = 0x10U, /**< I2C0 */
|
||||
DMA_MSEL_I2C1 = 0x11U, /**< I2C1 */
|
||||
DMA_MSEL_TIMER0 = 0x12U, /**< TIMER0 */
|
||||
DMA_MSEL_TIMER1 = 0x13U, /**< TIMER1 */
|
||||
DMA_MSEL_TIMER2 = 0x14U, /**< TIMER2 */
|
||||
DMA_MSEL_TIMER3 = 0x15U, /**< TIMER3 */
|
||||
DMA_MSEL_LPUART0 = 0x18U, /**< LPUART0 */
|
||||
DMA_MSEL_SPI2 = 0x1AU, /**< SPI2 */
|
||||
DMA_MSEL_TIMER4 = 0x1BU, /**< TIMER4 */
|
||||
DMA_MSEL_TIMER5 = 0x1CU, /**< TIMER5 */
|
||||
DMA_MSEL_TIMER6 = 0x1DU, /**< TIMER6 */
|
||||
DMA_MSEL_TIMER7 = 0x1EU, /**< TIMER7 */
|
||||
DMA_MSEL_ADC1 = 0x1FU, /**< ADC1 */
|
||||
DMA_MSEL_PIS = 0x20U, /**< PIS */
|
||||
DMA_MSEL_TRNG = 0x21U, /**< TRNG */
|
||||
DMA_MSEL_QSPI = 0x22U, /**< QSPI */
|
||||
DMA_MSEL_USB = 0x23U, /**< USB */
|
||||
} dma_msel_t;
|
||||
|
||||
/**
|
||||
* @brief Input signal to DMA channel
|
||||
*/
|
||||
typedef enum {
|
||||
DMA_MSIGSEL_NONE = 0x0U, /**< NONE */
|
||||
DMA_MSIGSEL_EXTI_0 = 0x0U, /**< External interrupt 0 */
|
||||
DMA_MSIGSEL_EXTI_1 = 0x1U, /**< External interrupt 1 */
|
||||
DMA_MSIGSEL_EXTI_2 = 0x2U, /**< External interrupt 2 */
|
||||
DMA_MSIGSEL_EXTI_3 = 0x3U, /**< External interrupt 3 */
|
||||
DMA_MSIGSEL_EXTI_4 = 0x4U, /**< External interrupt 4 */
|
||||
DMA_MSIGSEL_EXTI_5 = 0x5U, /**< External interrupt 5 */
|
||||
DMA_MSIGSEL_EXTI_6 = 0x6U, /**< External interrupt 6 */
|
||||
DMA_MSIGSEL_EXTI_7 = 0x7U, /**< External interrupt 7 */
|
||||
DMA_MSIGSEL_EXTI_8 = 0x8U, /**< External interrupt 8 */
|
||||
DMA_MSIGSEL_EXTI_9 = 0x9U, /**< External interrupt 9 */
|
||||
DMA_MSIGSEL_EXTI_10 = 0xAU, /**< External interrupt 10 */
|
||||
DMA_MSIGSEL_EXTI_11 = 0xBU, /**< External interrupt 11 */
|
||||
DMA_MSIGSEL_EXTI_12 = 0xCU, /**< External interrupt 12 */
|
||||
DMA_MSIGSEL_EXTI_13 = 0xDU, /**< External interrupt 13 */
|
||||
DMA_MSIGSEL_EXTI_14 = 0xEU, /**< External interrupt 14 */
|
||||
DMA_MSIGSEL_EXTI_15 = 0xFU, /**< External interrupt 15 */
|
||||
DMA_MSIGSEL_CRYPT_WRITE = 0x0U, /**< CRYPT write mode */
|
||||
DMA_MSIGSEL_CRYPT_READ = 0x1U, /**< CRYPT read mode */
|
||||
DMA_MSIGSEL_DAC0_CH0 = 0x0U, /**< DAC0 channel 0 complete */
|
||||
DMA_MSIGSEL_DAC0_CH1 = 0x1U, /**< DAC0 channel 1 complete */
|
||||
DMA_MSIGSEL_ADC = 0x0U, /**< ADC mode */
|
||||
DMA_MSIGSEL_UART_TXEMPTY = 0x0U, /**< UART0/UART1/UART2/UART3 transmit */
|
||||
DMA_MSIGSEL_UART_RNR = 0x1U, /**< UART0/UART1/UART2/UART3 receive */
|
||||
DMA_MSIGSEL_UART45_RNR = 0x0U, /**< UART4/UART5 reveive */
|
||||
DMA_MSIGSEL_UART45_TXEMPTY = 0x1U, /**< UART4/UART5 transmit */
|
||||
DMA_MSIGSEL_SPI_RNR = 0x0U, /**< SPI receive */
|
||||
DMA_MSIGSEL_SPI_TXEMPTY = 0x1U, /**< SPI transmit */
|
||||
DMA_MSIGSEL_I2C_RNR = 0x0U, /**< I2C receive */
|
||||
DMA_MSIGSEL_I2C_TXEMPTY = 0x1U, /**< I2C transmit */
|
||||
DMA_MSIGSEL_TIMER_CH1 = 0x0U, /**< TIM channal 1 */
|
||||
DMA_MSIGSEL_TIMER_CH2 = 0x1U, /**< TIM channal 2 */
|
||||
DMA_MSIGSEL_TIMER_CH3 = 0x2U, /**< TIM channal 3 */
|
||||
DMA_MSIGSEL_TIMER_CH4 = 0x3U, /**< TIM channal 4 */
|
||||
DMA_MSIGSEL_TIMER_TRI = 0x4U, /**< TIM trigger */
|
||||
DMA_MSIGSEL_TIMER_COMP = 0x5U, /**< TIM compare */
|
||||
DMA_MSIGSEL_TIMER_UPDATE = 0x6U, /**< TIM update */
|
||||
DMA_MSIGSEL_LPUART_RNR = 0x0U, /**< LPUART receive */
|
||||
DMA_MSIGSEL_LPUART_TXEMPTY = 0x1U, /**< LPUART transmit */
|
||||
DMA_MSIGSEL_PIS_CH0 = 0x0U, /**< PIS channal 0 */
|
||||
DMA_MSIGSEL_PIS_CH1 = 0x1U, /**< PIS channal 1 */
|
||||
DMA_MSIGSEL_PIS_CH2 = 0x2U, /**< PIS channal 2 */
|
||||
DMA_MSIGSEL_PIS_CH3 = 0x3U, /**< PIS channal 3 */
|
||||
DMA_MSIGSEL_PIS_CH4 = 0x4U, /**< PIS channal 4 */
|
||||
DMA_MSIGSEL_PIS_CH5 = 0x5U, /**< PIS channal 5 */
|
||||
DMA_MSIGSEL_PIS_CH6 = 0x6U, /**< PIS channal 6 */
|
||||
DMA_MSIGSEL_PIS_CH7 = 0x7U, /**< PIS channal 7 */
|
||||
DMA_MSIGSEL_PIS_CH8 = 0x8U, /**< PIS channal 8 */
|
||||
DMA_MSIGSEL_PIS_CH9 = 0x9U, /**< PIS channal 9 */
|
||||
DMA_MSIGSEL_PIS_CH10 = 0xAU, /**< PIS channal 10 */
|
||||
DMA_MSIGSEL_PIS_CH11 = 0xBU, /**< PIS channal 11 */
|
||||
DMA_MSIGSEL_PIS_CH12 = 0xCU, /**< PIS channal 12 */
|
||||
DMA_MSIGSEL_PIS_CH13 = 0xDU, /**< PIS channal 13 */
|
||||
DMA_MSIGSEL_PIS_CH14 = 0xEU, /**< PIS channal 14 */
|
||||
DMA_MSIGSEL_PIS_CH15 = 0xFU, /**< PIS channal 15 */
|
||||
DMA_MSIGSEL_QSPI_WRITE = 0x0U, /**< QSPI Write */
|
||||
DMA_MSIGSEL_QSPI_READ = 0x1U, /**< QSPI Read */
|
||||
DMA_MSIGSEL_EP_TX1 = 0x0U, /**< USB TX Endport 0 */
|
||||
DMA_MSIGSEL_EP_TX2 = 0x1U, /**< USB TX Endport 1 */
|
||||
DMA_MSIGSEL_EP_TX3 = 0x2U, /**< USB TX Endport 2 */
|
||||
DMA_MSIGSEL_EP_TX4 = 0x3U, /**< USB TX Endport 3 */
|
||||
DMA_MSIGSEL_EP_TX5 = 0x4U, /**< USB TX Endport 4 */
|
||||
DMA_MSIGSEL_EP_RX1 = 0x8U, /**< USB RX Endport 0 */
|
||||
DMA_MSIGSEL_EP_RX2 = 0x9U, /**< USB RX Endport 1 */
|
||||
DMA_MSIGSEL_EP_RX3 = 0xAU, /**< USB RX Endport 2 */
|
||||
DMA_MSIGSEL_EP_RX4 = 0xBU, /**< USB RX Endport 3 */
|
||||
DMA_MSIGSEL_EP_RX5 = 0xCU, /**< USB RX Endport 4 */
|
||||
} dma_msigsel_t;
|
||||
|
||||
/**
|
||||
* @brief DMA Descriptor control type
|
||||
*/
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t cycle_ctrl :3; /**< DMA operating mode @ref dma_cycle_ctrl_t */
|
||||
uint32_t next_useburst :1; /**< Uses the alternate data structure when complete a DMA cycle */
|
||||
uint32_t n_minus_1 :10; /**< Represent the total number of DMA transfers that DMA cycle contains. */
|
||||
uint32_t R_power :4; /**< Control how many DMA transfers can occur before re-arbitrates. @ref dma_arbiter_config_t */
|
||||
uint32_t src_prot_ctrl :3; /**< Control the state of HPROT when reads the source data. */
|
||||
uint32_t dst_prot_ctrl :3; /**< Control the state of HPROT when writes the destination data */
|
||||
uint32_t src_size :2; /**< Source data size @ref dma_data_size_t */
|
||||
uint32_t src_inc :2; /**< Control the source address increment. @ref dma_data_inc_t */
|
||||
uint32_t dst_size :2; /**< Destination data size. @ref dma_data_size_t */
|
||||
uint32_t dst_inc :2; /**< Destination address increment. @ref dma_data_inc_t */
|
||||
};
|
||||
uint32_t word;
|
||||
} dma_ctrl_t;
|
||||
|
||||
/**
|
||||
* @brief Channel control data structure
|
||||
*/
|
||||
typedef struct {
|
||||
void *src; /**< Source data end pointer */
|
||||
void *dst; /**< Destination data end pointer */
|
||||
dma_ctrl_t ctrl; /**< Control data configuration @ref dma_ctrl_t */
|
||||
uint32_t use; /**< Reserve for user */
|
||||
} dma_descriptor_t;
|
||||
|
||||
/**
|
||||
* @brief data increment
|
||||
*/
|
||||
typedef enum {
|
||||
DMA_DATA_INC_BYTE = 0x0U, /**< Address increment by byte */
|
||||
DMA_DATA_INC_HALFWORD = 0x1U, /**< Address increment by halfword */
|
||||
DMA_DATA_INC_WORD = 0x2U, /**< Address increment by word */
|
||||
DMA_DATA_INC_NONE = 0x3U, /**< No increment */
|
||||
} dma_data_inc_t;
|
||||
|
||||
/**
|
||||
* @brief Data size
|
||||
*/
|
||||
typedef enum {
|
||||
DMA_DATA_SIZE_BYTE = 0x0U, /**< Byte */
|
||||
DMA_DATA_SIZE_HALFWORD = 0x1U, /**< Halfword */
|
||||
DMA_DATA_SIZE_WORD = 0x2U, /**< Word */
|
||||
} dma_data_size_t;
|
||||
|
||||
/**
|
||||
* @brief The operating mode of the DMA cycle
|
||||
*/
|
||||
typedef enum {
|
||||
DMA_CYCLE_CTRL_NONE = 0x0U, /**< Stop */
|
||||
DMA_CYCLE_CTRL_BASIC = 0x1U, /**< Basic */
|
||||
DMA_CYCLE_CTRL_AUTO = 0x2U, /**< Auto-request */
|
||||
DMA_CYCLE_CTRL_PINGPONG = 0x3U, /**< Ping-pong */
|
||||
DMA_CYCLE_CTRL_MEM_SG_PRIMARY = 0x4U, /**< Memory scatter-gather using the primary structure */
|
||||
DMA_CYCLE_CTRL_MEM_SG_ALTERNATE = 0x5U, /**< Memory scatter-gather using the alternate structure */
|
||||
DMA_CYCLE_CTRL_PER_SG_PRIMARY = 0x6U, /**< Peripheral scatter-gather using the primary structure */
|
||||
DMA_CYCLE_CTRL_PER_SG_ALTERNATE = 0x7U, /**< Peripheral scatter-gather using the alternate structure */
|
||||
} dma_cycle_ctrl_t;
|
||||
|
||||
/**
|
||||
* @brief Control how many DMA transfers can occur
|
||||
* before the controller re-arbitrates
|
||||
*/
|
||||
typedef enum {
|
||||
DMA_R_POWER_1 = 0x0U, /**< Arbitrates after each DMA transfer */
|
||||
DMA_R_POWER_2 = 0x1U, /**< Arbitrates after 2 DMA transfer */
|
||||
DMA_R_POWER_4 = 0x2U, /**< Arbitrates after 4 DMA transfer */
|
||||
DMA_R_POWER_8 = 0x3U, /**< Arbitrates after 8 DMA transfer */
|
||||
DMA_R_POWER_16 = 0x4U, /**< Arbitrates after 16 DMA transfer */
|
||||
DMA_R_POWER_32 = 0x5U, /**< Arbitrates after 32 DMA transfer */
|
||||
DMA_R_POWER_64 = 0x6U, /**< Arbitrates after 64 DMA transfer */
|
||||
DMA_R_POWER_128 = 0x7U, /**< Arbitrates after 128 DMA transfer */
|
||||
DMA_R_POWER_256 = 0x8U, /**< Arbitrates after 256 DMA transfer */
|
||||
DMA_R_POWER_512 = 0x9U, /**< Arbitrates after 512 DMA transfer */
|
||||
DMA_R_POWER_1024 = 0xAU, /**< Arbitrates after 1024 DMA transfer */
|
||||
} dma_arbiter_config_t;
|
||||
|
||||
/**
|
||||
* @brief Callback function pointer and param
|
||||
*/
|
||||
typedef struct {
|
||||
void (*cplt_cbk)(void *arg); /**< DMA transfers complete callback */
|
||||
void (*err_cbk)(void* arg); /**< DMA occurs error callback */
|
||||
void *cplt_arg; /**< The parameter of cplt_cbk() */
|
||||
void *err_arg; /**< The parameter of err_cbk() */
|
||||
} dma_call_back_t;
|
||||
|
||||
/**
|
||||
* @brief DMA channal configure structure
|
||||
*/
|
||||
typedef struct {
|
||||
void *src; /**< Source data begin pointer */
|
||||
void *dst; /**< Destination data begin pointer */
|
||||
uint16_t size; /**< The total number of DMA transfers that DMA cycle contains */
|
||||
dma_data_size_t data_width; /**< Data width, @ref dma_data_size_t */
|
||||
dma_data_inc_t src_inc; /**< Source increment type. @ref dma_data_inc_t */
|
||||
dma_data_inc_t dst_inc; /**< Destination increment type. @ref dma_data_inc_t */
|
||||
dma_arbiter_config_t R_power; /**< Control how many DMA transfers can occur before re-arbitrates. @ref dma_arbiter_config_t */
|
||||
type_func_t primary; /**< Use primary descriptor or alternate descriptor */
|
||||
type_func_t burst; /**< Enable/Disable the useburst setting for this channel */
|
||||
type_func_t high_prio; /**< High priority or default priority */
|
||||
type_func_t interrupt; /**< Enable/disable interrupt */
|
||||
dma_msel_t msel; /**< Input source to DMA channel @ref dma_msel_t */
|
||||
dma_msigsel_t msigsel; /**< Input signal to DMA channel @ref dma_msigsel_t */
|
||||
uint8_t channel; /**< Channel index */
|
||||
} dma_config_t;
|
||||
|
||||
/**
|
||||
* @brief DMA handle structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
DMA_TypeDef *perh; /**< DMA registers base address */
|
||||
dma_config_t config; /**< Channel configure structure. @ref dma_config_t */
|
||||
void (*cplt_cbk)(void *arg); /**< DMA transfers complete callback */
|
||||
void (*err_cbk)(void *arg); /**< DMA bus occurs error callback */
|
||||
void *cplt_arg; /**< The parameter of cplt_cbk() */
|
||||
void *err_arg; /**< The parameter of err_cbk() */
|
||||
} dma_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Descriptor complete state
|
||||
*/
|
||||
typedef enum {
|
||||
DMA_DESCP_CPLT_PRI = 0x0U, /**< Primary descriptor has been completed */
|
||||
DMA_DESCP_CPLT_ALT = 0x1U, /**< Alternate descriptor has been completed */
|
||||
DMA_DESCP_CPLT_ALL = 0x2U, /**< Both primary and alternate descriptors have been completed */
|
||||
} dma_descrp_cplt_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup DMA_Private_Macros DMA Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_DMA_MSEL_TYPE(x) ((x) <= DMA_MSEL_USB)
|
||||
#define IS_DMA_MSIGSEL_TYPE(x) ((x) <= 0xF)
|
||||
#define IS_DMA_DATAINC_TYPE(x) (((x) == DMA_DATA_INC_BYTE) || \
|
||||
((x) == DMA_DATA_INC_HALFWORD) || \
|
||||
((x) == DMA_DATA_INC_WORD) || \
|
||||
((x) == DMA_DATA_INC_NONE))
|
||||
#define IS_DMA_DATASIZE_TYPE(x) (((x) == DMA_DATA_SIZE_BYTE) || \
|
||||
((x) == DMA_DATA_SIZE_HALFWORD) || \
|
||||
((x) == DMA_DATA_SIZE_WORD))
|
||||
#define IS_CYCLECTRL_TYPE(x) (((x) == DMA_CYCLE_CTRL_NONE) || \
|
||||
((x) == DMA_CYCLE_CTRL_BASIC) || \
|
||||
((x) == DMA_CYCLE_CTRL_AUTO) || \
|
||||
((x) == DMA_CYCLE_CTRL_PINGPONG) || \
|
||||
((x) == DMA_CYCLE_CTRL_MEM_SG_PRIMARY) || \
|
||||
((x) == DMA_CYCLE_CTRL_MEM_SG_ALTERNATE) || \
|
||||
((x) == DMA_CYCLE_CTRL_PER_SG_PRIMARY) || \
|
||||
((x) == DMA_CYCLE_CTRL_PER_SG_ALTERNATE))
|
||||
#define IS_DMA_ARBITERCONFIG_TYPE(x) (((x) == DMA_R_POWER_1) || \
|
||||
((x) == DMA_R_POWER_2) || \
|
||||
((x) == DMA_R_POWER_4) || \
|
||||
((x) == DMA_R_POWER_8) || \
|
||||
((x) == DMA_R_POWER_16) || \
|
||||
((x) == DMA_R_POWER_32) || \
|
||||
((x) == DMA_R_POWER_64) || \
|
||||
((x) == DMA_R_POWER_128) || \
|
||||
((x) == DMA_R_POWER_256) || \
|
||||
((x) == DMA_R_POWER_512) || \
|
||||
((x) == DMA_R_POWER_1024))
|
||||
#define IS_DMA(x) ((x) == DMA0)
|
||||
#define IS_DMA_CHANNEL(x) ((x) <= 11)
|
||||
#define IS_DMA_DATA_SIZE(x) ((x) <= 1024)
|
||||
#define IS_DMA_IT_TYPE(x) (((x) <= 11) || ((x) == 31))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup DMA_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup DMA_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
/* Initialization functions */
|
||||
extern void ald_dma_reset(DMA_TypeDef *DMAx);
|
||||
extern void ald_dma_init(DMA_TypeDef *DMAx);
|
||||
extern void ald_dma_config_struct(dma_config_t *p);
|
||||
extern void ald_dma_config_sg_alt_desc(dma_descriptor_t *desc, dma_config_t *config, uint8_t memory);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup DMA_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
/* Configure DMA channel functions */
|
||||
extern void ald_dma_config_auto(dma_handle_t *hperh);
|
||||
extern void ald_dma_restart_auto(dma_handle_t *hperh, void *src, void *dst, uint16_t size);
|
||||
extern void ald_dma_config_auto_easy(DMA_TypeDef *DMAx, void *src, void *dst,
|
||||
uint16_t size, uint8_t channel, void (*cbk)(void *arg));
|
||||
extern void ald_dma_config_basic(dma_handle_t *hperh);
|
||||
extern void ald_dma_restart_basic(dma_handle_t *hperh, void *src, void *dst, uint16_t size);
|
||||
extern void ald_dma_config_basic_easy(DMA_TypeDef *DMAx, void *src, void *dst, uint16_t size, dma_msel_t msel,
|
||||
dma_msigsel_t msigsel, uint8_t channel, void (*cbk)(void *arg));
|
||||
extern void ald_dma_config_ping_pong(DMA_TypeDef *DMAx, dma_config_t *config,
|
||||
uint8_t first, void (*cbk)(void *arg));
|
||||
extern void ald_dma_config_sg_mem(DMA_TypeDef *DMAx, dma_descriptor_t *desc,
|
||||
uint32_t nr, uint8_t channel, void (*cbk)(void *arg));
|
||||
extern void ald_dma_config_sg_per(DMA_TypeDef *DMAx, dma_descriptor_t *desc, uint32_t nr, uint8_t burst,
|
||||
dma_msel_t msel, dma_msigsel_t msigsel, uint8_t channel, void (*cbk)(void *arg));
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup DMA_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
/* DMA control functions */
|
||||
extern void ald_dma_channel_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state);
|
||||
extern void ald_dma_interrupt_config(DMA_TypeDef *DMAx, uint8_t channel, type_func_t state);
|
||||
extern it_status_t ald_dma_get_it_status(DMA_TypeDef *DMAx, uint8_t channel);
|
||||
extern flag_status_t ald_dma_get_flag_status(DMA_TypeDef *DMAx, uint8_t channel);
|
||||
extern void ald_dma_clear_flag_status(DMA_TypeDef *DMAx, uint8_t channel);
|
||||
extern dma_descrp_cplt_t ald_dma_descriptor_cplt_get(DMA_TypeDef *DMAx, uint8_t channel);
|
||||
extern void ald_dma_irq_handler(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__ALD_DMA_H__ */
|
||||
@@ -1,602 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_ebi.h
|
||||
* @brief Header file of EBI module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 20 Nov 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 20 Nov 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_EBI_H__
|
||||
#define __ALD_EBI_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup EBI
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup EBI_Public_Macros EBI Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define EBI_NOR_SRAM_TypeDef EBI_Bank1_TypeDef
|
||||
#define EBI_NOR_SRAM_EXTENDED_TypeDef EBI_Bank1E_TypeDef
|
||||
#define EBI_NAND_TypeDef EBI_Bank2_3_TypeDef
|
||||
#define EBI_LCD_TypeDef EBI_Bank1_LCD_TypeDef
|
||||
#define EBI_NOR_SRAM_DEVICE EBI_Bank1
|
||||
#define EBI_NOR_SRAM_EXTENDED_DEVICE EBI_Bank1E
|
||||
#define EBI_NAND_DEVICE EBI_Bank2_3
|
||||
#define EBI_LCD_DEVICE EBI_Bank1_LCD
|
||||
#define EBI_NAND_BANK2 0x00000010U
|
||||
#define EBI_NAND_BANK3 0x00000100U
|
||||
|
||||
/* PCTRLR register clear mask */
|
||||
#define PCTRLR_CLEAR_MASK ((uint32_t)(EBI_PCTRLRx_WAITEN_MSK | EBI_PCTRLRx_MEMBKEN_MSK | \
|
||||
EBI_PCTRLRx_MEMTYP_MSK | EBI_PCTRLRx_DATBUSWID_MSK | \
|
||||
EBI_PCTRLRx_ECCEN_MSK | EBI_PCTRLRx_CRDLY_MSK | \
|
||||
EBI_PCTRLRx_ARDLY_MSK | EBI_PCTRLRx_ECCPSIZE_MSK))
|
||||
|
||||
/* PMEMR register clear mask */
|
||||
#define PMEMR_CLEAR_MASK ((uint32_t)(EBI_PMEMRx_MEMSETUP_MSK | EBI_PMEMRx_MEMWAIT_MSK | \
|
||||
EBI_PMEMRx_MEMHOLD_MSK | EBI_PMEMRx_MEMHIZT_MSK))
|
||||
|
||||
/* PATTR register clear mask */
|
||||
#define PATTR_CLEAR_MASK ((uint32_t)(EBI_PATTRx_ATTSETUP_MSK | EBI_PATTRx_ATTWAIT_MSK | \
|
||||
EBI_PATTRx_ATTHOLD_MSK | EBI_PATTRx_ATTHIZT_MSK))
|
||||
|
||||
/* BCTRLR register clear mask */
|
||||
#define BCTRLR_CLEAR_MASK ((uint32_t)(EBI_BCTRLRx_FLASHACCEN_MSK | EBI_BCTRLRx_MUXEN_MSK | \
|
||||
EBI_BCTRLRx_MEMTYP_MSK | EBI_BCTRLRx_MEMWID_MSK | \
|
||||
EBI_BCTRLRx_BURSTEN_MSK | EBI_BCTRLRx_WAITPOL_MSK | \
|
||||
EBI_BCTRLRx_WRAPMODE_MSK | EBI_BCTRLRx_WAITCFG_MSK | \
|
||||
EBI_BCTRLRx_WREN_MSK | EBI_BCTRLRx_WAITEN_MSK | \
|
||||
EBI_BCTRLRx_EXTMODEN_MSK | EBI_BCTRLRx_ASYNCWAIT_MSK | \
|
||||
EBI_BCTRLRx_RWCBURSTEN_MSK))
|
||||
/* BTR register clear mask */
|
||||
#define BTR_CLEAR_MASK ((uint32_t)(EBI_BTRx_ADDATASETUP_MSK | EBI_BTRx_ADDHOLD_MSK | \
|
||||
EBI_BTRx_DATAHOLD_MSK | EBI_BTRx_BUSTURN_MSK | \
|
||||
EBI_BTRx_CLKDIV_MSK | EBI_BTRx_DATALAT_MSK | \
|
||||
EBI_BTRx_ACCMODE_MSK))
|
||||
|
||||
/* BWRTR register clear mask */
|
||||
#define BWTR_CLEAR_MASK ((uint32_t)(EBI_BWRTRx_ADDATASETUP_MSK | EBI_BWRTRx_ADDHOLD_MSK | \
|
||||
EBI_BWRTRx_DATAHOLD_MSK | EBI_BWRTRx_BUSTURN_MSK | \
|
||||
EBI_BWRTRx_ACCMODE_MSK))
|
||||
|
||||
#define LCDCTRL_CLEAR_MASK ((uint32_t)(EBI_LCDCTRLx_HSYNCPOL_POS | EBI_LCDCTRLx_VSYNCPOL_MSK | \
|
||||
EBI_LCDCTRLx_DENPOL_MSK | EBI_LCDCTRLx_LCDEN_MSK | \
|
||||
EBI_LCDCTRLx_LCDINT_MSK | EBI_LCDCTRLx_DCLKPOL_MSK | \
|
||||
EBI_LCDCTRLx_DATASETUP_MSK))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup EBI_Public_Types EBI Public Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief EBI Access Mode
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_ACCESS_MODE_A = 0x0U, /**< EBI access mode A */
|
||||
EBI_ACCESS_MODE_B = (0x1U << 28), /**< EBI access mode B */
|
||||
EBI_ACCESS_MODE_C = (0x2U << 28), /**< EBI access mode C */
|
||||
EBI_ACCESS_MODE_D = (0x3U << 28), /**< EBI access mode D */
|
||||
} ebi_access_mode_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NORSRAM Timing parameters structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t addr_setup; /**< Address setup HCLK cycles number, the value between 0 and 15 */
|
||||
uint32_t addr_hold; /**< Address hold HCLK cycles number, the value between 0 and 15 */
|
||||
uint32_t data_setup; /**< Data setup HCLK cycles number, the value between 1 and 255 */
|
||||
uint32_t bus_dur; /**< Bus turnaround duration HCLK cycles, the value between 0 and 15 */
|
||||
uint32_t div; /**< Defines the period of CLK clock signal, the value between 2 and 16 */
|
||||
uint32_t latency; /**< Issue clock cycles before getting the first data, the value between 2 and 17 */
|
||||
ebi_access_mode_t mode; /**< Specifies the asynchronous access mode */
|
||||
} ald_ebi_nor_sram_timing_t;
|
||||
|
||||
/**
|
||||
* @brief EBI_Wait_feature EBI Wait feature
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_NAND_WAIT_FEATURE_DISABLE = 0x0U, /**< NAND wait feature disable */
|
||||
EBI_NAND_WAIT_FEATURE_ENABLE = (0x1U << 1), /**< NAND wait feature enable */
|
||||
} ebi_nand_wait_feature_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NAND Data Width
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_NAND_MEM_BUS_WIDTH_8 = 0x0U, /**< NAND mem bus width 8-bits */
|
||||
EBI_NAND_MEM_BUS_WIDTH_16 = (0x3U << 4), /**< NAND mem bus width 16-bits */
|
||||
} ebi_nand_mem_bus_width_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NAND ECC STATE
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_NAND_ECC_DISABLE = 0U, /**< NAND ecc disable */
|
||||
EBI_NAND_ECC_ENABLE = (0x1U << 6), /**< NAND ecc enable */
|
||||
} ebi_nand_ecc_t;
|
||||
|
||||
/**
|
||||
* @brief EBI ECC Page Size
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_NAND_ECC_PAGE_SIZE_256BYTE = 0U, /**< NAND ecc page size 256 bytes */
|
||||
EBI_NAND_ECC_PAGE_SIZE_512BYTE = (0x1U << 17), /**< NAND ecc page size 512 bytes */
|
||||
EBI_NAND_ECC_PAGE_SIZE_1024BYTE = (0x2U << 17), /**< NAND ecc page size 1024 bytes */
|
||||
EBI_NAND_ECC_PAGE_SIZE_2048BYTE = (0x3U << 17), /**< NAND ecc page size 2048 bytes */
|
||||
EBI_NAND_ECC_PAGE_SIZE_4096BYTE = (0x4U << 17), /**< NAND ecc page size 4096 bytes */
|
||||
EBI_NAND_ECC_PAGE_SIZE_8192BYTE = (0x5U << 17), /**< NAND ecc page size 8192 bytes */
|
||||
} ebi_md_ecc_page_size_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NAND Configuration Structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t bank; /**< Specifies the NAND memory device that will be used */
|
||||
ebi_nand_wait_feature_t wait; /**< Enables or disables the Wait feature for the NAND Memory device */
|
||||
ebi_nand_mem_bus_width_t width; /**< Specifies the external memory device width */
|
||||
ebi_nand_ecc_t ecc; /**< Enables or disables the ECC computation */
|
||||
ebi_md_ecc_page_size_t size; /**< Defines the page size for the extended ECC */
|
||||
uint32_t cle_time; /**< Number of HCLK cycles between CLE low and RE low, the value between 0 and 255 */
|
||||
uint32_t ale_time; /**< Number of HCLK cycles between ALE low and RE low */
|
||||
} ald_ebi_nand_init_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NAND Timing parameters structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t time; /**< Number of cycles to setup address, the value between 0 and 255 */
|
||||
uint32_t wait_time; /**< Number of HCLK cycles to assert the command ,the value between 0 and 255 */
|
||||
uint32_t hold_time; /**< Number of HCLK cycles to hold address or data, the value between 0 and 255 */
|
||||
uint32_t hiz_time; /**< Number of HCLK cycles data bus is kept in HiZ, the value between 0 and 255 */
|
||||
} ald_ebi_nand_timing_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Data Address Bus Multiplexing
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_DATA_ADDRESS_MUX_DISABLE = 0x0U, /**< Data address mux disable */
|
||||
EBI_DATA_ADDRESS_MUX_ENABLE = (0x1U << 1), /**< Data address mux enable */
|
||||
} ebi_data_address_mux_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NOR/SRAM Bank
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_NORSRAM_BANK1 = 0x0U, /**< Norsram bank 1 */
|
||||
EBI_NORSRAM_BANK2 = 0x2U, /**< Norsram bank 2 */
|
||||
EBI_NORSRAM_BANK3 = 0x4U, /**< Norsram bank 3 */
|
||||
EBI_NORSRAM_BANK4 = 0x6U, /**< Norsram bank 4 */
|
||||
} ebi_norsram_bank_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Memory Type
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_MEMORY_TYPE_SRAM = 0x0U, /**< Memory tyepe SRAM */
|
||||
EBI_MEMORY_TYPE_PSRAM = (0x1U << 2), /**< Memory tyepe PSRAM */
|
||||
EBI_MEMORY_TYPE_NOR = (0x2U << 2), /**< Memory tyepe NOR */
|
||||
} ebi_memory_type_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NOR/SRAM Data Width
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_NORSRAM_MEM_BUS_WIDTH_8 = 0x0U, /**< Norsram Memory width 8-bits */
|
||||
EBI_NORSRAM_MEM_BUS_WIDTH_16 = (0x1U << 4), /**< Norsram Memory width 16-bits */
|
||||
EBI_NORSRAM_MEM_BUS_WIDTH_32 = (0x2U << 4), /**< Norsram Memory width 32-bits */
|
||||
} ebi_norsram_mem_bus_width_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NOR/SRAM Flash Access
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_NORSRAM_FLASH_ACCESS_DISABLE = 0x0U, /**< Norsram flash access disable */
|
||||
EBI_NORSRAM_FLASH_ACCESS_ENABLE = (0x1U << 6), /**< Norsram flash access enable */
|
||||
} ebi_norsram_flash_access_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Burst Access Mode
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_BURST_ACCESS_MODE_DISABLE = 0x0U, /**< Burst access disable */
|
||||
EBI_BURST_ACCESS_MODE_ENABLE = (0x1U << 8), /**< Burst access enable */
|
||||
} ebi_burst_access_mode_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Wait Signal Polarity
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_WAIT_SIGNAL_POLARITY_LOW = 0x0U, /**< Wait signal polarity low */
|
||||
EBI_WAIT_SIGNAL_POLARITY_HIGH = (0x1U << 9), /**< Wait signal polarity high */
|
||||
} ebi_wait_signal_polarity_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Wrap Mode
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_WRAP_MODE_DISABLE = 0x0U, /**< Wrap mode disable */
|
||||
EBI_WRAP_MODE_ENABLE = (0x1U << 10), /**< Wrap mode enable */
|
||||
} ebi_wrap_mode_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Wait Timing
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_WAIT_TIMING_BEFORE_WS = 0x0U, /**< Wait timing before ws */
|
||||
EBI_WAIT_TIMING_DURING_WS = (0x1U << 11), /**< Wait timing during ws */
|
||||
} ebi_wait_timing_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Write Operation State
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_WRITE_OPERATION_DISABLE = 0x0U, /**< Write operation disable */
|
||||
EBI_WRITE_OPERATION_ENABLE = (0x1U << 12), /**< Write operation enable */
|
||||
} ebi_write_operation_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Wait Signal
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_WAIT_SIGNAL_DISABLE = 0x0U, /**< Wait signal disable */
|
||||
EBI_WAIT_SIGNAL_ENABLE = (0x1U << 13), /**< Wait signal enable */
|
||||
} ebi_wait_signal_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Extended Mode
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_EXTENDED_MODE_DISABLE = 0x0U, /**< EBI extended mode disable */
|
||||
EBI_EXTENDED_MODE_ENABLE = (0x1U << 14), /**< EBI extended mode enable */
|
||||
} ebi_extended_mode_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Asynchronous Wait
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_ASYNCHRONOUS_WAIT_DISABLE = 0x0U, /**< Asynchronous wait disable */
|
||||
EBI_ASYNCHRONOUS_WAIT_ENABLE = (0x1U << 15), /**< Asynchronous wait enable */
|
||||
} ebi_asynchronous_wait_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Write Burst
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_WRITE_BURST_DISABLE = 0x0U, /**< Write burst disable */
|
||||
EBI_WRITE_BURST_ENABLE = (0x1U << 19), /**< Write burst enable */
|
||||
} ebi_write_burst_t;
|
||||
|
||||
/**
|
||||
* @brief EBI PCR Memory Type
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_PCTRLR_MEMORY_TYPE_None = 0x0U, /**< PCR memory type none */
|
||||
EBI_PCTRLR_MEMORY_TYPE_NAND = (0x1U << 3), /**< PCR memory type nand */
|
||||
} ebi_pctrlr_memory_type_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Interrupt definition
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_IT_RISING_EDGE = (1U << 3), /**< Rising edge trigger interrupt */
|
||||
EBI_IT_LEVEL = (1U << 4), /**< Level trigger interrupt */
|
||||
EBI_IT_FALLING_EDGE = (1U << 5), /**< Falling edge trigger interrupt */
|
||||
} ebi_it_t;
|
||||
|
||||
/**
|
||||
* @brief EBI Flag definition
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_FLAG_RISING_EDGE = (1U << 0), /**< Rising edge flag */
|
||||
EBI_FLAG_LEVEL = (1U << 1), /**< Level flag */
|
||||
EBI_FLAG_FALLING_EDGE = (1U << 2), /**< Falling edge flag */
|
||||
EBI_FLAG_FEMPT = (1U << 6), /**< Rising edge trigger interrupt */
|
||||
} ebi_flag_t;
|
||||
|
||||
/**
|
||||
* @brief EBI LCD_Horizontal Synch Polarity definition
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_LCD_HSYNCPOL_LOW = 0x0U, /**< Horizontal synch polarity low */
|
||||
EBI_LCD_HSYNCPOL_HIGH = (0x1U << 29), /**< Horizontal synch polarity high */
|
||||
} ebi_lcd_hsyncpol_t;
|
||||
|
||||
/**
|
||||
* @brief EBI LCD Vertical Synch Polarity definition
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_LCD_VSYNCPOL_LOW = 0x0U, /**< Vertical synch polarity low */
|
||||
EBI_LCD_VSYNCPOL_HIGH = (0x1U << 28), /**< Vertical synch polarity high */
|
||||
} ebi_lcd_vsyncpol_t;
|
||||
|
||||
/**
|
||||
* @brief EBI LCD Data Enable Polarity definition
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_LCD_DENPOL_LOW = 0x0U, /**< LCD data enable polarity low */
|
||||
EBI_LCD_DENPOL_HIGH = (0x1U << 27), /**< LCD data enable polarity high */
|
||||
} ebi_lcd_denpol_t;
|
||||
|
||||
/**
|
||||
* @brief EBI LCD Enable definition
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_LCD_LCDEN_DISABLE = 0x0U, /**< LCD disable */
|
||||
EBI_LCD_LCDEN_ENABLE = (0x1U << 26), /**< LCD data enable polarity low */
|
||||
} ebi_lcd_lcden_t;
|
||||
|
||||
/**
|
||||
* @brief EBI LCD Init Enable definition
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_LCD_LCDINT_DISABLE = 0x0U, /**< LCD init disable */
|
||||
EBI_LCD_LCDINT_ENABLE = (0x1 << 25), /**< LCD init enable */
|
||||
} ebi_lcd_lcdint_t;
|
||||
|
||||
/**
|
||||
* @brief EBI LCD Data Clock definition
|
||||
*/
|
||||
typedef enum {
|
||||
EBI_LCD_DCLKPOL_FALLING = 0x0U, /**< LCD data clock falling edge */
|
||||
EBI_LCD_DCLKPOL_RISING = (0x1U << 24), /**< LCD data clock rising edge */
|
||||
} ebi_lcd_dclkpol_t;
|
||||
|
||||
/**
|
||||
* @brief EBI LCD parameters structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t bank; /**< Specifies the NORSRAM memory device */
|
||||
ebi_lcd_hsyncpol_t h_polarity; /**< Horizontal sync polarity */
|
||||
ebi_lcd_vsyncpol_t v_polarity; /**< Vertical sync polarity */
|
||||
ebi_lcd_denpol_t data_polarity; /**< Data enable polarity */
|
||||
ebi_lcd_lcden_t enable; /**< LCD enable */
|
||||
ebi_lcd_dclkpol_t clk_polarity; /**< Data clock polarity */
|
||||
ebi_lcd_lcdint_t reset; /**< LCD Reset */
|
||||
uint8_t setup; /**< Data setup time */
|
||||
uint8_t v_width; /**< Vsync pulse width */
|
||||
uint8_t h_width; /**< Hsync puluse width */
|
||||
uint16_t nr_line; /**< Frame line number */
|
||||
uint16_t nr_pixel; /**< Frame pixel number */
|
||||
} ebi_lcd_init_t;
|
||||
|
||||
/**
|
||||
* @brief NOR LCD handle Structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
EBI_LCD_TypeDef *inst;
|
||||
ebi_lcd_init_t init;
|
||||
} ebi_lcd_handle_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NORSRAM Configuration Structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t bank; /**< Specifies the NORSRAM memory device, the value can be one of 0 ~ 3 */
|
||||
ebi_data_address_mux_t mux; /**< Address and data values are multiplexed or not */
|
||||
ebi_memory_type_t type; /**< Specifies the type of external memory */
|
||||
ebi_norsram_mem_bus_width_t width; /**< Specifies the external memory device width */
|
||||
ebi_burst_access_mode_t acc_mode; /**< Enables or disables the burst access mode for Flash memory */
|
||||
ebi_wait_signal_polarity_t polarity; /**< Wait signal polarity, valid only in burst mode */
|
||||
ebi_wrap_mode_t wrap_mode; /**< Enables or disables the Wrapped burst access mode, only in burst mode */
|
||||
ebi_wait_timing_t active; /**< Specifies if the wait signal is asserted, only in burst mode */
|
||||
ebi_write_operation_t write; /**< Enables or disables the write operation */
|
||||
ebi_wait_signal_t signal; /**< Enables or disables the wait state insertion, only in burst mode */
|
||||
ebi_extended_mode_t ext_mode; /**< Enables or disables the extended mode */
|
||||
ebi_asynchronous_wait_t wait; /**< Enables or disables wait signal during asynchronous transfers */
|
||||
ebi_write_burst_t burst; /**< Enables or disables the write burst operation */
|
||||
} ald_ebi_nor_sram_init_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup EBI_Private_Macros EBI Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_EBI_NORSRAM_BANK(x) (((x) == EBI_NORSRAM_BANK1) || \
|
||||
((x) == EBI_NORSRAM_BANK2) || \
|
||||
((x) == EBI_NORSRAM_BANK3) || \
|
||||
((x) == EBI_NORSRAM_BANK4))
|
||||
#define IS_EBI_MUX(x) (((x) == EBI_DATA_ADDRESS_MUX_DISABLE) || \
|
||||
((x) == EBI_DATA_ADDRESS_MUX_ENABLE))
|
||||
#define IS_EBI_MEMORY(x) (((x) == EBI_MEMORY_TYPE_SRAM) || \
|
||||
((x) == EBI_MEMORY_TYPE_PSRAM) || \
|
||||
((x) == EBI_MEMORY_TYPE_NOR))
|
||||
#define IS_EBI_NORSRAM_MEMORY_WIDTH(x) (((x) == EBI_NORSRAM_MEM_BUS_WIDTH_8) || \
|
||||
((x) == EBI_NORSRAM_MEM_BUS_WIDTH_16) || \
|
||||
((x) == EBI_NORSRAM_MEM_BUS_WIDTH_32))
|
||||
#define IS_EBI_WRITE_BURST(x) (((x) == EBI_WRITE_BURST_DISABLE) || \
|
||||
((x) == EBI_WRITE_BURST_ENABLE))
|
||||
#define IS_EBI_ACCESS_MODE(x) (((x) == EBI_ACCESS_MODE_A) || \
|
||||
((x) == EBI_ACCESS_MODE_B) || \
|
||||
((x) == EBI_ACCESS_MODE_C) || \
|
||||
((x) == EBI_ACCESS_MODE_D))
|
||||
#define IS_EBI_NAND_BANK(x) (((x) == EBI_NAND_BANK2) || \
|
||||
((x) == EBI_NAND_BANK3))
|
||||
#define IS_EBI_WAIT_FEATURE(x) (((x) == EBI_NAND_WAIT_FEATURE_DISABLE) || \
|
||||
((x) == EBI_NAND_WAIT_FEATURE_ENABLE))
|
||||
#define IS_EBI_NAND_MEMORY_WIDTH(x) (((x) == EBI_NAND_MEM_BUS_WIDTH_8) || \
|
||||
((x) == EBI_NAND_MEM_BUS_WIDTH_16))
|
||||
#define IS_EBI_ECC_STATE(x) (((x) == EBI_NAND_ECC_DISABLE) || \
|
||||
((x) == EBI_NAND_ECC_ENABLE))
|
||||
#define IS_EBI_ECCPAGE_SIZE(x) (((x) == EBI_NAND_ECC_PAGE_SIZE_256BYTE) || \
|
||||
((x) == EBI_NAND_ECC_PAGE_SIZE_512BYTE) || \
|
||||
((x) == EBI_NAND_ECC_PAGE_SIZE_1024BYTE) || \
|
||||
((x) == EBI_NAND_ECC_PAGE_SIZE_2048BYTE) || \
|
||||
((x) == EBI_NAND_ECC_PAGE_SIZE_4096BYTE) || \
|
||||
((x) == EBI_NAND_ECC_PAGE_SIZE_8192BYTE))
|
||||
#define IS_EBI_LCD_DEVICE(x) ((x) == EBI_LCD_DEVICE)
|
||||
#define IS_EBI_HORIZONTAL_SYNCH(x) (((x) == EBI_LCD_HSYNCPOL_LOW) || \
|
||||
((x) == EBI_LCD_HSYNCPOL_HIGH))
|
||||
#define IS_EBI_VERTICAL_SYNCH(x) (((x) == EBI_LCD_VSYNCPOL_LOW) || \
|
||||
((x) == EBI_LCD_VSYNCPOL_HIGH))
|
||||
#define IS_EBI_DATA_ENABLE(x) (((x) == EBI_LCD_DENPOL_LOW) || \
|
||||
((x) == EBI_LCD_DENPOL_HIGH))
|
||||
#define IS_EBI_LCD_ENABLE(x) (((x) == EBI_LCD_LCDEN_DISABLE) || \
|
||||
((x) == EBI_LCD_LCDEN_ENABLE))
|
||||
#define IS_EBI_LCD_RESET(x) (((x) == EBI_LCD_LCDINT_DISABLE) || \
|
||||
((x) == EBI_LCD_LCDINT_ENABLE))
|
||||
#define IS_EBI_DATA_CLOCK(x) (((x) == EBI_LCD_DCLKPOL_FALLING) || \
|
||||
((x) == EBI_LCD_DCLKPOL_RISING))
|
||||
#define IS_EBI_LCD_DATASETUP_TIME(x) ((x) < 255U)
|
||||
#define IS_EBI_HYSNC_PULSE_WIDTH(x) ((x) < 255U)
|
||||
#define IS_EBI_VSYNC_PULSE_WIDTH(x) ((x) < 255U)
|
||||
#define IS_EBI_FRAME_LINE_NUMBER(x) (((x) >= 1U) && ((x) < 65535))
|
||||
#define IS_EBI_FRAME_PIXEL_NUMBER(x) (((x) >= 1U) && ((x) < 65535))
|
||||
|
||||
#define IS_EBI_TCLR_TIME(x) ((x) <= 255U)
|
||||
#define IS_EBI_TAR_TIME(x) ((x) <= 255U)
|
||||
#define IS_EBI_SETUP_TIME(x) ((x) <= 255U)
|
||||
#define IS_EBI_WAIT_TIME(x) ((x) <= 255U)
|
||||
#define IS_EBI_HOLD_TIME(x) ((x) <= 255U)
|
||||
#define IS_EBI_HIZ_TIME(x) ((x) <= 255U)
|
||||
#define IS_EBI_NORSRAM_DEVICE(x) ((x) == EBI_NOR_SRAM_DEVICE)
|
||||
#define IS_EBI_NORSRAM_EXTENDED_DEVICE(x) ((x) == EBI_NOR_SRAM_EXTENDED_DEVICE)
|
||||
#define IS_EBI_NAND_DEVICE(x) ((x) == EBI_NAND_DEVICE)
|
||||
#define IS_EBI_BURSTMODE(x) (((x) == EBI_BURST_ACCESS_MODE_DISABLE) || \
|
||||
((x) == EBI_BURST_ACCESS_MODE_ENABLE))
|
||||
#define IS_EBI_WAIT_POLARITY(x) (((x) == EBI_WAIT_SIGNAL_POLARITY_LOW) || \
|
||||
((x) == EBI_WAIT_SIGNAL_POLARITY_HIGH))
|
||||
#define IS_EBI_WRAP_MODE(x) (((x) == EBI_WRAP_MODE_DISABLE) || \
|
||||
((x) == EBI_WRAP_MODE_ENABLE))
|
||||
#define IS_EBI_WAIT_SIGNAL_ACTIVE(x) (((x) == EBI_WAIT_TIMING_BEFORE_WS) || \
|
||||
((x) == EBI_WAIT_TIMING_DURING_WS))
|
||||
#define IS_EBI_WRITE_OPERATION(x) (((x) == EBI_WRITE_OPERATION_DISABLE) || \
|
||||
((x) == EBI_WRITE_OPERATION_ENABLE))
|
||||
#define IS_EBI_WAITE_SIGNAL(x) (((x) == EBI_WAIT_SIGNAL_DISABLE) || \
|
||||
((x) == EBI_WAIT_SIGNAL_ENABLE))
|
||||
#define IS_EBI_EXTENDED_MODE(x) (((x) == EBI_EXTENDED_MODE_DISABLE) || \
|
||||
((x) == EBI_EXTENDED_MODE_ENABLE))
|
||||
#define IS_EBI_ASYNWAIT(x) (((x) == EBI_ASYNCHRONOUS_WAIT_DISABLE) || \
|
||||
((x) == EBI_ASYNCHRONOUS_WAIT_ENABLE))
|
||||
#define IS_EBI_CLK_DIV(x) (((x) >= 1U) && ((x) <= 16U))
|
||||
#define IS_EBI_DATA_LATENCY(x) (((x) >= 1U) && ((x) <= 17U))
|
||||
#define IS_EBI_ADDRESS_SETUP_TIME(x) ((x) <= 15U)
|
||||
#define IS_EBI_ADDRESS_HOLD_TIME(x) (((x) > 0U) && ((x) <= 15U))
|
||||
#define IS_EBI_DATASETUP_TIME(x) (((x) > 0U) && ((x) <= 255U))
|
||||
#define IS_EBI_TURNAROUND_TIME(x) ((x) <= 15U)
|
||||
#define IS_EBI_BANK_NUMBER(x) (((x) > 0U) && ((x) <= 4U))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup EBI_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup EBI_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
/* NOR-FLASH SRAM initialize functions */
|
||||
void ald_ebi_nor_sram_init(EBI_NOR_SRAM_TypeDef *dev, ald_ebi_nor_sram_init_t *init);
|
||||
void ald_ebi_nor_sram_timing_init(EBI_NOR_SRAM_TypeDef *dev, ald_ebi_nor_sram_timing_t *timing, uint32_t bank);
|
||||
void ald_ebi_nor_sram_ext_timing_init(EBI_NOR_SRAM_EXTENDED_TypeDef *dev, ald_ebi_nor_sram_timing_t *timing, uint32_t bank, uint32_t mode);
|
||||
ald_status_t ald_ebi_nor_sram_deinit(EBI_NOR_SRAM_TypeDef *dev, EBI_NOR_SRAM_EXTENDED_TypeDef *e_dev, uint32_t bank);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup EBI_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
/* NOR/SRAM Control functions */
|
||||
void ald_ebi_nor_sram_enable(EBI_NOR_SRAM_TypeDef *dev, uint32_t bank);
|
||||
void ald_ebi_nor_sram_disable(EBI_NOR_SRAM_TypeDef *dev, uint32_t bank);
|
||||
void ald_ebi_nor_sram_write_enable(EBI_NOR_SRAM_TypeDef *dev, uint32_t bank);
|
||||
void ald_ebi_nor_sram_write_disable(EBI_NOR_SRAM_TypeDef *dev, uint32_t bank);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup EBI_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
/* NAND-FLASH initialize functions */
|
||||
void ald_ebi_nand_init(EBI_NAND_TypeDef *dev, ald_ebi_nand_init_t *init);
|
||||
void ald_ebi_nand_comm_timing_init(EBI_NAND_TypeDef *dev, ald_ebi_nand_timing_t *timing, uint32_t bank);
|
||||
void ald_ebi_nand_attr_timing_init(EBI_NAND_TypeDef *dev, ald_ebi_nand_timing_t *timing, uint32_t bank);
|
||||
void ald_ebi_nand_deinit(EBI_NAND_TypeDef *dev, uint32_t bank);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup EBI_Public_Functions_Group4
|
||||
* @{
|
||||
*/
|
||||
/* NAND-FLASH control functions */
|
||||
void ald_ebi_nand_enable(EBI_NAND_TypeDef *dev, uint32_t bank);
|
||||
void ald_ebi_nand_disable(EBI_NAND_TypeDef *dev, uint32_t bank);
|
||||
void ald_ebi_nand_enable_it(EBI_NAND_TypeDef *dev, uint32_t bank, ebi_it_t it);
|
||||
void ald_ebi_nand_disable_it(EBI_NAND_TypeDef *dev, uint32_t bank, ebi_it_t it);
|
||||
void ald_ebi_nand_ecc_enable(EBI_NAND_TypeDef *dev, uint32_t bank);
|
||||
void ald_ebi_nand_ecc_disable(EBI_NAND_TypeDef *dev, uint32_t bank);
|
||||
ald_status_t ald_ebi_nand_get_ecc(EBI_NAND_TypeDef *dev, uint32_t *val, uint32_t bank, uint32_t timeout);
|
||||
flag_status_t ald_ebi_nand_get_flag(EBI_NAND_TypeDef *dev, uint32_t bank, ebi_flag_t flag);
|
||||
void ald_ebi_nand_clear_flag(EBI_NAND_TypeDef *dev, uint32_t bank, ebi_flag_t flag);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup EBI_Public_Functions_Group5
|
||||
* @{
|
||||
*/
|
||||
void ald_ebi_lcd_init(ebi_lcd_handle_t *hlcd);
|
||||
void ald_ebi_lcd_reset(ebi_lcd_handle_t *hlcd);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_EBI_H__ */
|
||||
@@ -1,146 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_flash.h
|
||||
* @brief Header file of FLASH driver
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 17 Jun 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 17 Jun 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_FLASH_H__
|
||||
#define __ALD_FLASH_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup FLASH
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup FLASH_Private_Macros FLASH Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define FLASH_REG_UNLOCK() \
|
||||
do { \
|
||||
if (op_cmd == OP_FLASH) { \
|
||||
WRITE_REG(MSC->FLASHKEY, 0x8ACE0246); \
|
||||
WRITE_REG(MSC->FLASHKEY, 0x9BDF1357); \
|
||||
} \
|
||||
else { \
|
||||
WRITE_REG(MSC->INFOKEY, 0x7153BFD9); \
|
||||
WRITE_REG(MSC->INFOKEY, 0x0642CEA8); \
|
||||
} \
|
||||
} while (0)
|
||||
#define FLASH_REQ() (SET_BIT(MSC->FLASHCR, MSC_FLASHCR_FLASHREQ_MSK))
|
||||
#define FLASH_REQ_FIN() (CLEAR_BIT(MSC->FLASHCR, MSC_FLASHCR_FLASHREQ_MSK))
|
||||
#define FLASH_IAP_ENABLE() (SET_BIT(MSC->FLASHCR, MSC_FLASHCR_IAPEN_MSK))
|
||||
#define FLASH_IAP_DISABLE() (CLEAR_BIT(MSC->FLASHCR, MSC_FLASHCR_IAPEN_MSK))
|
||||
#define FLASH_BASE_ADDR 0x00000000
|
||||
#define FLASH_PAGE_SIZE 1024UL
|
||||
#define FLASH_WORD_SIZE 8UL
|
||||
#define FLASH_TOTAL_SIZE 512UL
|
||||
#define FLASH_PAGE_MASK (FLASH_PAGE_SIZE - 1)
|
||||
#define FLASH_WORD_MASK (FLASH_WORD_SIZE - 1)
|
||||
#define IS_FLASH_ADDRESS(ADDR) ((ADDR) < (FLASH_BASE_ADDR + FLASH_PAGE_SIZE * FLASH_TOTAL_SIZE))
|
||||
#define IS_4BYTES_ALIGN(ADDR) (((uint32_t)(ADDR) & 0x3) == 0 ? 1 : 0)
|
||||
#define FLASH_PAGE_ADDR(ADDR) ((ADDR) & (~FLASH_PAGE_MASK))
|
||||
#define FLASH_PAGEEND_ADDR(ADDR) ((ADDR) | FLASH_PAGE_MASK)
|
||||
#define FLASH_WORD_ADDR(ADDR) ((ADDR) & (~FLASH_WORD_MASK))
|
||||
#define FLASH_WORDEND_ADDR(ADDR) ((ADDR) | FLASH_WORD_MASK)
|
||||
#define INFO_PAGE_SIZE 1024UL
|
||||
#define INFO_PAGE_MASK (INFO_PAGE_SIZE - 1)
|
||||
#define INFO_PAGE_ADDR(ADDR) ((ADDR) & (~INFO_PAGE_MASK))
|
||||
|
||||
#ifdef USE_FLASH_FIFO
|
||||
#define FLASH_FIFO 1
|
||||
#else
|
||||
#define FLASH_FIFO 0
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup FLASH_Private_Types FLASH Private Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum {
|
||||
FLASH_CMD_AE = 0x000051AEU, /**< Program area erase all */
|
||||
FLASH_CMD_PE = 0x00005EA1U, /**< Page erase */
|
||||
FLASH_CMD_WP = 0x00005DA2U, /**< Word program */
|
||||
FLASH_CMD_WP_FAST = 0x00005CA3U, /**< Flash quickly program */
|
||||
FLASH_CMD_DATAPE = 0x00005BA4U, /**< Data flash page page erase */
|
||||
FLASH_CMD_DATAWP = 0x00005AA5U, /**< Data flash word program */
|
||||
FLASH_CMD_DATAWP_FAST = 0x000059A6U, /**< Data flash quickly program */
|
||||
FLASH_CMD_NP_AE = 0x000050AFU, /**< No-private area erase all */
|
||||
} flash_cmd_type;
|
||||
|
||||
typedef enum {
|
||||
OP_FLASH = 0U, /**< Operate Pragram area */
|
||||
OP_INFO = 1U, /**< Operate info area */
|
||||
} op_cmd_type;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup Flash_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
ald_status_t flash_page_erase(uint32_t addr);
|
||||
ald_status_t flash_word_program(uint32_t addr, uint32_t *data, uint32_t len, uint32_t fifo);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Flash_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_flash_read(uint32_t *ram_addr, uint32_t addr, uint16_t len);
|
||||
ald_status_t ald_flash_write(uint32_t addr, uint8_t *buf, uint16_t len);
|
||||
ald_status_t ald_flash_erase(uint32_t addr, uint16_t len);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_FLASH_H__ */
|
||||
@@ -1,339 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_gpio.h
|
||||
* @brief Header file of GPIO module driver
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 07 Nov 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 07 Nov 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_GPIO_H__
|
||||
#define __ALD_GPIO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup GPIO_Public_Macros GPIO Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define GPIO_PIN_0 (0x1U)
|
||||
#define GPIO_PIN_1 (0x2U)
|
||||
#define GPIO_PIN_2 (0x4U)
|
||||
#define GPIO_PIN_3 (0x8U)
|
||||
#define GPIO_PIN_4 (0x10U)
|
||||
#define GPIO_PIN_5 (0x20U)
|
||||
#define GPIO_PIN_6 (0x40U)
|
||||
#define GPIO_PIN_7 (0x80U)
|
||||
#define GPIO_PIN_8 (0x100U)
|
||||
#define GPIO_PIN_9 (0x200U)
|
||||
#define GPIO_PIN_10 (0x400U)
|
||||
#define GPIO_PIN_11 (0x800U)
|
||||
#define GPIO_PIN_12 (0x1000U)
|
||||
#define GPIO_PIN_13 (0x2000U)
|
||||
#define GPIO_PIN_14 (0x4000U)
|
||||
#define GPIO_PIN_15 (0x8000U)
|
||||
#define GPIO_PIN_ALL (0xFFFF)
|
||||
|
||||
/* Toggle IO */
|
||||
#define ALD_GPIOA_TOGGLE_PIN(x) (GPIOA->BIR = (x))
|
||||
#define ALD_GPIOB_TOGGLE_PIN(x) (GPIOB->BIR = (x))
|
||||
#define ALD_GPIOC_TOGGLE_PIN(x) (GPIOC->BIR = (x))
|
||||
#define ALD_GPIOD_TOGGLE_PIN(x) (GPIOD->BIR = (x))
|
||||
#define ALD_GPIOE_TOGGLE_PIN(x) (GPIOE->BIR = (x))
|
||||
#define ALD_GPIOF_TOGGLE_PIN(x) (GPIOF->BIR = (x))
|
||||
#define ALD_GPIOG_TOGGLE_PIN(x) (GPIOG->BIR = (x))
|
||||
#define ALD_GPIOH_TOGGLE_PIN(x) (GPIOH->BIR = (x))
|
||||
|
||||
/* Read IO level */
|
||||
#define ALD_GPIOA_READ_PIN(x) ((GPIOA->DIN & (x)) ? 1 : 0)
|
||||
#define ALD_GPIOB_READ_PIN(x) ((GPIOB->DIN & (x)) ? 1 : 0)
|
||||
#define ALD_GPIOC_READ_PIN(x) ((GPIOC->DIN & (x)) ? 1 : 0)
|
||||
#define ALD_GPIOD_READ_PIN(x) ((GPIOD->DIN & (x)) ? 1 : 0)
|
||||
#define ALD_GPIOE_READ_PIN(x) ((GPIOE->DIN & (x)) ? 1 : 0)
|
||||
#define ALD_GPIOF_READ_PIN(x) ((GPIOF->DIN & (x)) ? 1 : 0)
|
||||
#define ALD_GPIOG_READ_PIN(x) ((GPIOG->DIN & (x)) ? 1 : 0)
|
||||
#define ALD_GPIOH_READ_PIN(x) ((GPIOH->DIN & (x)) ? 1 : 0)
|
||||
|
||||
/* Set IO as high */
|
||||
#define ALD_GPIOA_SET_PIN(x) (GPIOA->BSRR = (x))
|
||||
#define ALD_GPIOB_SET_PIN(x) (GPIOB->BSRR = (x))
|
||||
#define ALD_GPIOC_SET_PIN(x) (GPIOC->BSRR = (x))
|
||||
#define ALD_GPIOD_SET_PIN(x) (GPIOD->BSRR = (x))
|
||||
#define ALD_GPIOE_SET_PIN(x) (GPIOE->BSRR = (x))
|
||||
#define ALD_GPIOF_SET_PIN(x) (GPIOF->BSRR = (x))
|
||||
#define ALD_GPIOG_SET_PIN(x) (GPIOG->BSRR = (x))
|
||||
#define ALD_GPIOH_SET_PIN(x) (GPIOH->BSRR = (x))
|
||||
|
||||
/* Set IO as low */
|
||||
#define ALD_GPIOA_RESET_PIN(x) (GPIOA->BSRR = ((x) << 16))
|
||||
#define ALD_GPIOB_RESET_PIN(x) (GPIOB->BSRR = ((x) << 16))
|
||||
#define ALD_GPIOC_RESET_PIN(x) (GPIOC->BSRR = ((x) << 16))
|
||||
#define ALD_GPIOD_RESET_PIN(x) (GPIOD->BSRR = ((x) << 16))
|
||||
#define ALD_GPIOE_RESET_PIN(x) (GPIOE->BSRR = ((x) << 16))
|
||||
#define ALD_GPIOF_RESET_PIN(x) (GPIOF->BSRR = ((x) << 16))
|
||||
#define ALD_GPIOG_RESET_PIN(x) (GPIOG->BSRR = ((x) << 16))
|
||||
#define ALD_GPIOH_RESET_PIN(x) (GPIOH->BSRR = ((x) << 16))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup GPIO_Public_Types GPIO Public Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief GPIO mode
|
||||
*/
|
||||
typedef enum {
|
||||
GPIO_MODE_CLOSE = 0x0U, /**< Digital close Analog open */
|
||||
GPIO_MODE_INPUT = 0x1U, /**< Input */
|
||||
GPIO_MODE_OUTPUT = 0x2U, /**< Output */
|
||||
} gpio_mode_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO open-drain or push-pull
|
||||
*/
|
||||
typedef enum {
|
||||
GPIO_PUSH_PULL = 0x0U, /**< Push-Pull */
|
||||
GPIO_OPEN_DRAIN = 0x2U, /**< Open-Drain. Can't output high level */
|
||||
GPIO_OPEN_SOURCE = 0x3U, /**< Open-Source. Can't output low level */
|
||||
} gpio_odos_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO push-up or push-down
|
||||
*/
|
||||
typedef enum {
|
||||
GPIO_FLOATING = 0x0U, /**< Floating */
|
||||
GPIO_PUSH_UP = 0x1U, /**< Push-Up */
|
||||
GPIO_PUSH_DOWN = 0x2U, /**< Push-Down */
|
||||
GPIO_PUSH_UP_DOWN = 0x3U, /**< Push-Up and Push-Down */
|
||||
} gpio_push_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO output drive
|
||||
*/
|
||||
typedef enum {
|
||||
GPIO_OUT_DRIVE_0_1 = 0x0U, /**< 0.1mA */
|
||||
GPIO_OUT_DRIVE_1 = 0x1U, /**< 1mA */
|
||||
GPIO_OUT_DRIVE_6 = 0x2U, /**< 6mA */
|
||||
GPIO_OUT_DRIVE_20 = 0x3U, /**< 20mA */
|
||||
} gpio_out_drive_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO filter
|
||||
*/
|
||||
typedef enum {
|
||||
GPIO_FILTER_DISABLE = 0x0U, /**< Disable filter */
|
||||
GPIO_FILTER_ENABLE = 0x1U, /**< Enable filter */
|
||||
} gpio_filter_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO type
|
||||
*/
|
||||
typedef enum {
|
||||
GPIO_TYPE_CMOS = 0x0U, /**< CMOS Type */
|
||||
GPIO_TYPE_TTL = 0x1U, /**< TTL Type */
|
||||
} gpio_type_t;
|
||||
|
||||
/**
|
||||
* @brief GPIO functions
|
||||
*/
|
||||
typedef enum {
|
||||
GPIO_FUNC_0 = 0U, /**< function #0 */
|
||||
GPIO_FUNC_1 = 1U, /**< function #1 */
|
||||
GPIO_FUNC_2 = 2U, /**< function #2 */
|
||||
GPIO_FUNC_3 = 3U, /**< function #3 */
|
||||
GPIO_FUNC_4 = 4U, /**< function #4 */
|
||||
GPIO_FUNC_5 = 5U, /**< function #5 */
|
||||
GPIO_FUNC_6 = 6U, /**< function #6 */
|
||||
GPIO_FUNC_7 = 7U, /**< function #7 */
|
||||
} gpio_func_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief GPIO Init Structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
gpio_mode_t mode; /**< Specifies the operating mode for the selected pins.
|
||||
This parameter can be any value of @ref gpio_mode_t */
|
||||
gpio_odos_t odos; /**< Specifies the Open-Drain or Push-Pull for the selected pins.
|
||||
This parameter can be a value of @ref gpio_odos_t */
|
||||
gpio_push_t pupd; /**< Specifies the Pull-up or Pull-Down for the selected pins.
|
||||
This parameter can be a value of @ref gpio_push_t */
|
||||
gpio_out_drive_t podrv; /**< Specifies the output P-MOS driver for the selected pins.
|
||||
This parameter can be a value of @ref gpio_out_drive_t */
|
||||
gpio_out_drive_t nodrv; /**< Specifies the output N-MOS driver for the selected pins.
|
||||
This parameter can be a value of @ref gpio_out_drive_t */
|
||||
gpio_filter_t flt; /**< Specifies the input filter for the selected pins.
|
||||
This parameter can be a value of @ref gpio_filter_t */
|
||||
gpio_type_t type; /**< Specifies the type for the selected pins.
|
||||
This parameter can be a value of @ref gpio_type_t */
|
||||
gpio_func_t func; /**< Specifies the function for the selected pins.
|
||||
This parameter can be a value of @ref gpio_func_t */
|
||||
} gpio_init_t;
|
||||
|
||||
/**
|
||||
* @brief EXTI trigger style
|
||||
*/
|
||||
typedef enum {
|
||||
EXTI_TRIGGER_RISING_EDGE = 0U, /**< Rising edge trigger */
|
||||
EXTI_TRIGGER_TRAILING_EDGE = 1U, /**< Trailing edge trigger */
|
||||
EXTI_TRIGGER_BOTH_EDGE = 2U, /**< Rising and trailing edge trigger */
|
||||
} exti_trigger_style_t;
|
||||
|
||||
/**
|
||||
* @brief EXTI filter clock select
|
||||
*/
|
||||
typedef enum {
|
||||
EXTI_FILTER_CLOCK_10K = 0U, /**< cks = 10KHz */
|
||||
EXTI_FILTER_CLOCK_32K = 1U, /**< cks = 32KHz */
|
||||
} exti_filter_clock_t;
|
||||
|
||||
/**
|
||||
* @brief EXTI Init Structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
type_func_t filter; /**< Enable filter. */
|
||||
exti_filter_clock_t cks; /**< Filter clock select. */
|
||||
uint8_t filter_time; /**< Filter duration */
|
||||
} exti_init_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup GPIO_Private_Macros GPIO Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define PIN_MASK 0xFFFFU
|
||||
#define UNLOCK_KEY 0x55AAU
|
||||
|
||||
#define IS_GPIO_PIN(x) ((((x) & (uint16_t)0x00) == 0) && ((x) != (uint16_t)0x0))
|
||||
#define IS_GPIO_PORT(GPIOx) ((GPIOx == GPIOA) || \
|
||||
(GPIOx == GPIOB) || \
|
||||
(GPIOx == GPIOC) || \
|
||||
(GPIOx == GPIOD) || \
|
||||
(GPIOx == GPIOE) || \
|
||||
(GPIOx == GPIOF) || \
|
||||
(GPIOx == GPIOG) || \
|
||||
(GPIOx == GPIOH))
|
||||
#define IS_GPIO_MODE(x) (((x) == GPIO_MODE_CLOSE) || \
|
||||
((x) == GPIO_MODE_INPUT) || \
|
||||
((x) == GPIO_MODE_OUTPUT))
|
||||
#define IS_GPIO_ODOS(x) (((x) == GPIO_PUSH_PULL) || \
|
||||
((x) == GPIO_OPEN_DRAIN) || \
|
||||
((x) == GPIO_OPEN_SOURCE))
|
||||
#define IS_GPIO_PUPD(x) (((x) == GPIO_FLOATING) || \
|
||||
((x) == GPIO_PUSH_UP) || \
|
||||
((x) == GPIO_PUSH_DOWN) || \
|
||||
((x) == GPIO_PUSH_UP_DOWN))
|
||||
#define IS_GPIO_ODRV(x) (((x) == GPIO_OUT_DRIVE_0_1) || \
|
||||
((x) == GPIO_OUT_DRIVE_1) || \
|
||||
((x) == GPIO_OUT_DRIVE_6) || \
|
||||
((x) == GPIO_OUT_DRIVE_20))
|
||||
#define IS_GPIO_FLT(x) (((x) == GPIO_FILTER_DISABLE) || \
|
||||
((x) == GPIO_FILTER_ENABLE))
|
||||
#define IS_GPIO_TYPE(x) (((x) == GPIO_TYPE_TTL) || \
|
||||
((x) == GPIO_TYPE_CMOS))
|
||||
#define IS_TRIGGER_STYLE(x) (((x) == EXTI_TRIGGER_RISING_EDGE) || \
|
||||
((x) == EXTI_TRIGGER_TRAILING_EDGE) || \
|
||||
((x) == EXTI_TRIGGER_BOTH_EDGE))
|
||||
#define IS_EXTI_FLTCKS_TYPE(x) (((x) == EXTI_FILTER_CLOCK_10K) || \
|
||||
((x) == EXTI_FILTER_CLOCK_32K))
|
||||
#define IS_GPIO_FUNC(x) ((x) <= 7)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
void ald_gpio_init(GPIO_TypeDef *GPIOx, uint16_t pin, gpio_init_t *init);
|
||||
void ald_gpio_init_default(GPIO_TypeDef *GPIOx, uint16_t pin);
|
||||
void ald_gpio_func_default(GPIO_TypeDef *GPIOx);
|
||||
void ald_gpio_exti_init(GPIO_TypeDef *GPIOx, uint16_t pin, exti_init_t *init);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
uint8_t ald_gpio_read_pin(GPIO_TypeDef *GPIOx, uint16_t pin);
|
||||
void ald_gpio_write_pin(GPIO_TypeDef *GPIOx, uint16_t pin, uint8_t val);
|
||||
void ald_gpio_toggle_pin(GPIO_TypeDef *GPIOx, uint16_t pin);
|
||||
void ald_gpio_toggle_dir(GPIO_TypeDef *GPIOx, uint16_t pin);
|
||||
void ald_gpio_lock_pin(GPIO_TypeDef *GPIOx, uint16_t pin);
|
||||
uint16_t ald_gpio_read_port(GPIO_TypeDef *GPIOx);
|
||||
void ald_gpio_write_port(GPIO_TypeDef *GPIOx, uint16_t val);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
void ald_gpio_exti_interrupt_config(uint16_t pin, exti_trigger_style_t style, type_func_t status);
|
||||
flag_status_t ald_gpio_exti_get_flag_status(uint16_t pin);
|
||||
void ald_gpio_exti_clear_flag_status(uint16_t pin);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_GPIO_H__ */
|
||||
@@ -1,470 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_i2c.h
|
||||
* @brief Header file of I2C driver
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 15 Nov 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 30 Jun 2020 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_I2C_H__
|
||||
#define __ALD_I2C_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "ald_dma.h"
|
||||
#include "ald_cmu.h"
|
||||
#include <string.h>
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup I2C
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup I2C_Public_Types I2C Public Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief I2C Error Code
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_ERROR_NONE = 0x0U, /**< No error */
|
||||
I2C_ERROR_BERR = 0x1U, /**< Berr error */
|
||||
I2C_ERROR_ARLO = 0x2U, /**< Arlo error */
|
||||
I2C_ERROR_RUD = 0x4U, /**< Rx underflow error */
|
||||
I2C_ERROR_AF = 0x8U, /**< Af error */
|
||||
I2C_ERROR_ROV = 0x10U, /**< Rx overflow error */
|
||||
I2C_ERROR_RF = 0x20U, /**< Rx full error */
|
||||
I2C_ERROR_TUD = 0x40U, /**< Tx underflow error */
|
||||
I2C_ERROR_TOV = 0x80U, /**< Tx overflow error */
|
||||
I2C_ERROR_TE = 0x100U, /**< Tx empty error */
|
||||
I2C_ERROR_DMA = 0x200U, /**< Dma error */
|
||||
I2C_ERROR_TIMEOUT = 0x400U, /**< Timeout error */
|
||||
} i2c_error_t;
|
||||
|
||||
/**
|
||||
* @brief I2C state structure definition
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_STATE_RESET = 0x0U, /**< Peripheral is not yet Initialized */
|
||||
I2C_STATE_READY = 0x20U, /**< Peripheral Initialized and ready for use */
|
||||
I2C_STATE_BUSY = 0x24U, /**< An internal process is ongoing */
|
||||
I2C_STATE_BUSY_TX = 0x21U, /**< Data Transmission process is ongoing */
|
||||
I2C_STATE_BUSY_RX = 0x22U, /**< Data Reception process is ongoing */
|
||||
I2C_STATE_TIMEOUT = 0xA0U, /**< timeout state */
|
||||
I2C_STATE_ERROR = 0xE0U, /**< Error */
|
||||
} i2c_state_t;
|
||||
|
||||
/**
|
||||
* @brief I2C Addressing Mode
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_ADDR_7BIT = 0x0U, /**< 7 bit address */
|
||||
I2C_ADDR_10BIT = 0x1U, /**< 10 bit address */
|
||||
} i2c_addr_t;
|
||||
|
||||
/**
|
||||
* @brief I2C Dual Addressing Mode
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_DUALADDR_DISABLE = 0x0U, /**< dual address is disable */
|
||||
I2C_DUALADDR_ENABLE = 0x1U, /**< dual address is enable */
|
||||
} i2c_dual_addr_t;
|
||||
|
||||
/**
|
||||
* @brief I2C General Call Addressing mode
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_GENERALCALL_DISABLE = 0x0U, /**< general call address is disable */
|
||||
I2C_GENERALCALL_ENABLE = 0x1U, /**< general call address is enable */
|
||||
} i2c_general_addr_t;
|
||||
|
||||
/**
|
||||
* @brief I2C Nostretch Mode
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_NOSTRETCH_DISABLE = 0x0U, /**< Nostretch disable */
|
||||
I2C_NOSTRETCH_ENABLE = 0x1U, /**< Nostretch enable */
|
||||
} i2c_nostretch_t;
|
||||
|
||||
/**
|
||||
* @brief I2C Memory Address Size
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_MEMADD_SIZE_8BIT = 0x8U, /**< 8 bit memory address size */
|
||||
I2C_MEMADD_SIZE_16BIT = 0x10U, /**< 10 bit memory address size */
|
||||
} i2c_addr_size_t;
|
||||
|
||||
/**
|
||||
* @brief I2C mode structure definition
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_MODE_NONE = 0x0U, /**< No I2C communication on going */
|
||||
I2C_MODE_MASTER = 0x10U, /**< I2C communication is in Master mode */
|
||||
I2C_MODE_SLAVE = 0x20U, /**< I2C communication is in Slave mode */
|
||||
I2C_MODE_MEM = 0x40U, /**< I2C communication is in Memory mode */
|
||||
} i2c_mode_t;
|
||||
|
||||
/**
|
||||
* @brief I2C Clock
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_STANDARD_MODE_MAX_CLK = 100000U, /**< Standard mode clock */
|
||||
I2C_FAST_MODE_MAX_CLK = 400000U, /**< Fast mode clock */
|
||||
I2C_EXTREME_FAST_MODE_MAX_CLK = 1000000U, /**< Extreme mode clock */
|
||||
} i2c_clock_t;
|
||||
|
||||
/**
|
||||
* @brief I2C OAR2 Register
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_OAR2_ENDUAL = (1U << 0), /**< ENDUAL BIT */
|
||||
I2C_OAR2_ADD2 = (1U << 1) /**< ADD2 BIT */
|
||||
} i2c_oar2_t;
|
||||
|
||||
/**
|
||||
* @brief I2C CON1 Register
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_CON1_PE = (1U << 0), /**< Peripheral enable BIT */
|
||||
I2C_CON1_TXDMA = (1U << 14), /**< Transmit DMA BIT */
|
||||
I2C_CON1_RXDMA = (1U << 15), /**< Receive DMA BIT */
|
||||
I2C_CON1_SBC = (1U << 16), /**< Receive DMA BIT */
|
||||
I2C_CON1_NOSTRETCH = (1U << 17), /**< Slave bytes control BIT */
|
||||
I2C_CON1_GCEN = (1U << 19), /**< General call BIT */
|
||||
I2C_CON1_SMBHEN = (1U << 20), /**< SMBus slave device enable BIT */
|
||||
I2C_CON1_SMBDEN = (1U << 21), /**< SMBus master device enable BIT */
|
||||
I2C_CON1_ALERTEN = (1U << 22), /**< SMBus alert device enable BIT */
|
||||
I2C_CON1_PECEN = (1U << 23), /**< PEC enable BIT */
|
||||
} i2c_con1_t;
|
||||
|
||||
/**
|
||||
* @brief I2C CON2 Register
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_CON2_RD_WRN = (1U << 10), /**< Master R/W control BIT */
|
||||
I2C_CON2_ADD10 = (1U << 11), /**< 10bit address control BIT */
|
||||
I2C_CON2_HEAD10R = (1U << 12), /**< 10bit address master Receive control BIT */
|
||||
I2C_CON2_START = (1U << 13), /**< Master start singal control BIT */
|
||||
I2C_CON2_STOP = (1U << 14), /**< Master stop singal control BIT */
|
||||
I2C_CON2_NACK = (1U << 15), /**< Master Nack control BIT */
|
||||
I2C_CON2_RELOAD = (1U << 24), /**< Master communication reload control BIT */
|
||||
I2C_CON2_AUTOEND = (1U << 25), /**< Master Autoend control BIT */
|
||||
I2C_CON2_PECBYTE = (1U << 26), /**< PEC control BIT */
|
||||
I2C_CON2_HOLDACK = (1U << 28), /**< Hold ack control BIT */
|
||||
} i2c_con2_t;
|
||||
|
||||
/**
|
||||
* @brief I2C ADDR1 Register
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_OA1MODE = (1U << 10), /**< Addr1 bits choose BIT */
|
||||
I2C_OA1EN = (1U << 15), /**< Addr1 enable BIT */
|
||||
} i2c_addr1_t;
|
||||
|
||||
/**
|
||||
* @brief I2C ADDR2 Register
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_OA2EN = (1U << 15), /**< Addr2 enable BIT */
|
||||
} i2c_addr2_t;
|
||||
|
||||
/**
|
||||
* @brief I2C TIMEOUTR Register
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_TIMEOUTR_TIDLE = (1U << 12), /**< SCL idle check enable BIT */
|
||||
I2C_TIMEOUTR_TIMEOUTEN = (1U << 15), /**< Timeout enable BIT */
|
||||
} i2c_timoutr_t;
|
||||
|
||||
/**
|
||||
* @brief I2C peripherals module
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_MODULE_MASTER = (1U << 0), /**< Master module */
|
||||
I2C_MODULE_SLAVE = (1U << 1) /**< Slave module */
|
||||
} i2c_module_t;
|
||||
|
||||
/**
|
||||
* @brief I2C STAT Register
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_STAT_TXE = (1U << 0), /**< Transmit FIFO empty flag */
|
||||
I2C_STAT_TXF = (1U << 1), /**< Transmit FIFO full flag */
|
||||
I2C_STAT_TXOV = (1U << 2), /**< Transmit FIFO overrun flag */
|
||||
I2C_STAT_TXUD = (1U << 3), /**< Transmit FIFO underrun flag*/
|
||||
I2C_STAT_THTH = (1U << 4), /**< Transmit FIFO threshold flag */
|
||||
I2C_STAT_RXE = (1U << 5), /**< Receive FIFO empty flag*/
|
||||
I2C_STAT_RXF = (1U << 6), /**< Receive FIFO full flag*/
|
||||
I2C_STAT_RXOV = (1U << 7), /**< Receive FIFO overrun flag */
|
||||
I2C_STAT_RXUD = (1U << 8), /**< Receive FIFO underrun flag */
|
||||
I2C_STAT_RXTH = (1U << 9), /**< Receive FIFO threshold flag */
|
||||
I2C_STAT_TC = (1U << 10), /**< Transmit completed flag */
|
||||
I2C_STAT_TCR = (1U << 11), /**< Transmit and reload completed flag */
|
||||
I2C_STAT_BUSY = (1U << 15), /**< Bus status busy flag */
|
||||
I2C_STAT_DIR = (1U << 16), /**< Slave R/W flag */
|
||||
} i2c_stat_t;
|
||||
|
||||
/**
|
||||
* @brief Interrupt Configuration Definition
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_IT_TXE = (1U << 0), /**< Transmit FIFO empty interrupt */
|
||||
I2C_IT_TXOV = (1U << 2), /**< Transmit FIFO overrun interrupt */
|
||||
I2C_IT_TXUD = (1U << 3), /**< Transmit FIFO underrun interrupt*/
|
||||
I2C_IT_TXTH = (1U << 4), /**< Transmit FIFO threshold interrupt */
|
||||
I2C_IT_RXF = (1U << 6), /**< Receive FIFO full interrupt*/
|
||||
I2C_IT_RXOV = (1U << 7), /**< Receive FIFO overrun interrupt */
|
||||
I2C_IT_RXUD = (1U << 8), /**< Receive FIFO underrun interrupt */
|
||||
I2C_IT_RXTH = (1U << 9), /**< Receive FIFO threshold interrupt */
|
||||
I2C_IT_TC = (1U << 10), /**< Transmit completed interrupt */
|
||||
I2C_IT_TCR = (1U << 11), /**< Transmit and reload completed interrupt */
|
||||
I2C_IT_ADDR = (1U << 12), /**< Address matching interrupt */
|
||||
I2C_IT_NACK = (1U << 13), /**< NACK interrupt */
|
||||
I2C_IT_STOP = (1U << 14), /**< Stop detection interrupt */
|
||||
I2C_IT_BERR = (1U << 16), /**< Bus error interrupt */
|
||||
I2C_IT_ARLO = (1U << 17), /**< Arbitration loss interrupt */
|
||||
I2C_IT_PECE = (1U << 18), /**< PEC error interrupt */
|
||||
I2C_IT_TOUT = (1U << 19), /**< Timeout interrupt */
|
||||
I2C_IT_ALERT = (1U << 20), /**< SMBus Alert interrupt */
|
||||
} i2c_interrupt_t;
|
||||
|
||||
/**
|
||||
* @brief I2C TRISE Register
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_TRISE_TRISE = 0x3FU, /**< TRISE BITS */
|
||||
} i2c_trise_t;
|
||||
|
||||
/**
|
||||
* @brief I2C Configuration Structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
i2c_module_t module; /**< Specifies the communication module */
|
||||
uint32_t clk_speed; /**< Specifies the clock frequency */
|
||||
uint32_t own_addr1; /**< Specifies the first device own address */
|
||||
i2c_addr_t addr_mode; /**< Specifies addressing mode */
|
||||
i2c_dual_addr_t dual_addr; /**< Specifies if dual addressing mode is selected */
|
||||
uint32_t own_addr2; /**< Specifies the second device own address */
|
||||
i2c_general_addr_t general_call;/**< Specifies if general call mode is selected */
|
||||
i2c_nostretch_t no_stretch; /**< Specifies if nostretch mode is selected */
|
||||
} i2c_init_t;
|
||||
|
||||
/**
|
||||
* @brief I2C handle Structure definition
|
||||
*/
|
||||
typedef struct i2c_handle_s {
|
||||
I2C_TypeDef *perh; /**< I2C registers base address */
|
||||
i2c_init_t init; /**< I2C communication parameters */
|
||||
uint8_t *p_buff; /**< Pointer to I2C transfer buffer */
|
||||
uint16_t xfer_size; /**< I2C transfer size */
|
||||
__IO uint16_t xfer_count; /**< I2C transfer counter */
|
||||
|
||||
dma_handle_t hdmatx; /**< I2C Tx DMA handle parameters */
|
||||
dma_handle_t hdmarx; /**< I2C Rx DMA handle parameters */
|
||||
|
||||
lock_state_t lock; /**< I2C locking object */
|
||||
__IO i2c_state_t state; /**< I2C communication state */
|
||||
__IO i2c_mode_t mode; /**< I2C communication mode */
|
||||
__IO uint32_t error_code; /**< I2C Error code */
|
||||
|
||||
void (*master_tx_cplt_cbk)(struct i2c_handle_s *arg); /**< Master Tx completed callback */
|
||||
void (*master_rx_cplt_cbk)(struct i2c_handle_s *arg); /**< Master Rx completed callback */
|
||||
void (*slave_tx_cplt_cbk)(struct i2c_handle_s *arg); /**< Slave Tx completed callback */
|
||||
void (*slave_rx_cplt_cbk)(struct i2c_handle_s *arg); /**< Slave Rx completed callback */
|
||||
void (*mem_tx_cplt_cbk)(struct i2c_handle_s *arg); /**< Tx to Memory completed callback */
|
||||
void (*mem_rx_cplt_cbk)(struct i2c_handle_s *arg); /**< Rx from Memory completed callback */
|
||||
void (*error_callback)(struct i2c_handle_s *arg); /**< Error callback */
|
||||
} i2c_handle_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup I2C_Public_Macro I2C Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define I2C_FLAG_MASK (0xFFFFFFFFU)
|
||||
#define I2C_RESET_HANDLE_STATE(x) ((x)->state = I2C_STATE_RESET)
|
||||
#define I2C_ENABLE_IT(x, y) (SET_BIT((x)->perh->IER, (y)))
|
||||
#define I2C_DISABLE_IT(x, y) (SET_BIT((x)->perh->IDR, (y)))
|
||||
#define I2C_CLEAR_IT(x, y) (SET_BIT((x)->perh->ICR, (y)))
|
||||
#define I2C_GET_IT_FLAG(x, y) (READ_BIT((x)->perh->RIF, (y)))
|
||||
#define I2C_GET_IT_SOURCE(x, y) ((((x)->perh->IFM & (y)) == (y)) ? SET : RESET)
|
||||
#define I2C_GET_FLAG(x, y) ((((x)->perh->STAT) & ((y) & I2C_FLAG_MASK)) != RESET)
|
||||
#define I2C_MASTER_GET_DIR(x) (READ_BIT(((x)->perh->CON2), I2C_CON2_RD_WRN_MSK))
|
||||
#define I2C_SLAVE_GET_DIR(x) (READ_BIT(((x)->perh->STAT), I2C_STAT_DIR_MSK))
|
||||
#define I2C_ENABLE(x) (SET_BIT((x)->perh->CON1, I2C_CON1_PE_MSK))
|
||||
#define I2C_DISABLE(x) (CLEAR_BIT((x)->perh->CON1, I2C_CON1_PE_MSK))
|
||||
#define I2C_RST_TXFIFO(x) (SET_BIT((x)->perh->FCON, I2C_FCON_TXFRST_MSK))
|
||||
#define I2C_RST_RXFIFO(x) (SET_BIT((x)->perh->FCON, I2C_FCON_RXFRST_MSK))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup I2C_Private_Macro I2C Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_I2C_TYPE(x) (((x) == I2C0) || ((x) == I2C1))
|
||||
#define IS_I2C_MODULE(x) (((x) == I2C_MODULE_MASTER) || ((x) == I2C_MODULE_SLAVE))
|
||||
#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDR_7BIT) || \
|
||||
((ADDRESS) == I2C_ADDR_10BIT))
|
||||
#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDR_DISABLE) || \
|
||||
((ADDRESS) == I2C_DUALADDR_ENABLE))
|
||||
#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \
|
||||
((CALL) == I2C_GENERALCALL_ENABLE))
|
||||
#define IS_I2C_MEMADD_size(size) (((size) == I2C_MEMADD_SIZE_8BIT) || \
|
||||
((size) == I2C_MEMADD_SIZE_16BIT))
|
||||
#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \
|
||||
((STRETCH) == I2C_NOSTRETCH_ENABLE))
|
||||
#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0) && ((SPEED) <= I2C_EXTREME_FAST_MODE_MAX_CLK) )
|
||||
#define I2C_FREQ_RANGE(__PCLK__) ((__PCLK__) / 1000000)
|
||||
#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) &\
|
||||
(uint16_t)(0xFF00))) >> 8)))
|
||||
#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)(0x00FF))))
|
||||
#define IS_I2C_IT(x) (((x) == I2C_IT_TXE) || \
|
||||
((x) == I2C_IT_TXOV) || \
|
||||
((x) == I2C_IT_TXUD) || \
|
||||
((x) == I2C_IT_TXTH) || \
|
||||
((x) == I2C_IT_RXF) || \
|
||||
((x) == I2C_IT_RXOV) || \
|
||||
((x) == I2C_IT_RXUD) || \
|
||||
((x) == I2C_IT_RXTH) || \
|
||||
((x) == I2C_IT_TC) || \
|
||||
((x) == I2C_IT_TCR) || \
|
||||
((x) == I2C_IT_ADDR) || \
|
||||
((x) == I2C_IT_NACK) || \
|
||||
((x) == I2C_IT_STOP) || \
|
||||
((x) == I2C_IT_BERR) || \
|
||||
((x) == I2C_IT_ARLO) || \
|
||||
((x) == I2C_IT_PECE) || \
|
||||
((x) == I2C_IT_TOUT) || \
|
||||
((x) == I2C_IT_ALERT))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup I2C_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup I2C_Public_Functions_Group1 Initialization and de-initialization functions
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_i2c_init(i2c_handle_t *hperh);
|
||||
ald_status_t ald_i2c_reset(i2c_handle_t *hperh);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup I2C_Public_Functions_Group2 Input and Output operation functions
|
||||
* @{
|
||||
*/
|
||||
/** Blocking mode: Polling */
|
||||
ald_status_t ald_i2c_master_send(i2c_handle_t *hperh, uint16_t dev_addr,
|
||||
uint8_t *buf, uint32_t size, uint32_t timeout);
|
||||
ald_status_t ald_i2c_master_recv(i2c_handle_t *hperh, uint16_t dev_addr,
|
||||
uint8_t *buf, uint32_t size, uint32_t timeout);
|
||||
ald_status_t ald_i2c_slave_send(i2c_handle_t *hperh, uint8_t *buf, uint32_t size, uint32_t timeout);
|
||||
ald_status_t ald_i2c_slave_recv(i2c_handle_t *hperh, uint8_t *buf, uint32_t size, uint32_t timeout);
|
||||
ald_status_t ald_i2c_mem_write(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr,
|
||||
i2c_addr_size_t add_size, uint8_t *buf, uint32_t size, uint32_t timeout);
|
||||
ald_status_t ald_i2c_mem_read(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr,
|
||||
i2c_addr_size_t add_size, uint8_t *buf, uint32_t size, uint32_t timeout);
|
||||
|
||||
/** Non-Blocking mode: Interrupt */
|
||||
ald_status_t ald_i2c_master_send_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, uint32_t size);
|
||||
ald_status_t ald_i2c_master_recv_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint8_t *buf, uint32_t size);
|
||||
ald_status_t ald_i2c_slave_send_by_it(i2c_handle_t *hperh, uint8_t *buf, uint32_t size);
|
||||
ald_status_t ald_i2c_slave_recv_by_it(i2c_handle_t *hperh, uint8_t *buf, uint32_t size);
|
||||
ald_status_t ald_i2c_mem_write_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr,
|
||||
i2c_addr_size_t add_size, uint8_t *buf, uint32_t size);
|
||||
ald_status_t ald_i2c_mem_read_by_it(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr,
|
||||
i2c_addr_size_t add_size, uint8_t *buf, uint32_t size);
|
||||
|
||||
|
||||
/** Non-Blocking mode: DMA */
|
||||
ald_status_t ald_i2c_master_send_by_dma(i2c_handle_t *hperh, uint16_t dev_addr,
|
||||
uint8_t *buf, uint8_t size, uint8_t channel);
|
||||
ald_status_t ald_i2c_master_recv_by_dma(i2c_handle_t *hperh, uint16_t dev_addr,
|
||||
uint8_t *buf, uint8_t size, uint8_t channel);
|
||||
ald_status_t ald_i2c_slave_send_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint8_t size, uint8_t channel);
|
||||
ald_status_t ald_i2c_slave_recv_by_dma(i2c_handle_t *hperh, uint8_t *buf, uint8_t size, uint8_t channel);
|
||||
ald_status_t ald_i2c_mem_write_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr, i2c_addr_size_t add_size,
|
||||
uint8_t *buf, uint8_t size, uint8_t channel);
|
||||
ald_status_t ald_i2c_mem_read_by_dma(i2c_handle_t *hperh, uint16_t dev_addr, uint16_t mem_addr,
|
||||
i2c_addr_size_t add_size, uint8_t *buf, uint8_t size, uint8_t channel);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup I2C_Public_Functions_Group3 Peripheral state and Errors functions
|
||||
* @{
|
||||
*/
|
||||
i2c_state_t ald_i2c_get_state(i2c_handle_t *hperh);
|
||||
uint32_t ald_i2c_get_error(i2c_handle_t *hperh);
|
||||
void ald_i2c_clear_flag_status(i2c_handle_t *hperh, i2c_interrupt_t flag);
|
||||
flag_status_t ald_i2c_get_mask_flag_status(i2c_handle_t *hperh, i2c_interrupt_t flag);
|
||||
flag_status_t ald_i2c_get_flag_status(i2c_handle_t *hperh, i2c_interrupt_t flag);
|
||||
it_status_t ald_i2c_get_it_status(i2c_handle_t *hperh, i2c_interrupt_t it);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup I2C_Public_Functions_Group4 IRQ Handler and Callbacks
|
||||
* @{
|
||||
*/
|
||||
void ald_i2c_ev_irq_handler(i2c_handle_t *hperh);
|
||||
void ald_i2c_er_irq_handler(i2c_handle_t *hperh);
|
||||
void ald_i2c_interrupt_config(i2c_handle_t *hperh, i2c_interrupt_t it, type_func_t state);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_I2C_H__ */
|
||||
@@ -1,391 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_i2s.c
|
||||
* @brief Header file of I2S module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 13 Nov 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 13 Nov 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_I2S_H__
|
||||
#define __ALD_I2S_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "ald_dma.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup I2S
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup I2S_Public_Types I2S Public Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Channel length
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_WIDE_16 = 0x0U, /**< Channel length is 16 */
|
||||
I2S_WIDE_32 = 0x1U, /**< Channel length is 32 */
|
||||
} i2s_chlen_t;
|
||||
|
||||
/**
|
||||
* @brief Data length
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_LEN_16 = 0x0U, /**< Data length is 16 */
|
||||
I2S_LEN_24 = 0x1U, /**< Data length is 24 */
|
||||
I2S_LEN_32 = 0x2U, /**< Data length is 32 */
|
||||
} i2s_datalen_t;
|
||||
|
||||
/**
|
||||
* @brief Inactive state clock polarity
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_INACTIVE_LOW = 0x0U, /**< Inactive state is low */
|
||||
I2S_INACTIVE_HIGH = 0x1U, /**< Inactive state is high */
|
||||
} i2s_cpol_t;
|
||||
|
||||
/**
|
||||
* @brief I2s standard
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_STD_PHI = 0x0U, /**< Philips standard */
|
||||
I2S_STD_MSB = 0x1U, /**< MSB standard */
|
||||
I2S_STD_LSB = 0x2U, /**< LSB standard */
|
||||
I2S_STD_PCM = 0x3U, /**< PCM standard */
|
||||
} i2s_standard_t;
|
||||
|
||||
/**
|
||||
* @brief I2s configuration mode
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_MASTER_TRANSMIT = 0x2U, /**< I2S master transmit mode */
|
||||
I2S_MASTER_RECEIVE = 0x3U, /**< I2S master receive mode */
|
||||
} i2s_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Pcm frame synchronization
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_FRAME_SHORT = 0x0U, /**< I2S PCM short frame */
|
||||
I2S_FRAME_LONG = 0x1U, /**< I2S PCM long frame */
|
||||
} i2s_pcms_t;
|
||||
|
||||
/**
|
||||
* @brief I2S error status
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_ERROR_NONE = 0x0U, /**< none */
|
||||
I2S_ERROR_MODF = 0x1U, /**< mode fault */
|
||||
I2S_ERROR_DMA = 0x2U, /**< crc error */
|
||||
I2S_ERROR_FRE = 0x4U, /**< frame error */
|
||||
I2S_ERROR_RXOV = 0x8U, /**< receive over error */
|
||||
I2S_ERROR_TXOV = 0x10U, /**< dma error */
|
||||
I2S_ERROR_FLAG = 0x20U, /**< interrupt flag error */
|
||||
} i2s_error_t;
|
||||
|
||||
/**
|
||||
* @brief interrupt control
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_IT_TXE = (1U << 0), /**< Transmit fifo empty interrupt */
|
||||
I2S_IT_TXOV = (1U << 2), /**< Transmit fifo overflow interrupt */
|
||||
I2S_IT_TXUD = (1U << 3), /**< Transmit fifo underflow interrupt */
|
||||
I2S_IT_RXF = (1U << 9), /**< Receive fifo full interrupt */
|
||||
I2S_IT_RXOV = (1U << 10), /**< Receive fifo overflow interrupt */
|
||||
I2S_IT_RXUD = (1U << 11), /**< Receive fifo underflow interrupt */
|
||||
I2S_IT_RXTH = (1U << 12), /**< Receive fifo over threshold interrupt */
|
||||
I2S_IT_CRCERR = (1U << 16), /**< Crc error interrupt */
|
||||
I2S_IT_MODF = (1U << 17), /**< Mode error interrupt */
|
||||
I2S_IT_FRE = (1U << 18), /**< Frame error interrupt */
|
||||
} i2s_it_t;
|
||||
|
||||
/**
|
||||
* @brief I2S dma request definition
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_DMA_REQ_TX = 0U, /**< TX dma request */
|
||||
I2S_DMA_REQ_RX = 1U, /**< RX dma request */
|
||||
} i2s_dma_req_t;
|
||||
|
||||
/**
|
||||
* @brief interrupt flag
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_IF_TXE = (1U << 0), /**< Transmit fifo empty interrupt flag */
|
||||
I2S_IF_TXOV = (1U << 2), /**< Transmit fifo overflow interrupt flag */
|
||||
I2S_IF_TXUD = (1U << 3), /**< Transmit fifo underflow interrupt flag */
|
||||
I2S_IF_RXF = (1U << 9), /**< Receive fifo full interrupt flag */
|
||||
I2S_IF_RXOV = (1U << 10), /**< Receive fifo overflow interrupt flag */
|
||||
I2S_IF_RXUD = (1U << 11), /**< Receive fifo underflow interrupt flag */
|
||||
I2S_IF_RXTH = (1U << 12), /**< Receive fifo over threshold interrupt flag */
|
||||
I2S_IF_FRE = (1U << 18), /**< Frame error interrupt flag */
|
||||
} i2s_flag_t;
|
||||
|
||||
/**
|
||||
* @brief I2S state structures definition
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_STATE_RESET = 0x00U, /**< Peripheral is not initialized */
|
||||
I2S_STATE_READY = 0x01U, /**< Peripheral Initialized and ready for use */
|
||||
I2S_STATE_BUSY = 0x02U, /**< an internal process is ongoing */
|
||||
I2S_STATE_BUSY_TX = 0x11U, /**< transmit is ongoing */
|
||||
I2S_STATE_BUSY_RX = 0x21U, /**< receive is ongoing */
|
||||
I2S_STATE_BUSY_TX_RX = 0x31U, /**< transmit and receive are ongoing */
|
||||
I2S_STATE_TIMEOUT = 0x03U, /**< Timeout state */
|
||||
I2S_STATE_ERROR = 0x04U, /**< Error */
|
||||
} i2s_state_t;
|
||||
|
||||
/**
|
||||
* @brief I2S status definition
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_STATUS_TXE = (1U << 0), /**< Transmit fifo empty status */
|
||||
I2S_STATUS_TXF = (1U << 1), /**< Transmit fifo full status */
|
||||
I2S_STATUS_TXOV = (1U << 2), /**< Transmit fifo overflow status */
|
||||
I2S_STATUS_TXUD = (1U << 3), /**< Transmit fifo underflow status */
|
||||
I2S_STATUS_RXE = (1U << 8), /**< Receive fifo empty status */
|
||||
I2S_STATUS_RXF = (1U << 9), /**< Receive fifo full status */
|
||||
I2S_STATUS_RXOV = (1U << 10), /**< Receive fifo overflow status */
|
||||
I2S_STATUS_RXUD = (1U << 11), /**< Receive fifo underflow status */
|
||||
I2S_STATUS_CHSIDE = (1U << 14), /**< Sound channel status */
|
||||
I2S_STATUS_BUSY = (1U << 15), /**< BUSY status */
|
||||
} i2s_status_t;
|
||||
|
||||
/**
|
||||
* @brief Channel side
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_SIDE_LEFT = 0U, /**< Sound channel is left */
|
||||
I2S_SIDE_RIGHT = 1U, /**< Sound channel is right */
|
||||
} i2s_ch_side_t;
|
||||
|
||||
/**
|
||||
* @brief I2S TXE/RXNE status definition
|
||||
*/
|
||||
typedef enum {
|
||||
I2S_SR_TXE = 0U, /**< STAT TXE set */
|
||||
I2S_SR_RXNE = 1U, /**< STAT RXTH set */
|
||||
I2S_SR_TXE_RXNE = 2U, /**< STAT TXE and RXTH set */
|
||||
} i2s_sr_status_t;
|
||||
|
||||
/**
|
||||
* @brief I2S init structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
i2s_chlen_t ch_len; /**< Channel length choose */
|
||||
i2s_datalen_t data_len; /**< Data length choose */
|
||||
i2s_cpol_t polarity; /**< Inactive clock polarity */
|
||||
i2s_standard_t standard; /**< Standard choose */
|
||||
i2s_pcms_t pcm_frame; /**< PCM frame synchronization */
|
||||
type_func_t ext_clk_en; /**< Choose external clock or APB1 clock */
|
||||
uint32_t ext_clk; /**< External clock, unit is Hz */
|
||||
type_func_t mck_en; /**< Main clock output function */
|
||||
uint32_t sampling; /**< Sampling rate. eg. 192*1024-192KHz, 96*1024-96KHz */
|
||||
} i2s_init_t;
|
||||
|
||||
/**
|
||||
* @brief I2S handle structure definition
|
||||
*/
|
||||
typedef struct i2s_handle_s {
|
||||
SPI_I2S_TypeDef *perh; /**< I2S registers base address */
|
||||
i2s_init_t init; /**< I2S communication parameters */
|
||||
uint16_t *tx_buf; /**< Pointer to I2S Tx transfer buffer */
|
||||
uint32_t tx_size; /**< I2S Tx transfer size */
|
||||
uint32_t tx_count; /**< I2S Tx transfer counter */
|
||||
uint16_t *rx_buf; /**< Pointer to I2S Rx transfer buffer */
|
||||
uint32_t rx_size; /**< I2S Rx Transfer size */
|
||||
uint32_t rx_count; /**< I2S Rx Transfer Counter */
|
||||
|
||||
dma_handle_t hdmatx; /**< I2S DMA handle parameters */
|
||||
dma_handle_t hdmarx; /**< I2S DMA handle parameters */
|
||||
|
||||
lock_state_t lock; /**< Locking object */
|
||||
i2s_state_t state; /**< I2S communication state */
|
||||
uint8_t side; /**< I2S channel side */
|
||||
uint32_t err_code; /**< I2S error code */
|
||||
|
||||
void (*tx_cplt_cbk)(struct i2s_handle_s *arg); /**< Tx completed callback */
|
||||
void (*rx_cplt_cbk)(struct i2s_handle_s *arg); /**< Rx completed callback */
|
||||
void (*err_cbk)(struct i2s_handle_s *arg); /**< error callback */
|
||||
} i2s_handle_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup I2S_Public_Macros I2S Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define I2S_RESET_HANDLE_STATE(x) ((x)->state = I2S_STATE_RESET)
|
||||
#define I2S_ENABLE(x) (SET_BIT((x)->perh->I2SCFG, SPI_I2SCFG_I2SE_MSK))
|
||||
#define I2S_DISABLE(x) (CLEAR_BIT((x)->perh->I2SCFG, SPI_I2SCFG_I2SE_MSK))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup I2S_Private_Macros I2S Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_I2S(x) (((x) == I2S0) || \
|
||||
((x) == I2S1) || \
|
||||
((x) == I2S2))
|
||||
#define IS_I2S_CH_LEN(x) (((x) == I2S_WIDE_16) || \
|
||||
((x) == I2S_WIDE_32))
|
||||
#define IS_I2S_DATE_LEN(x) (((x) == I2S_LEN_16) || \
|
||||
((x) == I2S_LEN_24) || \
|
||||
((x) == I2S_LEN_32))
|
||||
#define IS_I2S_CPOL(x) (((x) == I2S_INACTIVE_LOW) || \
|
||||
((x) == I2S_INACTIVE_HIGH))
|
||||
#define IS_I2S_STANDARD(x) (((x) == I2S_STD_PHI) || \
|
||||
((x) == I2S_STD_MSB) || \
|
||||
((x) == I2S_STD_LSB) || \
|
||||
((x) == I2S_STD_PCM))
|
||||
#define IS_I2S_PCMS(x) (((x) == I2S_FRAME_SHORT) || \
|
||||
((x) == I2S_FRAME_LONG))
|
||||
#define IS_I2S_IT(x) (((x) == I2S_IT_TXE) || \
|
||||
((x) == I2S_IT_TXOV) || \
|
||||
((x) == I2S_IT_TXUD) || \
|
||||
((x) == I2S_IT_RXF) || \
|
||||
((x) == I2S_IT_RXOV) || \
|
||||
((x) == I2S_IT_RXUD) || \
|
||||
((x) == I2S_IT_RXTH) || \
|
||||
((x) == I2S_IT_CRCERR) || \
|
||||
((x) == I2S_IT_MODF) || \
|
||||
((x) == I2S_IT_FRE))
|
||||
#define IS_I2S_IF(x) (((x) == I2S_IF_TXE) || \
|
||||
((x) == I2S_IF_TXOV) || \
|
||||
((x) == I2S_IF_TXUD) || \
|
||||
((x) == I2S_IF_RXF) || \
|
||||
((x) == I2S_IF_RXOV) || \
|
||||
((x) == I2S_IF_RXUD) || \
|
||||
((x) == I2S_IF_RXTH) || \
|
||||
((x) == I2S_IF_FRE))
|
||||
#define IS_I2S_FLAG(x) (((x) == I2S_FLAG_TXE) || \
|
||||
((x) == I2S_FLAG_TXF) || \
|
||||
((x) == I2S_FLAG_TXOV) || \
|
||||
((x) == I2S_FLAG_TXUD) || \
|
||||
((x) == I2S_FLAG_RXE) || \
|
||||
((x) == I2S_FLAG_RXF) || \
|
||||
((x) == I2S_FLAG_RXOV) || \
|
||||
((x) == I2S_FLAG_RXUD) || \
|
||||
((x) == I2S_FLAG_CHSIDE) || \
|
||||
((x) == I2S_FLAG_BSY))
|
||||
#define IS_I2S_STATUS(x) (((x) == I2S_STATUS_TXE) || \
|
||||
((x) == I2S_STATUS_TXF) || \
|
||||
((x) == I2S_STATUS_TXOV) || \
|
||||
((x) == I2S_STATUS_TXUD) || \
|
||||
((x) == I2S_STATUS_RXE) || \
|
||||
((x) == I2S_STATUS_RXF) || \
|
||||
((x) == I2S_STATUS_RXOV) || \
|
||||
((x) == I2S_STATUS_RXUD) || \
|
||||
((x) == I2S_STATUS_CHSIDE) || \
|
||||
((x) == I2S_STATUS_BUSY))
|
||||
#define IS_I2S_DMA_REQ(x) (((x) == I2S_DMA_REQ_TX) || \
|
||||
((x) == I2S_DMA_REQ_RX))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup I2S_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup I2S_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
|
||||
ald_status_t ald_i2s_init(i2s_handle_t *hperh);
|
||||
void ald_i2s_reset(i2s_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup I2S_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_i2s_master_send(i2s_handle_t *hperh, uint16_t *buf, uint32_t size, uint32_t timeout);
|
||||
ald_status_t ald_i2s_master_recv(i2s_handle_t *hperh, uint16_t *buf, uint32_t size, uint32_t timeout);
|
||||
ald_status_t ald_i2s_master_send_by_it(i2s_handle_t *hperh, uint16_t *buf, uint32_t size);
|
||||
ald_status_t ald_i2s_master_recv_by_it(i2s_handle_t *hperh, uint16_t *buf, uint32_t size);
|
||||
|
||||
ald_status_t ald_i2s_master_send_by_dma(i2s_handle_t *hperh, uint16_t *buf, uint32_t size, uint8_t channel);
|
||||
ald_status_t ald_i2s_master_recv_by_dma(i2s_handle_t *hperh, uint16_t *buf, uint32_t size, uint8_t dma_ch, uint8_t _dma_ch);
|
||||
ald_status_t ald_i2s_dma_pause(i2s_handle_t *hperh);
|
||||
ald_status_t ald_i2s_dma_resume(i2s_handle_t *hperh);
|
||||
ald_status_t ald_i2s_dma_stop(i2s_handle_t *hperh);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup I2S_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
void ald_i2s_irq_handler(i2s_handle_t *hperh);
|
||||
void ald_i2s_interrupt_config(i2s_handle_t *hperh, i2s_it_t it, type_func_t state);
|
||||
void ald_i2s_dma_req_config(i2s_handle_t *hperh, i2s_dma_req_t req, type_func_t state);
|
||||
flag_status_t ald_i2s_get_status(i2s_handle_t *hperh, i2s_status_t status);
|
||||
it_status_t ald_i2s_get_it_status(i2s_handle_t *hperh, i2s_it_t it);
|
||||
flag_status_t ald_i2s_get_flag_status(i2s_handle_t *hperh, i2s_flag_t flag);
|
||||
flag_status_t ald_i2s_get_mask_flag_status(i2s_handle_t *hperh, i2s_flag_t flag);
|
||||
void ald_i2s_clear_flag_status(i2s_handle_t *hperh, i2s_flag_t flag);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup I2S_Public_Functions_Group4
|
||||
* @{
|
||||
*/
|
||||
i2s_state_t ald_i2s_get_state(i2s_handle_t *hperh);
|
||||
uint32_t ald_i2s_get_error(i2s_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,104 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_iap.h
|
||||
* @brief Header file of IAP module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 04 Dec 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 04 Dec 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_IAP_H__
|
||||
#define __ALD_IAP_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup IAP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup IAP_Private_Macros IAP Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IAP_WSP_ADDR 0x10000000U
|
||||
#define IAP_PE_ADDR 0x10000004U
|
||||
#define IAP_WP_ADDR 0x10000008U
|
||||
#define IAP_DWP_ADDR 0x1000000cU
|
||||
#define IAP_WordsProgram_DF 0x10000010U
|
||||
#define IAP_PageErase_DF 0x10000014U
|
||||
#define IAP_WordProgram_DF 0x10000018U
|
||||
#define IAP_DWordProgram_DF 0x1000001cU
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup IAP_Private_Types IAP Private Types
|
||||
* @{
|
||||
*/
|
||||
typedef uint32_t (*IAP_PE)(uint32_t addr);
|
||||
typedef uint32_t (*IAP_WP)(uint32_t addr, uint32_t data);
|
||||
typedef uint32_t (*IAP_DWP)(uint32_t addr, uint32_t data_l, uint32_t data_h);
|
||||
typedef uint32_t (*IAP_WSP)(uint32_t addr, uint8_t *data, uint32_t len, uint32_t erase);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup IAP_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t ald_iap_erase_page(uint32_t addr);
|
||||
uint32_t ald_iap_program_word(uint32_t addr, uint32_t data);
|
||||
uint32_t ald_iap_program_dword(uint32_t addr, uint32_t data_l, uint32_t data_h);
|
||||
uint32_t ald_iap_program_words(uint32_t addr, uint8_t *data, uint32_t len, uint32_t erase);
|
||||
uint32_t ald_iap_erase_page_df(uint32_t addr);
|
||||
uint32_t ald_iap_program_word_df(uint32_t addr, uint32_t data);
|
||||
uint32_t ald_iap_program_dword_df(uint32_t addr, uint32_t data_l, uint32_t data_h);
|
||||
uint32_t ald_iap_program_words_df(uint32_t addr, uint8_t *data, uint32_t len, uint32_t erase);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_IAP_H__ */
|
||||
@@ -1,222 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_nand.h
|
||||
* @brief Header file of EBI_NAND module driver
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 07 Dec 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 07 Dec 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_NAND_H_
|
||||
#define __ALD_NAND_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ald_ebi.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup NAND
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup NAND_Public_Types NAND Public Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief NAND State structures definition
|
||||
*/
|
||||
typedef enum {
|
||||
ALD_NAND_STATE_RESET = 0x00U, /**< NAND not yet initialized or disabled */
|
||||
ALD_NAND_STATE_READY = 0x01U, /**< NAND initialized and ready for use */
|
||||
ALD_NAND_STATE_BUSY = 0x02U, /**< NAND internal process is ongoing */
|
||||
ALD_NAND_STATE_ERROR = 0x03U /**< NAND error state */
|
||||
} ald_nand_state_t;
|
||||
|
||||
/**
|
||||
* @brief NAND Memory electronic signature Structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t maker_id; /**< Maker id */
|
||||
uint8_t device_id; /**< Device id */
|
||||
uint8_t third_id; /**< Third id */
|
||||
uint8_t fourth_id; /**< Fourth id */
|
||||
} nand_id_t;
|
||||
|
||||
/**
|
||||
* @brief NAND Memory address Structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t page; /**< NAND memory Page address */
|
||||
uint16_t plane; /**< NAND memory Plane address */
|
||||
uint16_t block; /**< NAND memory Block address */
|
||||
} nand_address_t;
|
||||
|
||||
/**
|
||||
* @brief NAND Memory info Structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t page_size; /**< NAND memory page (without spare area) size measured in bytes */
|
||||
uint32_t spare_size; /**< NAND memory spare area size measured in bytes */
|
||||
uint32_t block_size; /**< NAND memory block size measured in number of pages */
|
||||
uint32_t block_nbr; /**< NAND memory number of total block */
|
||||
uint32_t plane_nbr; /**< NAND memory number of planes */
|
||||
uint32_t plane_size; /**< NAND memory plane size measured in number of blocks */
|
||||
type_func_t extra_cmd; /**< NAND extra command needed for Page reading mode */
|
||||
} nand_device_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief NAND handle Structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
EBI_NAND_TypeDef *instance; /**< Register base address */
|
||||
ald_ebi_nand_init_t init; /**< NAND device control configuration parameters */
|
||||
lock_state_t lock; /**< NAND locking object */
|
||||
__IO ald_nand_state_t state; /**< NAND device access state */
|
||||
nand_device_cfg_t config; /**< NAND phusical characteristic information structure */
|
||||
} nand_handle_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup Nand_Private_Constants Nand Private Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define NAND_DEVICE1 EBI_BANK2
|
||||
#define NAND_DEVICE2 EBI_BANK3
|
||||
#define NAND_WRITE_TIMEOUT 1000U
|
||||
#define CMD_AREA (1U<<16U) /* A16 = CLE high */
|
||||
#define ADDR_AREA (1U<<17U) /* A17 = ALE high */
|
||||
#define NAND_CMD_AREA_A ((uint8_t)0x00U)
|
||||
#define NAND_CMD_AREA_B ((uint8_t)0x01U)
|
||||
#define NAND_CMD_AREA_C ((uint8_t)0x50U)
|
||||
#define NAND_CMD_AREA_TRUE1 ((uint8_t)0x30U)
|
||||
#define NAND_CMD_WRITE0 ((uint8_t)0x80U)
|
||||
#define NAND_CMD_WRITE_TRUE1 ((uint8_t)0x10U)
|
||||
#define NAND_CMD_ERASE0 ((uint8_t)0x60U)
|
||||
#define NAND_CMD_ERASE1 ((uint8_t)0xD0U)
|
||||
#define NAND_CMD_READID ((uint8_t)0x90U)
|
||||
#define NAND_CMD_STATUS ((uint8_t)0x70U)
|
||||
#define NAND_CMD_LOCK_STATUS ((uint8_t)0x7AU)
|
||||
#define NAND_CMD_RESET ((uint8_t)0xFFU)
|
||||
/* NAND memory status */
|
||||
#define NAND_VALID_ADDRESS 0x00000100U
|
||||
#define NAND_INVALID_ADDRESS 0x00000200U
|
||||
#define NAND_TIMEOUT_ERROR 0x00000400U
|
||||
#define NAND_BUSY 0x00000000U
|
||||
#define NAND_ERROR 0x00000001U
|
||||
#define NAND_READY 0x00000040U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup Nand_Private_Macros Nand Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define ARRAY_ADDRESS(x , y) ((x)->page + \
|
||||
(((x)->block + (((x)->plane) * \
|
||||
((y)->config.plane_size))) * ((y)->config.block_size)))
|
||||
#define COLUMN_ADDRESS( x) ((x)->config.page_size)
|
||||
#define ADDR_1ST_CYCLE(x) (uint8_t)(x) /* 1st addressing cycle */
|
||||
#define ADDR_2ND_CYCLE(x) (uint8_t)((x) >> 8U) /* 2nd addressing cycle */
|
||||
#define ADDR_3RD_CYCLE(x) (uint8_t)((x) >> 16U) /* 3rd addressing cycle */
|
||||
#define ADDR_4TH_CYCLE(x) (uint8_t)((x) >> 24U) /* 4th addressing cycle */
|
||||
#define COLUMN_1ST_CYCLE(x) (uint8_t)(x) /* 1st Column addressing cycle */
|
||||
#define COLUMN_2ND_CYCLE(x) (uint8_t)((x) >> 8U) /* 2nd Column addressing cycle */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup Nand_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
/** @addtogroup Nand_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
/* Initialization/de-initialization functions */
|
||||
ald_status_t ald_nand_init(nand_handle_t *hperh, ald_ebi_nand_timing_t *ctiming, ald_ebi_nand_timing_t *atiming);
|
||||
ald_status_t ald_nand_deinit(nand_handle_t *hperh);
|
||||
ald_status_t ald_nand_reset(nand_handle_t *hperh);
|
||||
void nand_config_device(nand_handle_t *hperh, nand_device_cfg_t *pdcfg);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup Nand_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
/* IO operation functions */
|
||||
ald_status_t ald_nand_read_id(nand_handle_t *hperh, nand_id_t *id);
|
||||
ald_status_t ald_nand_read_page_8b(nand_handle_t *hperh, nand_address_t *addr, uint8_t *buf, uint32_t nr);
|
||||
ald_status_t ald_nand_write_page_8b(nand_handle_t *hperh, nand_address_t *addr, uint8_t *buf, uint32_t nr);
|
||||
ald_status_t ald_nand_read_sparearea_8b(nand_handle_t *hperh, nand_address_t *addr, uint8_t *buf, uint32_t nr);
|
||||
ald_status_t ald_nand_write_sparearea_8b(nand_handle_t *hperh, nand_address_t *addr, uint8_t *buf, uint32_t nr);
|
||||
ald_status_t ald_nand_read_page_16b(nand_handle_t *hperh, nand_address_t *addr, uint16_t *buf, uint32_t nr);
|
||||
ald_status_t ald_nand_write_page_16b(nand_handle_t *hperh, nand_address_t *addr, uint16_t *buf, uint32_t nr);
|
||||
ald_status_t ald_nand_read_sparearea_16b(nand_handle_t *hperh, nand_address_t *addr, uint16_t *buf, uint32_t nr);
|
||||
ald_status_t ald_nand_write_sparearea_16b(nand_handle_t *hperh, nand_address_t *addr, uint16_t *buf, uint32_t nr);
|
||||
ald_status_t ald_nand_erase_block(nand_handle_t *hperh, nand_address_t *addr);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup Nand_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
/* NAND Control functions */
|
||||
void ald_nand_irq_handler(nand_handle_t *hperh);
|
||||
void ald_nand_irq_cbk(nand_handle_t *hperh);
|
||||
uint32_t ald_nand_address_inc(nand_handle_t *hperh, nand_address_t *addr);
|
||||
uint32_t ald_nand_read_status(nand_handle_t *hperh);
|
||||
ald_nand_state_t ald_nand_get_state(nand_handle_t *hperh);
|
||||
ald_status_t ald_nand_ecc_enable(nand_handle_t *hperh);
|
||||
ald_status_t ald_nand_ecc_disable(nand_handle_t *hperh);
|
||||
ald_status_t ald_nand_get_ecc(nand_handle_t *hperh, uint32_t *val, uint32_t timeout);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,236 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_nor_lcd.h
|
||||
* @brief Header file of EBI_NOR_LCD module driver
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 07 Dec 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 07 Dec 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_NOR_LCD_H_
|
||||
#define __ALD_NOR_LCD_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ald_ebi.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup NOR_LCD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup NOR_LCD_Private_Constants NOR LCD Private Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* NOR device IDs addresses */
|
||||
#define MC_ADDRESS ((uint16_t)0x0000U)
|
||||
#define DEVICE_CODE1_ADDR ((uint16_t)0x0001U)
|
||||
#define DEVICE_CODE2_ADDR ((uint16_t)0x000EU)
|
||||
#define DEVICE_CODE3_ADDR ((uint16_t)0x000FU)
|
||||
|
||||
/* NOR CFI IDs addresses */
|
||||
#define CFI1_ADDRESS ((uint16_t)0x10U)
|
||||
#define CFI2_ADDRESS ((uint16_t)0x11U)
|
||||
#define CFI3_ADDRESS ((uint16_t)0x12U)
|
||||
#define CFI4_ADDRESS ((uint16_t)0x13U)
|
||||
|
||||
/* NOR operation wait timeout */
|
||||
#define NOR_TMEOUT ((uint16_t)0xFFFFU)
|
||||
|
||||
/* NOR memory data width */
|
||||
#define NOR_MEMORY_8B ((uint8_t)0x0U)
|
||||
#define NOR_MEMORY_16B ((uint8_t)0x1U)
|
||||
|
||||
/* NOR memory device read/write start address */
|
||||
#define NOR_MEMORY_ADRESS1 EBI_BANK1_1
|
||||
#define NOR_MEMORY_ADRESS2 EBI_BANK1_2
|
||||
#define NOR_MEMORY_ADRESS3 EBI_BANK1_3
|
||||
#define NOR_MEMORY_ADRESS4 EBI_BANK1_4
|
||||
|
||||
#define NOR_CMD_ADDRESS_FIRST (uint16_t)0x0555U
|
||||
#define NOR_CMD_ADDRESS_FIRST_CFI (uint16_t)0x0055U
|
||||
#define NOR_CMD_ADDRESS_SECOND (uint16_t)0x02AAU
|
||||
#define NOR_CMD_ADDRESS_THIRD (uint16_t)0x0555U
|
||||
#define NOR_CMD_ADDRESS_FOURTH (uint16_t)0x0555U
|
||||
#define NOR_CMD_ADDRESS_FIFTH (uint16_t)0x02AAU
|
||||
#define NOR_CMD_ADDRESS_SIXTH (uint16_t)0x0555U
|
||||
|
||||
#define NOR_CMD_DATA_READ_RESET (uint16_t)0x00F0U
|
||||
#define NOR_CMD_DATA_FIRST (uint16_t)0x00AAU
|
||||
#define NOR_CMD_DATA_SECOND (uint16_t)0x0055U
|
||||
#define NOR_CMD_DATA_AUTO_SELECT (uint16_t)0x0090U
|
||||
#define NOR_CMD_DATA_PROGRAM (uint16_t)0x00A0U
|
||||
#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD (uint16_t)0x0080U
|
||||
#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH (uint16_t)0x00AAU
|
||||
#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH (uint16_t)0x0055U
|
||||
#define NOR_CMD_DATA_CHIP_ERASE (uint16_t)0x0010U
|
||||
#define NOR_CMD_DATA_CFI (uint16_t)0x0098U
|
||||
#define NOR_CMD_DATA_BUFFER_AND_PROG (uint8_t)0x25U
|
||||
#define NOR_CMD_DATA_BUFFER_AND_PROG_CONFIRM (uint8_t)0x29U
|
||||
#define NOR_CMD_DATA_BLOCK_ERASE (uint8_t)0x30U
|
||||
#define NOR_MASK_STATUS_DQ5 (uint16_t)0x0020U
|
||||
#define NOR_MASK_STATUS_DQ6 (uint16_t)0x0040U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup NOR_LCD_Private_Macros NOR_LCD Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define NOR_ADDR_SHIFT(NOR_ADDR, NOR_MEMORY_WIDTH_, ADDRESS) \
|
||||
((uint32_t)(((NOR_MEMORY_WIDTH_) == NOR_MEMORY_16B) ? \
|
||||
((uint32_t)((NOR_ADDR) + (2U * (ADDRESS)))): \
|
||||
((uint32_t)((NOR_ADDR) + (ADDRESS)))))
|
||||
#define NOR_WRITE(ADDR, DATA) (*(__IO uint16_t *)((uint32_t)(ADDR)) = (DATA))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup NOR_LCD_Public_Types NOR_LCD Public Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief ALD SRAM State structures definition
|
||||
*/
|
||||
typedef enum {
|
||||
ALD_NOR_STATE_RESET = 0x00U, /**< NOR not yet initialized or disabled */
|
||||
ALD_NOR_STATE_READY = 0x01U, /**< NOR initialized and ready for use */
|
||||
ALD_NOR_STATE_BUSY = 0x02U, /**< NOR internal processing is ongoing */
|
||||
ALD_NOR_STATE_ERROR = 0x03U, /**< NOR error state */
|
||||
ALD_NOR_STATE_PROTECTED = 0x04U /**< NOR NORSRAM device write protected */
|
||||
} ald_nor_state_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NOR Status typedef
|
||||
*/
|
||||
typedef enum {
|
||||
ALD_NOR_STATUS_SUCCESS = 0U, /**< NOR status success */
|
||||
ALD_NOR_STATUS_ONGOING, /**< NOR status ongoing */
|
||||
ALD_NOR_STATUS_ERROR, /**< NOR status error */
|
||||
ALD_NOR_STATUS_TIMEOUT, /**< NOR status timeout */
|
||||
} nor_status_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NOR ID typedef
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t m_code; /**< Defines the device's manufacturer code used to identify the memory */
|
||||
uint16_t device_code1; /**< DEVICE_CODE1_ADDR code1 */
|
||||
uint16_t device_code2; /**< DEVICE_CODE1_ADDR code2 */
|
||||
uint16_t device_code3; /**< DEVICE_CODE1_ADDR code3 */
|
||||
} nor_id_t;
|
||||
|
||||
/**
|
||||
* @brief EBI NOR CFI typedef
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t cfi_1; /**< NOR CFI 1 */
|
||||
uint16_t cfi_2; /**< NOR CFI 2 */
|
||||
uint16_t cfi_3; /**< NOR CFI 3 */
|
||||
uint16_t cfi_4; /**< NOR CFI 4 */
|
||||
} nor_cfi_t;
|
||||
|
||||
/**
|
||||
* @brief NOR handle Structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
EBI_NOR_SRAM_TypeDef *instance; /**< Register base address */
|
||||
EBI_NOR_SRAM_EXTENDED_TypeDef *ext; /**< Extended mode register base address */
|
||||
ald_ebi_nor_sram_init_t init; /**< NOR device control configuration parameters */
|
||||
lock_state_t lock; /**< NOR locking object */
|
||||
__IO ald_nor_state_t state; /**< NOR device access state */
|
||||
} nor_handle_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup NOR_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
/** @addtogroup NOR_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
/* Initialization/de-initialization functions */
|
||||
ald_status_t ald_nor_init(nor_handle_t *hperh, ald_ebi_nor_sram_timing_t *timing, ald_ebi_nor_sram_timing_t *ext_timing);
|
||||
ald_status_t ald_nor_deinit(nor_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup NOR_LCD_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
/* I/O operation functions */
|
||||
ald_status_t ald_nor_read_id(nor_handle_t *hperh, nor_id_t *id);
|
||||
ald_status_t ald_nor_return_readmode(nor_handle_t *hperh);
|
||||
ald_status_t ald_nor_read(nor_handle_t *hperh, uint32_t *addr, uint16_t *data);
|
||||
ald_status_t ald_nor_program(nor_handle_t *hperh, uint32_t *addr, uint16_t *data);
|
||||
ald_status_t ald_nor_read_buffer(nor_handle_t *hperh, uint32_t addr, uint16_t *data, uint32_t size);
|
||||
ald_status_t ald_nor_program_buffer(nor_handle_t *hperh, uint32_t addr, uint16_t *data, uint32_t size);
|
||||
ald_status_t ald_nor_erase_block(nor_handle_t *hperh, uint32_t blkaddr, uint32_t addr);
|
||||
ald_status_t ald_nor_erase_chip(nor_handle_t *hperh);
|
||||
ald_status_t ald_nor_read_cfi(nor_handle_t *hperh, nor_cfi_t *cfi);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup NOR_LCD_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
/* Control functions */
|
||||
ald_status_t ald_nor_write_enable(nor_handle_t *hperh);
|
||||
ald_status_t ald_nor_write_disable(nor_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup NOR_LCD_Public_Functions_Group4
|
||||
* @{
|
||||
*/
|
||||
/* State functions */
|
||||
ald_nor_state_t ald_nor_get_state(nor_handle_t *hperh);
|
||||
nor_status_t ald_nor_get_status(nor_handle_t *hperh, uint32_t addr, uint32_t timeout);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_NOR_LCD_H__ */
|
||||
@@ -1,727 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_pis.h
|
||||
* @brief Header file of PIS driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 27 Nov 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 27 Nov 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_PIS_H__
|
||||
#define __ALD_PIS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PIS_Public_Types PIS Public Types
|
||||
* @verbatim
|
||||
In PIS module, for the convenience of code maintenance,
|
||||
TIMERx is used to indicate the sequence of the timer peripheral.
|
||||
Different product series TIMERx represent different meanings:
|
||||
1. For ES32F36xx series:
|
||||
TIMER0 ----> AD16C4T0
|
||||
TIMER1 ----> AD16C4T1
|
||||
TIMER2 ----> GP32C4T0
|
||||
TIMER3 ----> GP32C4T1
|
||||
|
||||
2. For ES32F393x/ES32F336x/ES32F392x series:
|
||||
TIMER0 ----> GP16C4T0
|
||||
TIMER1 ----> GP16C4T1
|
||||
TIMER2 ----> GP32C4T0
|
||||
TIMER3 ----> GP32C4T1
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Producer entry
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_NON = 0x0U, /**< No async */
|
||||
PIS_GPIO_PIN0 = 0x10U, /**< Pin0, level,support async */
|
||||
PIS_GPIO_PIN1 = 0x11U, /**< Pin1, level,support async */
|
||||
PIS_GPIO_PIN2 = 0x12U, /**< Pin2, level,support async */
|
||||
PIS_GPIO_PIN3 = 0x13U, /**< Pin3, level,support async */
|
||||
PIS_GPIO_PIN4 = 0x14U, /**< Pin4, level,support async */
|
||||
PIS_GPIO_PIN5 = 0x15U, /**< Pin5, level,support async */
|
||||
PIS_GPIO_PIN6 = 0x16U, /**< Pin6, level,support async */
|
||||
PIS_GPIO_PIN7 = 0x17U, /**< Pin7, level,support async */
|
||||
PIS_GPIO_PIN8 = 0x18U, /**< Pin8, level,support async */
|
||||
PIS_GPIO_PIN9 = 0x19U, /**< Pin9, level,support async */
|
||||
PIS_GPIO_PIN10 = 0x1aU, /**< Pin10, level,support async */
|
||||
PIS_GPIO_PIN11 = 0x1bU, /**< Pin11, level,support async */
|
||||
PIS_GPIO_PIN12 = 0x1cU, /**< Pin12, level,support async */
|
||||
PIS_GPIO_PIN13 = 0x1dU, /**< Pin13, level,support async */
|
||||
PIS_GPIO_PIN14 = 0x1eU, /**< Pin14, level,support async */
|
||||
PIS_GPIO_PIN15 = 0x1fU, /**< Pin15, level,support async */
|
||||
PIS_ACMP_OUT0 = 0x30U, /**< Acmp0 output, level,support async */
|
||||
PIS_ACMP_OUT1 = 0x31U, /**< Acmp1 output, level,support async */
|
||||
PIS_DAC0_CH0 = 0x40U, /**< Dac0 channel 0, pclk2 pulse,support async */
|
||||
PIS_DAC0_CH1 = 0x41U, /**< Dac0 channel 1, pclk2 pulse,support async */
|
||||
PIS_ADC0_INSERT = 0x60U, /**< Adc0 insert, pclk2 pulse,support async */
|
||||
PIS_ADC0_NORMAL = 0x61U, /**< Adc0 normal, pclk2 pulse,support async */
|
||||
PIS_ADC0_RESERVE = 0x62U, /**< Adc0 reserve */
|
||||
PIS_LVD = 0x70U, /**< Lvd, level,support async */
|
||||
PIS_UART0_RESERVE0 = 0x80U, /**< Uart0 reserve bit 0 */
|
||||
PIS_UART0_RESERVE1 = 0x81U, /**< Uart0 reserve bit 1*/
|
||||
PIS_UART0_IRDAOUT = 0x82U, /**< Uart0 irdaout, level,support async */
|
||||
PIS_UART0_RTSOUT = 0x83U, /**< Uart0 rtsout, level,support async */
|
||||
PIS_UART0_TXOUT = 0x84U, /**< Uart0 txout, level,support async */
|
||||
PIS_UART0_SYN_SEND = 0x85U, /**< Uart0 syn send, pulse,support async */
|
||||
PIS_UART0_SYN_RECV = 0x86U, /**< Uart0 syn recv, pulse,support async */
|
||||
PIS_UART1_RESERVE0 = 0x90U, /**< Uart1 reserve bit 0 */
|
||||
PIS_UART1_RESERVE1 = 0x91U, /**< Uart1 reserve bit 1*/
|
||||
PIS_UART1_IRDA = 0x92U, /**< Uart1 irdaout, level,support async */
|
||||
PIS_UART1_RTS = 0x93U, /**< Uart1 rtsout, level,support async */
|
||||
PIS_UART1_TXOUT = 0x94U, /**< Uart1 txout, level,support async */
|
||||
PIS_UART1_SYN_SEND = 0x95U, /**< Uart1 syn send, pulse,support async */
|
||||
PIS_UART1_SYN_RECV = 0x96U, /**< Uart1 syn recv, pulse,support async */
|
||||
PIS_UART2_RESERVE0 = 0xa0U, /**< Uart2 reserve bit 0 */
|
||||
PIS_UART2_RESERVE1 = 0xa1U, /**< Uart2 reserve bit 1*/
|
||||
PIS_UART2_IRDA = 0xa2U, /**< Uart2 irdaout, level,support async */
|
||||
PIS_UART2_RTS = 0xa3U, /**< Uart2 rtsout, level,support async */
|
||||
PIS_UART2_TXOUT = 0xa4U, /**< Uart2 txout, level,support async */
|
||||
PIS_UART2_SYN_SEND = 0xa5U, /**< Uart2 syn send, pulse,support async */
|
||||
PIS_UART2_SYN_RECV = 0xa6U, /**< Uart2 syn recv, pulse,support async */
|
||||
PIS_UART3_RESERVE0 = 0xb1U, /**< Uart3 reserve bit 0 */
|
||||
PIS_UART3_RESERVE1 = 0xb2U, /**< Uart3 reserve bit 1*/
|
||||
PIS_UART3_IRDA = 0xb3U, /**< Uart3 irdaout, level,support async */
|
||||
PIS_UART3_RTS = 0xb4U, /**< Uart3 rtsout, level,support async */
|
||||
PIS_UART3_TXOUT = 0xb5U, /**< Uart3 txout, level,support async */
|
||||
PIS_UART3_SYN_SEND = 0xb6U, /**< Uart3 syn send, pulse,support async */
|
||||
PIS_UART3_SYN_RECV = 0xb7U, /**< Uart3 syn recv, pulse,support async */
|
||||
PIS_UART4_RECV = 0xc0U, /**< uart4 recv, plck1 pulse */
|
||||
PIS_UART4_SEND = 0xc1U, /**< uart4 send, plck1 pulse */
|
||||
PIS_UART4_TXOUT = 0xc2U, /**< uart4 txout, plck1 level */
|
||||
PIS_UART5_RECV = 0xd0U, /**< uart5 recv, plck1 pulse */
|
||||
PIS_UART5_SEND = 0xd1U, /**< uart5 send, plck1 pulse */
|
||||
PIS_UART5_TXOUT = 0xd2U, /**< uart5 txout, plck1 level */
|
||||
PIS_SPI0_RECV = 0xe0U, /**< Spi0 recv, plck1 pulse */
|
||||
PIS_SPI0_SEND = 0xe1U, /**< Spi0 send, plck1 pulse */
|
||||
PIS_SPI0_NE = 0xe2U, /**< Spi0 ne, plck1 level */
|
||||
PIS_SPI1_RECV = 0xf0U, /**< Spi1 recv, plck1 pulse */
|
||||
PIS_SPI1_SEND = 0xf1U, /**< Spi1 send, plck1 pulse */
|
||||
PIS_SPI1_NE = 0xf2U, /**< Spi1 ne, plck1 level */
|
||||
PIS_I2C0_RECV = 0x100U, /**< I2c0 recv, plck1 level */
|
||||
PIS_I2C0_SEND = 0x101U, /**< I2c0 send, plck1 level */
|
||||
PIS_I2C1_RECV = 0x110U, /**< I2c1 recv, plck1 level */
|
||||
PIS_I2C1_SEND = 0x111U, /**< I2c1 send, plck1 level */
|
||||
PIS_TIMER0_UPDATA = 0x120U, /**< Timer0 updata, plck1 pulse */
|
||||
PIS_TIMER0_TRIG = 0x121U, /**< Timer0 trig, plck1 pulse */
|
||||
PIS_TIMER0_INPUT_1 = 0x122U, /**< Timer0 chan1 input catch, plck1 pulse */
|
||||
PIS_TIMER0_OUTPUT_1 = 0x123U, /**< Timer0 chan1 output compare, plck1 pulse */
|
||||
PIS_TIMER0_INPUT_2 = 0x124U, /**< Timer0 chan2 input catch, plck1 pulse */
|
||||
PIS_TIMER0_OUTPUT_2 = 0x125U, /**< Timer0 chan2 output compare, plck1 pulse */
|
||||
PIS_TIMER0_INPUT_3 = 0x126U, /**< Timer0 chan3 input catch, plck1 pulse */
|
||||
PIS_TIMER0_OUTPUT_3 = 0x127U, /**< Timer0 chan3 output compare, plck1 pulse */
|
||||
PIS_TIMER0_INPUT_4 = 0x128U, /**< Timer0 chan4 input catch, plck1 pulse */
|
||||
PIS_TIMER0_OUTPUT_4 = 0x129U, /**< Timer0 chan4 output compare, plck1 pulse */
|
||||
PIS_TIMER1_UPDATA = 0x130U, /**< Timer1 updata, plck1 pulse */
|
||||
PIS_TIMER1_TRIG = 0x131U, /**< Timer1 trig, plck1 pulse */
|
||||
PIS_TIMER1_INPUT_1 = 0x132U, /**< Timer1 chan1 input catch, plck1 pulse */
|
||||
PIS_TIMER1_OUTPUT_1 = 0x133U, /**< Timer1 chan1 output compare, plck1 pulse */
|
||||
PIS_TIMER1_INPUT_2 = 0x134U, /**< Timer1 chan2 input catch, plck1 pulse */
|
||||
PIS_TIMER1_OUTPUT_2 = 0x135U, /**< Timer1 chan2 output compare, plck1 pulse */
|
||||
PIS_TIMER1_INPUT_3 = 0x136U, /**< Timer1 chan3 input catch, plck1 pulse */
|
||||
PIS_TIMER1_OUTPUT_3 = 0x137U, /**< Timer1 chan3 output compare, plck1 pulse */
|
||||
PIS_TIMER1_INPUT_4 = 0x138U, /**< Timer1 chan4 input catch, plck1 pulse */
|
||||
PIS_TIMER1_OUTPUT_4 = 0x139U, /**< Timer1 chan4 output compare, plck1 pulse */
|
||||
PIS_TIMER2_UPDATA = 0x140U, /**< Timer2 updata, plck1 pulse */
|
||||
PIS_TIMER2_TRIG = 0x141U, /**< Timer2 trig, plck1 pulse */
|
||||
PIS_TIMER2_INPUT_1 = 0x142U, /**< Timer2 chan1 input catch, plck1 pulse */
|
||||
PIS_TIMER2_OUTPUT_1 = 0x143U, /**< Timer2 chan1 output compare, plck1 pulse */
|
||||
PIS_TIMER2_INPUT_2 = 0x144U, /**< Timer2 chan2 input catch, plck1 pulse */
|
||||
PIS_TIMER2_OUTPUT_2 = 0x145U, /**< Timer2 chan2 output compare, plck1 pulse */
|
||||
PIS_TIMER2_INPUT_3 = 0x146U, /**< Timer2 chan3 input catch, plck1 pulse */
|
||||
PIS_TIMER2_OUTPUT_3 = 0x147U, /**< Timer2 chan3 output compare, plck1 pulse */
|
||||
PIS_TIMER2_INPUT_4 = 0x148U, /**< Timer2 chan4 input catch, plck1 pulse */
|
||||
PIS_TIMER2_OUTPUT_4 = 0x149U, /**< Timer2 chan4 output compare, plck1 pulse */
|
||||
PIS_TIMER3_UPDATA = 0x150U, /**< Timer3 updata, plck1 pulse */
|
||||
PIS_TIMER3_TRIG = 0x151U, /**< Timer3 trig, plck1 pulse */
|
||||
PIS_TIMER3_INPUT_1 = 0x152U, /**< Timer3 chan1 input catch, plck1 pulse */
|
||||
PIS_TIMER3_OUTPUT_1 = 0x153U, /**< Timer3 chan1 output compare, plck1 pulse */
|
||||
PIS_TIMER3_INPUT_2 = 0x154U, /**< Timer3 chan2 input catch, plck1 pulse */
|
||||
PIS_TIMER3_OUTPUT_2 = 0x155U, /**< Timer3 chan2 output compare, plck1 pulse */
|
||||
PIS_TIMER3_INPUT_3 = 0x156U, /**< Timer3 chan3 input catch, plck1 pulse */
|
||||
PIS_TIMER3_OUTPUT_3 = 0x157U, /**< Timer3 chan3 output compare, plck1 pulse */
|
||||
PIS_TIMER3_INPUT_4 = 0x158U, /**< Timer3 chan4 input catch, plck1 pulse */
|
||||
PIS_TIMER3_OUTPUT_4 = 0x159U, /**< Timer3 chan4 output compare, plck1 pulse */
|
||||
PIS_RTC_CLOCK = 0x160U, /**< Rtc clock, pulse,support async */
|
||||
PIS_RTC_ALARM = 0x161U, /**< Rtc alarm, pulse,support async */
|
||||
PIS_LPTIMER0_SYN_UPDATA = 0x170U, /**< Lptimer0 syn updata, pulse,support async */
|
||||
PIS_LPTIMER0_ASY_UPDATA = 0x171U, /**< Lptimer0 asy updata, pulse,support async */
|
||||
PIS_LPUART0_ASY_RECV = 0x180U, /**< Lpuart0 asy recv, pulse,support async */
|
||||
PIS_LPUART0_ASY_SEND = 0x181U, /**< Lpuart0 asy send, pulse,support async */
|
||||
PIS_LPUART0_SYN_RECV = 0x182U, /**< Lpuart0 syn recv, pulse,support async */
|
||||
PIS_LPUART0_SYN_SEND = 0x183U, /**< Lpuart0 syn recv, pulse,support async */
|
||||
PIS_DMA = 0x190U, /**< Dma, pulse,support async */
|
||||
PIS_ADC1_INSERT = 0x1a0U, /**< Adc1 insert, pclk2 pulse,support async */
|
||||
PIS_ADC1_NORMAL = 0x1a1U, /**< Adc1 normal, pclk2 pulse,support async */
|
||||
PIS_ADC1_RESERVE = 0x1a2U, /**< Adc1 reserve */
|
||||
} pis_src_t;
|
||||
|
||||
/**
|
||||
* @brief Consumer entry
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_CH12_TIMER0_ITR0 = 0x003CU, /** Tim0 internal input chan0 */
|
||||
PIS_CH13_TIMER0_ITR1 = 0x003DU, /** Tim0 internal input chan1 */
|
||||
PIS_CH14_TIMER0_ITR2 = 0x003EU, /** Tim0 internal input chan2 */
|
||||
PIS_CH15_TIMER0_ITR3 = 0x003FU, /** Tim0 internal input chan3 */
|
||||
PIS_CH12_TIMER1_ITR0 = 0x003CU, /** Tim1 internal input chan0 */
|
||||
PIS_CH13_TIMER1_ITR1 = 0x003DU, /** Tim1 internal input chan1 */
|
||||
PIS_CH14_TIMER1_ITR2 = 0x003EU, /** Tim1 internal input chan2 */
|
||||
PIS_CH15_TIMER1_ITR3 = 0x003FU, /** Tim1 internal input chan3 */
|
||||
PIS_CH12_TIMER2_ITR0 = 0x003CU, /** Tim2 internal input chan0 */
|
||||
PIS_CH13_TIMER2_ITR1 = 0x003DU, /** Tim2 internal input chan1 */
|
||||
PIS_CH14_TIMER2_ITR2 = 0x003EU, /** Tim2 internal input chan2 */
|
||||
PIS_CH15_TIMER2_ITR3 = 0x003FU, /** Tim2 internal input chan3 */
|
||||
PIS_CH12_TIMER3_ITR0 = 0x003CU, /** Tim3 internal input chan0 */
|
||||
PIS_CH13_TIMER3_ITR1 = 0x003DU, /** Tim3 internal input chan1 */
|
||||
PIS_CH14_TIMER3_ITR2 = 0x003EU, /** Tim3 internal input chan2 */
|
||||
PIS_CH15_TIMER3_ITR3 = 0x003FU, /** Tim3 internal input chan3 */
|
||||
PIS_CH6_ADC0_NORMAL = 0x0036U, /** ADC0 normal transform */
|
||||
PIS_CH7_ADC0_INSERT = 0x0037U, /** ADC0 insert transform */
|
||||
PIS_CH0_ADC1_NORMAL = 0x0030U, /** ADC1 normal transform */
|
||||
PIS_CH1_ADC1_INSERT = 0x0031U, /** ADC1 insert transform */
|
||||
PIS_CH0_LPTIM0_EXT0 = 0x0030U, /** Lptim0 external trigger 0 */
|
||||
PIS_CH1_LPTIM0_EXT1 = 0x0031U, /** Lptim0 external trigger 1 */
|
||||
PIS_CH2_LPTIM0_EXT2 = 0x0032U, /** Lptim0 external trigger 2 */
|
||||
PIS_CH3_LPTIM0_EXT3 = 0x0033U, /** Lptim0 external trigger 3 */
|
||||
PIS_CH4_LPTIM0_EXT4 = 0x0034U, /** Lptim0 external trigger 4 */
|
||||
PIS_CH5_LPTIM0_EXT5 = 0x0035U, /** Lptim0 external trigger 5 */
|
||||
PIS_CH6_LPTIM0_EXT6 = 0x0036U, /** Lptim0 external trigger 6 */
|
||||
PIS_CH7_LPTIM0_EXT7 = 0x0037U, /** Lptim0 external trigger 7 */
|
||||
PIS_CH7_DMA_REQUEST = 0x0037U, /** DMA request 7 */
|
||||
PIS_CH15_LPUART0_RXD = 0x081FU, /**< Lpuart Rx data */
|
||||
PIS_CH14_UART5_RXD = 0x071EU, /**< Uart5 Rx data */
|
||||
PIS_CH13_UART4_RXD = 0x061DU, /**< Uart4 Rx data */
|
||||
PIS_CH12_UART3_RXD = 0x031CU, /**< Uart3 Rx data */
|
||||
PIS_CH11_UART2_RXD = 0x021BU, /**< Uart2 Rx data */
|
||||
PIS_CH10_UART1_RXD = 0x011AU, /**< Uart1 Rx data */
|
||||
PIS_CH9_UART0_RXD = 0x0019U, /**< Uart0 Rx data */
|
||||
PIS_CH8_TIMER3_CH4IN = 0x1B08U, /**< Tim3 input chan4 */
|
||||
PIS_CH8_TIMER2_CH4IN = 0x1308U, /**< Tim2 input chan4 */
|
||||
PIS_CH8_SPI1_CLK = 0x0F18U, /**< Spi1 clk */
|
||||
PIS_CH7_TIMER3_CH3IN = 0x1A07U, /**< Tim3 input chan3 */
|
||||
PIS_CH7_TIMER2_CH3IN = 0x1207U, /**< Tim2 input chan3 */
|
||||
PIS_CH7_SPI1_RX = 0x0E17U, /**< Spi1 rx */
|
||||
PIS_CH6_TIMER3_CH2IN = 0x1906U, /**< Tim3 input chan2 */
|
||||
PIS_CH6_TIMER2_CH2IN = 0x1106U, /**< Tim2 input chan2 */
|
||||
PIS_CH6_SPI0_CLK = 0x0D16U, /**< SPI0 CLK */
|
||||
PIS_CH5_TIMER3_CH1IN = 0x1805U, /**< Tim3 input chan1 */
|
||||
PIS_CH5_TIMER2_CH1IN = 0x1005U, /**< Tim2 input chan1 */
|
||||
PIS_CH5_SPI0_RX = 0x0C15U, /**< SPI0 RX */
|
||||
PIS_CH4_TIMER1_CH4IN = 0x0B04U, /**< Tim1 input chan4 */
|
||||
PIS_CH4_TIMER0_CH4IN = 0x0304U, /**< Tim0 input chan4 */
|
||||
PIS_CH3_TIMER1_CH3IN = 0x0A03U, /**< Tim1 input chan3 */
|
||||
PIS_CH3_TIMER0_CH3IN = 0x0203U, /**< Tim0 input chan3 */
|
||||
PIS_CH2_TIMER1_CH2IN = 0x0902U, /**< Tim1 input chan2 */
|
||||
PIS_CH2_TIMER0_CH2IN = 0x0102U, /**< Tim0 input chan2 */
|
||||
PIS_CH1_TIMER1_CH1IN = 0x0801U, /**< Tim1 input chan1 */
|
||||
PIS_CH0_TIMER0_CH1IN = 0x0000U, /**< Tim0 input chan1 */
|
||||
PIS_CH0_TIMER0_BRKIN = 0x0400U, /**< Tim0 break in */
|
||||
PIS_CH0_TIMER1_BRKIN = 0x0C00U, /**< Tim1 break in */
|
||||
PIS_TRIG_RESERVE = 0xFFFFU, /**< Other Consumer */
|
||||
} pis_trig_t;
|
||||
|
||||
/**
|
||||
* @brief Clock select
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_CLK_PCLK1 = 0U, /**< APB1 peripherals clock */
|
||||
PIS_CLK_PCLK2 = 1U, /**< APB2 peripherals clock */
|
||||
PIS_CLK_SYS = 2U, /**< AHB peripherals clock */
|
||||
PIS_CLK_RESERVE = 3U, /**< reserve clock */
|
||||
} pis_clock_t;
|
||||
|
||||
/**
|
||||
* @brief Level select
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_EDGE_NONE = 0U, /**< None edge */
|
||||
PIS_EDGE_UP = 1U, /**< Up edge */
|
||||
PIS_EDGE_DOWN = 2U, /**< Down edge */
|
||||
PIS_EDGE_UP_DOWN = 3U, /**< Up and down edge */
|
||||
} pis_edge_t;
|
||||
|
||||
/**
|
||||
* @brief Output style
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_OUT_LEVEL = 0U, /**< Level */
|
||||
PIS_OUT_PULSE = 1U, /**< Pulse */
|
||||
} pis_output_t;
|
||||
/**
|
||||
* @brief Sync select
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_SYN_DIRECT = 0U, /**< Direct */
|
||||
PIS_SYN_LEVEL_ASY_APB1 = 1U, /**< Producer level signal and Consumer in APB1 */
|
||||
PIS_SYN_LEVEL_ASY_APB2 = 2U, /**< Producer level signal and Consumer in APB2 */
|
||||
PIS_SYN_LEVEL_ASY_AHB = 3U, /**< Producer level signal and Consumer in AHB */
|
||||
PIS_SYN_PULSE_ASY_APB1 = 4U, /**< Producer Pulse signal and Consumer in APB1 */
|
||||
PIS_SYN_PULSE_ASY_APB2 = 5U, /**< Producer Pulse signal and Consumer in APB2 */
|
||||
PIS_SYN_PULSE_ASY_AHB = 6U, /**< Producer Pulse signal and Consumer in AHB */
|
||||
} pis_syncsel_t;
|
||||
|
||||
/**
|
||||
* @brief Pis channel
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_CH_0 = 0U, /**< Channel 0 */
|
||||
PIS_CH_1 = 1U, /**< Channel 1 */
|
||||
PIS_CH_2 = 2U, /**< Channel 2 */
|
||||
PIS_CH_3 = 3U, /**< Channel 3 */
|
||||
PIS_CH_4 = 4U, /**< Channel 4 */
|
||||
PIS_CH_5 = 5U, /**< Channel 5 */
|
||||
PIS_CH_6 = 6U, /**< Channel 6 */
|
||||
PIS_CH_7 = 7U, /**< Channel 7 */
|
||||
PIS_CH_8 = 8U, /**< Channel 8 */
|
||||
PIS_CH_9 = 9U, /**< Channel 9 */
|
||||
PIS_CH_10 = 10U,/**< Channel 10 */
|
||||
PIS_CH_11 = 11U,/**< Channel 11 */
|
||||
PIS_CH_12 = 12U,/**< Channel 12 */
|
||||
PIS_CH_13 = 13U,/**< Channel 13 */
|
||||
PIS_CH_14 = 14U,/**< Channel 14 */
|
||||
PIS_CH_15 = 15U,/**< Channel 15 */
|
||||
} pis_ch_t;
|
||||
|
||||
/**
|
||||
* @brief Pis output channel
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_OUT_CH_0 = 0U, /**< Channel 0 */
|
||||
PIS_OUT_CH_1 = 1U, /**< Channel 1 */
|
||||
PIS_OUT_CH_2 = 2U, /**< Channel 2 */
|
||||
PIS_OUT_CH_3 = 3U, /**< Channel 3 */
|
||||
} pis_out_ch_t;
|
||||
|
||||
/**
|
||||
* @brief Indirect value,no care of it.
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_CON_0 = 0U, /**< Con 0 */
|
||||
PIS_CON_1 = 1U, /**< Con 1 */
|
||||
PIS_CON_NONE = 2U, /**< None */
|
||||
} pis_con_t;
|
||||
|
||||
/**
|
||||
* @brief PIS state structures definition
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_STATE_RESET = 0x00U, /**< Peripheral is not initialized */
|
||||
PIS_STATE_READY = 0x01U, /**< Peripheral Initialized and ready for use */
|
||||
PIS_STATE_BUSY = 0x02U, /**< An internal process is ongoing */
|
||||
PIS_STATE_TIMEOUT = 0x03U, /**< Timeout state */
|
||||
PIS_STATE_ERROR = 0x04U, /**< Error */
|
||||
} pis_state_t;
|
||||
|
||||
/**
|
||||
* @brief PIS modulate target
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_UART0_TX = 0U, /**< Modulate uart0 tx */
|
||||
PIS_UART1_TX = 1U, /**< Modulate uart1 tx */
|
||||
PIS_UART2_TX = 2U, /**< Modulate uart2 tx */
|
||||
PIS_UART3_TX = 3U, /**< Modulate uart3 tx */
|
||||
PIS_LPUART0_TX = 4U, /**< Modulate lpuart0 tx */
|
||||
} pis_modu_targ_t;
|
||||
|
||||
/**
|
||||
* @brief PIS modulate level
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_LOW_LEVEL = 0U, /**< Modulate low level */
|
||||
PIS_HIGH_LEVEL = 1U, /**< Modulate high level */
|
||||
} pis_modu_level_t;
|
||||
|
||||
/**
|
||||
* @brief PIS modulate source
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_SRC_NONE = 0U, /**< Stop modulate */
|
||||
PIS_SRC_TIMER0 = 1U, /**< Modulate source is TIMER0 */
|
||||
PIS_SRC_TIMER1 = 2U, /**< Modulate source is TIMER1 */
|
||||
PIS_SRC_TIMER2 = 3U, /**< Modulate source is TIMER2 */
|
||||
PIS_SRC_TIMER3 = 4U, /**< Modulate source is TIMER3 */
|
||||
PIS_SRC_TIMER6 = 5U, /**< Modulate source is TIMER6 */
|
||||
PIS_SRC_TIMER7 = 6U, /**< Modulate source is TIMER7 */
|
||||
PIS_SRC_LPTIM0 = 7U, /**< Modulate source is LPTIM0 */
|
||||
PIS_SRC_BUZ = 8U, /**< Modulate source is buz */
|
||||
} pis_modu_src_t;
|
||||
|
||||
/**
|
||||
* @brief PIS modulate channel
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_TIMER_CH1 = 0U, /**< Src is TIMERx and choose channel 1 */
|
||||
PIS_TIMER_CH2 = 1U, /**< Src is TIMERx and choose channel 2 */
|
||||
PIS_TIMER_CH3 = 2U, /**< Src is TIMERx and choose channel 3 */
|
||||
PIS_TIMER_CH4 = 3U, /**< Src is TIMERx and choose channel 4 */
|
||||
} pis_modu_channel_t;
|
||||
|
||||
/**
|
||||
* @brief PIS input channel chose
|
||||
*/
|
||||
typedef enum {
|
||||
PIS_NONE_INPUT = 0U, /**< Consumer input none */
|
||||
PIS_PORT_INPUT = 1U, /**< Consumer input choose external port */
|
||||
PIS_CHAN_INPUT = 2U, /**< Consumer input choose pis channel */
|
||||
} pis_input_sel_t;
|
||||
|
||||
/**
|
||||
* @brief PIS init structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
pis_src_t producer_src; /**< Producer entry */
|
||||
pis_output_t producer_signal; /**< Producer signal mode */
|
||||
pis_clock_t producer_clk; /**< Producer module clock */
|
||||
pis_edge_t producer_edge; /**< Producer module pin output edge */
|
||||
pis_trig_t consumer_trig; /**< Consumer entry */
|
||||
pis_clock_t consumer_clk; /**< Consumer clock */
|
||||
pis_input_sel_t input_chan; /**< Consumer input channel */
|
||||
} pis_init_t;
|
||||
|
||||
/**
|
||||
* @brief PIS modulate config structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
pis_modu_targ_t target; /**< Modulate target */
|
||||
pis_modu_level_t level; /**< Modulate level */
|
||||
pis_modu_src_t src; /**< Modulate src */
|
||||
pis_modu_channel_t channel; /**< Modulate channel */
|
||||
} pis_modulate_config_t;
|
||||
|
||||
/**
|
||||
* @brief PIS Handle Structure definition
|
||||
*/
|
||||
typedef struct pis_handle_s {
|
||||
PIS_TypeDef *perh; /**< Register base address */
|
||||
pis_init_t init; /**< PIS required parameters */
|
||||
pis_ch_t consumer_ch; /**< Indirect value, no care of it */
|
||||
pis_con_t consumer_con; /**< Indirect value, no care of it */
|
||||
uint8_t consumer_pos; /**< Indirect value, no care of it */
|
||||
uint32_t check_info; /**< When destroy a handle ,user need check whether is right that ready to destroy */
|
||||
lock_state_t lock; /**< Locking object */
|
||||
pis_state_t state; /**< PIS operation state */
|
||||
} pis_handle_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup PIS_Private_Macros PIS Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_PIS(x) (((x) == PIS))
|
||||
#define IS_PIS_SRC(x) (((x) == PIS_NON) || \
|
||||
((x) == PIS_GPIO_PIN0) || \
|
||||
((x) == PIS_GPIO_PIN1) || \
|
||||
((x) == PIS_GPIO_PIN2) || \
|
||||
((x) == PIS_GPIO_PIN3) || \
|
||||
((x) == PIS_GPIO_PIN4) || \
|
||||
((x) == PIS_GPIO_PIN5) || \
|
||||
((x) == PIS_GPIO_PIN6) || \
|
||||
((x) == PIS_GPIO_PIN7) || \
|
||||
((x) == PIS_GPIO_PIN8) || \
|
||||
((x) == PIS_GPIO_PIN9) || \
|
||||
((x) == PIS_GPIO_PIN10) || \
|
||||
((x) == PIS_GPIO_PIN11) || \
|
||||
((x) == PIS_GPIO_PIN12) || \
|
||||
((x) == PIS_GPIO_PIN13) || \
|
||||
((x) == PIS_GPIO_PIN14) || \
|
||||
((x) == PIS_GPIO_PIN15) || \
|
||||
((x) == PIS_ACMP_OUT0) || \
|
||||
((x) == PIS_ACMP_OUT1) || \
|
||||
((x) == PIS_DAC0_CH0) || \
|
||||
((x) == PIS_DAC0_CH1) || \
|
||||
((x) == PIS_ADC0_INSERT) || \
|
||||
((x) == PIS_ADC0_NORMAL) || \
|
||||
((x) == PIS_ADC0_RESERVE) || \
|
||||
((x) == PIS_LVD) || \
|
||||
((x) == PIS_UART0_RESERVE0) || \
|
||||
((x) == PIS_UART0_RESERVE1) || \
|
||||
((x) == PIS_UART0_IRDAOUT) || \
|
||||
((x) == PIS_UART0_RTSOUT) || \
|
||||
((x) == PIS_UART0_TXOUT) || \
|
||||
((x) == PIS_UART0_SYN_SEND) || \
|
||||
((x) == PIS_UART0_SYN_RECV) || \
|
||||
((x) == PIS_UART1_RESERVE0) || \
|
||||
((x) == PIS_UART1_RESERVE1) || \
|
||||
((x) == PIS_UART1_IRDA) || \
|
||||
((x) == PIS_UART1_RTS) || \
|
||||
((x) == PIS_UART1_TXOUT) || \
|
||||
((x) == PIS_UART1_SYN_SEND) || \
|
||||
((x) == PIS_UART1_SYN_RECV) || \
|
||||
((x) == PIS_UART2_RESERVE0) || \
|
||||
((x) == PIS_UART2_RESERVE1) || \
|
||||
((x) == PIS_UART2_IRDA) || \
|
||||
((x) == PIS_UART2_RTS) || \
|
||||
((x) == PIS_UART2_TXOUT) || \
|
||||
((x) == PIS_UART2_SYN_SEND) || \
|
||||
((x) == PIS_UART2_SYN_RECV) || \
|
||||
((x) == PIS_UART3_RESERVE0) || \
|
||||
((x) == PIS_UART3_RESERVE1) || \
|
||||
((x) == PIS_UART3_IRDA) || \
|
||||
((x) == PIS_UART3_RTS) || \
|
||||
((x) == PIS_UART3_TXOUT) || \
|
||||
((x) == PIS_UART3_SYN_SEND) || \
|
||||
((x) == PIS_UART3_SYN_RECV) || \
|
||||
((x) == PIS_UART4_RECV) || \
|
||||
((x) == PIS_UART4_SEND) || \
|
||||
((x) == PIS_UART4_TXOUT) || \
|
||||
((x) == PIS_UART5_RECV) || \
|
||||
((x) == PIS_UART5_SEND) || \
|
||||
((x) == PIS_UART5_TXOUT) || \
|
||||
((x) == PIS_SPI0_RECV) || \
|
||||
((x) == PIS_SPI0_SEND) || \
|
||||
((x) == PIS_SPI0_NE) || \
|
||||
((x) == PIS_SPI1_RECV) || \
|
||||
((x) == PIS_SPI1_SEND) || \
|
||||
((x) == PIS_SPI1_NE) || \
|
||||
((x) == PIS_I2C0_RECV) || \
|
||||
((x) == PIS_I2C0_SEND) || \
|
||||
((x) == PIS_I2C1_RECV) || \
|
||||
((x) == PIS_I2C1_SEND) || \
|
||||
((x) == PIS_TIMER0_UPDATA) || \
|
||||
((x) == PIS_TIMER0_TRIG) || \
|
||||
((x) == PIS_TIMER0_INPUT_1) || \
|
||||
((x) == PIS_TIMER0_OUTPUT_1) || \
|
||||
((x) == PIS_TIMER0_INPUT_2) || \
|
||||
((x) == PIS_TIMER0_OUTPUT_2) || \
|
||||
((x) == PIS_TIMER0_INPUT_3) || \
|
||||
((x) == PIS_TIMER0_OUTPUT_3) || \
|
||||
((x) == PIS_TIMER0_INPUT_4) || \
|
||||
((x) == PIS_TIMER0_OUTPUT_4) || \
|
||||
((x) == PIS_TIMER1_UPDATA) || \
|
||||
((x) == PIS_TIMER1_TRIG) || \
|
||||
((x) == PIS_TIMER1_INPUT_1) || \
|
||||
((x) == PIS_TIMER1_OUTPUT_1) || \
|
||||
((x) == PIS_TIMER1_INPUT_2) || \
|
||||
((x) == PIS_TIMER1_OUTPUT_2) || \
|
||||
((x) == PIS_TIMER1_INPUT_3) || \
|
||||
((x) == PIS_TIMER1_OUTPUT_3) || \
|
||||
((x) == PIS_TIMER1_INPUT_4) || \
|
||||
((x) == PIS_TIMER1_OUTPUT_4) || \
|
||||
((x) == PIS_TIMER2_UPDATA) || \
|
||||
((x) == PIS_TIMER2_TRIG) || \
|
||||
((x) == PIS_TIMER2_INPUT_1) || \
|
||||
((x) == PIS_TIMER2_OUTPUT_1) || \
|
||||
((x) == PIS_TIMER2_INPUT_2) || \
|
||||
((x) == PIS_TIMER2_OUTPUT_2) || \
|
||||
((x) == PIS_TIMER2_INPUT_3) || \
|
||||
((x) == PIS_TIMER2_OUTPUT_3) || \
|
||||
((x) == PIS_TIMER2_INPUT_4) || \
|
||||
((x) == PIS_TIMER2_OUTPUT_4) || \
|
||||
((x) == PIS_TIMER3_UPDATA) || \
|
||||
((x) == PIS_TIMER3_TRIG) || \
|
||||
((x) == PIS_TIMER3_INPUT_1) || \
|
||||
((x) == PIS_TIMER3_OUTPUT_1) || \
|
||||
((x) == PIS_TIMER3_INPUT_2) || \
|
||||
((x) == PIS_TIMER3_OUTPUT_2) || \
|
||||
((x) == PIS_TIMER3_INPUT_3) || \
|
||||
((x) == PIS_TIMER3_OUTPUT_3) || \
|
||||
((x) == PIS_TIMER3_INPUT_4) || \
|
||||
((x) == PIS_TIMER3_OUTPUT_4) || \
|
||||
((x) == PIS_RTC_CLOCK) || \
|
||||
((x) == PIS_RTC_ALARM) || \
|
||||
((x) == PIS_LPTIMER0_SYN_UPDATA) || \
|
||||
((x) == PIS_LPTIMER0_ASY_UPDATA) || \
|
||||
((x) == PIS_LPUART0_ASY_RECV) || \
|
||||
((x) == PIS_LPUART0_ASY_SEND) || \
|
||||
((x) == PIS_LPUART0_SYN_RECV) || \
|
||||
((x) == PIS_LPUART0_SYN_SEND) || \
|
||||
((x) == PIS_DMA) || \
|
||||
((x) == PIS_ADC1_INSERT) || \
|
||||
((x) == PIS_ADC1_NORMAL) || \
|
||||
((x) == PIS_ADC1_RESERVE))
|
||||
#define IS_PIS_TRIG(x) (((x) == PIS_CH12_TIMER0_ITR0) || \
|
||||
((x) == PIS_CH13_TIMER0_ITR1) || \
|
||||
((x) == PIS_CH14_TIMER0_ITR2) || \
|
||||
((x) == PIS_CH15_TIMER0_ITR3) || \
|
||||
((x) == PIS_CH12_TIMER1_ITR0) || \
|
||||
((x) == PIS_CH13_TIMER1_ITR1) || \
|
||||
((x) == PIS_CH14_TIMER1_ITR2) || \
|
||||
((x) == PIS_CH15_TIMER1_ITR3) || \
|
||||
((x) == PIS_CH12_TIMER2_ITR0) || \
|
||||
((x) == PIS_CH13_TIMER2_ITR1) || \
|
||||
((x) == PIS_CH14_TIMER2_ITR2) || \
|
||||
((x) == PIS_CH15_TIMER2_ITR3) || \
|
||||
((x) == PIS_CH12_TIMER3_ITR0) || \
|
||||
((x) == PIS_CH13_TIMER3_ITR1) || \
|
||||
((x) == PIS_CH14_TIMER3_ITR2) || \
|
||||
((x) == PIS_CH15_TIMER3_ITR3) || \
|
||||
((x) == PIS_CH6_ADC0_NORMAL ) || \
|
||||
((x) == PIS_CH7_ADC0_INSERT) || \
|
||||
((x) == PIS_CH0_ADC1_NORMAL) || \
|
||||
((x) == PIS_CH1_ADC1_INSERT) || \
|
||||
((x) == PIS_CH0_LPTIM0_EXT0) || \
|
||||
((x) == PIS_CH1_LPTIM0_EXT1) || \
|
||||
((x) == PIS_CH2_LPTIM0_EXT2) || \
|
||||
((x) == PIS_CH3_LPTIM0_EXT3) || \
|
||||
((x) == PIS_CH4_LPTIM0_EXT4) || \
|
||||
((x) == PIS_CH5_LPTIM0_EXT5) || \
|
||||
((x) == PIS_CH6_LPTIM0_EXT6) || \
|
||||
((x) == PIS_CH7_LPTIM0_EXT7) || \
|
||||
((x) == PIS_CH7_DMA_REQUEST) || \
|
||||
((x) == PIS_CH15_LPUART0_RXD) || \
|
||||
((x) == PIS_CH14_UART5_RXD) || \
|
||||
((x) == PIS_CH13_UART4_RXD) || \
|
||||
((x) == PIS_CH12_UART3_RXD) || \
|
||||
((x) == PIS_CH11_UART2_RXD) || \
|
||||
((x) == PIS_CH10_UART1_RXD) || \
|
||||
((x) == PIS_CH9_UART0_RXD) || \
|
||||
((x) == PIS_CH8_TIMER3_CH4IN) || \
|
||||
((x) == PIS_CH8_TIMER2_CH4IN) || \
|
||||
((x) == PIS_CH8_SPI1_CLK) || \
|
||||
((x) == PIS_CH7_TIMER3_CH3IN) || \
|
||||
((x) == PIS_CH7_TIMER2_CH3IN) || \
|
||||
((x) == PIS_CH7_SPI1_RX) || \
|
||||
((x) == PIS_CH6_TIMER3_CH2IN) || \
|
||||
((x) == PIS_CH6_TIMER2_CH2IN) || \
|
||||
((x) == PIS_CH6_SPI0_CLK) || \
|
||||
((x) == PIS_CH5_TIMER3_CH1IN) || \
|
||||
((x) == PIS_CH5_TIMER2_CH1IN) || \
|
||||
((x) == PIS_CH5_SPI0_RX) || \
|
||||
((x) == PIS_CH4_TIMER1_CH4IN) || \
|
||||
((x) == PIS_CH4_TIMER0_CH4IN) || \
|
||||
((x) == PIS_CH3_TIMER1_CH3IN) || \
|
||||
((x) == PIS_CH3_TIMER0_CH3IN) || \
|
||||
((x) == PIS_CH2_TIMER1_CH2IN) || \
|
||||
((x) == PIS_CH2_TIMER0_CH2IN) || \
|
||||
((x) == PIS_CH1_TIMER1_CH1IN) || \
|
||||
((x) == PIS_CH0_TIMER0_CH1IN) || \
|
||||
((x) == PIS_CH0_TIMER0_BRKIN) || \
|
||||
((x) == PIS_CH0_TIMER1_BRKIN) || \
|
||||
((x) == PIS_TRIG_RESERVE) || \
|
||||
((x) == PIS_CH8_SPI1_CLK))
|
||||
#define IS_PIS_CLOCK(x) (((x) == PIS_CLK_PCLK1) || \
|
||||
((x) == PIS_CLK_PCLK2) || \
|
||||
((x) == PIS_CLK_SYS))
|
||||
#define IS_PIS_SIGNAL_MODE(x) (((x) == PIS_OUT_LEVEL) || \
|
||||
((x) == PIS_OUT_PULSE))
|
||||
#define IS_PIS_EDGE(x) (((x) == PIS_EDGE_NONE) || \
|
||||
((x) == PIS_EDGE_UP) || \
|
||||
((x) == PIS_EDGE_DOWN) || \
|
||||
((x) == PIS_EDGE_UP_DOWN))
|
||||
#define IS_PIS_OUTPUT(x) (((x) == PIS_OUT_LEVEL) || \
|
||||
((x) == PIS_OUT_PULSE))
|
||||
#define IS_PIS_OUPUT_CH(x) (((x) == PIS_OUT_CH_0) || \
|
||||
((x) == PIS_OUT_CH_1) || \
|
||||
((x) == PIS_OUT_CH_2) || \
|
||||
((x) == PIS_OUT_CH_3))
|
||||
#define IS_PIS_MODU_TARGET(x) (((x) == PIS_UART0_TX) || \
|
||||
((x) == PIS_UART1_TX) || \
|
||||
((x) == PIS_UART2_TX) || \
|
||||
((x) == PIS_UART3_TX) || \
|
||||
((x) == PIS_LPUART0_TX))
|
||||
#define IS_PIS_MODU_LEVEL(x) (((x) == PIS_LOW_LEVEL) || \
|
||||
((x) == PIS_HIGH_LEVEL))
|
||||
#define IS_PIS_MODU_SRC(x) (((x) == PIS_SRC_NONE) || \
|
||||
((x) == PIS_SRC_TIMER0) || \
|
||||
((x) == PIS_SRC_TIMER1) || \
|
||||
((x) == PIS_SRC_TIMER2) || \
|
||||
((x) == PIS_SRC_TIMER3) || \
|
||||
((x) == PIS_SRC_TIMER6) || \
|
||||
((x) == PIS_SRC_TIMER7) || \
|
||||
((x) == PIS_SRC_LPTIM0) || \
|
||||
((x) == PIS_SRC_BUZ))
|
||||
#define IS_PIS_MODU_CHANNEL(x) (((x) == PIS_TIMER_CH1) || \
|
||||
((x) == PIS_TIMER_CH2) || \
|
||||
((x) == PIS_TIMER_CH3) || \
|
||||
((x) == PIS_TIMER_CH4))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup PIS_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PIS_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_pis_create(pis_handle_t *hperh);
|
||||
ald_status_t ald_pis_destroy(pis_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup PIS_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_pis_output_start(pis_handle_t *hperh, pis_out_ch_t ch);
|
||||
ald_status_t ald_pis_output_stop(pis_handle_t *hperh, pis_out_ch_t ch);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup PIS_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
pis_state_t ald_pis_get_state(pis_handle_t *hperh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup PIS_Public_Functions_Group4
|
||||
* @{
|
||||
*/
|
||||
ald_status_t ald_pis_modu_config(pis_handle_t *hperh, pis_modulate_config_t *config);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_PIS_H__ */
|
||||
@@ -1,309 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_pmu.h
|
||||
* @brief Header file of PMU module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 04 Dec 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 04 Dec 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_PMU_H__
|
||||
#define __ALD_PMU_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "ald_syscfg.h"
|
||||
#include "ald_bkpc.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PMU
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PMU_Public_Macros PMU Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define PMU_LPSTOP_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(PMU->CR0, PMU_CR0_LPSTOP_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define PMU_LPSTOP_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(PMU->CR0, PMU_CR0_LPSTOP_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define PMU_FLASH_MODE_IDLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(PMU->CR0, PMU_CR0_SFPD_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define PMU_FLASH_MODE_WAIT() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(PMU->CR0, PMU_CR0_SFPD_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define PMU_MTSTOP_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(PMU->CR0, PMU_CR0_MTSTOP_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define PMU_MTSTOP_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(PMU->CR0, PMU_CR0_MTSTOP_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define PMU_VREF_ENABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
SET_BIT(PMU->VREFCR, PMU_VREFCR_VREFEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
#define PMU_VREF_DISABLE() \
|
||||
do { \
|
||||
SYSCFG_UNLOCK(); \
|
||||
CLEAR_BIT(PMU->VREFCR, PMU_VREFCR_VREFEN_MSK); \
|
||||
SYSCFG_LOCK(); \
|
||||
} while (0)
|
||||
|
||||
#define PMU_GET_LVD_STATUS() (READ_BITS(PMU->LVDCR, PMU_LVDCR_LVDO_MSK, PMU_LVDCR_LVDO_POS))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup PMU_Public_Types PMU Public Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Low power mode
|
||||
*/
|
||||
typedef enum {
|
||||
PMU_LP_STOP1 = 0x0U, /**< Stop1 */
|
||||
PMU_LP_STOP2 = 0x1U, /**< Stop2 */
|
||||
PMU_LP_STANDBY = 0x2U, /**< Standby */
|
||||
} pmu_lp_mode_t;
|
||||
|
||||
/**
|
||||
* @brief LDO_18 mode
|
||||
*/
|
||||
typedef enum {
|
||||
PMU_LDO_18_DRV_HIGH = 0x0U, /**< High drive */
|
||||
PMU_LDO_18_DRV_LOW = 0x1U, /**< Low drive */
|
||||
PMU_LDO_18_HOLD = 0x2U, /**< Hold */
|
||||
PMU_LDO_18_OFF = 0x3U, /**< Turn off */
|
||||
} pmu_ldo_18_mode_t;
|
||||
|
||||
typedef enum {
|
||||
PMU_SR_WUF = (1U << 0), /**< WakeUp status */
|
||||
PMU_SR_STANDBYF = (1U << 1), /**< Standby status */
|
||||
PMU_SR_USBRDY = (1U << 2), /**< USB Readby status */
|
||||
PMU_SR_RSTAT = (1U << 3), /**< RUN/LPRUAN status */
|
||||
} pmu_status_t;
|
||||
|
||||
/**
|
||||
* @brief LVD voltage select
|
||||
*/
|
||||
typedef enum {
|
||||
PMU_LVD_VOL_SEL_2_2 = 0x0U, /**< 2.2V ~ 2.25V */
|
||||
PMU_LVD_VOL_SEL_2_4 = 0x1U, /**< 2.4V ~ 2.45V */
|
||||
PMU_LVD_VOL_SEL_2_6 = 0x2U, /**< 2.6V ~ 2.65V */
|
||||
PMU_LVD_VOL_SEL_2_8 = 0x3U, /**< 2.8V ~ 2.85V */
|
||||
PMU_LVD_VOL_SEL_3_0 = 0x4U, /**< 3.0V ~ 3.05V */
|
||||
PMU_LVD_VOL_SEL_3_2 = 0x5U, /**< 3.2V ~ 3.25V */
|
||||
PMU_LVD_VOL_SEL_3_4 = 0x6U, /**< 3.4V ~ 3.45V */
|
||||
PMU_LVD_VOL_SEL_3_6 = 0x7U, /**< 3.6V ~ 3.65V */
|
||||
PMU_LVD_VOL_SEL_3_8 = 0x8U, /**< 3.8V ~ 3.85V */
|
||||
PMU_LVD_VOL_SEL_4_0 = 0x9U, /**< 4.0V ~ 4.05V */
|
||||
PMU_LVD_VOL_SEL_4_2 = 0xAU, /**< 4.2V ~ 4.25V */
|
||||
PMU_LVD_VOL_SEL_4_4 = 0xBU, /**< 4.4V ~ 4.45V */
|
||||
PMU_LVD_VOL_SEL_4_6 = 0xCU, /**< 4.6V ~ 4.65V */
|
||||
PMU_LVD_VOL_SEL_4_8 = 0xDU, /**< 4.8V ~ 4.85V */
|
||||
PMU_LVD_VOL_SEL_EXT = 0xFU, /**< Select external input. It must be 1.2V */
|
||||
} pmu_lvd_voltage_sel_t;
|
||||
|
||||
/**
|
||||
* @brief LVD trigger mode
|
||||
*/
|
||||
typedef enum {
|
||||
PMU_LVD_TRIGGER_RISING_EDGE = 0x0U, /**< Rising edge */
|
||||
PMU_LVD_TRIGGER_FALLING_EDGE = 0x1U, /**< Falling edge */
|
||||
PMU_LVD_TRIGGER_HIGH_LEVEL = 0x2U, /**< High level */
|
||||
PMU_LVD_TRIGGER_LOW_LEVEL = 0x3U, /**< Low level */
|
||||
PMU_LVD_TRIGGER_RISING_FALLING = 0x4U, /**< Rising and falling edge */
|
||||
} pmu_lvd_trigger_mode_t;
|
||||
|
||||
/**
|
||||
* @brief LDO output voltage selest in low power mode
|
||||
*/
|
||||
typedef enum {
|
||||
PMU_LDO_LPMODE_OUTPUT_0_9 = 0x0U, /**< 0.9V */
|
||||
PMU_LDO_LPMODE_OUTPUT_1_0 = 0x1U, /**< 1.0V */
|
||||
PMU_LDO_LPMODE_OUTPUT_1_1 = 0x2U, /**< 1.1V */
|
||||
PMU_LDO_LPMODE_OUTPUT_1_2 = 0x3U, /**< 1.2V */
|
||||
} pmu_ldo_lpmode_output_t;
|
||||
|
||||
typedef enum {
|
||||
PMU_POWER_SRAM0 = 0x1U, /**< SRAM0 */
|
||||
PMU_POWER_SRAM1 = 0x2U, /**< SRAM1 */
|
||||
PMU_POWER_SRAM2 = 0x4U, /**< SRAM2 */
|
||||
PMU_POWER_SRAM3 = 0x8U, /**< SRAM3 */
|
||||
PMU_POWER_SRAM4 = 0x10U, /**< SRAM4 */
|
||||
PMU_POWER_SRAM5 = 0x20U, /**< SRAM5 */
|
||||
PMU_POWER_CAN = 0x100U, /**< CAN */
|
||||
PMU_POWER_QSPI = 0x400U, /**< QSPI */
|
||||
PMU_POWER_USB = 0x800U, /**< USB */
|
||||
PMU_POWER_ROM = 0x1000U, /**< ROM */
|
||||
} pmu_perh_power_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup PMU_Private_Macros PMU Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_PMU_LP_MODE(x) (((x) == PMU_LP_STOP1) || \
|
||||
((x) == PMU_LP_STOP2) || \
|
||||
((x) == PMU_LP_STANDBY))
|
||||
#define IS_PMU_LDO18_MODE(x) (((x) == PMU_LDO_18_DRV_HIGH) || \
|
||||
((x) == PMU_LDO_18_DRV_LOW) || \
|
||||
((x) == PMU_LDO_18_HOLD) || \
|
||||
((x) == PMU_LDO_18_OFF))
|
||||
#define IS_PMU_STATUS(x) (((x) == PMU_SR_WUF) || \
|
||||
((x) == PMU_SR_STANDBYF) || \
|
||||
((x) == PMU_SR_USBRDY) || \
|
||||
((x) == PMU_SR_RSTAT))
|
||||
#define IS_PMU_LVD_VOL_SEL(x) (((x) == PMU_LVD_VOL_SEL_2_2) || \
|
||||
((x) == PMU_LVD_VOL_SEL_2_4) || \
|
||||
((x) == PMU_LVD_VOL_SEL_2_6) || \
|
||||
((x) == PMU_LVD_VOL_SEL_2_8) || \
|
||||
((x) == PMU_LVD_VOL_SEL_3_0) || \
|
||||
((x) == PMU_LVD_VOL_SEL_3_2) || \
|
||||
((x) == PMU_LVD_VOL_SEL_3_4) || \
|
||||
((x) == PMU_LVD_VOL_SEL_3_6) || \
|
||||
((x) == PMU_LVD_VOL_SEL_3_8) || \
|
||||
((x) == PMU_LVD_VOL_SEL_4_0) || \
|
||||
((x) == PMU_LVD_VOL_SEL_4_2) || \
|
||||
((x) == PMU_LVD_VOL_SEL_4_4) || \
|
||||
((x) == PMU_LVD_VOL_SEL_4_6) || \
|
||||
((x) == PMU_LVD_VOL_SEL_4_8) || \
|
||||
((x) == PMU_LVD_VOL_SEL_EXT))
|
||||
#define IS_PMU_LVD_TRIGGER_MODE(x) (((x) == PMU_LVD_TRIGGER_RISING_EDGE) || \
|
||||
((x) == PMU_LVD_TRIGGER_FALLING_EDGE) || \
|
||||
((x) == PMU_LVD_TRIGGER_HIGH_LEVEL) || \
|
||||
((x) == PMU_LVD_TRIGGER_LOW_LEVEL) || \
|
||||
((x) == PMU_LVD_TRIGGER_RISING_FALLING))
|
||||
#define IS_PMU_LDO_LPMODE_OUTPUT(x) (((x) == PMU_LDO_LPMODE_OUTPUT_0_9) || \
|
||||
((x) == PMU_LDO_LPMODE_OUTPUT_1_0) || \
|
||||
((x) == PMU_LDO_LPMODE_OUTPUT_1_1) || \
|
||||
((x) == PMU_LDO_LPMODE_OUTPUT_1_2))
|
||||
#define IS_PMU_PERH_POWER(x) (((x) == PMU_POWER_SRAM0) || \
|
||||
((x) == PMU_POWER_SRAM1) || \
|
||||
((x) == PMU_POWER_SRAM2) || \
|
||||
((x) == PMU_POWER_SRAM3) || \
|
||||
((x) == PMU_POWER_SRAM4) || \
|
||||
((x) == PMU_POWER_SRAM5) || \
|
||||
((x) == PMU_POWER_CAN) || \
|
||||
((x) == PMU_POWER_QSPI) || \
|
||||
((x) == PMU_POWER_USB) || \
|
||||
((x) == PMU_POWER_ROM))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup PMU_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
/** @addtogroup PMU_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
/* Low power mode select */
|
||||
__STATIC_INLINE__ void ald_pmu_sleep()
|
||||
{
|
||||
__WFI();
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void ald_pmu_sleep_deep()
|
||||
{
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
__WFI();
|
||||
}
|
||||
|
||||
void ald_pmu_stop1_enter(void);
|
||||
void ald_pmu_stop2_enter(void);
|
||||
void ald_pmu_standby_enter(bkpc_wakeup_port_t port, bkpc_wakeup_level_t level);
|
||||
void ald_pmu_ldo_12_config(type_func_t state);
|
||||
void ald_pmu_ldo_18_config(pmu_ldo_18_mode_t mode);
|
||||
#ifdef ES32F336x /* MCU Series: ES32F336x */
|
||||
void ald_pmu_lprun_config(pmu_ldo_lpmode_output_t vol, type_func_t state);
|
||||
#endif
|
||||
flag_status_t ald_pmu_get_status(pmu_status_t sr);
|
||||
void ald_pmu_clear_status(pmu_status_t sr);
|
||||
void ald_pmu_perh_power_config(pmu_perh_power_t perh, type_func_t state);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup PMU_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
/* LVD configure */
|
||||
void ald_pmu_lvd_config(pmu_lvd_voltage_sel_t sel, pmu_lvd_trigger_mode_t mode, type_func_t state);
|
||||
void ald_lvd_irq_handler(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_PMU_H__ */
|
||||
@@ -1,557 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file ald_qspi.h
|
||||
* @brief Header file of QSPI module driver.
|
||||
* @version V1.0
|
||||
* @date 09 Nov 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 09 Nov 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_QSPI_H_
|
||||
#define __ALD_QSPI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
#include "ald_dma.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup QSPI
|
||||
* @{
|
||||
*/
|
||||
/** @defgroup QSPI_Public_Types QSPI Public Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief ALD QSPI state
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_STATE_BUSY_TX = 0x11U, /**< Data Transmission process is ongoing */
|
||||
QSPI_STATE_BUSY_RX = 0x21U, /**< Data Reception process is ongoing */
|
||||
} qspi_state_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Instruction Transfer Type
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_XFER_SINGLE = 0x00U, /**< Instruction shifted on DQ0 only*/
|
||||
QSPI_XFER_DUAL = 0x01U, /**< Instruction,Address and data sent on DQ0 and DQ1*/
|
||||
QSPI_XFER_QUAD = 0x02U, /**< Instruction,Address and data sent on DQ0,DQ1 and DQ2*/
|
||||
} qspi_xfer_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Indirect Access SRAM fill level
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_SRAM_RD = 0U, /**< SRAM fill level(indirect write partition)in units of words(4bytes)*/
|
||||
QSPI_SRAM_WR = 1U, /**< SRAM fill level(indirect read partition)in units of words(4bytes)*/
|
||||
} qspi_sram_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Clock Phase
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_CPHA_1E = 0U, /**< First edge*/
|
||||
QSPI_CPHA_2E = 1U, /**< Second edge*/
|
||||
} qspi_cpha_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI_Clock_Polarity QSPI Clock Polarity
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_CPOL_L = 0U, /**< QSPI clock polarity low */
|
||||
QSPI_CPOL_H = 1U, /**< QSPI clock polarity high */
|
||||
} qspi_cpol_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI peripheral select decode
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_SINGLE_CHIP = 0x0U, /**< Only 1 of 4 selects n_ss_out[3:0] is active */
|
||||
QSPI_MULTI_CHIP = 0x1U, /**< Allow external 4-to-16 decode */
|
||||
} qspi_nss_decode_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI_Baud_Rate_Clock_Prescaler QSPI Baud Rate Clock Prescaler
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_DIV_2 = 0x0U, /**< Master mode baud rate dibisor 2*/
|
||||
QSPI_DIV_4 = 0x1U, /**< Master mode baud rate dibisor 4*/
|
||||
QSPI_DIV_6 = 0x2U, /**< Master mode baud rate dibisor 6*/
|
||||
QSPI_DIV_8 = 0x3U, /**< Master mode baud rate dibisor 8*/
|
||||
QSPI_DIV_10 = 0x4U, /**< Master mode baud rate dibisor 10*/
|
||||
QSPI_DIV_12 = 0x5U, /**< Master mode baud rate dibisor 12*/
|
||||
QSPI_DIV_14 = 0x6U, /**< Master mode baud rate dibisor 14*/
|
||||
QSPI_DIV_16 = 0x7U, /**< Master mode baud rate dibisor 16*/
|
||||
QSPI_DIV_18 = 0x8U, /**< Master mode baud rate dibisor 18*/
|
||||
QSPI_DIV_20 = 0x9U, /**< Master mode baud rate dibisor 20*/
|
||||
QSPI_DIV_22 = 0xAU, /**< Master mode baud rate dibisor 22*/
|
||||
QSPI_DIV_24 = 0xBU, /**< Master mode baud rate dibisor 24*/
|
||||
QSPI_DIV_26 = 0xCU, /**< Master mode baud rate dibisor 26*/
|
||||
QSPI_DIV_28 = 0xDU, /**< Master mode baud rate dibisor 28*/
|
||||
QSPI_DIV_30 = 0xEU, /**< Master mode baud rate dibisor 30*/
|
||||
QSPI_DIV_32 = 0xFU, /**< Master mode baud rate dibisor 32*/
|
||||
} qspi_clk_div_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Peripheral chip select decode
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_CS_NSS0 = 0x0U, /**< NSS0 active*/
|
||||
QSPI_CS_NSS1 = 0x1U, /**< NSS1 active*/
|
||||
QSPI_CS_NSS2 = 0x3U, /**< NSS2 active*/
|
||||
QSPI_CS_NSS3 = 0x7U, /**< NSS3 active*/
|
||||
} qspi_nss_t;
|
||||
|
||||
/**
|
||||
*@brief Size of flash connected to CS[x](x = 0 ~ 3)pin
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_NSS_512M = 0x0U, /**< size of 512Mb*/
|
||||
QSPI_NSS_1G = 0x1U, /**< size of 1Gb*/
|
||||
QSPI_NSS_2G = 0x2U, /**< size of 2Gb*/
|
||||
QSPI_NSS_4G = 0x3U, /**< size of 3Gb*/
|
||||
} qspi_nss_size_t;
|
||||
|
||||
/**
|
||||
*@brief Qspi external flash device configuration
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t addr; /**< Peripheral address */
|
||||
uint16_t page; /**< Flash page size */
|
||||
uint16_t blk; /**< Flash block size */
|
||||
qspi_nss_size_t cs0; /**< NSS0 flash size */
|
||||
qspi_nss_size_t cs1; /**< NSS1 flash size */
|
||||
qspi_nss_size_t cs2; /**< NSS2 flash size */
|
||||
qspi_nss_size_t cs3; /**< NSS3 flash size */
|
||||
} qspi_device_size_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Sample Edge Selection
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_FALLING_E = 0x0U, /**< Data outputs from flash are sampled on falling edge of the ref_clk*/
|
||||
QSPI_RISING_E = 0x1U, /**< Data outputs from flash are sampled on rising edge of the ref_clk*/
|
||||
} qspi_data_sampled_t;
|
||||
|
||||
/**
|
||||
* @brief Flash write-protected blocks configuration.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t lowblk; /**< the lower block in the range of blocks that is to be locked from writing*/
|
||||
uint32_t upblk; /**< upper block in the range of blocks that is to be locked from writing*/
|
||||
} qspi_wr_protect_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI STIG Command Structure.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t code; /**< command op-code*/
|
||||
uint32_t rd_len; /**< Number of Read Data Bytes*/
|
||||
uint32_t addr_len; /**< Number of Address Bytes*/
|
||||
uint32_t wr_len; /**< Number of Write Data Bytes*/
|
||||
uint32_t d_sycle; /**< Number of dummy cycles*/
|
||||
type_func_t mode_bit; /**< Mode Bit Configuration register are sent following the address bytes*/
|
||||
type_func_t op_addr; /**< If opcde requires an address*/
|
||||
uint32_t val; /**< Mode bits,sent to device following the address*/
|
||||
uint32_t addr; /**< Flash opcde address*/
|
||||
void *rd_buf; /**< Buffer for read data*/
|
||||
void *wr_buf; /**< Buffer with data to write*/
|
||||
} qspi_stig_cmd_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI base initialization structure.
|
||||
*/
|
||||
typedef struct {
|
||||
qspi_clk_div_t clkdiv; /**< QSPI Baud Rate Clock Prescaler*/
|
||||
type_func_t wrppin; /**< QSPI Set Write Protect Pin*/
|
||||
qspi_nss_decode_t nssdcode; /**< QSPI Peripheral Select Decode*/
|
||||
qspi_nss_t chipsel; /**< QSPI Peripheral Select Line*/
|
||||
qspi_cpol_t cpol; /**< QSPI polarity */
|
||||
qspi_cpha_t chpa; /**< QSPI phase */
|
||||
} qspi_init_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI legacy initialization structure.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t tx_thrd; /**< Tx FIFO threshhold */
|
||||
uint8_t rx_thrd; /**< Rx FIFO threshhold */
|
||||
} qspi_legacy_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Device Read Instruction Configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t rdcde; /**< Read opcode in non-xip mode*/
|
||||
uint8_t dcyles; /**< Number of dummy read clock cycles*/
|
||||
uint8_t mbitval; /**< Mode bits,sent to device following the address bytes*/
|
||||
type_func_t ddrbit; /**< Opcode from bit 7 to 0 is compliant with DDR command*/
|
||||
type_func_t modebit; /**< Enable mode bit*/
|
||||
qspi_xfer_t addxfer; /**< Transfer type used for address*/
|
||||
qspi_xfer_t datxfer; /**< Transfer type used for data*/
|
||||
qspi_xfer_t instxfer; /**< Transfer type used for instruction*/
|
||||
} qspi_read_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Device Write Instruction Configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t wrcde; /**< Write opcode*/
|
||||
uint8_t dcyles; /**< Number of dummy read clock cycles*/
|
||||
qspi_xfer_t addxfer; /**< Transfer type used for address*/
|
||||
qspi_xfer_t datxfer; /**< Transfer type used for data*/
|
||||
qspi_xfer_t instxfer; /**< Transfer type used for instruction*/
|
||||
type_func_t autowel; /**< Turn off automatic*/
|
||||
} qspi_write_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Indirect Configuration structure.involatile parameters
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t saddr; /**< Flash start address, commence write operation*/
|
||||
uint32_t wrlen; /**< Number of indirect write bytes*/
|
||||
} qspi_indac_wr_cfg_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t saddr; /**< FLASH start address, commence read operation*/
|
||||
uint32_t rdlen; /**< Number of indirect read bytes*/
|
||||
} qspi_indac_rd_cfg_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t srampt; /**< Defines the size of the indirect read partion in the SRAM*/
|
||||
uint32_t trgaddr; /**< Indirect trigger address which is used by AHB controller*/
|
||||
uint32_t trgrng; /**< The offset of indirect trigger address*/
|
||||
uint32_t wrwmark; /**< Maximum fill level of SRAM before a DMA, 0xFFFFFFFF disable the function*/
|
||||
uint32_t rdwmark; /**< Fill level passes watermark, an interrupt generated*/
|
||||
} qspi_indac_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI DAC configuration.
|
||||
*/
|
||||
typedef struct {
|
||||
type_func_t dtrprtcol; /**< DTR protocol*/
|
||||
type_func_t ahbdecoder; /**< AHB decoder, direct access mode only*/
|
||||
type_func_t xipimmed; /**< QSPI Enter XIP Immediately*/
|
||||
type_func_t xipnextrd; /**< QSPI Enter XIP Next Read*/
|
||||
type_func_t addrremap; /**< Enable AHB address re-mapping*/
|
||||
uint32_t remapaddr; /**< Remap incoming AHB address to different address*/
|
||||
type_func_t dmaperh; /**< QSPI dma interface*/
|
||||
qspi_read_cfg_t rdinit; /**< QSPI read instruction configuration*/
|
||||
qspi_write_cfg_t wrinit; /**< QSPI write instruction configuration*/
|
||||
} qspi_dac_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Handle Structure definition
|
||||
*/
|
||||
typedef struct {
|
||||
QSPI_TypeDef *perh; /**< QSPI registers base address*/
|
||||
qspi_init_t init; /**< QSPI communication parameters*/
|
||||
uint8_t *tx_buf; /**< Pointer to QSPI transfer buffer */
|
||||
uint16_t tx_size; /**< QSPI transfer size */
|
||||
uint16_t tx_cnt; /**< QSPI transfer counter */
|
||||
uint8_t *rx_buf; /**< Pointer to QSPI receive buffer */
|
||||
uint16_t rx_size; /**< QSPI receive size */
|
||||
uint16_t rx_cnt; /**< QSPI receive counter */
|
||||
|
||||
dma_handle_t hdma; /**< QSPI Rx/Tx DMA Handle parameters*/
|
||||
|
||||
qspi_state_t state; /**< QSPI communication state */
|
||||
__IO lock_state_t lock; /**< Locking object*/
|
||||
} qspi_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Defines command to be executed using STIG mechanism.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t ccsot; /**< range [0 ~ 255]*/
|
||||
uint32_t cseot; /**< range [0 ~ 255]*/
|
||||
uint32_t csdads; /**< range [0 ~ 255]*/
|
||||
uint32_t csda; /**< range [0 ~ 255]*/
|
||||
} qspi_dly_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Read Data Capture Configuration.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t dlytd; /**< Delay transmitted data [0 ~ 15]*/
|
||||
uint32_t dlydcl; /**< Delay the read data capturing logic [0 ~ 15]*/
|
||||
qspi_data_sampled_t smpledge; /**< Sample edge selection(of the flash data outputs) @ref qspi_data_sampled_t*/
|
||||
} qspi_data_capture_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Indirect Write Progress Status.
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_INDWR_PROGRESS = (1U << 2), /**< Indirect write operation in progress*/
|
||||
QSPI_INDWR_CPLT = (1U << 5), /**< Indirect write completion*/
|
||||
} qspi_indwr_status_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Indirect Read Progress Status.
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_INDRD_PROGRESS = (1U << 2), /**< Indirect read operation in progress*/
|
||||
QSPI_RD_CPLT = (1U << 5), /**< Indirect read completion*/
|
||||
} qspi_indrd_flag_t;
|
||||
|
||||
/**
|
||||
* @brief QSPI Auto Poll Configuration Struction.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t opcode; /**< Automatically poll operation code */
|
||||
uint32_t indx; /**< Polling bit index */
|
||||
uint32_t polarity; /**< Defines polling polarity */
|
||||
uint32_t validcnt; /**< Expect true result times */
|
||||
uint32_t repdly; /**< Defines additional delay for maintain de-assert during auto-polling phase */
|
||||
uint32_t polexpcnt; /**< Poll cycles,which polling expiration interrupt is generated*/
|
||||
} qspi_auto_poll_t;
|
||||
|
||||
/**
|
||||
*@brief QSPI_Interrupt_definition QSPI Interrupt Definition
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_IT_POLLF = (1U << 13), /**< Programmed polls cycles expired flag */
|
||||
QSPI_IT_INDRSFF = (1U << 12), /**< Indirect read partition of SRAM is full flag */
|
||||
QSPI_IT_SRFFF = (1U << 11), /**< Small rx FIFO full flag */
|
||||
QSPI_IT_SRFNEF = (1U << 10), /**< Small rx FIFO not empty flag */
|
||||
QSPI_IT_STFFF = (1U << 9), /**< Small tx FIFO full flag */
|
||||
QSPI_IT_STFNFF = (1U << 8), /**< Small tx FIFO not full flag */
|
||||
QSPI_IT_ROVF = (1U << 7), /**< Receive overflow flag */
|
||||
QSPI_IT_INDTWF = (1U << 6), /**< Indirect transfer watermark level breached flag */
|
||||
QSPI_IT_AHBAEF = (1U << 5), /**< Illegal AHB access detected flag */
|
||||
QSPI_IT_WPAF = (1U << 4), /**< Write to protected area was rejected flag */
|
||||
QSPI_IT_INDRRF = (1U << 3), /**< Indirect operation could not be accepted flag */
|
||||
QSPI_IT_INDCF = (1U << 2), /**< Controller has completed last triggered indirect operation flag */
|
||||
QSPI_IT_UDFF = (1U << 1), /**< Underflow detected flag */
|
||||
QSPI_IT_MODFF = (1U << 0), /**< Mode fail M flag */
|
||||
} qspi_it_t;
|
||||
/**
|
||||
* @brief QSPI_Flag_definition QSPI Flag Definition
|
||||
*/
|
||||
typedef enum {
|
||||
QSPI_IF_POLLF = (1U << 13), /**< Programmed polls cycles expired flag */
|
||||
QSPI_IF_INDRSFF = (1U << 12), /**< Indirect read partition of SRAM is full flag */
|
||||
QSPI_IF_SRFFF = (1U << 11), /**< Small rx FIFO full flag */
|
||||
QSPI_IF_SRFNEF = (1U << 10), /**< Small rx FIFO not empty flag */
|
||||
QSPI_IF_STFFF = (1U << 9), /**< Small tx FIFO full flag */
|
||||
QSPI_IF_STFNFF = (1U << 8), /**< Small tx FIFO not full flag */
|
||||
QSPI_IF_ROVF = (1U << 7), /**< Receive overflow flag */
|
||||
QSPI_IF_INDTWF = (1U << 6), /**< Indirect transfer watermark level breached flag */
|
||||
QSPI_IF_AHBAEF = (1U << 5), /**< Illegal AHB access detected flag */
|
||||
QSPI_IF_WPAF = (1U << 4), /**< Write to protected area was rejected flag */
|
||||
QSPI_IF_INDRRF = (1U << 3), /**< Indirect operation could not be accepted flag */
|
||||
QSPI_IF_INDCF = (1U << 2), /**< Controller has completed last triggered indirect operation flag */
|
||||
QSPI_IF_UDFF = (1U << 1), /**< Underflow detected flag */
|
||||
QSPI_IF_MODFF = (1U << 0), /**< Mode fail M flag */
|
||||
} qspi_flag_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup QSPI_Private_Macros QSPI Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_QSPI_SRAM_PARTITION(x) ((x) < 255)
|
||||
#define IS_QSPI_INDIRECT_TRIGGER_RANGE(x) (((x) < 16))
|
||||
#define IS_QSPI_INDIRECT_READ_WATERMARK(x) ((x) < 512)
|
||||
#define IS_QSPI_INDIRECT_SRAM_FILL_TYPE(x) (((x) == QSPI_SRAM_RD) || ((x) == QSPI_SRAM_WR))
|
||||
#define IS_QSPI_INDIRECT_READ_STATUS(x) (((x) == QSPI_INDRD_PROGRESS) || ((x) == QSPI_RD_CPLT))
|
||||
#define IS_QSPI_INDIRECT_WRITE_STATUS(x) (((x) == QSPI_INDWR_PROGRESS) || ((x) == QSPI_INDWR_CPLT))
|
||||
#define IS_QSPI_DEVICE_DELAY_CCSOT(x) ((x) < 256)
|
||||
#define IS_QSPI_DEVICE_DELAY_CSEOT(x) ((x) < 256)
|
||||
#define IS_QSPI_DEVICE_DELAY_CSDADS(x) ((x) < 256)
|
||||
#define IS_QSPI_DEVICE_DELAY_CSDA(x) ((x) < 256)
|
||||
|
||||
#define IS_QSPI_READ_DATA_CAPTURE_DELAY_READ(x) ((x) < 16)
|
||||
#define IS_QSPI_READ_DATA_SAMPLE_EDGE(x) (((x) == QSPI_FALLING_E) || \
|
||||
((x) == QSPI_RISING_E))
|
||||
#define IS_QSPI_READ_DATA_DELAY_TRANSMIT(x) ((x) < 16)
|
||||
#define IS_QSPI_ALL(x) ((x) == QSPI)
|
||||
#define IS_QSPI_DCYLES(x) ((x) <= 31)
|
||||
|
||||
#define IS_QSPI_ADDR_SIZE(x) ((x) <= 15)
|
||||
#define IS_QSPI_PAGE_SIZE(x) ((x) <= 0xfff)
|
||||
#define IS_QSPI_BLOCK_SIZE(x) ((x) <= 0x1f)
|
||||
#define IS_QSPI_NSS_SIZE(x) ((x) <= 3)
|
||||
|
||||
#define IS_QSPI_XFER_TYPE(x) (((x) == QSPI_XFER_SINGLE) || \
|
||||
((x) == QSPI_XFER_DUAL) || \
|
||||
((x) == QSPI_XFER_QUAD))
|
||||
#define IS_QSPI_DDR_BIT_ENABLE(x) (((x) == QSPI_READ_DDR_BIT_DISABLE) || \
|
||||
((x) == QSPI_READ_DDR_BIT_ENABLE))
|
||||
#define IS_QSPI_MODE_BIT_ENABLE(x) (((x) == QSPI_READ_INST_MODE_BIT_DISABLE) || \
|
||||
((x) == QSPI_READ_INST_MODE_BIT_ENABLE))
|
||||
#define IS_QSPI_RD_OPCODE(x) (((x) < 0xFF))
|
||||
#define IS_QSPI_WR_OPCODE(x) (((x) < 0xFF))
|
||||
#define IS_QSPI_CLOCK_PRESCALER(x) (((x) == QSPI_DIV_2) || \
|
||||
((x) == QSPI_DIV_4) || \
|
||||
((x) == QSPI_DIV_6) || \
|
||||
((x) == QSPI_DIV_8) || \
|
||||
((x) == QSPI_DIV_10) || \
|
||||
((x) == QSPI_DIV_12) || \
|
||||
((x) == QSPI_DIV_14) || \
|
||||
((x) == QSPI_DIV_16) || \
|
||||
((x) == QSPI_DIV_18) || \
|
||||
((x) == QSPI_DIV_20) || \
|
||||
((x) == QSPI_DIV_22) || \
|
||||
((x) == QSPI_DIV_24) || \
|
||||
((x) == QSPI_DIV_26) || \
|
||||
((x) == QSPI_DIV_28) || \
|
||||
((x) == QSPI_DIV_30) || \
|
||||
((x) == QSPI_DIV_32))
|
||||
#define IS_QSPI_CLOCK_PHASE(x) (((x) == QSPI_CPHA_1E) || \
|
||||
((x) == QSPI_CPHA_2E))
|
||||
#define IS_QSPI_CLOCK_POLARITY(x) (((x) == QSPI_CPOL_L) || \
|
||||
((x) == QSPI_CPOL_H))
|
||||
#define IS_QSPI_IF(x) (((x) == QSPI_IF_POLLF) || \
|
||||
((x) == QSPI_IF_INDRSFF) || \
|
||||
((x) == QSPI_IF_SRFFF) || \
|
||||
((x) == QSPI_IF_SRFNEF) || \
|
||||
((x) == QSPI_IF_STFFF) || \
|
||||
((x) == QSPI_IF_STFNFF) || \
|
||||
((x) == QSPI_IF_ROVF) || \
|
||||
((x) == QSPI_IF_INDTWF) || \
|
||||
((x) == QSPI_IF_AHBAEF) || \
|
||||
((x) == QSPI_IF_WPAF) || \
|
||||
((x) == QSPI_IF_INDRRF) || \
|
||||
((x) == QSPI_IF_INDCF) || \
|
||||
((x) == QSPI_IF_UDFF) || \
|
||||
((x) == QSPI_IF_MODFF))
|
||||
#define IS_QSPI_IT(x) (((x) == QSPI_IT_POLLF) || \
|
||||
((x) == QSPI_IT_INDRSFF) || \
|
||||
((x) == QSPI_IT_SRFFF) || \
|
||||
((x) == QSPI_IT_SRFNEF) || \
|
||||
((x) == QSPI_IT_STFFF) || \
|
||||
((x) == QSPI_IT_STFNFF) || \
|
||||
((x) == QSPI_IT_ROVF) || \
|
||||
((x) == QSPI_IT_INDTWF) || \
|
||||
((x) == QSPI_IT_AHBAEF) || \
|
||||
((x) == QSPI_IT_WPAF) || \
|
||||
((x) == QSPI_IT_INDRRF) || \
|
||||
((x) == QSPI_IT_INDCF) || \
|
||||
((x) == QSPI_IT_UDFF) || \
|
||||
((x) == QSPI_IT_MODFF))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup QSPI_Public_Macros QSPI Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define QSPI_MEMORY_ADDRESS 0x90000000U
|
||||
#define QSPI_SRAM_SIZE 255U
|
||||
#define QSPI_TIMEOUT_DEFAULT_VALUE 5000U /* 5s */
|
||||
#define QSPI_SRAM_DEPTH 0xFFU
|
||||
#define QSPI_DAC_ENABLE(hperh) SET_BIT((hperh)->perh->CR, QSPI_CR_DACEN_MSK)
|
||||
#define QSPI_DAC_DISABLE(hperh) CLEAR_BIT((hperh)->perh->CR, QSPI_CR_DACEN_MSK)
|
||||
#define QSPI_LEGACY_SPI_ENABLE(hperh) SET_BIT((hperh)->perh->CR, QSPI_CR_LIMEN_MSK)
|
||||
#define QSPI_LEGACY_SPI_DISABLE(hperh) CLEAR_BIT((hperh)->perh->CR, QSPI_CR_LIMEN_MSK)
|
||||
#define QSPI_WRITE_PROTECT_ENABLE(hperh) SET_BIT((hperh)->perh->WPCR, QSPI_WPCR_WPEN_MSK);
|
||||
#define QSPI_WRITE_PROTECT_DISABLE(hperh) CLEAR_BIT((hperh)->perh->WPCR, QSPI_WPCR_WPEN_MSK);
|
||||
#define QSPI_ENABLE(hperh) SET_BIT((hperh)->perh->CR, QSPI_CR_EN_MSK)
|
||||
#define QSPI_DISABLE(hperh) CLEAR_BIT((hperh)->perh->CR, QSPI_CR_EN_MSK)
|
||||
#define QSPI_AUTO_POLL_ENABLE(hperh) CLEAR_BIT((hperh)->perh->WCR, QSPI_WCR_PDIS_MSK)
|
||||
#define QSPI_AUTO_POLL_DISABLE(hperh) SET_BIT((hperh)->perh->WCR, QSPI_WCR_PDIS_MSK)
|
||||
#define QSPI_DMA_ENABLE(hperh) SET_BIT((hperh)->perh->CR, QSPI_CR_DMAEN_MSK)
|
||||
#define QSPI_DMA_DISABLE(hperh) CLEAR_BIT((hperh)->perh->CR, QSPI_CR_DMAEN_MSK)
|
||||
#define QSPI_CANCEL_INDIRECT_READ(hperh) SET_BIT((hperh)->perh->IRTR, QSPI_IRTR_RDDIS_MSK)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup QSPI_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup QSPI_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
/* QSPI basic execution functions */
|
||||
void ald_qspi_init(qspi_handle_t *hperh);
|
||||
uint32_t ald_qspi_dac_rd(uint32_t addr);
|
||||
void ald_qspi_dac_wr(uint32_t addr, uint32_t dat);
|
||||
ald_status_t ald_qspi_read_config(qspi_handle_t* hperh, const qspi_read_cfg_t * rdcfg);
|
||||
ald_status_t ald_qspi_write_config(qspi_handle_t* hperh, const qspi_write_cfg_t * wrcfg);
|
||||
ald_status_t ald_qspi_device_delay_config(qspi_handle_t * hperh, qspi_dly_cfg_t *dlycfg);
|
||||
ald_status_t ald_qspi_read_data_capture_config(qspi_handle_t * hperh, qspi_data_capture_cfg_t *dtcptcfg);
|
||||
ald_status_t ald_qspi_device_size_config(qspi_handle_t *hperh, qspi_device_size_t * devcfg);
|
||||
ald_status_t qspi_dac_config(qspi_handle_t * hperh, qspi_dac_cfg_t * dcfg);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup QSPI_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
/* QSPI indirect and stig access execution functions */
|
||||
ald_status_t ald_qspi_indac_config(qspi_handle_t * hperh, qspi_indac_cfg_t *indcfg);
|
||||
ald_status_t ald_qspi_indac_transmit_by_it(qspi_handle_t *hperh, uint32_t saddr, uint8_t *psrc, uint32_t size);
|
||||
ald_status_t ald_qspi_indac_transmit_by_poll(qspi_handle_t *hperh, uint32_t saddr, uint8_t *psrc, uint32_t size);
|
||||
ald_status_t ald_qspi_indac_read_by_poll(qspi_handle_t *hperh, uint32_t saddr, uint8_t *desbuf, uint16_t size);
|
||||
ald_status_t ald_qspi_indac_read_by_it(qspi_handle_t *hperh, uint32_t saddr, uint8_t *desbuf, uint16_t size);
|
||||
ald_status_t ald_qspi_execute_stig_cmd(qspi_handle_t* hperh, const qspi_stig_cmd_t * scmd);
|
||||
#ifdef ALD_DMA
|
||||
ald_status_t ald_qspi_indac_transmit_by_dma(qspi_handle_t *hperh, uint32_t addr, uint8_t *psrc, uint16_t size);
|
||||
ald_status_t ald_qspi_indac_read_by_dma(qspi_handle_t *hperh, uint32_t addr, uint8_t *pdbuf, uint16_t size);
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup QSPI_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
/* QSPI status functions */
|
||||
flag_status_t qspi_get_flag_status(qspi_handle_t *hperh, qspi_flag_t flag);
|
||||
void ald_qspi_clear_it_flag(qspi_handle_t *hperh, qspi_flag_t flag);
|
||||
uint16_t qspi_read_sram_fill_level(qspi_handle_t * hperh, qspi_sram_t srt);
|
||||
void ald_qspi_write_proect_config(qspi_handle_t * hperh, qspi_wr_protect_t* wpcfg);
|
||||
void ald_qspi_write_proect_inverse(qspi_handle_t * hperh, type_func_t state);
|
||||
ald_status_t ald_qspi_auto_poll(qspi_handle_t *hperh, qspi_auto_poll_t* apcfg);
|
||||
void ald_qspi_irq_handler(qspi_handle_t *hperh);
|
||||
void ald_qspi_interrupt_config(qspi_handle_t *hperh, qspi_it_t it, type_func_t state);
|
||||
void ald_qspi_legacy_config(qspi_handle_t* hperh, const qspi_legacy_cfg_t *config);
|
||||
flag_status_t qspi_indwr_get_status(qspi_handle_t *hperh, qspi_indwr_status_t status);
|
||||
ald_status_t qspi_indwr_wait_flag(qspi_handle_t *hperh, qspi_indwr_status_t flag, flag_status_t status, uint32_t timeout);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __ALD_QSPI_H__ */
|
||||
@@ -1,314 +0,0 @@
|
||||
/**
|
||||
*********************************************************************************
|
||||
*
|
||||
* @file ald_rmu.h
|
||||
* @brief Header file of RMU module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 04 Dec 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 04 Dec 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_RMU_H__
|
||||
#define __ALD_RMU_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup RMU
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RMU_Public_Types RMU Public Types
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief RMU BOR fliter
|
||||
*/
|
||||
typedef enum {
|
||||
RMU_BORFLT_1 = 0x1U, /**< 1 cycle */
|
||||
RMU_BORFLT_2 = 0x2U, /**< 2 cycles */
|
||||
RMU_BORFLT_3 = 0x3U, /**< 3 cycles */
|
||||
RMU_BORFLT_4 = 0x4U, /**< 4 cycles */
|
||||
RMU_BORFLT_5 = 0x5U, /**< 5 cycles */
|
||||
RMU_BORFLT_6 = 0x6U, /**< 6 cycles */
|
||||
RMU_BORFLT_7 = 0x7U, /**< 7 cycles */
|
||||
} rmu_bor_filter_t;
|
||||
|
||||
/**
|
||||
* @brief RMU BOR voltage
|
||||
*/
|
||||
typedef enum {
|
||||
RMU_VOL_NONE = 0x0U, /**< Disable */
|
||||
RMU_VOL_2_0 = 0x1U, /**< 2.0V */
|
||||
RMU_VOL_2_2 = 0x2U, /**< 2.2V */
|
||||
RMU_VOL_2_4 = 0x3U, /**< 2.4V */
|
||||
RMU_VOL_2_6 = 0x4U, /**< 2.6V */
|
||||
RMU_VOL_2_8 = 0x5U, /**< 2.8V */
|
||||
RMU_VOL_3_0 = 0x6U, /**< 3.0V */
|
||||
RMU_VOL_3_2 = 0x7U, /**< 3.2V */
|
||||
RMU_VOL_3_4 = 0x8U, /**< 3.4V */
|
||||
RMU_VOL_3_6 = 0x9U, /**< 3.6V */
|
||||
RMU_VOL_3_8 = 0xAU, /**< 3.8V */
|
||||
RMU_VOL_4_0 = 0xBU, /**< 4.0V */
|
||||
RMU_VOL_4_2 = 0xCU, /**< 4.2V */
|
||||
RMU_VOL_4_4 = 0xDU, /**< 4.4V */
|
||||
RMU_VOL_4_6 = 0xEU, /**< 4.6V */
|
||||
RMU_VOL_4_8 = 0xFU, /**< 4.8V */
|
||||
} rmu_bor_vol_t;
|
||||
|
||||
/**
|
||||
* @brief RMU reset status
|
||||
*/
|
||||
typedef enum {
|
||||
RMU_RST_POR = (1U << 0), /**< POR */
|
||||
RMU_RST_WAKEUP = (1U << 1), /**< WAKEUP */
|
||||
RMU_RST_BOR = (1U << 2), /**< BOR */
|
||||
RMU_RST_NMRST = (1U << 3), /**< NMRST */
|
||||
RMU_RST_IWDT = (1U << 4), /**< IWDT */
|
||||
RMU_RST_WWDT = (1U << 5), /**< WWDT */
|
||||
RMU_RST_LOCKUP = (1U << 6), /**< LOCKUP */
|
||||
RMU_RST_CHIP = (1U << 7), /**< CHIP */
|
||||
RMU_RST_MCU = (1U << 8), /**< MCU */
|
||||
RMU_RST_CPU = (1U << 9), /**< CPU */
|
||||
RMU_RST_CFG = (1U << 10), /**< CFG */
|
||||
RMU_RST_CFGERR = (1U << 16), /**< CFG Error */
|
||||
RMU_RST_ALL = (0xFFFFFU), /**< ALL */
|
||||
} rmu_state_t;
|
||||
|
||||
/**
|
||||
* @brief RMU periperal select bit
|
||||
* @verbatim
|
||||
In this module, for the convenience of code maintenance,
|
||||
TIMERx is used to indicate the sequence of the timer peripheral.
|
||||
Different product series TIMERx represent different meanings:
|
||||
1. For ES32F36xx series:
|
||||
TIMER0 ----> AD16C4T0
|
||||
TIMER1 ----> AD16C4T1
|
||||
TIMER2 ----> GP32C4T0
|
||||
TIMER3 ----> GP32C4T1
|
||||
TIMER4 ----> BS16T0
|
||||
TIMER5 ----> BS16T1
|
||||
TIMER6 ----> GP16C4T0
|
||||
TIMER7 ----> GP16C4T1
|
||||
|
||||
2. For ES32F393x/ES32F336x/ES32F392x series:
|
||||
TIMER0 ----> GP16C4T0
|
||||
TIMER1 ----> GP16C4T1
|
||||
TIMER2 ----> GP32C4T0
|
||||
TIMER3 ----> GP32C4T1
|
||||
TIMER4 ----> BS16T0
|
||||
TIMER5 ----> BS16T1
|
||||
TIMER6 ----> GP16C4T2
|
||||
TIMER7 ----> GP16C4T3
|
||||
@endverbatim
|
||||
*/
|
||||
typedef enum {
|
||||
RMU_PERH_GPIO = (1U << 0), /**< AHB1: GPIO */
|
||||
RMU_PERH_CRC = (1U << 1), /**< AHB1: CRC */
|
||||
RMU_PERH_CALC = (1U << 2), /**< AHB1: CALC */
|
||||
RMU_PERH_CRYPT = (1U << 3), /**< AHB1: CRYPT */
|
||||
RMU_PERH_TRNG = (1U << 4), /**< AHB1: TRNG */
|
||||
RMU_PERH_PIS = (1U << 5), /**< AHB1: PIS */
|
||||
RMU_PERH_USB = (1U << 10), /**< AHB1: USB */
|
||||
RMU_PERH_ECC = (1U << 11), /**< AHB1: ECC */
|
||||
RMU_PERH_CHIP = (1U << 0) | (1U << 27), /**< AHB2: CHIP */
|
||||
RMU_PERH_CPU = (1U << 1) | (1U << 27), /**< AHB2: CPU */
|
||||
RMU_PERH_EBI = (1U << 8) | (1U << 27), /**< AHB2: EBI */
|
||||
RMU_PERH_TIMER0 = (1U << 0) | (1U << 28), /**< APB1: TIMER0 */
|
||||
RMU_PERH_TIMER1 = (1U << 1) | (1U << 28), /**< APB1: TIMER1 */
|
||||
RMU_PERH_TIMER2 = (1U << 2) | (1U << 28), /**< APB1: TIMER2 */
|
||||
RMU_PERH_TIMER3 = (1U << 3) | (1U << 28), /**< APB1: TIMER3 */
|
||||
RMU_PERH_TIMER4 = (1U << 4) | (1U << 28), /**< APB1: TIMER4 */
|
||||
RMU_PERH_TIMER5 = (1U << 5) | (1U << 28), /**< APB1: TIMER5 */
|
||||
RMU_PERH_TIMER6 = (1U << 6) | (1U << 28), /**< APB1: TIMER6 */
|
||||
RMU_PERH_TIMER7 = (1U << 7) | (1U << 28), /**< APB1: TIMER7 */
|
||||
RMU_PERH_UART0 = (1U << 8) | (1U << 28), /**< APB1: UART0 */
|
||||
RMU_PERH_UART1 = (1U << 9) | (1U << 28), /**< APB1: UART1 */
|
||||
RMU_PERH_UART2 = (1U << 10) | (1U << 28), /**< APB1: UART2 */
|
||||
RMU_PERH_UART3 = (1U << 11) | (1U << 28), /**< APB1: UART3 */
|
||||
RMU_PERH_UART4 = (1U << 12) | (1U << 28), /**< APB1: UART4 */
|
||||
RMU_PERH_UART5 = (1U << 13) | (1U << 28), /**< APB1: UART5 */
|
||||
RMU_PERH_SPI0 = (1U << 16) | (1U << 28), /**< APB1: SPI0 */
|
||||
RMU_PERH_SPI1 = (1U << 17) | (1U << 28), /**< APB1: SPI1 */
|
||||
RMU_PERH_SPI2 = (1U << 18) | (1U << 28), /**< APB1: SPI2 */
|
||||
RMU_PERH_I2C0 = (1U << 20) | (1U << 28), /**< APB1: I2C0 */
|
||||
RMU_PERH_I2C1 = (1U << 21) | (1U << 28), /**< APB1: I2C1 */
|
||||
RMU_PERH_CAN0 = (1U << 24) | (1U << 28), /**< APB1: CAN0 */
|
||||
RMU_PERH_QSPI = (1U << 25) | (1U << 28), /**< APB1: QSPI */
|
||||
RMU_PERH_LPTIM0 = (1U << 0) | (1U << 29), /**< APB2: LPTIM0 */
|
||||
RMU_PERH_LPUART0 = (1U << 2) | (1U << 29), /**< APB2: LPUART */
|
||||
RMU_PERH_ADC0 = (1U << 4) | (1U << 29), /**< APB2: ADC0 */
|
||||
RMU_PERH_ADC1 = (1U << 5) | (1U << 29), /**< APB2: ADC1 */
|
||||
RMU_PERH_ACMP0 = (1U << 6) | (1U << 29), /**< APB2: ACMP0 */
|
||||
RMU_PERH_ACMP1 = (1U << 7) | (1U << 29), /**< APB2: ACMP1 */
|
||||
RMU_PERH_OPAMP = (1U << 8) | (1U << 29), /**< APB2: OPAMP */
|
||||
RMU_PERH_DAC0 = (1U << 9) | (1U << 29), /**< APB2: DAC0 */
|
||||
RMU_PERH_ACMP2 = (1U << 11) | (1U << 29), /**< APB2: WWDT */
|
||||
RMU_PERH_WWDT = (1U << 12) | (1U << 29), /**< APB2: WWDT */
|
||||
RMU_PERH_LCD = (1U << 13) | (1U << 29), /**< APB2: LCD */
|
||||
RMU_PERH_IWDT = (1U << 14) | (1U << 29), /**< APB2: IWDT */
|
||||
RMU_PERH_RTC = (1U << 15) | (1U << 29), /**< APB2: RTC */
|
||||
RMU_PERH_TSENSE = (1U << 16) | (1U << 29), /**< APB2: TSENSE */
|
||||
RMU_PERH_BKPC = (1U << 17) | (1U << 29), /**< APB2: BKPC */
|
||||
RMU_PERH_BKPRAM = (1U << 18) | (1U << 29), /**< APB2: BKPRAM */
|
||||
} rmu_peripheral_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup RMU_Private_Macros RMU Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_RMU_BORFLT(x) (((x) == RMU_BORFLT_1) || \
|
||||
((x) == RMU_BORFLT_2) || \
|
||||
((x) == RMU_BORFLT_3) || \
|
||||
((x) == RMU_BORFLT_4) || \
|
||||
((x) == RMU_BORFLT_5) || \
|
||||
((x) == RMU_BORFLT_6) || \
|
||||
((x) == RMU_BORFLT_7))
|
||||
#define IS_RMU_BORVOL(x) (((x) == RMU_VOL_NONE) || \
|
||||
((x) == RMU_VOL_2_0) || \
|
||||
((x) == RMU_VOL_2_2) || \
|
||||
((x) == RMU_VOL_2_4) || \
|
||||
((x) == RMU_VOL_2_6) || \
|
||||
((x) == RMU_VOL_2_8) || \
|
||||
((x) == RMU_VOL_3_0) || \
|
||||
((x) == RMU_VOL_3_2) || \
|
||||
((x) == RMU_VOL_3_4) || \
|
||||
((x) == RMU_VOL_3_6) || \
|
||||
((x) == RMU_VOL_3_8) || \
|
||||
((x) == RMU_VOL_4_0) || \
|
||||
((x) == RMU_VOL_4_2) || \
|
||||
((x) == RMU_VOL_4_4) || \
|
||||
((x) == RMU_VOL_4_6) || \
|
||||
((x) == RMU_VOL_4_8))
|
||||
#define IS_RMU_STATE(x) (((x) == RMU_RST_POR) || \
|
||||
((x) == RMU_RST_WAKEUP) || \
|
||||
((x) == RMU_RST_BOR) || \
|
||||
((x) == RMU_RST_NMRST) || \
|
||||
((x) == RMU_RST_IWDT) || \
|
||||
((x) == RMU_RST_WWDT) || \
|
||||
((x) == RMU_RST_LOCKUP) || \
|
||||
((x) == RMU_RST_CHIP) || \
|
||||
((x) == RMU_RST_MCU) || \
|
||||
((x) == RMU_RST_CPU) || \
|
||||
((x) == RMU_RST_CFG) || \
|
||||
((x) == RMU_RST_CFGERR) || \
|
||||
((x) == RMU_RST_ALL))
|
||||
#define IS_RMU_STATE_CLEAR(x) (((x) == RMU_RST_POR) || \
|
||||
((x) == RMU_RST_WAKEUP) || \
|
||||
((x) == RMU_RST_BOR) || \
|
||||
((x) == RMU_RST_NMRST) || \
|
||||
((x) == RMU_RST_IWDT) || \
|
||||
((x) == RMU_RST_WWDT) || \
|
||||
((x) == RMU_RST_LOCKUP) || \
|
||||
((x) == RMU_RST_CHIP) || \
|
||||
((x) == RMU_RST_MCU) || \
|
||||
((x) == RMU_RST_CPU) || \
|
||||
((x) == RMU_RST_CFG) || \
|
||||
((x) == RMU_RST_ALL))
|
||||
#define IS_RMU_PERH(x) (((x) == RMU_PERH_GPIO) || \
|
||||
((x) == RMU_PERH_CRC) || \
|
||||
((x) == RMU_PERH_CALC) || \
|
||||
((x) == RMU_PERH_CRYPT) || \
|
||||
((x) == RMU_PERH_TRNG) || \
|
||||
((x) == RMU_PERH_PIS) || \
|
||||
((x) == RMU_PERH_USB) || \
|
||||
((x) == RMU_PERH_ECC) || \
|
||||
((x) == RMU_PERH_CHIP) || \
|
||||
((x) == RMU_PERH_CPU) || \
|
||||
((x) == RMU_PERH_EBI) || \
|
||||
((x) == RMU_PERH_TIMER0) || \
|
||||
((x) == RMU_PERH_TIMER1) || \
|
||||
((x) == RMU_PERH_TIMER2) || \
|
||||
((x) == RMU_PERH_TIMER3) || \
|
||||
((x) == RMU_PERH_TIMER4) || \
|
||||
((x) == RMU_PERH_TIMER5) || \
|
||||
((x) == RMU_PERH_TIMER6) || \
|
||||
((x) == RMU_PERH_TIMER7) || \
|
||||
((x) == RMU_PERH_UART0) || \
|
||||
((x) == RMU_PERH_UART1) || \
|
||||
((x) == RMU_PERH_UART2) || \
|
||||
((x) == RMU_PERH_UART3) || \
|
||||
((x) == RMU_PERH_UART4) || \
|
||||
((x) == RMU_PERH_UART5) || \
|
||||
((x) == RMU_PERH_SPI0) || \
|
||||
((x) == RMU_PERH_SPI1) || \
|
||||
((x) == RMU_PERH_SPI2) || \
|
||||
((x) == RMU_PERH_I2C0) || \
|
||||
((x) == RMU_PERH_I2C1) || \
|
||||
((x) == RMU_PERH_CAN0) || \
|
||||
((x) == RMU_PERH_QSPI) || \
|
||||
((x) == RMU_PERH_LPTIM0) || \
|
||||
((x) == RMU_PERH_LPUART0) || \
|
||||
((x) == RMU_PERH_ADC0) || \
|
||||
((x) == RMU_PERH_ADC1) || \
|
||||
((x) == RMU_PERH_ACMP0) || \
|
||||
((x) == RMU_PERH_ACMP1) || \
|
||||
((x) == RMU_PERH_OPAMP) || \
|
||||
((x) == RMU_PERH_DAC0) || \
|
||||
((x) == RMU_PERH_ACMP2) || \
|
||||
((x) == RMU_PERH_WWDT) || \
|
||||
((x) == RMU_PERH_LCD) || \
|
||||
((x) == RMU_PERH_IWDT) || \
|
||||
((x) == RMU_PERH_RTC) || \
|
||||
((x) == RMU_PERH_TSENSE) || \
|
||||
((x) == RMU_PERH_BKPC) || \
|
||||
((x) == RMU_PERH_BKPRAM))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup RMU_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
void ald_rmu_bor_config(rmu_bor_filter_t flt, rmu_bor_vol_t vol, type_func_t state);
|
||||
uint32_t ald_rmu_get_reset_status(rmu_state_t state);
|
||||
void ald_rmu_clear_reset_status(rmu_state_t state);
|
||||
void ald_rmu_reset_periperal(rmu_peripheral_t perh);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ALD_RMU_H__ */
|
||||
@@ -1,685 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file ald_rtc.h
|
||||
* @brief Header file of RTC Module driver.
|
||||
*
|
||||
* @version V1.0
|
||||
* @date 16 Nov 2019
|
||||
* @author AE Team
|
||||
* @note
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 16 Nov 2019 AE Team The first version
|
||||
*
|
||||
* Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* 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 __ALD_RTC_H__
|
||||
#define __ALD_RTC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/** @addtogroup ES32FXXX_ALD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup RTC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RTC_Public_Types RTC Public Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Hours format
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_HOUR_FORMAT_24 = 0x0U, /**< 24-hours format */
|
||||
RTC_HOUR_FORMAT_12 = 0x1U, /**< 12-hours format */
|
||||
} rtc_hour_format_t;
|
||||
|
||||
/**
|
||||
* @brief Output mode
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_OUTPUT_DISABLE = 0x0U, /**< Disable output */
|
||||
RTC_OUTPUT_ALARM_A = 0x1U, /**< Output alarm_a signal */
|
||||
RTC_OUTPUT_ALARM_B = 0x2U, /**< Output alarm_b signal */
|
||||
RTC_OUTPUT_WAKEUP = 0x3U, /**< Output wakeup signal */
|
||||
} rtc_output_select_t;
|
||||
|
||||
/**
|
||||
* @brief Output polarity
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_OUTPUT_POLARITY_HIGH = 0x0U, /**< Polarity is high */
|
||||
RTC_OUTPUT_POLARITY_LOW = 0x1U, /**< Polarity is low */
|
||||
} rtc_output_polarity_t;
|
||||
|
||||
/**
|
||||
* @brief Initialization structure
|
||||
*/
|
||||
typedef struct {
|
||||
rtc_hour_format_t hour_format; /**< Hours format */
|
||||
uint32_t asynch_pre_div; /**< Asynchronous predivider value */
|
||||
uint32_t synch_pre_div; /**< Synchronous predivider value */
|
||||
rtc_output_select_t output; /**< Output signal type */
|
||||
rtc_output_polarity_t output_polarity; /**< Output polarity */
|
||||
} rtc_init_t;
|
||||
|
||||
/**
|
||||
* @brief Source select
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_SOURCE_LOSC = 0x0U, /**< LOSC */
|
||||
RTC_SOURCE_LRC = 0x1U, /**< LRC */
|
||||
RTC_SOURCE_HRC_DIV_1M = 0x2U, /**< HRC divide to 1MHz */
|
||||
RTC_SOURCE_HOSC_DIV_1M = 0x3U, /**< HOSC divide to 1MHz */
|
||||
} rtc_source_sel_t;
|
||||
|
||||
/**
|
||||
* @brief Time structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t hour; /**< Hours */
|
||||
uint8_t minute; /**< Minutes */
|
||||
uint8_t second; /**< Seconds */
|
||||
uint16_t sub_sec; /**< Sub-seconds */
|
||||
} rtc_time_t;
|
||||
|
||||
/**
|
||||
* @brief Date structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t week; /**< Weeks */
|
||||
uint8_t day; /**< days */
|
||||
uint8_t month; /**< months */
|
||||
uint8_t year; /**< years */
|
||||
} rtc_date_t;
|
||||
|
||||
/**
|
||||
* @brief Data format
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_FORMAT_DEC = 0U, /**< Decimal */
|
||||
RTC_FORMAT_BCD = 1U, /**< BSD */
|
||||
} rtc_format_t;
|
||||
|
||||
/**
|
||||
* @brief Index of alarm
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_ALARM_A = 0x0U, /**< Alarm-A */
|
||||
RTC_ALARM_B = 0x1U, /**< Alarm-B */
|
||||
} rtc_alarm_idx_t;
|
||||
|
||||
/**
|
||||
* @brief Alarm mask
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_ALARM_MASK_NONE = 0x0U, /**< Mask is disable */
|
||||
RTC_ALARM_MASK_WEEK_DAY = (1U << 30), /**< Mask week or day */
|
||||
RTC_ALARM_MASK_HOUR = (1U << 23), /**< Mask hour */
|
||||
RTC_ALARM_MASK_MINUTE = (1U << 15), /**< Mask minute */
|
||||
RTC_ALARM_MASK_SECOND = (1U << 7), /**< Mask second */
|
||||
RTC_ALARM_MASK_ALL = 0x40808080U, /**< Mask all */
|
||||
} rtc_alarm_mask_t;
|
||||
|
||||
/**
|
||||
* @brief Alarm sub-second mask
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_ALARM_SS_MASK_NONE = 0xFU, /**< Mask is disable */
|
||||
RTC_ALARM_SS_MASK_14_1 = 0x1U, /**< Mask bit(1-14) */
|
||||
RTC_ALARM_SS_MASK_14_2 = 0x2U, /**< Mask bit(2-14) */
|
||||
RTC_ALARM_SS_MASK_14_3 = 0x3U, /**< Mask bit(3-14) */
|
||||
RTC_ALARM_SS_MASK_14_4 = 0x4U, /**< Mask bit(4-14) */
|
||||
RTC_ALARM_SS_MASK_14_5 = 0x5U, /**< Mask bit(5-14) */
|
||||
RTC_ALARM_SS_MASK_14_6 = 0x6U, /**< Mask bit(6-14) */
|
||||
RTC_ALARM_SS_MASK_14_7 = 0x7U, /**< Mask bit(7-14) */
|
||||
RTC_ALARM_SS_MASK_14_8 = 0x8U, /**< Mask bit(8-14) */
|
||||
RTC_ALARM_SS_MASK_14_9 = 0x9U, /**< Mask bit(9-14) */
|
||||
RTC_ALARM_SS_MASK_14_10 = 0xAU, /**< Mask bit(10-14) */
|
||||
RTC_ALARM_SS_MASK_14_11 = 0xBU, /**< Mask bit(11-14) */
|
||||
RTC_ALARM_SS_MASK_14_12 = 0xCU, /**< Mask bit(12-14) */
|
||||
RTC_ALARM_SS_MASK_14_13 = 0xDU, /**< Mask bit(13-14) */
|
||||
RTC_ALARM_SS_MASK_14 = 0xEU, /**< Mask bit14 */
|
||||
RTC_ALARM_SS_MASK_ALL = 0x0U, /**< Mask bit(0-14) */
|
||||
} rtc_sub_second_mask_t;
|
||||
|
||||
/**
|
||||
* @brief Alarm select week or day */
|
||||
typedef enum {
|
||||
RTC_SELECT_DAY = 0x0U, /**< Alarm select day */
|
||||
RTC_SELECT_WEEK = 0x1U, /**< Alarm select week */
|
||||
} rtc_week_day_sel_t;
|
||||
|
||||
/**
|
||||
* @brief Alarm structure
|
||||
*/
|
||||
typedef struct {
|
||||
rtc_alarm_idx_t idx; /**< Index of alarm */
|
||||
rtc_time_t time; /**< Time structure */
|
||||
uint32_t mask; /**< Alarm mask */
|
||||
rtc_sub_second_mask_t ss_mask; /**< Alarm sub-second mask */
|
||||
rtc_week_day_sel_t sel; /**< Select week or day */
|
||||
|
||||
union {
|
||||
uint8_t week; /**< Alarm select week */
|
||||
uint8_t day; /**< Alarm select day */
|
||||
};
|
||||
} rtc_alarm_t;
|
||||
|
||||
/**
|
||||
* @brief Time stamp signel select
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_TS_SIGNAL_SEL_TAMPER0 = 0U, /**< Select tamper0 */
|
||||
RTC_TS_SIGNAL_SEL_TAMPER1 = 1U, /**< Select tamper1 */
|
||||
} rtc_ts_signal_sel_t;
|
||||
|
||||
/**
|
||||
* @brief Time stamp trigger style
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_TS_RISING_EDGE = 0U, /**< Rising edge */
|
||||
RTC_TS_FALLING_EDGE = 1U, /**< Falling edge */
|
||||
} rtc_ts_trigger_style_t;
|
||||
|
||||
/**
|
||||
* @brief Index of tamper
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_TAMPER_0 = 0U, /**< Tamper0 */
|
||||
RTC_TAMPER_1 = 1U, /**< Tamper1 */
|
||||
} rtc_tamper_idx_t;
|
||||
|
||||
/**
|
||||
* @brief Tamper trigger type
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_TAMPER_TRIGGER_LOW = 0U, /**< High trigger */
|
||||
RTC_TAMPER_TRIGGER_HIGH = 1U, /**< Low trigger */
|
||||
} rtc_tamper_trigger_t;
|
||||
|
||||
/**
|
||||
* @brief Tamper sampling frequency
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_TAMPER_SAMPLING_FREQ_32768 = 0U, /**< RTCCLK / 32768 */
|
||||
RTC_TAMPER_SAMPLING_FREQ_16384 = 1U, /**< RTCCLK / 16384 */
|
||||
RTC_TAMPER_SAMPLING_FREQ_8192 = 2U, /**< RTCCLK / 8192 */
|
||||
RTC_TAMPER_SAMPLING_FREQ_4096 = 3U, /**< RTCCLK / 4096 */
|
||||
RTC_TAMPER_SAMPLING_FREQ_2048 = 4U, /**< RTCCLK / 2048 */
|
||||
RTC_TAMPER_SAMPLING_FREQ_1024 = 5U, /**< RTCCLK / 1024 */
|
||||
RTC_TAMPER_SAMPLING_FREQ_512 = 6U, /**< RTCCLK / 512 */
|
||||
RTC_TAMPER_SAMPLING_FREQ_256 = 7U, /**< RTCCLK / 256 */
|
||||
} rtc_tamper_sampling_freq_t;
|
||||
|
||||
/**
|
||||
* @brief Tamper filter time
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_TAMPER_DURATION_1 = 0U, /**< Duration 1 sampling */
|
||||
RTC_TAMPER_DURATION_2 = 1U, /**< Duration 2 sampling */
|
||||
RTC_TAMPER_DURATION_4 = 2U, /**< Duration 4 sampling */
|
||||
RTC_TAMPER_DURATION_8 = 3U, /**< Duration 8 sampling */
|
||||
} rtc_tamper_duration_t;
|
||||
|
||||
/**
|
||||
* @brief Tamper structure
|
||||
*/
|
||||
typedef struct {
|
||||
rtc_tamper_idx_t idx; /**< Index of tamper */
|
||||
rtc_tamper_trigger_t trig; /**< Trigger type */
|
||||
rtc_tamper_sampling_freq_t freq; /**< Sampling frequency */
|
||||
rtc_tamper_duration_t dur; /**< Filter time */
|
||||
type_func_t ts; /**< Enable/Disable trigger time stamp event */
|
||||
} rtc_tamper_t;
|
||||
|
||||
/**
|
||||
* @brief Wake-up clock
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_WAKEUP_CLOCK_DIV_16 = 0U, /**< RTCCLK / 16 */
|
||||
RTC_WAKEUP_CLOCK_DIV_8 = 1U, /**< RTCCLK / 8 */
|
||||
RTC_WAKEUP_CLOCK_DIV_4 = 2U, /**< RTCCLK / 4 */
|
||||
RTC_WAKEUP_CLOCK_DIV_2 = 3U, /**< RTCCLK / 2 */
|
||||
RTC_WAKEUP_CLOCK_1HZ = 4U, /**< 1Hz */
|
||||
RTC_WAKEUP_CLOCK_1HZ_PULS = 6U, /**< 1Hz and WUT + 65536 */
|
||||
} rtc_wakeup_clock_t;
|
||||
|
||||
/**
|
||||
* @brief RTC clock output type
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_CLOCK_OUTPUT_32768 = 0U, /**< 32768Hz */
|
||||
RTC_CLOCK_OUTPUT_1024 = 1U, /**< 1024Hz */
|
||||
RTC_CLOCK_OUTPUT_32 = 2U, /**< 32Hz */
|
||||
RTC_CLOCK_OUTPUT_1 = 3U, /**< 1Hz */
|
||||
RTC_CLOCK_OUTPUT_CAL_1 = 4U, /**< 1Hz after calibration */
|
||||
RTC_CLOCK_OUTPUT_EXA_1 = 5U, /**< Exact 1Hz */
|
||||
} rtc_clock_output_t;
|
||||
|
||||
/**
|
||||
* @ Calibration frequency
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_CALI_FREQ_10_SEC = 0U, /**< Calibrate every 10 seconds */
|
||||
RTC_CALI_FREQ_20_SEC = 1U, /**< Calibrate every 20 seconds */
|
||||
RTC_CALI_FREQ_1_MIN = 2U, /**< Calibrate every 1 minute */
|
||||
RTC_CALI_FREQ_2_MIN = 3U, /**< Calibrate every 2 minutes */
|
||||
RTC_CALI_FREQ_5_MIN = 4U, /**< Calibrate every 5 minutes */
|
||||
RTC_CALI_FREQ_10_MIN = 5U, /**< Calibrate every 10 minutes */
|
||||
RTC_CALI_FREQ_20_MIN = 6U, /**< Calibrate every 20 minutes */
|
||||
RTC_CALI_FREQ_1_SEC = 7U, /**< Calibrate every 1 second */
|
||||
} rtc_cali_freq_t;
|
||||
|
||||
/**
|
||||
* @brief Temperature compensate type
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_CALI_TC_NONE = 0U, /**< Temperature compensate disable */
|
||||
RTC_CALI_TC_AUTO_BY_HW = 1U, /**< Temperature compensate by hardware */
|
||||
RTC_CALI_TC_AUTO_BY_SF = 2U, /**< Temperature compensate by software */
|
||||
RTC_CALI_TC_AUTO_BY_HW_SF = 3U, /**< Temperature compensate by hardware, trigger by software */
|
||||
} rtc_cali_tc_t;
|
||||
|
||||
/**
|
||||
* @ Calculate frequency
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_CALI_CALC_FREQ_10_SEC = 0U, /**< Calculate every 10 seconds */
|
||||
RTC_CALI_CALC_FREQ_20_SEC = 1U, /**< Calculate every 20 seconds */
|
||||
RTC_CALI_CALC_FREQ_1_MIN = 2U, /**< Calculate every 1 minute */
|
||||
RTC_CALI_CALC_FREQ_2_MIN = 3U, /**< Calculate every 2 minutes */
|
||||
RTC_CALI_CALC_FREQ_5_MIN = 4U, /**< Calculate every 5 minutes */
|
||||
RTC_CALI_CALC_FREQ_10_MIN = 5U, /**< Calculate every 10 minutes */
|
||||
RTC_CALI_CALC_FREQ_20_MIN = 6U, /**< Calculate every 20 minutes */
|
||||
RTC_CALI_CALC_FREQ_1_HOUR = 7U, /**< Calculate every 1 hour */
|
||||
} rtc_cali_calc_freq_t;
|
||||
|
||||
/**
|
||||
* @brief Calibration algorithm
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_CALI_CALC_4 = 0U, /**< 4-polynomial */
|
||||
RTC_CALI_CALC_2 = 1U, /**< 2-parabola */
|
||||
} rtc_cali_calc_t;
|
||||
|
||||
/**
|
||||
* @brief Calibration structure
|
||||
*/
|
||||
typedef struct {
|
||||
rtc_cali_freq_t cali_freq; /**< calibrate frequency */
|
||||
rtc_cali_tc_t tc; /**< Temperature compensate type */
|
||||
rtc_cali_calc_freq_t calc_freq; /**< Calculate frequency */
|
||||
rtc_cali_calc_t calc; /**< algorithm */
|
||||
type_func_t acc; /**< Enable/Disable decimal accumulate */
|
||||
} rtc_cali_t;
|
||||
|
||||
/**
|
||||
* @brief Interrupt type
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_IT_SEC = (1U << 0), /**< Second */
|
||||
RTC_IT_MIN = (1U << 1), /**< Minute */
|
||||
RTC_IT_HR = (1U << 2), /**< Hour */
|
||||
RTC_IT_DAY = (1U << 3), /**< Day */
|
||||
RTC_IT_MON = (1U << 4), /**< Month */
|
||||
RTC_IT_YR = (1U << 5), /**< Year */
|
||||
RTC_IT_ALMA = (1U << 8), /**< Alarm-A */
|
||||
RTC_IT_ALMB = (1U << 9), /**< Alarm-B */
|
||||
RTC_IT_TS = (1U << 10), /**< Time stamp */
|
||||
RTC_IT_TSOV = (1U << 11), /**< Time stamp overflow */
|
||||
RTC_IT_TP0 = (1U << 12), /**< Tamper-0 */
|
||||
RTC_IT_TP1 = (1U << 13), /**< Tamper-1 */
|
||||
RTC_IT_RSC = (1U << 16), /**< Synchronous complete */
|
||||
RTC_IT_SFC = (1U << 17), /**< Shift complete */
|
||||
RTC_IT_WU = (1U << 18), /**< Wake-up */
|
||||
RTC_IT_TCC = (1U << 24), /**< Temperature compensate complete */
|
||||
RTC_IT_TCE = (1U << 25), /**< Temperature compensate error */
|
||||
} rtc_it_t;
|
||||
|
||||
/**
|
||||
* @brief Interrupt flag
|
||||
*/
|
||||
typedef enum {
|
||||
RTC_IF_SEC = (1U << 0), /**< Second */
|
||||
RTC_IF_MIN = (1U << 1), /**< Minute */
|
||||
RTC_IF_HR = (1U << 2), /**< Hour */
|
||||
RTC_IF_DAY = (1U << 3), /**< Day */
|
||||
RTC_IF_MON = (1U << 4), /**< Month */
|
||||
RTC_IF_YR = (1U << 5), /**< Year */
|
||||
RTC_IF_ALMA = (1U << 8), /**< Alarm-A */
|
||||
RTC_IF_ALMB = (1U << 9), /**< Alarm-B */
|
||||
RTC_IF_TS = (1U << 10), /**< Time stamp */
|
||||
RTC_IF_TSOV = (1U << 11), /**< Time stamp overflow */
|
||||
RTC_IF_TP0 = (1U << 12), /**< Tamper-0 */
|
||||
RTC_IF_TP1 = (1U << 13), /**< Tamper-1 */
|
||||
RTC_IF_RSC = (1U << 16), /**< Synchronous complete */
|
||||
RTC_IF_SFC = (1U << 17), /**< Shift complete */
|
||||
RTC_IF_WU = (1U << 18), /**< Wake-up */
|
||||
RTC_IF_TCC = (1U << 24), /**< Temperature compensate complete */
|
||||
RTC_IF_TCE = (1U << 25), /**< Temperature compensate error */
|
||||
} rtc_flag_t;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RTC_Public_Macro RTC Public Macros
|
||||
* @{
|
||||
*/
|
||||
#define RTC_UNLOCK() (WRITE_REG(RTC->WPR, 0x55AAAA55U))
|
||||
#define RTC_LOCK() (WRITE_REG(RTC->WPR, 0x0U))
|
||||
#define RTC_BY_PASS_ENABLE() \
|
||||
do { \
|
||||
RTC_UNLOCK(); \
|
||||
SET_BIT(RTC->CON, RTC_CON_SHDBP_MSK); \
|
||||
RTC_LOCK(); \
|
||||
} while (0)
|
||||
#define RTC_BY_PASS_DISABLE() \
|
||||
do { \
|
||||
RTC_UNLOCK(); \
|
||||
CLEAR_BIT(RTC->CON, RTC_CON_SHDBP_MSK); \
|
||||
RTC_LOCK(); \
|
||||
} while (0)
|
||||
#define RTC_SUMMER_TIME_ENABLE() \
|
||||
do { \
|
||||
RTC_UNLOCK(); \
|
||||
SET_BIT(RTC->CON, RTC_CON_ADD1H_MSK); \
|
||||
RTC_LOCK(); \
|
||||
} while (0)
|
||||
#define RTC_SUMMER_TIME_DISABLE() \
|
||||
do { \
|
||||
RTC_UNLOCK(); \
|
||||
CLEAR_BIT(RTC->CON, RTC_CON_ADD1H_MSK); \
|
||||
RTC_LOCK(); \
|
||||
} while (0)
|
||||
#define RTC_WINTER_TIME_ENABLE() \
|
||||
do { \
|
||||
RTC_UNLOCK(); \
|
||||
SET_BIT(RTC->CON, RTC_CON_SUB1H_MSK); \
|
||||
RTC_LOCK(); \
|
||||
} while (0)
|
||||
#define RTC_WINTER_TIME_DISABLE() \
|
||||
do { \
|
||||
RTC_UNLOCK(); \
|
||||
CLEAR_BIT(RTC->CON, RTC_CON_SUB1H_MSK); \
|
||||
RTC_LOCK(); \
|
||||
} while (0)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CAN_Private_Macros CAN Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define RTC_CALI_UNLOCK() (WRITE_REG(RTC->CALWPR, 0x699655AAU))
|
||||
#define RTC_CALI_LOCK() (WRITE_REG(RTC->CALWPR, 0x0U))
|
||||
#define ALARM_MASK_ALL 0x40808080
|
||||
#define RTC_TIMEOUT_VALUE 100
|
||||
|
||||
#define IS_SHIFT_SUB_SS(x) ((x) < (1U << 15))
|
||||
#define IS_RTC_HOUR_FORMAT(x) (((x) == RTC_HOUR_FORMAT_24) || \
|
||||
((x) == RTC_HOUR_FORMAT_12))
|
||||
#define IS_RTC_OUTPUT_SEL(x) (((x) == RTC_OUTPUT_DISABLE) || \
|
||||
((x) == RTC_OUTPUT_ALARM_A) || \
|
||||
((x) == RTC_OUTPUT_ALARM_B) || \
|
||||
((x) == RTC_OUTPUT_WAKEUP))
|
||||
#define IS_RTC_OUTPUT_POLARITY(x) (((x) == RTC_OUTPUT_POLARITY_HIGH) || \
|
||||
((x) == RTC_OUTPUT_POLARITY_LOW))
|
||||
#define IS_RTC_SOURCE_SEL(x) (((x) == RTC_SOURCE_LOSC) || \
|
||||
((x) == RTC_SOURCE_LRC) || \
|
||||
((x) == RTC_SOURCE_HRC_DIV_1M ) || \
|
||||
((x) == RTC_SOURCE_HOSC_DIV_1M))
|
||||
#define IS_RTC_ALARM(x) (((x) == RTC_ALARM_A) || \
|
||||
((x) == RTC_ALARM_B))
|
||||
#define IS_RTC_ALARM_SEL(x) (((x) == RTC_SELECT_DAY) || \
|
||||
((x) == RTC_SELECT_WEEK))
|
||||
#define IS_RTC_ALARM_MASK(x) (((x) == RTC_ALARM_MASK_NONE) || \
|
||||
((x) == RTC_ALARM_MASK_WEEK_DAY) || \
|
||||
((x) == RTC_ALARM_MASK_HOUR) || \
|
||||
((x) == RTC_ALARM_MASK_MINUTE) || \
|
||||
((x) == RTC_ALARM_MASK_SECOND) || \
|
||||
((x) == RTC_ALARM_MASK_ALL))
|
||||
#define IS_RTC_ALARM_SS_MASK(x) (((x) == RTC_ALARM_SS_MASK_NONE) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_1) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_2) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_3) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_4) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_5) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_6) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_7) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_8) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_9) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_10) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_11) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_12) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14_13) || \
|
||||
((x) == RTC_ALARM_SS_MASK_14) || \
|
||||
((x) == RTC_ALARM_SS_MASK_ALL))
|
||||
#define IS_RTC_TS_SIGNAL(x) (((x) == RTC_TS_SIGNAL_SEL_TAMPER0) || \
|
||||
((x) == RTC_TS_SIGNAL_SEL_TAMPER1))
|
||||
#define IS_RTC_TS_STYLE(x) (((x) == RTC_TS_RISING_EDGE) || \
|
||||
((x) == RTC_TS_FALLING_EDGE))
|
||||
#define IS_RTC_FORMAT(x) (((x) == RTC_FORMAT_DEC) || \
|
||||
((x) == RTC_FORMAT_BCD))
|
||||
#define IS_RTC_TAMPER(x) (((x) == RTC_TAMPER_0) || \
|
||||
((x) == RTC_TAMPER_1))
|
||||
#define IS_RTC_TAMPER_TRIGGER(x) (((x) == RTC_TAMPER_TRIGGER_LOW) || \
|
||||
((x) == RTC_TAMPER_TRIGGER_HIGH))
|
||||
#define IS_RTC_TAMPER_SAMPLING_FREQ(x) (((x) == RTC_TAMPER_SAMPLING_FREQ_32768) || \
|
||||
((x) == RTC_TAMPER_SAMPLING_FREQ_16384) || \
|
||||
((x) == RTC_TAMPER_SAMPLING_FREQ_8192) || \
|
||||
((x) == RTC_TAMPER_SAMPLING_FREQ_4096) || \
|
||||
((x) == RTC_TAMPER_SAMPLING_FREQ_2048) || \
|
||||
((x) == RTC_TAMPER_SAMPLING_FREQ_1024) || \
|
||||
((x) == RTC_TAMPER_SAMPLING_FREQ_512) || \
|
||||
((x) == RTC_TAMPER_SAMPLING_FREQ_256))
|
||||
#define IS_RTC_TAMPER_DURATION(x) (((x) == RTC_TAMPER_DURATION_1) || \
|
||||
((x) == RTC_TAMPER_DURATION_2) || \
|
||||
((x) == RTC_TAMPER_DURATION_4) || \
|
||||
((x) == RTC_TAMPER_DURATION_8))
|
||||
#define IS_RTC_WAKEUP_CLOCK(x) (((x) == RTC_WAKEUP_CLOCK_DIV_16) || \
|
||||
((x) == RTC_WAKEUP_CLOCK_DIV_8) || \
|
||||
((x) == RTC_WAKEUP_CLOCK_DIV_4) || \
|
||||
((x) == RTC_WAKEUP_CLOCK_DIV_2) || \
|
||||
((x) == RTC_WAKEUP_CLOCK_1HZ) || \
|
||||
((x) == RTC_WAKEUP_CLOCK_1HZ_PULS))
|
||||
#define IS_RTC_CLOCK_OUTPUT(x) (((x) == RTC_CLOCK_OUTPUT_32768) || \
|
||||
((x) == RTC_CLOCK_OUTPUT_1024) || \
|
||||
((x) == RTC_CLOCK_OUTPUT_32) || \
|
||||
((x) == RTC_CLOCK_OUTPUT_1) || \
|
||||
((x) == RTC_CLOCK_OUTPUT_CAL_1) || \
|
||||
((x) == RTC_CLOCK_OUTPUT_EXA_1))
|
||||
#define IS_RTC_CALI_FREQ(x) (((x) == RTC_CALI_FREQ_10_SEC) || \
|
||||
((x) == RTC_CALI_FREQ_20_SEC) || \
|
||||
((x) == RTC_CALI_FREQ_1_MIN) || \
|
||||
((x) == RTC_CALI_FREQ_2_MIN) || \
|
||||
((x) == RTC_CALI_FREQ_5_MIN) || \
|
||||
((x) == RTC_CALI_FREQ_10_MIN) || \
|
||||
((x) == RTC_CALI_FREQ_20_MIN) || \
|
||||
((x) == RTC_CALI_FREQ_1_SEC))
|
||||
#define IS_RTC_CALI_TC(x) (((x) == RTC_CALI_TC_NONE) || \
|
||||
((x) == RTC_CALI_TC_AUTO_BY_HW) || \
|
||||
((x) == RTC_CALI_TC_AUTO_BY_SF) || \
|
||||
((x) == RTC_CALI_TC_AUTO_BY_HW_SF))
|
||||
#define IS_RTC_CALC_FREQ(x) (((x) == RTC_CALI_CALC_FREQ_10_SEC) || \
|
||||
((x) == RTC_CALI_CALC_FREQ_20_SEC) || \
|
||||
((x) == RTC_CALI_CALC_FREQ_1_MIN) || \
|
||||
((x) == RTC_CALI_CALC_FREQ_2_MIN) || \
|
||||
((x) == RTC_CALI_CALC_FREQ_5_MIN) || \
|
||||
((x) == RTC_CALI_CALC_FREQ_10_MIN) || \
|
||||
((x) == RTC_CALI_CALC_FREQ_20_MIN) || \
|
||||
((x) == RTC_CALI_CALC_FREQ_1_HOUR))
|
||||
#define IS_RTC_CALI_CALC(x) (((x) == RTC_CALI_CALC_4) || \
|
||||
((x) == RTC_CALI_CALC_2))
|
||||
#define IS_RTC_IT(x) (((x) == RTC_IT_SEC) || \
|
||||
((x) == RTC_IT_MIN) || \
|
||||
((x) == RTC_IT_HR) || \
|
||||
((x) == RTC_IT_DAY) || \
|
||||
((x) == RTC_IT_MON) || \
|
||||
((x) == RTC_IT_YR) || \
|
||||
((x) == RTC_IT_ALMA) || \
|
||||
((x) == RTC_IT_ALMB) || \
|
||||
((x) == RTC_IT_TS) || \
|
||||
((x) == RTC_IT_TSOV) || \
|
||||
((x) == RTC_IT_TP0) || \
|
||||
((x) == RTC_IT_TP1) || \
|
||||
((x) == RTC_IT_RSC) || \
|
||||
((x) == RTC_IT_SFC) || \
|
||||
((x) == RTC_IT_WU) || \
|
||||
((x) == RTC_IT_TCC) || \
|
||||
((x) == RTC_IT_TCE))
|
||||
#define IS_RTC_IF(x) (((x) == RTC_IF_SEC) || \
|
||||
((x) == RTC_IF_MIN) || \
|
||||
((x) == RTC_IF_HR) || \
|
||||
((x) == RTC_IF_DAY) || \
|
||||
((x) == RTC_IF_MON) || \
|
||||
((x) == RTC_IF_YR) || \
|
||||
((x) == RTC_IF_ALMA) || \
|
||||
((x) == RTC_IF_ALMB) || \
|
||||
((x) == RTC_IF_TS) || \
|
||||
((x) == RTC_IF_TSOV) || \
|
||||
((x) == RTC_IF_TP0) || \
|
||||
((x) == RTC_IF_TP1) || \
|
||||
((x) == RTC_IF_RSC) || \
|
||||
((x) == RTC_IF_SFC) || \
|
||||
((x) == RTC_IF_WU) || \
|
||||
((x) == RTC_IF_TCC) || \
|
||||
((x) == RTC_IF_TCE))
|
||||
#define IS_RTC_SECOND(x) ((x) < 60)
|
||||
#define IS_RTC_MINUTE(x) ((x) < 60)
|
||||
#define IS_RTC_HOUR(x) ((x) < 24)
|
||||
#define IS_RTC_DAY(x) (((x) > 0) && ((x) < 32))
|
||||
#define IS_RTC_MONTH(x) (((x) > 0) && ((x) < 13))
|
||||
#define IS_RTC_YEAR(x) ((x) < 100)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup RTC_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup RTC_Public_Functions_Group1
|
||||
* @{
|
||||
*/
|
||||
/* Initialization functions */
|
||||
void ald_rtc_reset(void);
|
||||
void ald_rtc_init(rtc_init_t *init);
|
||||
void ald_rtc_source_select(rtc_source_sel_t sel);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup RTC_Public_Functions_Group2
|
||||
* @{
|
||||
*/
|
||||
/* Time and date operation functions */
|
||||
ald_status_t ald_rtc_set_time(rtc_time_t *time, rtc_format_t format);
|
||||
ald_status_t ald_rtc_set_date(rtc_date_t *date, rtc_format_t format);
|
||||
void ald_rtc_get_time(rtc_time_t *time, rtc_format_t format);
|
||||
void ald_rtc_get_date(rtc_date_t *date, rtc_format_t format);
|
||||
int32_t ald_rtc_get_date_time(rtc_date_t *date, rtc_time_t *time, rtc_format_t format);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup RTC_Public_Functions_Group3
|
||||
* @{
|
||||
*/
|
||||
/* Alarm functions */
|
||||
void ald_rtc_set_alarm(rtc_alarm_t *alarm, rtc_format_t format);
|
||||
void ald_rtc_get_alarm(rtc_alarm_t *alarm, rtc_format_t format);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup RTC_Public_Functions_Group4
|
||||
* @{
|
||||
*/
|
||||
/* Time stamp functions */
|
||||
void ald_rtc_set_time_stamp(rtc_ts_signal_sel_t sel, rtc_ts_trigger_style_t style);
|
||||
void ald_rtc_cancel_time_stamp(void);
|
||||
void ald_rtc_get_time_stamp(rtc_time_t *ts_time, rtc_date_t *ts_date, rtc_format_t format);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup RTC_Public_Functions_Group5
|
||||
* @{
|
||||
*/
|
||||
/* Tamper functions */
|
||||
void ald_rtc_set_tamper(rtc_tamper_t *tamper);
|
||||
void ald_rtc_cancel_tamper(rtc_tamper_idx_t idx);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup RTC_Public_Functions_Group6
|
||||
* @{
|
||||
*/
|
||||
/* Wakeup functions */
|
||||
void ald_rtc_set_wakeup(rtc_wakeup_clock_t clock, uint16_t value);
|
||||
void ald_rtc_cancel_wakeup(void);
|
||||
uint16_t ald_rtc_get_wakeup_timer_value(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup RTC_Public_Functions_Group7
|
||||
* @{
|
||||
*/
|
||||
/* Clock output functions */
|
||||
ald_status_t ald_rtc_set_clock_output(rtc_clock_output_t clock);
|
||||
void ald_rtc_cancel_clock_output(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/** @addtogroup RTC_Public_Functions_Group8
|
||||
* @{
|
||||
*/
|
||||
/* Control functions */
|
||||
void ald_rtc_interrupt_config(rtc_it_t it, type_func_t state);
|
||||
void ald_rtc_alarm_cmd(rtc_alarm_idx_t idx, type_func_t state);
|
||||
ald_status_t ald_rtc_set_shift(type_func_t add_1s, uint16_t sub_ss);
|
||||
void ald_rtc_set_cali(rtc_cali_t *config);
|
||||
void ald_rtc_cancel_cali(void);
|
||||
ald_status_t ald_rtc_get_cali_status(void);
|
||||
void ald_rtc_write_temp(uint16_t temp);
|
||||
it_status_t ald_rtc_get_it_status(rtc_it_t it);
|
||||
flag_status_t ald_rtc_get_flag_status(rtc_flag_t flag);
|
||||
void ald_rtc_clear_flag_status(rtc_flag_t flag);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user