From 8063250f66b741a9a1379b6e47257d146db902e7 Mon Sep 17 00:00:00 2001 From: lgv Date: Wed, 7 Jan 2026 11:41:07 +0800 Subject: [PATCH] feat:add erpc usb cdc interface --- .config | 69 +- CMakeLists.txt | 120 +- .../proto/generated/c_head_service_client.cpp | 10 +- .../proto/generated/c_head_service_client.h | 5 +- .../proto/generated/c_head_service_server.cpp | 10 +- .../proto/generated/c_head_service_server.h | 5 +- .../proto/generated/head_service_client.cpp | 85 +- .../proto/generated/head_service_client.hpp | 4 +- .../proto/generated/head_service_common.h | 13 +- .../proto/generated/head_service_common.hpp | 13 +- .../generated/head_service_interface.cpp | 2 +- .../generated/head_service_interface.hpp | 5 +- .../proto/generated/head_service_server.cpp | 99 +- .../proto/generated/head_service_server.hpp | 5 +- applications/erpc/proto/head_service.erpc | 3 +- .../erpc/service/include/head_service_impl.h | 1 + .../erpc/service/src/erpc_server_main.cpp | 10 +- .../erpc/service/src/head_service_impl.cpp | 22 +- applications/main.c | 11 +- board/CubeMX_Config/.mxproject | 10 +- board/CubeMX_Config/CubeMX_Config.ioc | 134 +- .../Inc/stm32h7xx_hal_pcd.h | 444 ++ ...xx_hal_spi_ex.h => stm32h7xx_hal_pcd_ex.h} | 78 +- .../Inc/stm32h7xx_hal_spi.h | 1130 ----- .../Inc/stm32h7xx_ll_spi.h | 3781 ---------------- .../Inc/stm32h7xx_ll_usb.h | 578 +++ .../Src/stm32h7xx_hal_pcd.c | 2346 ++++++++++ .../Src/stm32h7xx_hal_pcd_ex.c | 341 ++ .../Src/stm32h7xx_hal_spi.c | 4016 ----------------- .../Src/stm32h7xx_hal_spi_ex.c | 226 - .../Src/stm32h7xx_ll_usb.c | 2257 +++++++++ board/CubeMX_Config/Inc/stm32h7xx_hal_conf.h | 4 +- board/CubeMX_Config/Inc/stm32h7xx_it.h | 1 + board/CubeMX_Config/Inc/usb_device.h | 102 + board/CubeMX_Config/Inc/usbd_cdc_if.h | 132 + board/CubeMX_Config/Inc/usbd_conf.h | 173 + board/CubeMX_Config/Inc/usbd_desc.h | 143 + .../Class/CDC/Inc/usbd_cdc.h | 184 + .../Class/CDC/Src/usbd_cdc.c | 893 ++++ .../Core/Inc/usbd_core.h | 175 + .../Core/Inc/usbd_ctlreq.h | 101 + .../Core/Inc/usbd_def.h | 523 +++ .../Core/Inc/usbd_ioreq.h | 113 + .../Core/Src/usbd_core.c | 1215 +++++ .../Core/Src/usbd_ctlreq.c | 1058 +++++ .../Core/Src/usbd_ioreq.c | 224 + .../ST/STM32_USB_Device_Library/LICENSE.txt | 86 + board/CubeMX_Config/Src/main.c | 75 +- board/CubeMX_Config/Src/stm32h7xx_hal_msp.c | 171 +- board/CubeMX_Config/Src/stm32h7xx_it.c | 16 +- board/CubeMX_Config/Src/usb_device.c | 101 + board/CubeMX_Config/Src/usbd_cdc_if.c | 328 ++ board/CubeMX_Config/Src/usbd_conf.c | 693 +++ board/CubeMX_Config/Src/usbd_desc.c | 418 ++ .../cmake/stm32cubemx/CMakeLists.txt | 38 +- board/Kconfig | 4 + board/SConscript | 4 +- board/board.c | 22 +- board/linker_scripts/link.lds | 51 +- board/ports/{ => qflash}/qspi_flash_init.c | 0 board/ports/usb/usb_cdc_char_device.c | 408 ++ board/ports/usb/usb_cdc_char_device.h | 20 + board/ports/usb/usb_cdc_init.c | 154 + board/ports/usb/usb_config.h | 320 ++ packages/Kconfig | 3 + packages/erpc-1.14.0/SConscript | 5 + .../erpc-1.14.0/erpc_c/port/erpc_port_rtt.cpp | 15 + .../transports/erpc_usb_cdc_transport.cpp | 352 +- .../transports/erpc_usb_cdc_transport.hpp | 142 +- packages/packages.dbsqlite | Bin 8192 -> 147456 bytes .../drivers/usb/cherryusb/core/usbd_core.h | 2 +- .../drivers/usb/cherryusb/core/usbh_core.h | 2 +- .../cherryusb/platform/rtthread/usb_check.c | 2 +- rtconfig.h | 15 +- 74 files changed, 14544 insertions(+), 9777 deletions(-) create mode 100644 board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd.h rename board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/{stm32h7xx_hal_spi_ex.h => stm32h7xx_hal_pcd_ex.h} (51%) delete mode 100644 board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h delete mode 100644 board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_spi.h create mode 100644 board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usb.h create mode 100644 board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c create mode 100644 board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c delete mode 100644 board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c delete mode 100644 board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c create mode 100644 board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c create mode 100644 board/CubeMX_Config/Inc/usb_device.h create mode 100644 board/CubeMX_Config/Inc/usbd_cdc_if.h create mode 100644 board/CubeMX_Config/Inc/usbd_conf.h create mode 100644 board/CubeMX_Config/Inc/usbd_desc.h create mode 100644 board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h create mode 100644 board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c create mode 100644 board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h create mode 100644 board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h create mode 100644 board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h create mode 100644 board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h create mode 100644 board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c create mode 100644 board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c create mode 100644 board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c create mode 100644 board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/LICENSE.txt create mode 100644 board/CubeMX_Config/Src/usb_device.c create mode 100644 board/CubeMX_Config/Src/usbd_cdc_if.c create mode 100644 board/CubeMX_Config/Src/usbd_conf.c create mode 100644 board/CubeMX_Config/Src/usbd_desc.c rename board/ports/{ => qflash}/qspi_flash_init.c (100%) create mode 100644 board/ports/usb/usb_cdc_char_device.c create mode 100644 board/ports/usb/usb_cdc_char_device.h create mode 100644 board/ports/usb/usb_cdc_init.c create mode 100644 board/ports/usb/usb_config.h create mode 100644 packages/erpc-1.14.0/erpc_c/port/erpc_port_rtt.cpp diff --git a/.config b/.config index 4964e5b..c18a2c6 100644 --- a/.config +++ b/.config @@ -172,7 +172,7 @@ CONFIG_RT_USING_HEAP=y # end of Memory Management CONFIG_RT_USING_DEVICE=y -# CONFIG_RT_USING_DEVICE_OPS is not set +CONFIG_RT_USING_DEVICE_OPS=y # CONFIG_RT_USING_INTERRUPT_INFO is not set # CONFIG_RT_USING_THREADSAFE_PRINTF is not set CONFIG_RT_USING_CONSOLE=y @@ -236,7 +236,7 @@ CONFIG_RT_USING_SERIAL=y CONFIG_RT_USING_SERIAL_V1=y # CONFIG_RT_USING_SERIAL_V2 is not set CONFIG_RT_SERIAL_USING_DMA=y -CONFIG_RT_SERIAL_RB_BUFSZ=1024 +CONFIG_RT_SERIAL_RB_BUFSZ=64 # CONFIG_RT_USING_SERIAL_BYPASS is not set # CONFIG_RT_USING_CAN is not set # CONFIG_RT_USING_CPUTIME is not set @@ -275,7 +275,60 @@ CONFIG_RT_USING_SPI=y CONFIG_RT_USING_PIN=y CONFIG_RT_USING_KTIME=y # CONFIG_RT_USING_HWTIMER is not set -# CONFIG_RT_USING_CHERRYUSB is not set +CONFIG_RT_USING_CHERRYUSB=y +CONFIG_RT_CHERRYUSB_DEVICE=y +CONFIG_RT_CHERRYUSB_DEVICE_SPEED_FS=y +# CONFIG_RT_CHERRYUSB_DEVICE_SPEED_HS is not set +# CONFIG_RT_CHERRYUSB_DEVICE_SPEED_AUTO is not set +# CONFIG_RT_CHERRYUSB_DEVICE_CUSTOM is not set +# CONFIG_RT_CHERRYUSB_DEVICE_FSDEV_ST is not set +# CONFIG_RT_CHERRYUSB_DEVICE_FSDEV_CUSTOM is not set +CONFIG_RT_CHERRYUSB_DEVICE_DWC2_ST=y +# CONFIG_RT_CHERRYUSB_DEVICE_DWC2_ESP is not set +# CONFIG_RT_CHERRYUSB_DEVICE_DWC2_KENDRYTE is not set +# CONFIG_RT_CHERRYUSB_DEVICE_DWC2_AT is not set +# CONFIG_RT_CHERRYUSB_DEVICE_DWC2_HC is not set +# CONFIG_RT_CHERRYUSB_DEVICE_DWC2_NATION is not set +# CONFIG_RT_CHERRYUSB_DEVICE_DWC2_GD is not set +# CONFIG_RT_CHERRYUSB_DEVICE_DWC2_CUSTOM is not set +# CONFIG_RT_CHERRYUSB_DEVICE_MUSB_ES is not set +# CONFIG_RT_CHERRYUSB_DEVICE_MUSB_SUNXI is not set +# CONFIG_RT_CHERRYUSB_DEVICE_MUSB_BK is not set +# CONFIG_RT_CHERRYUSB_DEVICE_MUSB_SIFLI is not set +# CONFIG_RT_CHERRYUSB_DEVICE_MUSB_CUSTOM is not set +# CONFIG_RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX is not set +# CONFIG_RT_CHERRYUSB_DEVICE_CHIPIDEA_CUSTOM is not set +# CONFIG_RT_CHERRYUSB_DEVICE_KINETIS_MCX is not set +# CONFIG_RT_CHERRYUSB_DEVICE_KINETIS_MM32 is not set +# CONFIG_RT_CHERRYUSB_DEVICE_KINETIS_CUSTOM is not set +# CONFIG_RT_CHERRYUSB_DEVICE_BL is not set +# CONFIG_RT_CHERRYUSB_DEVICE_HPM is not set +# CONFIG_RT_CHERRYUSB_DEVICE_AIC is not set +# CONFIG_RT_CHERRYUSB_DEVICE_RP2040 is not set +# CONFIG_RT_CHERRYUSB_DEVICE_CH32 is not set +# CONFIG_RT_CHERRYUSB_DEVICE_PUSB2 is not set +# CONFIG_RT_CHERRYUSB_DEVICE_NRF5X is not set +CONFIG_RT_CHERRYUSB_DEVICE_CDC_ACM=y +# CONFIG_RT_CHERRYUSB_DEVICE_HID is not set +# CONFIG_RT_CHERRYUSB_DEVICE_MSC is not set +# CONFIG_RT_CHERRYUSB_DEVICE_AUDIO is not set +# CONFIG_RT_CHERRYUSB_DEVICE_VIDEO is not set +# CONFIG_RT_CHERRYUSB_DEVICE_CDC_RNDIS is not set +# CONFIG_RT_CHERRYUSB_DEVICE_CDC_ECM is not set +# CONFIG_RT_CHERRYUSB_DEVICE_CDC_NCM is not set +# CONFIG_RT_CHERRYUSB_DEVICE_MTP is not set +# CONFIG_RT_CHERRYUSB_DEVICE_ADB is not set +# CONFIG_RT_CHERRYUSB_DEVICE_DFU is not set +# CONFIG_RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV is not set +CONFIG_CONFIG_USBDEV_REQUEST_BUFFER_LEN=1024 +CONFIG_CONFIG_USBDEV_MSC_MAX_BUFSIZE=1024 +# CONFIG_CONFIG_USBDEV_RNDIS_USING_LWIP is not set +# CONFIG_CONFIG_USBDEV_CDC_ECM_USING_LWIP is not set +CONFIG_RT_CHERRYUSB_DEVICE_TEMPLATE_NONE=y +# CONFIG_RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM is not set +# CONFIG_RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1 is not set +# CONFIG_RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC is not set +# CONFIG_RT_CHERRYUSB_HOST is not set # end of Device Drivers # @@ -324,7 +377,7 @@ CONFIG_PTHREAD_NUM_MAX=8 CONFIG_RT_USING_CPLUSPLUS=y # CONFIG_RT_USING_CPLUSPLUS11 is not set # CONFIG_RT_USING_CPP_WRAPPER is not set -# CONFIG_RT_USING_CPP_EXCEPTIONS is not set +CONFIG_RT_USING_CPP_EXCEPTIONS=y # end of C/C++ and POSIX layer # @@ -585,6 +638,7 @@ CONFIG_RT_USING_CPLUSPLUS=y # # tools packages # +# CONFIG_PKG_USING_VECTOR is not set # CONFIG_PKG_USING_CMBACKTRACE is not set # CONFIG_PKG_USING_MCOREDUMP is not set # CONFIG_PKG_USING_EASYFLASH is not set @@ -1079,6 +1133,7 @@ CONFIG_PKG_STM32H7_CMSIS_DRIVER_VER="latest" # CONFIG_PKG_USING_IST8310 is not set # CONFIG_PKG_USING_ST7789_SPI is not set # CONFIG_PKG_USING_ISOTP_C is not set +# CONFIG_PKG_USING_IKUNLED is not set # CONFIG_PKG_USING_SPI_TOOLS is not set # end of peripheral libraries and drivers @@ -1441,6 +1496,7 @@ CONFIG_BSP_SCB_ENABLE_I_CACHE=y # CONFIG_BSP_SCB_ENABLE_D_CACHE is not set CONFIG_BSP_ENABLE_FPU=y CONFIG_BSP_USING_GPIO=y +# CONFIG_BSP_USING_USBD is not set CONFIG_BSP_USING_UART=y CONFIG_BSP_STM32_UART_V1_TX_TIMEOUT=6000 CONFIG_BSP_USING_UART1=y @@ -1476,9 +1532,10 @@ CONFIG_BSP_USING_ERPC=y CONFIG_ERPC_USING_RTT=y CONFIG_ERPC_MODE=y CONFIG_ERPC_MODE_SERVER=y -CONFIG_ERPC_MODE_CLIENT=y +# CONFIG_ERPC_MODE_CLIENT is not set CONFIG_ERPC_TRANSPORTS=y # CONFIG_ERPC_TRANSPORTS_SPI is not set -CONFIG_ERPC_TRANSPORTS_UART=y +# CONFIG_ERPC_TRANSPORTS_UART is not set # CONFIG_ERPC_TRANSPORTS_TCP is not set +CONFIG_ERPC_TRANSPORTS_USB_CDC=y # end of Third Packages Drivers diff --git a/CMakeLists.txt b/CMakeLists.txt index ef9453f..c29f29c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ SET(CMAKE_ASM_FLAGS " -c -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard SET(CMAKE_C_COMPILER_WORKS TRUE) SET(CMAKE_CXX_COMPILER "C:/tool/rtthread/env-windows/tools/bin/../../tools/gnu_gcc/arm_gcc/mingw/bin/arm-none-eabi-g++.exe") -SET(CMAKE_CXX_FLAGS " -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -Wl,--gc-sections") +SET(CMAKE_CXX_FLAGS " -mcpu=cortex-m7 -mthumb -mfpu=fpv5-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g") SET(CMAKE_CXX_COMPILER_WORKS TRUE) SET(CMAKE_OBJCOPY "C:/tool/rtthread/env-windows/tools/bin/../../tools/gnu_gcc/arm_gcc/mingw/bin/arm-none-eabi-objcopy.exe") @@ -36,6 +36,7 @@ INCLUDE_DIRECTORIES( applications/erpc/proto/generated board board/CubeMX_Config/Inc + board/ports/usb libraries/HAL_Drivers/CMSIS/Include packages/erpc-1.14.0/erpc_c packages/erpc-1.14.0/erpc_c/config @@ -52,6 +53,23 @@ INCLUDE_DIRECTORIES( rt-thread/components/drivers/phy rt-thread/components/drivers/smp_call rt-thread/components/drivers/spi + rt-thread/components/drivers/usb/cherryusb + rt-thread/components/drivers/usb/cherryusb/common + rt-thread/components/drivers/usb/cherryusb/core + rt-thread/components/drivers/usb/cherryusb/class/hub + rt-thread/components/drivers/usb/cherryusb/class/cdc + rt-thread/components/drivers/usb/cherryusb/class/msc + rt-thread/components/drivers/usb/cherryusb/class/hid + rt-thread/components/drivers/usb/cherryusb/class/audio + rt-thread/components/drivers/usb/cherryusb/class/video + rt-thread/components/drivers/usb/cherryusb/class/wireless + rt-thread/components/drivers/usb/cherryusb/class/midi + rt-thread/components/drivers/usb/cherryusb/class/adb + rt-thread/components/drivers/usb/cherryusb/class/dfu + rt-thread/components/drivers/usb/cherryusb/class/vendor/net + rt-thread/components/drivers/usb/cherryusb/class/vendor/serial + rt-thread/components/drivers/usb/cherryusb/class/vendor/wifi + rt-thread/components/drivers/usb/cherryusb/osal rt-thread/components/finsh rt-thread/components/libc/compilers/common/include rt-thread/components/libc/compilers/newlib @@ -84,17 +102,25 @@ ADD_DEFINITIONS( # Library source files SET(RT_APP_ERPC_SOURCES applications/erpc/service/src/erpc_server_main.cpp + applications/erpc/proto/generated/head_service_interface.cpp applications/erpc/common/src/erpc_error_handler.cpp applications/erpc/service/src/head_service_impl.cpp applications/erpc/proto/generated/head_service_server.cpp - applications/erpc/client/src/erpc_client_main.cpp - applications/erpc/proto/generated/head_service_interface.cpp - applications/erpc/proto/generated/head_service_client.cpp ) SET(RT_APPLICATIONS_SOURCES - applications/servo.c applications/main.c + applications/servo.c +) + +SET(RT_CHERRYUSB_SOURCES + rt-thread/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c + rt-thread/components/drivers/usb/cherryusb/class/cdc/usbd_cdc_acm.c + rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c + rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_msh.c + rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_glue_st.c + rt-thread/components/drivers/usb/cherryusb/core/usbd_core.c + rt-thread/components/drivers/usb/cherryusb/port/dwc2/usb_dc_dwc2.c ) SET(RT_COMPILER_SOURCES @@ -108,8 +134,8 @@ SET(RT_COMPILER_SOURCES ) SET(RT_CPP_SOURCES - rt-thread/components/libc/cplusplus/cxx_crt.cpp rt-thread/components/libc/cplusplus/cxx_crt_init.c + rt-thread/components/libc/cplusplus/cxx_crt.cpp ) SET(RT_DEVICEDRIVERS_SOURCES @@ -132,7 +158,8 @@ SET(RT_DEVICEDRIVERS_SOURCES SET(RT_DRIVERS_SOURCES board/CubeMX_Config/Src/stm32h7xx_hal_msp.c board/board.c - board/ports/qspi_flash_init.c + board/ports/usb/usb_cdc_char_device.c + board/ports/usb/usb_cdc_init.c libraries/STM32H7xx_HAL/CMSIS/Device/ST/STM32H7xx/Source/Templates/gcc/startup_stm32h750xx.s libraries/HAL_Drivers/drivers/drv_gpio.c libraries/HAL_Drivers/drivers/drv_spi.c @@ -141,31 +168,28 @@ SET(RT_DRIVERS_SOURCES ) SET(RT_ERPC_SOURCES - packages/erpc-1.14.0/erpc_c/setup/erpc_setup_mbf_dynamic.cpp - packages/erpc-1.14.0/erpc_c/setup/erpc_server_setup.cpp packages/erpc-1.14.0/erpc_c/infra/erpc_server.cpp - packages/erpc-1.14.0/erpc_c/setup/erpc_setup_mbf_static.cpp - packages/erpc-1.14.0/erpc_c/infra/erpc_simple_server.cpp - packages/erpc-1.14.0/erpc_c/setup/erpc_setup_serial.cpp - packages/erpc-1.14.0/erpc_c/infra/erpc_pre_post_action.cpp - packages/erpc-1.14.0/erpc_c/infra/erpc_message_buffer.cpp - packages/erpc-1.14.0/erpc_c/infra/erpc_basic_codec.cpp - packages/erpc-1.14.0/erpc_c/infra/erpc_framed_transport.cpp - packages/erpc-1.14.0/erpc_c/infra/erpc_client_manager.cpp - packages/erpc-1.14.0/erpc_c/transports/erpc_serial_transport.cpp - packages/erpc-1.14.0/erpc_c/infra/erpc_message_loggers.cpp - packages/erpc-1.14.0/erpc_c/port/erpc_threading_pthreads.cpp - packages/erpc-1.14.0/erpc_c/infra/erpc_transport_arbitrator.cpp - packages/erpc-1.14.0/erpc_c/infra/erpc_arbitrated_client_manager.cpp - packages/erpc-1.14.0/erpc_c/transports/erpc_inter_thread_buffer_transport.cpp + packages/erpc-1.14.0/erpc_c/port/erpc_port_rtt.cpp packages/erpc-1.14.0/erpc_c/infra/erpc_crc16.cpp - packages/erpc-1.14.0/erpc_c/setup/erpc_arbitrated_client_setup.cpp - packages/erpc-1.14.0/erpc_c/setup/erpc_client_setup.cpp + packages/erpc-1.14.0/erpc_c/infra/erpc_simple_server.cpp + packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.cpp + packages/erpc-1.14.0/erpc_c/infra/erpc_message_loggers.cpp + packages/erpc-1.14.0/erpc_c/setup/erpc_server_setup.cpp + packages/erpc-1.14.0/erpc_c/infra/erpc_transport_arbitrator.cpp + packages/erpc-1.14.0/erpc_c/infra/erpc_framed_transport.cpp + packages/erpc-1.14.0/erpc_c/infra/erpc_message_buffer.cpp + packages/erpc-1.14.0/erpc_c/transports/erpc_inter_thread_buffer_transport.cpp + packages/erpc-1.14.0/erpc_c/infra/erpc_basic_codec.cpp + packages/erpc-1.14.0/erpc_c/setup/erpc_setup_mbf_static.cpp + packages/erpc-1.14.0/erpc_c/setup/erpc_setup_usb_cdc.cpp + packages/erpc-1.14.0/erpc_c/infra/erpc_pre_post_action.cpp + packages/erpc-1.14.0/erpc_c/setup/erpc_setup_mbf_dynamic.cpp + packages/erpc-1.14.0/erpc_c/port/erpc_threading_pthreads.cpp ) SET(RT_FINSH_SOURCES - rt-thread/components/finsh/cmd.c rt-thread/components/finsh/msh.c + rt-thread/components/finsh/cmd.c rt-thread/components/finsh/msh_parse.c rt-thread/components/finsh/shell.c ) @@ -189,17 +213,17 @@ SET(RT_KERNEL_SOURCES ) SET(RT_KLIBC_SOURCES - rt-thread/src/klibc/rt_vsscanf.c rt-thread/src/klibc/rt_vsnprintf_tiny.c - rt-thread/src/klibc/kerrno.c - rt-thread/src/klibc/kstdio.c + rt-thread/src/klibc/rt_vsscanf.c rt-thread/src/klibc/kstring.c + rt-thread/src/klibc/kstdio.c + rt-thread/src/klibc/kerrno.c ) SET(RT_KTIME_SOURCES + rt-thread/components/drivers/ktime/src/cputimer.c rt-thread/components/drivers/ktime/src/hrtimer.c rt-thread/components/drivers/ktime/src/boottime.c - rt-thread/components/drivers/ktime/src/cputimer.c ) SET(RT_LIBCPU_SOURCES @@ -212,30 +236,30 @@ SET(RT_LIBCPU_SOURCES ) SET(RT_LIBRARIES_SOURCES - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc_ex.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cec.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_comp.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_usart.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rng.c libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cryp.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cec.c + libraries/STM32H7xx_HAL/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sram.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_comp.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cryp_ex.c libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma_ex.c libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_usart.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cryp_ex.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc.c + libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c - libraries/STM32H7xx_HAL/CMSIS/Device/ST/STM32H7xx/Source/Templates/system_stm32h7xx.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_sram.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_crc_ex.c - libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rng.c ) SET(RT_POSIX_SOURCES @@ -276,6 +300,7 @@ SET(RT_COMPILER_LIBS # Libraries ADD_LIBRARY(rtt_app_erpc OBJECT ${RT_APP_ERPC_SOURCES}) +ADD_LIBRARY(rtt_CherryUSB OBJECT ${RT_CHERRYUSB_SOURCES}) ADD_LIBRARY(rtt_Compiler OBJECT ${RT_COMPILER_SOURCES}) ADD_LIBRARY(rtt_CPP OBJECT ${RT_CPP_SOURCES}) ADD_LIBRARY(rtt_DeviceDrivers OBJECT ${RT_DEVICEDRIVERS_SOURCES}) @@ -303,6 +328,7 @@ TARGET_LINK_LIBRARIES(rtt_Compiler INTERFACE ${RT_COMPILER_LIBS}) ADD_EXECUTABLE(${CMAKE_PROJECT_NAME}.elf ${RT_APPLICATIONS_SOURCES}) TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME}.elf rtt_app_erpc + rtt_CherryUSB rtt_Compiler rtt_CPP rtt_DeviceDrivers diff --git a/applications/erpc/proto/generated/c_head_service_client.cpp b/applications/erpc/proto/generated/c_head_service_client.cpp index 8455bdb..5cb44b0 100644 --- a/applications/erpc/proto/generated/c_head_service_client.cpp +++ b/applications/erpc/proto/generated/c_head_service_client.cpp @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -28,6 +28,14 @@ int32_t add(int32_t a, int32_t b) return result; } +int64_t sum_i32(const list_int32_1_t * arr) +{ + int64_t result; + result = s_demo_client->sum_i32(arr); + + return result; +} + void initdemo_client(erpc_client_t client) { #if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC diff --git a/applications/erpc/proto/generated/c_head_service_client.h b/applications/erpc/proto/generated/c_head_service_client.h index dce06f0..9d8dcf1 100644 --- a/applications/erpc/proto/generated/c_head_service_client.h +++ b/applications/erpc/proto/generated/c_head_service_client.h @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -25,11 +25,14 @@ enum _demo_ids { kdemo_service_id = 1, kdemo_add_id = 1, + kdemo_sum_i32_id = 2, }; //! @name demo //@{ int32_t add(int32_t a, int32_t b); + +int64_t sum_i32(const list_int32_1_t * arr); //@} #endif // ERPC_FUNCTIONS_DEFINITIONS diff --git a/applications/erpc/proto/generated/c_head_service_server.cpp b/applications/erpc/proto/generated/c_head_service_server.cpp index be321bb..734aded 100644 --- a/applications/erpc/proto/generated/c_head_service_server.cpp +++ b/applications/erpc/proto/generated/c_head_service_server.cpp @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -28,6 +28,14 @@ class demo_server: public demo_interface return result; } + + int64_t sum_i32(const list_int32_1_t * arr) + { + int64_t result; + result = ::sum_i32(arr); + + return result; + } }; ERPC_MANUALLY_CONSTRUCTED_STATIC(demo_service, s_demo_service); diff --git a/applications/erpc/proto/generated/c_head_service_server.h b/applications/erpc/proto/generated/c_head_service_server.h index 9e73208..cdffa87 100644 --- a/applications/erpc/proto/generated/c_head_service_server.h +++ b/applications/erpc/proto/generated/c_head_service_server.h @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -26,11 +26,14 @@ enum _demo_ids { kdemo_service_id = 1, kdemo_add_id = 1, + kdemo_sum_i32_id = 2, }; //! @name demo //@{ int32_t add(int32_t a, int32_t b); + +int64_t sum_i32(const list_int32_1_t * arr); //@} diff --git a/applications/erpc/proto/generated/head_service_client.cpp b/applications/erpc/proto/generated/head_service_client.cpp index f2556a7..eb18f5b 100644 --- a/applications/erpc/proto/generated/head_service_client.cpp +++ b/applications/erpc/proto/generated/head_service_client.cpp @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -20,6 +20,26 @@ using namespace erpc; using namespace std; using namespace erpcShim; +//! @brief Function to write struct list_int32_1_t +static void write_list_int32_1_t_struct(erpc::Codec * codec, const list_int32_1_t * data); + + +// Write struct list_int32_1_t function implementation +static void write_list_int32_1_t_struct(erpc::Codec * codec, const list_int32_1_t * data) +{ + if(NULL == data) + { + return; + } + + codec->startWriteList(data->elementsCount); + for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount) + { + codec->write(data->elements[listCount]); + } +} + + demo_client::demo_client(ClientManager *manager) @@ -88,6 +108,69 @@ int32_t demo_client::add(int32_t a, int32_t b) #endif + if (err != kErpcStatus_Success) + { + result = -1; + } + + return result; +} + +// demo interface sum_i32 function client shim. +int64_t demo_client::sum_i32(const list_int32_1_t * arr) +{ + erpc_status_t err = kErpcStatus_Success; + + int64_t result; + +#if ERPC_PRE_POST_ACTION + pre_post_action_cb preCB = m_clientManager->getPreCB(); + if (preCB) + { + preCB(); + } +#endif + + // Get a new request. + RequestContext request = m_clientManager->createRequest(false); + + // Encode the request. + Codec * codec = request.getCodec(); + + if (codec == NULL) + { + err = kErpcStatus_MemoryError; + } + else + { + codec->startWriteMessage(message_type_t::kInvocationMessage, m_serviceId, m_sum_i32Id, request.getSequence()); + + write_list_int32_1_t_struct(codec, arr); + + // Send message to server + // Codec status is checked inside this function. + m_clientManager->performRequest(request); + + codec->read(result); + + err = codec->getStatus(); + } + + // Dispose of the request. + m_clientManager->releaseRequest(request); + + // Invoke error handler callback function + m_clientManager->callErrorHandler(err, m_sum_i32Id); + +#if ERPC_PRE_POST_ACTION + pre_post_action_cb postCB = m_clientManager->getPostCB(); + if (postCB) + { + postCB(); + } +#endif + + if (err != kErpcStatus_Success) { result = -1; diff --git a/applications/erpc/proto/generated/head_service_client.hpp b/applications/erpc/proto/generated/head_service_client.hpp index d9ea6c0..1502e87 100644 --- a/applications/erpc/proto/generated/head_service_client.hpp +++ b/applications/erpc/proto/generated/head_service_client.hpp @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -24,6 +24,8 @@ class demo_client: public demo_interface virtual int32_t add(int32_t a, int32_t b); + virtual int64_t sum_i32(const list_int32_1_t * arr); + protected: erpc::ClientManager *m_clientManager; }; diff --git a/applications/erpc/proto/generated/head_service_common.h b/applications/erpc/proto/generated/head_service_common.h index 929b429..8e573c6 100644 --- a/applications/erpc/proto/generated/head_service_common.h +++ b/applications/erpc/proto/generated/head_service_common.h @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -27,6 +27,17 @@ extern "C" #if !defined(ERPC_TYPE_DEFINITIONS_ERPCSHIM) #define ERPC_TYPE_DEFINITIONS_ERPCSHIM +// Aliases data types declarations +typedef struct list_int32_1_t list_int32_1_t; + +// Structures/unions data types declarations +struct list_int32_1_t +{ + int32_t * elements; + uint32_t elementsCount; +}; + + #endif // ERPC_TYPE_DEFINITIONS_ERPCSHIM #if defined(__cplusplus) diff --git a/applications/erpc/proto/generated/head_service_common.hpp b/applications/erpc/proto/generated/head_service_common.hpp index 628aad4..fcb664c 100644 --- a/applications/erpc/proto/generated/head_service_common.hpp +++ b/applications/erpc/proto/generated/head_service_common.hpp @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -22,6 +22,17 @@ #if !defined(ERPC_TYPE_DEFINITIONS_ERPCSHIM) #define ERPC_TYPE_DEFINITIONS_ERPCSHIM +// Aliases data types declarations +typedef struct list_int32_1_t list_int32_1_t; + +// Structures/unions data types declarations +struct list_int32_1_t +{ + int32_t * elements; + uint32_t elementsCount; +}; + + #endif // ERPC_TYPE_DEFINITIONS_ERPCSHIM diff --git a/applications/erpc/proto/generated/head_service_interface.cpp b/applications/erpc/proto/generated/head_service_interface.cpp index 5e605b9..963f4f3 100644 --- a/applications/erpc/proto/generated/head_service_interface.cpp +++ b/applications/erpc/proto/generated/head_service_interface.cpp @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ diff --git a/applications/erpc/proto/generated/head_service_interface.hpp b/applications/erpc/proto/generated/head_service_interface.hpp index 1f09b87..bc42062 100644 --- a/applications/erpc/proto/generated/head_service_interface.hpp +++ b/applications/erpc/proto/generated/head_service_interface.hpp @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -20,10 +20,13 @@ class demo_interface public: static const uint8_t m_serviceId = 1; static const uint8_t m_addId = 1; + static const uint8_t m_sum_i32Id = 2; virtual ~demo_interface(void); virtual int32_t add(int32_t a, int32_t b) = 0; + + virtual int64_t sum_i32(const list_int32_1_t * arr) = 0; private: }; } // erpcShim diff --git a/applications/erpc/proto/generated/head_service_server.cpp b/applications/erpc/proto/generated/head_service_server.cpp index 023fb5a..058ef05 100644 --- a/applications/erpc/proto/generated/head_service_server.cpp +++ b/applications/erpc/proto/generated/head_service_server.cpp @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -25,6 +25,42 @@ extern bool nestingDetection; #endif +//! @brief Function to read struct list_int32_1_t +static void read_list_int32_1_t_struct(erpc::Codec * codec, list_int32_1_t * data); + + +// Read struct list_int32_1_t function implementation +static void read_list_int32_1_t_struct(erpc::Codec * codec, list_int32_1_t * data) +{ + if(NULL == data) + { + return; + } + + codec->startReadList(data->elementsCount); + data->elements = (int32_t *) erpc_malloc(data->elementsCount * sizeof(int32_t)); + if ((data->elements == NULL) && (data->elementsCount > 0)) + { + codec->updateStatus(kErpcStatus_MemoryError); + } + for (uint32_t listCount = 0U; listCount < data->elementsCount; ++listCount) + { + codec->read(data->elements[listCount]); + } +} + + +//! @brief Function to free space allocated inside struct list_int32_1_t +static void free_list_int32_1_t_struct(list_int32_1_t * data); + + +// Free space allocated inside struct list_int32_1_t function implementation +static void free_list_int32_1_t_struct(list_int32_1_t * data) +{ + erpc_free(data->elements); +} + + demo_service::demo_service(demo_interface *_demo_interface) : erpc::Service(demo_interface::m_serviceId) @@ -54,6 +90,12 @@ erpc_status_t demo_service::handleInvocation(uint32_t methodId, uint32_t sequenc break; } + case demo_interface::m_sum_i32Id: + { + erpcStatus = sum_i32_shim(codec, messageFactory, transport, sequence); + break; + } + default: { erpcStatus = kErpcStatus_InvalidArgument; @@ -110,3 +152,58 @@ erpc_status_t demo_service::add_shim(Codec * codec, MessageBufferFactory *messag return err; } + +// Server shim for sum_i32 of demo interface. +erpc_status_t demo_service::sum_i32_shim(Codec * codec, MessageBufferFactory *messageFactory, Transport * transport, uint32_t sequence) +{ + erpc_status_t err = kErpcStatus_Success; + + list_int32_1_t *arr = NULL; + arr = (list_int32_1_t *) erpc_malloc(sizeof(list_int32_1_t)); + if (arr == NULL) + { + codec->updateStatus(kErpcStatus_MemoryError); + } + int64_t result; + + // startReadMessage() was already called before this shim was invoked. + + read_list_int32_1_t_struct(codec, arr); + + err = codec->getStatus(); + if (err == kErpcStatus_Success) + { + // Invoke the actual served function. +#if ERPC_NESTED_CALLS_DETECTION + nestingDetection = true; +#endif + result = m_handler->sum_i32(arr); +#if ERPC_NESTED_CALLS_DETECTION + nestingDetection = false; +#endif + + // preparing MessageBuffer for serializing data + err = messageFactory->prepareServerBufferForSend(codec->getBufferRef(), transport->reserveHeaderSize()); + } + + if (err == kErpcStatus_Success) + { + // preparing codec for serializing data + codec->reset(transport->reserveHeaderSize()); + + // Build response message. + codec->startWriteMessage(message_type_t::kReplyMessage, demo_interface::m_serviceId, demo_interface::m_sum_i32Id, sequence); + + codec->write(result); + + err = codec->getStatus(); + } + + if (arr) + { + free_list_int32_1_t_struct(arr); + } + erpc_free(arr); + + return err; +} diff --git a/applications/erpc/proto/generated/head_service_server.hpp b/applications/erpc/proto/generated/head_service_server.hpp index 9a2c47d..dc890f8 100644 --- a/applications/erpc/proto/generated/head_service_server.hpp +++ b/applications/erpc/proto/generated/head_service_server.hpp @@ -1,5 +1,5 @@ /* - * Generated by erpcgen 1.14.0 on Wed Dec 24 14:07:39 2025. + * Generated by erpcgen 1.14.0 on Wed Dec 31 16:10:10 2025. * * AUTOGENERATED - DO NOT EDIT */ @@ -41,6 +41,9 @@ private: demo_interface *m_handler; /*! @brief Server shim for add of demo interface. */ erpc_status_t add_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence); + + /*! @brief Server shim for sum_i32 of demo interface. */ + erpc_status_t sum_i32_shim(erpc::Codec * codec, erpc::MessageBufferFactory *messageFactory, erpc::Transport * transport, uint32_t sequence); }; } // erpcShim diff --git a/applications/erpc/proto/head_service.erpc b/applications/erpc/proto/head_service.erpc index 3140e1d..a82afac 100644 --- a/applications/erpc/proto/head_service.erpc +++ b/applications/erpc/proto/head_service.erpc @@ -1,3 +1,4 @@ interface demo { - add(int32 a, int32 b) -> int32 + add(int32 a, int32 b) -> int32; + sum_i32(list arr) -> int64; }; \ No newline at end of file diff --git a/applications/erpc/service/include/head_service_impl.h b/applications/erpc/service/include/head_service_impl.h index 0858856..b14cfab 100644 --- a/applications/erpc/service/include/head_service_impl.h +++ b/applications/erpc/service/include/head_service_impl.h @@ -18,6 +18,7 @@ public: // 实现你 .erpc 里定义的方法(这里只举例 add) int32_t add(int32_t a, int32_t b) override; + int64_t sum_i32(const list_int32_1_t* arr) override; }; diff --git a/applications/erpc/service/src/erpc_server_main.cpp b/applications/erpc/service/src/erpc_server_main.cpp index 7972447..d779be3 100644 --- a/applications/erpc/service/src/erpc_server_main.cpp +++ b/applications/erpc/service/src/erpc_server_main.cpp @@ -10,6 +10,7 @@ #include "erpc_server_setup.h" #include "erpc_transport_setup.h" #include "erpc_mbf_setup.h" +#include "erpc_usb_cdc_transport.hpp" #include "erpc/proto/generated/head_service_server.hpp" @@ -48,7 +49,14 @@ static void erpc_server_entry(void *parameter) rt_kprintf("[erpc] server init on %s, %d\r\n", ERPC_SERVER_UART_NAME, ERPC_UART_BAUD); // 1) transport - erpc_transport_t transport = erpc_transport_serial_init(ERPC_SERVER_UART_NAME,ERPC_UART_BAUD); + static serial_port_usb_cdc_config_t cfg = { + .dev_name = "cdc0", + .rx_wait_ms = -1, + .tx_wait_ms = 2000, + }; + + erpc_transport_t transport = erpc_transport_usb_cdc_init(NULL, NULL, &cfg, NULL, 0); + // erpc_transport_t transport = erpc_transport_serial_init(ERPC_SERVER_UART_NAME,ERPC_UART_BAUD); // erpc_transport_t transport = erpc_transport_cmsis_uart_init(ERPC_SERVER_UART_NAME); if (!transport) { diff --git a/applications/erpc/service/src/head_service_impl.cpp b/applications/erpc/service/src/head_service_impl.cpp index 3fda4cb..4ed8212 100644 --- a/applications/erpc/service/src/head_service_impl.cpp +++ b/applications/erpc/service/src/head_service_impl.cpp @@ -8,10 +8,20 @@ int32_t HeadServiceImpl::add(int32_t a, int32_t b) { - int32_t r = a + b; - rt_tick_t now = rt_tick_get(); - rt_uint32_t ms = (rt_uint32_t)((rt_uint64_t)now * 1000 / RT_TICK_PER_SECOND); - rt_kprintf("[%lu ms] [erpc service] add(%ld,%ld)=%ld\r\n", - (unsigned long)ms, (long)a, (long)b, (long)r); - return r; + return a + b; + // rt_tick_t now = rt_tick_get(); + // rt_uint32_t ms = (rt_uint32_t)((rt_uint64_t)now * 1000 / RT_TICK_PER_SECOND); + // rt_kprintf("[%lu ms] [erpc service] add(%ld,%ld)=%ld\r\n", + // (unsigned long)ms, (long)a, (long)b, (long)r); + // return r; +} + +int64_t HeadServiceImpl::sum_i32(const list_int32_1_t* arr) +{ + int64_t sum = 0; + for (int i = 0; i < arr->elementsCount; ++i) + { + sum+= arr->elements[i]; + } + return sum; } diff --git a/applications/main.c b/applications/main.c index f12ed8e..edc48fa 100644 --- a/applications/main.c +++ b/applications/main.c @@ -32,17 +32,10 @@ int main(void) rt_thread_mdelay(100); // rt_kprintf("Hello RT-Thread!\n"); } + return RT_EOK; } -static inline int dwt_init(void) -{ - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - DWT->CYCCNT = 0; - DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; - return 0; -} - -INIT_APP_EXPORT(dwt_init); + diff --git a/board/CubeMX_Config/.mxproject b/board/CubeMX_Config/.mxproject index 9719fe4..6a63c52 100644 --- a/board/CubeMX_Config/.mxproject +++ b/board/CubeMX_Config/.mxproject @@ -1,14 +1,14 @@ [PreviousLibFiles] -LibFiles=Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_bus.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_crs.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_system.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_utils.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_dmamux.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_mdma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_def.h;Drivers\STM32H7xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_qspi.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_delayblock.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_spi.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_spi.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_spi_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_usart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_lpuart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart_ex.h;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_qspi.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_delayblock.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_spi.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_spi_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_bus.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_crs.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_system.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_utils.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_dmamux.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_mdma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_def.h;Drivers\STM32H7xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_qspi.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_delayblock.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_spi.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_spi.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_spi_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_usart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_lpuart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart_ex.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h750xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h7xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\system_stm32h7xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\system_stm32h7xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h; +LibFiles=Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pcd.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pcd_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_usb.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_bus.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_crs.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_system.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_utils.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_dmamux.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_mdma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_def.h;Drivers\STM32H7xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_qspi.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_delayblock.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_usart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_lpuart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart_ex.h;Middlewares\ST\STM32_USB_Device_Library\Core\Inc\usbd_core.h;Middlewares\ST\STM32_USB_Device_Library\Core\Inc\usbd_ctlreq.h;Middlewares\ST\STM32_USB_Device_Library\Core\Inc\usbd_def.h;Middlewares\ST\STM32_USB_Device_Library\Core\Inc\usbd_ioreq.h;Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Inc\usbd_cdc.h;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_usb.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_qspi.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_delayblock.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_core.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ctlreq.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ioreq.c;Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Src\usbd_cdc.c;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pcd.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pcd_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_usb.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_rcc_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_bus.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_rcc.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_crs.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_system.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_utils.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_flash_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_gpio_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_gpio.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_hsem.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_dma_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_dma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_dmamux.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_mdma.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_pwr_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_pwr.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_cortex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_def.h;Drivers\STM32H7xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_i2c_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_exti.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_qspi.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_delayblock.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_tim_ex.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_usart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_ll_lpuart.h;Drivers\STM32H7xx_HAL_Driver\Inc\stm32h7xx_hal_uart_ex.h;Middlewares\ST\STM32_USB_Device_Library\Core\Inc\usbd_core.h;Middlewares\ST\STM32_USB_Device_Library\Core\Inc\usbd_ctlreq.h;Middlewares\ST\STM32_USB_Device_Library\Core\Inc\usbd_def.h;Middlewares\ST\STM32_USB_Device_Library\Core\Inc\usbd_ioreq.h;Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Inc\usbd_cdc.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h750xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\stm32h7xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\system_stm32h7xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Include\system_stm32h7xx.h;Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_armclang_ltm.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv81mml.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm35p.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h; [PreviousUsedCMakes] -SourceFiles=Src\main.c;Src\stm32h7xx_it.c;Src\stm32h7xx_hal_msp.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_qspi.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_delayblock.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_spi.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_spi_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;Src\system_stm32h7xx.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_qspi.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_delayblock.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_spi.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_spi_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;Src\system_stm32h7xx.c;;; -HeaderPath=Drivers\STM32H7xx_HAL_Driver\Inc;Drivers\STM32H7xx_HAL_Driver\Inc\Legacy;Drivers\CMSIS\Device\ST\STM32H7xx\Include;Drivers\CMSIS\Include;Inc; +SourceFiles=Src\main.c;Src\usb_device.c;Src\usbd_conf.c;Src\usbd_desc.c;Src\usbd_cdc_if.c;Src\stm32h7xx_it.c;Src\stm32h7xx_hal_msp.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_usb.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_qspi.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_delayblock.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_core.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ctlreq.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ioreq.c;Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Src\usbd_cdc.c;Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;Src\system_stm32h7xx.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pcd_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_usb.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_rcc_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_flash_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_gpio.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_hsem.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_mdma.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_pwr_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_cortex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_i2c_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_exti.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_qspi.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_ll_delayblock.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_tim_ex.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart.c;Drivers\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_uart_ex.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_core.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ctlreq.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ioreq.c;Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Src\usbd_cdc.c;Drivers\CMSIS\Device\ST\STM32H7xx\Source\Templates\system_stm32h7xx.c;Src\system_stm32h7xx.c;;;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_core.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ctlreq.c;Middlewares\ST\STM32_USB_Device_Library\Core\Src\usbd_ioreq.c;Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Src\usbd_cdc.c; +HeaderPath=Drivers\STM32H7xx_HAL_Driver\Inc;Drivers\STM32H7xx_HAL_Driver\Inc\Legacy;Middlewares\ST\STM32_USB_Device_Library\Core\Inc;Middlewares\ST\STM32_USB_Device_Library\Class\CDC\Inc;Drivers\CMSIS\Device\ST\STM32H7xx\Include;Drivers\CMSIS\Include;Inc; CDefines=USE_PWR_LDO_SUPPLY;USE_PWR_LDO_SUPPLY;USE_PWR_LDO_SUPPLY;USE_HAL_DRIVER;STM32H750xx;USE_HAL_DRIVER;USE_HAL_DRIVER; [PreviousGenFiles] HeaderPath=..\Inc -HeaderFiles=stm32h7xx_it.h;stm32h7xx_hal_conf.h;main.h; +HeaderFiles=usb_device.h;usbd_conf.h;usbd_desc.h;usbd_cdc_if.h;stm32h7xx_it.h;stm32h7xx_hal_conf.h;main.h; SourcePath=..\Src -SourceFiles=stm32h7xx_it.c;stm32h7xx_hal_msp.c;main.c; +SourceFiles=usb_device.c;usbd_conf.c;usbd_desc.c;usbd_cdc_if.c;stm32h7xx_it.c;stm32h7xx_hal_msp.c;main.c; diff --git a/board/CubeMX_Config/CubeMX_Config.ioc b/board/CubeMX_Config/CubeMX_Config.ioc index 5f1306e..538ca6d 100644 --- a/board/CubeMX_Config/CubeMX_Config.ioc +++ b/board/CubeMX_Config/CubeMX_Config.ioc @@ -14,41 +14,42 @@ Mcu.CPN=STM32H750XBH6 Mcu.Family=STM32H7 Mcu.IP0=CORTEX_M7 Mcu.IP1=DEBUG -Mcu.IP10=USART3 +Mcu.IP10=USB_DEVICE +Mcu.IP11=USB_OTG_FS Mcu.IP2=MEMORYMAP Mcu.IP3=NVIC Mcu.IP4=QUADSPI Mcu.IP5=RCC -Mcu.IP6=SPI5 -Mcu.IP7=SYS -Mcu.IP8=USART1 -Mcu.IP9=USART2 -Mcu.IPNb=11 +Mcu.IP6=SYS +Mcu.IP7=USART1 +Mcu.IP8=USART2 +Mcu.IP9=USART3 +Mcu.IPNb=12 Mcu.Name=STM32H750XBHx Mcu.Package=TFBGA240 Mcu.Pin0=PD5 Mcu.Pin1=PD6 -Mcu.Pin10=PH0-OSC_IN (PH0) -Mcu.Pin11=PK0 -Mcu.Pin12=PF6 +Mcu.Pin10=PG6 +Mcu.Pin11=PH1-OSC_OUT (PH1) +Mcu.Pin12=PH0-OSC_IN (PH0) Mcu.Pin13=PF7 Mcu.Pin14=PF8 Mcu.Pin15=PF10 Mcu.Pin16=PF9 -Mcu.Pin17=PJ10 -Mcu.Pin18=PE9 -Mcu.Pin19=PD9 +Mcu.Pin17=PE9 +Mcu.Pin18=PD9 +Mcu.Pin19=PD8 Mcu.Pin2=PA14 (JTCK/SWCLK) -Mcu.Pin20=PD8 -Mcu.Pin21=VP_SYS_VS_Systick +Mcu.Pin20=VP_SYS_VS_Systick +Mcu.Pin21=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS Mcu.Pin22=VP_MEMORYMAP_VS_MEMORYMAP Mcu.Pin3=PC15-OSC32_OUT (OSC32_OUT) Mcu.Pin4=PC14-OSC32_IN (OSC32_IN) Mcu.Pin5=PA13 (JTMS/SWDIO) Mcu.Pin6=PA10 Mcu.Pin7=PA9 -Mcu.Pin8=PG6 -Mcu.Pin9=PH1-OSC_OUT (PH1) +Mcu.Pin8=PA12 +Mcu.Pin9=PA11 Mcu.PinsNb=23 Mcu.ThirdPartyNb=0 Mcu.UserConstants= @@ -61,7 +62,8 @@ NVIC.ForceEnableDMAVector=true NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false -NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +NVIC.OTG_FS_IRQn=true\:5\:0\:true\:false\:true\:true\:true\:true +NVIC.PendSV_IRQn=true\:0\:0\:true\:false\:true\:false\:false\:false NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false @@ -69,6 +71,16 @@ NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false PA10.Locked=true PA10.Mode=Asynchronous PA10.Signal=USART1_RX +PA11.GPIOParameters=GPIO_Speed,GPIO_PuPd +PA11.GPIO_PuPd=GPIO_PULLUP +PA11.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PA11.Mode=Device_Only +PA11.Signal=USB_OTG_FS_DM +PA12.GPIOParameters=GPIO_Speed,GPIO_PuPd +PA12.GPIO_PuPd=GPIO_PULLUP +PA12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH +PA12.Mode=Device_Only +PA12.Signal=USB_OTG_FS_DP PA13\ (JTMS/SWDIO).Mode=Serial_Wire PA13\ (JTMS/SWDIO).Signal=DEBUG_JTMS-SWDIO PA14\ (JTCK/SWCLK).Mode=Serial_Wire @@ -92,30 +104,23 @@ PD9.Mode=Asynchronous PD9.Signal=USART3_RX PE9.Locked=true PE9.Signal=S_TIM1_CH1 -PF10.Mode=Single Bank 1 +PF10.Mode=Single Bank 1 2IOs PF10.Signal=QUADSPI_CLK -PF6.Mode=Single Bank 1 -PF6.Signal=QUADSPI_BK1_IO3 PF7.Locked=true -PF7.Mode=Single Bank 1 PF7.Signal=QUADSPI_BK1_IO2 PF8.Locked=true -PF8.Mode=Single Bank 1 +PF8.Mode=Single Bank 1 2IOs PF8.Signal=QUADSPI_BK1_IO0 PF9.Locked=true -PF9.Mode=Single Bank 1 +PF9.Mode=Single Bank 1 2IOs PF9.Signal=QUADSPI_BK1_IO1 PG6.Locked=true -PG6.Mode=Single Bank 1 +PG6.Mode=Single Bank 1 2IOs PG6.Signal=QUADSPI_BK1_NCS PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT -PJ10.Mode=TX_Only_Simplex_Unidirect_Master -PJ10.Signal=SPI5_MOSI -PK0.Mode=TX_Only_Simplex_Unidirect_Master -PK0.Signal=SPI5_SCK PinOutPanel.CurrentBGAView=Top PinOutPanel.RotationAngle=0 ProjectManager.AskForMigrate=true @@ -150,14 +155,14 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_QUADSPI_Init-QUADSPI-false-HAL-true,5-MX_SPI5_Init-SPI5-false-HAL-true,6-MX_USART2_UART_Init-USART2-false-HAL-true,7-MX_USART3_UART_Init-USART3-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true,5-MX_USART3_UART_Init-USART3-false-HAL-true,6-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true QUADSPI.ChipSelectHighTime=QSPI_CS_HIGH_TIME_5_CYCLE QUADSPI.ClockPrescaler=5 QUADSPI.FifoThreshold=4 QUADSPI.FlashSize=22 QUADSPI.IPParameters=ClockPrescaler,FifoThreshold,SampleShifting,FlashSize,ChipSelectHighTime QUADSPI.SampleShifting=QSPI_SAMPLE_SHIFTING_HALFCYCLE -RCC.ADCFreq_Value=129000000 +RCC.ADCFreq_Value=50390625 RCC.AHB12Freq_Value=240000000 RCC.AHB4Freq_Value=240000000 RCC.APB1Freq_Value=120000000 @@ -174,20 +179,21 @@ RCC.D1PPRE=RCC_APB3_DIV2 RCC.D2PPRE1=RCC_APB1_DIV2 RCC.D2PPRE2=RCC_APB2_DIV2 RCC.D3PPRE=RCC_APB4_DIV2 -RCC.DFSDMACLkFreq_Value=480000000 +RCC.DFSDMACLkFreq_Value=48000000 RCC.DFSDMFreq_Value=120000000 -RCC.DIVM1=4 -RCC.DIVN1=60 +RCC.DIVM1=5 +RCC.DIVN1=192 RCC.DIVP1Freq_Value=480000000 -RCC.DIVP2Freq_Value=129000000 -RCC.DIVP3Freq_Value=129000000 -RCC.DIVQ1Freq_Value=480000000 -RCC.DIVQ2Freq_Value=129000000 -RCC.DIVQ3Freq_Value=129000000 +RCC.DIVP2Freq_Value=50390625 +RCC.DIVP3Freq_Value=50390625 +RCC.DIVQ1=20 +RCC.DIVQ1Freq_Value=48000000 +RCC.DIVQ2Freq_Value=50390625 +RCC.DIVQ3Freq_Value=50390625 RCC.DIVR1Freq_Value=480000000 -RCC.DIVR2Freq_Value=129000000 -RCC.DIVR3Freq_Value=129000000 -RCC.FDCANFreq_Value=480000000 +RCC.DIVR2Freq_Value=50390625 +RCC.DIVR3Freq_Value=50390625 +RCC.FDCANFreq_Value=48000000 RCC.FMCFreq_Value=240000000 RCC.FamilyName=M RCC.HCLK3ClockFreq_Value=240000000 @@ -196,27 +202,29 @@ RCC.HPRE=RCC_HCLK_DIV2 RCC.HRTIMFreq_Value=240000000 RCC.I2C123Freq_Value=120000000 RCC.I2C4Freq_Value=120000000 -RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVN1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value +RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVN1,DIVP1Freq_Value,DIVP2Freq_Value,DIVP3Freq_Value,DIVQ1,DIVQ1Freq_Value,DIVQ2Freq_Value,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2Freq_Value,DIVR3Freq_Value,FDCANFreq_Value,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value RCC.LPTIM1Freq_Value=120000000 RCC.LPTIM2Freq_Value=120000000 RCC.LPTIM345Freq_Value=120000000 RCC.LPUART1Freq_Value=120000000 -RCC.LTDCFreq_Value=129000000 +RCC.LTDCFreq_Value=50390625 +RCC.LockedElements=AHBOutput RCC.MCO1PinFreq_Value=64000000 RCC.MCO2PinFreq_Value=480000000 RCC.PLL2FRACN=0 RCC.PLL3FRACN=0 RCC.PLLFRACN=0 +RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE RCC.QSPIFreq_Value=240000000 RCC.RNGFreq_Value=48000000 RCC.RTCFreq_Value=32000 -RCC.SAI1Freq_Value=480000000 -RCC.SAI23Freq_Value=480000000 -RCC.SAI4AFreq_Value=480000000 -RCC.SAI4BFreq_Value=480000000 -RCC.SDMMCFreq_Value=480000000 -RCC.SPDIFRXFreq_Value=480000000 -RCC.SPI123Freq_Value=480000000 +RCC.SAI1Freq_Value=48000000 +RCC.SAI23Freq_Value=48000000 +RCC.SAI4AFreq_Value=48000000 +RCC.SAI4BFreq_Value=48000000 +RCC.SDMMCFreq_Value=48000000 +RCC.SPDIFRXFreq_Value=48000000 +RCC.SPI123Freq_Value=48000000 RCC.SPI45Freq_Value=120000000 RCC.SPI6Freq_Value=120000000 RCC.SWPMI1Freq_Value=120000000 @@ -227,28 +235,32 @@ RCC.Tim2OutputFreq_Value=240000000 RCC.TraceFreq_Value=480000000 RCC.USART16Freq_Value=120000000 RCC.USART234578Freq_Value=120000000 -RCC.USBFreq_Value=480000000 +RCC.USBFreq_Value=48000000 RCC.VCO1OutputFreq_Value=960000000 -RCC.VCO2OutputFreq_Value=258000000 -RCC.VCO3OutputFreq_Value=258000000 -RCC.VCOInput1Freq_Value=16000000 -RCC.VCOInput2Freq_Value=2000000 -RCC.VCOInput3Freq_Value=2000000 +RCC.VCO2OutputFreq_Value=100781250 +RCC.VCO3OutputFreq_Value=100781250 +RCC.VCOInput1Freq_Value=5000000 +RCC.VCOInput2Freq_Value=781250 +RCC.VCOInput3Freq_Value=781250 SH.S_TIM1_CH1.0=TIM1_CH1 SH.S_TIM1_CH1.ConfNb=1 -SPI5.CalculateBaudRate=60.0 MBits/s -SPI5.Direction=SPI_DIRECTION_2LINES_TXONLY -SPI5.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate -SPI5.Mode=SPI_MODE_MASTER -SPI5.VirtualType=VM_MASTER USART1.IPParameters=VirtualMode-Asynchronous USART1.VirtualMode-Asynchronous=VM_ASYNC USART2.IPParameters=VirtualMode-Asynchronous USART2.VirtualMode-Asynchronous=VM_ASYNC USART3.IPParameters=VirtualMode-Asynchronous USART3.VirtualMode-Asynchronous=VM_ASYNC +USB_DEVICE.CLASS_NAME_FS=CDC +USB_DEVICE.IPParameters=VirtualMode-CDC_FS,VirtualModeFS,CLASS_NAME_FS +USB_DEVICE.VirtualMode-CDC_FS=Cdc +USB_DEVICE.VirtualModeFS=Cdc_FS +USB_OTG_FS.IPParameters=VirtualMode,dma_enable +USB_OTG_FS.VirtualMode=Device_Only +USB_OTG_FS.dma_enable=ENABLE VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS +VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS board=custom diff --git a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd.h b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd.h new file mode 100644 index 0000000..f1fe87f --- /dev/null +++ b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd.h @@ -0,0 +1,444 @@ +/** + ****************************************************************************** + * @file stm32h7xx_hal_pcd.h + * @author MCD Application Team + * @brief Header file of PCD HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H7xx_HAL_PCD_H +#define STM32H7xx_HAL_PCD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx_ll_usb.h" + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) + +/** @addtogroup STM32H7xx_HAL_Driver + * @{ + */ + +/** @addtogroup PCD + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup PCD_Exported_Types PCD Exported Types + * @{ + */ + +/** + * @brief PCD State structure definition + */ +typedef enum +{ + HAL_PCD_STATE_RESET = 0x00, + HAL_PCD_STATE_READY = 0x01, + HAL_PCD_STATE_ERROR = 0x02, + HAL_PCD_STATE_BUSY = 0x03, + HAL_PCD_STATE_TIMEOUT = 0x04 +} PCD_StateTypeDef; + +/* Device LPM suspend state */ +typedef enum +{ + LPM_L0 = 0x00, /* on */ + LPM_L1 = 0x01, /* LPM L1 sleep */ + LPM_L2 = 0x02, /* suspend */ + LPM_L3 = 0x03, /* off */ +} PCD_LPM_StateTypeDef; + +typedef enum +{ + PCD_LPM_L0_ACTIVE = 0x00, /* on */ + PCD_LPM_L1_ACTIVE = 0x01, /* LPM L1 sleep */ +} PCD_LPM_MsgTypeDef; + +typedef enum +{ + PCD_BCD_ERROR = 0xFF, + PCD_BCD_CONTACT_DETECTION = 0xFE, + PCD_BCD_STD_DOWNSTREAM_PORT = 0xFD, + PCD_BCD_CHARGING_DOWNSTREAM_PORT = 0xFC, + PCD_BCD_DEDICATED_CHARGING_PORT = 0xFB, + PCD_BCD_DISCOVERY_COMPLETED = 0x00, + +} PCD_BCD_MsgTypeDef; + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +typedef USB_OTG_GlobalTypeDef PCD_TypeDef; +typedef USB_OTG_CfgTypeDef PCD_InitTypeDef; +typedef USB_OTG_EPTypeDef PCD_EPTypeDef; +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + +/** + * @brief PCD Handle Structure definition + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +typedef struct __PCD_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + PCD_TypeDef *Instance; /*!< Register base address */ + PCD_InitTypeDef Init; /*!< PCD required parameters */ + __IO uint8_t USB_Address; /*!< USB Address */ + PCD_EPTypeDef IN_ep[16]; /*!< IN endpoint parameters */ + PCD_EPTypeDef OUT_ep[16]; /*!< OUT endpoint parameters */ + HAL_LockTypeDef Lock; /*!< PCD peripheral status */ + __IO PCD_StateTypeDef State; /*!< PCD communication state */ + __IO uint32_t ErrorCode; /*!< PCD Error code */ + uint32_t Setup[12]; /*!< Setup packet buffer */ + PCD_LPM_StateTypeDef LPM_State; /*!< LPM State */ + uint32_t BESL; + uint32_t FrameNumber; /*!< Store Current Frame number */ + + + uint32_t lpm_active; /*!< Enable or disable the Link Power Management . + This parameter can be set to ENABLE or DISABLE */ + + uint32_t battery_charging_active; /*!< Enable or disable Battery charging. + This parameter can be set to ENABLE or DISABLE */ + void *pData; /*!< Pointer to upper stack Handler */ + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + void (* SOFCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD SOF callback */ + void (* SetupStageCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Setup Stage callback */ + void (* ResetCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Reset callback */ + void (* SuspendCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Suspend callback */ + void (* ResumeCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Resume callback */ + void (* ConnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Connect callback */ + void (* DisconnectCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Disconnect callback */ + + void (* DataOutStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data OUT Stage callback */ + void (* DataInStageCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD Data IN Stage callback */ + void (* ISOOUTIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO OUT Incomplete callback */ + void (* ISOINIncompleteCallback)(struct __PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< USB OTG PCD ISO IN Incomplete callback */ + void (* BCDCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< USB OTG PCD BCD callback */ + void (* LPMCallback)(struct __PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< USB OTG PCD LPM callback */ + + void (* MspInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp Init callback */ + void (* MspDeInitCallback)(struct __PCD_HandleTypeDef *hpcd); /*!< USB OTG PCD Msp DeInit callback */ +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +} PCD_HandleTypeDef; + +/** + * @} + */ + +/* Include PCD HAL Extended module */ +#include "stm32h7xx_hal_pcd_ex.h" + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup PCD_Exported_Constants PCD Exported Constants + * @{ + */ + +/** @defgroup PCD_Speed PCD Speed + * @{ + */ +#define PCD_SPEED_HIGH USBD_HS_SPEED +#define PCD_SPEED_HIGH_IN_FULL USBD_HSINFS_SPEED +#define PCD_SPEED_FULL USBD_FS_SPEED +/** + * @} + */ + +/** @defgroup PCD_PHY_Module PCD PHY Module + * @{ + */ +#define PCD_PHY_ULPI 1U +#define PCD_PHY_EMBEDDED 2U +#define PCD_PHY_UTMI 3U +/** + * @} + */ + +/** @defgroup PCD_Error_Code_definition PCD Error Code definition + * @brief PCD Error Code definition + * @{ + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +#define HAL_PCD_ERROR_INVALID_CALLBACK (0x00000010U) /*!< Invalid Callback error */ +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** + * @} + */ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup PCD_Exported_Macros PCD Exported Macros + * @brief macros to handle interrupts and specific clock configurations + * @{ + */ +#define __HAL_PCD_ENABLE(__HANDLE__) (void)USB_EnableGlobalInt ((__HANDLE__)->Instance) +#define __HAL_PCD_DISABLE(__HANDLE__) (void)USB_DisableGlobalInt ((__HANDLE__)->Instance) + +#define __HAL_PCD_GET_FLAG(__HANDLE__, __INTERRUPT__) \ + ((USB_ReadInterrupts((__HANDLE__)->Instance) & (__INTERRUPT__)) == (__INTERRUPT__)) + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +#define __HAL_PCD_CLEAR_FLAG(__HANDLE__, __INTERRUPT__) (((__HANDLE__)->Instance->GINTSTS) &= (__INTERRUPT__)) +#define __HAL_PCD_IS_INVALID_INTERRUPT(__HANDLE__) (USB_ReadInterrupts((__HANDLE__)->Instance) == 0U) + +#define __HAL_PCD_UNGATE_PHYCLOCK(__HANDLE__) \ + *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) &= ~(USB_OTG_PCGCCTL_STOPCLK) + +#define __HAL_PCD_GATE_PHYCLOCK(__HANDLE__) \ + *(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE) |= USB_OTG_PCGCCTL_STOPCLK + +#define __HAL_PCD_IS_PHY_SUSPENDED(__HANDLE__) \ + ((*(__IO uint32_t *)((uint32_t)((__HANDLE__)->Instance) + USB_OTG_PCGCCTL_BASE)) & 0x10U) + +#define __HAL_USB_OTG_HS_WAKEUP_EXTI_ENABLE_IT() EXTI_D1->IMR2 |= (USB_OTG_HS_WAKEUP_EXTI_LINE) +#define __HAL_USB_OTG_HS_WAKEUP_EXTI_DISABLE_IT() EXTI_D1->IMR2 &= ~(USB_OTG_HS_WAKEUP_EXTI_LINE) +#define __HAL_USB_OTG_FS_WAKEUP_EXTI_ENABLE_IT() EXTI_D1->IMR2 |= (USB_OTG_FS_WAKEUP_EXTI_LINE) +#define __HAL_USB_OTG_FS_WAKEUP_EXTI_DISABLE_IT() EXTI_D1->IMR2 &= ~(USB_OTG_FS_WAKEUP_EXTI_LINE) +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup PCD_Exported_Functions PCD Exported Functions + * @{ + */ + +/* Initialization/de-initialization functions ********************************/ +/** @addtogroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd); +void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd); +void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd); + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +/** @defgroup HAL_PCD_Callback_ID_enumeration_definition HAL USB OTG PCD Callback ID enumeration definition + * @brief HAL USB OTG PCD Callback ID enumeration definition + * @{ + */ +typedef enum +{ + HAL_PCD_SOF_CB_ID = 0x01, /*!< USB PCD SOF callback ID */ + HAL_PCD_SETUPSTAGE_CB_ID = 0x02, /*!< USB PCD Setup Stage callback ID */ + HAL_PCD_RESET_CB_ID = 0x03, /*!< USB PCD Reset callback ID */ + HAL_PCD_SUSPEND_CB_ID = 0x04, /*!< USB PCD Suspend callback ID */ + HAL_PCD_RESUME_CB_ID = 0x05, /*!< USB PCD Resume callback ID */ + HAL_PCD_CONNECT_CB_ID = 0x06, /*!< USB PCD Connect callback ID */ + HAL_PCD_DISCONNECT_CB_ID = 0x07, /*!< USB PCD Disconnect callback ID */ + + HAL_PCD_MSPINIT_CB_ID = 0x08, /*!< USB PCD MspInit callback ID */ + HAL_PCD_MSPDEINIT_CB_ID = 0x09 /*!< USB PCD MspDeInit callback ID */ + +} HAL_PCD_CallbackIDTypeDef; +/** + * @} + */ + +/** @defgroup HAL_PCD_Callback_pointer_definition HAL USB OTG PCD Callback pointer definition + * @brief HAL USB OTG PCD Callback pointer definition + * @{ + */ + +typedef void (*pPCD_CallbackTypeDef)(PCD_HandleTypeDef *hpcd); /*!< pointer to a common USB OTG PCD callback function */ +typedef void (*pPCD_DataOutStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data OUT Stage callback */ +typedef void (*pPCD_DataInStageCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD Data IN Stage callback */ +typedef void (*pPCD_IsoOutIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO OUT Incomplete callback */ +typedef void (*pPCD_IsoInIncpltCallbackTypeDef)(PCD_HandleTypeDef *hpcd, uint8_t epnum); /*!< pointer to USB OTG PCD ISO IN Incomplete callback */ +typedef void (*pPCD_LpmCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); /*!< pointer to USB OTG PCD LPM callback */ +typedef void (*pPCD_BcdCallbackTypeDef)(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); /*!< pointer to USB OTG PCD BCD callback */ + +/** + * @} + */ + +HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID, + pPCD_CallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID); + +HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, + pPCD_DataOutStageCallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, + pPCD_DataInStageCallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, + pPCD_IsoOutIncpltCallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, + pPCD_IsoInIncpltCallbackTypeDef pCallback); + +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd); + +HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +/** + * @} + */ + +/* I/O operation functions ***************************************************/ +/* Non-Blocking mode: Interrupt */ +/** @addtogroup PCD_Exported_Functions_Group2 Input and Output operation functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd); +void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd); + +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd); +void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd); + +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum); +/** + * @} + */ + +/* Peripheral Control functions **********************************************/ +/** @addtogroup PCD_Exported_Functions_Group3 Peripheral Control functions + * @{ + */ +HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address); +HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type); +HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len); +HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr); +HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd); +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +HAL_StatusTypeDef HAL_PCD_SetTestMode(const PCD_HandleTypeDef *hpcd, uint8_t testmode); +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + +uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr); +/** + * @} + */ + +/* Peripheral State functions ************************************************/ +/** @addtogroup PCD_Exported_Functions_Group4 Peripheral State functions + * @{ + */ +PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd); +/** + * @} + */ + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup PCD_Private_Constants PCD Private Constants + * @{ + */ +/** @defgroup USB_EXTI_Line_Interrupt USB EXTI line interrupt + * @{ + */ +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +#define USB_OTG_FS_WAKEUP_EXTI_LINE (0x1U << 12) /*!< USB FS EXTI Line WakeUp Interrupt */ +#define USB_OTG_HS_WAKEUP_EXTI_LINE (0x1U << 11) /*!< USB HS EXTI Line WakeUp Interrupt */ +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + + +/** + * @} + */ +/** + * @} + */ + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +#ifndef USB_OTG_DOEPINT_OTEPSPR +#define USB_OTG_DOEPINT_OTEPSPR (0x1UL << 5) /*!< Status Phase Received interrupt */ +#endif /* defined USB_OTG_DOEPINT_OTEPSPR */ + +#ifndef USB_OTG_DOEPMSK_OTEPSPRM +#define USB_OTG_DOEPMSK_OTEPSPRM (0x1UL << 5) /*!< Setup Packet Received interrupt mask */ +#endif /* defined USB_OTG_DOEPMSK_OTEPSPRM */ + +#ifndef USB_OTG_DOEPINT_NAK +#define USB_OTG_DOEPINT_NAK (0x1UL << 13) /*!< NAK interrupt */ +#endif /* defined USB_OTG_DOEPINT_NAK */ + +#ifndef USB_OTG_DOEPMSK_NAKM +#define USB_OTG_DOEPMSK_NAKM (0x1UL << 13) /*!< OUT Packet NAK interrupt mask */ +#endif /* defined USB_OTG_DOEPMSK_NAKM */ + +#ifndef USB_OTG_DOEPINT_STPKTRX +#define USB_OTG_DOEPINT_STPKTRX (0x1UL << 15) /*!< Setup Packet Received interrupt */ +#endif /* defined USB_OTG_DOEPINT_STPKTRX */ + +#ifndef USB_OTG_DOEPMSK_NYETM +#define USB_OTG_DOEPMSK_NYETM (0x1UL << 14) /*!< Setup Packet Received interrupt mask */ +#endif /* defined USB_OTG_DOEPMSK_NYETM */ +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PCD_Private_Macros PCD Private Macros + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32H7xx_HAL_PCD_H */ diff --git a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi_ex.h b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd_ex.h similarity index 51% rename from board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi_ex.h rename to board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd_ex.h index 3e32a0e..221e2af 100644 --- a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi_ex.h +++ b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_pcd_ex.h @@ -1,8 +1,8 @@ /** ****************************************************************************** - * @file stm32h7xx_hal_spi_ex.h + * @file stm32h7xx_hal_pcd_ex.h * @author MCD Application Team - * @brief Header file of SPI HAL Extended module. + * @brief Header file of PCD HAL Extension module. ****************************************************************************** * @attention * @@ -17,68 +17,51 @@ */ /* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef STM32H7xx_HAL_SPI_EX_H -#define STM32H7xx_HAL_SPI_EX_H +#ifndef STM32H7xx_HAL_PCD_EX_H +#define STM32H7xx_HAL_PCD_EX_H #ifdef __cplusplus extern "C" { -#endif +#endif /* __cplusplus */ /* Includes ------------------------------------------------------------------*/ #include "stm32h7xx_hal_def.h" +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) /** @addtogroup STM32H7xx_HAL_Driver * @{ */ -/** @addtogroup SPIEx +/** @addtogroup PCDEx * @{ */ - /* Exported types ------------------------------------------------------------*/ -/** @defgroup SPIEx_Exported_Types SPIEx Exported Types - * @{ - */ - -/** - * @} - */ - /* Exported constants --------------------------------------------------------*/ -/** @defgroup SPIEx_Exported_Constants SPIEx Exported Constants - * @{ - */ - -/** - * @} - */ - /* Exported macros -----------------------------------------------------------*/ -/** @defgroup SPIEx_Exported_Macros SPIEx Extended Exported Macros - * @{ - */ - -/** - * @} - */ - /* Exported functions --------------------------------------------------------*/ -/** @addtogroup SPIEx_Exported_Functions +/** @addtogroup PCDEx_Exported_Functions PCDEx Exported Functions * @{ */ - -/* Initialization and de-initialization functions ****************************/ -/* IO operation functions *****************************************************/ -/** @addtogroup SPIEx_Exported_Functions_Group1 +/** @addtogroup PCDEx_Exported_Functions_Group1 Peripheral Control functions * @{ */ -HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef *hspi); -HAL_StatusTypeDef HAL_SPIEx_EnableLockConfiguration(SPI_HandleTypeDef *hspi); -HAL_StatusTypeDef HAL_SPIEx_ConfigureUnderrun(SPI_HandleTypeDef *hspi, uint32_t UnderrunDetection, - uint32_t UnderrunBehaviour); -/** - * @} - */ +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size); +HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size); +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + + +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd); + + +HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd); +HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd); +void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd); + +void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg); +void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg); + /** * @} */ @@ -91,9 +74,14 @@ HAL_StatusTypeDef HAL_SPIEx_ConfigureUnderrun(SPI_HandleTypeDef *hspi, uint32_t * @} */ +/** + * @} + */ +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ #ifdef __cplusplus } -#endif +#endif /* __cplusplus */ -#endif /* STM32H7xx_HAL_SPI_EX_H */ + +#endif /* STM32H7xx_HAL_PCD_EX_H */ diff --git a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h deleted file mode 100644 index 71a7b1d..0000000 --- a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h +++ /dev/null @@ -1,1130 +0,0 @@ -/** - ****************************************************************************** - * @file stm32h7xx_hal_spi.h - * @author MCD Application Team - * @brief Header file of SPI HAL module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef STM32H7xx_HAL_SPI_H -#define STM32H7xx_HAL_SPI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32h7xx_hal_def.h" - -/** @addtogroup STM32H7xx_HAL_Driver - * @{ - */ - -/** @addtogroup SPI - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/** @defgroup SPI_Exported_Types SPI Exported Types - * @{ - */ - -/** - * @brief SPI Configuration Structure definition - */ -typedef struct -{ - uint32_t Mode; /*!< Specifies the SPI operating mode. - This parameter can be a value of @ref SPI_Mode */ - - uint32_t Direction; /*!< Specifies the SPI bidirectional mode state. - This parameter can be a value of @ref SPI_Direction */ - - uint32_t DataSize; /*!< Specifies the SPI data size. - This parameter can be a value of @ref SPI_Data_Size */ - - uint32_t CLKPolarity; /*!< Specifies the serial clock steady state. - This parameter can be a value of @ref SPI_Clock_Polarity */ - - uint32_t CLKPhase; /*!< Specifies the clock active edge for the bit capture. - This parameter can be a value of @ref SPI_Clock_Phase */ - - uint32_t NSS; /*!< Specifies whether the NSS signal is managed by - hardware (NSS pin) or by software using the SSI bit. - This parameter can be a value of - @ref SPI_Slave_Select_Management */ - - uint32_t BaudRatePrescaler; /*!< Specifies the Baud Rate prescaler value which will be - used to configure the transmit and receive SCK clock. - This parameter can be a value of @ref SPI_BaudRate_Prescaler - @note The communication clock is derived from the master - clock. The slave clock does not need to be set. */ - - uint32_t FirstBit; /*!< Specifies whether data transfers start from MSB or LSB bit. - This parameter can be a value of @ref SPI_MSB_LSB_Transmission */ - - uint32_t TIMode; /*!< Specifies if the TI mode is enabled or not. - This parameter can be a value of @ref SPI_TI_Mode */ - - uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not. - This parameter can be a value of @ref SPI_CRC_Calculation */ - - uint32_t CRCPolynomial; /*!< Specifies the polynomial used for the CRC calculation. - This parameter must be an odd number between - Min_Data = 0 and Max_Data = 65535 */ - - uint32_t CRCLength; /*!< Specifies the CRC Length used for the CRC calculation. - This parameter can be a value of @ref SPI_CRC_length */ - - uint32_t NSSPMode; /*!< Specifies whether the NSSP signal is enabled or not . - This parameter can be a value of @ref SPI_NSSP_Mode - This mode is activated by the SSOM bit in the SPIx_CR2 register - and it takes effect only if the SPI interface is configured - as Motorola SPI master (FRF=0). */ - - uint32_t NSSPolarity; /*!< Specifies which level of SS input/output external signal - (present on SS pin) is considered as active one. - This parameter can be a value of @ref SPI_NSS_Polarity */ - - uint32_t FifoThreshold; /*!< Specifies the FIFO threshold level. - This parameter can be a value of @ref SPI_Fifo_Threshold */ - - uint32_t TxCRCInitializationPattern; /*!< Specifies the transmitter CRC initialization Pattern used for - the CRC calculation. This parameter can be a value of - @ref SPI_CRC_Calculation_Initialization_Pattern */ - - uint32_t RxCRCInitializationPattern; /*!< Specifies the receiver CRC initialization Pattern used for - the CRC calculation. This parameter can be a value of - @ref SPI_CRC_Calculation_Initialization_Pattern */ - - uint32_t MasterSSIdleness; /*!< Specifies an extra delay, expressed in number of SPI clock cycle - periods, inserted additionally between active edge of SS - and first data transaction start in master mode. - This parameter can be a value of @ref SPI_Master_SS_Idleness */ - - uint32_t MasterInterDataIdleness; /*!< Specifies minimum time delay (expressed in SPI clock cycles periods) - inserted between two consecutive data frames in master mode. - This parameter can be a value of - @ref SPI_Master_InterData_Idleness */ - - uint32_t MasterReceiverAutoSusp; /*!< Control continuous SPI transfer in master receiver mode - and automatic management in order to avoid overrun condition. - This parameter can be a value of @ref SPI_Master_RX_AutoSuspend*/ - - uint32_t MasterKeepIOState; /*!< Control of Alternate function GPIOs state - This parameter can be a value of @ref SPI_Master_Keep_IO_State */ - - uint32_t IOSwap; /*!< Invert MISO/MOSI alternate functions - This parameter can be a value of @ref SPI_IO_Swap */ -} SPI_InitTypeDef; - -/** - * @brief HAL SPI State structure definition - */ -typedef enum -{ - HAL_SPI_STATE_RESET = 0x00UL, /*!< Peripheral not Initialized */ - HAL_SPI_STATE_READY = 0x01UL, /*!< Peripheral Initialized and ready for use */ - HAL_SPI_STATE_BUSY = 0x02UL, /*!< an internal process is ongoing */ - HAL_SPI_STATE_BUSY_TX = 0x03UL, /*!< Data Transmission process is ongoing */ - HAL_SPI_STATE_BUSY_RX = 0x04UL, /*!< Data Reception process is ongoing */ - HAL_SPI_STATE_BUSY_TX_RX = 0x05UL, /*!< Data Transmission and Reception process is ongoing */ - HAL_SPI_STATE_ERROR = 0x06UL, /*!< SPI error state */ - HAL_SPI_STATE_ABORT = 0x07UL /*!< SPI abort is ongoing */ -} HAL_SPI_StateTypeDef; - -#if defined(USE_SPI_RELOAD_TRANSFER) -/** - * @brief SPI Reload Structure definition - */ -typedef struct -{ - const uint8_t *pTxBuffPtr; /*!< Pointer to SPI Tx transfer Buffer */ - - uint16_t TxXferSize; /*!< SPI Tx Transfer size to reload */ - - uint8_t *pRxBuffPtr; /*!< Pointer to SPI Rx transfer Buffer */ - - uint16_t RxXferSize; /*!< SPI Rx Transfer size to reload */ - - uint32_t Requested; /*!< SPI reload request */ - -} SPI_ReloadTypeDef; -#endif /* USE_SPI_RELOAD_TRANSFER */ - -/** - * @brief SPI handle Structure definition - */ -typedef struct __SPI_HandleTypeDef -{ - SPI_TypeDef *Instance; /*!< SPI registers base address */ - - SPI_InitTypeDef Init; /*!< SPI communication parameters */ - - const uint8_t *pTxBuffPtr; /*!< Pointer to SPI Tx transfer Buffer */ - - uint16_t TxXferSize; /*!< SPI Tx Transfer size */ - - __IO uint16_t TxXferCount; /*!< SPI Tx Transfer Counter */ - - uint8_t *pRxBuffPtr; /*!< Pointer to SPI Rx transfer Buffer */ - - uint16_t RxXferSize; /*!< SPI Rx Transfer size */ - - __IO uint16_t RxXferCount; /*!< SPI Rx Transfer Counter */ - - uint32_t CRCSize; /*!< SPI CRC size used for the transfer */ - - void (*RxISR)(struct __SPI_HandleTypeDef *hspi); /*!< function pointer on Rx ISR */ - - void (*TxISR)(struct __SPI_HandleTypeDef *hspi); /*!< function pointer on Tx ISR */ - - DMA_HandleTypeDef *hdmatx; /*!< SPI Tx DMA Handle parameters */ - - DMA_HandleTypeDef *hdmarx; /*!< SPI Rx DMA Handle parameters */ - - HAL_LockTypeDef Lock; /*!< Locking object */ - - __IO HAL_SPI_StateTypeDef State; /*!< SPI communication state */ - - __IO uint32_t ErrorCode; /*!< SPI Error code */ - -#if defined(USE_SPI_RELOAD_TRANSFER) - - SPI_ReloadTypeDef Reload; /*!< SPI reload parameters */ - -#endif /* USE_SPI_RELOAD_TRANSFER */ - -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - void (* TxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Tx Completed callback */ - void (* RxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Rx Completed callback */ - void (* TxRxCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI TxRx Completed callback */ - void (* TxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Tx Half Completed callback */ - void (* RxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Rx Half Completed callback */ - void (* TxRxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI TxRx Half Completed callback */ - void (* ErrorCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Error callback */ - void (* AbortCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Abort callback */ - void (* SuspendCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Suspend callback */ - void (* MspInitCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Msp Init callback */ - void (* MspDeInitCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI Msp DeInit callback */ - -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -} SPI_HandleTypeDef; - -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) -/** - * @brief HAL SPI Callback ID enumeration definition - */ -typedef enum -{ - HAL_SPI_TX_COMPLETE_CB_ID = 0x00UL, /*!< SPI Tx Completed callback ID */ - HAL_SPI_RX_COMPLETE_CB_ID = 0x01UL, /*!< SPI Rx Completed callback ID */ - HAL_SPI_TX_RX_COMPLETE_CB_ID = 0x02UL, /*!< SPI TxRx Completed callback ID */ - HAL_SPI_TX_HALF_COMPLETE_CB_ID = 0x03UL, /*!< SPI Tx Half Completed callback ID */ - HAL_SPI_RX_HALF_COMPLETE_CB_ID = 0x04UL, /*!< SPI Rx Half Completed callback ID */ - HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID = 0x05UL, /*!< SPI TxRx Half Completed callback ID */ - HAL_SPI_ERROR_CB_ID = 0x06UL, /*!< SPI Error callback ID */ - HAL_SPI_ABORT_CB_ID = 0x07UL, /*!< SPI Abort callback ID */ - HAL_SPI_SUSPEND_CB_ID = 0x08UL, /*!< SPI Suspend callback ID */ - HAL_SPI_MSPINIT_CB_ID = 0x09UL, /*!< SPI Msp Init callback ID */ - HAL_SPI_MSPDEINIT_CB_ID = 0x0AUL /*!< SPI Msp DeInit callback ID */ - -} HAL_SPI_CallbackIDTypeDef; - -/** - * @brief HAL SPI Callback pointer definition - */ -typedef void (*pSPI_CallbackTypeDef)(SPI_HandleTypeDef *hspi); /*!< pointer to an SPI callback function */ - -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -/** - * @} - */ - -/* Exported constants --------------------------------------------------------*/ - -/** @defgroup SPI_Exported_Constants SPI Exported Constants - * @{ - */ - -/** @defgroup SPI_FIFO_Type SPI FIFO Type - * @{ - */ -#define SPI_LOWEND_FIFO_SIZE 8UL -#define SPI_HIGHEND_FIFO_SIZE 16UL -/** - * @} - */ - -/** @defgroup SPI_Error_Code SPI Error Codes - * @{ - */ -#define HAL_SPI_ERROR_NONE (0x00000000UL) /*!< No error */ -#define HAL_SPI_ERROR_MODF (0x00000001UL) /*!< MODF error */ -#define HAL_SPI_ERROR_CRC (0x00000002UL) /*!< CRC error */ -#define HAL_SPI_ERROR_OVR (0x00000004UL) /*!< OVR error */ -#define HAL_SPI_ERROR_FRE (0x00000008UL) /*!< FRE error */ -#define HAL_SPI_ERROR_DMA (0x00000010UL) /*!< DMA transfer error */ -#define HAL_SPI_ERROR_FLAG (0x00000020UL) /*!< Error on RXP/TXP/DXP/FTLVL/FRLVL Flag */ -#define HAL_SPI_ERROR_ABORT (0x00000040UL) /*!< Error during SPI Abort procedure */ -#define HAL_SPI_ERROR_UDR (0x00000080UL) /*!< Underrun error */ -#define HAL_SPI_ERROR_TIMEOUT (0x00000100UL) /*!< Timeout error */ -#define HAL_SPI_ERROR_UNKNOW (0x00000200UL) /*!< Unknown error */ -#define HAL_SPI_ERROR_NOT_SUPPORTED (0x00000400UL) /*!< Requested operation not supported */ -#define HAL_SPI_ERROR_RELOAD (0x00000800UL) /*!< Reload error */ -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) -#define HAL_SPI_ERROR_INVALID_CALLBACK (0x00001000UL) /*!< Invalid Callback error */ -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -/** - * @} - */ - -/** @defgroup SPI_Mode SPI Mode - * @{ - */ -#define SPI_MODE_SLAVE (0x00000000UL) -#define SPI_MODE_MASTER SPI_CFG2_MASTER -/** - * @} - */ - -/** @defgroup SPI_Direction SPI Direction Mode - * @{ - */ -#define SPI_DIRECTION_2LINES (0x00000000UL) -#define SPI_DIRECTION_2LINES_TXONLY SPI_CFG2_COMM_0 -#define SPI_DIRECTION_2LINES_RXONLY SPI_CFG2_COMM_1 -#define SPI_DIRECTION_1LINE SPI_CFG2_COMM -/** - * @} - */ - -/** @defgroup SPI_Data_Size SPI Data Size - * @{ - */ -#define SPI_DATASIZE_4BIT (0x00000003UL) -#define SPI_DATASIZE_5BIT (0x00000004UL) -#define SPI_DATASIZE_6BIT (0x00000005UL) -#define SPI_DATASIZE_7BIT (0x00000006UL) -#define SPI_DATASIZE_8BIT (0x00000007UL) -#define SPI_DATASIZE_9BIT (0x00000008UL) -#define SPI_DATASIZE_10BIT (0x00000009UL) -#define SPI_DATASIZE_11BIT (0x0000000AUL) -#define SPI_DATASIZE_12BIT (0x0000000BUL) -#define SPI_DATASIZE_13BIT (0x0000000CUL) -#define SPI_DATASIZE_14BIT (0x0000000DUL) -#define SPI_DATASIZE_15BIT (0x0000000EUL) -#define SPI_DATASIZE_16BIT (0x0000000FUL) -#define SPI_DATASIZE_17BIT (0x00000010UL) -#define SPI_DATASIZE_18BIT (0x00000011UL) -#define SPI_DATASIZE_19BIT (0x00000012UL) -#define SPI_DATASIZE_20BIT (0x00000013UL) -#define SPI_DATASIZE_21BIT (0x00000014UL) -#define SPI_DATASIZE_22BIT (0x00000015UL) -#define SPI_DATASIZE_23BIT (0x00000016UL) -#define SPI_DATASIZE_24BIT (0x00000017UL) -#define SPI_DATASIZE_25BIT (0x00000018UL) -#define SPI_DATASIZE_26BIT (0x00000019UL) -#define SPI_DATASIZE_27BIT (0x0000001AUL) -#define SPI_DATASIZE_28BIT (0x0000001BUL) -#define SPI_DATASIZE_29BIT (0x0000001CUL) -#define SPI_DATASIZE_30BIT (0x0000001DUL) -#define SPI_DATASIZE_31BIT (0x0000001EUL) -#define SPI_DATASIZE_32BIT (0x0000001FUL) -/** - * @} - */ - -/** @defgroup SPI_Clock_Polarity SPI Clock Polarity - * @{ - */ -#define SPI_POLARITY_LOW (0x00000000UL) -#define SPI_POLARITY_HIGH SPI_CFG2_CPOL -/** - * @} - */ - -/** @defgroup SPI_Clock_Phase SPI Clock Phase - * @{ - */ -#define SPI_PHASE_1EDGE (0x00000000UL) -#define SPI_PHASE_2EDGE SPI_CFG2_CPHA -/** - * @} - */ - -/** @defgroup SPI_Slave_Select_Management SPI Slave Select Management - * @{ - */ -#define SPI_NSS_SOFT SPI_CFG2_SSM -#define SPI_NSS_HARD_INPUT (0x00000000UL) -#define SPI_NSS_HARD_OUTPUT SPI_CFG2_SSOE -/** - * @} - */ - -/** @defgroup SPI_NSSP_Mode SPI NSS Pulse Mode - * @{ - */ -#define SPI_NSS_PULSE_DISABLE (0x00000000UL) -#define SPI_NSS_PULSE_ENABLE SPI_CFG2_SSOM -/** - * @} - */ - -/** @defgroup SPI_BaudRate_Prescaler SPI BaudRate Prescaler - * @{ - */ -#define SPI_BAUDRATEPRESCALER_2 (0x00000000UL) -#define SPI_BAUDRATEPRESCALER_4 (0x10000000UL) -#define SPI_BAUDRATEPRESCALER_8 (0x20000000UL) -#define SPI_BAUDRATEPRESCALER_16 (0x30000000UL) -#define SPI_BAUDRATEPRESCALER_32 (0x40000000UL) -#define SPI_BAUDRATEPRESCALER_64 (0x50000000UL) -#define SPI_BAUDRATEPRESCALER_128 (0x60000000UL) -#define SPI_BAUDRATEPRESCALER_256 (0x70000000UL) -/** - * @} - */ - -/** @defgroup SPI_MSB_LSB_Transmission SPI MSB LSB Transmission - * @{ - */ -#define SPI_FIRSTBIT_MSB (0x00000000UL) -#define SPI_FIRSTBIT_LSB SPI_CFG2_LSBFRST -/** - * @} - */ - -/** @defgroup SPI_TI_Mode SPI TI Mode - * @{ - */ -#define SPI_TIMODE_DISABLE (0x00000000UL) -#define SPI_TIMODE_ENABLE SPI_CFG2_SP_0 -/** - * @} - */ - -/** @defgroup SPI_CRC_Calculation SPI CRC Calculation - * @{ - */ -#define SPI_CRCCALCULATION_DISABLE (0x00000000UL) -#define SPI_CRCCALCULATION_ENABLE SPI_CFG1_CRCEN -/** - * @} - */ - -/** @defgroup SPI_CRC_length SPI CRC Length - * @{ - */ -#define SPI_CRC_LENGTH_DATASIZE (0x00000000UL) -#define SPI_CRC_LENGTH_4BIT (0x00030000UL) -#define SPI_CRC_LENGTH_5BIT (0x00040000UL) -#define SPI_CRC_LENGTH_6BIT (0x00050000UL) -#define SPI_CRC_LENGTH_7BIT (0x00060000UL) -#define SPI_CRC_LENGTH_8BIT (0x00070000UL) -#define SPI_CRC_LENGTH_9BIT (0x00080000UL) -#define SPI_CRC_LENGTH_10BIT (0x00090000UL) -#define SPI_CRC_LENGTH_11BIT (0x000A0000UL) -#define SPI_CRC_LENGTH_12BIT (0x000B0000UL) -#define SPI_CRC_LENGTH_13BIT (0x000C0000UL) -#define SPI_CRC_LENGTH_14BIT (0x000D0000UL) -#define SPI_CRC_LENGTH_15BIT (0x000E0000UL) -#define SPI_CRC_LENGTH_16BIT (0x000F0000UL) -#define SPI_CRC_LENGTH_17BIT (0x00100000UL) -#define SPI_CRC_LENGTH_18BIT (0x00110000UL) -#define SPI_CRC_LENGTH_19BIT (0x00120000UL) -#define SPI_CRC_LENGTH_20BIT (0x00130000UL) -#define SPI_CRC_LENGTH_21BIT (0x00140000UL) -#define SPI_CRC_LENGTH_22BIT (0x00150000UL) -#define SPI_CRC_LENGTH_23BIT (0x00160000UL) -#define SPI_CRC_LENGTH_24BIT (0x00170000UL) -#define SPI_CRC_LENGTH_25BIT (0x00180000UL) -#define SPI_CRC_LENGTH_26BIT (0x00190000UL) -#define SPI_CRC_LENGTH_27BIT (0x001A0000UL) -#define SPI_CRC_LENGTH_28BIT (0x001B0000UL) -#define SPI_CRC_LENGTH_29BIT (0x001C0000UL) -#define SPI_CRC_LENGTH_30BIT (0x001D0000UL) -#define SPI_CRC_LENGTH_31BIT (0x001E0000UL) -#define SPI_CRC_LENGTH_32BIT (0x001F0000UL) -/** - * @} - */ - -/** @defgroup SPI_Fifo_Threshold SPI Fifo Threshold - * @{ - */ -#define SPI_FIFO_THRESHOLD_01DATA (0x00000000UL) -#define SPI_FIFO_THRESHOLD_02DATA (0x00000020UL) -#define SPI_FIFO_THRESHOLD_03DATA (0x00000040UL) -#define SPI_FIFO_THRESHOLD_04DATA (0x00000060UL) -#define SPI_FIFO_THRESHOLD_05DATA (0x00000080UL) -#define SPI_FIFO_THRESHOLD_06DATA (0x000000A0UL) -#define SPI_FIFO_THRESHOLD_07DATA (0x000000C0UL) -#define SPI_FIFO_THRESHOLD_08DATA (0x000000E0UL) -#define SPI_FIFO_THRESHOLD_09DATA (0x00000100UL) -#define SPI_FIFO_THRESHOLD_10DATA (0x00000120UL) -#define SPI_FIFO_THRESHOLD_11DATA (0x00000140UL) -#define SPI_FIFO_THRESHOLD_12DATA (0x00000160UL) -#define SPI_FIFO_THRESHOLD_13DATA (0x00000180UL) -#define SPI_FIFO_THRESHOLD_14DATA (0x000001A0UL) -#define SPI_FIFO_THRESHOLD_15DATA (0x000001C0UL) -#define SPI_FIFO_THRESHOLD_16DATA (0x000001E0UL) -/** - * @} - */ - -/** @defgroup SPI_CRC_Calculation_Initialization_Pattern SPI CRC Calculation Initialization Pattern - * @{ - */ -#define SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN (0x00000000UL) -#define SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN (0x00000001UL) -/** - * @} - */ - -/** @defgroup SPI_NSS_Polarity SPI NSS Polarity - * @{ - */ -#define SPI_NSS_POLARITY_LOW (0x00000000UL) -#define SPI_NSS_POLARITY_HIGH SPI_CFG2_SSIOP -/** - * @} - */ - -/** @defgroup SPI_Master_Keep_IO_State Keep IO State - * @{ - */ -#define SPI_MASTER_KEEP_IO_STATE_DISABLE (0x00000000UL) -#define SPI_MASTER_KEEP_IO_STATE_ENABLE SPI_CFG2_AFCNTR -/** - * @} - */ - -/** @defgroup SPI_IO_Swap Control SPI IO Swap - * @{ - */ -#define SPI_IO_SWAP_DISABLE (0x00000000UL) -#define SPI_IO_SWAP_ENABLE SPI_CFG2_IOSWP -/** - * @} - */ - -/** @defgroup SPI_Master_SS_Idleness SPI Master SS Idleness - * @{ - */ -#define SPI_MASTER_SS_IDLENESS_00CYCLE (0x00000000UL) -#define SPI_MASTER_SS_IDLENESS_01CYCLE (0x00000001UL) -#define SPI_MASTER_SS_IDLENESS_02CYCLE (0x00000002UL) -#define SPI_MASTER_SS_IDLENESS_03CYCLE (0x00000003UL) -#define SPI_MASTER_SS_IDLENESS_04CYCLE (0x00000004UL) -#define SPI_MASTER_SS_IDLENESS_05CYCLE (0x00000005UL) -#define SPI_MASTER_SS_IDLENESS_06CYCLE (0x00000006UL) -#define SPI_MASTER_SS_IDLENESS_07CYCLE (0x00000007UL) -#define SPI_MASTER_SS_IDLENESS_08CYCLE (0x00000008UL) -#define SPI_MASTER_SS_IDLENESS_09CYCLE (0x00000009UL) -#define SPI_MASTER_SS_IDLENESS_10CYCLE (0x0000000AUL) -#define SPI_MASTER_SS_IDLENESS_11CYCLE (0x0000000BUL) -#define SPI_MASTER_SS_IDLENESS_12CYCLE (0x0000000CUL) -#define SPI_MASTER_SS_IDLENESS_13CYCLE (0x0000000DUL) -#define SPI_MASTER_SS_IDLENESS_14CYCLE (0x0000000EUL) -#define SPI_MASTER_SS_IDLENESS_15CYCLE (0x0000000FUL) -/** - * @} - */ - -/** @defgroup SPI_Master_InterData_Idleness SPI Master Inter-Data Idleness - * @{ - */ -#define SPI_MASTER_INTERDATA_IDLENESS_00CYCLE (0x00000000UL) -#define SPI_MASTER_INTERDATA_IDLENESS_01CYCLE (0x00000010UL) -#define SPI_MASTER_INTERDATA_IDLENESS_02CYCLE (0x00000020UL) -#define SPI_MASTER_INTERDATA_IDLENESS_03CYCLE (0x00000030UL) -#define SPI_MASTER_INTERDATA_IDLENESS_04CYCLE (0x00000040UL) -#define SPI_MASTER_INTERDATA_IDLENESS_05CYCLE (0x00000050UL) -#define SPI_MASTER_INTERDATA_IDLENESS_06CYCLE (0x00000060UL) -#define SPI_MASTER_INTERDATA_IDLENESS_07CYCLE (0x00000070UL) -#define SPI_MASTER_INTERDATA_IDLENESS_08CYCLE (0x00000080UL) -#define SPI_MASTER_INTERDATA_IDLENESS_09CYCLE (0x00000090UL) -#define SPI_MASTER_INTERDATA_IDLENESS_10CYCLE (0x000000A0UL) -#define SPI_MASTER_INTERDATA_IDLENESS_11CYCLE (0x000000B0UL) -#define SPI_MASTER_INTERDATA_IDLENESS_12CYCLE (0x000000C0UL) -#define SPI_MASTER_INTERDATA_IDLENESS_13CYCLE (0x000000D0UL) -#define SPI_MASTER_INTERDATA_IDLENESS_14CYCLE (0x000000E0UL) -#define SPI_MASTER_INTERDATA_IDLENESS_15CYCLE (0x000000F0UL) -/** - * @} - */ - -/** @defgroup SPI_Master_RX_AutoSuspend SPI Master Receiver AutoSuspend - * @{ - */ -#define SPI_MASTER_RX_AUTOSUSP_DISABLE (0x00000000UL) -#define SPI_MASTER_RX_AUTOSUSP_ENABLE SPI_CR1_MASRX -/** - * @} - */ - -/** @defgroup SPI_Underrun_Behaviour SPI Underrun Behavior - * @{ - */ -#define SPI_UNDERRUN_BEHAV_REGISTER_PATTERN (0x00000000UL) -#define SPI_UNDERRUN_BEHAV_LAST_RECEIVED SPI_CFG1_UDRCFG_0 -#define SPI_UNDERRUN_BEHAV_LAST_TRANSMITTED SPI_CFG1_UDRCFG_1 -/** - * @} - */ - -/** @defgroup SPI_Underrun_Detection SPI Underrun Detection - * @{ - */ -#define SPI_UNDERRUN_DETECT_BEGIN_DATA_FRAME (0x00000000UL) -#define SPI_UNDERRUN_DETECT_END_DATA_FRAME SPI_CFG1_UDRDET_0 -#define SPI_UNDERRUN_DETECT_BEGIN_ACTIVE_NSS SPI_CFG1_UDRDET_1 -/** - * @} - */ - -/** @defgroup SPI_Interrupt_definition SPI Interrupt Definition - * @{ - */ -#define SPI_IT_RXP SPI_IER_RXPIE -#define SPI_IT_TXP SPI_IER_TXPIE -#define SPI_IT_DXP SPI_IER_DXPIE -#define SPI_IT_EOT SPI_IER_EOTIE -#define SPI_IT_TXTF SPI_IER_TXTFIE -#define SPI_IT_UDR SPI_IER_UDRIE -#define SPI_IT_OVR SPI_IER_OVRIE -#define SPI_IT_CRCERR SPI_IER_CRCEIE -#define SPI_IT_FRE SPI_IER_TIFREIE -#define SPI_IT_MODF SPI_IER_MODFIE -#define SPI_IT_TSERF SPI_IER_TSERFIE -#define SPI_IT_ERR (SPI_IT_UDR | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF | SPI_IT_CRCERR) -/** - * @} - */ - -/** @defgroup SPI_Flags_definition SPI Flags Definition - * @{ - */ -#define SPI_FLAG_RXP SPI_SR_RXP /* SPI status flag : Rx-Packet available flag */ -#define SPI_FLAG_TXP SPI_SR_TXP /* SPI status flag : Tx-Packet space available flag */ -#define SPI_FLAG_DXP SPI_SR_DXP /* SPI status flag : Duplex Packet flag */ -#define SPI_FLAG_EOT SPI_SR_EOT /* SPI status flag : End of transfer flag */ -#define SPI_FLAG_TXTF SPI_SR_TXTF /* SPI status flag : Transmission Transfer Filled flag */ -#define SPI_FLAG_UDR SPI_SR_UDR /* SPI Error flag : Underrun flag */ -#define SPI_FLAG_OVR SPI_SR_OVR /* SPI Error flag : Overrun flag */ -#define SPI_FLAG_CRCERR SPI_SR_CRCE /* SPI Error flag : CRC error flag */ -#define SPI_FLAG_FRE SPI_SR_TIFRE /* SPI Error flag : TI mode frame format error flag */ -#define SPI_FLAG_MODF SPI_SR_MODF /* SPI Error flag : Mode fault flag */ -#define SPI_FLAG_TSERF SPI_SR_TSERF /* SPI status flag : Additional number of data reloaded flag */ -#define SPI_FLAG_SUSP SPI_SR_SUSP /* SPI status flag : Transfer suspend complete flag */ -#define SPI_FLAG_TXC SPI_SR_TXC /* SPI status flag : TxFIFO transmission complete flag */ -#define SPI_FLAG_FRLVL SPI_SR_RXPLVL /* SPI status flag : Fifo reception level flag */ -#define SPI_FLAG_RXWNE SPI_SR_RXWNE /* SPI status flag : RxFIFO word not empty flag */ -/** - * @} - */ - -/** @defgroup SPI_reception_fifo_status_level SPI Reception FIFO Status Level - * @{ - */ -#define SPI_RX_FIFO_0PACKET (0x00000000UL) /* 0 or multiple of 4 packets available in the RxFIFO */ -#define SPI_RX_FIFO_1PACKET (SPI_SR_RXPLVL_0) -#define SPI_RX_FIFO_2PACKET (SPI_SR_RXPLVL_1) -#define SPI_RX_FIFO_3PACKET (SPI_SR_RXPLVL_1 | SPI_SR_RXPLVL_0) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macros -----------------------------------------------------------*/ -/** @defgroup SPI_Exported_Macros SPI Exported Macros - * @{ - */ - -/** @brief Reset SPI handle state. - * @param __HANDLE__: specifies the SPI Handle. - * This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral. - * @retval None - */ -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) -#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) do{ \ - (__HANDLE__)->State = HAL_SPI_STATE_RESET; \ - (__HANDLE__)->MspInitCallback = NULL; \ - (__HANDLE__)->MspDeInitCallback = NULL; \ - } while(0) -#else -#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SPI_STATE_RESET) -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - -/** @brief Enable the specified SPI interrupts. - * @param __HANDLE__: specifies the SPI Handle. - * This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral. - * @param __INTERRUPT__: specifies the interrupt source to enable or disable. - * This parameter can be one of the following values: - * @arg SPI_IT_RXP : Rx-Packet available interrupt - * @arg SPI_IT_TXP : Tx-Packet space available interrupt - * @arg SPI_IT_DXP : Duplex Packet interrupt - * @arg SPI_IT_EOT : End of transfer interrupt - * @arg SPI_IT_TXTF : Transmission Transfer Filled interrupt - * @arg SPI_IT_UDR : Underrun interrupt - * @arg SPI_IT_OVR : Overrun interrupt - * @arg SPI_IT_CRCERR : CRC error interrupt - * @arg SPI_IT_FRE : TI mode frame format error interrupt - * @arg SPI_IT_MODF : Mode fault interrupt - * @arg SPI_IT_TSERF : Additional number of data reloaded interrupt - * @arg SPI_IT_ERR : Error interrupt - * @retval None - */ -#define __HAL_SPI_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER |= (__INTERRUPT__)) - -/** @brief Disable the specified SPI interrupts. - * @param __HANDLE__: specifies the SPI Handle. - * This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral. - * @param __INTERRUPT__: specifies the interrupt source to enable or disable. - * This parameter can be one of the following values: - * @arg SPI_IT_RXP : Rx-Packet available interrupt - * @arg SPI_IT_TXP : Tx-Packet space available interrupt - * @arg SPI_IT_DXP : Duplex Packet interrupt - * @arg SPI_IT_EOT : End of transfer interrupt - * @arg SPI_IT_TXTF : Transmission Transfer Filled interrupt - * @arg SPI_IT_UDR : Underrun interrupt - * @arg SPI_IT_OVR : Overrun interrupt - * @arg SPI_IT_CRCERR : CRC error interrupt - * @arg SPI_IT_FRE : TI mode frame format error interrupt - * @arg SPI_IT_MODF : Mode fault interrupt - * @arg SPI_IT_TSERF : Additional number of data reloaded interrupt - * @arg SPI_IT_ERR : Error interrupt - * @retval None - */ -#define __HAL_SPI_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->IER &= (~(__INTERRUPT__))) - -/** @brief Check whether the specified SPI interrupt source is enabled or not. - * @param __HANDLE__: specifies the SPI Handle. - * This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral. - * @param __INTERRUPT__: specifies the SPI interrupt source to check. - * This parameter can be one of the following values: - * @arg SPI_IT_RXP : Rx-Packet available interrupt - * @arg SPI_IT_TXP : Tx-Packet space available interrupt - * @arg SPI_IT_DXP : Duplex Packet interrupt - * @arg SPI_IT_EOT : End of transfer interrupt - * @arg SPI_IT_TXTF : Transmission Transfer Filled interrupt - * @arg SPI_IT_UDR : Underrun interrupt - * @arg SPI_IT_OVR : Overrun interrupt - * @arg SPI_IT_CRCERR : CRC error interrupt - * @arg SPI_IT_FRE : TI mode frame format error interrupt - * @arg SPI_IT_MODF : Mode fault interrupt - * @arg SPI_IT_TSERF : Additional number of data reloaded interrupt - * @arg SPI_IT_ERR : Error interrupt - * @retval The new state of __IT__ (TRUE or FALSE). - */ -#define __HAL_SPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IER & \ - (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) - -/** @brief Check whether the specified SPI flag is set or not. - * @param __HANDLE__: specifies the SPI Handle. - * This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral. - * @param __FLAG__: specifies the flag to check. - * This parameter can be one of the following values: - * @arg SPI_FLAG_RXP : Rx-Packet available flag - * @arg SPI_FLAG_TXP : Tx-Packet space available flag - * @arg SPI_FLAG_DXP : Duplex Packet flag - * @arg SPI_FLAG_EOT : End of transfer flag - * @arg SPI_FLAG_TXTF : Transmission Transfer Filled flag - * @arg SPI_FLAG_UDR : Underrun flag - * @arg SPI_FLAG_OVR : Overrun flag - * @arg SPI_FLAG_CRCERR : CRC error flag - * @arg SPI_FLAG_FRE : TI mode frame format error flag - * @arg SPI_FLAG_MODF : Mode fault flag - * @arg SPI_FLAG_TSERF : Additional number of data reloaded flag - * @arg SPI_FLAG_SUSP : Transfer suspend complete flag - * @arg SPI_FLAG_TXC : TxFIFO transmission complete flag - * @arg SPI_FLAG_FRLVL : Fifo reception level flag - * @arg SPI_FLAG_RXWNE : RxFIFO word not empty flag - * @retval The new state of __FLAG__ (TRUE or FALSE). - */ -#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) - -/** @brief Clear the SPI CRCERR pending flag. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_CLEAR_CRCERRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_CRCEC) - -/** @brief Clear the SPI MODF pending flag. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_CLEAR_MODFFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , (uint32_t)(SPI_IFCR_MODFC)); - -/** @brief Clear the SPI OVR pending flag. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_CLEAR_OVRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_OVRC) - -/** @brief Clear the SPI FRE pending flag. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_CLEAR_FREFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_TIFREC) - -/** @brief Clear the SPI UDR pending flag. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_CLEAR_UDRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_UDRC) - -/** @brief Clear the SPI EOT pending flag. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_CLEAR_EOTFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_EOTC) - -/** @brief Clear the SPI UDR pending flag. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_CLEAR_TXTFFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_TXTFC) - -/** @brief Clear the SPI SUSP pending flag. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_CLEAR_SUSPFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_SUSPC) - -/** @brief Clear the SPI TSERF pending flag. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_CLEAR_TSERFFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_TSERFC) - -/** @brief Enable the SPI peripheral. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1 , SPI_CR1_SPE) - -/** @brief Disable the SPI peripheral. - * @param __HANDLE__: specifies the SPI Handle. - * @retval None - */ -#define __HAL_SPI_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1 , SPI_CR1_SPE) -/** - * @} - */ - - -/* Include SPI HAL Extension module */ -#include "stm32h7xx_hal_spi_ex.h" - - -/* Exported functions --------------------------------------------------------*/ -/** @addtogroup SPI_Exported_Functions - * @{ - */ - -/** @addtogroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions - * @{ - */ -/* Initialization/de-initialization functions ********************************/ -HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi); -HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi); -void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi); -void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi); - -/* Callbacks Register/UnRegister functions ***********************************/ -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) -HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID, - pSPI_CallbackTypeDef pCallback); -HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -/** - * @} - */ - -/** @addtogroup SPI_Exported_Functions_Group2 IO operation functions - * @{ - */ -/* I/O operation functions ***************************************************/ -HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, - uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, - uint16_t Size); - -HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, - uint16_t Size); - -#if defined(USE_SPI_RELOAD_TRANSFER) -HAL_StatusTypeDef HAL_SPI_Reload_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_SPI_Reload_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_SPI_Reload_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, - uint8_t *pRxData, uint16_t Size); -#endif /* USE_SPI_RELOAD_TRANSFER */ - -HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi); -HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi); -HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi); - -/* Transfer Abort functions */ -HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi); -HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi); - -void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi); -void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi); -void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi); -void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi); -void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi); -void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi); -void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi); -void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi); -void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi); -void HAL_SPI_SuspendCallback(SPI_HandleTypeDef *hspi); -/** - * @} - */ - -/** @addtogroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions - * @{ - */ - -/* Peripheral State and Error functions ***************************************/ -HAL_SPI_StateTypeDef HAL_SPI_GetState(const SPI_HandleTypeDef *hspi); -uint32_t HAL_SPI_GetError(const SPI_HandleTypeDef *hspi); -/** - * @} - */ - -/** - * @} - */ - -/* Private macros ------------------------------------------------------------*/ -/** @defgroup SPI_Private_Macros SPI Private Macros - * @{ - */ - -/** @brief Set the SPI transmit-only mode in 1Line configuration. - * @param __HANDLE__: specifies the SPI Handle. - * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. - * @retval None - */ -#define SPI_1LINE_TX(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_HDDIR) - -/** @brief Set the SPI receive-only mode in 1Line configuration. - * @param __HANDLE__: specifies the SPI Handle. - * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. - * @retval None - */ -#define SPI_1LINE_RX(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_HDDIR) - -/** @brief Set the SPI transmit-only mode in 2Lines configuration. - * @param __HANDLE__: specifies the SPI Handle. - * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. - * @retval None - */ -#define SPI_2LINES_TX(__HANDLE__) MODIFY_REG((__HANDLE__)->Instance->CFG2, SPI_CFG2_COMM, SPI_CFG2_COMM_0) - -/** @brief Set the SPI receive-only mode in 2Lines configuration. - * @param __HANDLE__: specifies the SPI Handle. - * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. - * @retval None - */ -#define SPI_2LINES_RX(__HANDLE__) MODIFY_REG((__HANDLE__)->Instance->CFG2, SPI_CFG2_COMM, SPI_CFG2_COMM_1) - -/** @brief Set the SPI Transmit-Receive mode in 2Lines configuration. - * @param __HANDLE__: specifies the SPI Handle. - * This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral. - * @retval None - */ -#define SPI_2LINES(__HANDLE__) MODIFY_REG((__HANDLE__)->Instance->CFG2, SPI_CFG2_COMM, 0x00000000UL) - -#define IS_SPI_MODE(MODE) (((MODE) == SPI_MODE_SLAVE) || \ - ((MODE) == SPI_MODE_MASTER)) - -#define IS_SPI_DIRECTION(MODE) (((MODE) == SPI_DIRECTION_2LINES) || \ - ((MODE) == SPI_DIRECTION_2LINES_RXONLY) || \ - ((MODE) == SPI_DIRECTION_1LINE) || \ - ((MODE) == SPI_DIRECTION_2LINES_TXONLY)) - -#define IS_SPI_DIRECTION_2LINES(MODE) ((MODE) == SPI_DIRECTION_2LINES) - -#define IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(MODE) (((MODE) == SPI_DIRECTION_2LINES)|| \ - ((MODE) == SPI_DIRECTION_1LINE) || \ - ((MODE) == SPI_DIRECTION_2LINES_TXONLY)) - -#define IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(MODE) (((MODE) == SPI_DIRECTION_2LINES)|| \ - ((MODE) == SPI_DIRECTION_1LINE) || \ - ((MODE) == SPI_DIRECTION_2LINES_RXONLY)) - -#define IS_SPI_DATASIZE(DATASIZE) (((DATASIZE) == SPI_DATASIZE_32BIT) || \ - ((DATASIZE) == SPI_DATASIZE_31BIT) || \ - ((DATASIZE) == SPI_DATASIZE_30BIT) || \ - ((DATASIZE) == SPI_DATASIZE_29BIT) || \ - ((DATASIZE) == SPI_DATASIZE_28BIT) || \ - ((DATASIZE) == SPI_DATASIZE_27BIT) || \ - ((DATASIZE) == SPI_DATASIZE_26BIT) || \ - ((DATASIZE) == SPI_DATASIZE_25BIT) || \ - ((DATASIZE) == SPI_DATASIZE_24BIT) || \ - ((DATASIZE) == SPI_DATASIZE_23BIT) || \ - ((DATASIZE) == SPI_DATASIZE_22BIT) || \ - ((DATASIZE) == SPI_DATASIZE_21BIT) || \ - ((DATASIZE) == SPI_DATASIZE_20BIT) || \ - ((DATASIZE) == SPI_DATASIZE_22BIT) || \ - ((DATASIZE) == SPI_DATASIZE_19BIT) || \ - ((DATASIZE) == SPI_DATASIZE_18BIT) || \ - ((DATASIZE) == SPI_DATASIZE_17BIT) || \ - ((DATASIZE) == SPI_DATASIZE_16BIT) || \ - ((DATASIZE) == SPI_DATASIZE_15BIT) || \ - ((DATASIZE) == SPI_DATASIZE_14BIT) || \ - ((DATASIZE) == SPI_DATASIZE_13BIT) || \ - ((DATASIZE) == SPI_DATASIZE_12BIT) || \ - ((DATASIZE) == SPI_DATASIZE_11BIT) || \ - ((DATASIZE) == SPI_DATASIZE_10BIT) || \ - ((DATASIZE) == SPI_DATASIZE_9BIT) || \ - ((DATASIZE) == SPI_DATASIZE_8BIT) || \ - ((DATASIZE) == SPI_DATASIZE_7BIT) || \ - ((DATASIZE) == SPI_DATASIZE_6BIT) || \ - ((DATASIZE) == SPI_DATASIZE_5BIT) || \ - ((DATASIZE) == SPI_DATASIZE_4BIT)) - -#define IS_SPI_FIFOTHRESHOLD(THRESHOLD) (((THRESHOLD) == SPI_FIFO_THRESHOLD_01DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_02DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_03DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_04DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_05DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_06DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_07DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_08DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_09DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_10DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_11DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_12DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_13DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_14DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_15DATA) || \ - ((THRESHOLD) == SPI_FIFO_THRESHOLD_16DATA)) - -#define IS_SPI_CPOL(CPOL) (((CPOL) == SPI_POLARITY_LOW) || \ - ((CPOL) == SPI_POLARITY_HIGH)) - -#define IS_SPI_CPHA(CPHA) (((CPHA) == SPI_PHASE_1EDGE) || \ - ((CPHA) == SPI_PHASE_2EDGE)) - -#define IS_SPI_NSS(NSS) (((NSS) == SPI_NSS_SOFT) || \ - ((NSS) == SPI_NSS_HARD_INPUT) || \ - ((NSS) == SPI_NSS_HARD_OUTPUT)) - -#define IS_SPI_NSSP(NSSP) (((NSSP) == SPI_NSS_PULSE_ENABLE) || \ - ((NSSP) == SPI_NSS_PULSE_DISABLE)) - -#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER) (((PRESCALER) == SPI_BAUDRATEPRESCALER_2) || \ - ((PRESCALER) == SPI_BAUDRATEPRESCALER_4) || \ - ((PRESCALER) == SPI_BAUDRATEPRESCALER_8) || \ - ((PRESCALER) == SPI_BAUDRATEPRESCALER_16) || \ - ((PRESCALER) == SPI_BAUDRATEPRESCALER_32) || \ - ((PRESCALER) == SPI_BAUDRATEPRESCALER_64) || \ - ((PRESCALER) == SPI_BAUDRATEPRESCALER_128) || \ - ((PRESCALER) == SPI_BAUDRATEPRESCALER_256)) - -#define IS_SPI_FIRST_BIT(BIT) (((BIT) == SPI_FIRSTBIT_MSB) || \ - ((BIT) == SPI_FIRSTBIT_LSB)) - -#define IS_SPI_TIMODE(MODE) (((MODE) == SPI_TIMODE_DISABLE) || \ - ((MODE) == SPI_TIMODE_ENABLE)) - -#define IS_SPI_CRC_CALCULATION(CALCULATION) (((CALCULATION) == SPI_CRCCALCULATION_DISABLE) || \ - ((CALCULATION) == SPI_CRCCALCULATION_ENABLE)) - -#define IS_SPI_CRC_INITIALIZATION_PATTERN(PATTERN) (((PATTERN) == SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN) || \ - ((PATTERN) == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN)) - -#define IS_SPI_CRC_LENGTH(LENGTH) (((LENGTH) == SPI_CRC_LENGTH_DATASIZE) || \ - ((LENGTH) == SPI_CRC_LENGTH_32BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_31BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_30BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_29BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_28BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_27BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_26BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_25BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_24BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_23BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_22BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_21BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_20BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_19BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_18BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_17BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_16BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_15BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_14BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_13BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_12BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_11BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_10BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_9BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_8BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_7BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_6BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_5BIT) || \ - ((LENGTH) == SPI_CRC_LENGTH_4BIT)) - - -#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL) ((POLYNOMIAL) > 0x0UL) - -#define IS_SPI_CRC_POLYNOMIAL_SIZE(POLYNOM, LENGTH) (((POLYNOM) >> (((LENGTH) >> SPI_CFG1_CRCSIZE_Pos) + 1UL)) == 0UL) - - -#define IS_SPI_UNDERRUN_DETECTION(MODE) (((MODE) == SPI_UNDERRUN_DETECT_BEGIN_DATA_FRAME) || \ - ((MODE) == SPI_UNDERRUN_DETECT_END_DATA_FRAME) || \ - ((MODE) == SPI_UNDERRUN_DETECT_BEGIN_ACTIVE_NSS)) - -#define IS_SPI_UNDERRUN_BEHAVIOUR(MODE) (((MODE) == SPI_UNDERRUN_BEHAV_REGISTER_PATTERN) || \ - ((MODE) == SPI_UNDERRUN_BEHAV_LAST_RECEIVED) || \ - ((MODE) == SPI_UNDERRUN_BEHAV_LAST_TRANSMITTED)) - -#define IS_SPI_MASTER_RX_AUTOSUSP(MODE) (((MODE) == SPI_MASTER_RX_AUTOSUSP_DISABLE) || \ - ((MODE) == SPI_MASTER_RX_AUTOSUSP_ENABLE)) -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* STM32H7xx_HAL_SPI_H */ - -/** - * @} - */ diff --git a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_spi.h b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_spi.h deleted file mode 100644 index e382453..0000000 --- a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_spi.h +++ /dev/null @@ -1,3781 +0,0 @@ -/** - ****************************************************************************** - * @file stm32h7xx_ll_spi.h - * @author MCD Application Team - * @brief Header file of SPI LL module. - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef STM32H7xx_LL_SPI_H -#define STM32H7xx_LL_SPI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32h7xx.h" - -/** @addtogroup STM32H7xx_LL_Driver - * @{ - */ - -#if defined(SPI1) || defined(SPI2) || defined(SPI3) || defined(SPI4) || defined(SPI5) || defined(SPI6) - -/** @defgroup SPI_LL SPI - * @{ - */ - -/* Private variables ---------------------------------------------------------*/ - -/* Private constants ---------------------------------------------------------*/ - -/* Private macros ------------------------------------------------------------*/ -/** @defgroup SPI_LL_Private_Macros SPI Private Macros - * @{ - */ -/** - * @} - */ - -/* Exported types ------------------------------------------------------------*/ -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup SPI_LL_Exported_Types SPI Exported Types - * @{ - */ - -/** - * @brief SPI Init structures definition - */ -typedef struct -{ - uint32_t TransferDirection; /*!< Specifies the SPI unidirectional or bidirectional data mode. - This parameter can be a value of @ref SPI_LL_EC_TRANSFER_MODE. - - This feature can be modified afterwards using unitary function - @ref LL_SPI_SetTransferDirection().*/ - - uint32_t Mode; /*!< Specifies the SPI mode (Master/Slave). - This parameter can be a value of @ref SPI_LL_EC_MODE. - - This feature can be modified afterwards using unitary function - @ref LL_SPI_SetMode().*/ - - uint32_t DataWidth; /*!< Specifies the SPI data width. - This parameter can be a value of @ref SPI_LL_EC_DATAWIDTH. - - This feature can be modified afterwards using unitary function - @ref LL_SPI_SetDataWidth().*/ - - uint32_t ClockPolarity; /*!< Specifies the serial clock steady state. - This parameter can be a value of @ref SPI_LL_EC_POLARITY. - - This feature can be modified afterwards using unitary function - @ref LL_SPI_SetClockPolarity().*/ - - uint32_t ClockPhase; /*!< Specifies the clock active edge for the bit capture. - This parameter can be a value of @ref SPI_LL_EC_PHASE. - - This feature can be modified afterwards using unitary function - @ref LL_SPI_SetClockPhase().*/ - - uint32_t NSS; /*!< Specifies whether the NSS signal is managed by hardware (NSS pin) - or by software using the SSI bit. - - This parameter can be a value of @ref SPI_LL_EC_NSS_MODE. - - This feature can be modified afterwards using unitary function - @ref LL_SPI_SetNSSMode().*/ - - uint32_t BaudRate; /*!< Specifies the BaudRate prescaler value which will be used to configure - the transmit and receive SCK clock. - This parameter can be a value of @ref SPI_LL_EC_BAUDRATEPRESCALER. - @note The communication clock is derived from the master clock. - The slave clock does not need to be set. - - This feature can be modified afterwards using unitary function - @ref LL_SPI_SetBaudRatePrescaler().*/ - - uint32_t BitOrder; /*!< Specifies whether data transfers start from MSB or LSB bit. - This parameter can be a value of @ref SPI_LL_EC_BIT_ORDER. - - This feature can be modified afterwards using unitary function - @ref LL_SPI_SetTransferBitOrder().*/ - - uint32_t CRCCalculation; /*!< Specifies if the CRC calculation is enabled or not. - This parameter can be a value of @ref SPI_LL_EC_CRC_CALCULATION. - - This feature can be modified afterwards using unitary functions - @ref LL_SPI_EnableCRC() and @ref LL_SPI_DisableCRC().*/ - - uint32_t CRCPoly; /*!< Specifies the polynomial used for the CRC calculation. - This parameter must be a number between Min_Data = 0x00 - and Max_Data = 0xFFFFFFFF. - - This feature can be modified afterwards using unitary function - @ref LL_SPI_SetCRCPolynomial().*/ - -} LL_SPI_InitTypeDef; - -/** - * @} - */ -#endif /*USE_FULL_LL_DRIVER*/ - -/* Exported types ------------------------------------------------------------*/ - -/* Exported constants --------------------------------------------------------*/ -/** @defgroup SPI_LL_Exported_Constants SPI Exported Constants - * @{ - */ - -/** @defgroup SPI_LL_EC_GET_FLAG Get Flags Defines - * @brief Flags defines which can be used with LL_SPI_ReadReg function - * @{ - */ -#define LL_SPI_SR_RXP (SPI_SR_RXP) -#define LL_SPI_SR_TXP (SPI_SR_TXP) -#define LL_SPI_SR_DXP (SPI_SR_DXP) -#define LL_SPI_SR_EOT (SPI_SR_EOT) -#define LL_SPI_SR_TXTF (SPI_SR_TXTF) -#define LL_SPI_SR_UDR (SPI_SR_UDR) -#define LL_SPI_SR_CRCE (SPI_SR_CRCE) -#define LL_SPI_SR_MODF (SPI_SR_MODF) -#define LL_SPI_SR_OVR (SPI_SR_OVR) -#define LL_SPI_SR_TIFRE (SPI_SR_TIFRE) -#define LL_SPI_SR_TSERF (SPI_SR_TSERF) -#define LL_SPI_SR_SUSP (SPI_SR_SUSP) -#define LL_SPI_SR_TXC (SPI_SR_TXC) -#define LL_SPI_SR_RXWNE (SPI_SR_RXWNE) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_IT IT Defines - * @brief IT defines which can be used with LL_SPI_ReadReg and LL_SPI_WriteReg functions - * @{ - */ -#define LL_SPI_IER_RXPIE (SPI_IER_RXPIE) -#define LL_SPI_IER_TXPIE (SPI_IER_TXPIE) -#define LL_SPI_IER_DXPIE (SPI_IER_DXPIE) -#define LL_SPI_IER_EOTIE (SPI_IER_EOTIE) -#define LL_SPI_IER_TXTFIE (SPI_IER_TXTFIE) -#define LL_SPI_IER_UDRIE (SPI_IER_UDRIE) -#define LL_SPI_IER_OVRIE (SPI_IER_OVRIE) -#define LL_SPI_IER_CRCEIE (SPI_IER_CRCEIE) -#define LL_SPI_IER_TIFREIE (SPI_IER_TIFREIE) -#define LL_SPI_IER_MODFIE (SPI_IER_MODFIE) -#define LL_SPI_IER_TSERFIE (SPI_IER_TSERFIE) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_MODE Mode - * @{ - */ -#define LL_SPI_MODE_MASTER (SPI_CFG2_MASTER) -#define LL_SPI_MODE_SLAVE (0x00000000UL) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_SS_LEVEL SS Level - * @{ - */ -#define LL_SPI_SS_LEVEL_HIGH (SPI_CR1_SSI) -#define LL_SPI_SS_LEVEL_LOW (0x00000000UL) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_SS_IDLENESS SS Idleness - * @{ - */ -#define LL_SPI_SS_IDLENESS_00CYCLE (0x00000000UL) -#define LL_SPI_SS_IDLENESS_01CYCLE (SPI_CFG2_MSSI_0) -#define LL_SPI_SS_IDLENESS_02CYCLE (SPI_CFG2_MSSI_1) -#define LL_SPI_SS_IDLENESS_03CYCLE (SPI_CFG2_MSSI_0 | SPI_CFG2_MSSI_1) -#define LL_SPI_SS_IDLENESS_04CYCLE (SPI_CFG2_MSSI_2) -#define LL_SPI_SS_IDLENESS_05CYCLE (SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_0) -#define LL_SPI_SS_IDLENESS_06CYCLE (SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_1) -#define LL_SPI_SS_IDLENESS_07CYCLE (SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_1 | SPI_CFG2_MSSI_0) -#define LL_SPI_SS_IDLENESS_08CYCLE (SPI_CFG2_MSSI_3) -#define LL_SPI_SS_IDLENESS_09CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_0) -#define LL_SPI_SS_IDLENESS_10CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_1) -#define LL_SPI_SS_IDLENESS_11CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_1 | SPI_CFG2_MSSI_0) -#define LL_SPI_SS_IDLENESS_12CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_2) -#define LL_SPI_SS_IDLENESS_13CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_0) -#define LL_SPI_SS_IDLENESS_14CYCLE (SPI_CFG2_MSSI_3 | SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_1) -#define LL_SPI_SS_IDLENESS_15CYCLE (SPI_CFG2_MSSI_3\ - | SPI_CFG2_MSSI_2 | SPI_CFG2_MSSI_1 | SPI_CFG2_MSSI_0) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_ID_IDLENESS Master Inter-Data Idleness - * @{ - */ -#define LL_SPI_ID_IDLENESS_00CYCLE (0x00000000UL) -#define LL_SPI_ID_IDLENESS_01CYCLE (SPI_CFG2_MIDI_0) -#define LL_SPI_ID_IDLENESS_02CYCLE (SPI_CFG2_MIDI_1) -#define LL_SPI_ID_IDLENESS_03CYCLE (SPI_CFG2_MIDI_0 | SPI_CFG2_MIDI_1) -#define LL_SPI_ID_IDLENESS_04CYCLE (SPI_CFG2_MIDI_2) -#define LL_SPI_ID_IDLENESS_05CYCLE (SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_0) -#define LL_SPI_ID_IDLENESS_06CYCLE (SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_1) -#define LL_SPI_ID_IDLENESS_07CYCLE (SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_1 | SPI_CFG2_MIDI_0) -#define LL_SPI_ID_IDLENESS_08CYCLE (SPI_CFG2_MIDI_3) -#define LL_SPI_ID_IDLENESS_09CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_0) -#define LL_SPI_ID_IDLENESS_10CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_1) -#define LL_SPI_ID_IDLENESS_11CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_1 | SPI_CFG2_MIDI_0) -#define LL_SPI_ID_IDLENESS_12CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_2) -#define LL_SPI_ID_IDLENESS_13CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_0) -#define LL_SPI_ID_IDLENESS_14CYCLE (SPI_CFG2_MIDI_3 | SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_1) -#define LL_SPI_ID_IDLENESS_15CYCLE (SPI_CFG2_MIDI_3\ - | SPI_CFG2_MIDI_2 | SPI_CFG2_MIDI_1 | SPI_CFG2_MIDI_0) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_TXCRCINIT_ALL TXCRC Init All - * @{ - */ -#define LL_SPI_TXCRCINIT_ALL_ZERO_PATTERN (0x00000000UL) -#define LL_SPI_TXCRCINIT_ALL_ONES_PATTERN (SPI_CR1_TCRCINI) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_RXCRCINIT_ALL RXCRC Init All - * @{ - */ -#define LL_SPI_RXCRCINIT_ALL_ZERO_PATTERN (0x00000000UL) -#define LL_SPI_RXCRCINIT_ALL_ONES_PATTERN (SPI_CR1_RCRCINI) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_UDR_CONFIG_REGISTER UDR Config Register - * @{ - */ -#define LL_SPI_UDR_CONFIG_REGISTER_PATTERN (0x00000000UL) -#define LL_SPI_UDR_CONFIG_LAST_RECEIVED (SPI_CFG1_UDRCFG_0) -#define LL_SPI_UDR_CONFIG_LAST_TRANSMITTED (SPI_CFG1_UDRCFG_1) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_UDR_DETECT_BEGIN_DATA UDR Detect Begin Data - * @{ - */ -#define LL_SPI_UDR_DETECT_BEGIN_DATA_FRAME (0x00000000UL) -#define LL_SPI_UDR_DETECT_END_DATA_FRAME (SPI_CFG1_UDRDET_0) -#define LL_SPI_UDR_DETECT_BEGIN_ACTIVE_NSS (SPI_CFG1_UDRDET_1) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_PROTOCOL Protocol - * @{ - */ -#define LL_SPI_PROTOCOL_MOTOROLA (0x00000000UL) -#define LL_SPI_PROTOCOL_TI (SPI_CFG2_SP_0) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_PHASE Phase - * @{ - */ -#define LL_SPI_PHASE_1EDGE (0x00000000UL) -#define LL_SPI_PHASE_2EDGE (SPI_CFG2_CPHA) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_POLARITY Polarity - * @{ - */ -#define LL_SPI_POLARITY_LOW (0x00000000UL) -#define LL_SPI_POLARITY_HIGH (SPI_CFG2_CPOL) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_NSS_POLARITY NSS Polarity - * @{ - */ -#define LL_SPI_NSS_POLARITY_LOW (0x00000000UL) -#define LL_SPI_NSS_POLARITY_HIGH (SPI_CFG2_SSIOP) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_BAUDRATEPRESCALER Baud Rate Prescaler - * @{ - */ -#define LL_SPI_BAUDRATEPRESCALER_DIV2 (0x00000000UL) -#define LL_SPI_BAUDRATEPRESCALER_DIV4 (SPI_CFG1_MBR_0) -#define LL_SPI_BAUDRATEPRESCALER_DIV8 (SPI_CFG1_MBR_1) -#define LL_SPI_BAUDRATEPRESCALER_DIV16 (SPI_CFG1_MBR_1 | SPI_CFG1_MBR_0) -#define LL_SPI_BAUDRATEPRESCALER_DIV32 (SPI_CFG1_MBR_2) -#define LL_SPI_BAUDRATEPRESCALER_DIV64 (SPI_CFG1_MBR_2 | SPI_CFG1_MBR_0) -#define LL_SPI_BAUDRATEPRESCALER_DIV128 (SPI_CFG1_MBR_2 | SPI_CFG1_MBR_1) -#define LL_SPI_BAUDRATEPRESCALER_DIV256 (SPI_CFG1_MBR_2 | SPI_CFG1_MBR_1 | SPI_CFG1_MBR_0) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_BIT_ORDER Bit Order - * @{ - */ -#define LL_SPI_LSB_FIRST (SPI_CFG2_LSBFRST) -#define LL_SPI_MSB_FIRST (0x00000000UL) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_TRANSFER_MODE Transfer Mode - * @{ - */ -#define LL_SPI_FULL_DUPLEX (0x00000000UL) -#define LL_SPI_SIMPLEX_TX (SPI_CFG2_COMM_0) -#define LL_SPI_SIMPLEX_RX (SPI_CFG2_COMM_1) -#define LL_SPI_HALF_DUPLEX_RX (SPI_CFG2_COMM_0|SPI_CFG2_COMM_1) -#define LL_SPI_HALF_DUPLEX_TX (SPI_CFG2_COMM_0|SPI_CFG2_COMM_1|SPI_CR1_HDDIR) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_DATAWIDTH Data Width - * @{ - */ -#define LL_SPI_DATAWIDTH_4BIT (SPI_CFG1_DSIZE_0 | SPI_CFG1_DSIZE_1) -#define LL_SPI_DATAWIDTH_5BIT (SPI_CFG1_DSIZE_2) -#define LL_SPI_DATAWIDTH_6BIT (SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_7BIT (SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1) -#define LL_SPI_DATAWIDTH_8BIT (SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_9BIT (SPI_CFG1_DSIZE_3) -#define LL_SPI_DATAWIDTH_10BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_11BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_1) -#define LL_SPI_DATAWIDTH_12BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_13BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2) -#define LL_SPI_DATAWIDTH_14BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_15BIT (SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1) -#define LL_SPI_DATAWIDTH_16BIT (SPI_CFG1_DSIZE_3\ - | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_17BIT (SPI_CFG1_DSIZE_4) -#define LL_SPI_DATAWIDTH_18BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_19BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_1) -#define LL_SPI_DATAWIDTH_20BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_0 | SPI_CFG1_DSIZE_1) -#define LL_SPI_DATAWIDTH_21BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_2) -#define LL_SPI_DATAWIDTH_22BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_23BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1) -#define LL_SPI_DATAWIDTH_24BIT (SPI_CFG1_DSIZE_4\ - | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_25BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_3) -#define LL_SPI_DATAWIDTH_26BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_27BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_1) -#define LL_SPI_DATAWIDTH_28BIT (SPI_CFG1_DSIZE_4\ - | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_29BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2) -#define LL_SPI_DATAWIDTH_30BIT (SPI_CFG1_DSIZE_4\ - | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_0) -#define LL_SPI_DATAWIDTH_31BIT (SPI_CFG1_DSIZE_4\ - | SPI_CFG1_DSIZE_3 | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1) -#define LL_SPI_DATAWIDTH_32BIT (SPI_CFG1_DSIZE_4 | SPI_CFG1_DSIZE_3\ - | SPI_CFG1_DSIZE_2 | SPI_CFG1_DSIZE_1 | SPI_CFG1_DSIZE_0) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_FIFO_TH FIFO Threshold - * @{ - */ -#define LL_SPI_FIFO_TH_01DATA (0x00000000UL) -#define LL_SPI_FIFO_TH_02DATA (SPI_CFG1_FTHLV_0) -#define LL_SPI_FIFO_TH_03DATA (SPI_CFG1_FTHLV_1) -#define LL_SPI_FIFO_TH_04DATA (SPI_CFG1_FTHLV_0 | SPI_CFG1_FTHLV_1) -#define LL_SPI_FIFO_TH_05DATA (SPI_CFG1_FTHLV_2) -#define LL_SPI_FIFO_TH_06DATA (SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_0) -#define LL_SPI_FIFO_TH_07DATA (SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_1) -#define LL_SPI_FIFO_TH_08DATA (SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_1 | SPI_CFG1_FTHLV_0) -#define LL_SPI_FIFO_TH_09DATA (SPI_CFG1_FTHLV_3) -#define LL_SPI_FIFO_TH_10DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_0) -#define LL_SPI_FIFO_TH_11DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_1) -#define LL_SPI_FIFO_TH_12DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_1 | SPI_CFG1_FTHLV_0) -#define LL_SPI_FIFO_TH_13DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_2) -#define LL_SPI_FIFO_TH_14DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_0) -#define LL_SPI_FIFO_TH_15DATA (SPI_CFG1_FTHLV_3 | SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_1) -#define LL_SPI_FIFO_TH_16DATA (SPI_CFG1_FTHLV_3\ - | SPI_CFG1_FTHLV_2 | SPI_CFG1_FTHLV_1 | SPI_CFG1_FTHLV_0) -/** - * @} - */ - -#if defined(USE_FULL_LL_DRIVER) - -/** @defgroup SPI_LL_EC_CRC_CALCULATION CRC Calculation - * @{ - */ -#define LL_SPI_CRCCALCULATION_DISABLE (0x00000000UL) /*!< CRC calculation disabled */ -#define LL_SPI_CRCCALCULATION_ENABLE (SPI_CFG1_CRCEN) /*!< CRC calculation enabled */ -/** - * @} - */ -#endif /* USE_FULL_LL_DRIVER */ - -/** @defgroup SPI_LL_EC_CRC CRC - * @{ - */ -#define LL_SPI_CRC_4BIT (SPI_CFG1_CRCSIZE_0 | SPI_CFG1_CRCSIZE_1) -#define LL_SPI_CRC_5BIT (SPI_CFG1_CRCSIZE_2) -#define LL_SPI_CRC_6BIT (SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_7BIT (SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1) -#define LL_SPI_CRC_8BIT (SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_9BIT (SPI_CFG1_CRCSIZE_3) -#define LL_SPI_CRC_10BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_11BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_1) -#define LL_SPI_CRC_12BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_13BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2) -#define LL_SPI_CRC_14BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_15BIT (SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1) -#define LL_SPI_CRC_16BIT (SPI_CFG1_CRCSIZE_3\ - | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_17BIT (SPI_CFG1_CRCSIZE_4) -#define LL_SPI_CRC_18BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_19BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_1) -#define LL_SPI_CRC_20BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_0 | SPI_CFG1_CRCSIZE_1) -#define LL_SPI_CRC_21BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_2) -#define LL_SPI_CRC_22BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_23BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1) -#define LL_SPI_CRC_24BIT (SPI_CFG1_CRCSIZE_4\ - | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_25BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_3) -#define LL_SPI_CRC_26BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_27BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_1) -#define LL_SPI_CRC_28BIT (SPI_CFG1_CRCSIZE_4\ - | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_29BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2) -#define LL_SPI_CRC_30BIT (SPI_CFG1_CRCSIZE_4\ - | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_0) -#define LL_SPI_CRC_31BIT (SPI_CFG1_CRCSIZE_4\ - | SPI_CFG1_CRCSIZE_3 | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1) -#define LL_SPI_CRC_32BIT (SPI_CFG1_CRCSIZE_4 | SPI_CFG1_CRCSIZE_3\ - | SPI_CFG1_CRCSIZE_2 | SPI_CFG1_CRCSIZE_1 | SPI_CFG1_CRCSIZE_0) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_NSS_MODE NSS Mode - * @{ - */ -#define LL_SPI_NSS_SOFT (SPI_CFG2_SSM) -#define LL_SPI_NSS_HARD_INPUT (0x00000000UL) -#define LL_SPI_NSS_HARD_OUTPUT (SPI_CFG2_SSOE) -/** - * @} - */ - -/** @defgroup SPI_LL_EC_RX_FIFO RxFIFO Packing LeVel - * @{ - */ -#define LL_SPI_RX_FIFO_0PACKET (0x00000000UL) /* 0 or multiple of 4 packet available is the RxFIFO */ -#define LL_SPI_RX_FIFO_1PACKET (SPI_SR_RXPLVL_0) -#define LL_SPI_RX_FIFO_2PACKET (SPI_SR_RXPLVL_1) -#define LL_SPI_RX_FIFO_3PACKET (SPI_SR_RXPLVL_1 | SPI_SR_RXPLVL_0) -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/** @defgroup SPI_LL_Exported_Macros SPI Exported Macros - * @{ - */ - -/** @defgroup SPI_LL_EM_WRITE_READ Common Write and read registers Macros - * @{ - */ - -/** - * @brief Write a value in SPI register - * @param __INSTANCE__ SPI Instance - * @param __REG__ Register to be written - * @param __VALUE__ Value to be written in the register - * @retval None - */ -#define LL_SPI_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) - -/** - * @brief Read a value in SPI register - * @param __INSTANCE__ SPI Instance - * @param __REG__ Register to be read - * @retval Register value - */ -#define LL_SPI_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) -/** - * @} - */ - -/** - * @} - */ - - -/* Exported functions --------------------------------------------------------*/ - -/** @defgroup SPI_LL_Exported_Functions SPI Exported Functions - * @{ - */ - -/** @defgroup SPI_LL_EF_Configuration Configuration - * @{ - */ - -/** - * @brief Enable SPI peripheral - * @rmtoll CR1 SPE LL_SPI_Enable - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_Enable(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CR1, SPI_CR1_SPE); -} - -/** - * @brief Disable SPI peripheral - * @note When disabling the SPI, follow the procedure described in the Reference Manual. - * @rmtoll CR1 SPE LL_SPI_Disable - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_Disable(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->CR1, SPI_CR1_SPE); -} - -/** - * @brief Check if SPI peripheral is enabled - * @rmtoll CR1 SPE LL_SPI_IsEnabled - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabled(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CR1, SPI_CR1_SPE) == (SPI_CR1_SPE)) ? 1UL : 0UL); -} - -/** - * @brief Swap the MOSI and MISO pin - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG2 IOSWP LL_SPI_EnableIOSwap - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIOSwap(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CFG2, SPI_CFG2_IOSWP); -} - -/** - * @brief Restore default function for MOSI and MISO pin - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG2 IOSWP LL_SPI_DisableIOSwap - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIOSwap(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->CFG2, SPI_CFG2_IOSWP); -} - -/** - * @brief Check if MOSI and MISO pin are swapped - * @rmtoll CFG2 IOSWP LL_SPI_IsEnabledIOSwap - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIOSwap(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CFG2, SPI_CFG2_IOSWP) == (SPI_CFG2_IOSWP)) ? 1UL : 0UL); -} - -/** - * @brief Enable GPIO control - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG2 AFCNTR LL_SPI_EnableGPIOControl - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableGPIOControl(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CFG2, SPI_CFG2_AFCNTR); -} - -/** - * @brief Disable GPIO control - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG2 AFCNTR LL_SPI_DisableGPIOControl - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableGPIOControl(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->CFG2, SPI_CFG2_AFCNTR); -} - -/** - * @brief Check if GPIO control is active - * @rmtoll CFG2 AFCNTR LL_SPI_IsEnabledGPIOControl - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledGPIOControl(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CFG2, SPI_CFG2_AFCNTR) == (SPI_CFG2_AFCNTR)) ? 1UL : 0UL); -} - -/** - * @brief Set SPI Mode to Master or Slave - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG2 MASTER LL_SPI_SetMode - * @param SPIx SPI Instance - * @param Mode This parameter can be one of the following values: - * @arg @ref LL_SPI_MODE_MASTER - * @arg @ref LL_SPI_MODE_SLAVE - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetMode(SPI_TypeDef *SPIx, uint32_t Mode) -{ - MODIFY_REG(SPIx->CFG2, SPI_CFG2_MASTER, Mode); -} - -/** - * @brief Get SPI Mode (Master or Slave) - * @rmtoll CFG2 MASTER LL_SPI_GetMode - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_MODE_MASTER - * @arg @ref LL_SPI_MODE_SLAVE - */ -__STATIC_INLINE uint32_t LL_SPI_GetMode(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_MASTER)); -} - -/** - * @brief Configure the Idleness applied by master between active edge of SS and first send data - * @rmtoll CFG2 MSSI LL_SPI_SetMasterSSIdleness - * @param SPIx SPI Instance - * @param MasterSSIdleness This parameter can be one of the following values: - * @arg @ref LL_SPI_SS_IDLENESS_00CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_01CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_02CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_03CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_04CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_05CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_06CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_07CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_08CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_09CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_10CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_11CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_12CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_13CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_14CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_15CYCLE - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetMasterSSIdleness(SPI_TypeDef *SPIx, uint32_t MasterSSIdleness) -{ - MODIFY_REG(SPIx->CFG2, SPI_CFG2_MSSI, MasterSSIdleness); -} - -/** - * @brief Get the configured Idleness applied by master - * @rmtoll CFG2 MSSI LL_SPI_GetMasterSSIdleness - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_SS_IDLENESS_00CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_01CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_02CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_03CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_04CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_05CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_06CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_07CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_08CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_09CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_10CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_11CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_12CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_13CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_14CYCLE - * @arg @ref LL_SPI_SS_IDLENESS_15CYCLE - */ -__STATIC_INLINE uint32_t LL_SPI_GetMasterSSIdleness(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_MSSI)); -} - -/** - * @brief Configure the idleness applied by master between data frame - * @rmtoll CFG2 MIDI LL_SPI_SetInterDataIdleness - * @param SPIx SPI Instance - * @param MasterInterDataIdleness This parameter can be one of the following values: - * @arg @ref LL_SPI_ID_IDLENESS_00CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_01CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_02CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_03CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_04CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_05CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_06CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_07CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_08CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_09CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_10CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_11CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_12CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_13CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_14CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_15CYCLE - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetInterDataIdleness(SPI_TypeDef *SPIx, uint32_t MasterInterDataIdleness) -{ - MODIFY_REG(SPIx->CFG2, SPI_CFG2_MIDI, MasterInterDataIdleness); -} - -/** - * @brief Get the configured inter data idleness - * @rmtoll CFG2 MIDI LL_SPI_SetInterDataIdleness - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_ID_IDLENESS_00CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_01CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_02CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_03CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_04CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_05CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_06CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_07CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_08CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_09CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_10CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_11CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_12CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_13CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_14CYCLE - * @arg @ref LL_SPI_ID_IDLENESS_15CYCLE - */ -__STATIC_INLINE uint32_t LL_SPI_GetInterDataIdleness(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_MIDI)); -} - -/** - * @brief Set transfer size - * @note Count is the number of frame to be transferred - * @rmtoll CR2 TSIZE LL_SPI_SetTransferSize - * @param SPIx SPI Instance - * @param Count 0..0xFFFF - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetTransferSize(SPI_TypeDef *SPIx, uint32_t Count) -{ - MODIFY_REG(SPIx->CR2, SPI_CR2_TSIZE, Count); -} - -/** - * @brief Get transfer size - * @note Count is the number of frame to be transferred - * @rmtoll CR2 TSIZE LL_SPI_GetTransferSize - * @param SPIx SPI Instance - * @retval 0..0xFFFF - */ -__STATIC_INLINE uint32_t LL_SPI_GetTransferSize(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CR2, SPI_CR2_TSIZE)); -} - -/** - * @brief Set reload transfer size - * @note Count is the number of frame to be transferred - * @rmtoll CR2 TSER LL_SPI_SetReloadSize - * @param SPIx SPI Instance - * @param Count 0..0xFFFF - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetReloadSize(SPI_TypeDef *SPIx, uint32_t Count) -{ - MODIFY_REG(SPIx->CR2, SPI_CR2_TSER, Count << SPI_CR2_TSER_Pos); -} - -/** - * @brief Get reload transfer size - * @note Count is the number of frame to be transferred - * @rmtoll CR2 TSER LL_SPI_GetReloadSize - * @param SPIx SPI Instance - * @retval 0..0xFFFF - */ -__STATIC_INLINE uint32_t LL_SPI_GetReloadSize(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CR2, SPI_CR2_TSER) >> SPI_CR2_TSER_Pos); -} - -/** - * @brief Lock the AF configuration of associated IOs - * @note Once this bit is set, the AF configuration remains locked until a hardware reset occurs. - * the reset of the IOLock bit is done by hardware. for that, LL_SPI_DisableIOLock can not exist. - * @rmtoll CR1 IOLOCK LL_SPI_EnableIOLock - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIOLock(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CR1, SPI_CR1_IOLOCK); -} - -/** - * @brief Check if the AF configuration is locked. - * @rmtoll CR1 IOLOCK LL_SPI_IsEnabledIOLock - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIOLock(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CR1, SPI_CR1_IOLOCK) == (SPI_CR1_IOLOCK)) ? 1UL : 0UL); -} - -/** - * @brief Set Tx CRC Initialization Pattern - * @rmtoll CR1 TCRCINI LL_SPI_SetTxCRCInitPattern - * @param SPIx SPI Instance - * @param TXCRCInitAll This parameter can be one of the following values: - * @arg @ref LL_SPI_TXCRCINIT_ALL_ZERO_PATTERN - * @arg @ref LL_SPI_TXCRCINIT_ALL_ONES_PATTERN - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetTxCRCInitPattern(SPI_TypeDef *SPIx, uint32_t TXCRCInitAll) -{ - MODIFY_REG(SPIx->CR1, SPI_CR1_TCRCINI, TXCRCInitAll); -} - -/** - * @brief Get Tx CRC Initialization Pattern - * @rmtoll CR1 TCRCINI LL_SPI_GetTxCRCInitPattern - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_TXCRCINIT_ALL_ZERO_PATTERN - * @arg @ref LL_SPI_TXCRCINIT_ALL_ONES_PATTERN - */ -__STATIC_INLINE uint32_t LL_SPI_GetTxCRCInitPattern(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_TCRCINI)); -} - -/** - * @brief Set Rx CRC Initialization Pattern - * @rmtoll CR1 RCRCINI LL_SPI_SetRxCRCInitPattern - * @param SPIx SPI Instance - * @param RXCRCInitAll This parameter can be one of the following values: - * @arg @ref LL_SPI_RXCRCINIT_ALL_ZERO_PATTERN - * @arg @ref LL_SPI_RXCRCINIT_ALL_ONES_PATTERN - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetRxCRCInitPattern(SPI_TypeDef *SPIx, uint32_t RXCRCInitAll) -{ - MODIFY_REG(SPIx->CR1, SPI_CR1_RCRCINI, RXCRCInitAll); -} - -/** - * @brief Get Rx CRC Initialization Pattern - * @rmtoll CR1 RCRCINI LL_SPI_GetRxCRCInitPattern - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_RXCRCINIT_ALL_ZERO_PATTERN - * @arg @ref LL_SPI_RXCRCINIT_ALL_ONES_PATTERN - */ -__STATIC_INLINE uint32_t LL_SPI_GetRxCRCInitPattern(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_RCRCINI)); -} - -/** - * @brief Set internal SS input level ignoring what comes from PIN. - * @note This configuration has effect only with config LL_SPI_NSS_SOFT - * @rmtoll CR1 SSI LL_SPI_SetInternalSSLevel - * @param SPIx SPI Instance - * @param SSLevel This parameter can be one of the following values: - * @arg @ref LL_SPI_SS_LEVEL_HIGH - * @arg @ref LL_SPI_SS_LEVEL_LOW - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetInternalSSLevel(SPI_TypeDef *SPIx, uint32_t SSLevel) -{ - MODIFY_REG(SPIx->CR1, SPI_CR1_SSI, SSLevel); -} - -/** - * @brief Get internal SS input level - * @rmtoll CR1 SSI LL_SPI_GetInternalSSLevel - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_SS_LEVEL_HIGH - * @arg @ref LL_SPI_SS_LEVEL_LOW - */ -__STATIC_INLINE uint32_t LL_SPI_GetInternalSSLevel(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_SSI)); -} - -/** - * @brief Enable CRC computation on 33/17 bits - * @rmtoll CR1 CRC33_17 LL_SPI_EnableFullSizeCRC - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableFullSizeCRC(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CR1, SPI_CR1_CRC33_17); -} - -/** - * @brief Disable CRC computation on 33/17 bits - * @rmtoll CR1 CRC33_17 LL_SPI_DisableFullSizeCRC - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableFullSizeCRC(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->CR1, SPI_CR1_CRC33_17); -} - -/** - * @brief Check if Enable CRC computation on 33/17 bits is enabled - * @rmtoll CR1 CRC33_17 LL_SPI_IsEnabledFullSizeCRC - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledFullSizeCRC(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CR1, SPI_CR1_CRC33_17) == (SPI_CR1_CRC33_17)) ? 1UL : 0UL); -} - -/** - * @brief Suspend an ongoing transfer for Master configuration - * @rmtoll CR1 CSUSP LL_SPI_SuspendMasterTransfer - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_SuspendMasterTransfer(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CR1, SPI_CR1_CSUSP); -} - -/** - * @brief Start effective transfer on wire for Master configuration - * @rmtoll CR1 CSTART LL_SPI_StartMasterTransfer - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_StartMasterTransfer(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CR1, SPI_CR1_CSTART); -} - -/** - * @brief Check if there is an unfinished master transfer - * @rmtoll CR1 CSTART LL_SPI_IsActiveMasterTransfer - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveMasterTransfer(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CR1, SPI_CR1_CSTART) == (SPI_CR1_CSTART)) ? 1UL : 0UL); -} - -/** - * @brief Enable Master Rx auto suspend in case of overrun - * @rmtoll CR1 MASRX LL_SPI_EnableMasterRxAutoSuspend - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableMasterRxAutoSuspend(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CR1, SPI_CR1_MASRX); -} - -/** - * @brief Disable Master Rx auto suspend in case of overrun - * @rmtoll CR1 MASRX LL_SPI_DisableMasterRxAutoSuspend - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableMasterRxAutoSuspend(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->CR1, SPI_CR1_MASRX); -} - -/** - * @brief Check if Master Rx auto suspend is activated - * @rmtoll CR1 MASRX LL_SPI_IsEnabledMasterRxAutoSuspend - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledMasterRxAutoSuspend(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CR1, SPI_CR1_MASRX) == (SPI_CR1_MASRX)) ? 1UL : 0UL); -} - -/** - * @brief Set Underrun behavior - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG1 UDRCFG LL_SPI_SetUDRConfiguration - * @param SPIx SPI Instance - * @param UDRConfig This parameter can be one of the following values: - * @arg @ref LL_SPI_UDR_CONFIG_REGISTER_PATTERN - * @arg @ref LL_SPI_UDR_CONFIG_LAST_RECEIVED - * @arg @ref LL_SPI_UDR_CONFIG_LAST_TRANSMITTED - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetUDRConfiguration(SPI_TypeDef *SPIx, uint32_t UDRConfig) -{ - MODIFY_REG(SPIx->CFG1, SPI_CFG1_UDRCFG, UDRConfig); -} - -/** - * @brief Get Underrun behavior - * @rmtoll CFG1 UDRCFG LL_SPI_GetUDRConfiguration - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_UDR_CONFIG_REGISTER_PATTERN - * @arg @ref LL_SPI_UDR_CONFIG_LAST_RECEIVED - * @arg @ref LL_SPI_UDR_CONFIG_LAST_TRANSMITTED - */ -__STATIC_INLINE uint32_t LL_SPI_GetUDRConfiguration(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG1, SPI_CFG1_UDRCFG)); -} - -/** - * @brief Set Underrun Detection method - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG1 UDRDET LL_SPI_SetUDRDetection - * @param SPIx SPI Instance - * @param UDRDetection This parameter can be one of the following values: - * @arg @ref LL_SPI_UDR_DETECT_BEGIN_DATA_FRAME - * @arg @ref LL_SPI_UDR_DETECT_END_DATA_FRAME - * @arg @ref LL_SPI_UDR_DETECT_BEGIN_ACTIVE_NSS - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetUDRDetection(SPI_TypeDef *SPIx, uint32_t UDRDetection) -{ - MODIFY_REG(SPIx->CFG1, SPI_CFG1_UDRDET, UDRDetection); -} - -/** - * @brief Get Underrun Detection method - * @rmtoll CFG1 UDRDET LL_SPI_GetUDRDetection - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_UDR_DETECT_BEGIN_DATA_FRAME - * @arg @ref LL_SPI_UDR_DETECT_END_DATA_FRAME - * @arg @ref LL_SPI_UDR_DETECT_BEGIN_ACTIVE_NSS - */ -__STATIC_INLINE uint32_t LL_SPI_GetUDRDetection(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG1, SPI_CFG1_UDRDET)); -} - -/** - * @brief Set Serial protocol used - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG2 SP LL_SPI_SetStandard - * @param SPIx SPI Instance - * @param Standard This parameter can be one of the following values: - * @arg @ref LL_SPI_PROTOCOL_MOTOROLA - * @arg @ref LL_SPI_PROTOCOL_TI - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetStandard(SPI_TypeDef *SPIx, uint32_t Standard) -{ - MODIFY_REG(SPIx->CFG2, SPI_CFG2_SP, Standard); -} - -/** - * @brief Get Serial protocol used - * @rmtoll CFG2 SP LL_SPI_GetStandard - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_PROTOCOL_MOTOROLA - * @arg @ref LL_SPI_PROTOCOL_TI - */ -__STATIC_INLINE uint32_t LL_SPI_GetStandard(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_SP)); -} - -/** - * @brief Set Clock phase - * @note This configuration can not be changed when SPI is enabled. - * This bit is not used in SPI TI mode. - * @rmtoll CFG2 CPHA LL_SPI_SetClockPhase - * @param SPIx SPI Instance - * @param ClockPhase This parameter can be one of the following values: - * @arg @ref LL_SPI_PHASE_1EDGE - * @arg @ref LL_SPI_PHASE_2EDGE - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetClockPhase(SPI_TypeDef *SPIx, uint32_t ClockPhase) -{ - MODIFY_REG(SPIx->CFG2, SPI_CFG2_CPHA, ClockPhase); -} - -/** - * @brief Get Clock phase - * @rmtoll CFG2 CPHA LL_SPI_GetClockPhase - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_PHASE_1EDGE - * @arg @ref LL_SPI_PHASE_2EDGE - */ -__STATIC_INLINE uint32_t LL_SPI_GetClockPhase(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_CPHA)); -} - -/** - * @brief Set Clock polarity - * @note This configuration can not be changed when SPI is enabled. - * This bit is not used in SPI TI mode. - * @rmtoll CFG2 CPOL LL_SPI_SetClockPolarity - * @param SPIx SPI Instance - * @param ClockPolarity This parameter can be one of the following values: - * @arg @ref LL_SPI_POLARITY_LOW - * @arg @ref LL_SPI_POLARITY_HIGH - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetClockPolarity(SPI_TypeDef *SPIx, uint32_t ClockPolarity) -{ - MODIFY_REG(SPIx->CFG2, SPI_CFG2_CPOL, ClockPolarity); -} - -/** - * @brief Get Clock polarity - * @rmtoll CFG2 CPOL LL_SPI_GetClockPolarity - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_POLARITY_LOW - * @arg @ref LL_SPI_POLARITY_HIGH - */ -__STATIC_INLINE uint32_t LL_SPI_GetClockPolarity(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_CPOL)); -} - -/** - * @brief Set NSS polarity - * @note This configuration can not be changed when SPI is enabled. - * This bit is not used in SPI TI mode. - * @rmtoll CFG2 SSIOP LL_SPI_SetNSSPolarity - * @param SPIx SPI Instance - * @param NSSPolarity This parameter can be one of the following values: - * @arg @ref LL_SPI_NSS_POLARITY_LOW - * @arg @ref LL_SPI_NSS_POLARITY_HIGH - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetNSSPolarity(SPI_TypeDef *SPIx, uint32_t NSSPolarity) -{ - MODIFY_REG(SPIx->CFG2, SPI_CFG2_SSIOP, NSSPolarity); -} - -/** - * @brief Get NSS polarity - * @rmtoll CFG2 SSIOP LL_SPI_GetNSSPolarity - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_NSS_POLARITY_LOW - * @arg @ref LL_SPI_NSS_POLARITY_HIGH - */ -__STATIC_INLINE uint32_t LL_SPI_GetNSSPolarity(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_SSIOP)); -} - -/** - * @brief Set Baudrate Prescaler - * @note This configuration can not be changed when SPI is enabled. - * SPI BaudRate = fPCLK/Pescaler. - * @rmtoll CFG1 MBR LL_SPI_SetBaudRatePrescaler - * @param SPIx SPI Instance - * @param Baudrate This parameter can be one of the following values: - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV2 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV4 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV8 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV16 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV32 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV64 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV128 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV256 - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetBaudRatePrescaler(SPI_TypeDef *SPIx, uint32_t Baudrate) -{ - MODIFY_REG(SPIx->CFG1, SPI_CFG1_MBR, Baudrate); -} - -/** - * @brief Get Baudrate Prescaler - * @rmtoll CFG1 MBR LL_SPI_GetBaudRatePrescaler - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV2 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV4 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV8 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV16 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV32 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV64 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV128 - * @arg @ref LL_SPI_BAUDRATEPRESCALER_DIV256 - */ -__STATIC_INLINE uint32_t LL_SPI_GetBaudRatePrescaler(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG1, SPI_CFG1_MBR)); -} - -/** - * @brief Set Transfer Bit Order - * @note This configuration can not be changed when SPI is enabled. - * This bit is not used in SPI TI mode. - * @rmtoll CFG2 LSBFRST LL_SPI_SetTransferBitOrder - * @param SPIx SPI Instance - * @param BitOrder This parameter can be one of the following values: - * @arg @ref LL_SPI_LSB_FIRST - * @arg @ref LL_SPI_MSB_FIRST - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetTransferBitOrder(SPI_TypeDef *SPIx, uint32_t BitOrder) -{ - MODIFY_REG(SPIx->CFG2, SPI_CFG2_LSBFRST, BitOrder); -} - -/** - * @brief Get Transfer Bit Order - * @rmtoll CFG2 LSBFRST LL_SPI_GetTransferBitOrder - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_LSB_FIRST - * @arg @ref LL_SPI_MSB_FIRST - */ -__STATIC_INLINE uint32_t LL_SPI_GetTransferBitOrder(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_LSBFRST)); -} - -/** - * @brief Set Transfer Mode - * @note This configuration can not be changed when SPI is enabled except for half duplex direction - * using LL_SPI_SetHalfDuplexDirection. - * @rmtoll CR1 HDDIR LL_SPI_SetTransferDirection\n - * CFG2 COMM LL_SPI_SetTransferDirection - * @param SPIx SPI Instance - * @param TransferDirection This parameter can be one of the following values: - * @arg @ref LL_SPI_FULL_DUPLEX - * @arg @ref LL_SPI_SIMPLEX_TX - * @arg @ref LL_SPI_SIMPLEX_RX - * @arg @ref LL_SPI_HALF_DUPLEX_RX - * @arg @ref LL_SPI_HALF_DUPLEX_TX - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetTransferDirection(SPI_TypeDef *SPIx, uint32_t TransferDirection) -{ - MODIFY_REG(SPIx->CR1, SPI_CR1_HDDIR, TransferDirection & SPI_CR1_HDDIR); - MODIFY_REG(SPIx->CFG2, SPI_CFG2_COMM, TransferDirection & SPI_CFG2_COMM); -} - -/** - * @brief Get Transfer Mode - * @rmtoll CR1 HDDIR LL_SPI_GetTransferDirection\n - * CFG2 COMM LL_SPI_GetTransferDirection - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_FULL_DUPLEX - * @arg @ref LL_SPI_SIMPLEX_TX - * @arg @ref LL_SPI_SIMPLEX_RX - * @arg @ref LL_SPI_HALF_DUPLEX_RX - * @arg @ref LL_SPI_HALF_DUPLEX_TX - */ -__STATIC_INLINE uint32_t LL_SPI_GetTransferDirection(const SPI_TypeDef *SPIx) -{ - uint32_t Hddir = READ_BIT(SPIx->CR1, SPI_CR1_HDDIR); - uint32_t Comm = READ_BIT(SPIx->CFG2, SPI_CFG2_COMM); - return (Hddir | Comm); -} - -/** - * @brief Set direction for Half-Duplex Mode - * @note In master mode the MOSI pin is used and in slave mode the MISO pin is used for Half-Duplex. - * @rmtoll CR1 HDDIR LL_SPI_SetHalfDuplexDirection - * @param SPIx SPI Instance - * @param HalfDuplexDirection This parameter can be one of the following values: - * @arg @ref LL_SPI_HALF_DUPLEX_RX - * @arg @ref LL_SPI_HALF_DUPLEX_TX - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetHalfDuplexDirection(SPI_TypeDef *SPIx, uint32_t HalfDuplexDirection) -{ - MODIFY_REG(SPIx->CR1, SPI_CR1_HDDIR, HalfDuplexDirection & SPI_CR1_HDDIR); -} - -/** - * @brief Get direction for Half-Duplex Mode - * @note In master mode the MOSI pin is used and in slave mode the MISO pin is used for Half-Duplex. - * @rmtoll CR1 HDDIR LL_SPI_GetHalfDuplexDirection - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_HALF_DUPLEX_RX - * @arg @ref LL_SPI_HALF_DUPLEX_TX - */ -__STATIC_INLINE uint32_t LL_SPI_GetHalfDuplexDirection(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CR1, SPI_CR1_HDDIR) | SPI_CFG2_COMM); -} - -/** - * @brief Set Frame Data Size - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG1 DSIZE LL_SPI_SetDataWidth - * @param SPIx SPI Instance - * @param DataWidth This parameter can be one of the following values: - * @arg @ref LL_SPI_DATAWIDTH_4BIT - * @arg @ref LL_SPI_DATAWIDTH_5BIT - * @arg @ref LL_SPI_DATAWIDTH_6BIT - * @arg @ref LL_SPI_DATAWIDTH_7BIT - * @arg @ref LL_SPI_DATAWIDTH_8BIT - * @arg @ref LL_SPI_DATAWIDTH_9BIT - * @arg @ref LL_SPI_DATAWIDTH_10BIT - * @arg @ref LL_SPI_DATAWIDTH_11BIT - * @arg @ref LL_SPI_DATAWIDTH_12BIT - * @arg @ref LL_SPI_DATAWIDTH_13BIT - * @arg @ref LL_SPI_DATAWIDTH_14BIT - * @arg @ref LL_SPI_DATAWIDTH_15BIT - * @arg @ref LL_SPI_DATAWIDTH_16BIT - * @arg @ref LL_SPI_DATAWIDTH_17BIT - * @arg @ref LL_SPI_DATAWIDTH_18BIT - * @arg @ref LL_SPI_DATAWIDTH_19BIT - * @arg @ref LL_SPI_DATAWIDTH_20BIT - * @arg @ref LL_SPI_DATAWIDTH_21BIT - * @arg @ref LL_SPI_DATAWIDTH_22BIT - * @arg @ref LL_SPI_DATAWIDTH_23BIT - * @arg @ref LL_SPI_DATAWIDTH_24BIT - * @arg @ref LL_SPI_DATAWIDTH_25BIT - * @arg @ref LL_SPI_DATAWIDTH_26BIT - * @arg @ref LL_SPI_DATAWIDTH_27BIT - * @arg @ref LL_SPI_DATAWIDTH_28BIT - * @arg @ref LL_SPI_DATAWIDTH_29BIT - * @arg @ref LL_SPI_DATAWIDTH_30BIT - * @arg @ref LL_SPI_DATAWIDTH_31BIT - * @arg @ref LL_SPI_DATAWIDTH_32BIT - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetDataWidth(SPI_TypeDef *SPIx, uint32_t DataWidth) -{ - MODIFY_REG(SPIx->CFG1, SPI_CFG1_DSIZE, DataWidth); -} - -/** - * @brief Get Frame Data Size - * @rmtoll CFG1 DSIZE LL_SPI_GetDataWidth - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_DATAWIDTH_4BIT - * @arg @ref LL_SPI_DATAWIDTH_5BIT - * @arg @ref LL_SPI_DATAWIDTH_6BIT - * @arg @ref LL_SPI_DATAWIDTH_7BIT - * @arg @ref LL_SPI_DATAWIDTH_8BIT - * @arg @ref LL_SPI_DATAWIDTH_9BIT - * @arg @ref LL_SPI_DATAWIDTH_10BIT - * @arg @ref LL_SPI_DATAWIDTH_11BIT - * @arg @ref LL_SPI_DATAWIDTH_12BIT - * @arg @ref LL_SPI_DATAWIDTH_13BIT - * @arg @ref LL_SPI_DATAWIDTH_14BIT - * @arg @ref LL_SPI_DATAWIDTH_15BIT - * @arg @ref LL_SPI_DATAWIDTH_16BIT - * @arg @ref LL_SPI_DATAWIDTH_17BIT - * @arg @ref LL_SPI_DATAWIDTH_18BIT - * @arg @ref LL_SPI_DATAWIDTH_19BIT - * @arg @ref LL_SPI_DATAWIDTH_20BIT - * @arg @ref LL_SPI_DATAWIDTH_21BIT - * @arg @ref LL_SPI_DATAWIDTH_22BIT - * @arg @ref LL_SPI_DATAWIDTH_23BIT - * @arg @ref LL_SPI_DATAWIDTH_24BIT - * @arg @ref LL_SPI_DATAWIDTH_25BIT - * @arg @ref LL_SPI_DATAWIDTH_26BIT - * @arg @ref LL_SPI_DATAWIDTH_27BIT - * @arg @ref LL_SPI_DATAWIDTH_28BIT - * @arg @ref LL_SPI_DATAWIDTH_29BIT - * @arg @ref LL_SPI_DATAWIDTH_30BIT - * @arg @ref LL_SPI_DATAWIDTH_31BIT - * @arg @ref LL_SPI_DATAWIDTH_32BIT - */ -__STATIC_INLINE uint32_t LL_SPI_GetDataWidth(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG1, SPI_CFG1_DSIZE)); -} - -/** - * @brief Set threshold of FIFO that triggers a transfer event - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG1 FTHLV LL_SPI_SetFIFOThreshold - * @param SPIx SPI Instance - * @param Threshold This parameter can be one of the following values: - * @arg @ref LL_SPI_FIFO_TH_01DATA - * @arg @ref LL_SPI_FIFO_TH_02DATA - * @arg @ref LL_SPI_FIFO_TH_03DATA - * @arg @ref LL_SPI_FIFO_TH_04DATA - * @arg @ref LL_SPI_FIFO_TH_05DATA - * @arg @ref LL_SPI_FIFO_TH_06DATA - * @arg @ref LL_SPI_FIFO_TH_07DATA - * @arg @ref LL_SPI_FIFO_TH_08DATA - * @arg @ref LL_SPI_FIFO_TH_09DATA - * @arg @ref LL_SPI_FIFO_TH_10DATA - * @arg @ref LL_SPI_FIFO_TH_11DATA - * @arg @ref LL_SPI_FIFO_TH_12DATA - * @arg @ref LL_SPI_FIFO_TH_13DATA - * @arg @ref LL_SPI_FIFO_TH_14DATA - * @arg @ref LL_SPI_FIFO_TH_15DATA - * @arg @ref LL_SPI_FIFO_TH_16DATA - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetFIFOThreshold(SPI_TypeDef *SPIx, uint32_t Threshold) -{ - MODIFY_REG(SPIx->CFG1, SPI_CFG1_FTHLV, Threshold); -} - -/** - * @brief Get threshold of FIFO that triggers a transfer event - * @rmtoll CFG1 FTHLV LL_SPI_GetFIFOThreshold - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_FIFO_TH_01DATA - * @arg @ref LL_SPI_FIFO_TH_02DATA - * @arg @ref LL_SPI_FIFO_TH_03DATA - * @arg @ref LL_SPI_FIFO_TH_04DATA - * @arg @ref LL_SPI_FIFO_TH_05DATA - * @arg @ref LL_SPI_FIFO_TH_06DATA - * @arg @ref LL_SPI_FIFO_TH_07DATA - * @arg @ref LL_SPI_FIFO_TH_08DATA - * @arg @ref LL_SPI_FIFO_TH_09DATA - * @arg @ref LL_SPI_FIFO_TH_10DATA - * @arg @ref LL_SPI_FIFO_TH_11DATA - * @arg @ref LL_SPI_FIFO_TH_12DATA - * @arg @ref LL_SPI_FIFO_TH_13DATA - * @arg @ref LL_SPI_FIFO_TH_14DATA - * @arg @ref LL_SPI_FIFO_TH_15DATA - * @arg @ref LL_SPI_FIFO_TH_16DATA - */ -__STATIC_INLINE uint32_t LL_SPI_GetFIFOThreshold(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG1, SPI_CFG1_FTHLV)); -} - -/** - * @brief Enable CRC - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG1 CRCEN LL_SPI_EnableCRC - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableCRC(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CFG1, SPI_CFG1_CRCEN); -} - -/** - * @brief Disable CRC - * @rmtoll CFG1 CRCEN LL_SPI_DisableCRC - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableCRC(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->CFG1, SPI_CFG1_CRCEN); -} - -/** - * @brief Check if CRC is enabled - * @rmtoll CFG1 CRCEN LL_SPI_IsEnabledCRC - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledCRC(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CFG1, SPI_CFG1_CRCEN) == SPI_CFG1_CRCEN) ? 1UL : 0UL); -} - -/** - * @brief Set CRC Length - * @note This configuration can not be changed when SPI is enabled. - * @rmtoll CFG1 CRCSIZE LL_SPI_SetCRCWidth - * @param SPIx SPI Instance - * @param CRCLength This parameter can be one of the following values: - * @arg @ref LL_SPI_CRC_4BIT - * @arg @ref LL_SPI_CRC_5BIT - * @arg @ref LL_SPI_CRC_6BIT - * @arg @ref LL_SPI_CRC_7BIT - * @arg @ref LL_SPI_CRC_8BIT - * @arg @ref LL_SPI_CRC_9BIT - * @arg @ref LL_SPI_CRC_10BIT - * @arg @ref LL_SPI_CRC_11BIT - * @arg @ref LL_SPI_CRC_12BIT - * @arg @ref LL_SPI_CRC_13BIT - * @arg @ref LL_SPI_CRC_14BIT - * @arg @ref LL_SPI_CRC_15BIT - * @arg @ref LL_SPI_CRC_16BIT - * @arg @ref LL_SPI_CRC_17BIT - * @arg @ref LL_SPI_CRC_18BIT - * @arg @ref LL_SPI_CRC_19BIT - * @arg @ref LL_SPI_CRC_20BIT - * @arg @ref LL_SPI_CRC_21BIT - * @arg @ref LL_SPI_CRC_22BIT - * @arg @ref LL_SPI_CRC_23BIT - * @arg @ref LL_SPI_CRC_24BIT - * @arg @ref LL_SPI_CRC_25BIT - * @arg @ref LL_SPI_CRC_26BIT - * @arg @ref LL_SPI_CRC_27BIT - * @arg @ref LL_SPI_CRC_28BIT - * @arg @ref LL_SPI_CRC_29BIT - * @arg @ref LL_SPI_CRC_30BIT - * @arg @ref LL_SPI_CRC_31BIT - * @arg @ref LL_SPI_CRC_32BIT - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetCRCWidth(SPI_TypeDef *SPIx, uint32_t CRCLength) -{ - MODIFY_REG(SPIx->CFG1, SPI_CFG1_CRCSIZE, CRCLength); -} - -/** - * @brief Get CRC Length - * @rmtoll CFG1 CRCSIZE LL_SPI_GetCRCWidth - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_CRC_4BIT - * @arg @ref LL_SPI_CRC_5BIT - * @arg @ref LL_SPI_CRC_6BIT - * @arg @ref LL_SPI_CRC_7BIT - * @arg @ref LL_SPI_CRC_8BIT - * @arg @ref LL_SPI_CRC_9BIT - * @arg @ref LL_SPI_CRC_10BIT - * @arg @ref LL_SPI_CRC_11BIT - * @arg @ref LL_SPI_CRC_12BIT - * @arg @ref LL_SPI_CRC_13BIT - * @arg @ref LL_SPI_CRC_14BIT - * @arg @ref LL_SPI_CRC_15BIT - * @arg @ref LL_SPI_CRC_16BIT - * @arg @ref LL_SPI_CRC_17BIT - * @arg @ref LL_SPI_CRC_18BIT - * @arg @ref LL_SPI_CRC_19BIT - * @arg @ref LL_SPI_CRC_20BIT - * @arg @ref LL_SPI_CRC_21BIT - * @arg @ref LL_SPI_CRC_22BIT - * @arg @ref LL_SPI_CRC_23BIT - * @arg @ref LL_SPI_CRC_24BIT - * @arg @ref LL_SPI_CRC_25BIT - * @arg @ref LL_SPI_CRC_26BIT - * @arg @ref LL_SPI_CRC_27BIT - * @arg @ref LL_SPI_CRC_28BIT - * @arg @ref LL_SPI_CRC_29BIT - * @arg @ref LL_SPI_CRC_30BIT - * @arg @ref LL_SPI_CRC_31BIT - * @arg @ref LL_SPI_CRC_32BIT - */ -__STATIC_INLINE uint32_t LL_SPI_GetCRCWidth(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG1, SPI_CFG1_CRCSIZE)); -} - -/** - * @brief Set NSS Mode - * @note This configuration can not be changed when SPI is enabled. - * This bit is not used in SPI TI mode. - * @rmtoll CFG2 SSM LL_SPI_SetNSSMode\n - * CFG2 SSOE LL_SPI_SetNSSMode - * @param SPIx SPI Instance - * @param NSS This parameter can be one of the following values: - * @arg @ref LL_SPI_NSS_SOFT - * @arg @ref LL_SPI_NSS_HARD_INPUT - * @arg @ref LL_SPI_NSS_HARD_OUTPUT - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetNSSMode(SPI_TypeDef *SPIx, uint32_t NSS) -{ - MODIFY_REG(SPIx->CFG2, SPI_CFG2_SSM | SPI_CFG2_SSOE, NSS); -} - -/** - * @brief Set NSS Mode - * @rmtoll CFG2 SSM LL_SPI_GetNSSMode\n - * CFG2 SSOE LL_SPI_GetNSSMode - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_NSS_SOFT - * @arg @ref LL_SPI_NSS_HARD_INPUT - * @arg @ref LL_SPI_NSS_HARD_OUTPUT - */ -__STATIC_INLINE uint32_t LL_SPI_GetNSSMode(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->CFG2, SPI_CFG2_SSM | SPI_CFG2_SSOE)); -} - -/** - * @brief Enable NSS pulse mgt - * @note This configuration can not be changed when SPI is enabled. - * This bit is not used in SPI TI mode. - * @rmtoll CFG2 SSOM LL_SPI_EnableNSSPulseMgt - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableNSSPulseMgt(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CFG2, SPI_CFG2_SSOM); -} - -/** - * @brief Disable NSS pulse mgt - * @note This configuration can not be changed when SPI is enabled. - * This bit is not used in SPI TI mode. - * @rmtoll CFG2 SSOM LL_SPI_DisableNSSPulseMgt - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableNSSPulseMgt(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->CFG2, SPI_CFG2_SSOM); -} - -/** - * @brief Check if NSS pulse is enabled - * @rmtoll CFG2 SSOM LL_SPI_IsEnabledNSSPulse - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledNSSPulse(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CFG2, SPI_CFG2_SSOM) == SPI_CFG2_SSOM) ? 1UL : 0UL); -} - -/** - * @} - */ - -/** @defgroup SPI_LL_EF_FLAG_Management FLAG_Management - * @{ - */ - -/** - * @brief Check if there is enough data in FIFO to read a full packet - * @rmtoll SR RXP LL_SPI_IsActiveFlag_RXP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_RXP(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_RXP) == (SPI_SR_RXP)) ? 1UL : 0UL); -} - -/** - * @brief Check if there is enough space in FIFO to hold a full packet - * @rmtoll SR TXP LL_SPI_IsActiveFlag_TXP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXP(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_TXP) == (SPI_SR_TXP)) ? 1UL : 0UL); -} - -/** - * @brief Check if there enough space in FIFO to hold a full packet, AND enough data to read a full packet - * @rmtoll SR DXP LL_SPI_IsActiveFlag_DXP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_DXP(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_DXP) == (SPI_SR_DXP)) ? 1UL : 0UL); -} - -/** - * @brief Check that end of transfer event occurred - * @rmtoll SR EOT LL_SPI_IsActiveFlag_EOT - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_EOT(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_EOT) == (SPI_SR_EOT)) ? 1UL : 0UL); -} - -/** - * @brief Check that all required data has been filled in the fifo according to transfer size - * @rmtoll SR TXTF LL_SPI_IsActiveFlag_TXTF - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXTF(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_TXTF) == (SPI_SR_TXTF)) ? 1UL : 0UL); -} - -/** - * @brief Get Underrun error flag - * @rmtoll SR UDR LL_SPI_IsActiveFlag_UDR - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_UDR(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_UDR) == (SPI_SR_UDR)) ? 1UL : 0UL); -} - -/** - * @brief Get CRC error flag - * @rmtoll SR CRCE LL_SPI_IsActiveFlag_CRCERR - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_CRCERR(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_CRCE) == (SPI_SR_CRCE)) ? 1UL : 0UL); -} - -/** - * @brief Get Mode fault error flag - * @rmtoll SR MODF LL_SPI_IsActiveFlag_MODF - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_MODF(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_MODF) == (SPI_SR_MODF)) ? 1UL : 0UL); -} - -/** - * @brief Get Overrun error flag - * @rmtoll SR OVR LL_SPI_IsActiveFlag_OVR - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_OVR(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_OVR) == (SPI_SR_OVR)) ? 1UL : 0UL); -} - -/** - * @brief Get TI Frame format error flag - * @rmtoll SR TIFRE LL_SPI_IsActiveFlag_FRE - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_FRE(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_TIFRE) == (SPI_SR_TIFRE)) ? 1UL : 0UL); -} - -/** - * @brief Check if the additional number of data has been reloaded - * @rmtoll SR TSERF LL_SPI_IsActiveFlag_TSER - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TSER(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_TSERF) == (SPI_SR_TSERF)) ? 1UL : 0UL); -} - -/** - * @brief Check if a suspend operation is done - * @rmtoll SR SUSP LL_SPI_IsActiveFlag_SUSP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_SUSP(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_SUSP) == (SPI_SR_SUSP)) ? 1UL : 0UL); -} - -/** - * @brief Check if last TxFIFO or CRC frame transmission is completed - * @rmtoll SR TXC LL_SPI_IsActiveFlag_TXC - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_TXC(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_TXC) == (SPI_SR_TXC)) ? 1UL : 0UL); -} - -/** - * @brief Check if at least one 32-bit data is available in RxFIFO - * @rmtoll SR RXWNE LL_SPI_IsActiveFlag_RXWNE - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsActiveFlag_RXWNE(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->SR, SPI_SR_RXWNE) == (SPI_SR_RXWNE)) ? 1UL : 0UL); -} - -/** - * @brief Get number of data framed remaining in current TSIZE - * @rmtoll SR CTSIZE LL_SPI_GetRemainingDataFrames - * @param SPIx SPI Instance - * @retval 0..0xFFFF - */ -__STATIC_INLINE uint32_t LL_SPI_GetRemainingDataFrames(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->SR, SPI_SR_CTSIZE) >> SPI_SR_CTSIZE_Pos); -} - -/** - * @brief Get RxFIFO packing Level - * @rmtoll SR RXPLVL LL_SPI_GetRxFIFOPackingLevel - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_SPI_RX_FIFO_0PACKET - * @arg @ref LL_SPI_RX_FIFO_1PACKET - * @arg @ref LL_SPI_RX_FIFO_2PACKET - * @arg @ref LL_SPI_RX_FIFO_3PACKET - */ -__STATIC_INLINE uint32_t LL_SPI_GetRxFIFOPackingLevel(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->SR, SPI_SR_RXPLVL)); -} - -/** - * @brief Clear End Of Transfer flag - * @rmtoll IFCR EOTC LL_SPI_ClearFlag_EOT - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_ClearFlag_EOT(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IFCR, SPI_IFCR_EOTC); -} - -/** - * @brief Clear TXTF flag - * @rmtoll IFCR TXTFC LL_SPI_ClearFlag_TXTF - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_ClearFlag_TXTF(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IFCR, SPI_IFCR_TXTFC); -} - -/** - * @brief Clear Underrun error flag - * @rmtoll IFCR UDRC LL_SPI_ClearFlag_UDR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_ClearFlag_UDR(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IFCR, SPI_IFCR_UDRC); -} - -/** - * @brief Clear Overrun error flag - * @rmtoll IFCR OVRC LL_SPI_ClearFlag_OVR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_ClearFlag_OVR(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IFCR, SPI_IFCR_OVRC); -} - -/** - * @brief Clear CRC error flag - * @rmtoll IFCR CRCEC LL_SPI_ClearFlag_CRCERR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_ClearFlag_CRCERR(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IFCR, SPI_IFCR_CRCEC); -} - -/** - * @brief Clear Mode fault error flag - * @rmtoll IFCR MODFC LL_SPI_ClearFlag_MODF - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_ClearFlag_MODF(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IFCR, SPI_IFCR_MODFC); -} - -/** - * @brief Clear Frame format error flag - * @rmtoll IFCR TIFREC LL_SPI_ClearFlag_FRE - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_ClearFlag_FRE(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IFCR, SPI_IFCR_TIFREC); -} - -/** - * @brief Clear TSER flag - * @rmtoll IFCR TSERFC LL_SPI_ClearFlag_TSER - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_ClearFlag_TSER(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IFCR, SPI_IFCR_TSERFC); -} - -/** - * @brief Clear SUSP flag - * @rmtoll IFCR SUSPC LL_SPI_ClearFlag_SUSP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_ClearFlag_SUSP(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IFCR, SPI_IFCR_SUSPC); -} - -/** - * @} - */ - -/** @defgroup SPI_LL_EF_IT_Management IT_Management - * @{ - */ - -/** - * @brief Enable Rx Packet available IT - * @rmtoll IER RXPIE LL_SPI_EnableIT_RXP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_RXP(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_RXPIE); -} - -/** - * @brief Enable Tx Packet space available IT - * @rmtoll IER TXPIE LL_SPI_EnableIT_TXP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_TXP(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_TXPIE); -} - -/** - * @brief Enable Duplex Packet available IT - * @rmtoll IER DXPIE LL_SPI_EnableIT_DXP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_DXP(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_DXPIE); -} - -/** - * @brief Enable End Of Transfer IT - * @rmtoll IER EOTIE LL_SPI_EnableIT_EOT - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_EOT(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_EOTIE); -} - -/** - * @brief Enable TXTF IT - * @rmtoll IER TXTFIE LL_SPI_EnableIT_TXTF - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_TXTF(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_TXTFIE); -} - -/** - * @brief Enable Underrun IT - * @rmtoll IER UDRIE LL_SPI_EnableIT_UDR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_UDR(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_UDRIE); -} - -/** - * @brief Enable Overrun IT - * @rmtoll IER OVRIE LL_SPI_EnableIT_OVR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_OVR(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_OVRIE); -} - -/** - * @brief Enable CRC Error IT - * @rmtoll IER CRCEIE LL_SPI_EnableIT_CRCERR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_CRCERR(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_CRCEIE); -} - -/** - * @brief Enable TI Frame Format Error IT - * @rmtoll IER TIFREIE LL_SPI_EnableIT_FRE - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_FRE(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_TIFREIE); -} - -/** - * @brief Enable MODF IT - * @rmtoll IER MODFIE LL_SPI_EnableIT_MODF - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_MODF(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_MODFIE); -} - -/** - * @brief Enable TSER reload IT - * @rmtoll IER TSERFIE LL_SPI_EnableIT_TSER - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableIT_TSER(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->IER, SPI_IER_TSERFIE); -} - -/** - * @brief Disable Rx Packet available IT - * @rmtoll IER RXPIE LL_SPI_DisableIT_RXP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_RXP(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_RXPIE); -} - -/** - * @brief Disable Tx Packet space available IT - * @rmtoll IER TXPIE LL_SPI_DisableIT_TXP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_TXP(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_TXPIE); -} - -/** - * @brief Disable Duplex Packet available IT - * @rmtoll IER DXPIE LL_SPI_DisableIT_DXP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_DXP(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_DXPIE); -} - -/** - * @brief Disable End Of Transfer IT - * @rmtoll IER EOTIE LL_SPI_DisableIT_EOT - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_EOT(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_EOTIE); -} - -/** - * @brief Disable TXTF IT - * @rmtoll IER TXTFIE LL_SPI_DisableIT_TXTF - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_TXTF(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_TXTFIE); -} - -/** - * @brief Disable Underrun IT - * @rmtoll IER UDRIE LL_SPI_DisableIT_UDR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_UDR(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_UDRIE); -} - -/** - * @brief Disable Overrun IT - * @rmtoll IER OVRIE LL_SPI_DisableIT_OVR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_OVR(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_OVRIE); -} - -/** - * @brief Disable CRC Error IT - * @rmtoll IER CRCEIE LL_SPI_DisableIT_CRCERR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_CRCERR(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_CRCEIE); -} - -/** - * @brief Disable TI Frame Format Error IT - * @rmtoll IER TIFREIE LL_SPI_DisableIT_FRE - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_FRE(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_TIFREIE); -} - -/** - * @brief Disable MODF IT - * @rmtoll IER MODFIE LL_SPI_DisableIT_MODF - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_MODF(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_MODFIE); -} - -/** - * @brief Disable TSER reload IT - * @rmtoll IER TSERFIE LL_SPI_DisableIT_TSER - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableIT_TSER(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->IER, SPI_IER_TSERFIE); -} - -/** - * @brief Check if Rx Packet available IT is enabled - * @rmtoll IER RXPIE LL_SPI_IsEnabledIT_RXP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_RXP(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_RXPIE) == (SPI_IER_RXPIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if Tx Packet space available IT is enabled - * @rmtoll IER TXPIE LL_SPI_IsEnabledIT_TXP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_TXP(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_TXPIE) == (SPI_IER_TXPIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if Duplex Packet available IT is enabled - * @rmtoll IER DXPIE LL_SPI_IsEnabledIT_DXP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_DXP(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_DXPIE) == (SPI_IER_DXPIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if End Of Transfer IT is enabled - * @rmtoll IER EOTIE LL_SPI_IsEnabledIT_EOT - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_EOT(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_EOTIE) == (SPI_IER_EOTIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if TXTF IT is enabled - * @rmtoll IER TXTFIE LL_SPI_IsEnabledIT_TXTF - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_TXTF(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_TXTFIE) == (SPI_IER_TXTFIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if Underrun IT is enabled - * @rmtoll IER UDRIE LL_SPI_IsEnabledIT_UDR - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_UDR(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_UDRIE) == (SPI_IER_UDRIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if Overrun IT is enabled - * @rmtoll IER OVRIE LL_SPI_IsEnabledIT_OVR - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_OVR(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_OVRIE) == (SPI_IER_OVRIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if CRC Error IT is enabled - * @rmtoll IER CRCEIE LL_SPI_IsEnabledIT_CRCERR - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_CRCERR(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_CRCEIE) == (SPI_IER_CRCEIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if TI Frame Format Error IT is enabled - * @rmtoll IER TIFREIE LL_SPI_IsEnabledIT_FRE - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_FRE(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_TIFREIE) == (SPI_IER_TIFREIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if MODF IT is enabled - * @rmtoll IER MODFIE LL_SPI_IsEnabledIT_MODF - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_MODF(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_MODFIE) == (SPI_IER_MODFIE)) ? 1UL : 0UL); -} - -/** - * @brief Check if TSER reload IT is enabled - * @rmtoll IER TSERFIE LL_SPI_IsEnabledIT_TSER - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledIT_TSER(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->IER, SPI_IER_TSERFIE) == (SPI_IER_TSERFIE)) ? 1UL : 0UL); -} - -/** - * @} - */ - -/** @defgroup SPI_LL_EF_DMA_Management DMA Management - * @{ - */ - -/** - * @brief Enable DMA Rx - * @rmtoll CFG1 RXDMAEN LL_SPI_EnableDMAReq_RX - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableDMAReq_RX(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CFG1, SPI_CFG1_RXDMAEN); -} - -/** - * @brief Disable DMA Rx - * @rmtoll CFG1 RXDMAEN LL_SPI_DisableDMAReq_RX - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableDMAReq_RX(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->CFG1, SPI_CFG1_RXDMAEN); -} - -/** - * @brief Check if DMA Rx is enabled - * @rmtoll CFG1 RXDMAEN LL_SPI_IsEnabledDMAReq_RX - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledDMAReq_RX(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CFG1, SPI_CFG1_RXDMAEN) == (SPI_CFG1_RXDMAEN)) ? 1UL : 0UL); -} - -/** - * @brief Enable DMA Tx - * @rmtoll CFG1 TXDMAEN LL_SPI_EnableDMAReq_TX - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_EnableDMAReq_TX(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->CFG1, SPI_CFG1_TXDMAEN); -} - -/** - * @brief Disable DMA Tx - * @rmtoll CFG1 TXDMAEN LL_SPI_DisableDMAReq_TX - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_SPI_DisableDMAReq_TX(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->CFG1, SPI_CFG1_TXDMAEN); -} - -/** - * @brief Check if DMA Tx is enabled - * @rmtoll CFG1 TXDMAEN LL_SPI_IsEnabledDMAReq_TX - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_SPI_IsEnabledDMAReq_TX(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->CFG1, SPI_CFG1_TXDMAEN) == (SPI_CFG1_TXDMAEN)) ? 1UL : 0UL); -} -/** - * @brief Get the data register address used for DMA transfer - * @rmtoll TXDR TXDR LL_SPI_DMA_GetTxRegAddr - * @param SPIx SPI Instance - * @retval Address of data register - */ -__STATIC_INLINE uint32_t LL_SPI_DMA_GetTxRegAddr(const SPI_TypeDef *SPIx) -{ - return (uint32_t) &(SPIx->TXDR); -} - -/** - * @brief Get the data register address used for DMA transfer - * @rmtoll RXDR RXDR LL_SPI_DMA_GetRxRegAddr - * @param SPIx SPI Instance - * @retval Address of data register - */ -__STATIC_INLINE uint32_t LL_SPI_DMA_GetRxRegAddr(const SPI_TypeDef *SPIx) -{ - return (uint32_t) &(SPIx->RXDR); -} -/** - * @} - */ - -/** @defgroup SPI_LL_EF_DATA_Management DATA_Management - * @{ - */ - -/** - * @brief Read Data Register - * @rmtoll RXDR . LL_SPI_ReceiveData8 - * @param SPIx SPI Instance - * @retval 0..0xFF - */ -__STATIC_INLINE uint8_t LL_SPI_ReceiveData8(SPI_TypeDef *SPIx) /* Derogation MISRAC2012-Rule-8.13 */ -{ - return (*((__IO uint8_t *)&SPIx->RXDR)); -} - -/** - * @brief Read Data Register - * @rmtoll RXDR . LL_SPI_ReceiveData16 - * @param SPIx SPI Instance - * @retval 0..0xFFFF - */ -__STATIC_INLINE uint16_t LL_SPI_ReceiveData16(SPI_TypeDef *SPIx) /* Derogation MISRAC2012-Rule-8.13 */ -{ -#if defined (__GNUC__) - __IO uint16_t *spirxdr = (__IO uint16_t *)(&(SPIx->RXDR)); - return (*spirxdr); -#else - return (*((__IO uint16_t *)&SPIx->RXDR)); -#endif /* __GNUC__ */ -} - -/** - * @brief Read Data Register - * @rmtoll RXDR . LL_SPI_ReceiveData32 - * @param SPIx SPI Instance - * @retval 0..0xFFFFFFFF - */ -__STATIC_INLINE uint32_t LL_SPI_ReceiveData32(SPI_TypeDef *SPIx) /* Derogation MISRAC2012-Rule-8.13 */ -{ - return (*((__IO uint32_t *)&SPIx->RXDR)); -} - -/** - * @brief Write Data Register - * @rmtoll TXDR . LL_SPI_TransmitData8 - * @param SPIx SPI Instance - * @param TxData 0..0xFF - * @retval None - */ -__STATIC_INLINE void LL_SPI_TransmitData8(SPI_TypeDef *SPIx, uint8_t TxData) -{ - *((__IO uint8_t *)&SPIx->TXDR) = TxData; -} - -/** - * @brief Write Data Register - * @rmtoll TXDR . LL_SPI_TransmitData16 - * @param SPIx SPI Instance - * @param TxData 0..0xFFFF - * @retval None - */ -__STATIC_INLINE void LL_SPI_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData) -{ -#if defined (__GNUC__) - __IO uint16_t *spitxdr = ((__IO uint16_t *)&SPIx->TXDR); - *spitxdr = TxData; -#else - *((__IO uint16_t *)&SPIx->TXDR) = TxData; -#endif /* __GNUC__ */ -} - -/** - * @brief Write Data Register - * @rmtoll TXDR . LL_SPI_TransmitData32 - * @param SPIx SPI Instance - * @param TxData 0..0xFFFFFFFF - * @retval None - */ -__STATIC_INLINE void LL_SPI_TransmitData32(SPI_TypeDef *SPIx, uint32_t TxData) -{ - *((__IO uint32_t *)&SPIx->TXDR) = TxData; -} - -/** - * @brief Set polynomial for CRC calcul - * @rmtoll CRCPOLY CRCPOLY LL_SPI_SetCRCPolynomial - * @param SPIx SPI Instance - * @param CRCPoly 0..0xFFFFFFFF - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetCRCPolynomial(SPI_TypeDef *SPIx, uint32_t CRCPoly) -{ - WRITE_REG(SPIx->CRCPOLY, CRCPoly); -} - -/** - * @brief Get polynomial for CRC calcul - * @rmtoll CRCPOLY CRCPOLY LL_SPI_GetCRCPolynomial - * @param SPIx SPI Instance - * @retval 0..0xFFFFFFFF - */ -__STATIC_INLINE uint32_t LL_SPI_GetCRCPolynomial(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_REG(SPIx->CRCPOLY)); -} - -/** - * @brief Set the underrun pattern - * @rmtoll UDRDR UDRDR LL_SPI_SetUDRPattern - * @param SPIx SPI Instance - * @param Pattern 0..0xFFFFFFFF - * @retval None - */ -__STATIC_INLINE void LL_SPI_SetUDRPattern(SPI_TypeDef *SPIx, uint32_t Pattern) -{ - WRITE_REG(SPIx->UDRDR, Pattern); -} - -/** - * @brief Get the underrun pattern - * @rmtoll UDRDR UDRDR LL_SPI_GetUDRPattern - * @param SPIx SPI Instance - * @retval 0..0xFFFFFFFF - */ -__STATIC_INLINE uint32_t LL_SPI_GetUDRPattern(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_REG(SPIx->UDRDR)); -} - -/** - * @brief Get Rx CRC - * @rmtoll RXCRCR RXCRC LL_SPI_GetRxCRC - * @param SPIx SPI Instance - * @retval 0..0xFFFFFFFF - */ -__STATIC_INLINE uint32_t LL_SPI_GetRxCRC(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_REG(SPIx->RXCRC)); -} - -/** - * @brief Get Tx CRC - * @rmtoll TXCRCR TXCRC LL_SPI_GetTxCRC - * @param SPIx SPI Instance - * @retval 0..0xFFFFFFFF - */ -__STATIC_INLINE uint32_t LL_SPI_GetTxCRC(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_REG(SPIx->TXCRC)); -} - -/** - * @} - */ - -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup SPI_LL_EF_Init Initialization and de-initialization functions - * @{ - */ - -ErrorStatus LL_SPI_DeInit(const SPI_TypeDef *SPIx); -ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct); -void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct); - -/** - * @} - */ -#endif /* USE_FULL_LL_DRIVER */ -/** - * @} - */ -/** - * @} - */ - -/** @defgroup I2S_LL I2S - * @{ - */ - -/* Private variables ---------------------------------------------------------*/ -/* Private constants ---------------------------------------------------------*/ -/* Private macros ------------------------------------------------------------*/ - -/* Exported types ------------------------------------------------------------*/ -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup I2S_LL_ES_INIT I2S Exported Init structure - * @{ - */ - -/** - * @brief I2S Init structure definition - */ - -typedef struct -{ - uint32_t Mode; /*!< Specifies the I2S operating mode. - This parameter can be a value of @ref I2S_LL_EC_MODE - - This feature can be modified afterwards using unitary function - @ref LL_I2S_SetTransferMode().*/ - - uint32_t Standard; /*!< Specifies the standard used for the I2S communication. - This parameter can be a value of @ref I2S_LL_EC_STANDARD - - This feature can be modified afterwards using unitary function - @ref LL_I2S_SetStandard().*/ - - - uint32_t DataFormat; /*!< Specifies the data format for the I2S communication. - This parameter can be a value of @ref I2S_LL_EC_DATA_FORMAT - - This feature can be modified afterwards using unitary function - @ref LL_I2S_SetDataFormat().*/ - - - uint32_t MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not. - This parameter can be a value of @ref I2S_LL_EC_MCLK_OUTPUT - - This feature can be modified afterwards using unitary functions - @ref LL_I2S_EnableMasterClock() or @ref LL_I2S_DisableMasterClock.*/ - - - uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication. - This parameter can be a value of @ref I2S_LL_EC_AUDIO_FREQ - - Audio Frequency can be modified afterwards using Reference manual formulas - to calculate Prescaler Linear, Parity and unitary functions - @ref LL_I2S_SetPrescalerLinear() and @ref LL_I2S_SetPrescalerParity() - to set it.*/ - - - uint32_t ClockPolarity; /*!< Specifies the idle state of the I2S clock. - This parameter can be a value of @ref I2S_LL_EC_POLARITY - - This feature can be modified afterwards using unitary function - @ref LL_I2S_SetClockPolarity().*/ - -} LL_I2S_InitTypeDef; - -/** - * @} - */ -#endif /*USE_FULL_LL_DRIVER*/ - -/* Exported constants --------------------------------------------------------*/ -/** @defgroup I2S_LL_Exported_Constants I2S Exported Constants - * @{ - */ - -/** @defgroup I2S_LL_EC_DATA_FORMAT Data Format - * @{ - */ -#define LL_I2S_DATAFORMAT_16B (0x00000000UL) -#define LL_I2S_DATAFORMAT_16B_EXTENDED (SPI_I2SCFGR_CHLEN) -#define LL_I2S_DATAFORMAT_24B (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_0) -#define LL_I2S_DATAFORMAT_24B_LEFT_ALIGNED (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_0 | SPI_I2SCFGR_DATFMT) -#define LL_I2S_DATAFORMAT_32B (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_1) -/** - * @} - */ - -/** @defgroup I2S_LL_EC_CHANNEL_LENGTH_TYPE Type of Channel Length - * @{ - */ -#define LL_I2S_SLAVE_VARIABLE_CH_LENGTH (0x00000000UL) -#define LL_I2S_SLAVE_FIXED_CH_LENGTH (SPI_I2SCFGR_FIXCH) -/** - * @} - */ - -/** @defgroup I2S_LL_EC_POLARITY Clock Polarity - * @{ - */ -#define LL_I2S_POLARITY_LOW (0x00000000UL) -#define LL_I2S_POLARITY_HIGH (SPI_I2SCFGR_CKPOL) -/** - * @} - */ - -/** @defgroup I2S_LL_EC_STANDARD I2S Standard - * @{ - */ -#define LL_I2S_STANDARD_PHILIPS (0x00000000UL) -#define LL_I2S_STANDARD_MSB (SPI_I2SCFGR_I2SSTD_0) -#define LL_I2S_STANDARD_LSB (SPI_I2SCFGR_I2SSTD_1) -#define LL_I2S_STANDARD_PCM_SHORT (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1) -#define LL_I2S_STANDARD_PCM_LONG (SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1 | SPI_I2SCFGR_PCMSYNC) -/** - * @} - */ - -/** @defgroup I2S_LL_EC_MODE Operation Mode - * @{ - */ -#define LL_I2S_MODE_SLAVE_TX (0x00000000UL) -#define LL_I2S_MODE_SLAVE_RX (SPI_I2SCFGR_I2SCFG_0) -#define LL_I2S_MODE_SLAVE_FULL_DUPLEX (SPI_I2SCFGR_I2SCFG_2) -#define LL_I2S_MODE_MASTER_TX (SPI_I2SCFGR_I2SCFG_1) -#define LL_I2S_MODE_MASTER_RX (SPI_I2SCFGR_I2SCFG_1 | SPI_I2SCFGR_I2SCFG_0) -#define LL_I2S_MODE_MASTER_FULL_DUPLEX (SPI_I2SCFGR_I2SCFG_2 | SPI_I2SCFGR_I2SCFG_0) -/** - * @} - */ - -/** @defgroup I2S_LL_EC_PRESCALER_PARITY Prescaler Factor - * @{ - */ -#define LL_I2S_PRESCALER_PARITY_EVEN (0x00000000UL) /*!< Odd factor: Real divider value is = I2SDIV * 2 */ -#define LL_I2S_PRESCALER_PARITY_ODD (0x00000001UL) /*!< Odd factor: Real divider value is = (I2SDIV * 2)+1 */ -/** - * @} - */ - -/** @defgroup I2S_LL_EC_FIFO_TH FIFO Threshold Level - * @{ - */ -#define LL_I2S_FIFO_TH_01DATA (LL_SPI_FIFO_TH_01DATA) -#define LL_I2S_FIFO_TH_02DATA (LL_SPI_FIFO_TH_02DATA) -#define LL_I2S_FIFO_TH_03DATA (LL_SPI_FIFO_TH_03DATA) -#define LL_I2S_FIFO_TH_04DATA (LL_SPI_FIFO_TH_04DATA) -#define LL_I2S_FIFO_TH_05DATA (LL_SPI_FIFO_TH_05DATA) -#define LL_I2S_FIFO_TH_06DATA (LL_SPI_FIFO_TH_06DATA) -#define LL_I2S_FIFO_TH_07DATA (LL_SPI_FIFO_TH_07DATA) -#define LL_I2S_FIFO_TH_08DATA (LL_SPI_FIFO_TH_08DATA) -/** - * @} - */ - -/** @defgroup I2S_LL_EC_BIT_ORDER Transmission Bit Order - * @{ - */ -#define LL_I2S_LSB_FIRST (LL_SPI_LSB_FIRST) -#define LL_I2S_MSB_FIRST (LL_SPI_MSB_FIRST) -/** - * @} - */ - -#if defined(USE_FULL_LL_DRIVER) - -/** @defgroup I2S_LL_EC_MCLK_OUTPUT MCLK Output - * @{ - */ -#define LL_I2S_MCLK_OUTPUT_DISABLE (0x00000000UL) -#define LL_I2S_MCLK_OUTPUT_ENABLE (SPI_I2SCFGR_MCKOE) -/** - * @} - */ - -/** @defgroup I2S_LL_EC_AUDIO_FREQ Audio Frequency - * @{ - */ - -#define LL_I2S_AUDIOFREQ_192K 192000UL /*!< Audio Frequency configuration 192000 Hz */ -#define LL_I2S_AUDIOFREQ_96K 96000UL /*!< Audio Frequency configuration 96000 Hz */ -#define LL_I2S_AUDIOFREQ_48K 48000UL /*!< Audio Frequency configuration 48000 Hz */ -#define LL_I2S_AUDIOFREQ_44K 44100UL /*!< Audio Frequency configuration 44100 Hz */ -#define LL_I2S_AUDIOFREQ_32K 32000UL /*!< Audio Frequency configuration 32000 Hz */ -#define LL_I2S_AUDIOFREQ_22K 22050UL /*!< Audio Frequency configuration 22050 Hz */ -#define LL_I2S_AUDIOFREQ_16K 16000UL /*!< Audio Frequency configuration 16000 Hz */ -#define LL_I2S_AUDIOFREQ_11K 11025UL /*!< Audio Frequency configuration 11025 Hz */ -#define LL_I2S_AUDIOFREQ_8K 8000UL /*!< Audio Frequency configuration 8000 Hz */ -#define LL_I2S_AUDIOFREQ_DEFAULT 0UL /*!< Audio Freq not specified. Register I2SDIV = 0 */ -/** - * @} - */ -#endif /* USE_FULL_LL_DRIVER */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/** @defgroup I2S_LL_Exported_Macros I2S Exported Macros - * @{ - */ - -/** @defgroup I2S_LL_EM_WRITE_READ Common Write and read registers Macros - * @{ - */ - -/** - * @brief Write a value in I2S register - * @param __INSTANCE__ I2S Instance - * @param __REG__ Register to be written - * @param __VALUE__ Value to be written in the register - * @retval None - */ -#define LL_I2S_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) - -/** - * @brief Read a value in I2S register - * @param __INSTANCE__ I2S Instance - * @param __REG__ Register to be read - * @retval Register value - */ -#define LL_I2S_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) -/** - * @} - */ - -/** - * @} - */ - - -/* Exported functions --------------------------------------------------------*/ - -/** @defgroup I2S_LL_Exported_Functions I2S Exported Functions - * @{ - */ - -/** @defgroup I2S_LL_EF_Configuration Configuration - * @{ - */ - -/** - * @brief Set I2S Data frame format - * @rmtoll I2SCFGR DATLEN LL_I2S_SetDataFormat\n - * I2SCFGR CHLEN LL_I2S_SetDataFormat\n - * I2SCFGR DATFMT LL_I2S_SetDataFormat - * @param SPIx SPI Handle - * @param DataLength This parameter can be one of the following values: - * @arg @ref LL_I2S_DATAFORMAT_16B - * @arg @ref LL_I2S_DATAFORMAT_16B_EXTENDED - * @arg @ref LL_I2S_DATAFORMAT_24B - * @arg @ref LL_I2S_DATAFORMAT_24B_LEFT_ALIGNED - * @arg @ref LL_I2S_DATAFORMAT_32B - * @retval None - */ -__STATIC_INLINE void LL_I2S_SetDataFormat(SPI_TypeDef *SPIx, uint32_t DataLength) -{ - MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATFMT, DataLength); -} - -/** - * @brief Get I2S Data frame format - * @rmtoll I2SCFGR DATLEN LL_I2S_GetDataFormat\n - * I2SCFGR CHLEN LL_I2S_GetDataFormat\n - * I2SCFGR DATFMT LL_I2S_GetDataFormat - * @param SPIx SPI Handle - * @retval Return value can be one of the following values: - * @arg @ref LL_I2S_DATAFORMAT_16B - * @arg @ref LL_I2S_DATAFORMAT_16B_EXTENDED - * @arg @ref LL_I2S_DATAFORMAT_24B - * @arg @ref LL_I2S_DATAFORMAT_24B_LEFT_ALIGNED - * @arg @ref LL_I2S_DATAFORMAT_32B - */ -__STATIC_INLINE uint32_t LL_I2S_GetDataFormat(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATFMT)); -} - -/** - * @brief Set I2S Channel Length Type - * @note This feature is useful with SLAVE only - * @rmtoll I2SCFGR FIXCH LL_I2S_SetChannelLengthType - * @param SPIx SPI Handle - * @param ChannelLengthType This parameter can be one of the following values: - * @arg @ref LL_I2S_SLAVE_VARIABLE_CH_LENGTH - * @arg @ref LL_I2S_SLAVE_FIXED_CH_LENGTH - * @retval None - */ -__STATIC_INLINE void LL_I2S_SetChannelLengthType(SPI_TypeDef *SPIx, uint32_t ChannelLengthType) -{ - MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_FIXCH, ChannelLengthType); -} - -/** - * @brief Get I2S Channel Length Type - * @note This feature is useful with SLAVE only - * @rmtoll I2SCFGR FIXCH LL_I2S_GetChannelLengthType - * @param SPIx SPI Handle - * @retval Return value can be one of the following values: - * @arg @ref LL_I2S_SLAVE_VARIABLE_CH_LENGTH - * @arg @ref LL_I2S_SLAVE_FIXED_CH_LENGTH - */ -__STATIC_INLINE uint32_t LL_I2S_GetChannelLengthType(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_FIXCH)); -} - -/** - * @brief Invert the default polarity of WS signal - * @rmtoll I2SCFGR WSINV LL_I2S_EnableWordSelectInversion - * @param SPIx SPI Handle - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableWordSelectInversion(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_WSINV); -} - -/** - * @brief Use the default polarity of WS signal - * @rmtoll I2SCFGR WSINV LL_I2S_DisableWordSelectInversion - * @param SPIx SPI Handle - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableWordSelectInversion(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_WSINV); -} - -/** - * @brief Check if polarity of WS signal is inverted - * @rmtoll I2SCFGR WSINV LL_I2S_IsEnabledWordSelectInversion - * @param SPIx SPI Handle - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledWordSelectInversion(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_WSINV) == (SPI_I2SCFGR_WSINV)) ? 1UL : 0UL); -} - -/** - * @brief Set 2S Clock Polarity - * @rmtoll I2SCFGR CKPOL LL_I2S_SetClockPolarity - * @param SPIx SPI Handle - * @param ClockPolarity This parameter can be one of the following values: - * @arg @ref LL_I2S_POLARITY_LOW - * @arg @ref LL_I2S_POLARITY_HIGH - * @retval None - */ -__STATIC_INLINE void LL_I2S_SetClockPolarity(SPI_TypeDef *SPIx, uint32_t ClockPolarity) -{ - MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_CKPOL, ClockPolarity); -} - -/** - * @brief Get 2S Clock Polarity - * @rmtoll I2SCFGR CKPOL LL_I2S_GetClockPolarity - * @param SPIx SPI Handle - * @retval Return value can be one of the following values: - * @arg @ref LL_I2S_POLARITY_LOW - * @arg @ref LL_I2S_POLARITY_HIGH - */ -__STATIC_INLINE uint32_t LL_I2S_GetClockPolarity(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_CKPOL)); -} - -/** - * @brief Set I2S standard - * @rmtoll I2SCFGR I2SSTD LL_I2S_SetStandard\n - * I2SCFGR PCMSYNC LL_I2S_SetStandard - * @param SPIx SPI Handle - * @param Standard This parameter can be one of the following values: - * @arg @ref LL_I2S_STANDARD_PHILIPS - * @arg @ref LL_I2S_STANDARD_MSB - * @arg @ref LL_I2S_STANDARD_LSB - * @arg @ref LL_I2S_STANDARD_PCM_SHORT - * @arg @ref LL_I2S_STANDARD_PCM_LONG - * @retval None - */ -__STATIC_INLINE void LL_I2S_SetStandard(SPI_TypeDef *SPIx, uint32_t Standard) -{ - MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC, Standard); -} - -/** - * @brief Get I2S standard - * @rmtoll I2SCFGR I2SSTD LL_I2S_GetStandard\n - * I2SCFGR PCMSYNC LL_I2S_GetStandard - * @param SPIx SPI Handle - * @retval Return value can be one of the following values: - * @arg @ref LL_I2S_STANDARD_PHILIPS - * @arg @ref LL_I2S_STANDARD_MSB - * @arg @ref LL_I2S_STANDARD_LSB - * @arg @ref LL_I2S_STANDARD_PCM_SHORT - * @arg @ref LL_I2S_STANDARD_PCM_LONG - */ -__STATIC_INLINE uint32_t LL_I2S_GetStandard(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC)); -} - -/** - * @brief Set I2S config - * @rmtoll I2SCFGR I2SCFG LL_I2S_SetTransferMode - * @param SPIx SPI Handle - * @param Standard This parameter can be one of the following values: - * @arg @ref LL_I2S_MODE_SLAVE_TX - * @arg @ref LL_I2S_MODE_SLAVE_RX - * @arg @ref LL_I2S_MODE_SLAVE_FULL_DUPLEX - * @arg @ref LL_I2S_MODE_MASTER_TX - * @arg @ref LL_I2S_MODE_MASTER_RX - * @arg @ref LL_I2S_MODE_MASTER_FULL_DUPLEX - * @retval None - */ -__STATIC_INLINE void LL_I2S_SetTransferMode(SPI_TypeDef *SPIx, uint32_t Standard) -{ - MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SCFG, Standard); -} - -/** - * @brief Get I2S config - * @rmtoll I2SCFGR I2SCFG LL_I2S_GetTransferMode - * @param SPIx SPI Handle - * @retval Return value can be one of the following values: - * @arg @ref LL_I2S_MODE_SLAVE_TX - * @arg @ref LL_I2S_MODE_SLAVE_RX - * @arg @ref LL_I2S_MODE_SLAVE_FULL_DUPLEX - * @arg @ref LL_I2S_MODE_MASTER_TX - * @arg @ref LL_I2S_MODE_MASTER_RX - * @arg @ref LL_I2S_MODE_MASTER_FULL_DUPLEX - */ -__STATIC_INLINE uint32_t LL_I2S_GetTransferMode(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SCFG)); -} - -/** - * @brief Select I2S mode and Enable I2S peripheral - * @rmtoll I2SCFGR I2SMOD LL_I2S_Enable\n - * CR1 SPE LL_I2S_Enable - * @param SPIx SPI Handle - * @retval None - */ -__STATIC_INLINE void LL_I2S_Enable(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD); - SET_BIT(SPIx->CR1, SPI_CR1_SPE); -} - -/** - * @brief Disable I2S peripheral and disable I2S mode - * @rmtoll CR1 SPE LL_I2S_Disable\n - * I2SCFGR I2SMOD LL_I2S_Disable - * @param SPIx SPI Handle - * @retval None - */ -__STATIC_INLINE void LL_I2S_Disable(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->CR1, SPI_CR1_SPE); - CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD); -} - -/** - * @brief Swap the SDO and SDI pin - * @note This configuration can not be changed when I2S is enabled. - * @rmtoll CFG2 IOSWP LL_I2S_EnableIOSwap - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableIOSwap(SPI_TypeDef *SPIx) -{ - LL_SPI_EnableIOSwap(SPIx); -} - -/** - * @brief Restore default function for SDO and SDI pin - * @note This configuration can not be changed when I2S is enabled. - * @rmtoll CFG2 IOSWP LL_I2S_DisableIOSwap - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableIOSwap(SPI_TypeDef *SPIx) -{ - LL_SPI_DisableIOSwap(SPIx); -} - -/** - * @brief Check if SDO and SDI pin are swapped - * @rmtoll CFG2 IOSWP LL_I2S_IsEnabledIOSwap - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledIOSwap(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsEnabledIOSwap(SPIx); -} - -/** - * @brief Enable GPIO control - * @note This configuration can not be changed when I2S is enabled. - * @rmtoll CFG2 AFCNTR LL_I2S_EnableGPIOControl - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableGPIOControl(SPI_TypeDef *SPIx) -{ - LL_SPI_EnableGPIOControl(SPIx); -} - -/** - * @brief Disable GPIO control - * @note This configuration can not be changed when I2S is enabled. - * @rmtoll CFG2 AFCNTR LL_I2S_DisableGPIOControl - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableGPIOControl(SPI_TypeDef *SPIx) -{ - LL_SPI_DisableGPIOControl(SPIx); -} - -/** - * @brief Check if GPIO control is active - * @rmtoll CFG2 AFCNTR LL_I2S_IsEnabledGPIOControl - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledGPIOControl(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsEnabledGPIOControl(SPIx); -} - -/** - * @brief Lock the AF configuration of associated IOs - * @note Once this bit is set, the SPI_CFG2 register content can not be modified until a hardware reset occurs. - * The reset of the IOLock bit is done by hardware. for that, LL_SPI_DisableIOLock can not exist. - * @rmtoll CR1 IOLOCK LL_SPI_EnableIOLock - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableIOLock(SPI_TypeDef *SPIx) -{ - LL_SPI_EnableIOLock(SPIx); -} - -/** - * @brief Check if the the SPI_CFG2 register is locked - * @rmtoll CR1 IOLOCK LL_I2S_IsEnabledIOLock - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledIOLock(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsEnabledIOLock(SPIx); -} - -/** - * @brief Set Transfer Bit Order - * @note This configuration can not be changed when I2S is enabled. - * @rmtoll CFG2 LSBFRST LL_I2S_SetTransferBitOrder - * @param SPIx SPI Instance - * @param BitOrder This parameter can be one of the following values: - * @arg @ref LL_I2S_LSB_FIRST - * @arg @ref LL_I2S_MSB_FIRST - * @retval None - */ -__STATIC_INLINE void LL_I2S_SetTransferBitOrder(SPI_TypeDef *SPIx, uint32_t BitOrder) -{ - LL_SPI_SetTransferBitOrder(SPIx, BitOrder); -} -/** - * @brief Get Transfer Bit Order - * @rmtoll CFG2 LSBFRST LL_I2S_GetTransferBitOrder - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_I2S_LSB_FIRST - * @arg @ref LL_I2S_MSB_FIRST - */ -__STATIC_INLINE uint32_t LL_I2S_GetTransferBitOrder(const SPI_TypeDef *SPIx) -{ - return LL_SPI_GetTransferBitOrder(SPIx); -} - -/** - * @brief Start effective transfer on wire - * @rmtoll CR1 CSTART LL_I2S_StartTransfer - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_StartTransfer(SPI_TypeDef *SPIx) -{ - LL_SPI_StartMasterTransfer(SPIx); -} - -/** - * @brief Check if there is an unfinished transfer - * @rmtoll CR1 CSTART LL_I2S_IsActiveTransfer - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsActiveTransfer(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsActiveMasterTransfer(SPIx); -} - -/** - * @brief Set threshold of FIFO that triggers a transfer event - * @note This configuration can not be changed when I2S is enabled. - * @rmtoll CFG1 FTHLV LL_I2S_SetFIFOThreshold - * @param SPIx SPI Instance - * @param Threshold This parameter can be one of the following values: - * @arg @ref LL_I2S_FIFO_TH_01DATA - * @arg @ref LL_I2S_FIFO_TH_02DATA - * @arg @ref LL_I2S_FIFO_TH_03DATA - * @arg @ref LL_I2S_FIFO_TH_04DATA - * @arg @ref LL_I2S_FIFO_TH_05DATA - * @arg @ref LL_I2S_FIFO_TH_06DATA - * @arg @ref LL_I2S_FIFO_TH_07DATA - * @arg @ref LL_I2S_FIFO_TH_08DATA - * @retval None - */ -__STATIC_INLINE void LL_I2S_SetFIFOThreshold(SPI_TypeDef *SPIx, uint32_t Threshold) -{ - LL_SPI_SetFIFOThreshold(SPIx, Threshold); -} - -/** - * @brief Get threshold of FIFO that triggers a transfer event - * @rmtoll CFG1 FTHLV LL_I2S_GetFIFOThreshold - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_I2S_FIFO_TH_01DATA - * @arg @ref LL_I2S_FIFO_TH_02DATA - * @arg @ref LL_I2S_FIFO_TH_03DATA - * @arg @ref LL_I2S_FIFO_TH_04DATA - * @arg @ref LL_I2S_FIFO_TH_05DATA - * @arg @ref LL_I2S_FIFO_TH_06DATA - * @arg @ref LL_I2S_FIFO_TH_07DATA - * @arg @ref LL_I2S_FIFO_TH_08DATA - */ -__STATIC_INLINE uint32_t LL_I2S_GetFIFOThreshold(const SPI_TypeDef *SPIx) -{ - return LL_SPI_GetFIFOThreshold(SPIx); -} - -/** - * @brief Set I2S linear prescaler - * @rmtoll I2SCFGR I2SDIV LL_I2S_SetPrescalerLinear - * @param SPIx SPI Instance - * @param PrescalerLinear Value between Min_Data=0x00 and Max_Data=0xFF - * @note PrescalerLinear '1' is not authorized with parity LL_I2S_PRESCALER_PARITY_ODD - * @retval None - */ -__STATIC_INLINE void LL_I2S_SetPrescalerLinear(SPI_TypeDef *SPIx, uint32_t PrescalerLinear) -{ - MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_I2SDIV, (PrescalerLinear << SPI_I2SCFGR_I2SDIV_Pos)); -} - -/** - * @brief Get I2S linear prescaler - * @rmtoll I2SCFGR I2SDIV LL_I2S_GetPrescalerLinear - * @param SPIx SPI Instance - * @retval PrescalerLinear Value between Min_Data=0x00 and Max_Data=0xFF - */ -__STATIC_INLINE uint32_t LL_I2S_GetPrescalerLinear(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SDIV) >> SPI_I2SCFGR_I2SDIV_Pos); -} - -/** - * @brief Set I2S parity prescaler - * @rmtoll I2SCFGR ODD LL_I2S_SetPrescalerParity - * @param SPIx SPI Instance - * @param PrescalerParity This parameter can be one of the following values: - * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN - * @arg @ref LL_I2S_PRESCALER_PARITY_ODD - * @retval None - */ -__STATIC_INLINE void LL_I2S_SetPrescalerParity(SPI_TypeDef *SPIx, uint32_t PrescalerParity) -{ - MODIFY_REG(SPIx->I2SCFGR, SPI_I2SCFGR_ODD, PrescalerParity << SPI_I2SCFGR_ODD_Pos); -} - -/** - * @brief Get I2S parity prescaler - * @rmtoll I2SCFGR ODD LL_I2S_GetPrescalerParity - * @param SPIx SPI Instance - * @retval Returned value can be one of the following values: - * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN - * @arg @ref LL_I2S_PRESCALER_PARITY_ODD - */ -__STATIC_INLINE uint32_t LL_I2S_GetPrescalerParity(const SPI_TypeDef *SPIx) -{ - return (uint32_t)(READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_ODD) >> SPI_I2SCFGR_ODD_Pos); -} - -/** - * @brief Enable the Master Clock Output (Pin MCK) - * @rmtoll I2SCFGR MCKOE LL_I2S_EnableMasterClock - * @param SPIx SPI Handle - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableMasterClock(SPI_TypeDef *SPIx) -{ - SET_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_MCKOE); -} - -/** - * @brief Disable the Master Clock Output (Pin MCK) - * @rmtoll I2SCFGR MCKOE LL_I2S_DisableMasterClock - * @param SPIx SPI Handle - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableMasterClock(SPI_TypeDef *SPIx) -{ - CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_MCKOE); -} - -/** - * @brief Check if the master clock output (Pin MCK) is enabled - * @rmtoll I2SCFGR MCKOE LL_I2S_IsEnabledMasterClock - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledMasterClock(const SPI_TypeDef *SPIx) -{ - return ((READ_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_MCKOE) == (SPI_I2SCFGR_MCKOE)) ? 1UL : 0UL); -} - -/** - * @} - */ - - -/** @defgroup I2S_LL_EF_FLAG_Management FLAG_Management - * @{ - */ - -/** - * @brief Check if there enough data in FIFO to read a full packet - * @rmtoll SR RXP LL_I2S_IsActiveFlag_RXP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_RXP(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsActiveFlag_RXP(SPIx); -} - -/** - * @brief Check if there enough space in FIFO to hold a full packet - * @rmtoll SR TXP LL_I2S_IsActiveFlag_TXP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_TXP(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsActiveFlag_TXP(SPIx); -} - -/** - * @brief Get Underrun error flag - * @rmtoll SR UDR LL_I2S_IsActiveFlag_UDR - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_UDR(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsActiveFlag_UDR(SPIx); -} - -/** - * @brief Get Overrun error flag - * @rmtoll SR OVR LL_I2S_IsActiveFlag_OVR - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_OVR(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsActiveFlag_OVR(SPIx); -} - -/** - * @brief Get TI Frame format error flag - * @rmtoll SR TIFRE LL_I2S_IsActiveFlag_FRE - * @param SPIx SPI Instance - * @retval State of bit (1 or 0). - */ -__STATIC_INLINE uint32_t LL_I2S_IsActiveFlag_FRE(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsActiveFlag_FRE(SPIx); -} - -/** - * @brief Clear Underrun error flag - * @rmtoll IFCR UDRC LL_I2S_ClearFlag_UDR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_ClearFlag_UDR(SPI_TypeDef *SPIx) -{ - LL_SPI_ClearFlag_UDR(SPIx); -} - -/** - * @brief Clear Overrun error flag - * @rmtoll IFCR OVRC LL_I2S_ClearFlag_OVR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_ClearFlag_OVR(SPI_TypeDef *SPIx) -{ - LL_SPI_ClearFlag_OVR(SPIx); -} - -/** - * @brief Clear Frame format error flag - * @rmtoll IFCR TIFREC LL_I2S_ClearFlag_FRE - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_ClearFlag_FRE(SPI_TypeDef *SPIx) -{ - LL_SPI_ClearFlag_FRE(SPIx); -} - -/** - * @} - */ - -/** @defgroup I2S_LL_EF_IT_Management IT_Management - * @{ - */ - -/** - * @brief Enable Rx Packet available IT - * @rmtoll IER RXPIE LL_I2S_EnableIT_RXP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableIT_RXP(SPI_TypeDef *SPIx) -{ - LL_SPI_EnableIT_RXP(SPIx); -} - -/** - * @brief Enable Tx Packet space available IT - * @rmtoll IER TXPIE LL_I2S_EnableIT_TXP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableIT_TXP(SPI_TypeDef *SPIx) -{ - LL_SPI_EnableIT_TXP(SPIx); -} - -/** - * @brief Enable Underrun IT - * @rmtoll IER UDRIE LL_I2S_EnableIT_UDR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableIT_UDR(SPI_TypeDef *SPIx) -{ - LL_SPI_EnableIT_UDR(SPIx); -} - -/** - * @brief Enable Overrun IT - * @rmtoll IER OVRIE LL_I2S_EnableIT_OVR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableIT_OVR(SPI_TypeDef *SPIx) -{ - LL_SPI_EnableIT_OVR(SPIx); -} - -/** - * @brief Enable TI Frame Format Error IT - * @rmtoll IER TIFREIE LL_I2S_EnableIT_FRE - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableIT_FRE(SPI_TypeDef *SPIx) -{ - LL_SPI_EnableIT_FRE(SPIx); -} - -/** - * @brief Disable Rx Packet available IT - * @rmtoll IER RXPIE LL_I2S_DisableIT_RXP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableIT_RXP(SPI_TypeDef *SPIx) -{ - LL_SPI_DisableIT_RXP(SPIx); -} - -/** - * @brief Disable Tx Packet space available IT - * @rmtoll IER TXPIE LL_I2S_DisableIT_TXP - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableIT_TXP(SPI_TypeDef *SPIx) -{ - LL_SPI_DisableIT_TXP(SPIx); -} - -/** - * @brief Disable Underrun IT - * @rmtoll IER UDRIE LL_I2S_DisableIT_UDR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableIT_UDR(SPI_TypeDef *SPIx) -{ - LL_SPI_DisableIT_UDR(SPIx); -} - -/** - * @brief Disable Overrun IT - * @rmtoll IER OVRIE LL_I2S_DisableIT_OVR - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableIT_OVR(SPI_TypeDef *SPIx) -{ - LL_SPI_DisableIT_OVR(SPIx); -} - -/** - * @brief Disable TI Frame Format Error IT - * @rmtoll IER TIFREIE LL_I2S_DisableIT_FRE - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableIT_FRE(SPI_TypeDef *SPIx) -{ - LL_SPI_DisableIT_FRE(SPIx); -} - -/** - * @brief Check if Rx Packet available IT is enabled - * @rmtoll IER RXPIE LL_I2S_IsEnabledIT_RXP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_RXP(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsEnabledIT_RXP(SPIx); -} - -/** - * @brief Check if Tx Packet space available IT is enabled - * @rmtoll IER TXPIE LL_I2S_IsEnabledIT_TXP - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_TXP(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsEnabledIT_TXP(SPIx); -} - -/** - * @brief Check if Underrun IT is enabled - * @rmtoll IER UDRIE LL_I2S_IsEnabledIT_UDR - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_UDR(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsEnabledIT_UDR(SPIx); -} - -/** - * @brief Check if Overrun IT is enabled - * @rmtoll IER OVRIE LL_I2S_IsEnabledIT_OVR - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_OVR(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsEnabledIT_OVR(SPIx); -} - -/** - * @brief Check if TI Frame Format Error IT is enabled - * @rmtoll IER TIFREIE LL_I2S_IsEnabledIT_FRE - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledIT_FRE(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsEnabledIT_FRE(SPIx); -} - -/** - * @} - */ - -/** @defgroup I2S_LL_EF_DMA_Management DMA_Management - * @{ - */ - -/** - * @brief Enable DMA Rx - * @rmtoll CFG1 RXDMAEN LL_I2S_EnableDMAReq_RX - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableDMAReq_RX(SPI_TypeDef *SPIx) -{ - LL_SPI_EnableDMAReq_RX(SPIx); -} - -/** - * @brief Disable DMA Rx - * @rmtoll CFG1 RXDMAEN LL_I2S_DisableDMAReq_RX - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableDMAReq_RX(SPI_TypeDef *SPIx) -{ - LL_SPI_DisableDMAReq_RX(SPIx); -} - -/** - * @brief Check if DMA Rx is enabled - * @rmtoll CFG1 RXDMAEN LL_I2S_IsEnabledDMAReq_RX - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledDMAReq_RX(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsEnabledDMAReq_RX(SPIx); -} - -/** - * @brief Enable DMA Tx - * @rmtoll CFG1 TXDMAEN LL_I2S_EnableDMAReq_TX - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_EnableDMAReq_TX(SPI_TypeDef *SPIx) -{ - LL_SPI_EnableDMAReq_TX(SPIx); -} - -/** - * @brief Disable DMA Tx - * @rmtoll CFG1 TXDMAEN LL_I2S_DisableDMAReq_TX - * @param SPIx SPI Instance - * @retval None - */ -__STATIC_INLINE void LL_I2S_DisableDMAReq_TX(SPI_TypeDef *SPIx) -{ - LL_SPI_DisableDMAReq_TX(SPIx); -} - -/** - * @brief Check if DMA Tx is enabled - * @rmtoll CFG1 TXDMAEN LL_I2S_IsEnabledDMAReq_TX - * @param SPIx SPI Instance - * @retval State of bit (1 or 0) - */ -__STATIC_INLINE uint32_t LL_I2S_IsEnabledDMAReq_TX(const SPI_TypeDef *SPIx) -{ - return LL_SPI_IsEnabledDMAReq_TX(SPIx); -} - -/** - * @} - */ - -/** @defgroup I2S_LL_EF_DATA_Management DATA_Management - * @{ - */ - -/** - * @brief Read Data Register - * @rmtoll RXDR . LL_I2S_ReceiveData16 - * @param SPIx SPI Instance - * @retval 0..0xFFFF - */ -__STATIC_INLINE uint16_t LL_I2S_ReceiveData16(SPI_TypeDef *SPIx) /* Derogation MISRAC2012-Rule-8.13 */ -{ - return LL_SPI_ReceiveData16(SPIx); -} - -/** - * @brief Read Data Register - * @rmtoll RXDR . LL_I2S_ReceiveData32 - * @param SPIx SPI Instance - * @retval 0..0xFFFFFFFF - */ -__STATIC_INLINE uint32_t LL_I2S_ReceiveData32(SPI_TypeDef *SPIx) /* Derogation MISRAC2012-Rule-8.13 */ -{ - return LL_SPI_ReceiveData32(SPIx); -} - -/** - * @brief Write Data Register - * @rmtoll TXDR . LL_I2S_TransmitData16 - * @param SPIx SPI Instance - * @param TxData 0..0xFFFF - * @retval None - */ -__STATIC_INLINE void LL_I2S_TransmitData16(SPI_TypeDef *SPIx, uint16_t TxData) -{ - LL_SPI_TransmitData16(SPIx, TxData); -} - -/** - * @brief Write Data Register - * @rmtoll TXDR . LL_I2S_TransmitData32 - * @param SPIx SPI Instance - * @param TxData 0..0xFFFFFFFF - * @retval None - */ -__STATIC_INLINE void LL_I2S_TransmitData32(SPI_TypeDef *SPIx, uint32_t TxData) -{ - LL_SPI_TransmitData32(SPIx, TxData); -} - - -/** - * @} - */ - - -#if defined(USE_FULL_LL_DRIVER) -/** @defgroup I2S_LL_EF_Init Initialization and de-initialization functions - * @{ - */ - -ErrorStatus LL_I2S_DeInit(const SPI_TypeDef *SPIx); -ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, const LL_I2S_InitTypeDef *I2S_InitStruct); -void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct); -void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, uint32_t PrescalerParity); - -/** - * @} - */ -#endif /* USE_FULL_LL_DRIVER */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /* defined(SPI1) || defined(SPI2) || defined(SPI3) || defined(SPI4) || defined(SPI5) || defined(SPI6) */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* STM32H7xx_LL_SPI_H */ diff --git a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usb.h b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usb.h new file mode 100644 index 0000000..9cfe6a1 --- /dev/null +++ b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_ll_usb.h @@ -0,0 +1,578 @@ +/** + ****************************************************************************** + * @file stm32h7xx_ll_usb.h + * @author MCD Application Team + * @brief Header file of USB Low Layer HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32H7xx_LL_USB_H +#define STM32H7xx_LL_USB_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx_hal_def.h" + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +/** @addtogroup STM32H7xx_HAL_Driver + * @{ + */ + +/** @addtogroup USB_LL + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +#ifndef HAL_USB_TIMEOUT +#define HAL_USB_TIMEOUT 0xF000000U +#endif /* define HAL_USB_TIMEOUT */ + +#ifndef HAL_USB_CURRENT_MODE_MAX_DELAY_MS +#define HAL_USB_CURRENT_MODE_MAX_DELAY_MS 200U +#endif /* define HAL_USB_CURRENT_MODE_MAX_DELAY_MS */ + +/** + * @brief USB Mode definition + */ + +typedef enum +{ + USB_DEVICE_MODE = 0, + USB_HOST_MODE = 1, + USB_DRD_MODE = 2 +} USB_ModeTypeDef; + +/** + * @brief URB States definition + */ +typedef enum +{ + URB_IDLE = 0, + URB_DONE, + URB_NOTREADY, + URB_NYET, + URB_ERROR, + URB_STALL +} USB_URBStateTypeDef; + +/** + * @brief Host channel States definition + */ +typedef enum +{ + HC_IDLE = 0, + HC_XFRC, + HC_HALTED, + HC_ACK, + HC_NAK, + HC_NYET, + HC_STALL, + HC_XACTERR, + HC_BBLERR, + HC_DATATGLERR +} USB_HCStateTypeDef; + + +/** + * @brief USB Instance Initialization Structure definition + */ +typedef struct +{ + uint8_t dev_endpoints; /*!< Device Endpoints number. + This parameter depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t Host_channels; /*!< Host Channels number. + This parameter Depends on the used USB core. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t dma_enable; /*!< USB DMA state. + If DMA is not supported this parameter shall be set by default to zero */ + + uint8_t speed; /*!< USB Core speed. + This parameter can be any value of @ref PCD_Speed/HCD_Speed + (HCD_SPEED_xxx, HCD_SPEED_xxx) */ + + uint8_t ep0_mps; /*!< Set the Endpoint 0 Max Packet size. */ + + uint8_t phy_itface; /*!< Select the used PHY interface. + This parameter can be any value of @ref PCD_PHY_Module/HCD_PHY_Module */ + + uint8_t Sof_enable; /*!< Enable or disable the output of the SOF signal. */ + + uint8_t low_power_enable; /*!< Enable or disable the low Power Mode. */ + + uint8_t lpm_enable; /*!< Enable or disable Link Power Management. */ + + uint8_t battery_charging_enable; /*!< Enable or disable Battery charging. */ + + uint8_t vbus_sensing_enable; /*!< Enable or disable the VBUS Sensing feature. */ + + uint8_t use_dedicated_ep1; /*!< Enable or disable the use of the dedicated EP1 interrupt. */ + + uint8_t use_external_vbus; /*!< Enable or disable the use of the external VBUS. */ + +} USB_CfgTypeDef; + +typedef struct +{ + uint8_t num; /*!< Endpoint number + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t is_in; /*!< Endpoint direction + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t is_stall; /*!< Endpoint stall condition + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t is_iso_incomplete; /*!< Endpoint isoc condition + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t type; /*!< Endpoint type + This parameter can be any value of @ref USB_LL_EP_Type */ + + uint8_t data_pid_start; /*!< Initial data PID + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint32_t maxpacket; /*!< Endpoint Max packet size + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint8_t *xfer_buff; /*!< Pointer to transfer buffer */ + + uint32_t xfer_len; /*!< Current transfer length */ + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer */ + + uint8_t even_odd_frame; /*!< IFrame parity + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint16_t tx_fifo_num; /*!< Transmission FIFO number + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address */ + + uint32_t xfer_size; /*!< requested transfer size */ +} USB_EPTypeDef; + +typedef struct +{ + uint8_t dev_addr; /*!< USB device address. + This parameter must be a number between Min_Data = 1 and Max_Data = 255 */ + + uint8_t ch_num; /*!< Host channel number. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t ep_num; /*!< Endpoint number. + This parameter must be a number between Min_Data = 1 and Max_Data = 15 */ + + uint8_t ep_is_in; /*!< Endpoint direction + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t speed; /*!< USB Host Channel speed. + This parameter can be any value of @ref HCD_Device_Speed: + (HCD_DEVICE_SPEED_xxx) */ + + uint8_t do_ping; /*!< Enable or disable the use of the PING protocol for HS mode. */ + uint8_t do_ssplit; /*!< Enable start split transaction in HS mode. */ + uint8_t do_csplit; /*!< Enable complete split transaction in HS mode. */ + uint8_t ep_ss_schedule; /*!< Enable periodic endpoint start split schedule . */ + uint32_t iso_splt_xactPos; /*!< iso split transfer transaction position. */ + + uint8_t hub_port_nbr; /*!< USB HUB port number */ + uint8_t hub_addr; /*!< USB HUB address */ + + uint8_t ep_type; /*!< Endpoint Type. + This parameter can be any value of @ref USB_LL_EP_Type */ + + uint16_t max_packet; /*!< Endpoint Max packet size. + This parameter must be a number between Min_Data = 0 and Max_Data = 64KB */ + + uint8_t data_pid; /*!< Initial data PID. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t *xfer_buff; /*!< Pointer to transfer buffer. */ + + uint32_t XferSize; /*!< OTG Channel transfer size. */ + + uint32_t xfer_len; /*!< Current transfer length. */ + + uint32_t xfer_count; /*!< Partial transfer length in case of multi packet transfer. */ + + uint8_t toggle_in; /*!< IN transfer current toggle flag. + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint8_t toggle_out; /*!< OUT transfer current toggle flag + This parameter must be a number between Min_Data = 0 and Max_Data = 1 */ + + uint32_t dma_addr; /*!< 32 bits aligned transfer buffer address. */ + + uint32_t ErrCnt; /*!< Host channel error count. */ + uint32_t NyetErrCnt; /*!< Complete Split NYET Host channel error count. */ + + USB_URBStateTypeDef urb_state; /*!< URB state. + This parameter can be any value of @ref USB_URBStateTypeDef */ + + USB_HCStateTypeDef state; /*!< Host Channel state. + This parameter can be any value of @ref USB_HCStateTypeDef */ +} USB_HCTypeDef; + +typedef USB_ModeTypeDef USB_OTG_ModeTypeDef; +typedef USB_CfgTypeDef USB_OTG_CfgTypeDef; +typedef USB_EPTypeDef USB_OTG_EPTypeDef; +typedef USB_URBStateTypeDef USB_OTG_URBStateTypeDef; +typedef USB_HCStateTypeDef USB_OTG_HCStateTypeDef; +typedef USB_HCTypeDef USB_OTG_HCTypeDef; + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup PCD_Exported_Constants PCD Exported Constants + * @{ + */ + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +/** @defgroup USB_OTG_CORE VERSION ID + * @{ + */ +#define USB_OTG_CORE_ID_300A 0x4F54300AU +#define USB_OTG_CORE_ID_310A 0x4F54310AU +/** + * @} + */ + +/** @defgroup USB_Core_Mode_ USB Core Mode + * @{ + */ +#define USB_OTG_MODE_DEVICE 0U +#define USB_OTG_MODE_HOST 1U +#define USB_OTG_MODE_DRD 2U +/** + * @} + */ + +/** @defgroup USB_LL_Core_Speed USB Low Layer Core Speed + * @{ + */ +#define USB_OTG_SPEED_HIGH 0U +#define USB_OTG_SPEED_HIGH_IN_FULL 1U +#define USB_OTG_SPEED_FULL 3U +/** + * @} + */ + +/** @defgroup USB_LL_Core_PHY USB Low Layer Core PHY + * @{ + */ +#define USB_OTG_ULPI_PHY 1U +#define USB_OTG_EMBEDDED_PHY 2U +/** + * @} + */ + +/** @defgroup USB_LL_Turnaround_Timeout Turnaround Timeout Value + * @{ + */ +#ifndef USBD_HS_TRDT_VALUE +#define USBD_HS_TRDT_VALUE 9U +#endif /* USBD_HS_TRDT_VALUE */ +#ifndef USBD_FS_TRDT_VALUE +#define USBD_FS_TRDT_VALUE 5U +#define USBD_DEFAULT_TRDT_VALUE 9U +#endif /* USBD_HS_TRDT_VALUE */ +/** + * @} + */ + +/** @defgroup USB_LL_Core_MPS USB Low Layer Core MPS + * @{ + */ +#define USB_OTG_HS_MAX_PACKET_SIZE 512U +#define USB_OTG_FS_MAX_PACKET_SIZE 64U +#define USB_OTG_MAX_EP0_SIZE 64U +/** + * @} + */ + +/** @defgroup USB_LL_Core_PHY_Frequency USB Low Layer Core PHY Frequency + * @{ + */ +#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ (0U << 1) +#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ (1U << 1) +#define DSTS_ENUMSPD_FS_PHY_48MHZ (3U << 1) +/** + * @} + */ + +/** @defgroup USB_LL_CORE_Frame_Interval USB Low Layer Core Frame Interval + * @{ + */ +#define DCFG_FRAME_INTERVAL_80 0U +#define DCFG_FRAME_INTERVAL_85 1U +#define DCFG_FRAME_INTERVAL_90 2U +#define DCFG_FRAME_INTERVAL_95 3U +/** + * @} + */ +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ +/** @defgroup USB_LL_EP0_MPS USB Low Layer EP0 MPS + * @{ + */ +#define EP_MPS_64 0U +#define EP_MPS_32 1U +#define EP_MPS_16 2U +#define EP_MPS_8 3U +/** + * @} + */ + +/** @defgroup USB_LL_EP_Type USB Low Layer EP Type + * @{ + */ +#define EP_TYPE_CTRL 0U +#define EP_TYPE_ISOC 1U +#define EP_TYPE_BULK 2U +#define EP_TYPE_INTR 3U +#define EP_TYPE_MSK 3U +/** + * @} + */ + +/** @defgroup USB_LL_EP_Speed USB Low Layer EP Speed + * @{ + */ +#define EP_SPEED_LOW 0U +#define EP_SPEED_FULL 1U +#define EP_SPEED_HIGH 2U +/** + * @} + */ + +/** @defgroup USB_LL_CH_PID_Type USB Low Layer Channel PID Type + * @{ + */ +#define HC_PID_DATA0 0U +#define HC_PID_DATA2 1U +#define HC_PID_DATA1 2U +#define HC_PID_SETUP 3U +/** + * @} + */ + +/** @defgroup USB_LL Device Speed + * @{ + */ +#define USBD_HS_SPEED 0U +#define USBD_HSINFS_SPEED 1U +#define USBH_HS_SPEED 0U +#define USBD_FS_SPEED 2U +#define USBH_FSLS_SPEED 1U +/** + * @} + */ + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +/** @defgroup USB_LL_STS_Defines USB Low Layer STS Defines + * @{ + */ +#define STS_GOUT_NAK 1U +#define STS_DATA_UPDT 2U +#define STS_XFER_COMP 3U +#define STS_SETUP_COMP 4U +#define STS_SETUP_UPDT 6U +/** + * @} + */ + +/** @defgroup USB_LL_HCFG_SPEED_Defines USB Low Layer HCFG Speed Defines + * @{ + */ +#define HCFG_30_60_MHZ 0U +#define HCFG_48_MHZ 1U +#define HCFG_6_MHZ 2U +/** + * @} + */ + +/** @defgroup USB_LL_HFIR_Defines USB Low Layer frame interval Defines + * @{ + */ +#define HFIR_6_MHZ 6000U +#define HFIR_60_MHZ 60000U +#define HFIR_48_MHZ 48000U +/** + * @} + */ + +/** @defgroup USB_LL_HPRT0_PRTSPD_SPEED_Defines USB Low Layer HPRT0 PRTSPD Speed Defines + * @{ + */ +#define HPRT0_PRTSPD_HIGH_SPEED 0U +#define HPRT0_PRTSPD_FULL_SPEED 1U +#define HPRT0_PRTSPD_LOW_SPEED 2U +/** + * @} + */ + +#define HCCHAR_CTRL 0U +#define HCCHAR_ISOC 1U +#define HCCHAR_BULK 2U +#define HCCHAR_INTR 3U + +#define GRXSTS_PKTSTS_IN 2U +#define GRXSTS_PKTSTS_IN_XFER_COMP 3U +#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5U +#define GRXSTS_PKTSTS_CH_HALTED 7U + +#define CLEAR_INTERRUPT_MASK 0xFFFFFFFFU + +#define HC_MAX_PKT_CNT 256U +#define ISO_SPLT_MPS 188U + +#define HCSPLT_BEGIN 1U +#define HCSPLT_MIDDLE 2U +#define HCSPLT_END 3U +#define HCSPLT_FULL 4U + +#define TEST_J 1U +#define TEST_K 2U +#define TEST_SE0_NAK 3U +#define TEST_PACKET 4U +#define TEST_FORCE_EN 5U + +#define USBx_PCGCCTL *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_PCGCCTL_BASE) +#define USBx_HPRT0 *(__IO uint32_t *)((uint32_t)USBx_BASE + USB_OTG_HOST_PORT_BASE) + +#define USBx_DEVICE ((USB_OTG_DeviceTypeDef *)(USBx_BASE + USB_OTG_DEVICE_BASE)) +#define USBx_INEP(i) ((USB_OTG_INEndpointTypeDef *)(USBx_BASE\ + + USB_OTG_IN_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE))) + +#define USBx_OUTEP(i) ((USB_OTG_OUTEndpointTypeDef *)(USBx_BASE\ + + USB_OTG_OUT_ENDPOINT_BASE + ((i) * USB_OTG_EP_REG_SIZE))) + +#define USBx_DFIFO(i) *(__IO uint32_t *)(USBx_BASE + USB_OTG_FIFO_BASE + ((i) * USB_OTG_FIFO_SIZE)) + +#define USBx_HOST ((USB_OTG_HostTypeDef *)(USBx_BASE + USB_OTG_HOST_BASE)) +#define USBx_HC(i) ((USB_OTG_HostChannelTypeDef *)(USBx_BASE\ + + USB_OTG_HOST_CHANNEL_BASE\ + + ((i) * USB_OTG_HOST_CHANNEL_SIZE))) + + +#define EP_ADDR_MSK 0xFU +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup USB_LL_Exported_Macros USB Low Layer Exported Macros + * @{ + */ +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +#define USB_MASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK &= ~(__INTERRUPT__)) +#define USB_UNMASK_INTERRUPT(__INSTANCE__, __INTERRUPT__) ((__INSTANCE__)->GINTMSK |= (__INTERRUPT__)) + +#define CLEAR_IN_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_INEP(__EPNUM__)->DIEPINT = (__INTERRUPT__)) +#define CLEAR_OUT_EP_INTR(__EPNUM__, __INTERRUPT__) (USBx_OUTEP(__EPNUM__)->DOEPINT = (__INTERRUPT__)) +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup USB_LL_Exported_Functions USB Low Layer Exported Functions + * @{ + */ +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg); +HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg); +HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx, uint32_t hclk, uint8_t speed); +HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode); +HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed); +HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num); +HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma); +HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src, + uint8_t ch_ep_num, uint16_t len, uint8_t dma); + +void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len); +HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep); +HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address); +HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, uint8_t dma, const uint8_t *psetup); +uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx); +uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx); +uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx); +uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum); +uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx); +uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum); +uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx); +uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum); +void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt); + +HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg); +HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq); +HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state); +uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx); +uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx); +HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num, + uint8_t epnum, uint8_t dev_address, uint8_t speed, + uint8_t ep_type, uint16_t mps); +HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, + USB_OTG_HCTypeDef *hc, uint8_t dma); + +uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num); +HAL_StatusTypeDef USB_DoPing(const USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num); +HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx); +HAL_StatusTypeDef USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx); +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* STM32H7xx_LL_USB_H */ diff --git a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c new file mode 100644 index 0000000..a50cac2 --- /dev/null +++ b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c @@ -0,0 +1,2346 @@ +/** + ****************************************************************************** + * @file stm32h7xx_hal_pcd.c + * @author MCD Application Team + * @brief PCD HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The PCD HAL driver can be used as follows: + + (#) Declare a PCD_HandleTypeDef handle structure, for example: + PCD_HandleTypeDef hpcd; + + (#) Fill parameters of Init structure in HCD handle + + (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...) + + (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API: + (##) Enable the PCD/USB Low Level interface clock using + (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + (+++) __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); (For High Speed Mode) + + (##) Initialize the related GPIO clocks + (##) Configure PCD pin-out + (##) Configure PCD NVIC interrupt + + (#)Associate the Upper USB device stack to the HAL PCD Driver: + (##) hpcd.pData = pdev; + + (#)Enable PCD transmission and reception: + (##) HAL_PCD_Start(); + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx_hal.h" + +/** @addtogroup STM32H7xx_HAL_Driver + * @{ + */ + +/** @defgroup PCD PCD + * @brief PCD HAL module driver + * @{ + */ + +#ifdef HAL_PCD_MODULE_ENABLED + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/** @defgroup PCD_Private_Macros PCD Private Macros + * @{ + */ +#define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b)) +/** + * @} + */ + +/* Private functions prototypes ----------------------------------------------*/ +/** @defgroup PCD_Private_Functions PCD Private Functions + * @{ + */ +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum); +static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum); +static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum); +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup PCD_Exported_Functions PCD Exported Functions + * @{ + */ + +/** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the PCD according to the specified + * parameters in the PCD_InitTypeDef and initialize the associated handle. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd) +{ + uint8_t i; + + /* Check the PCD handle allocation */ + if (hpcd == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance)); + + if (hpcd->State == HAL_PCD_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hpcd->Lock = HAL_UNLOCKED; + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SOFCallback = HAL_PCD_SOFCallback; + hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback; + hpcd->ResetCallback = HAL_PCD_ResetCallback; + hpcd->SuspendCallback = HAL_PCD_SuspendCallback; + hpcd->ResumeCallback = HAL_PCD_ResumeCallback; + hpcd->ConnectCallback = HAL_PCD_ConnectCallback; + hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback; + hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; + hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; + hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; + hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; + hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; + hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; + + if (hpcd->MspInitCallback == NULL) + { + hpcd->MspInitCallback = HAL_PCD_MspInit; + } + + /* Init the low level hardware */ + hpcd->MspInitCallback(hpcd); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC... */ + HAL_PCD_MspInit(hpcd); +#endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */ + } + + hpcd->State = HAL_PCD_STATE_BUSY; + + /* Disable the Interrupts */ + __HAL_PCD_DISABLE(hpcd); + + /*Init the Core (common init.) */ + if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK) + { + hpcd->State = HAL_PCD_STATE_ERROR; + return HAL_ERROR; + } + + /* Force Device Mode */ + if (USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE) != HAL_OK) + { + hpcd->State = HAL_PCD_STATE_ERROR; + return HAL_ERROR; + } + + /* Init endpoints structures */ + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + { + /* Init ep structure */ + hpcd->IN_ep[i].is_in = 1U; + hpcd->IN_ep[i].num = i; + hpcd->IN_ep[i].tx_fifo_num = i; + /* Control until ep is activated */ + hpcd->IN_ep[i].type = EP_TYPE_CTRL; + hpcd->IN_ep[i].maxpacket = 0U; + hpcd->IN_ep[i].xfer_buff = 0U; + hpcd->IN_ep[i].xfer_len = 0U; + } + + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + { + hpcd->OUT_ep[i].is_in = 0U; + hpcd->OUT_ep[i].num = i; + /* Control until ep is activated */ + hpcd->OUT_ep[i].type = EP_TYPE_CTRL; + hpcd->OUT_ep[i].maxpacket = 0U; + hpcd->OUT_ep[i].xfer_buff = 0U; + hpcd->OUT_ep[i].xfer_len = 0U; + } + + /* Init Device */ + if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK) + { + hpcd->State = HAL_PCD_STATE_ERROR; + return HAL_ERROR; + } + + hpcd->USB_Address = 0U; + hpcd->State = HAL_PCD_STATE_READY; + + /* Activate LPM */ + if (hpcd->Init.lpm_enable == 1U) + { + (void)HAL_PCDEx_ActivateLPM(hpcd); + } + + (void)USB_DevDisconnect(hpcd->Instance); + + return HAL_OK; +} + +/** + * @brief DeInitializes the PCD peripheral. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd) +{ + /* Check the PCD handle allocation */ + if (hpcd == NULL) + { + return HAL_ERROR; + } + + hpcd->State = HAL_PCD_STATE_BUSY; + + /* Stop Device */ + if (USB_StopDevice(hpcd->Instance) != HAL_OK) + { + return HAL_ERROR; + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + if (hpcd->MspDeInitCallback == NULL) + { + hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware */ + hpcd->MspDeInitCallback(hpcd); +#else + /* DeInit the low level hardware: CLOCK, NVIC.*/ + HAL_PCD_MspDeInit(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + hpcd->State = HAL_PCD_STATE_RESET; + + return HAL_OK; +} + +/** + * @brief Initializes the PCD MSP. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes PCD MSP. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_MspDeInit could be implemented in the user file + */ +} + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +/** + * @brief Register a User USB PCD Callback + * To be used instead of the weak predefined callback + * @param hpcd USB PCD handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID + * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID + * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID + * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID + * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID + * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID + * @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID + * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID + * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd, + HAL_PCD_CallbackIDTypeDef CallbackID, + pPCD_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + return HAL_ERROR; + } + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + switch (CallbackID) + { + case HAL_PCD_SOF_CB_ID : + hpcd->SOFCallback = pCallback; + break; + + case HAL_PCD_SETUPSTAGE_CB_ID : + hpcd->SetupStageCallback = pCallback; + break; + + case HAL_PCD_RESET_CB_ID : + hpcd->ResetCallback = pCallback; + break; + + case HAL_PCD_SUSPEND_CB_ID : + hpcd->SuspendCallback = pCallback; + break; + + case HAL_PCD_RESUME_CB_ID : + hpcd->ResumeCallback = pCallback; + break; + + case HAL_PCD_CONNECT_CB_ID : + hpcd->ConnectCallback = pCallback; + break; + + case HAL_PCD_DISCONNECT_CB_ID : + hpcd->DisconnectCallback = pCallback; + break; + + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = pCallback; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hpcd->State == HAL_PCD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = pCallback; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + return status; +} + +/** + * @brief Unregister an USB PCD Callback + * USB PCD callback is redirected to the weak predefined callback + * @param hpcd USB PCD handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID + * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID + * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID + * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID + * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID + * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID + * @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID + * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID + * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + /* Setup Legacy weak Callbacks */ + if (hpcd->State == HAL_PCD_STATE_READY) + { + switch (CallbackID) + { + case HAL_PCD_SOF_CB_ID : + hpcd->SOFCallback = HAL_PCD_SOFCallback; + break; + + case HAL_PCD_SETUPSTAGE_CB_ID : + hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback; + break; + + case HAL_PCD_RESET_CB_ID : + hpcd->ResetCallback = HAL_PCD_ResetCallback; + break; + + case HAL_PCD_SUSPEND_CB_ID : + hpcd->SuspendCallback = HAL_PCD_SuspendCallback; + break; + + case HAL_PCD_RESUME_CB_ID : + hpcd->ResumeCallback = HAL_PCD_ResumeCallback; + break; + + case HAL_PCD_CONNECT_CB_ID : + hpcd->ConnectCallback = HAL_PCD_ConnectCallback; + break; + + case HAL_PCD_DISCONNECT_CB_ID : + hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback; + break; + + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = HAL_PCD_MspInit; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (hpcd->State == HAL_PCD_STATE_RESET) + { + switch (CallbackID) + { + case HAL_PCD_MSPINIT_CB_ID : + hpcd->MspInitCallback = HAL_PCD_MspInit; + break; + + case HAL_PCD_MSPDEINIT_CB_ID : + hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; + break; + + default : + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + return status; +} + +/** + * @brief Register USB PCD Data OUT Stage Callback + * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Data OUT Stage Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd, + pPCD_DataOutStageCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataOutStageCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD Data OUT Stage Callback + * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD Data IN Stage Callback + * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Data IN Stage Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd, + pPCD_DataInStageCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataInStageCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD Data IN Stage Callback + * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD Iso OUT incomplete Callback + * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd, + pPCD_IsoOutIncpltCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOOUTIncompleteCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD Iso OUT incomplete Callback + * USB PCD Iso OUT incomplete Callback is redirected + * to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD Iso IN incomplete Callback + * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd, + pPCD_IsoInIncpltCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOINIncompleteCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD Iso IN incomplete Callback + * USB PCD Iso IN incomplete Callback is redirected + * to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD BCD Callback + * To be used instead of the weak HAL_PCDEx_BCD_Callback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD BCD Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterBcdCallback(PCD_HandleTypeDef *hpcd, pPCD_BcdCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->BCDCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD BCD Callback + * USB BCD Callback is redirected to the weak HAL_PCDEx_BCD_Callback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterBcdCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->BCDCallback = HAL_PCDEx_BCD_Callback; /* Legacy weak HAL_PCDEx_BCD_Callback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Register USB PCD LPM Callback + * To be used instead of the weak HAL_PCDEx_LPM_Callback() predefined callback + * @param hpcd PCD handle + * @param pCallback pointer to the USB PCD LPM Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_RegisterLpmCallback(PCD_HandleTypeDef *hpcd, pPCD_LpmCallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->LPMCallback = pCallback; + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} + +/** + * @brief Unregister the USB PCD LPM Callback + * USB LPM Callback is redirected to the weak HAL_PCDEx_LPM_Callback() predefined callback + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_UnRegisterLpmCallback(PCD_HandleTypeDef *hpcd) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Process locked */ + __HAL_LOCK(hpcd); + + if (hpcd->State == HAL_PCD_STATE_READY) + { + hpcd->LPMCallback = HAL_PCDEx_LPM_Callback; /* Legacy weak HAL_PCDEx_LPM_Callback */ + } + else + { + /* Update the error code */ + hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + /* Release Lock */ + __HAL_UNLOCK(hpcd); + + return status; +} +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Start the USB device + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + __HAL_LOCK(hpcd); + + if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) && + (hpcd->Init.battery_charging_enable == 1U)) + { + /* Enable USB Transceiver */ + USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN; + } + + __HAL_PCD_ENABLE(hpcd); + (void)USB_DevConnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Stop the USB device. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + __HAL_LOCK(hpcd); + __HAL_PCD_DISABLE(hpcd); + (void)USB_DevDisconnect(hpcd->Instance); + + (void)USB_FlushTxFifo(hpcd->Instance, 0x10U); + + if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) && + (hpcd->Init.battery_charging_enable == 1U)) + { + /* Disable USB Transceiver */ + USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); + } + + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +/** + * @brief Handles PCD interrupt request. + * @param hpcd PCD handle + * @retval HAL status + */ +void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + uint32_t USBx_BASE = (uint32_t)USBx; + USB_OTG_EPTypeDef *ep; + uint32_t i; + uint32_t ep_intr; + uint32_t epint; + uint32_t epnum; + uint32_t fifoemptymsk; + uint32_t RegVal; + + /* ensure that we are in device mode */ + if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE) + { + /* avoid spurious interrupt */ + if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) + { + return; + } + + /* store current frame number */ + hpcd->FrameNumber = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF_Msk) >> USB_OTG_DSTS_FNSOF_Pos; + + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS)) + { + /* incorrect mode, acknowledge the interrupt */ + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS); + } + + /* Handle RxQLevel Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL)) + { + USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); + + RegVal = USBx->GRXSTSP; + + ep = &hpcd->OUT_ep[RegVal & USB_OTG_GRXSTSP_EPNUM]; + + if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT) + { + if ((RegVal & USB_OTG_GRXSTSP_BCNT) != 0U) + { + (void)USB_ReadPacket(USBx, ep->xfer_buff, + (uint16_t)((RegVal & USB_OTG_GRXSTSP_BCNT) >> 4)); + + ep->xfer_buff += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4; + ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4; + } + } + else if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT) + { + (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U); + ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4; + } + else + { + /* ... */ + } + + USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL); + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT)) + { + epnum = 0U; + + /* Read in the device interrupt bits */ + ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance); + + while (ep_intr != 0U) + { + if ((ep_intr & 0x1U) != 0U) + { + epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum); + + if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC); + (void)PCD_EP_OutXfrComplete_int(hpcd, epnum); + } + + if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP); + /* Class B setup phase done for previous decoded setup */ + (void)PCD_EP_OutSetupPacket_int(hpcd, epnum); + } + + if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS); + } + + /* Clear OUT Endpoint disable interrupt */ + if ((epint & USB_OTG_DOEPINT_EPDISD) == USB_OTG_DOEPINT_EPDISD) + { + if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == USB_OTG_GINTSTS_BOUTNAKEFF) + { + USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK; + } + + ep = &hpcd->OUT_ep[epnum]; + + if (ep->is_iso_incomplete == 1U) + { + ep->is_iso_incomplete = 0U; + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum); +#else + HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_EPDISD); + } + + /* Clear Status Phase Received interrupt */ + if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); + } + + /* Clear OUT NAK interrupt */ + if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK); + } + } + epnum++; + ep_intr >>= 1U; + } + } + + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT)) + { + /* Read in the device interrupt bits */ + ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance); + + epnum = 0U; + + while (ep_intr != 0U) + { + if ((ep_intr & 0x1U) != 0U) /* In ITR */ + { + epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum); + + if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) + { + fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); + USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; + + CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC); + + if (hpcd->Init.dma_enable == 1U) + { + hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; + + /* this is ZLP, so prepare EP0 for next setup */ + if ((epnum == 0U) && (hpcd->IN_ep[epnum].xfer_len == 0U)) + { + /* prepare to rx more setup packets */ + (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); + } + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataInStageCallback(hpcd, (uint8_t)epnum); +#else + HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC) + { + CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC); + } + if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE) + { + CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE); + } + if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE) + { + CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE); + } + if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD) + { + (void)USB_FlushTxFifo(USBx, epnum); + + ep = &hpcd->IN_ep[epnum]; + + if (ep->is_iso_incomplete == 1U) + { + ep->is_iso_incomplete = 0U; + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum); +#else + HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD); + } + if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) + { + (void)PCD_WriteEmptyTxFifo(hpcd, epnum); + } + } + epnum++; + ep_intr >>= 1U; + } + } + + /* Handle Resume Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT)) + { + /* Clear the Remote Wake-up Signaling */ + USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; + + if (hpcd->LPM_State == LPM_L1) + { + hpcd->LPM_State = LPM_L0; + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->LPMCallback(hpcd, PCD_LPM_L0_ACTIVE); +#else + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ResumeCallback(hpcd); +#else + HAL_PCD_ResumeCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT); + } + + /* Handle Suspend Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP)) + { + if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SuspendCallback(hpcd); +#else + HAL_PCD_SuspendCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP); + } + + /* Handle LPM Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT)) + { + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT); + + if (hpcd->LPM_State == LPM_L0) + { + hpcd->LPM_State = LPM_L1; + hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >> 2U; + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->LPMCallback(hpcd, PCD_LPM_L1_ACTIVE); +#else + HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SuspendCallback(hpcd); +#else + HAL_PCD_SuspendCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + + /* Handle Reset Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST)) + { + USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; + (void)USB_FlushTxFifo(hpcd->Instance, 0x10U); + + for (i = 0U; i < hpcd->Init.dev_endpoints; i++) + { + USBx_INEP(i)->DIEPINT = 0xFB7FU; + USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; + USBx_OUTEP(i)->DOEPINT = 0xFB7FU; + USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; + USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK; + } + USBx_DEVICE->DAINTMSK |= 0x10001U; + + if (hpcd->Init.use_dedicated_ep1 != 0U) + { + USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM | + USB_OTG_DOEPMSK_XFRCM | + USB_OTG_DOEPMSK_EPDM; + + USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM | + USB_OTG_DIEPMSK_XFRCM | + USB_OTG_DIEPMSK_EPDM; + } + else + { + USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM | + USB_OTG_DOEPMSK_XFRCM | + USB_OTG_DOEPMSK_EPDM | + USB_OTG_DOEPMSK_OTEPSPRM | + USB_OTG_DOEPMSK_NAKM; + + USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM | + USB_OTG_DIEPMSK_XFRCM | + USB_OTG_DIEPMSK_EPDM; + } + + /* Set Default Address to 0 */ + USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD; + + /* setup EP0 to receive SETUP packets */ + (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, + (uint8_t *)hpcd->Setup); + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST); + } + + /* Handle Enumeration done Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE)) + { + (void)USB_ActivateSetup(hpcd->Instance); + hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance); + + /* Set USB Turnaround time */ + (void)USB_SetTurnaroundTime(hpcd->Instance, + HAL_RCC_GetHCLKFreq(), + (uint8_t)hpcd->Init.speed); + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ResetCallback(hpcd); +#else + HAL_PCD_ResetCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE); + } + + /* Handle SOF Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF)) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SOFCallback(hpcd); +#else + HAL_PCD_SOFCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF); + } + + /* Handle Global OUT NAK effective Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_BOUTNAKEFF)) + { + USBx->GINTMSK &= ~USB_OTG_GINTMSK_GONAKEFFM; + + for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++) + { + if (hpcd->OUT_ep[epnum].is_iso_incomplete == 1U) + { + /* Abort current transaction and disable the EP */ + (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)epnum); + } + } + } + + /* Handle Incomplete ISO IN Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR)) + { + for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++) + { + RegVal = USBx_INEP(epnum)->DIEPCTL; + + if ((hpcd->IN_ep[epnum].type == EP_TYPE_ISOC) && + ((RegVal & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)) + { + hpcd->IN_ep[epnum].is_iso_incomplete = 1U; + + /* Abort current transaction and disable the EP */ + (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)(epnum | 0x80U)); + } + } + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR); + } + + /* Handle Incomplete ISO OUT Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) + { + for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++) + { + RegVal = USBx_OUTEP(epnum)->DOEPCTL; + + if ((hpcd->OUT_ep[epnum].type == EP_TYPE_ISOC) && + ((RegVal & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) && + (((RegVal & (0x1U << 16)) >> 16U) == (hpcd->FrameNumber & 0x1U))) + { + hpcd->OUT_ep[epnum].is_iso_incomplete = 1U; + + USBx->GINTMSK |= USB_OTG_GINTMSK_GONAKEFFM; + + if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == 0U) + { + USBx_DEVICE->DCTL |= USB_OTG_DCTL_SGONAK; + break; + } + } + } + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); + } + + /* Handle Connection event Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT)) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->ConnectCallback(hpcd); +#else + HAL_PCD_ConnectCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT); + } + + /* Handle Disconnection event Interrupt */ + if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT)) + { + RegVal = hpcd->Instance->GOTGINT; + + if ((RegVal & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DisconnectCallback(hpcd); +#else + HAL_PCD_DisconnectCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + hpcd->Instance->GOTGINT |= RegVal; + } + } +} +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + + +/** + * @brief Data OUT stage callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_DataOutStageCallback could be implemented in the user file + */ +} + +/** + * @brief Data IN stage callback + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_DataInStageCallback could be implemented in the user file + */ +} +/** + * @brief Setup stage callback + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_SetupStageCallback could be implemented in the user file + */ +} + +/** + * @brief USB Start Of Frame callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_SOFCallback could be implemented in the user file + */ +} + +/** + * @brief USB Reset callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ResetCallback could be implemented in the user file + */ +} + +/** + * @brief Suspend event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_SuspendCallback could be implemented in the user file + */ +} + +/** + * @brief Resume event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ResumeCallback could be implemented in the user file + */ +} + +/** + * @brief Incomplete ISO OUT callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Incomplete ISO IN callback. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval None + */ +__weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(epnum); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file + */ +} + +/** + * @brief Connection event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_ConnectCallback could be implemented in the user file + */ +} + +/** + * @brief Disconnection event callback. + * @param hpcd PCD handle + * @retval None + */ +__weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCD_DisconnectCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions + * @brief management functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to control the PCD data + transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Connect the USB device + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + __HAL_LOCK(hpcd); + + if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) && + (hpcd->Init.battery_charging_enable == 1U)) + { + /* Enable USB Transceiver */ + USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN; + } + (void)USB_DevConnect(hpcd->Instance); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Disconnect the USB device. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + __HAL_LOCK(hpcd); + (void)USB_DevDisconnect(hpcd->Instance); + + if (((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) != 0U) && + (hpcd->Init.battery_charging_enable == 1U)) + { + /* Disable USB Transceiver */ + USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); + } + + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Set the USB Device address. + * @param hpcd PCD handle + * @param address new device address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address) +{ + __HAL_LOCK(hpcd); + hpcd->USB_Address = address; + (void)USB_SetDevAddress(hpcd->Instance, address); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} +/** + * @brief Open and configure an endpoint. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param ep_mps endpoint max packet size + * @param ep_type endpoint type + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, + uint16_t ep_mps, uint8_t ep_type) +{ + HAL_StatusTypeDef ret = HAL_OK; + PCD_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + + ep->num = ep_addr & EP_ADDR_MSK; + ep->maxpacket = (uint32_t)ep_mps & 0x7FFU; + ep->type = ep_type; + + if (ep->is_in != 0U) + { + /* Assign a Tx FIFO */ + ep->tx_fifo_num = ep->num; + } + + /* Set initial data PID. */ + if (ep_type == EP_TYPE_BULK) + { + ep->data_pid_start = 0U; + } + + __HAL_LOCK(hpcd); + (void)USB_ActivateEndpoint(hpcd->Instance, ep); + __HAL_UNLOCK(hpcd); + + return ret; +} + +/** + * @brief Deactivate an endpoint. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_EPTypeDef *ep; + + if ((ep_addr & 0x80U) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + ep->num = ep_addr & EP_ADDR_MSK; + + __HAL_LOCK(hpcd); + (void)USB_DeactivateEndpoint(hpcd->Instance, ep); + __HAL_UNLOCK(hpcd); + return HAL_OK; +} + + +/** + * @brief Receive an amount of data. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param pBuf pointer to the reception buffer + * @param len amount of data to be received + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + PCD_EPTypeDef *ep; + + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = 0U; + ep->num = ep_addr & EP_ADDR_MSK; + + if (hpcd->Init.dma_enable == 1U) + { + ep->dma_addr = (uint32_t)pBuf; + } + + (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable); + + return HAL_OK; +} + +/** + * @brief Get Received Data Size + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval Data Size + */ +uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr) +{ + return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count; +} +/** + * @brief Send an amount of data + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @param pBuf pointer to the transmission buffer + * @param len amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len) +{ + PCD_EPTypeDef *ep; + + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + + /*setup and start the Xfer */ + ep->xfer_buff = pBuf; + ep->xfer_len = len; + ep->xfer_count = 0U; + ep->is_in = 1U; + ep->num = ep_addr & EP_ADDR_MSK; + + if (hpcd->Init.dma_enable == 1U) + { + ep->dma_addr = (uint32_t)pBuf; + } + + (void)USB_EPStartXfer(hpcd->Instance, ep, (uint8_t)hpcd->Init.dma_enable); + + return HAL_OK; +} + +/** + * @brief Set a STALL condition over an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_EPTypeDef *ep; + + if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints) + { + return HAL_ERROR; + } + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr]; + ep->is_in = 0U; + } + + ep->is_stall = 1U; + ep->num = ep_addr & EP_ADDR_MSK; + + __HAL_LOCK(hpcd); + + (void)USB_EPSetStall(hpcd->Instance, ep); + + if ((ep_addr & EP_ADDR_MSK) == 0U) + { + (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t)hpcd->Init.dma_enable, (uint8_t *)hpcd->Setup); + } + + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Clear a STALL condition over in an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + PCD_EPTypeDef *ep; + + if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints) + { + return HAL_ERROR; + } + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 1U; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + ep->is_in = 0U; + } + + ep->is_stall = 0U; + ep->num = ep_addr & EP_ADDR_MSK; + + __HAL_LOCK(hpcd); + (void)USB_EPClearStall(hpcd->Instance, ep); + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Abort an USB EP transaction. + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + HAL_StatusTypeDef ret; + PCD_EPTypeDef *ep; + + if ((0x80U & ep_addr) == 0x80U) + { + ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK]; + } + else + { + ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK]; + } + + /* Stop Xfer */ + ret = USB_EPStopXfer(hpcd->Instance, ep); + + return ret; +} + +/** + * @brief Flush an endpoint + * @param hpcd PCD handle + * @param ep_addr endpoint address + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr) +{ + __HAL_LOCK(hpcd); + + if ((ep_addr & 0x80U) == 0x80U) + { + (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK); + } + else + { + (void)USB_FlushRxFifo(hpcd->Instance); + } + + __HAL_UNLOCK(hpcd); + + return HAL_OK; +} + +/** + * @brief Activate remote wakeup signalling + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) +{ + return (USB_ActivateRemoteWakeup(hpcd->Instance)); +} + +/** + * @brief De-activate remote wakeup signalling. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd) +{ + return (USB_DeActivateRemoteWakeup(hpcd->Instance)); +} + +/** + * @} + */ + +/** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the PCD handle state. + * @param hpcd PCD handle + * @retval HAL state + */ +PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd) +{ + return hpcd->State; +} + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +/** + * @brief Set the USB Device high speed test mode. + * @param hpcd PCD handle + * @param testmode USB Device high speed test mode + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCD_SetTestMode(const PCD_HandleTypeDef *hpcd, uint8_t testmode) +{ + const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + uint32_t USBx_BASE = (uint32_t)USBx; + + switch (testmode) + { + case TEST_J: + case TEST_K: + case TEST_SE0_NAK: + case TEST_PACKET: + case TEST_FORCE_EN: + USBx_DEVICE->DCTL &= ~(0x7U << 4); + USBx_DEVICE->DCTL |= (uint32_t)testmode << 4; + break; + + default: + break; + } + + return HAL_OK; +} +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @addtogroup PCD_Private_Functions + * @{ + */ +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +/** + * @brief Check FIFO for the next packet to be loaded. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval HAL status + */ +static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + uint32_t USBx_BASE = (uint32_t)USBx; + USB_OTG_EPTypeDef *ep; + uint32_t len; + uint32_t len32b; + uint32_t fifoemptymsk; + + ep = &hpcd->IN_ep[epnum]; + + if (ep->xfer_count > ep->xfer_len) + { + return HAL_ERROR; + } + + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->maxpacket) + { + len = ep->maxpacket; + } + + len32b = (len + 3U) / 4U; + + while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) && + (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U)) + { + /* Write the FIFO */ + len = ep->xfer_len - ep->xfer_count; + + if (len > ep->maxpacket) + { + len = ep->maxpacket; + } + len32b = (len + 3U) / 4U; + + (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len, + (uint8_t)hpcd->Init.dma_enable); + + ep->xfer_buff += len; + ep->xfer_count += len; + } + + if (ep->xfer_len <= ep->xfer_count) + { + fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK)); + USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; + } + + return HAL_OK; +} + + +/** + * @brief process EP OUT transfer complete interrupt. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval HAL status + */ +static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum) +{ + USB_OTG_EPTypeDef *ep; + const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U); + uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT; + + if (hpcd->Init.dma_enable == 1U) + { + if ((DoepintReg & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) /* Class C */ + { + /* StupPktRcvd = 1 this is a setup packet */ + if ((gSNPSiD > USB_OTG_CORE_ID_300A) && + ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); + } + } + else if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) /* Class E */ + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); + } + else if ((DoepintReg & (USB_OTG_DOEPINT_STUP | USB_OTG_DOEPINT_OTEPSPR)) == 0U) + { + /* StupPktRcvd = 1 this is a setup packet */ + if ((gSNPSiD > USB_OTG_CORE_ID_300A) && + ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); + } + else + { + ep = &hpcd->OUT_ep[epnum]; + + /* out data packet received over EP */ + ep->xfer_count = ep->xfer_size - (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); + + if (epnum == 0U) + { + if (ep->xfer_len == 0U) + { + /* this is ZLP, so prepare EP0 for next setup */ + (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); + } + else + { + ep->xfer_buff += ep->xfer_count; + } + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); +#else + HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + else + { + /* ... */ + } + } + else + { + if (gSNPSiD == USB_OTG_CORE_ID_310A) + { + /* StupPktRcvd = 1 this is a setup packet */ + if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); + } + else + { + if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); +#else + HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + else + { + if ((epnum == 0U) && (hpcd->OUT_ep[epnum].xfer_len == 0U)) + { + /* this is ZLP, so prepare EP0 for next setup */ + (void)USB_EP0_OutStart(hpcd->Instance, 0U, (uint8_t *)hpcd->Setup); + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum); +#else + HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + + return HAL_OK; +} + + +/** + * @brief process EP OUT setup packet received interrupt. + * @param hpcd PCD handle + * @param epnum endpoint number + * @retval HAL status + */ +static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum) +{ + const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U); + uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT; + + if ((gSNPSiD > USB_OTG_CORE_ID_300A) && + ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)) + { + CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX); + } + + /* Inform the upper layer that a setup packet is available */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->SetupStageCallback(hpcd); +#else + HAL_PCD_SetupStageCallback(hpcd); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + + if ((gSNPSiD > USB_OTG_CORE_ID_300A) && (hpcd->Init.dma_enable == 1U)) + { + (void)USB_EP0_OutStart(hpcd->Instance, 1U, (uint8_t *)hpcd->Setup); + } + + return HAL_OK; +} +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + +/** + * @} + */ +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ +#endif /* HAL_PCD_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c new file mode 100644 index 0000000..1d4bfe9 --- /dev/null +++ b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c @@ -0,0 +1,341 @@ +/** + ****************************************************************************** + * @file stm32h7xx_hal_pcd_ex.c + * @author MCD Application Team + * @brief PCD Extended HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Extended features functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx_hal.h" + +/** @addtogroup STM32H7xx_HAL_Driver + * @{ + */ + +/** @defgroup PCDEx PCDEx + * @brief PCD Extended HAL module driver + * @{ + */ + +#ifdef HAL_PCD_MODULE_ENABLED + +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup PCDEx_Exported_Functions PCDEx Exported Functions + * @{ + */ + +/** @defgroup PCDEx_Exported_Functions_Group1 Peripheral Control functions + * @brief PCDEx control functions + * +@verbatim + =============================================================================== + ##### Extended features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Update FIFO configuration + +@endverbatim + * @{ + */ +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +/** + * @brief Set Tx FIFO + * @param hpcd PCD handle + * @param fifo The number of Tx fifo + * @param size Fifo size + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_SetTxFiFo(PCD_HandleTypeDef *hpcd, uint8_t fifo, uint16_t size) +{ + uint8_t i; + uint32_t Tx_Offset; + + /* TXn min size = 16 words. (n : Transmit FIFO index) + When a TxFIFO is not used, the Configuration should be as follows: + case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes) + --> Txm can use the space allocated for Txn. + case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes) + --> Txn should be configured with the minimum space of 16 words + The FIFO is used optimally when used TxFIFOs are allocated in the top + of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones. + When DMA is used 3n * FIFO locations should be reserved for internal DMA registers */ + + Tx_Offset = hpcd->Instance->GRXFSIZ; + + if (fifo == 0U) + { + hpcd->Instance->DIEPTXF0_HNPTXFSIZ = ((uint32_t)size << 16) | Tx_Offset; + } + else + { + Tx_Offset += (hpcd->Instance->DIEPTXF0_HNPTXFSIZ) >> 16; + for (i = 0U; i < (fifo - 1U); i++) + { + Tx_Offset += (hpcd->Instance->DIEPTXF[i] >> 16); + } + + /* Multiply Tx_Size by 2 to get higher performance */ + hpcd->Instance->DIEPTXF[fifo - 1U] = ((uint32_t)size << 16) | Tx_Offset; + } + + return HAL_OK; +} + +/** + * @brief Set Rx FIFO + * @param hpcd PCD handle + * @param size Size of Rx fifo + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_SetRxFiFo(PCD_HandleTypeDef *hpcd, uint16_t size) +{ + hpcd->Instance->GRXFSIZ = size; + + return HAL_OK; +} + +/** + * @brief Activate LPM feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateLPM(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + hpcd->lpm_active = 1U; + hpcd->LPM_State = LPM_L0; + USBx->GINTMSK |= USB_OTG_GINTMSK_LPMINTM; + USBx->GLPMCFG |= (USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL); + + return HAL_OK; +} + +/** + * @brief Deactivate LPM feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_DeActivateLPM(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + hpcd->lpm_active = 0U; + USBx->GINTMSK &= ~USB_OTG_GINTMSK_LPMINTM; + USBx->GLPMCFG &= ~(USB_OTG_GLPMCFG_LPMEN | USB_OTG_GLPMCFG_LPMACK | USB_OTG_GLPMCFG_ENBESL); + + return HAL_OK; +} + + +/** + * @brief Handle BatteryCharging Process. + * @param hpcd PCD handle + * @retval HAL status + */ +void HAL_PCDEx_BCD_VBUSDetect(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + uint32_t tickstart = HAL_GetTick(); + + /* Enable DCD : Data Contact Detect */ + USBx->GCCFG |= USB_OTG_GCCFG_DCDEN; + + /* Wait for Min DCD Timeout */ + HAL_Delay(300U); + + /* Check Detect flag */ + if ((USBx->GCCFG & USB_OTG_GCCFG_DCDET) == USB_OTG_GCCFG_DCDET) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_CONTACT_DETECTION); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CONTACT_DETECTION); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + + /* Primary detection: checks if connected to Standard Downstream Port + (without charging capability) */ + USBx->GCCFG &= ~USB_OTG_GCCFG_DCDEN; + HAL_Delay(50U); + USBx->GCCFG |= USB_OTG_GCCFG_PDEN; + HAL_Delay(50U); + + if ((USBx->GCCFG & USB_OTG_GCCFG_PDET) == 0U) + { + /* Case of Standard Downstream Port */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_STD_DOWNSTREAM_PORT); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + /* start secondary detection to check connection to Charging Downstream + Port or Dedicated Charging Port */ + USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN); + HAL_Delay(50U); + USBx->GCCFG |= USB_OTG_GCCFG_SDEN; + HAL_Delay(50U); + + if ((USBx->GCCFG & USB_OTG_GCCFG_SDET) == USB_OTG_GCCFG_SDET) + { + /* case Dedicated Charging Port */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DEDICATED_CHARGING_PORT); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { + /* case Charging Downstream Port */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_CHARGING_DOWNSTREAM_PORT); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + } + + /* Battery Charging capability discovery finished */ + (void)HAL_PCDEx_DeActivateBCD(hpcd); + + /* Check for the Timeout, else start USB Device */ + if ((HAL_GetTick() - tickstart) > 1000U) + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_ERROR); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_ERROR); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } + else + { +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + hpcd->BCDCallback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); +#else + HAL_PCDEx_BCD_Callback(hpcd, PCD_BCD_DISCOVERY_COMPLETED); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + } +} + +/** + * @brief Activate BatteryCharging feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_ActivateBCD(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN); + USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN); + + /* Power Down USB transceiver */ + USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); + + /* Enable Battery charging */ + USBx->GCCFG |= USB_OTG_GCCFG_BCDEN; + + hpcd->battery_charging_active = 1U; + + return HAL_OK; +} + +/** + * @brief Deactivate BatteryCharging feature. + * @param hpcd PCD handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_PCDEx_DeActivateBCD(PCD_HandleTypeDef *hpcd) +{ + USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; + + USBx->GCCFG &= ~(USB_OTG_GCCFG_SDEN); + USBx->GCCFG &= ~(USB_OTG_GCCFG_PDEN); + + /* Disable Battery charging */ + USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN); + + hpcd->battery_charging_active = 0U; + + return HAL_OK; +} + +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + +/** + * @brief Send LPM message to user layer callback. + * @param hpcd PCD handle + * @param msg LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(msg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCDEx_LPM_Callback could be implemented in the user file + */ +} + +/** + * @brief Send BatteryCharging message to user layer callback. + * @param hpcd PCD handle + * @param msg LPM message + * @retval HAL status + */ +__weak void HAL_PCDEx_BCD_Callback(PCD_HandleTypeDef *hpcd, PCD_BCD_MsgTypeDef msg) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hpcd); + UNUSED(msg); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_PCDEx_BCD_Callback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ +#endif /* HAL_PCD_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c deleted file mode 100644 index e0571e0..0000000 --- a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c +++ /dev/null @@ -1,4016 +0,0 @@ -/** - ****************************************************************************** - * @file stm32h7xx_hal_spi.c - * @author MCD Application Team - * @brief SPI HAL module driver. - * This file provides firmware functions to manage the following - * functionalities of the Serial Peripheral Interface (SPI) peripheral: - * + Initialization and de-initialization functions - * + IO operation functions - * + Peripheral Control functions - * + Peripheral State functions - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - @verbatim - ============================================================================== - ##### How to use this driver ##### - ============================================================================== - [..] - The SPI HAL driver can be used as follows: - - (#) Declare a SPI_HandleTypeDef handle structure, for example: - SPI_HandleTypeDef hspi; - - (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API: - (##) Enable the SPIx interface clock - (##) SPI pins configuration - (+++) Enable the clock for the SPI GPIOs - (+++) Configure these SPI pins as alternate function push-pull - (##) NVIC configuration if you need to use interrupt process or DMA process - (+++) Configure the SPIx interrupt priority - (+++) Enable the NVIC SPI IRQ handle - (##) DMA Configuration if you need to use DMA process - (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Stream/Channel - (+++) Enable the DMAx clock - (+++) Configure the DMA handle parameters - (+++) Configure the DMA Tx or Rx Stream/Channel - (+++) Associate the initialized hdma_tx handle to the hspi DMA Tx or Rx handle - (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx - or Rx Stream/Channel - - (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS - management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure. - - (#) Initialize the SPI registers by calling the HAL_SPI_Init() API: - (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) - by calling the customized HAL_SPI_MspInit() API. - [..] - Callback registration: - - (#) The compilation flag USE_HAL_SPI_REGISTER_CALLBACKS when set to 1UL - allows the user to configure dynamically the driver callbacks. - Use Functions HAL_SPI_RegisterCallback() to register an interrupt callback. - - Function HAL_SPI_RegisterCallback() allows to register following callbacks: - (+) TxCpltCallback : SPI Tx Completed callback - (+) RxCpltCallback : SPI Rx Completed callback - (+) TxRxCpltCallback : SPI TxRx Completed callback - (+) TxHalfCpltCallback : SPI Tx Half Completed callback - (+) RxHalfCpltCallback : SPI Rx Half Completed callback - (+) TxRxHalfCpltCallback : SPI TxRx Half Completed callback - (+) ErrorCallback : SPI Error callback - (+) AbortCpltCallback : SPI Abort callback - (+) SuspendCallback : SPI Suspend callback - (+) MspInitCallback : SPI Msp Init callback - (+) MspDeInitCallback : SPI Msp DeInit callback - This function takes as parameters the HAL peripheral handle, the Callback ID - and a pointer to the user callback function. - - - (#) Use function HAL_SPI_UnRegisterCallback to reset a callback to the default - weak function. - HAL_SPI_UnRegisterCallback takes as parameters the HAL peripheral handle, - and the Callback ID. - This function allows to reset following callbacks: - (+) TxCpltCallback : SPI Tx Completed callback - (+) RxCpltCallback : SPI Rx Completed callback - (+) TxRxCpltCallback : SPI TxRx Completed callback - (+) TxHalfCpltCallback : SPI Tx Half Completed callback - (+) RxHalfCpltCallback : SPI Rx Half Completed callback - (+) TxRxHalfCpltCallback : SPI TxRx Half Completed callback - (+) ErrorCallback : SPI Error callback - (+) AbortCpltCallback : SPI Abort callback - (+) SuspendCallback : SPI Suspend callback - (+) MspInitCallback : SPI Msp Init callback - (+) MspDeInitCallback : SPI Msp DeInit callback - - By default, after the HAL_SPI_Init() and when the state is HAL_SPI_STATE_RESET - all callbacks are set to the corresponding weak functions: - examples HAL_SPI_MasterTxCpltCallback(), HAL_SPI_MasterRxCpltCallback(). - Exception done for MspInit and MspDeInit functions that are - reset to the legacy weak functions in the HAL_SPI_Init()/ HAL_SPI_DeInit() only when - these callbacks are null (not registered beforehand). - If MspInit or MspDeInit are not null, the HAL_SPI_Init()/ HAL_SPI_DeInit() - keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. - - Callbacks can be registered/unregistered in HAL_SPI_STATE_READY state only. - Exception done MspInit/MspDeInit functions that can be registered/unregistered - in HAL_SPI_STATE_READY or HAL_SPI_STATE_RESET state, - thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. - Then, the user first registers the MspInit/MspDeInit user callbacks - using HAL_SPI_RegisterCallback() before calling HAL_SPI_DeInit() - or HAL_SPI_Init() function. - - When The compilation define USE_HAL_PPP_REGISTER_CALLBACKS is set to 0 or not defined, - the callback registering feature is not available and weak callbacks are used. - - SuspendCallback restriction: - SuspendCallback is called only when MasterReceiverAutoSusp is enabled and - EOT interrupt is activated. SuspendCallback is used in relation with functions - HAL_SPI_Transmit_IT, HAL_SPI_Receive_IT and HAL_SPI_TransmitReceive_IT. - - [..] - Circular mode restriction: - (+) The DMA circular mode cannot be used when the SPI is configured in these modes: - (++) Master 2Lines RxOnly - (++) Master 1Line Rx - (+) The CRC feature is not managed when the DMA circular mode is enabled - (+) The functions HAL_SPI_DMAPause()/ HAL_SPI_DMAResume() are not supported. Return always - HAL_ERROR with ErrorCode set to HAL_SPI_ERROR_NOT_SUPPORTED. - Those functions are maintained for backward compatibility reasons. - - @endverbatim - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32h7xx_hal.h" - -/** @addtogroup STM32H7xx_HAL_Driver - * @{ - */ - -/** @defgroup SPI SPI - * @brief SPI HAL module driver - * @{ - */ -#ifdef HAL_SPI_MODULE_ENABLED - -/* Private typedef -----------------------------------------------------------*/ -/* Private defines -----------------------------------------------------------*/ -/** @defgroup SPI_Private_Constants SPI Private Constants - * @{ - */ -#define SPI_DEFAULT_TIMEOUT 100UL -/** - * @} - */ - -/* Private macros ------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/** @defgroup SPI_Private_Functions SPI Private Functions - * @{ - */ -static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma); -static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma); -static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma); -static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma); -static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma); -static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma); -static void SPI_DMAError(DMA_HandleTypeDef *hdma); -static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma); -static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma); -static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma); -static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef *hspi, uint32_t Flag, - FlagStatus FlagStatus, uint32_t Timeout, uint32_t Tickstart); -static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi); -static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi); -static void SPI_TxISR_32BIT(SPI_HandleTypeDef *hspi); -static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi); -static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi); -static void SPI_RxISR_32BIT(SPI_HandleTypeDef *hspi); -static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi); -static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi); -static uint32_t SPI_GetPacketSize(const SPI_HandleTypeDef *hspi); - - -/** - * @} - */ - -/* Exported functions --------------------------------------------------------*/ -/** @defgroup SPI_Exported_Functions SPI Exported Functions - * @{ - */ - -/** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - ##### Initialization and de-initialization functions ##### - =============================================================================== - [..] This subsection provides a set of functions allowing to initialize and - de-initialize the SPIx peripheral: - - (+) User must implement HAL_SPI_MspInit() function in which he configures - all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). - - (+) Call the function HAL_SPI_Init() to configure the selected device with - the selected configuration: - (++) Mode - (++) Direction - (++) Data Size - (++) Clock Polarity and Phase - (++) NSS Management - (++) BaudRate Prescaler - (++) FirstBit - (++) TIMode - (++) CRC Calculation - (++) CRC Polynomial if CRC enabled - (++) CRC Length, used only with Data8 and Data16 - (++) FIFO reception threshold - (++) FIFO transmission threshold - - (+) Call the function HAL_SPI_DeInit() to restore the default configuration - of the selected SPIx peripheral. - -@endverbatim - * @{ - */ - -/** - * @brief Initialize the SPI according to the specified parameters - * in the SPI_InitTypeDef and initialize the associated handle. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi) -{ - uint32_t crc_length; - uint32_t packet_length; -#if (USE_SPI_CRC != 0UL) - uint32_t crc_poly_msb_mask; -#endif /* USE_SPI_CRC */ - - /* Check the SPI handle allocation */ - if (hspi == NULL) - { - return HAL_ERROR; - } - - /* Check the parameters */ - assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); - assert_param(IS_SPI_MODE(hspi->Init.Mode)); - assert_param(IS_SPI_DIRECTION(hspi->Init.Direction)); - assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize)); - assert_param(IS_SPI_FIFOTHRESHOLD(hspi->Init.FifoThreshold)); - assert_param(IS_SPI_NSS(hspi->Init.NSS)); - assert_param(IS_SPI_NSSP(hspi->Init.NSSPMode)); - assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler)); - assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit)); - assert_param(IS_SPI_TIMODE(hspi->Init.TIMode)); - if (hspi->Init.TIMode == SPI_TIMODE_DISABLE) - { - assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity)); - assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase)); - } -#if (USE_SPI_CRC != 0UL) - assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation)); - if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) - { - assert_param(IS_SPI_CRC_LENGTH(hspi->Init.CRCLength)); - assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial)); - assert_param(IS_SPI_CRC_INITIALIZATION_PATTERN(hspi->Init.TxCRCInitializationPattern)); - assert_param(IS_SPI_CRC_INITIALIZATION_PATTERN(hspi->Init.RxCRCInitializationPattern)); - } -#else - hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; -#endif /* USE_SPI_CRC */ - - /* Verify that the SPI instance supports Data Size higher than 16bits */ - if ((!IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (hspi->Init.DataSize > SPI_DATASIZE_16BIT)) - { - return HAL_ERROR; - } - - /* Verify that the SPI instance supports requested data packing */ - packet_length = SPI_GetPacketSize(hspi); - if (((!IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (packet_length > SPI_LOWEND_FIFO_SIZE)) || - ((IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (packet_length > SPI_HIGHEND_FIFO_SIZE))) - { - return HAL_ERROR; - } - -#if (USE_SPI_CRC != 0UL) - if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) - { - /* Verify that the SPI instance supports CRC Length higher than 16bits */ - if ((!IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (hspi->Init.CRCLength > SPI_CRC_LENGTH_16BIT)) - { - return HAL_ERROR; - } - - /* Align the CRC Length on the data size */ - if (hspi->Init.CRCLength == SPI_CRC_LENGTH_DATASIZE) - { - crc_length = (hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) << SPI_CFG1_CRCSIZE_Pos; - } - else - { - crc_length = hspi->Init.CRCLength; - } - - /* Verify the correctness of polynom size */ - assert_param(IS_SPI_CRC_POLYNOMIAL_SIZE(hspi->Init.CRCPolynomial, crc_length)); - - /* Verify that the CRC Length is higher than DataSize */ - if ((hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) > (crc_length >> SPI_CFG1_CRCSIZE_Pos)) - { - return HAL_ERROR; - } - } - else - { - crc_length = hspi->Init.DataSize << SPI_CFG1_CRCSIZE_Pos; - } -#endif /* USE_SPI_CRC */ - - if (hspi->State == HAL_SPI_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - hspi->Lock = HAL_UNLOCKED; - -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - /* Init the SPI Callback settings */ - hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */ - hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */ - hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ - hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ - hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ - hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ - hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */ - hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ - hspi->SuspendCallback = HAL_SPI_SuspendCallback; /* Legacy weak SuspendCallback */ - - if (hspi->MspInitCallback == NULL) - { - hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ - } - - /* Init the low level hardware : GPIO, CLOCK, NVIC... */ - hspi->MspInitCallback(hspi); -#else - /* Init the low level hardware : GPIO, CLOCK, NVIC... */ - HAL_SPI_MspInit(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - } - - hspi->State = HAL_SPI_STATE_BUSY; - - /* Disable the selected SPI peripheral */ - __HAL_SPI_DISABLE(hspi); - -#if (USE_SPI_CRC == 0) - /* Keep the default value of CRCSIZE in case of CRC is not used */ - crc_length = hspi->Instance->CFG1 & SPI_CFG1_CRCSIZE; -#endif /* USE_SPI_CRC */ - - /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/ - /* Configure : SPI Mode, Communication Mode, Clock polarity and phase, NSS management, - Communication speed, First bit, CRC calculation state, CRC Length */ - - /* SPIx NSS Software Management Configuration */ - if ((hspi->Init.NSS == SPI_NSS_SOFT) && (((hspi->Init.Mode == SPI_MODE_MASTER) && \ - (hspi->Init.NSSPolarity == SPI_NSS_POLARITY_LOW)) || \ - ((hspi->Init.Mode == SPI_MODE_SLAVE) && \ - (hspi->Init.NSSPolarity == SPI_NSS_POLARITY_HIGH)))) - { - SET_BIT(hspi->Instance->CR1, SPI_CR1_SSI); - } - - /* SPIx Master Rx Auto Suspend Configuration */ - if (((hspi->Init.Mode & SPI_MODE_MASTER) == SPI_MODE_MASTER) && (hspi->Init.DataSize >= SPI_DATASIZE_8BIT)) - { - MODIFY_REG(hspi->Instance->CR1, SPI_CR1_MASRX, hspi->Init.MasterReceiverAutoSusp); - } - else - { - CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_MASRX); - } - - /* SPIx CFG1 Configuration */ - WRITE_REG(hspi->Instance->CFG1, (hspi->Init.BaudRatePrescaler | hspi->Init.CRCCalculation | crc_length | - hspi->Init.FifoThreshold | hspi->Init.DataSize)); - - /* SPIx CFG2 Configuration */ - WRITE_REG(hspi->Instance->CFG2, (hspi->Init.NSSPMode | hspi->Init.TIMode | - hspi->Init.NSSPolarity | hspi->Init.NSS | - hspi->Init.CLKPolarity | hspi->Init.CLKPhase | - hspi->Init.FirstBit | hspi->Init.Mode | - hspi->Init.MasterInterDataIdleness | hspi->Init.Direction | - hspi->Init.MasterSSIdleness | hspi->Init.IOSwap)); - -#if (USE_SPI_CRC != 0UL) - /*---------------------------- SPIx CRCPOLY Configuration ------------------*/ - /* Configure : CRC Polynomial */ - if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) - { - /* Initialize TXCRC Pattern Initial Value */ - if (hspi->Init.TxCRCInitializationPattern == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN) - { - SET_BIT(hspi->Instance->CR1, SPI_CR1_TCRCINI); - } - else - { - CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_TCRCINI); - } - - /* Initialize RXCRC Pattern Initial Value */ - if (hspi->Init.RxCRCInitializationPattern == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN) - { - SET_BIT(hspi->Instance->CR1, SPI_CR1_RCRCINI); - } - else - { - CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_RCRCINI); - } - - /* Enable 33/17 bits CRC computation */ - if (((!IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (crc_length == SPI_CRC_LENGTH_16BIT)) || - ((IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (crc_length == SPI_CRC_LENGTH_32BIT))) - { - /* Set SPI_CR1_CRC33_17 bit */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CRC33_17); - /* Write CRC polynomial in SPI Register */ - WRITE_REG(hspi->Instance->CRCPOLY, hspi->Init.CRCPolynomial); - } - else - { - /* Clear SPI_CR1_CRC33_17 bit */ - CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRC33_17); - - /* Write CRC polynomial and set MSB bit at 1 in SPI Register */ - /* Set MSB is mandatory for a correct CRC computation */ - crc_poly_msb_mask = (0x1UL << ((crc_length >> SPI_CFG1_CRCSIZE_Pos) + 0x1U)); - WRITE_REG(hspi->Instance->CRCPOLY, (hspi->Init.CRCPolynomial) | crc_poly_msb_mask); - } - } -#endif /* USE_SPI_CRC */ - - /* Insure that Underrun configuration is managed only by Salve */ - if (hspi->Init.Mode == SPI_MODE_SLAVE) - { - /* Set Default Underrun configuration */ -#if (USE_SPI_CRC != 0UL) - if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_DISABLE) -#endif /* USE_SPI_CRC */ - { - MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRDET, SPI_CFG1_UDRDET_0); - } - MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, SPI_CFG1_UDRCFG_1); - } - -#if defined(SPI_I2SCFGR_I2SMOD) - /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */ - CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD); -#endif /* SPI_I2SCFGR_I2SMOD */ - - /* Insure that AFCNTR is managed only by Master */ - if ((hspi->Init.Mode & SPI_MODE_MASTER) == SPI_MODE_MASTER) - { - /* Alternate function GPIOs control */ - MODIFY_REG(hspi->Instance->CFG2, SPI_CFG2_AFCNTR, (hspi->Init.MasterKeepIOState)); - } - - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->State = HAL_SPI_STATE_READY; - - return HAL_OK; -} - -/** - * @brief De-Initialize the SPI peripheral. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi) -{ - /* Check the SPI handle allocation */ - if (hspi == NULL) - { - return HAL_ERROR; - } - - /* Check SPI Instance parameter */ - assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); - - hspi->State = HAL_SPI_STATE_BUSY; - - /* Disable the SPI Peripheral Clock */ - __HAL_SPI_DISABLE(hspi); - -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - if (hspi->MspDeInitCallback == NULL) - { - hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ - } - - /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ - hspi->MspDeInitCallback(hspi); -#else - /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ - HAL_SPI_MspDeInit(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->State = HAL_SPI_STATE_RESET; - - /* Release Lock */ - __HAL_UNLOCK(hspi); - - return HAL_OK; -} - -/** - * @brief Initialize the SPI MSP. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_MspInit should be implemented in the user file - */ -} - -/** - * @brief De-Initialize the SPI MSP. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -__weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_MspDeInit should be implemented in the user file - */ -} - -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) -/** - * @brief Register a User SPI Callback - * To be used instead of the weak predefined callback - * @param hspi Pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for the specified SPI. - * @param CallbackID ID of the callback to be registered - * @param pCallback pointer to the Callback function - * @note The HAL_SPI_RegisterCallback() may be called before HAL_SPI_Init() in HAL_SPI_STATE_RESET - * to register callbacks for HAL_SPI_MSPINIT_CB_ID and HAL_SPI_MSPDEINIT_CB_ID - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID, - pSPI_CallbackTypeDef pCallback) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (pCallback == NULL) - { - /* Update the error code */ - hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK; - - return HAL_ERROR; - } - - if (HAL_SPI_STATE_READY == hspi->State) - { - switch (CallbackID) - { - case HAL_SPI_TX_COMPLETE_CB_ID : - hspi->TxCpltCallback = pCallback; - break; - - case HAL_SPI_RX_COMPLETE_CB_ID : - hspi->RxCpltCallback = pCallback; - break; - - case HAL_SPI_TX_RX_COMPLETE_CB_ID : - hspi->TxRxCpltCallback = pCallback; - break; - - case HAL_SPI_TX_HALF_COMPLETE_CB_ID : - hspi->TxHalfCpltCallback = pCallback; - break; - - case HAL_SPI_RX_HALF_COMPLETE_CB_ID : - hspi->RxHalfCpltCallback = pCallback; - break; - - case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID : - hspi->TxRxHalfCpltCallback = pCallback; - break; - - case HAL_SPI_ERROR_CB_ID : - hspi->ErrorCallback = pCallback; - break; - - case HAL_SPI_ABORT_CB_ID : - hspi->AbortCpltCallback = pCallback; - break; - - case HAL_SPI_SUSPEND_CB_ID : - hspi->SuspendCallback = pCallback; - break; - - case HAL_SPI_MSPINIT_CB_ID : - hspi->MspInitCallback = pCallback; - break; - - case HAL_SPI_MSPDEINIT_CB_ID : - hspi->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); - - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (HAL_SPI_STATE_RESET == hspi->State) - { - switch (CallbackID) - { - case HAL_SPI_MSPINIT_CB_ID : - hspi->MspInitCallback = pCallback; - break; - - case HAL_SPI_MSPDEINIT_CB_ID : - hspi->MspDeInitCallback = pCallback; - break; - - default : - /* Update the error code */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); - - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); - - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} - -/** - * @brief Unregister an SPI Callback - * SPI callback is redirected to the weak predefined callback - * @param hspi Pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for the specified SPI. - * @param CallbackID ID of the callback to be unregistered - * @note The HAL_SPI_UnRegisterCallback() may be called before HAL_SPI_Init() in HAL_SPI_STATE_RESET - * to un-register callbacks for HAL_SPI_MSPINIT_CB_ID and HAL_SPI_MSPDEINIT_CB_ID - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID) -{ - HAL_StatusTypeDef status = HAL_OK; - - if (HAL_SPI_STATE_READY == hspi->State) - { - switch (CallbackID) - { - case HAL_SPI_TX_COMPLETE_CB_ID : - hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */ - break; - - case HAL_SPI_RX_COMPLETE_CB_ID : - hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */ - break; - - case HAL_SPI_TX_RX_COMPLETE_CB_ID : - hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ - break; - - case HAL_SPI_TX_HALF_COMPLETE_CB_ID : - hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ - break; - - case HAL_SPI_RX_HALF_COMPLETE_CB_ID : - hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ - break; - - case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID : - hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ - break; - - case HAL_SPI_ERROR_CB_ID : - hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */ - break; - - case HAL_SPI_ABORT_CB_ID : - hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ - break; - - case HAL_SPI_SUSPEND_CB_ID : - hspi->SuspendCallback = HAL_SPI_SuspendCallback; /* Legacy weak SuspendCallback */ - break; - - case HAL_SPI_MSPINIT_CB_ID : - hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ - break; - - case HAL_SPI_MSPDEINIT_CB_ID : - hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ - break; - - default : - /* Update the error code */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); - - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else if (HAL_SPI_STATE_RESET == hspi->State) - { - switch (CallbackID) - { - case HAL_SPI_MSPINIT_CB_ID : - hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ - break; - - case HAL_SPI_MSPDEINIT_CB_ID : - hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ - break; - - default : - /* Update the error code */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); - - /* Return error status */ - status = HAL_ERROR; - break; - } - } - else - { - /* Update the error code */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); - - /* Return error status */ - status = HAL_ERROR; - } - - return status; -} -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -/** - * @} - */ - -/** @defgroup SPI_Exported_Functions_Group2 IO operation functions - * @brief Data transfers functions - * -@verbatim - ============================================================================== - ##### IO operation functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to manage the SPI - data transfers. - - [..] The SPI supports master and slave mode : - - (#) There are two modes of transfer: - (##) Blocking mode: The communication is performed in polling mode. - The HAL status of all data processing is returned by the same function - after finishing transfer. - (##) No-Blocking mode: The communication is performed using Interrupts - or DMA, These APIs return the HAL status. - The end of the data processing will be indicated through the - dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when - using DMA mode. - The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks - will be executed respectively at the end of the transmit or Receive process - The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected - - (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA) - exist for 1Line (simplex) and 2Lines (full duplex) modes. - -@endverbatim - * @{ - */ - -/** - * @brief Transmit an amount of data in blocking mode. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pData : pointer to data buffer - * @param Size : amount of data to be sent - * @param Timeout: Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ -#if defined (__GNUC__) - __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR)); -#endif /* __GNUC__ */ - - uint32_t tickstart; - - /* Check Direction parameter */ - assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction)); - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - if (hspi->State != HAL_SPI_STATE_READY) - { - return HAL_BUSY; - } - - if ((pData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Set the transaction information */ - hspi->State = HAL_SPI_STATE_BUSY_TX; - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->pTxBuffPtr = (const uint8_t *)pData; - hspi->TxXferSize = Size; - hspi->TxXferCount = Size; - - /*Init field not used in handle to zero */ - hspi->pRxBuffPtr = NULL; - hspi->RxXferSize = (uint16_t) 0UL; - hspi->RxXferCount = (uint16_t) 0UL; - hspi->TxISR = NULL; - hspi->RxISR = NULL; - - /* Configure communication direction : 1Line */ - if (hspi->Init.Direction == SPI_DIRECTION_1LINE) - { - SPI_1LINE_TX(hspi); - } - else - { - SPI_2LINES_TX(hspi); - } - - /* Set the number of data at current transfer */ - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); - - /* Enable SPI peripheral */ - __HAL_SPI_ENABLE(hspi); - - if (hspi->Init.Mode == SPI_MODE_MASTER) - { - /* Master transfer start */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); - } - - /* Transmit data in 32 Bit mode */ - if (hspi->Init.DataSize > SPI_DATASIZE_16BIT) - { - /* Transmit data in 32 Bit mode */ - while (hspi->TxXferCount > 0UL) - { - /* Wait until TXP flag is set to send data */ - if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) - { - *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); - hspi->pTxBuffPtr += sizeof(uint32_t); - hspi->TxXferCount--; - } - else - { - /* Timeout management */ - if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) - { - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_TIMEOUT; - } - } - } - } - /* Transmit data in 16 Bit mode */ - else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) - { - /* Transmit data in 16 Bit mode */ - while (hspi->TxXferCount > 0UL) - { - /* Wait until TXP flag is set to send data */ - if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) - { - if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA)) - { - *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); - hspi->pTxBuffPtr += sizeof(uint32_t); - hspi->TxXferCount -= (uint16_t)2UL; - } - else - { -#if defined (__GNUC__) - *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr); -#else - *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr); -#endif /* __GNUC__ */ - hspi->pTxBuffPtr += sizeof(uint16_t); - hspi->TxXferCount--; - } - } - else - { - /* Timeout management */ - if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) - { - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_TIMEOUT; - } - } - } - } - /* Transmit data in 8 Bit mode */ - else - { - while (hspi->TxXferCount > 0UL) - { - /* Wait until TXP flag is set to send data */ - if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) - { - if ((hspi->TxXferCount > 3UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_03DATA)) - { - *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); - hspi->pTxBuffPtr += sizeof(uint32_t); - hspi->TxXferCount -= (uint16_t)4UL; - } - else if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA)) - { -#if defined (__GNUC__) - *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr); -#else - *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr); -#endif /* __GNUC__ */ - hspi->pTxBuffPtr += sizeof(uint16_t); - hspi->TxXferCount -= (uint16_t)2UL; - } - else - { - *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr); - hspi->pTxBuffPtr += sizeof(uint8_t); - hspi->TxXferCount--; - } - } - else - { - /* Timeout management */ - if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) - { - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_TIMEOUT; - } - } - } - } - - /* Wait for Tx (and CRC) data to be sent */ - if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); - } - - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) - { - return HAL_ERROR; - } - else - { - return HAL_OK; - } -} - -/** - * @brief Receive an amount of data in blocking mode. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pData : pointer to data buffer - * @param Size : amount of data to be received - * @param Timeout: Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ - uint32_t tickstart; - uint32_t temp_sr_reg; - uint16_t init_max_data_in_fifo; - init_max_data_in_fifo = (((uint16_t)(hspi->Init.FifoThreshold >> 5U) + 1U)); -#if defined (__GNUC__) - __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR)); -#endif /* __GNUC__ */ - - /* Check Direction parameter */ - assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction)); - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - if (hspi->State != HAL_SPI_STATE_READY) - { - return HAL_BUSY; - } - - if ((pData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Set the transaction information */ - hspi->State = HAL_SPI_STATE_BUSY_RX; - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->pRxBuffPtr = (uint8_t *)pData; - hspi->RxXferSize = Size; - hspi->RxXferCount = Size; - - /*Init field not used in handle to zero */ - hspi->pTxBuffPtr = NULL; - hspi->TxXferSize = (uint16_t) 0UL; - hspi->TxXferCount = (uint16_t) 0UL; - hspi->RxISR = NULL; - hspi->TxISR = NULL; - - /* Configure communication direction: 1Line */ - if (hspi->Init.Direction == SPI_DIRECTION_1LINE) - { - SPI_1LINE_RX(hspi); - } - else - { - SPI_2LINES_RX(hspi); - } - - /* Set the number of data at current transfer */ - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); - - /* Enable SPI peripheral */ - __HAL_SPI_ENABLE(hspi); - - if (hspi->Init.Mode == SPI_MODE_MASTER) - { - /* Master transfer start */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); - } - - /* Receive data in 32 Bit mode */ - if (hspi->Init.DataSize > SPI_DATASIZE_16BIT) - { - /* Transfer loop */ - while (hspi->RxXferCount > 0UL) - { - /* Evaluate state of SR register */ - temp_sr_reg = hspi->Instance->SR; - - /* Check the RXP flag */ - if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP)) - { - *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint32_t); - hspi->RxXferCount--; - } - /* Check RXWNE flag if RXP cannot be reached */ - else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL)) - { - *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint32_t); - hspi->RxXferCount--; - } - else - { - /* Timeout management */ - if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) - { - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_TIMEOUT; - } - } - } - } - /* Receive data in 16 Bit mode */ - else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) - { - /* Transfer loop */ - while (hspi->RxXferCount > 0UL) - { - /* Evaluate state of SR register */ - temp_sr_reg = hspi->Instance->SR; - - /* Check the RXP flag */ - if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP)) - { -#if defined (__GNUC__) - *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; -#else - *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); -#endif /* __GNUC__ */ - hspi->pRxBuffPtr += sizeof(uint16_t); - hspi->RxXferCount--; - } - /* Check RXWNE flag if RXP cannot be reached */ - else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL)) - { -#if defined (__GNUC__) - *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; -#else - *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); -#endif /* __GNUC__ */ - hspi->pRxBuffPtr += sizeof(uint16_t); -#if defined (__GNUC__) - *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; -#else - *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); -#endif /* __GNUC__ */ - hspi->pRxBuffPtr += sizeof(uint16_t); - hspi->RxXferCount -= (uint16_t)2UL; - } - /* Check RXPLVL flags when RXWNE cannot be reached */ - else if ((hspi->RxXferCount == 1UL) && ((temp_sr_reg & SPI_SR_RXPLVL_0) != 0UL)) - { -#if defined (__GNUC__) - *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; -#else - *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); -#endif /* __GNUC__ */ - hspi->pRxBuffPtr += sizeof(uint16_t); - hspi->RxXferCount--; - } - else - { - /* Timeout management */ - if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) - { - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_TIMEOUT; - } - } - } - } - /* Receive data in 8 Bit mode */ - else - { - /* Transfer loop */ - while (hspi->RxXferCount > 0UL) - { - /* Evaluate state of SR register */ - temp_sr_reg = hspi->Instance->SR; - - /* Check the RXP flag */ - if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP)) - { - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - hspi->RxXferCount--; - } - /* Check RXWNE flag if RXP cannot be reached */ - else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL)) - { - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - hspi->RxXferCount -= (uint16_t)4UL; - } - /* Check RXPLVL flags when RXWNE cannot be reached */ - else if ((hspi->RxXferCount < 4UL) && ((temp_sr_reg & SPI_SR_RXPLVL_Msk) != 0UL)) - { - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - hspi->RxXferCount--; - } - else - { - /* Timeout management */ - if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) - { - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_TIMEOUT; - } - } - } - } - -#if (USE_SPI_CRC != 0UL) - if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) - { - /* Wait for crc data to be received */ - if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); - } - } -#endif /* USE_SPI_CRC */ - - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - - if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) - { - return HAL_ERROR; - } - else - { - return HAL_OK; - } -} - -/** - * @brief Transmit and Receive an amount of data in blocking mode. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pTxData: pointer to transmission data buffer - * @param pRxData: pointer to reception data buffer - * @param Size : amount of data to be sent and received - * @param Timeout: Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, - uint16_t Size, uint32_t Timeout) -{ -#if defined (__GNUC__) - __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR)); - __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR)); -#endif /* __GNUC__ */ - - uint32_t tickstart; - uint32_t fifo_length; - uint32_t temp_sr_reg; - uint16_t initial_TxXferCount; - uint16_t initial_RxXferCount; - uint16_t init_max_data_in_fifo; - init_max_data_in_fifo = (((uint16_t)(hspi->Init.FifoThreshold >> 5U) + 1U)); - - /* Check Direction parameter */ - assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - initial_TxXferCount = Size; - initial_RxXferCount = Size; - - if (hspi->State != HAL_SPI_STATE_READY) - { - return HAL_BUSY; - } - - if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Set the transaction information */ - hspi->State = HAL_SPI_STATE_BUSY_TX_RX; - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->pRxBuffPtr = (uint8_t *)pRxData; - hspi->RxXferCount = Size; - hspi->RxXferSize = Size; - hspi->pTxBuffPtr = (const uint8_t *)pTxData; - hspi->TxXferCount = Size; - hspi->TxXferSize = Size; - - /*Init field not used in handle to zero */ - hspi->RxISR = NULL; - hspi->TxISR = NULL; - - /* Set Full-Duplex mode */ - SPI_2LINES(hspi); - - /* Initialize FIFO length */ - if (IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) - { - fifo_length = SPI_HIGHEND_FIFO_SIZE; - } - else - { - fifo_length = SPI_LOWEND_FIFO_SIZE; - } - - /* Set the number of data at current transfer */ - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); - - __HAL_SPI_ENABLE(hspi); - - if (hspi->Init.Mode == SPI_MODE_MASTER) - { - /* Master transfer start */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); - } - - /* Transmit and Receive data in 32 Bit mode */ - if (hspi->Init.DataSize > SPI_DATASIZE_16BIT) - { - /* Adapt fifo length to 32bits data width */ - fifo_length = (fifo_length / 4UL); - - while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL)) - { - /* Check TXP flag */ - if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) && - (initial_RxXferCount < (initial_TxXferCount + fifo_length))) - { - *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); - hspi->pTxBuffPtr += sizeof(uint32_t); - hspi->TxXferCount --; - initial_TxXferCount = hspi->TxXferCount; - } - - /* Evaluate state of SR register */ - temp_sr_reg = hspi->Instance->SR; - - if (initial_RxXferCount > 0UL) - { - /* Check the RXP flag */ - if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP)) - { - *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint32_t); - hspi->RxXferCount--; - initial_RxXferCount = hspi->RxXferCount; - } - /* Check RXWNE flag if RXP cannot be reached */ - else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL)) - { - *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint32_t); - hspi->RxXferCount--; - initial_RxXferCount = hspi->RxXferCount; - } - else - { - /* Timeout management */ - if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) - { - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_TIMEOUT; - } - } - } - } - } - /* Transmit and Receive data in 16 Bit mode */ - else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) - { - /* Adapt fifo length to 16bits data width */ - fifo_length = (fifo_length / 2UL); - - while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL)) - { - /* Check the TXP flag */ - if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) && - (initial_RxXferCount < (initial_TxXferCount + fifo_length))) - { -#if defined (__GNUC__) - *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr); -#else - *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr); -#endif /* __GNUC__ */ - hspi->pTxBuffPtr += sizeof(uint16_t); - hspi->TxXferCount--; - initial_TxXferCount = hspi->TxXferCount; - } - - /* Evaluate state of SR register */ - temp_sr_reg = hspi->Instance->SR; - - if (initial_RxXferCount > 0UL) - { - /* Check the RXP flag */ - if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP)) - { -#if defined (__GNUC__) - *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; -#else - *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); -#endif /* __GNUC__ */ - hspi->pRxBuffPtr += sizeof(uint16_t); - hspi->RxXferCount--; - initial_RxXferCount = hspi->RxXferCount; - } - /* Check RXWNE flag if RXP cannot be reached */ - else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL)) - { -#if defined (__GNUC__) - *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; -#else - *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); -#endif /* __GNUC__ */ - hspi->pRxBuffPtr += sizeof(uint16_t); -#if defined (__GNUC__) - *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; -#else - *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); -#endif /* __GNUC__ */ - hspi->pRxBuffPtr += sizeof(uint16_t); - hspi->RxXferCount -= (uint16_t)2UL; - initial_RxXferCount = hspi->RxXferCount; - } - /* Check RXPLVL flags when RXWNE cannot be reached */ - else if ((initial_RxXferCount == 1UL) && ((temp_sr_reg & SPI_SR_RXPLVL_0) != 0UL)) - { -#if defined (__GNUC__) - *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; -#else - *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); -#endif /* __GNUC__ */ - hspi->pRxBuffPtr += sizeof(uint16_t); - hspi->RxXferCount--; - initial_RxXferCount = hspi->RxXferCount; - } - else - { - /* Timeout management */ - if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) - { - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_TIMEOUT; - } - } - } - } - } - /* Transmit and Receive data in 8 Bit mode */ - else - { - while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL)) - { - /* Check the TXP flag */ - if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) && - (initial_RxXferCount < (initial_TxXferCount + fifo_length))) - { - *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr); - hspi->pTxBuffPtr += sizeof(uint8_t); - hspi->TxXferCount--; - initial_TxXferCount = hspi->TxXferCount; - } - - /* Evaluate state of SR register */ - temp_sr_reg = hspi->Instance->SR; - - if (initial_RxXferCount > 0UL) - { - /* Check the RXP flag */ - if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP)) - { - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - hspi->RxXferCount--; - initial_RxXferCount = hspi->RxXferCount; - } - /* Check RXWNE flag if RXP cannot be reached */ - else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL)) - { - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - hspi->RxXferCount -= (uint16_t)4UL; - initial_RxXferCount = hspi->RxXferCount; - } - /* Check RXPLVL flags when RXWNE cannot be reached */ - else if ((initial_RxXferCount < 4UL) && ((temp_sr_reg & SPI_SR_RXPLVL_Msk) != 0UL)) - { - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - hspi->RxXferCount--; - initial_RxXferCount = hspi->RxXferCount; - } - else - { - /* Timeout management */ - if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) - { - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_TIMEOUT; - } - } - } - } - } - - /* Wait for Tx/Rx (and CRC) data to be sent/received */ - if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); - } - - /* Call standard close procedure with error check */ - SPI_CloseTransfer(hspi); - - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) - { - return HAL_ERROR; - } - else - { - return HAL_OK; - } -} - -/** - * @brief Transmit an amount of data in non-blocking mode with Interrupt. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size : amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size) -{ - /* Check Direction parameter */ - assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction)); - - if ((pData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - if (hspi->State != HAL_SPI_STATE_READY) - { - return HAL_BUSY; - } - - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Set the transaction information */ - hspi->State = HAL_SPI_STATE_BUSY_TX; - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->pTxBuffPtr = (const uint8_t *)pData; - hspi->TxXferSize = Size; - hspi->TxXferCount = Size; - - /* Init field not used in handle to zero */ - hspi->pRxBuffPtr = NULL; - hspi->RxXferSize = (uint16_t) 0UL; - hspi->RxXferCount = (uint16_t) 0UL; - hspi->RxISR = NULL; - -#if defined(USE_SPI_RELOAD_TRANSFER) - hspi->Reload.Requested = 0UL; - hspi->Reload.pTxBuffPtr = NULL; - hspi->Reload.TxXferSize = NULL; -#endif /* USE_SPI_RELOAD_TRANSFER */ - - /* Set the function for IT treatment */ - if (hspi->Init.DataSize > SPI_DATASIZE_16BIT) - { - hspi->TxISR = SPI_TxISR_32BIT; - } - else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) - { - hspi->TxISR = SPI_TxISR_16BIT; - } - else - { - hspi->TxISR = SPI_TxISR_8BIT; - } - - /* Configure communication direction : 1Line */ - if (hspi->Init.Direction == SPI_DIRECTION_1LINE) - { - SPI_1LINE_TX(hspi); - } - else - { - SPI_2LINES_TX(hspi); - } - - /* Set the number of data at current transfer */ - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); - - /* Enable SPI peripheral */ - __HAL_SPI_ENABLE(hspi); - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - /* Enable EOT, TXP, FRE, MODF, UDR and TSERF interrupts */ - __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF | SPI_IT_TSERF)); - - if (hspi->Init.Mode == SPI_MODE_MASTER) - { - /* Master transfer start */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); - } - - return HAL_OK; -} - -/** - * @brief Receive an amount of data in non-blocking mode with Interrupt. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size : amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) -{ - /* Check Direction parameter */ - assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction)); - - if (hspi->State != HAL_SPI_STATE_READY) - { - return HAL_BUSY; - } - - if ((pData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Set the transaction information */ - hspi->State = HAL_SPI_STATE_BUSY_RX; - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->pRxBuffPtr = (uint8_t *)pData; - hspi->RxXferSize = Size; - hspi->RxXferCount = Size; - - /* Init field not used in handle to zero */ - hspi->pTxBuffPtr = NULL; - hspi->TxXferSize = (uint16_t) 0UL; - hspi->TxXferCount = (uint16_t) 0UL; - hspi->TxISR = NULL; - -#if defined(USE_SPI_RELOAD_TRANSFER) - hspi->Reload.Requested = 0UL; - hspi->Reload.pRxBuffPtr = NULL; - hspi->Reload.RxXferSize = NULL; -#endif /* USE_SPI_RELOAD_TRANSFER */ - - /* Set the function for IT treatment */ - if (hspi->Init.DataSize > SPI_DATASIZE_16BIT) - { - hspi->RxISR = SPI_RxISR_32BIT; - } - else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) - { - hspi->RxISR = SPI_RxISR_16BIT; - } - else - { - hspi->RxISR = SPI_RxISR_8BIT; - } - - /* Configure communication direction : 1Line */ - if (hspi->Init.Direction == SPI_DIRECTION_1LINE) - { - SPI_1LINE_RX(hspi); - } - else - { - SPI_2LINES_RX(hspi); - } - - /* Note : The SPI must be enabled after unlocking current process - to avoid the risk of SPI interrupt handle execution before current - process unlock */ - - /* Set the number of data at current transfer */ - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); - - /* Enable SPI peripheral */ - __HAL_SPI_ENABLE(hspi); - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - /* Enable EOT, RXP, OVR, FRE, MODF and TSERF interrupts */ - __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_RXP | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF | SPI_IT_TSERF)); - - if (hspi->Init.Mode == SPI_MODE_MASTER) - { - /* Master transfer start */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); - } - - return HAL_OK; -} - -/** - * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pTxData: pointer to transmission data buffer - * @param pRxData: pointer to reception data buffer - * @param Size : amount of data to be sent and received - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, - uint16_t Size) -{ - uint32_t tmp_TxXferCount; -#if defined (__GNUC__) - __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR)); -#endif /* __GNUC__ */ - - /* Check Direction parameter */ - assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); - - if (hspi->State != HAL_SPI_STATE_READY) - { - return HAL_BUSY; - } - - if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Set the transaction information */ - hspi->State = HAL_SPI_STATE_BUSY_TX_RX; - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->pTxBuffPtr = (const uint8_t *)pTxData; - hspi->TxXferSize = Size; - hspi->TxXferCount = Size; - hspi->pRxBuffPtr = (uint8_t *)pRxData; - hspi->RxXferSize = Size; - hspi->RxXferCount = Size; - tmp_TxXferCount = hspi->TxXferCount; - -#if defined(USE_SPI_RELOAD_TRANSFER) - hspi->Reload.Requested = 0UL; - hspi->Reload.pRxBuffPtr = NULL; - hspi->Reload.RxXferSize = NULL; - hspi->Reload.pTxBuffPtr = NULL; - hspi->Reload.TxXferSize = NULL; -#endif /* USE_SPI_RELOAD_TRANSFER */ - - /* Set the function for IT treatment */ - if (hspi->Init.DataSize > SPI_DATASIZE_16BIT) - { - hspi->TxISR = SPI_TxISR_32BIT; - hspi->RxISR = SPI_RxISR_32BIT; - } - else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) - { - hspi->RxISR = SPI_RxISR_16BIT; - hspi->TxISR = SPI_TxISR_16BIT; - } - else - { - hspi->RxISR = SPI_RxISR_8BIT; - hspi->TxISR = SPI_TxISR_8BIT; - } - - /* Set Full-Duplex mode */ - SPI_2LINES(hspi); - - /* Set the number of data at current transfer */ - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); - - /* Enable SPI peripheral */ - __HAL_SPI_ENABLE(hspi); - - /* Fill in the TxFIFO */ - while ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (tmp_TxXferCount != 0UL)) - { - /* Transmit data in 32 Bit mode */ - if (hspi->Init.DataSize > SPI_DATASIZE_16BIT) - { - *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); - hspi->pTxBuffPtr += sizeof(uint32_t); - hspi->TxXferCount--; - tmp_TxXferCount = hspi->TxXferCount; - } - /* Transmit data in 16 Bit mode */ - else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) - { -#if defined (__GNUC__) - *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr); -#else - *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr); -#endif /* __GNUC__ */ - hspi->pTxBuffPtr += sizeof(uint16_t); - hspi->TxXferCount--; - tmp_TxXferCount = hspi->TxXferCount; - } - /* Transmit data in 8 Bit mode */ - else - { - *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr); - hspi->pTxBuffPtr += sizeof(uint8_t); - hspi->TxXferCount--; - tmp_TxXferCount = hspi->TxXferCount; - } - } - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - /* Enable EOT, DXP, UDR, OVR, FRE, MODF and TSERF interrupts */ - __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | - SPI_IT_FRE | SPI_IT_MODF | SPI_IT_TSERF)); - - if (hspi->Init.Mode == SPI_MODE_MASTER) - { - /* Start Master transfer */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); - } - - return HAL_OK; -} - -#if defined(USE_SPI_RELOAD_TRANSFER) -/** - * @brief Transmit an additional amount of data in blocking mode. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size : amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Reload_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size) -{ - /* check if there is already a request to reload */ - if ((hspi->Reload.Requested == 1UL) || (pData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - if (hspi->State == HAL_SPI_STATE_BUSY_TX) - { - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Insert the new number of data to be sent just after the current one */ - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSER, (Size & 0xFFFFFFFFUL) << 16UL); - - /* Set the transaction information */ - hspi->Reload.Requested = 1UL; - hspi->Reload.pTxBuffPtr = (const uint8_t *)pData; - hspi->Reload.TxXferSize = Size; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} -#endif /* USE_SPI_RELOAD_TRANSFER */ - -#if defined(USE_SPI_RELOAD_TRANSFER) -/** - * @brief Receive an additional amount of data in blocking mode. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size : amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Reload_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) -{ - /* check if there is already a request to reload */ - if ((hspi->Reload.Requested == 1UL) || (pData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - if (hspi->State == HAL_SPI_STATE_BUSY_RX) - { - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Insert the new number of data that will be received just after the current one */ - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSER, (Size & 0xFFFFFFFFUL) << 16UL); - - /* Set the transaction information */ - hspi->Reload.Requested = 1UL; - hspi->Reload.pRxBuffPtr = (uint8_t *)pData; - hspi->Reload.RxXferSize = Size; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} -#endif /* USE_SPI_RELOAD_TRANSFER */ - -#if defined(USE_SPI_RELOAD_TRANSFER) -/** - * @brief Transmit and receive an additional amount of data in blocking mode. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pTxData: pointer to transmission data buffer - * @param pRxData: pointer to reception data buffer - * @param Size : amount of data to be sent and received - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Reload_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, - uint8_t *pRxData, uint16_t Size) -{ - /* check if there is already a request to reload */ - if ((hspi->Reload.Requested == 1UL) || (pTxData == NULL) || (pRxData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - if (hspi->State == HAL_SPI_STATE_BUSY_TX_RX) - { - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Insert the new number of data that will be sent and received just after the current one */ - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSER, (Size & 0xFFFFFFFFUL) << 16UL); - - /* Set the transaction information */ - hspi->Reload.Requested = 1UL; - hspi->Reload.pTxBuffPtr = (const uint8_t *)pTxData; - hspi->Reload.TxXferSize = Size; - hspi->Reload.pRxBuffPtr = (uint8_t *)pRxData; - hspi->Reload.RxXferSize = Size; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_OK; - } - else - { - return HAL_ERROR; - } -} -#endif /* USE_SPI_RELOAD_TRANSFER */ - -/** - * @brief Transmit an amount of data in non-blocking mode with DMA. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size : amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size) -{ - - /* Check Direction parameter */ - assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction)); - - if (hspi->State != HAL_SPI_STATE_READY) - { - return HAL_BUSY; - } - - if ((pData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Set the transaction information */ - hspi->State = HAL_SPI_STATE_BUSY_TX; - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->pTxBuffPtr = (const uint8_t *)pData; - hspi->TxXferSize = Size; - hspi->TxXferCount = Size; - - /* Init field not used in handle to zero */ - hspi->pRxBuffPtr = NULL; - hspi->TxISR = NULL; - hspi->RxISR = NULL; - hspi->RxXferSize = (uint16_t)0UL; - hspi->RxXferCount = (uint16_t)0UL; - - /* Configure communication direction : 1Line */ - if (hspi->Init.Direction == SPI_DIRECTION_1LINE) - { - SPI_1LINE_TX(hspi); - } - else - { - SPI_2LINES_TX(hspi); - } - - /* Packing mode management is enabled by the DMA settings */ - if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)) || \ - ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && ((hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \ - (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)))) - { - /* Restriction the DMA data received is not allowed in this mode */ - __HAL_UNLOCK(hspi); - return HAL_ERROR; - } - - /* Adjust XferCount according to DMA alignment / Data size */ - if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) - { - if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) - { - hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL; - } - if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD) - { - hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 3UL) >> 2UL; - } - } - else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT) - { - if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD) - { - hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL; - } - } - else - { - /* Adjustment done */ - } - - /* Set the SPI TxDMA Half transfer complete callback */ - hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt; - - /* Set the SPI TxDMA transfer complete callback */ - hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt; - - /* Set the DMA error callback */ - hspi->hdmatx->XferErrorCallback = SPI_DMAError; - - /* Set the DMA AbortCpltCallback */ - hspi->hdmatx->XferAbortCallback = NULL; - - /* Clear TXDMAEN bit*/ - CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN); - - /* Enable the Tx DMA Stream/Channel */ - if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->TXDR, - hspi->TxXferCount)) - { - /* Update SPI error code */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_ERROR; - } - - /* Set the number of data at current transfer */ - if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR) - { - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL); - } - else - { - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); - } - - /* Enable Tx DMA Request */ - SET_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN); - - /* Enable the SPI Error Interrupt Bit */ - __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF)); - - /* Enable SPI peripheral */ - __HAL_SPI_ENABLE(hspi); - - if (hspi->Init.Mode == SPI_MODE_MASTER) - { - /* Master transfer start */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); - } - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_OK; -} - -/** - * @brief Receive an amount of data in non-blocking mode with DMA. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size : amount of data to be sent - * @note When the CRC feature is enabled the pData Length must be Size + 1. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) -{ - - /* Check Direction parameter */ - assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction)); - - if (hspi->State != HAL_SPI_STATE_READY) - { - __HAL_UNLOCK(hspi); - return HAL_BUSY; - } - - if ((pData == NULL) || (Size == 0UL)) - { - __HAL_UNLOCK(hspi); - return HAL_ERROR; - } - - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Set the transaction information */ - hspi->State = HAL_SPI_STATE_BUSY_RX; - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->pRxBuffPtr = (uint8_t *)pData; - hspi->RxXferSize = Size; - hspi->RxXferCount = Size; - - /*Init field not used in handle to zero */ - hspi->RxISR = NULL; - hspi->TxISR = NULL; - hspi->TxXferSize = (uint16_t) 0UL; - hspi->TxXferCount = (uint16_t) 0UL; - - /* Configure communication direction : 1Line */ - if (hspi->Init.Direction == SPI_DIRECTION_1LINE) - { - SPI_1LINE_RX(hspi); - } - else - { - SPI_2LINES_RX(hspi); - } - - /* Packing mode management is enabled by the DMA settings */ - if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)) || \ - ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && ((hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \ - (hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)))) - { - /* Restriction the DMA data received is not allowed in this mode */ - __HAL_UNLOCK(hspi); - return HAL_ERROR; - } - - /* Clear RXDMAEN bit */ - CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN); - - /* Adjust XferCount according to DMA alignment / Data size */ - if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) - { - if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) - { - hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL; - } - if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD) - { - hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 3UL) >> 2UL; - } - } - else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT) - { - if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD) - { - hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL; - } - } - else - { - /* Adjustment done */ - } - - /* Set the SPI RxDMA Half transfer complete callback */ - hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt; - - /* Set the SPI Rx DMA transfer complete callback */ - hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt; - - /* Set the DMA error callback */ - hspi->hdmarx->XferErrorCallback = SPI_DMAError; - - /* Set the DMA AbortCpltCallback */ - hspi->hdmarx->XferAbortCallback = NULL; - - /* Enable the Rx DMA Stream/Channel */ - if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->RXDR, (uint32_t)hspi->pRxBuffPtr, - hspi->RxXferCount)) - { - /* Update SPI error code */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_ERROR; - } - - /* Set the number of data at current transfer */ - if (hspi->hdmarx->Init.Mode == DMA_CIRCULAR) - { - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL); - } - else - { - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); - } - - /* Enable Rx DMA Request */ - SET_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN); - - /* Enable the SPI Error Interrupt Bit */ - __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF)); - - /* Enable SPI peripheral */ - __HAL_SPI_ENABLE(hspi); - - if (hspi->Init.Mode == SPI_MODE_MASTER) - { - /* Master transfer start */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); - } - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_OK; -} - -/** - * @brief Transmit and Receive an amount of data in non-blocking mode with DMA. - * @param hspi : pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param pTxData: pointer to transmission data buffer - * @param pRxData: pointer to reception data buffer - * @param Size : amount of data to be sent - * @note When the CRC feature is enabled the pRxData Length must be Size + 1 - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData, - uint16_t Size) -{ - /* Check Direction parameter */ - assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); - - if (hspi->State != HAL_SPI_STATE_READY) - { - return HAL_BUSY; - } - - if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL)) - { - return HAL_ERROR; - } - - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Set the transaction information */ - hspi->State = HAL_SPI_STATE_BUSY_TX_RX; - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - hspi->pTxBuffPtr = (const uint8_t *)pTxData; - hspi->TxXferSize = Size; - hspi->TxXferCount = Size; - hspi->pRxBuffPtr = (uint8_t *)pRxData; - hspi->RxXferSize = Size; - hspi->RxXferCount = Size; - - /* Init field not used in handle to zero */ - hspi->RxISR = NULL; - hspi->TxISR = NULL; - - /* Set Full-Duplex mode */ - SPI_2LINES(hspi); - - /* Reset the Tx/Rx DMA bits */ - CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN); - - /* Packing mode management is enabled by the DMA settings */ - if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && \ - ((hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD) || \ - (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD))) || \ - ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && \ - (((hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \ - (hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)) || \ - ((hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \ - (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD))))) - { - /* Restriction the DMA data received is not allowed in this mode */ - /* Unlock the process */ - __HAL_UNLOCK(hspi); - return HAL_ERROR; - } - - /* Adjust XferCount according to DMA alignment / Data size */ - if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT) - { - if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) - { - hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL; - } - if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD) - { - hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 3UL) >> 2UL; - } - if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) - { - hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL; - } - if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD) - { - hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 3UL) >> 2UL; - } - } - else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT) - { - if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD) - { - hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL; - } - if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD) - { - hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL; - } - } - else - { - /* Adjustment done */ - } - - /* Set the SPI Tx/Rx DMA Half transfer complete callback */ - hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt; - hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt; - - /* Set the DMA error callback */ - hspi->hdmarx->XferErrorCallback = SPI_DMAError; - - /* Set the DMA AbortCallback */ - hspi->hdmarx->XferAbortCallback = NULL; - - /* Enable the Rx DMA Stream/Channel */ - if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->RXDR, (uint32_t)hspi->pRxBuffPtr, - hspi->RxXferCount)) - { - /* Update SPI error code */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_ERROR; - } - - /* Enable Rx DMA Request */ - SET_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN); - - /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing - is performed in DMA reception complete callback */ - hspi->hdmatx->XferHalfCpltCallback = NULL; - hspi->hdmatx->XferCpltCallback = NULL; - hspi->hdmatx->XferAbortCallback = NULL; - - /* Set the DMA error callback */ - hspi->hdmatx->XferErrorCallback = SPI_DMAError; - - /* Enable the Tx DMA Stream/Channel */ - if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->TXDR, - hspi->TxXferCount)) - { - /* Abort Rx DMA Channel already started */ - (void)HAL_DMA_Abort(hspi->hdmarx); - - /* Update SPI error code */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_ERROR; - } - - if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR) - { - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL); - } - else - { - MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size); - } - - /* Enable Tx DMA Request */ - SET_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN); - - /* Enable the SPI Error Interrupt Bit */ - __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_OVR | SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF)); - - /* Enable SPI peripheral */ - __HAL_SPI_ENABLE(hspi); - - if (hspi->Init.Mode == SPI_MODE_MASTER) - { - /* Master transfer start */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART); - } - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return HAL_OK; -} - -/** - * @brief Abort ongoing transfer (blocking mode). - * @param hspi SPI handle. - * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), - * started in Interrupt or DMA mode. - * @note This procedure performs following operations : - * + Disable SPI Interrupts (depending of transfer direction) - * + Disable the DMA transfer in the peripheral register (if enabled) - * + Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) - * + Set handle State to READY. - * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi) -{ - HAL_StatusTypeDef errorcode; - - __IO uint32_t count; - - /* Lock the process */ - __HAL_LOCK(hspi); - - /* Set hspi->state to aborting to avoid any interaction */ - hspi->State = HAL_SPI_STATE_ABORT; - - /* Initialized local variable */ - errorcode = HAL_OK; - count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24UL / 1000UL); - - /* If master communication on going, make sure current frame is done before closing the connection */ - if (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART)) - { - /* Disable EOT interrupt */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT); - do - { - count--; - if (count == 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); - break; - } - } while (HAL_IS_BIT_SET(hspi->Instance->IER, SPI_IT_EOT)); - - /* Request a Suspend transfer */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP); - do - { - count--; - if (count == 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); - break; - } - } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART)); - - /* Clear SUSP flag */ - __HAL_SPI_CLEAR_SUSPFLAG(hspi); - do - { - count--; - if (count == 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); - break; - } - } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_SUSP)); - } - - /* Disable the SPI DMA Tx request if enabled */ - if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN)) - { - if (hspi->hdmatx != NULL) - { - /* Abort the SPI DMA Tx Stream/Channel : use blocking DMA Abort API (no callback) */ - hspi->hdmatx->XferAbortCallback = NULL; - - /* Abort DMA Tx Handle linked to SPI Peripheral */ - if (HAL_DMA_Abort(hspi->hdmatx) != HAL_OK) - { - if (HAL_DMA_GetError(hspi->hdmatx) == HAL_DMA_ERROR_TIMEOUT) - { - hspi->ErrorCode = HAL_SPI_ERROR_ABORT; - } - } - } - } - - /* Disable the SPI DMA Rx request if enabled */ - if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN)) - { - if (hspi->hdmarx != NULL) - { - /* Abort the SPI DMA Rx Stream/Channel : use blocking DMA Abort API (no callback) */ - hspi->hdmarx->XferAbortCallback = NULL; - - /* Abort DMA Rx Handle linked to SPI Peripheral */ - if (HAL_DMA_Abort(hspi->hdmarx) != HAL_OK) - { - if (HAL_DMA_GetError(hspi->hdmarx) == HAL_DMA_ERROR_TIMEOUT) - { - hspi->ErrorCode = HAL_SPI_ERROR_ABORT; - } - } - } - } - - /* Proceed with abort procedure */ - SPI_AbortTransfer(hspi); - - /* Check error during Abort procedure */ - if (HAL_IS_BIT_SET(hspi->ErrorCode, HAL_SPI_ERROR_ABORT)) - { - /* return HAL_Error in case of error during Abort procedure */ - errorcode = HAL_ERROR; - } - else - { - /* Reset errorCode */ - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - } - - /* Restore hspi->state to ready */ - hspi->State = HAL_SPI_STATE_READY; - - /* Unlock the process */ - __HAL_UNLOCK(hspi); - - return errorcode; -} - -/** - * @brief Abort ongoing transfer (Interrupt mode). - * @param hspi SPI handle. - * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), - * started in Interrupt or DMA mode. - * @note This procedure performs following operations : - * + Disable SPI Interrupts (depending of transfer direction) - * + Disable the DMA transfer in the peripheral register (if enabled) - * + Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) - * + Set handle State to READY - * + At abort completion, call user abort complete callback. - * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be - * considered as completed only when user abort complete callback is executed (not when exiting function). - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi) -{ - HAL_StatusTypeDef errorcode; - __IO uint32_t count; - uint32_t dma_tx_abort_done = 1UL; - uint32_t dma_rx_abort_done = 1UL; - - /* Set hspi->state to aborting to avoid any interaction */ - hspi->State = HAL_SPI_STATE_ABORT; - - /* Initialized local variable */ - errorcode = HAL_OK; - count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24UL / 1000UL); - - /* If master communication on going, make sure current frame is done before closing the connection */ - if (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART)) - { - /* Disable EOT interrupt */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT); - do - { - count--; - if (count == 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); - break; - } - } while (HAL_IS_BIT_SET(hspi->Instance->IER, SPI_IT_EOT)); - - /* Request a Suspend transfer */ - SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP); - do - { - count--; - if (count == 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); - break; - } - } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART)); - - /* Clear SUSP flag */ - __HAL_SPI_CLEAR_SUSPFLAG(hspi); - do - { - count--; - if (count == 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); - break; - } - } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_SUSP)); - } - - /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialized - before any call to DMA Abort functions */ - - if (hspi->hdmatx != NULL) - { - if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN)) - { - /* Set DMA Abort Complete callback if SPI DMA Tx request if enabled */ - hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback; - - dma_tx_abort_done = 0UL; - - /* Abort DMA Tx Handle linked to SPI Peripheral */ - if (HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK) - { - if (HAL_DMA_GetError(hspi->hdmatx) == HAL_DMA_ERROR_NO_XFER) - { - dma_tx_abort_done = 1UL; - hspi->hdmatx->XferAbortCallback = NULL; - } - } - } - else - { - hspi->hdmatx->XferAbortCallback = NULL; - } - } - - if (hspi->hdmarx != NULL) - { - if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN)) - { - /* Set DMA Abort Complete callback if SPI DMA Rx request if enabled */ - hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback; - - dma_rx_abort_done = 0UL; - - /* Abort DMA Rx Handle linked to SPI Peripheral */ - if (HAL_DMA_Abort_IT(hspi->hdmarx) != HAL_OK) - { - if (HAL_DMA_GetError(hspi->hdmarx) == HAL_DMA_ERROR_NO_XFER) - { - dma_rx_abort_done = 1UL; - hspi->hdmarx->XferAbortCallback = NULL; - } - } - } - else - { - hspi->hdmarx->XferAbortCallback = NULL; - } - } - - /* If no running DMA transfer, finish cleanup and call callbacks */ - if ((dma_tx_abort_done == 1UL) && (dma_rx_abort_done == 1UL)) - { - /* Proceed with abort procedure */ - SPI_AbortTransfer(hspi); - - /* Check error during Abort procedure */ - if (HAL_IS_BIT_SET(hspi->ErrorCode, HAL_SPI_ERROR_ABORT)) - { - /* return HAL_Error in case of error during Abort procedure */ - errorcode = HAL_ERROR; - } - else - { - /* Reset errorCode */ - hspi->ErrorCode = HAL_SPI_ERROR_NONE; - } - - /* Restore hspi->state to ready */ - hspi->State = HAL_SPI_STATE_READY; - - /* Call user Abort complete callback */ -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->AbortCpltCallback(hspi); -#else - HAL_SPI_AbortCpltCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - } - - return errorcode; -} - -/** - * @brief Pause the DMA Transfer. - * This API is not supported, it is maintained for backward compatibility. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for the specified SPI module. - * @retval HAL_ERROR - */ -HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi) -{ - /* Set error code to not supported */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED); - - return HAL_ERROR; -} - -/** - * @brief Resume the DMA Transfer. - * This API is not supported, it is maintained for backward compatibility. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for the specified SPI module. - * @retval HAL_ERROR - */ -HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi) -{ - /* Set error code to not supported */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED); - - return HAL_ERROR; -} - -/** - * @brief Stop the DMA Transfer. - * This API is not supported, it is maintained for backward compatibility. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for the specified SPI module. - * @retval HAL_ERROR - */ -HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi) -{ - /* Set error code to not supported */ - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED); - - return HAL_ERROR; -} - -/** - * @brief Handle SPI interrupt request. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for the specified SPI module. - * @retval None - */ -void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi) -{ - uint32_t itsource = hspi->Instance->IER; - uint32_t itflag = hspi->Instance->SR; - uint32_t trigger = itsource & itflag; - uint32_t cfg1 = hspi->Instance->CFG1; - uint32_t handled = 0UL; - - HAL_SPI_StateTypeDef State = hspi->State; -#if defined (__GNUC__) - __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR)); -#endif /* __GNUC__ */ - - /* SPI in SUSPEND mode ----------------------------------------------------*/ - if (HAL_IS_BIT_SET(itflag, SPI_FLAG_SUSP) && HAL_IS_BIT_SET(itsource, SPI_FLAG_EOT)) - { - /* Clear the Suspend flag */ - __HAL_SPI_CLEAR_SUSPFLAG(hspi); - - /* Suspend on going, Call the Suspend callback */ -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->SuspendCallback(hspi); -#else - HAL_SPI_SuspendCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - return; - } - - /* SPI in mode Transmitter and Receiver ------------------------------------*/ - if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_OVR) && HAL_IS_BIT_CLR(trigger, SPI_FLAG_UDR) && \ - HAL_IS_BIT_SET(trigger, SPI_FLAG_DXP)) - { - hspi->TxISR(hspi); - hspi->RxISR(hspi); - handled = 1UL; - } - - /* SPI in mode Receiver ----------------------------------------------------*/ - if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_OVR) && HAL_IS_BIT_SET(trigger, SPI_FLAG_RXP) && \ - HAL_IS_BIT_CLR(trigger, SPI_FLAG_DXP)) - { - hspi->RxISR(hspi); - handled = 1UL; - } - - /* SPI in mode Transmitter -------------------------------------------------*/ - if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_UDR) && HAL_IS_BIT_SET(trigger, SPI_FLAG_TXP) && \ - HAL_IS_BIT_CLR(trigger, SPI_FLAG_DXP)) - { - hspi->TxISR(hspi); - handled = 1UL; - } - -#if defined(USE_SPI_RELOAD_TRANSFER) - /* SPI Reload -------------------------------------------------*/ - if (HAL_IS_BIT_SET(trigger, SPI_FLAG_TSERF)) - { - __HAL_SPI_CLEAR_TSERFFLAG(hspi); - } -#endif /* USE_SPI_RELOAD_TRANSFER */ - - if (handled != 0UL) - { - return; - } - - /* SPI End Of Transfer: DMA or IT based transfer */ - if (HAL_IS_BIT_SET(trigger, SPI_FLAG_EOT)) - { - /* Clear EOT/TXTF/SUSP flag */ - __HAL_SPI_CLEAR_EOTFLAG(hspi); - __HAL_SPI_CLEAR_TXTFFLAG(hspi); - __HAL_SPI_CLEAR_SUSPFLAG(hspi); - - /* Disable EOT interrupt */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT); - - /* For the IT based receive extra polling maybe required for last packet */ - if (HAL_IS_BIT_CLR(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN)) - { - /* Pooling remaining data */ - while (hspi->RxXferCount != 0UL) - { - /* Receive data in 32 Bit mode */ - if (hspi->Init.DataSize > SPI_DATASIZE_16BIT) - { - *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint32_t); - } - /* Receive data in 16 Bit mode */ - else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) - { -#if defined (__GNUC__) - *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; -#else - *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR); -#endif /* __GNUC__ */ - hspi->pRxBuffPtr += sizeof(uint16_t); - } - /* Receive data in 8 Bit mode */ - else - { - *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - } - - hspi->RxXferCount--; - } - } - - /* Call SPI Standard close procedure */ - SPI_CloseTransfer(hspi); - - hspi->State = HAL_SPI_STATE_READY; - if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) - { -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->ErrorCallback(hspi); -#else - HAL_SPI_ErrorCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - return; - } - -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - /* Call appropriate user callback */ - if (State == HAL_SPI_STATE_BUSY_TX_RX) - { - hspi->TxRxCpltCallback(hspi); - } - else if (State == HAL_SPI_STATE_BUSY_RX) - { - hspi->RxCpltCallback(hspi); - } - else if (State == HAL_SPI_STATE_BUSY_TX) - { - hspi->TxCpltCallback(hspi); - } -#else - /* Call appropriate user callback */ - if (State == HAL_SPI_STATE_BUSY_TX_RX) - { - HAL_SPI_TxRxCpltCallback(hspi); - } - else if (State == HAL_SPI_STATE_BUSY_RX) - { - HAL_SPI_RxCpltCallback(hspi); - } - else if (State == HAL_SPI_STATE_BUSY_TX) - { - HAL_SPI_TxCpltCallback(hspi); - } -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - else - { - /* End of the appropriate call */ - } - - return; - } - - /* SPI in Error Treatment --------------------------------------------------*/ - if ((trigger & (SPI_FLAG_MODF | SPI_FLAG_OVR | SPI_FLAG_FRE | SPI_FLAG_UDR)) != 0UL) - { - /* SPI Overrun error interrupt occurred ----------------------------------*/ - if ((trigger & SPI_FLAG_OVR) != 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR); - __HAL_SPI_CLEAR_OVRFLAG(hspi); - } - - /* SPI Mode Fault error interrupt occurred -------------------------------*/ - if ((trigger & SPI_FLAG_MODF) != 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF); - __HAL_SPI_CLEAR_MODFFLAG(hspi); - } - - /* SPI Frame error interrupt occurred ------------------------------------*/ - if ((trigger & SPI_FLAG_FRE) != 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE); - __HAL_SPI_CLEAR_FREFLAG(hspi); - } - - /* SPI Underrun error interrupt occurred ------------------------------------*/ - if ((trigger & SPI_FLAG_UDR) != 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_UDR); - __HAL_SPI_CLEAR_UDRFLAG(hspi); - } - - if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) - { - /* Disable SPI peripheral */ - __HAL_SPI_DISABLE(hspi); - - /* Disable all interrupts */ - __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_RXP | SPI_IT_TXP | SPI_IT_MODF | - SPI_IT_OVR | SPI_IT_FRE | SPI_IT_UDR)); - - /* Disable the SPI DMA requests if enabled */ - if (HAL_IS_BIT_SET(cfg1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN)) - { - /* Disable the SPI DMA requests */ - CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN); - - /* Abort the SPI DMA Rx channel */ - if (hspi->hdmarx != NULL) - { - /* Set the SPI DMA Abort callback : - will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */ - hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError; - if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmarx)) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); - } - } - /* Abort the SPI DMA Tx channel */ - if (hspi->hdmatx != NULL) - { - /* Set the SPI DMA Abort callback : - will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */ - hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError; - if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmatx)) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); - } - } - } - else - { - /* Restore hspi->State to Ready */ - hspi->State = HAL_SPI_STATE_READY; - - /* Call user error callback */ -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->ErrorCallback(hspi); -#else - HAL_SPI_ErrorCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - } - } - return; - } -} - -/** - * @brief Tx Transfer completed callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_TxCpltCallback should be implemented in the user file - */ -} - -/** - * @brief Rx Transfer completed callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_RxCpltCallback should be implemented in the user file - */ -} - -/** - * @brief Tx and Rx Transfer completed callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -__weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_TxRxCpltCallback should be implemented in the user file - */ -} - -/** - * @brief Tx Half Transfer completed callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -__weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_TxHalfCpltCallback should be implemented in the user file - */ -} - -/** - * @brief Rx Half Transfer completed callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -__weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file - */ -} - -/** - * @brief Tx and Rx Half Transfer callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -__weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file - */ -} - -/** - * @brief SPI error callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_ErrorCallback should be implemented in the user file - */ - /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes - and user can use HAL_SPI_GetError() API to check the latest error occurred - */ -} - -/** - * @brief SPI Abort Complete callback. - * @param hspi SPI handle. - * @retval None - */ -__weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_AbortCpltCallback can be implemented in the user file. - */ -} - -/** - * @brief SPI Suspend callback. - * @param hspi SPI handle. - * @retval None - */ -__weak void HAL_SPI_SuspendCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */ -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hspi); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_SPI_SuspendCallback can be implemented in the user file. - */ -} - -/** - * @} - */ - -/** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions - * @brief SPI control functions - * -@verbatim - =============================================================================== - ##### Peripheral State and Errors functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to control the SPI. - (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral - (+) HAL_SPI_GetError() check in run-time Errors occurring during communication -@endverbatim - * @{ - */ - -/** - * @brief Return the SPI handle state. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval SPI state - */ -HAL_SPI_StateTypeDef HAL_SPI_GetState(const SPI_HandleTypeDef *hspi) -{ - /* Return SPI handle state */ - return hspi->State; -} - -/** - * @brief Return the SPI error code. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval SPI error code in bitmap format - */ -uint32_t HAL_SPI_GetError(const SPI_HandleTypeDef *hspi) -{ - /* Return SPI ErrorCode */ - return hspi->ErrorCode; -} - -/** - * @} - */ - -/** - * @} - */ - -/** @addtogroup SPI_Private_Functions - * @brief Private functions - * @{ - */ - -/** - * @brief DMA SPI transmit process complete callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains - * the configuration information for the specified DMA module. - * @retval None - */ -static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma) -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; - - if (hspi->State != HAL_SPI_STATE_ABORT) - { - if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR) - { -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->TxCpltCallback(hspi); -#else - HAL_SPI_TxCpltCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - } - else - { - /* Enable EOT interrupt */ - __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT); - } - } -} - -/** - * @brief DMA SPI receive process complete callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains - * the configuration information for the specified DMA module. - * @retval None - */ -static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma) -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; - - if (hspi->State != HAL_SPI_STATE_ABORT) - { - if (hspi->hdmarx->Init.Mode == DMA_CIRCULAR) - { -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->RxCpltCallback(hspi); -#else - HAL_SPI_RxCpltCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - } - else - { - /* Enable EOT interrupt */ - __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT); - } - } -} - -/** - * @brief DMA SPI transmit receive process complete callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains - * the configuration information for the specified DMA module. - * @retval None - */ -static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma) -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; - - if (hspi->State != HAL_SPI_STATE_ABORT) - { - if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR) - { -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->TxRxCpltCallback(hspi); -#else - HAL_SPI_TxRxCpltCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - } - else - { - /* Enable EOT interrupt */ - __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT); - } - } -} - -/** - * @brief DMA SPI half transmit process complete callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains - * the configuration information for the specified DMA module. - * @retval None - */ -static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */ -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *) - ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */ - -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->TxHalfCpltCallback(hspi); -#else - HAL_SPI_TxHalfCpltCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -} - -/** - * @brief DMA SPI half receive process complete callback - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains - * the configuration information for the specified DMA module. - * @retval None - */ -static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */ -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *) - ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */ - -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->RxHalfCpltCallback(hspi); -#else - HAL_SPI_RxHalfCpltCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -} - -/** - * @brief DMA SPI half transmit receive process complete callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains - * the configuration information for the specified DMA module. - * @retval None - */ -static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */ -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *) - ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */ - -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->TxRxHalfCpltCallback(hspi); -#else - HAL_SPI_TxRxHalfCpltCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -} - -/** - * @brief DMA SPI communication error callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains - * the configuration information for the specified DMA module. - * @retval None - */ -static void SPI_DMAError(DMA_HandleTypeDef *hdma) -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; - - /* if DMA error is FIFO error ignore it */ - if (HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE) - { - /* Call SPI standard close procedure */ - SPI_CloseTransfer(hspi); - - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); - hspi->State = HAL_SPI_STATE_READY; -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->ErrorCallback(hspi); -#else - HAL_SPI_ErrorCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ - } -} - -/** - * @brief DMA SPI communication abort callback, when initiated by HAL services on Error - * (To be called at end of DMA Abort procedure following error occurrence). - * @param hdma DMA handle. - * @retval None - */ -static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma) -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; - hspi->RxXferCount = (uint16_t) 0UL; - hspi->TxXferCount = (uint16_t) 0UL; - - /* Restore hspi->State to Ready */ - hspi->State = HAL_SPI_STATE_READY; - -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->ErrorCallback(hspi); -#else - HAL_SPI_ErrorCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -} - -/** - * @brief DMA SPI Tx communication abort callback, when initiated by user - * (To be called at end of DMA Tx Abort procedure following user abort request). - * @note When this callback is executed, User Abort complete call back is called only if no - * Abort still ongoing for Rx DMA Handle. - * @param hdma DMA handle. - * @retval None - */ -static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma) -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; - - hspi->hdmatx->XferAbortCallback = NULL; - - /* Check if an Abort process is still ongoing */ - if (hspi->hdmarx != NULL) - { - if (hspi->hdmarx->XferAbortCallback != NULL) - { - return; - } - } - - /* Call the Abort procedure */ - SPI_AbortTransfer(hspi); - - /* Restore hspi->State to Ready */ - hspi->State = HAL_SPI_STATE_READY; - - /* Call user Abort complete callback */ -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->AbortCpltCallback(hspi); -#else - HAL_SPI_AbortCpltCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -} - -/** - * @brief DMA SPI Rx communication abort callback, when initiated by user - * (To be called at end of DMA Rx Abort procedure following user abort request). - * @note When this callback is executed, User Abort complete call back is called only if no - * Abort still ongoing for Tx DMA Handle. - * @param hdma DMA handle. - * @retval None - */ -static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma) -{ - SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; - - hspi->hdmarx->XferAbortCallback = NULL; - - /* Check if an Abort process is still ongoing */ - if (hspi->hdmatx != NULL) - { - if (hspi->hdmatx->XferAbortCallback != NULL) - { - return; - } - } - - /* Call the Abort procedure */ - SPI_AbortTransfer(hspi); - - /* Restore hspi->State to Ready */ - hspi->State = HAL_SPI_STATE_READY; - - /* Call user Abort complete callback */ -#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL) - hspi->AbortCpltCallback(hspi); -#else - HAL_SPI_AbortCpltCallback(hspi); -#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ -} - -/** - * @brief Manage the receive 8-bit in Interrupt context. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi) -{ - /* Receive data in 8 Bit mode */ - *((uint8_t *)hspi->pRxBuffPtr) = (*(__IO uint8_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint8_t); - hspi->RxXferCount--; - - /* Disable IT if no more data excepted */ - if (hspi->RxXferCount == 0UL) - { -#if defined(USE_SPI_RELOAD_TRANSFER) - /* Check if there is any request to reload */ - if (hspi->Reload.Requested == 1UL) - { - hspi->RxXferSize = hspi->Reload.RxXferSize; - hspi->RxXferCount = hspi->Reload.RxXferSize; - hspi->pRxBuffPtr = hspi->Reload.pRxBuffPtr; - hspi->Reload.Requested = 0UL; - } - else - { - /* Disable RXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP); - } -#else - /* Disable RXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP); -#endif /* USE_SPI_RELOAD_TRANSFER */ - } -} - - -/** - * @brief Manage the 16-bit receive in Interrupt context. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi) -{ - /* Receive data in 16 Bit mode */ -#if defined (__GNUC__) - __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR)); - - *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits; -#else - *((uint16_t *)hspi->pRxBuffPtr) = (*(__IO uint16_t *)&hspi->Instance->RXDR); -#endif /* __GNUC__ */ - hspi->pRxBuffPtr += sizeof(uint16_t); - hspi->RxXferCount--; - - /* Disable IT if no more data excepted */ - if (hspi->RxXferCount == 0UL) - { -#if defined(USE_SPI_RELOAD_TRANSFER) - /* Check if there is any request to reload */ - if (hspi->Reload.Requested == 1UL) - { - hspi->RxXferSize = hspi->Reload.RxXferSize; - hspi->RxXferCount = hspi->Reload.RxXferSize; - hspi->pRxBuffPtr = hspi->Reload.pRxBuffPtr; - hspi->Reload.Requested = 0UL; - } - else - { - /* Disable RXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP); - } -#else - /* Disable RXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP); -#endif /* USE_SPI_RELOAD_TRANSFER */ - } -} - - -/** - * @brief Manage the 32-bit receive in Interrupt context. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -static void SPI_RxISR_32BIT(SPI_HandleTypeDef *hspi) -{ - /* Receive data in 32 Bit mode */ - *((uint32_t *)hspi->pRxBuffPtr) = (*(__IO uint32_t *)&hspi->Instance->RXDR); - hspi->pRxBuffPtr += sizeof(uint32_t); - hspi->RxXferCount--; - - /* Disable IT if no more data excepted */ - if (hspi->RxXferCount == 0UL) - { -#if defined(USE_SPI_RELOAD_TRANSFER) - /* Check if there is any request to reload */ - if (hspi->Reload.Requested == 1UL) - { - hspi->RxXferSize = hspi->Reload.RxXferSize; - hspi->RxXferCount = hspi->Reload.RxXferSize; - hspi->pRxBuffPtr = hspi->Reload.pRxBuffPtr; - hspi->Reload.Requested = 0UL; - } - else - { - /* Disable RXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP); - } -#else - /* Disable RXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP); -#endif /* USE_SPI_RELOAD_TRANSFER */ - } -} - - -/** - * @brief Handle the data 8-bit transmit in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi) -{ - /* Transmit data in 8 Bit mode */ - *(__IO uint8_t *)&hspi->Instance->TXDR = *((const uint8_t *)hspi->pTxBuffPtr); - hspi->pTxBuffPtr += sizeof(uint8_t); - hspi->TxXferCount--; - - /* Disable IT if no more data excepted */ - if (hspi->TxXferCount == 0UL) - { -#if defined(USE_SPI_RELOAD_TRANSFER) - /* Check if there is any request to reload */ - if (hspi->Reload.Requested == 1UL) - { - hspi->TxXferSize = hspi->Reload.TxXferSize; - hspi->TxXferCount = hspi->Reload.TxXferSize; - hspi->pTxBuffPtr = hspi->Reload.pTxBuffPtr; - - /* In full duplex mode the reload request is reset in RX side */ - if (hspi->State == HAL_SPI_STATE_BUSY_TX) - { - hspi->Reload.Requested = 0UL; - } - } - else - { - /* Disable TXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP); - } -#else - /* Disable TXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP); -#endif /* USE_SPI_RELOAD_TRANSFER */ - } -} - -/** - * @brief Handle the data 16-bit transmit in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi) -{ - /* Transmit data in 16 Bit mode */ -#if defined (__GNUC__) - __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR)); - - *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr); -#else - *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr); -#endif /* __GNUC__ */ - hspi->pTxBuffPtr += sizeof(uint16_t); - hspi->TxXferCount--; - - /* Disable IT if no more data excepted */ - if (hspi->TxXferCount == 0UL) - { -#if defined(USE_SPI_RELOAD_TRANSFER) - /* Check if there is any request to reload */ - if (hspi->Reload.Requested == 1UL) - { - hspi->TxXferSize = hspi->Reload.TxXferSize; - hspi->TxXferCount = hspi->Reload.TxXferSize; - hspi->pTxBuffPtr = hspi->Reload.pTxBuffPtr; - - /* In full duplex mode the reload request is reset in RX side */ - if (hspi->State == HAL_SPI_STATE_BUSY_TX) - { - hspi->Reload.Requested = 0UL; - } - } - else - { - /* Disable TXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP); - } -#else - /* Disable TXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP); -#endif /* USE_SPI_RELOAD_TRANSFER */ - } -} - -/** - * @brief Handle the data 32-bit transmit in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -static void SPI_TxISR_32BIT(SPI_HandleTypeDef *hspi) -{ - /* Transmit data in 32 Bit mode */ - *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr); - hspi->pTxBuffPtr += sizeof(uint32_t); - hspi->TxXferCount--; - - /* Disable IT if no more data excepted */ - if (hspi->TxXferCount == 0UL) - { -#if defined(USE_SPI_RELOAD_TRANSFER) - /* Check if there is any request to reload */ - if (hspi->Reload.Requested == 1UL) - { - hspi->TxXferSize = hspi->Reload.TxXferSize; - hspi->TxXferCount = hspi->Reload.TxXferSize; - hspi->pTxBuffPtr = hspi->Reload.pTxBuffPtr; - - /* In full duplex mode the reload request is reset in RX side */ - if (hspi->State == HAL_SPI_STATE_BUSY_TX) - { - hspi->Reload.Requested = 0UL; - } - } - else - { - /* Disable TXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP); - } -#else - /* Disable TXP interrupts */ - __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP); -#endif /* USE_SPI_RELOAD_TRANSFER */ - } -} - -/** - * @brief Abort Transfer and clear flags. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi) -{ - /* Disable SPI peripheral */ - __HAL_SPI_DISABLE(hspi); - - /* Disable ITs */ - __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_RXP | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | \ - SPI_IT_FRE | SPI_IT_MODF)); - - /* Clear the Status flags in the SR register */ - __HAL_SPI_CLEAR_EOTFLAG(hspi); - __HAL_SPI_CLEAR_TXTFFLAG(hspi); - - /* Disable Tx DMA Request */ - CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN); - - /* Clear the Error flags in the SR register */ - __HAL_SPI_CLEAR_OVRFLAG(hspi); - __HAL_SPI_CLEAR_UDRFLAG(hspi); - __HAL_SPI_CLEAR_FREFLAG(hspi); - __HAL_SPI_CLEAR_MODFFLAG(hspi); - __HAL_SPI_CLEAR_SUSPFLAG(hspi); - -#if (USE_SPI_CRC != 0U) - __HAL_SPI_CLEAR_CRCERRFLAG(hspi); -#endif /* USE_SPI_CRC */ - - hspi->TxXferCount = (uint16_t)0UL; - hspi->RxXferCount = (uint16_t)0UL; -} - - -/** - * @brief Close Transfer and clear flags. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval HAL_ERROR: if any error detected - * HAL_OK: if nothing detected - */ -static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi) -{ - uint32_t itflag = hspi->Instance->SR; - - __HAL_SPI_CLEAR_EOTFLAG(hspi); - __HAL_SPI_CLEAR_TXTFFLAG(hspi); - - /* Disable SPI peripheral */ - __HAL_SPI_DISABLE(hspi); - - /* Disable ITs */ - __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_RXP | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | \ - SPI_IT_FRE | SPI_IT_MODF)); - - /* Disable Tx DMA Request */ - CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN); - - /* Report UnderRun error for non RX Only communication */ - if (hspi->State != HAL_SPI_STATE_BUSY_RX) - { - if ((itflag & SPI_FLAG_UDR) != 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_UDR); - __HAL_SPI_CLEAR_UDRFLAG(hspi); - } - } - - /* Report OverRun error for non TX Only communication */ - if (hspi->State != HAL_SPI_STATE_BUSY_TX) - { - if ((itflag & SPI_FLAG_OVR) != 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR); - __HAL_SPI_CLEAR_OVRFLAG(hspi); - } - -#if (USE_SPI_CRC != 0UL) - /* Check if CRC error occurred */ - if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) - { - if ((itflag & SPI_FLAG_CRCERR) != 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); - __HAL_SPI_CLEAR_CRCERRFLAG(hspi); - } - } -#endif /* USE_SPI_CRC */ - } - - /* SPI Mode Fault error interrupt occurred -------------------------------*/ - if ((itflag & SPI_FLAG_MODF) != 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF); - __HAL_SPI_CLEAR_MODFFLAG(hspi); - } - - /* SPI Frame error interrupt occurred ------------------------------------*/ - if ((itflag & SPI_FLAG_FRE) != 0UL) - { - SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE); - __HAL_SPI_CLEAR_FREFLAG(hspi); - } - - hspi->TxXferCount = (uint16_t)0UL; - hspi->RxXferCount = (uint16_t)0UL; -} - -/** - * @brief Handle SPI Communication Timeout. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param Flag: SPI flag to check - * @param Status: flag state to check - * @param Timeout: Timeout duration - * @param Tickstart: Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status, - uint32_t Timeout, uint32_t Tickstart) -{ - /* Wait until flag is set */ - while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) == Status) - { - /* Check for the Timeout */ - if ((((HAL_GetTick() - Tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) - { - return HAL_TIMEOUT; - } - } - return HAL_OK; -} - -/** - * @brief Compute configured packet size from fifo perspective. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval Packet size occupied in the fifo - */ -static uint32_t SPI_GetPacketSize(const SPI_HandleTypeDef *hspi) -{ - uint32_t fifo_threashold = (hspi->Init.FifoThreshold >> SPI_CFG1_FTHLV_Pos) + 1UL; - uint32_t data_size = (hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) + 1UL; - - /* Convert data size to Byte */ - data_size = (data_size + 7UL) / 8UL; - - return data_size * fifo_threashold; -} - -/** - * @} - */ - -#endif /* HAL_SPI_MODULE_ENABLED */ - -/** - * @} - */ - -/** - * @} - */ diff --git a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c deleted file mode 100644 index fac9ba5..0000000 --- a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c +++ /dev/null @@ -1,226 +0,0 @@ -/** - ****************************************************************************** - * @file stm32h7xx_hal_spi_ex.c - * @author MCD Application Team - * @brief Extended SPI HAL module driver. - * This file provides firmware functions to manage the following - * SPI peripheral extended functionalities : - * + IO operation functions - * + Peripheral Control functions - * - ****************************************************************************** - * @attention - * - * Copyright (c) 2017 STMicroelectronics. - * All rights reserved. - * - * This software is licensed under terms that can be found in the LICENSE file - * in the root directory of this software component. - * If no LICENSE file comes with this software, it is provided AS-IS. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32h7xx_hal.h" - -/** @addtogroup STM32H7xx_HAL_Driver - * @{ - */ - -/** @defgroup SPIEx SPIEx - * @brief SPI Extended HAL module driver - * @{ - */ -#ifdef HAL_SPI_MODULE_ENABLED - -/* Private typedef -----------------------------------------------------------*/ -/* Private defines -----------------------------------------------------------*/ -/* Private macros ------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ - -/** @defgroup SPIEx_Exported_Functions SPIEx Exported Functions - * @{ - */ - -/** @defgroup SPIEx_Exported_Functions_Group1 IO operation functions - * @brief Data transfers functions - * -@verbatim - ============================================================================== - ##### IO operation functions ##### - =============================================================================== - [..] - This subsection provides a set of extended functions to manage the SPI - data transfers. - - (#) SPIEx function: - (++) HAL_SPIEx_FlushRxFifo() - (++) HAL_SPIEx_EnableLockConfiguration() - (++) HAL_SPIEx_ConfigureUnderrun() - -@endverbatim - * @{ - */ - -/** - * @brief Flush the RX fifo. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for the specified SPI module. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef *hspi) -{ - uint8_t count = 0; - uint32_t itflag = hspi->Instance->SR; - __IO uint32_t tmpreg; - - while (((hspi->Instance->SR & SPI_FLAG_FRLVL) != SPI_RX_FIFO_0PACKET) || ((itflag & SPI_FLAG_RXWNE) != 0UL)) - { - count += (uint8_t)4UL; - tmpreg = hspi->Instance->RXDR; - UNUSED(tmpreg); /* To avoid GCC warning */ - - if (IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) - { - if (count > SPI_HIGHEND_FIFO_SIZE) - { - return HAL_TIMEOUT; - } - } - else - { - if (count > SPI_LOWEND_FIFO_SIZE) - { - return HAL_TIMEOUT; - } - } - } - return HAL_OK; -} - - -/** - * @brief Enable the Lock for the AF configuration of associated IOs - * and write protect the Content of Configuration register 2 - * when SPI is enabled - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -HAL_StatusTypeDef HAL_SPIEx_EnableLockConfiguration(SPI_HandleTypeDef *hspi) -{ - HAL_StatusTypeDef errorcode = HAL_OK; - - /* Process Locked */ - __HAL_LOCK(hspi); - - if (hspi->State != HAL_SPI_STATE_READY) - { - errorcode = HAL_BUSY; - hspi->State = HAL_SPI_STATE_READY; - /* Process Unlocked */ - __HAL_UNLOCK(hspi); - return errorcode; - } - - /* Check if the SPI is disabled to edit IOLOCK bit */ - if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) - { - SET_BIT(hspi->Instance->CR1, SPI_CR1_IOLOCK); - } - else - { - /* Disable SPI peripheral */ - __HAL_SPI_DISABLE(hspi); - - SET_BIT(hspi->Instance->CR1, SPI_CR1_IOLOCK); - - /* Enable SPI peripheral */ - __HAL_SPI_ENABLE(hspi); - } - - hspi->State = HAL_SPI_STATE_READY; - /* Process Unlocked */ - __HAL_UNLOCK(hspi); - return errorcode; -} - -/** - * @brief Configure the UNDERRUN condition and behavior of slave transmitter. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @param UnderrunDetection : Detection of underrun condition at slave transmitter - * This parameter can be a value of @ref SPI_Underrun_Detection. - * @param UnderrunBehaviour : Behavior of slave transmitter at underrun condition - * This parameter can be a value of @ref SPI_Underrun_Behaviour. - * @retval None - */ -HAL_StatusTypeDef HAL_SPIEx_ConfigureUnderrun(SPI_HandleTypeDef *hspi, uint32_t UnderrunDetection, - uint32_t UnderrunBehaviour) -{ - HAL_StatusTypeDef errorcode = HAL_OK; - - /* Process Locked */ - __HAL_LOCK(hspi); - - /* Check State and Insure that Underrun configuration is managed only by Salve */ - if ((hspi->State != HAL_SPI_STATE_READY) || (hspi->Init.Mode != SPI_MODE_SLAVE)) - { - errorcode = HAL_BUSY; - hspi->State = HAL_SPI_STATE_READY; - /* Process Unlocked */ - __HAL_UNLOCK(hspi); - return errorcode; - } - - /* Check the parameters */ - assert_param(IS_SPI_UNDERRUN_DETECTION(UnderrunDetection)); - assert_param(IS_SPI_UNDERRUN_BEHAVIOUR(UnderrunBehaviour)); - - /* Check if the SPI is disabled to edit CFG1 register */ - if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) - { - /* Configure Underrun fields */ - MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRDET, UnderrunDetection); - MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, UnderrunBehaviour); - } - else - { - /* Disable SPI peripheral */ - __HAL_SPI_DISABLE(hspi); - - /* Configure Underrun fields */ - MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRDET, UnderrunDetection); - MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, UnderrunBehaviour); - - /* Enable SPI peripheral */ - __HAL_SPI_ENABLE(hspi); - } - - - hspi->State = HAL_SPI_STATE_READY; - /* Process Unlocked */ - __HAL_UNLOCK(hspi); - return errorcode; -} - -/** - * @} - */ - -/** - * @} - */ - -#endif /* HAL_SPI_MODULE_ENABLED */ - -/** - * @} - */ - -/** - * @} - */ diff --git a/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c new file mode 100644 index 0000000..54ff752 --- /dev/null +++ b/board/CubeMX_Config/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c @@ -0,0 +1,2257 @@ +/** + ****************************************************************************** + * @file stm32h7xx_ll_usb.c + * @author MCD Application Team + * @brief USB Low Layer HAL module driver. + * + * This file provides firmware functions to manage the following + * functionalities of the USB Peripheral Controller: + * + Initialization/de-initialization functions + * + I/O operation functions + * + Peripheral Control functions + * + Peripheral State functions + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Fill parameters of Init structure in USB_CfgTypeDef structure. + + (#) Call USB_CoreInit() API to initialize the USB Core peripheral. + + (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes. + + @endverbatim + + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx_hal.h" + +/** @addtogroup STM32H7xx_LL_USB_DRIVER + * @{ + */ + +#if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +#if defined (USB_OTG_FS) || defined (USB_OTG_HS) +static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx); + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions + * @{ + */ + +/** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization/de-initialization functions ##### + =============================================================================== + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the USB Core + * @param USBx USB Instance + * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) +{ + HAL_StatusTypeDef ret; + if (cfg.phy_itface == USB_OTG_ULPI_PHY) + { + USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); + + /* Init The ULPI Interface */ + USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); + + /* Select vbus source */ + USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); + if (cfg.use_external_vbus == 1U) + { + USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD; + } + + /* Reset after a PHY select */ + ret = USB_CoreReset(USBx); + } + else /* FS interface (embedded Phy) */ + { + /* Select FS Embedded PHY */ + USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; + + /* Reset after a PHY select */ + ret = USB_CoreReset(USBx); + + if (cfg.battery_charging_enable == 0U) + { + /* Activate the USB Transceiver */ + USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN; + } + else + { + /* Deactivate the USB Transceiver */ + USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN); + } + } + + if (cfg.dma_enable == 1U) + { + /* make sure to reserve 18 fifo Locations for DMA buffers */ + USBx->GDFIFOCFG &= ~(0xFFFFU << 16); + USBx->GDFIFOCFG |= 0x3EEU << 16; + + USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2; + USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN; + } + + return ret; +} + + +/** + * @brief Set the USB turnaround time + * @param USBx USB Instance + * @param hclk: AHB clock frequency + * @retval USB turnaround time In PHY Clocks number + */ +HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx, + uint32_t hclk, uint8_t speed) +{ + uint32_t UsbTrd; + + /* The USBTRD is configured according to the tables below, depending on AHB frequency + used by application. In the low AHB frequency range it is used to stretch enough the USB response + time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access + latency to the Data FIFO */ + if (speed == USBD_FS_SPEED) + { + if ((hclk >= 14200000U) && (hclk < 15000000U)) + { + /* hclk Clock Range between 14.2-15 MHz */ + UsbTrd = 0xFU; + } + else if ((hclk >= 15000000U) && (hclk < 16000000U)) + { + /* hclk Clock Range between 15-16 MHz */ + UsbTrd = 0xEU; + } + else if ((hclk >= 16000000U) && (hclk < 17200000U)) + { + /* hclk Clock Range between 16-17.2 MHz */ + UsbTrd = 0xDU; + } + else if ((hclk >= 17200000U) && (hclk < 18500000U)) + { + /* hclk Clock Range between 17.2-18.5 MHz */ + UsbTrd = 0xCU; + } + else if ((hclk >= 18500000U) && (hclk < 20000000U)) + { + /* hclk Clock Range between 18.5-20 MHz */ + UsbTrd = 0xBU; + } + else if ((hclk >= 20000000U) && (hclk < 21800000U)) + { + /* hclk Clock Range between 20-21.8 MHz */ + UsbTrd = 0xAU; + } + else if ((hclk >= 21800000U) && (hclk < 24000000U)) + { + /* hclk Clock Range between 21.8-24 MHz */ + UsbTrd = 0x9U; + } + else if ((hclk >= 24000000U) && (hclk < 27700000U)) + { + /* hclk Clock Range between 24-27.7 MHz */ + UsbTrd = 0x8U; + } + else if ((hclk >= 27700000U) && (hclk < 32000000U)) + { + /* hclk Clock Range between 27.7-32 MHz */ + UsbTrd = 0x7U; + } + else /* if(hclk >= 32000000) */ + { + /* hclk Clock Range between 32-200 MHz */ + UsbTrd = 0x6U; + } + } + else if (speed == USBD_HS_SPEED) + { + UsbTrd = USBD_HS_TRDT_VALUE; + } + else + { + UsbTrd = USBD_DEFAULT_TRDT_VALUE; + } + + USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; + USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT); + + return HAL_OK; +} + +/** + * @brief USB_EnableGlobalInt + * Enables the controller's Global Int in the AHB Config reg + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx) +{ + USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT; + return HAL_OK; +} + +/** + * @brief USB_DisableGlobalInt + * Disable the controller's Global Int in the AHB Config reg + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx) +{ + USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT; + return HAL_OK; +} + +/** + * @brief USB_SetCurrentMode Set functional mode + * @param USBx Selected device + * @param mode current core mode + * This parameter can be one of these values: + * @arg USB_DEVICE_MODE Peripheral mode + * @arg USB_HOST_MODE Host mode + * @retval HAL status + */ +HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_OTG_ModeTypeDef mode) +{ + uint32_t ms = 0U; + + USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD); + + if (mode == USB_HOST_MODE) + { + USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD; + + do + { + HAL_Delay(10U); + ms += 10U; + } while ((USB_GetMode(USBx) != (uint32_t)USB_HOST_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS)); + } + else if (mode == USB_DEVICE_MODE) + { + USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; + + do + { + HAL_Delay(10U); + ms += 10U; + } while ((USB_GetMode(USBx) != (uint32_t)USB_DEVICE_MODE) && (ms < HAL_USB_CURRENT_MODE_MAX_DELAY_MS)); + } + else + { + return HAL_ERROR; + } + + if (ms == HAL_USB_CURRENT_MODE_MAX_DELAY_MS) + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief USB_DevInit Initializes the USB_OTG controller registers + * for device mode + * @param USBx Selected device + * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) +{ + HAL_StatusTypeDef ret = HAL_OK; + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t i; + + for (i = 0U; i < 15U; i++) + { + USBx->DIEPTXF[i] = 0U; + } + + /* VBUS Sensing setup */ + if (cfg.vbus_sensing_enable == 0U) + { + USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS; + + /* Deactivate VBUS Sensing B */ + USBx->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + /* B-peripheral session valid override enable */ + USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; + USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; + } + else + { + /* Enable HW VBUS sensing */ + USBx->GCCFG |= USB_OTG_GCCFG_VBDEN; + } + + /* Restart the Phy Clock */ + USBx_PCGCCTL = 0U; + + if (cfg.phy_itface == USB_OTG_ULPI_PHY) + { + if (cfg.speed == USBD_HS_SPEED) + { + /* Set Core speed to High speed mode */ + (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH); + } + else + { + /* Set Core speed to Full speed mode */ + (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_HIGH_IN_FULL); + } + } + else + { + /* Set Core speed to Full speed mode */ + (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL); + } + + /* Flush the FIFOs */ + if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */ + { + ret = HAL_ERROR; + } + + if (USB_FlushRxFifo(USBx) != HAL_OK) + { + ret = HAL_ERROR; + } + + /* Clear all pending Device Interrupts */ + USBx_DEVICE->DIEPMSK = 0U; + USBx_DEVICE->DOEPMSK = 0U; + USBx_DEVICE->DAINTMSK = 0U; + + for (i = 0U; i < cfg.dev_endpoints; i++) + { + if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) + { + if (i == 0U) + { + USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK; + } + else + { + USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK; + } + } + else + { + USBx_INEP(i)->DIEPCTL = 0U; + } + + USBx_INEP(i)->DIEPTSIZ = 0U; + USBx_INEP(i)->DIEPINT = 0xFB7FU; + } + + for (i = 0U; i < cfg.dev_endpoints; i++) + { + if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) + { + if (i == 0U) + { + USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK; + } + else + { + USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK; + } + } + else + { + USBx_OUTEP(i)->DOEPCTL = 0U; + } + + USBx_OUTEP(i)->DOEPTSIZ = 0U; + USBx_OUTEP(i)->DOEPINT = 0xFB7FU; + } + + USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM); + + /* Disable all interrupts. */ + USBx->GINTMSK = 0U; + + /* Clear any pending interrupts */ + USBx->GINTSTS = 0xBFFFFFFFU; + + /* Enable the common interrupts */ + if (cfg.dma_enable == 0U) + { + USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; + } + + /* Enable interrupts matching to the Device mode ONLY */ + USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST | + USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT | + USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM | + USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM; + + if (cfg.Sof_enable != 0U) + { + USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM; + } + + if (cfg.vbus_sensing_enable == 1U) + { + USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT); + } + + return ret; +} + +/** + * @brief USB_FlushTxFifo Flush a Tx FIFO + * @param USBx Selected device + * @param num FIFO number + * This parameter can be a value from 1 to 15 + 15 means Flush all Tx FIFOs + * @retval HAL status + */ +HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num) +{ + __IO uint32_t count = 0U; + + /* Wait for AHB master IDLE state. */ + do + { + count++; + + if (count > HAL_USB_TIMEOUT) + { + return HAL_TIMEOUT; + } + } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); + + /* Flush TX Fifo */ + count = 0U; + USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6)); + + do + { + count++; + + if (count > HAL_USB_TIMEOUT) + { + return HAL_TIMEOUT; + } + } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH); + + return HAL_OK; +} + +/** + * @brief USB_FlushRxFifo Flush Rx FIFO + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx) +{ + __IO uint32_t count = 0U; + + /* Wait for AHB master IDLE state. */ + do + { + count++; + + if (count > HAL_USB_TIMEOUT) + { + return HAL_TIMEOUT; + } + } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); + + /* Flush RX Fifo */ + count = 0U; + USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH; + + do + { + count++; + + if (count > HAL_USB_TIMEOUT) + { + return HAL_TIMEOUT; + } + } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH); + + return HAL_OK; +} + +/** + * @brief USB_SetDevSpeed Initializes the DevSpd field of DCFG register + * depending the PHY type and the enumeration speed of the device. + * @param USBx Selected device + * @param speed device speed + * This parameter can be one of these values: + * @arg USB_OTG_SPEED_HIGH: High speed mode + * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode + * @arg USB_OTG_SPEED_FULL: Full speed mode + * @retval Hal status + */ +HAL_StatusTypeDef USB_SetDevSpeed(const USB_OTG_GlobalTypeDef *USBx, uint8_t speed) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + USBx_DEVICE->DCFG |= speed; + return HAL_OK; +} + +/** + * @brief USB_GetDevSpeed Return the Dev Speed + * @param USBx Selected device + * @retval speed device speed + * This parameter can be one of these values: + * @arg USBD_HS_SPEED: High speed mode + * @arg USBD_FS_SPEED: Full speed mode + */ +uint8_t USB_GetDevSpeed(const USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint8_t speed; + uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD; + + if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ) + { + speed = USBD_HS_SPEED; + } + else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) || + (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ)) + { + speed = USBD_FS_SPEED; + } + else + { + speed = 0xFU; + } + + return speed; +} + +/** + * @brief Activate and configure an endpoint + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t epnum = (uint32_t)ep->num; + + if (ep->is_in == 1U) + { + USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)); + + if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U) + { + USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) | + ((uint32_t)ep->type << 18) | (epnum << 22) | + USB_OTG_DIEPCTL_SD0PID_SEVNFRM | + USB_OTG_DIEPCTL_USBAEP; + } + } + else + { + USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16); + + if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U) + { + USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) | + ((uint32_t)ep->type << 18) | + USB_OTG_DIEPCTL_SD0PID_SEVNFRM | + USB_OTG_DOEPCTL_USBAEP; + } + } + return HAL_OK; +} + +/** + * @brief Activate and configure a dedicated endpoint + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t epnum = (uint32_t)ep->num; + + /* Read DEPCTLn register */ + if (ep->is_in == 1U) + { + if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U) + { + USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) | + ((uint32_t)ep->type << 18) | (epnum << 22) | + USB_OTG_DIEPCTL_SD0PID_SEVNFRM | + USB_OTG_DIEPCTL_USBAEP; + } + + USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)); + } + else + { + if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U) + { + USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) | + ((uint32_t)ep->type << 18) | (epnum << 22) | + USB_OTG_DOEPCTL_USBAEP; + } + + USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16); + } + + return HAL_OK; +} + +/** + * @brief De-activate and de-initialize an endpoint + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeactivateEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t epnum = (uint32_t)ep->num; + + /* Read DEPCTLn register */ + if (ep->is_in == 1U) + { + if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) + { + USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK; + USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS; + } + + USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK))); + USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK))); + USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP | + USB_OTG_DIEPCTL_MPSIZ | + USB_OTG_DIEPCTL_TXFNUM | + USB_OTG_DIEPCTL_SD0PID_SEVNFRM | + USB_OTG_DIEPCTL_EPTYP); + } + else + { + if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) + { + USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK; + USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS; + } + + USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16)); + USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16)); + USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP | + USB_OTG_DOEPCTL_MPSIZ | + USB_OTG_DOEPCTL_SD0PID_SEVNFRM | + USB_OTG_DOEPCTL_EPTYP); + } + + return HAL_OK; +} + +/** + * @brief De-activate and de-initialize a dedicated endpoint + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t epnum = (uint32_t)ep->num; + + /* Read DEPCTLn register */ + if (ep->is_in == 1U) + { + if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) + { + USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK; + USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS; + } + + USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP; + USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK))); + } + else + { + if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) + { + USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK; + USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS; + } + + USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP; + USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16)); + } + + return HAL_OK; +} + +/** + * @brief USB_EPStartXfer : setup and starts a transfer over an EP + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @param dma USB dma enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep, uint8_t dma) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t epnum = (uint32_t)ep->num; + uint16_t pktcnt; + + /* IN endpoint */ + if (ep->is_in == 1U) + { + /* Zero Length Packet? */ + if (ep->xfer_len == 0U) + { + USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); + USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19)); + USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); + } + else + { + /* Program the transfer size and packet count + * as follows: xfersize = N * maxpacket + + * short_packet pktcnt = N + (short_packet + * exist ? 1 : 0) + */ + USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); + USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); + + if (epnum == 0U) + { + if (ep->xfer_len > ep->maxpacket) + { + ep->xfer_len = ep->maxpacket; + } + + USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19)); + } + else + { + pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket); + USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19)); + + if (ep->type == EP_TYPE_ISOC) + { + USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT); + USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & ((uint32_t)pktcnt << 29)); + } + } + + USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len); + } + + if (dma == 1U) + { + if ((uint32_t)ep->dma_addr != 0U) + { + USBx_INEP(epnum)->DIEPDMA = (uint32_t)(ep->dma_addr); + } + + if (ep->type == EP_TYPE_ISOC) + { + if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U) + { + USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM; + } + else + { + USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; + } + } + + /* EP enable, IN data in FIFO */ + USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); + } + else + { + /* EP enable, IN data in FIFO */ + USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); + + if (ep->type != EP_TYPE_ISOC) + { + /* Enable the Tx FIFO Empty Interrupt for this EP */ + if (ep->xfer_len > 0U) + { + USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK); + } + } + else + { + if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U) + { + USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM; + } + else + { + USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; + } + + (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len, dma); + } + } + } + else /* OUT endpoint */ + { + /* Program the transfer size and packet count as follows: + * pktcnt = N + * xfersize = N * maxpacket + */ + USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ); + USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT); + + if (epnum == 0U) + { + if (ep->xfer_len > 0U) + { + ep->xfer_len = ep->maxpacket; + } + + /* Store transfer size, for EP0 this is equal to endpoint max packet size */ + ep->xfer_size = ep->maxpacket; + + USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size); + USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19)); + } + else + { + if (ep->xfer_len == 0U) + { + USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket); + USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19)); + } + else + { + pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket); + ep->xfer_size = ep->maxpacket * pktcnt; + + USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19); + USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & ep->xfer_size; + } + } + + if (dma == 1U) + { + if ((uint32_t)ep->xfer_buff != 0U) + { + USBx_OUTEP(epnum)->DOEPDMA = (uint32_t)(ep->xfer_buff); + } + } + + if (ep->type == EP_TYPE_ISOC) + { + if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U) + { + USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM; + } + else + { + USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; + } + } + /* EP enable */ + USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); + } + + return HAL_OK; +} + + +/** + * @brief USB_EPStoptXfer Stop transfer on an EP + * @param USBx usb device instance + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPStopXfer(const USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) +{ + __IO uint32_t count = 0U; + HAL_StatusTypeDef ret = HAL_OK; + uint32_t USBx_BASE = (uint32_t)USBx; + + /* IN endpoint */ + if (ep->is_in == 1U) + { + /* EP enable, IN data in FIFO */ + if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) + { + USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_SNAK); + USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_EPDIS); + + do + { + count++; + + if (count > 10000U) + { + ret = HAL_ERROR; + break; + } + } while (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA); + } + } + else /* OUT endpoint */ + { + if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) + { + USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_SNAK); + USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_EPDIS); + + do + { + count++; + + if (count > 10000U) + { + ret = HAL_ERROR; + break; + } + } while (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA); + } + } + + return ret; +} + + +/** + * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated + * with the EP/channel + * @param USBx Selected device + * @param src pointer to source buffer + * @param ch_ep_num endpoint or host channel number + * @param len Number of bytes to write + * @param dma USB dma enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + * @retval HAL status + */ +HAL_StatusTypeDef USB_WritePacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *src, + uint8_t ch_ep_num, uint16_t len, uint8_t dma) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint8_t *pSrc = src; + uint32_t count32b; + uint32_t i; + + if (dma == 0U) + { + count32b = ((uint32_t)len + 3U) / 4U; + for (i = 0U; i < count32b; i++) + { + USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc); + pSrc++; + pSrc++; + pSrc++; + pSrc++; + } + } + + return HAL_OK; +} + +/** + * @brief USB_ReadPacket : read a packet from the RX FIFO + * @param USBx Selected device + * @param dest source pointer + * @param len Number of bytes to read + * @retval pointer to destination buffer + */ +void *USB_ReadPacket(const USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint8_t *pDest = dest; + uint32_t pData; + uint32_t i; + uint32_t count32b = (uint32_t)len >> 2U; + uint16_t remaining_bytes = len % 4U; + + for (i = 0U; i < count32b; i++) + { + __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U)); + pDest++; + pDest++; + pDest++; + pDest++; + } + + /* When Number of data is not word aligned, read the remaining byte */ + if (remaining_bytes != 0U) + { + i = 0U; + __UNALIGNED_UINT32_WRITE(&pData, USBx_DFIFO(0U)); + + do + { + *(uint8_t *)pDest = (uint8_t)(pData >> (8U * (uint8_t)(i))); + i++; + pDest++; + remaining_bytes--; + } while (remaining_bytes != 0U); + } + + return ((void *)pDest); +} + +/** + * @brief USB_EPSetStall : set a stall condition over an EP + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPSetStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t epnum = (uint32_t)ep->num; + + if (ep->is_in == 1U) + { + if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U)) + { + USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS); + } + USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL; + } + else + { + if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U)) + { + USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS); + } + USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL; + } + + return HAL_OK; +} + +/** + * @brief USB_EPClearStall : Clear a stall condition over an EP + * @param USBx Selected device + * @param ep pointer to endpoint structure + * @retval HAL status + */ +HAL_StatusTypeDef USB_EPClearStall(const USB_OTG_GlobalTypeDef *USBx, const USB_OTG_EPTypeDef *ep) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t epnum = (uint32_t)ep->num; + + if (ep->is_in == 1U) + { + USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; + if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK)) + { + USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */ + } + } + else + { + USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; + if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK)) + { + USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */ + } + } + return HAL_OK; +} + +/** + * @brief USB_StopDevice : Stop the usb device mode + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx) +{ + HAL_StatusTypeDef ret; + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t i; + + /* Clear Pending interrupt */ + for (i = 0U; i < 15U; i++) + { + USBx_INEP(i)->DIEPINT = 0xFB7FU; + USBx_OUTEP(i)->DOEPINT = 0xFB7FU; + } + + /* Clear interrupt masks */ + USBx_DEVICE->DIEPMSK = 0U; + USBx_DEVICE->DOEPMSK = 0U; + USBx_DEVICE->DAINTMSK = 0U; + + /* Flush the FIFO */ + ret = USB_FlushRxFifo(USBx); + if (ret != HAL_OK) + { + return ret; + } + + ret = USB_FlushTxFifo(USBx, 0x10U); + if (ret != HAL_OK) + { + return ret; + } + + return ret; +} + +/** + * @brief USB_SetDevAddress : Stop the usb device mode + * @param USBx Selected device + * @param address new device address to be assigned + * This parameter can be a value from 0 to 255 + * @retval HAL status + */ +HAL_StatusTypeDef USB_SetDevAddress(const USB_OTG_GlobalTypeDef *USBx, uint8_t address) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD); + USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD; + + return HAL_OK; +} + +/** + * @brief USB_DevConnect : Connect the USB device by enabling Rpu + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevConnect(const USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + /* In case phy is stopped, ensure to ungate and restore the phy CLK */ + USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK); + + USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS; + + return HAL_OK; +} + +/** + * @brief USB_DevDisconnect : Disconnect the USB device by disabling Rpu + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DevDisconnect(const USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + /* In case phy is stopped, ensure to ungate and restore the phy CLK */ + USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK); + + USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS; + + return HAL_OK; +} + +/** + * @brief USB_ReadInterrupts: return the global USB interrupt status + * @param USBx Selected device + * @retval USB Global Interrupt status + */ +uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef const *USBx) +{ + uint32_t tmpreg; + + tmpreg = USBx->GINTSTS; + tmpreg &= USBx->GINTMSK; + + return tmpreg; +} + +/** + * @brief USB_ReadChInterrupts: return USB channel interrupt status + * @param USBx Selected device + * @param chnum Channel number + * @retval USB Channel Interrupt status + */ +uint32_t USB_ReadChInterrupts(const USB_OTG_GlobalTypeDef *USBx, uint8_t chnum) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t tmpreg; + + tmpreg = USBx_HC(chnum)->HCINT; + tmpreg &= USBx_HC(chnum)->HCINTMSK; + + return tmpreg; +} + +/** + * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status + * @param USBx Selected device + * @retval USB Device OUT EP interrupt status + */ +uint32_t USB_ReadDevAllOutEpInterrupt(const USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t tmpreg; + + tmpreg = USBx_DEVICE->DAINT; + tmpreg &= USBx_DEVICE->DAINTMSK; + + return ((tmpreg & 0xffff0000U) >> 16); +} + +/** + * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status + * @param USBx Selected device + * @retval USB Device IN EP interrupt status + */ +uint32_t USB_ReadDevAllInEpInterrupt(const USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t tmpreg; + + tmpreg = USBx_DEVICE->DAINT; + tmpreg &= USBx_DEVICE->DAINTMSK; + + return ((tmpreg & 0xFFFFU)); +} + +/** + * @brief Returns Device OUT EP Interrupt register + * @param USBx Selected device + * @param epnum endpoint number + * This parameter can be a value from 0 to 15 + * @retval Device OUT EP Interrupt register + */ +uint32_t USB_ReadDevOutEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t tmpreg; + + tmpreg = USBx_OUTEP((uint32_t)epnum)->DOEPINT; + tmpreg &= USBx_DEVICE->DOEPMSK; + + return tmpreg; +} + +/** + * @brief Returns Device IN EP Interrupt register + * @param USBx Selected device + * @param epnum endpoint number + * This parameter can be a value from 0 to 15 + * @retval Device IN EP Interrupt register + */ +uint32_t USB_ReadDevInEPInterrupt(const USB_OTG_GlobalTypeDef *USBx, uint8_t epnum) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t tmpreg; + uint32_t msk; + uint32_t emp; + + msk = USBx_DEVICE->DIEPMSK; + emp = USBx_DEVICE->DIEPEMPMSK; + msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7; + tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk; + + return tmpreg; +} + +/** + * @brief USB_ClearInterrupts: clear a USB interrupt + * @param USBx Selected device + * @param interrupt flag + * @retval None + */ +void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt) +{ + USBx->GINTSTS &= interrupt; +} + +/** + * @brief Returns USB core mode + * @param USBx Selected device + * @retval return core mode : Host or Device + * This parameter can be one of these values: + * 1 : Host + * 0 : Device + */ +uint32_t USB_GetMode(const USB_OTG_GlobalTypeDef *USBx) +{ + return ((USBx->GINTSTS) & 0x1U); +} + +/** + * @brief Activate EP0 for Setup transactions + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateSetup(const USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + /* Set the MPS of the IN EP0 to 64 bytes */ + USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ; + + USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK; + + return HAL_OK; +} + +/** + * @brief Prepare the EP0 to start the first control setup + * @param USBx Selected device + * @param dma USB dma enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + * @param psetup pointer to setup packet + * @retval HAL status + */ +HAL_StatusTypeDef USB_EP0_OutStart(const USB_OTG_GlobalTypeDef *USBx, uint8_t dma, const uint8_t *psetup) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U); + + if (gSNPSiD > USB_OTG_CORE_ID_300A) + { + if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) + { + return HAL_OK; + } + } + + USBx_OUTEP(0U)->DOEPTSIZ = 0U; + USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19)); + USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U); + USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT; + + if (dma == 1U) + { + USBx_OUTEP(0U)->DOEPDMA = (uint32_t)psetup; + /* EP enable */ + USBx_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP; + } + + return HAL_OK; +} + +/** + * @brief Reset the USB Core (needed after USB clock settings change) + * @param USBx Selected device + * @retval HAL status + */ +static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx) +{ + __IO uint32_t count = 0U; + + /* Wait for AHB master IDLE state. */ + do + { + count++; + + if (count > HAL_USB_TIMEOUT) + { + return HAL_TIMEOUT; + } + } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U); + + /* Core Soft Reset */ + count = 0U; + USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; + + do + { + count++; + + if (count > HAL_USB_TIMEOUT) + { + return HAL_TIMEOUT; + } + } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); + + return HAL_OK; +} + +/** + * @brief USB_HostInit : Initializes the USB OTG controller registers + * for Host mode + * @param USBx Selected device + * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains + * the configuration information for the specified USBx peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) +{ + HAL_StatusTypeDef ret = HAL_OK; + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t i; + + /* Restart the Phy Clock */ + USBx_PCGCCTL = 0U; + + /* Disable VBUS sensing */ + USBx->GCCFG &= ~(USB_OTG_GCCFG_VBDEN); + + /* Disable Battery chargin detector */ + USBx->GCCFG &= ~(USB_OTG_GCCFG_BCDEN); + + + if ((USBx->GUSBCFG & USB_OTG_GUSBCFG_PHYSEL) == 0U) + { + if (cfg.speed == USBH_FSLS_SPEED) + { + /* Force Device Enumeration to FS/LS mode only */ + USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS; + } + else + { + /* Set default Max speed support */ + USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS); + } + } + else + { + /* Set default Max speed support */ + USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS); + } + + /* Make sure the FIFOs are flushed. */ + if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */ + { + ret = HAL_ERROR; + } + + if (USB_FlushRxFifo(USBx) != HAL_OK) + { + ret = HAL_ERROR; + } + + /* Clear all pending HC Interrupts */ + for (i = 0U; i < cfg.Host_channels; i++) + { + USBx_HC(i)->HCINT = CLEAR_INTERRUPT_MASK; + USBx_HC(i)->HCINTMSK = 0U; + } + + /* Disable all interrupts. */ + USBx->GINTMSK = 0U; + + /* Clear any pending interrupts */ + USBx->GINTSTS = CLEAR_INTERRUPT_MASK; + /* set Rx FIFO size */ + USBx->GRXFSIZ = 0x200U; + USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x100U << 16) & USB_OTG_NPTXFD) | 0x200U); + USBx->HPTXFSIZ = (uint32_t)(((0xE0U << 16) & USB_OTG_HPTXFSIZ_PTXFD) | 0x300U); + + /* Enable the common interrupts */ + if (cfg.dma_enable == 0U) + { + USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; + } + + /* Enable interrupts matching to the Host mode ONLY */ + USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | \ + USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \ + USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM); + + return ret; +} + +/** + * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the + * HCFG register on the PHY type and set the right frame interval + * @param USBx Selected device + * @param freq clock frequency + * This parameter can be one of these values: + * HCFG_48_MHZ : Full Speed 48 MHz Clock + * HCFG_6_MHZ : Low Speed 6 MHz Clock + * @retval HAL status + */ +HAL_StatusTypeDef USB_InitFSLSPClkSel(const USB_OTG_GlobalTypeDef *USBx, uint8_t freq) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS); + USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS; + + if (freq == HCFG_48_MHZ) + { + USBx_HOST->HFIR = HFIR_48_MHZ; + } + else if (freq == HCFG_6_MHZ) + { + USBx_HOST->HFIR = HFIR_6_MHZ; + } + else + { + return HAL_ERROR; + } + + return HAL_OK; +} + +/** + * @brief USB_OTG_ResetPort : Reset Host Port + * @param USBx Selected device + * @retval HAL status + * @note (1)The application must wait at least 10 ms + * before clearing the reset bit. + */ +HAL_StatusTypeDef USB_ResetPort(const USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + __IO uint32_t hprt0 = 0U; + + hprt0 = USBx_HPRT0; + + hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | + USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG); + + USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0); + HAL_Delay(100U); /* See Note #1 */ + USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0); + HAL_Delay(10U); + + return HAL_OK; +} + +/** + * @brief USB_DriveVbus : activate or de-activate vbus + * @param state VBUS state + * This parameter can be one of these values: + * 0 : Deactivate VBUS + * 1 : Activate VBUS + * @retval HAL status + */ +HAL_StatusTypeDef USB_DriveVbus(const USB_OTG_GlobalTypeDef *USBx, uint8_t state) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + __IO uint32_t hprt0 = 0U; + + hprt0 = USBx_HPRT0; + + hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET | + USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG); + + if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U)) + { + USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0); + } + if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U)) + { + USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0); + } + return HAL_OK; +} + +/** + * @brief Return Host Core speed + * @param USBx Selected device + * @retval speed : Host speed + * This parameter can be one of these values: + * @arg HCD_SPEED_HIGH: High speed mode + * @arg HCD_SPEED_FULL: Full speed mode + * @arg HCD_SPEED_LOW: Low speed mode + */ +uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef const *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + __IO uint32_t hprt0 = 0U; + + hprt0 = USBx_HPRT0; + return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17); +} + +/** + * @brief Return Host Current Frame number + * @param USBx Selected device + * @retval current frame number + */ +uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef const *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM); +} + +/** + * @brief Initialize a host channel + * @param USBx Selected device + * @param ch_num Channel number + * This parameter can be a value from 1 to 15 + * @param epnum Endpoint number + * This parameter can be a value from 1 to 15 + * @param dev_address Current device address + * This parameter can be a value from 0 to 255 + * @param speed Current device speed + * This parameter can be one of these values: + * @arg USB_OTG_SPEED_HIGH: High speed mode + * @arg USB_OTG_SPEED_FULL: Full speed mode + * @arg USB_OTG_SPEED_LOW: Low speed mode + * @param ep_type Endpoint Type + * This parameter can be one of these values: + * @arg EP_TYPE_CTRL: Control type + * @arg EP_TYPE_ISOC: Isochronous type + * @arg EP_TYPE_BULK: Bulk type + * @arg EP_TYPE_INTR: Interrupt type + * @param mps Max Packet Size + * This parameter can be a value from 0 to 32K + * @retval HAL state + */ +HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num, + uint8_t epnum, uint8_t dev_address, uint8_t speed, + uint8_t ep_type, uint16_t mps) +{ + HAL_StatusTypeDef ret = HAL_OK; + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t HCcharEpDir; + uint32_t HCcharLowSpeed; + uint32_t HostCoreSpeed; + + /* Clear old interrupt conditions for this host channel. */ + USBx_HC((uint32_t)ch_num)->HCINT = CLEAR_INTERRUPT_MASK; + + /* Enable channel interrupts required for this transfer. */ + switch (ep_type) + { + case EP_TYPE_CTRL: + case EP_TYPE_BULK: + USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM | + USB_OTG_HCINTMSK_STALLM | + USB_OTG_HCINTMSK_TXERRM | + USB_OTG_HCINTMSK_DTERRM | + USB_OTG_HCINTMSK_AHBERR | + USB_OTG_HCINTMSK_NAKM; + + if ((epnum & 0x80U) == 0x80U) + { + USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM; + } + else + { + USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET | + USB_OTG_HCINTMSK_ACKM; + } + break; + + case EP_TYPE_INTR: + USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM | + USB_OTG_HCINTMSK_STALLM | + USB_OTG_HCINTMSK_TXERRM | + USB_OTG_HCINTMSK_DTERRM | + USB_OTG_HCINTMSK_NAKM | + USB_OTG_HCINTMSK_AHBERR | + USB_OTG_HCINTMSK_FRMORM; + + if ((epnum & 0x80U) == 0x80U) + { + USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM; + } + + break; + + case EP_TYPE_ISOC: + USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM | + USB_OTG_HCINTMSK_ACKM | + USB_OTG_HCINTMSK_AHBERR | + USB_OTG_HCINTMSK_FRMORM; + + if ((epnum & 0x80U) == 0x80U) + { + USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM); + } + break; + + default: + ret = HAL_ERROR; + break; + } + + /* Clear Hub Start Split transaction */ + USBx_HC((uint32_t)ch_num)->HCSPLT = 0U; + + /* Enable host channel Halt interrupt */ + USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_CHHM; + + /* Enable the top level host channel interrupt. */ + USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU); + + /* Make sure host channel interrupts are enabled. */ + USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM; + + /* Program the HCCHAR register */ + if ((epnum & 0x80U) == 0x80U) + { + HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR; + } + else + { + HCcharEpDir = 0U; + } + + HostCoreSpeed = USB_GetHostSpeed(USBx); + + /* LS device plugged to HUB */ + if ((speed == HPRT0_PRTSPD_LOW_SPEED) && (HostCoreSpeed != HPRT0_PRTSPD_LOW_SPEED)) + { + HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV; + } + else + { + HCcharLowSpeed = 0U; + } + + USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) | + ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) | + (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) | + ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) | + USB_OTG_HCCHAR_MC_0 | HCcharEpDir | HCcharLowSpeed; + + if ((ep_type == EP_TYPE_INTR) || (ep_type == EP_TYPE_ISOC)) + { + USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM; + } + + return ret; +} + +/** + * @brief Start a transfer over a host channel + * @param USBx Selected device + * @param hc pointer to host channel structure + * @param dma USB dma enabled or disabled + * This parameter can be one of these values: + * 0 : DMA feature not used + * 1 : DMA feature used + * @retval HAL state + */ +HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t ch_num = (uint32_t)hc->ch_num; + __IO uint32_t tmpreg; + uint8_t is_oddframe; + uint16_t len_words; + uint16_t num_packets; + uint16_t max_hc_pkt_count = HC_MAX_PKT_CNT; + + /* in DMA mode host Core automatically issues ping in case of NYET/NAK */ + if (dma == 1U) + { + if ((hc->ep_type == EP_TYPE_CTRL) || (hc->ep_type == EP_TYPE_BULK)) + { + + USBx_HC((uint32_t)ch_num)->HCINTMSK &= ~(USB_OTG_HCINTMSK_NYET | + USB_OTG_HCINTMSK_ACKM | + USB_OTG_HCINTMSK_NAKM); + } + } + else + { + if ((hc->speed == USBH_HS_SPEED) && (hc->do_ping == 1U)) + { + (void)USB_DoPing(USBx, hc->ch_num); + return HAL_OK; + } + } + + if (hc->do_ssplit == 1U) + { + /* Set number of packet to 1 for Split transaction */ + num_packets = 1U; + + if (hc->ep_is_in != 0U) + { + hc->XferSize = (uint32_t)num_packets * hc->max_packet; + } + else + { + if (hc->ep_type == EP_TYPE_ISOC) + { + if (hc->xfer_len > ISO_SPLT_MPS) + { + /* Isochrone Max Packet Size for Split mode */ + hc->XferSize = hc->max_packet; + hc->xfer_len = hc->XferSize; + + if ((hc->iso_splt_xactPos == HCSPLT_BEGIN) || (hc->iso_splt_xactPos == HCSPLT_MIDDLE)) + { + hc->iso_splt_xactPos = HCSPLT_MIDDLE; + } + else + { + hc->iso_splt_xactPos = HCSPLT_BEGIN; + } + } + else + { + hc->XferSize = hc->xfer_len; + + if ((hc->iso_splt_xactPos != HCSPLT_BEGIN) && (hc->iso_splt_xactPos != HCSPLT_MIDDLE)) + { + hc->iso_splt_xactPos = HCSPLT_FULL; + } + else + { + hc->iso_splt_xactPos = HCSPLT_END; + } + } + } + else + { + if ((dma == 1U) && (hc->xfer_len > hc->max_packet)) + { + hc->XferSize = (uint32_t)num_packets * hc->max_packet; + } + else + { + hc->XferSize = hc->xfer_len; + } + } + } + } + else + { + /* Compute the expected number of packets associated to the transfer */ + if (hc->xfer_len > 0U) + { + num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet); + + if (num_packets > max_hc_pkt_count) + { + num_packets = max_hc_pkt_count; + hc->XferSize = (uint32_t)num_packets * hc->max_packet; + } + } + else + { + num_packets = 1U; + } + + /* + * For IN channel HCTSIZ.XferSize is expected to be an integer multiple of + * max_packet size. + */ + if (hc->ep_is_in != 0U) + { + hc->XferSize = (uint32_t)num_packets * hc->max_packet; + } + else + { + hc->XferSize = hc->xfer_len; + } + } + + /* Initialize the HCTSIZn register */ + USBx_HC(ch_num)->HCTSIZ = (hc->XferSize & USB_OTG_HCTSIZ_XFRSIZ) | + (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) | + (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID); + + if (dma != 0U) + { + /* xfer_buff MUST be 32-bits aligned */ + USBx_HC(ch_num)->HCDMA = (uint32_t)hc->xfer_buff; + } + + is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U; + USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM; + USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29; + + if (hc->do_ssplit == 1U) + { + /* Set Hub start Split transaction */ + USBx_HC((uint32_t)ch_num)->HCSPLT = ((uint32_t)hc->hub_addr << USB_OTG_HCSPLT_HUBADDR_Pos) | + (uint32_t)hc->hub_port_nbr | USB_OTG_HCSPLT_SPLITEN; + + /* unmask ack & nyet for IN/OUT transactions */ + USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_ACKM | + USB_OTG_HCINTMSK_NYET); + + if ((hc->do_csplit == 1U) && (hc->ep_is_in == 0U)) + { + USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT; + USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_NYET; + } + + if (((hc->ep_type == EP_TYPE_ISOC) || (hc->ep_type == EP_TYPE_INTR)) && + (hc->do_csplit == 1U) && (hc->ep_is_in == 1U)) + { + USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT; + } + + /* Position management for iso out transaction on split mode */ + if ((hc->ep_type == EP_TYPE_ISOC) && (hc->ep_is_in == 0U)) + { + /* Set data payload position */ + switch (hc->iso_splt_xactPos) + { + case HCSPLT_BEGIN: + /* First data payload for OUT Transaction */ + USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_1; + break; + + case HCSPLT_MIDDLE: + /* Middle data payload for OUT Transaction */ + USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_Pos; + break; + + case HCSPLT_END: + /* End data payload for OUT Transaction */ + USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_0; + break; + + case HCSPLT_FULL: + /* Entire data payload for OUT Transaction */ + USBx_HC((uint32_t)ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS; + break; + + default: + break; + } + } + } + else + { + /* Clear Hub Start Split transaction */ + USBx_HC((uint32_t)ch_num)->HCSPLT = 0U; + } + + /* Set host channel enable */ + tmpreg = USBx_HC(ch_num)->HCCHAR; + tmpreg &= ~USB_OTG_HCCHAR_CHDIS; + + /* make sure to set the correct ep direction */ + if (hc->ep_is_in != 0U) + { + tmpreg |= USB_OTG_HCCHAR_EPDIR; + } + else + { + tmpreg &= ~USB_OTG_HCCHAR_EPDIR; + } + tmpreg |= USB_OTG_HCCHAR_CHENA; + USBx_HC(ch_num)->HCCHAR = tmpreg; + + if (dma != 0U) /* dma mode */ + { + return HAL_OK; + } + + if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U) && (hc->do_csplit == 0U)) + { + switch (hc->ep_type) + { + /* Non periodic transfer */ + case EP_TYPE_CTRL: + case EP_TYPE_BULK: + + len_words = (uint16_t)((hc->xfer_len + 3U) / 4U); + + /* check if there is enough space in FIFO space */ + if (len_words > (USBx->HNPTXSTS & 0xFFFFU)) + { + /* need to process data in nptxfempty interrupt */ + USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM; + } + break; + + /* Periodic transfer */ + case EP_TYPE_INTR: + case EP_TYPE_ISOC: + len_words = (uint16_t)((hc->xfer_len + 3U) / 4U); + /* check if there is enough space in FIFO space */ + if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */ + { + /* need to process data in ptxfempty interrupt */ + USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM; + } + break; + + default: + break; + } + + /* Write packet into the Tx FIFO. */ + (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len, 0); + } + + return HAL_OK; +} + +/** + * @brief Read all host channel interrupts status + * @param USBx Selected device + * @retval HAL state + */ +uint32_t USB_HC_ReadInterrupt(const USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + return ((USBx_HOST->HAINT) & 0xFFFFU); +} + +/** + * @brief Halt a host channel + * @param USBx Selected device + * @param hc_num Host Channel number + * This parameter can be a value from 1 to 15 + * @retval HAL state + */ +HAL_StatusTypeDef USB_HC_Halt(const USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t hcnum = (uint32_t)hc_num; + __IO uint32_t count = 0U; + uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18; + uint32_t ChannelEna = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) >> 31; + uint32_t SplitEna = (USBx_HC(hcnum)->HCSPLT & USB_OTG_HCSPLT_SPLITEN) >> 31; + + /* In buffer DMA, Channel disable must not be programmed for non-split periodic channels. + At the end of the next uframe/frame (in the worst case), the core generates a channel halted + and disables the channel automatically. */ + + if ((((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == USB_OTG_GAHBCFG_DMAEN) && (SplitEna == 0U)) && + ((ChannelEna == 0U) || (((HcEpType == HCCHAR_ISOC) || (HcEpType == HCCHAR_INTR))))) + { + return HAL_OK; + } + + /* Check for space in the request queue to issue the halt. */ + if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK)) + { + USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS; + + if ((USBx->GAHBCFG & USB_OTG_GAHBCFG_DMAEN) == 0U) + { + if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U) + { + USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA; + USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + do + { + count++; + + if (count > 1000U) + { + break; + } + } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); + } + else + { + USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + } + } + else + { + USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + } + } + else + { + USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS; + + if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U) + { + USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA; + USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + do + { + count++; + + if (count > 1000U) + { + break; + } + } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); + } + else + { + USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + } + } + + return HAL_OK; +} + +/** + * @brief Initiate Do Ping protocol + * @param USBx Selected device + * @param hc_num Host Channel number + * This parameter can be a value from 1 to 15 + * @retval HAL state + */ +HAL_StatusTypeDef USB_DoPing(const USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + uint32_t chnum = (uint32_t)ch_num; + uint32_t num_packets = 1U; + uint32_t tmpreg; + + USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) | + USB_OTG_HCTSIZ_DOPING; + + /* Set host channel enable */ + tmpreg = USBx_HC(chnum)->HCCHAR; + tmpreg &= ~USB_OTG_HCCHAR_CHDIS; + tmpreg |= USB_OTG_HCCHAR_CHENA; + USBx_HC(chnum)->HCCHAR = tmpreg; + + return HAL_OK; +} + +/** + * @brief Stop Host Core + * @param USBx Selected device + * @retval HAL state + */ +HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx) +{ + HAL_StatusTypeDef ret = HAL_OK; + uint32_t USBx_BASE = (uint32_t)USBx; + __IO uint32_t count = 0U; + uint32_t value; + uint32_t i; + + (void)USB_DisableGlobalInt(USBx); + + /* Flush USB FIFO */ + if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */ + { + ret = HAL_ERROR; + } + + if (USB_FlushRxFifo(USBx) != HAL_OK) + { + ret = HAL_ERROR; + } + + /* Flush out any leftover queued requests. */ + for (i = 0U; i <= 15U; i++) + { + value = USBx_HC(i)->HCCHAR; + value |= USB_OTG_HCCHAR_CHDIS; + value &= ~USB_OTG_HCCHAR_CHENA; + value &= ~USB_OTG_HCCHAR_EPDIR; + USBx_HC(i)->HCCHAR = value; + } + + /* Halt all channels to put them into a known state. */ + for (i = 0U; i <= 15U; i++) + { + value = USBx_HC(i)->HCCHAR; + value |= USB_OTG_HCCHAR_CHDIS; + value |= USB_OTG_HCCHAR_CHENA; + value &= ~USB_OTG_HCCHAR_EPDIR; + USBx_HC(i)->HCCHAR = value; + + do + { + count++; + + if (count > 1000U) + { + break; + } + } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); + } + + /* Clear any pending Host interrupts */ + USBx_HOST->HAINT = CLEAR_INTERRUPT_MASK; + USBx->GINTSTS = CLEAR_INTERRUPT_MASK; + + (void)USB_EnableGlobalInt(USBx); + + return ret; +} + +/** + * @brief USB_ActivateRemoteWakeup active remote wakeup signalling + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_ActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) + { + /* active Remote wakeup signalling */ + USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG; + } + + return HAL_OK; +} + +/** + * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling + * @param USBx Selected device + * @retval HAL status + */ +HAL_StatusTypeDef USB_DeActivateRemoteWakeup(const USB_OTG_GlobalTypeDef *USBx) +{ + uint32_t USBx_BASE = (uint32_t)USBx; + + /* active Remote wakeup signalling */ + USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG); + + return HAL_OK; +} +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ + +/** + * @} + */ + +/** + * @} + */ +#endif /* defined (USB_OTG_FS) || defined (USB_OTG_HS) */ +#endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */ + +/** + * @} + */ diff --git a/board/CubeMX_Config/Inc/stm32h7xx_hal_conf.h b/board/CubeMX_Config/Inc/stm32h7xx_hal_conf.h index 9c33c52..9eae003 100644 --- a/board/CubeMX_Config/Inc/stm32h7xx_hal_conf.h +++ b/board/CubeMX_Config/Inc/stm32h7xx_hal_conf.h @@ -72,7 +72,7 @@ /* #define HAL_SD_MODULE_ENABLED */ /* #define HAL_MMC_MODULE_ENABLED */ /* #define HAL_SPDIFRX_MODULE_ENABLED */ -#define HAL_SPI_MODULE_ENABLED +/* #define HAL_SPI_MODULE_ENABLED */ /* #define HAL_SWPMI_MODULE_ENABLED */ /* #define HAL_TIM_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED @@ -80,7 +80,7 @@ /* #define HAL_IRDA_MODULE_ENABLED */ /* #define HAL_SMARTCARD_MODULE_ENABLED */ /* #define HAL_WWDG_MODULE_ENABLED */ -/* #define HAL_PCD_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED /* #define HAL_HCD_MODULE_ENABLED */ /* #define HAL_DFSDM_MODULE_ENABLED */ /* #define HAL_DSI_MODULE_ENABLED */ diff --git a/board/CubeMX_Config/Inc/stm32h7xx_it.h b/board/CubeMX_Config/Inc/stm32h7xx_it.h index e073db9..1b7bd93 100644 --- a/board/CubeMX_Config/Inc/stm32h7xx_it.h +++ b/board/CubeMX_Config/Inc/stm32h7xx_it.h @@ -55,6 +55,7 @@ void SVC_Handler(void); void DebugMon_Handler(void); void PendSV_Handler(void); void SysTick_Handler(void); +void OTG_FS_IRQHandler(void); /* USER CODE BEGIN EFP */ /* USER CODE END EFP */ diff --git a/board/CubeMX_Config/Inc/usb_device.h b/board/CubeMX_Config/Inc/usb_device.h new file mode 100644 index 0000000..59ae196 --- /dev/null +++ b/board/CubeMX_Config/Inc/usb_device.h @@ -0,0 +1,102 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usb_device.h + * @version : v1.0_Cube + * @brief : Header for usb_device.c file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_DEVICE__H__ +#define __USB_DEVICE__H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx.h" +#include "stm32h7xx_hal.h" +#include "usbd_def.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/** @addtogroup USBD_OTG_DRIVER + * @{ + */ + +/** @defgroup USBD_DEVICE USBD_DEVICE + * @brief Device file for Usb otg low level driver. + * @{ + */ + +/** @defgroup USBD_DEVICE_Exported_Variables USBD_DEVICE_Exported_Variables + * @brief Public variables. + * @{ + */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* + * -- Insert your variables declaration here -- + */ +/* USER CODE BEGIN VARIABLES */ + +/* USER CODE END VARIABLES */ +/** + * @} + */ + +/** @defgroup USBD_DEVICE_Exported_FunctionsPrototype USBD_DEVICE_Exported_FunctionsPrototype + * @brief Declaration of public functions for Usb device. + * @{ + */ + +/** USB Device initialization function. */ +void MX_USB_DEVICE_Init(void); + +/* + * -- Insert functions declaration here -- + */ +/* USER CODE BEGIN FD */ + +/* USER CODE END FD */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_DEVICE__H__ */ diff --git a/board/CubeMX_Config/Inc/usbd_cdc_if.h b/board/CubeMX_Config/Inc/usbd_cdc_if.h new file mode 100644 index 0000000..772877e --- /dev/null +++ b/board/CubeMX_Config/Inc/usbd_cdc_if.h @@ -0,0 +1,132 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_cdc_if.h + * @version : v1.0_Cube + * @brief : Header for usbd_cdc_if.c file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ + +#ifndef __USBD_CDC_IF_H__ +#define __USBD_CDC_IF_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @brief For Usb device. + * @{ + */ + +/** @defgroup USBD_CDC_IF USBD_CDC_IF + * @brief Usb VCP device module + * @{ + */ + +/** @defgroup USBD_CDC_IF_Exported_Defines USBD_CDC_IF_Exported_Defines + * @brief Defines. + * @{ + */ +/* Define size for the receive and transmit buffer over CDC */ +#define APP_RX_DATA_SIZE 2048 +#define APP_TX_DATA_SIZE 2048 +/* USER CODE BEGIN EXPORTED_DEFINES */ + +/* USER CODE END EXPORTED_DEFINES */ + +/** + * @} + */ + +/** @defgroup USBD_CDC_IF_Exported_Types USBD_CDC_IF_Exported_Types + * @brief Types. + * @{ + */ + +/* USER CODE BEGIN EXPORTED_TYPES */ + +/* USER CODE END EXPORTED_TYPES */ + +/** + * @} + */ + +/** @defgroup USBD_CDC_IF_Exported_Macros USBD_CDC_IF_Exported_Macros + * @brief Aliases. + * @{ + */ + +/* USER CODE BEGIN EXPORTED_MACRO */ + +/* USER CODE END EXPORTED_MACRO */ + +/** + * @} + */ + +/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables + * @brief Public variables. + * @{ + */ + +/** CDC Interface callback. */ +extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; + +/* USER CODE BEGIN EXPORTED_VARIABLES */ + +/* USER CODE END EXPORTED_VARIABLES */ + +/** + * @} + */ + +/** @defgroup USBD_CDC_IF_Exported_FunctionsPrototype USBD_CDC_IF_Exported_FunctionsPrototype + * @brief Public functions declaration. + * @{ + */ + +uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); + +/* USER CODE BEGIN EXPORTED_FUNCTIONS */ + +/* USER CODE END EXPORTED_FUNCTIONS */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CDC_IF_H__ */ + diff --git a/board/CubeMX_Config/Inc/usbd_conf.h b/board/CubeMX_Config/Inc/usbd_conf.h new file mode 100644 index 0000000..00a46dc --- /dev/null +++ b/board/CubeMX_Config/Inc/usbd_conf.h @@ -0,0 +1,173 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_conf.h + * @version : v1.0_Cube + * @brief : Header for usbd_conf.c file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CONF__H__ +#define __USBD_CONF__H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include +#include +#include "main.h" +#include "stm32h7xx.h" +#include "stm32h7xx_hal.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/** @addtogroup USBD_OTG_DRIVER + * @brief Driver for Usb device. + * @{ + */ + +/** @defgroup USBD_CONF USBD_CONF + * @brief Configuration file for Usb otg low level driver. + * @{ + */ + +/** @defgroup USBD_CONF_Exported_Variables USBD_CONF_Exported_Variables + * @brief Public variables. + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CONF_Exported_Defines USBD_CONF_Exported_Defines + * @brief Defines for configuration of the Usb device. + * @{ + */ + +/*---------- -----------*/ +#define USBD_MAX_NUM_INTERFACES 1U +/*---------- -----------*/ +#define USBD_MAX_NUM_CONFIGURATION 1U +/*---------- -----------*/ +#define USBD_MAX_STR_DESC_SIZ 512U +/*---------- -----------*/ +#define USBD_DEBUG_LEVEL 0U +/*---------- -----------*/ +#define USBD_LPM_ENABLED 1U +/*---------- -----------*/ +#define USBD_SELF_POWERED 1U + +/****************************************/ +/* #define for FS and HS identification */ +#define DEVICE_FS 0 +#define DEVICE_HS 1 + +/** + * @} + */ + +/** @defgroup USBD_CONF_Exported_Macros USBD_CONF_Exported_Macros + * @brief Aliases. + * @{ + */ +/* Memory management macros make sure to use static memory allocation */ +/** Alias for memory allocation. */ + +#define USBD_malloc (void *)USBD_static_malloc + +/** Alias for memory release. */ +#define USBD_free USBD_static_free + +/** Alias for memory set. */ +#define USBD_memset memset + +/** Alias for memory copy. */ +#define USBD_memcpy memcpy + +/** Alias for delay. */ +#define USBD_Delay HAL_Delay + +/* DEBUG macros */ + +#if (USBD_DEBUG_LEVEL > 0) +#define USBD_UsrLog(...) printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_UsrLog(...) +#endif /* (USBD_DEBUG_LEVEL > 0U) */ + +#if (USBD_DEBUG_LEVEL > 1) + +#define USBD_ErrLog(...) printf("ERROR: ");\ + printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_ErrLog(...) +#endif /* (USBD_DEBUG_LEVEL > 1U) */ + +#if (USBD_DEBUG_LEVEL > 2) +#define USBD_DbgLog(...) printf("DEBUG : ");\ + printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_DbgLog(...) +#endif /* (USBD_DEBUG_LEVEL > 2U) */ + +/** + * @} + */ + +/** @defgroup USBD_CONF_Exported_Types USBD_CONF_Exported_Types + * @brief Types. + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CONF_Exported_FunctionsPrototype USBD_CONF_Exported_FunctionsPrototype + * @brief Declaration of public functions for Usb device. + * @{ + */ + +/* Exported functions -------------------------------------------------------*/ +void *USBD_static_malloc(uint32_t size); +void USBD_static_free(void *p); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CONF__H__ */ + diff --git a/board/CubeMX_Config/Inc/usbd_desc.h b/board/CubeMX_Config/Inc/usbd_desc.h new file mode 100644 index 0000000..6fbcfd6 --- /dev/null +++ b/board/CubeMX_Config/Inc/usbd_desc.h @@ -0,0 +1,143 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_desc.c + * @version : v1.0_Cube + * @brief : Header for usbd_conf.c file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_DESC__C__ +#define __USBD_DESC__C__ + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_DESC USBD_DESC + * @brief Usb device descriptors module. + * @{ + */ + +/** @defgroup USBD_DESC_Exported_Constants USBD_DESC_Exported_Constants + * @brief Constants. + * @{ + */ +#define DEVICE_ID1 (UID_BASE) +#define DEVICE_ID2 (UID_BASE + 0x4) +#define DEVICE_ID3 (UID_BASE + 0x8) + +#define USB_SIZ_STRING_SERIAL 0x1A + +/* USER CODE BEGIN EXPORTED_CONSTANTS */ + +/* USER CODE END EXPORTED_CONSTANTS */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Exported_Defines USBD_DESC_Exported_Defines + * @brief Defines. + * @{ + */ + +/* USER CODE BEGIN EXPORTED_DEFINES */ + +/* USER CODE END EXPORTED_DEFINES */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Exported_TypesDefinitions USBD_DESC_Exported_TypesDefinitions + * @brief Types. + * @{ + */ + +/* USER CODE BEGIN EXPORTED_TYPES */ + +/* USER CODE END EXPORTED_TYPES */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Exported_Macros USBD_DESC_Exported_Macros + * @brief Aliases. + * @{ + */ + +/* USER CODE BEGIN EXPORTED_MACRO */ + +/* USER CODE END EXPORTED_MACRO */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Exported_Variables USBD_DESC_Exported_Variables + * @brief Public variables. + * @{ + */ + +/** Descriptor for the Usb device. */ +extern USBD_DescriptorsTypeDef FS_Desc; + +/* USER CODE BEGIN EXPORTED_VARIABLES */ + +/* USER CODE END EXPORTED_VARIABLES */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Exported_FunctionsPrototype USBD_DESC_Exported_FunctionsPrototype + * @brief Public functions declaration. + * @{ + */ + +/* USER CODE BEGIN EXPORTED_FUNCTIONS */ + +/* USER CODE END EXPORTED_FUNCTIONS */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_DESC__C__ */ + diff --git a/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h new file mode 100644 index 0000000..aeac6bf --- /dev/null +++ b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h @@ -0,0 +1,184 @@ +/** + ****************************************************************************** + * @file usbd_cdc.h + * @author MCD Application Team + * @brief header file for the usbd_cdc.c file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CDC_H +#define __USB_CDC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_cdc + * @brief This file is the Header file for usbd_cdc.c + * @{ + */ + + +/** @defgroup usbd_cdc_Exported_Defines + * @{ + */ +#ifndef CDC_IN_EP +#define CDC_IN_EP 0x81U /* EP1 for data IN */ +#endif /* CDC_IN_EP */ +#ifndef CDC_OUT_EP +#define CDC_OUT_EP 0x01U /* EP1 for data OUT */ +#endif /* CDC_OUT_EP */ +#ifndef CDC_CMD_EP +#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */ +#endif /* CDC_CMD_EP */ + +#ifndef CDC_HS_BINTERVAL +#define CDC_HS_BINTERVAL 0x10U +#endif /* CDC_HS_BINTERVAL */ + +#ifndef CDC_FS_BINTERVAL +#define CDC_FS_BINTERVAL 0x10U +#endif /* CDC_FS_BINTERVAL */ + +/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ +#define CDC_DATA_HS_MAX_PACKET_SIZE 512U /* Endpoint IN & OUT Packet size */ +#define CDC_DATA_FS_MAX_PACKET_SIZE 64U /* Endpoint IN & OUT Packet size */ +#define CDC_CMD_PACKET_SIZE 8U /* Control Endpoint Packet size */ + +#define USB_CDC_CONFIG_DESC_SIZ 67U +#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE +#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE + +#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE +#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE + +#define CDC_REQ_MAX_DATA_SIZE 0x7U +/*---------------------------------------------------------------------*/ +/* CDC definitions */ +/*---------------------------------------------------------------------*/ +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00U +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01U +#define CDC_SET_COMM_FEATURE 0x02U +#define CDC_GET_COMM_FEATURE 0x03U +#define CDC_CLEAR_COMM_FEATURE 0x04U +#define CDC_SET_LINE_CODING 0x20U +#define CDC_GET_LINE_CODING 0x21U +#define CDC_SET_CONTROL_LINE_STATE 0x22U +#define CDC_SEND_BREAK 0x23U + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ +typedef struct +{ + uint32_t bitrate; + uint8_t format; + uint8_t paritytype; + uint8_t datatype; +} USBD_CDC_LineCodingTypeDef; + +typedef struct _USBD_CDC_Itf +{ + int8_t (* Init)(void); + int8_t (* DeInit)(void); + int8_t (* Control)(uint8_t cmd, uint8_t *pbuf, uint16_t length); + int8_t (* Receive)(uint8_t *Buf, uint32_t *Len); + int8_t (* TransmitCplt)(uint8_t *Buf, uint32_t *Len, uint8_t epnum); +} USBD_CDC_ItfTypeDef; + + +typedef struct +{ + uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32-bit alignment */ + uint8_t CmdOpCode; + uint8_t CmdLength; + uint8_t *RxBuffer; + uint8_t *TxBuffer; + uint32_t RxLength; + uint32_t TxLength; + + __IO uint32_t TxState; + __IO uint32_t RxState; +} USBD_CDC_HandleTypeDef; + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_CDC; +#define USBD_CDC_CLASS &USBD_CDC +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops); + +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, + uint32_t length, uint8_t ClassId); +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId); +#else +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, + uint32_t length); +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev); +#endif /* USE_USBD_COMPOSITE */ +uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff); +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_CDC_H */ +/** + * @} + */ + +/** + * @} + */ + diff --git a/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c new file mode 100644 index 0000000..ad8da25 --- /dev/null +++ b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -0,0 +1,893 @@ +/** + ****************************************************************************** + * @file usbd_cdc.c + * @author MCD Application Team + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB CDC Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as CDC Device (and enumeration for each implemented memory interface) + * - OUT/IN data transfer + * - Command IN transfer (class requests management) + * - Error management + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + * @verbatim + * + * =================================================================== + * CDC Class Driver Description + * =================================================================== + * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices + * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus + * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007" + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN) + * - Requests management (as described in section 6.2 in specification) + * - Abstract Control Model compliant + * - Union Functional collection (using 1 IN endpoint for control) + * - Data interface class + * + * These aspects may be enriched or modified for a specific user application. + * + * This driver doesn't implement the following aspects of the specification + * (but it is possible to manage these features with some modifications on this driver): + * - Any class-specific aspect relative to communication classes should be managed by user application. + * - All communication classes other than PSTN are not managed + * + * @endverbatim + * + ****************************************************************************** + */ + +/* BSPDependencies +- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c" +- "stm32xxxxx_{eval}{discovery}_io.c" +EndBSPDependencies */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_CDC + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_CDC_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_FunctionPrototypes + * @{ + */ + +static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev); +#ifndef USE_USBD_COMPOSITE +static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length); +static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length); +static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length); +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length); +#endif /* USE_USBD_COMPOSITE */ + +#ifndef USE_USBD_COMPOSITE +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; +#endif /* USE_USBD_COMPOSITE */ +/** + * @} + */ + +/** @defgroup USBD_CDC_Private_Variables + * @{ + */ + + +/* CDC interface class callbacks structure */ +USBD_ClassTypeDef USBD_CDC = +{ + USBD_CDC_Init, + USBD_CDC_DeInit, + USBD_CDC_Setup, + NULL, /* EP0_TxSent */ + USBD_CDC_EP0_RxReady, + USBD_CDC_DataIn, + USBD_CDC_DataOut, + NULL, + NULL, + NULL, +#ifdef USE_USBD_COMPOSITE + NULL, + NULL, + NULL, + NULL, +#else + USBD_CDC_GetHSCfgDesc, + USBD_CDC_GetFSCfgDesc, + USBD_CDC_GetOtherSpeedCfgDesc, + USBD_CDC_GetDeviceQualifierDescriptor, +#endif /* USE_USBD_COMPOSITE */ +}; + +#ifndef USE_USBD_COMPOSITE +/* USB CDC device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + /* Configuration Descriptor */ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength */ + 0x00, + 0x02, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor + describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif /* USBD_SELF_POWERED */ + USBD_MAX_POWER, /* MaxPower (mA) */ + + /*---------------------------------------------------------------------------*/ + + /* Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoint used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface */ + + /* Header Functional Descriptor */ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /* Call Management Functional Descriptor */ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface */ + + /* ACM Functional Descriptor */ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /* Union Functional Descriptor */ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /* Endpoint 2 Descriptor */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */ + HIBYTE(CDC_CMD_PACKET_SIZE), + CDC_FS_BINTERVAL, /* bInterval */ + /*---------------------------------------------------------------------------*/ + + /* Data class interface descriptor */ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + + /* Endpoint OUT Descriptor */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00, /* bInterval */ + + /* Endpoint IN Descriptor */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00 /* bInterval */ +}; +#endif /* USE_USBD_COMPOSITE */ + +static uint8_t CDCInEpAdd = CDC_IN_EP; +static uint8_t CDCOutEpAdd = CDC_OUT_EP; +static uint8_t CDCCmdEpAdd = CDC_CMD_EP; + +/** + * @} + */ + +/** @defgroup USBD_CDC_Private_Functions + * @{ + */ + +/** + * @brief USBD_CDC_Init + * Initialize the CDC interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + USBD_CDC_HandleTypeDef *hcdc; + + hcdc = (USBD_CDC_HandleTypeDef *)USBD_malloc(sizeof(USBD_CDC_HandleTypeDef)); + + if (hcdc == NULL) + { + pdev->pClassDataCmsit[pdev->classId] = NULL; + return (uint8_t)USBD_EMEM; + } + + (void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_HandleTypeDef)); + + pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc; + pdev->pClassData = pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Open EP IN */ + (void)USBD_LL_OpenEP(pdev, CDCInEpAdd, USBD_EP_TYPE_BULK, + CDC_DATA_HS_IN_PACKET_SIZE); + + pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U; + + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, CDCOutEpAdd, USBD_EP_TYPE_BULK, + CDC_DATA_HS_OUT_PACKET_SIZE); + + pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U; + + /* Set bInterval for CDC CMD Endpoint */ + pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = CDC_HS_BINTERVAL; + } + else + { + /* Open EP IN */ + (void)USBD_LL_OpenEP(pdev, CDCInEpAdd, USBD_EP_TYPE_BULK, + CDC_DATA_FS_IN_PACKET_SIZE); + + pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U; + + /* Open EP OUT */ + (void)USBD_LL_OpenEP(pdev, CDCOutEpAdd, USBD_EP_TYPE_BULK, + CDC_DATA_FS_OUT_PACKET_SIZE); + + pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U; + + /* Set bInterval for CMD Endpoint */ + pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = CDC_FS_BINTERVAL; + } + + /* Open Command IN EP */ + (void)USBD_LL_OpenEP(pdev, CDCCmdEpAdd, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE); + pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 1U; + + hcdc->RxBuffer = NULL; + + /* Init physical Interface components */ + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init(); + + /* Init Xfer states */ + hcdc->TxState = 0U; + hcdc->RxState = 0U; + + if (hcdc->RxBuffer == NULL) + { + return (uint8_t)USBD_EMEM; + } + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer, + CDC_DATA_HS_OUT_PACKET_SIZE); + } + else + { + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_Init + * DeInitialize the CDC layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + UNUSED(cfgidx); + + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this CDC class instance */ + CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); + CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + /* Close EP IN */ + (void)USBD_LL_CloseEP(pdev, CDCInEpAdd); + pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 0U; + + /* Close EP OUT */ + (void)USBD_LL_CloseEP(pdev, CDCOutEpAdd); + pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 0U; + + /* Close Command IN EP */ + (void)USBD_LL_CloseEP(pdev, CDCCmdEpAdd); + pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 0U; + pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = 0U; + + /* DeInit physical Interface components */ + if (pdev->pClassDataCmsit[pdev->classId] != NULL) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit(); + (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]); + pdev->pClassDataCmsit[pdev->classId] = NULL; + pdev->pClassData = NULL; + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_Setup + * Handle the CDC specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + uint16_t len; + uint8_t ifalt = 0U; + uint16_t status_info = 0U; + USBD_StatusTypeDef ret = USBD_OK; + + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + if (req->wLength != 0U) + { + if ((req->bmRequest & 0x80U) != 0U) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest, + (uint8_t *)hcdc->data, + req->wLength); + + len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength); + (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len); + } + else + { + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE); + + (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength); + } + } + else + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest, + (uint8_t *)req, 0U); + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_STATUS: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_GET_INTERFACE: + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + (void)USBD_CtlSendData(pdev, &ifalt, 1U); + } + else + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_SET_INTERFACE: + if (pdev->dev_state != USBD_STATE_CONFIGURED) + { + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_CLEAR_FEATURE: + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + break; + + default: + USBD_CtlError(pdev, req); + ret = USBD_FAIL; + break; + } + + return (uint8_t)ret; +} + +/** + * @brief USBD_CDC_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CDC_HandleTypeDef *hcdc; + PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData; + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) + { + return (uint8_t)USBD_FAIL; + } + + hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) && + ((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U)) + { + /* Update the packet total length */ + pdev->ep_in[epnum & 0xFU].total_length = 0U; + + /* Send ZLP */ + (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U); + } + else + { + hcdc->TxState = 0U; + + if (((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt != NULL) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum); + } + } + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) + { + return (uint8_t)USBD_FAIL; + } + + /* Get the received data length */ + hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum); + + /* USB data will be immediately processed, this allow next USB traffic being + NAKed till the end of the application Xfer */ + + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hcdc->RxBuffer, &hcdc->RxLength); + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_EP0_RxReady + * Handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + + if ((pdev->pUserData[pdev->classId] != NULL) && (hcdc->CmdOpCode != 0xFFU)) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(hcdc->CmdOpCode, + (uint8_t *)hcdc->data, + (uint16_t)hcdc->CmdLength); + hcdc->CmdOpCode = 0xFFU; + } + + return (uint8_t)USBD_OK; +} +#ifndef USE_USBD_COMPOSITE +/** + * @brief USBD_CDC_GetFSCfgDesc + * Return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length) +{ + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP); + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_FS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE; + } + + *length = (uint16_t)sizeof(USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; +} + +/** + * @brief USBD_CDC_GetHSCfgDesc + * Return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length) +{ + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP); + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_HS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE; + } + + *length = (uint16_t)sizeof(USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; +} + +/** + * @brief USBD_CDC_GetOtherSpeedCfgDesc + * Return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length) +{ + USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP); + USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP); + USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP); + + if (pEpCmdDesc != NULL) + { + pEpCmdDesc->bInterval = CDC_FS_BINTERVAL; + } + + if (pEpOutDesc != NULL) + { + pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE; + } + + if (pEpInDesc != NULL) + { + pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE; + } + + *length = (uint16_t)sizeof(USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; +} + +/** + * @brief USBD_CDC_GetDeviceQualifierDescriptor + * return Device Qualifier descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length) +{ + *length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc); + + return USBD_CDC_DeviceQualifierDesc; +} +#endif /* USE_USBD_COMPOSITE */ +/** + * @brief USBD_CDC_RegisterInterface + * @param pdev: device instance + * @param fops: CD Interface callback + * @retval status + */ +uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops) +{ + if (fops == NULL) + { + return (uint8_t)USBD_FAIL; + } + + pdev->pUserData[pdev->classId] = fops; + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_SetTxBuffer + * @param pdev: device instance + * @param pbuff: Tx Buffer + * @param length: length of data to be sent + * @param ClassId: The Class ID + * @retval status + */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, uint32_t length, uint8_t ClassId) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else +uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, + uint8_t *pbuff, uint32_t length) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#endif /* USE_USBD_COMPOSITE */ + + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + + hcdc->TxBuffer = pbuff; + hcdc->TxLength = length; + + return (uint8_t)USBD_OK; +} + +/** + * @brief USBD_CDC_SetRxBuffer + * @param pdev: device instance + * @param pbuff: Rx Buffer + * @retval status + */ +uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + + hcdc->RxBuffer = pbuff; + + return (uint8_t)USBD_OK; +} + + +/** + * @brief USBD_CDC_TransmitPacket + * Transmit packet on IN endpoint + * @param pdev: device instance + * @param ClassId: The Class ID + * @retval status + */ +#ifdef USE_USBD_COMPOSITE +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[ClassId]; +#else +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; +#endif /* USE_USBD_COMPOSITE */ + + USBD_StatusTypeDef ret = USBD_BUSY; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, ClassId); +#endif /* USE_USBD_COMPOSITE */ + + if (hcdc == NULL) + { + return (uint8_t)USBD_FAIL; + } + + if (hcdc->TxState == 0U) + { + /* Tx Transfer in progress */ + hcdc->TxState = 1U; + + /* Update the packet total length */ + pdev->ep_in[CDCInEpAdd & 0xFU].total_length = hcdc->TxLength; + + /* Transmit next packet */ + (void)USBD_LL_Transmit(pdev, CDCInEpAdd, hcdc->TxBuffer, hcdc->TxLength); + + ret = USBD_OK; + } + + return (uint8_t)ret; +} + +/** + * @brief USBD_CDC_ReceivePacket + * prepare OUT Endpoint for reception + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; + +#ifdef USE_USBD_COMPOSITE + /* Get the Endpoints addresses allocated for this class instance */ + CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId); +#endif /* USE_USBD_COMPOSITE */ + + if (pdev->pClassDataCmsit[pdev->classId] == NULL) + { + return (uint8_t)USBD_FAIL; + } + + if (pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer, + CDC_DATA_HS_OUT_PACKET_SIZE); + } + else + { + /* Prepare Out endpoint to receive next packet */ + (void)USBD_LL_PrepareReceive(pdev, CDCOutEpAdd, hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); + } + + return (uint8_t)USBD_OK; +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h new file mode 100644 index 0000000..4672921 --- /dev/null +++ b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_core.h @@ -0,0 +1,175 @@ +/** + ****************************************************************************** + * @file usbd_core.h + * @author MCD Application Team + * @brief Header file for usbd_core.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CORE_H +#define __USBD_CORE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" +#include "usbd_def.h" +#include "usbd_ioreq.h" +#include "usbd_ctlreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_CORE + * @brief This file is the Header file for usbd_core.c file + * @{ + */ + + +/** @defgroup USBD_CORE_Exported_Defines + * @{ + */ +#ifndef USBD_DEBUG_LEVEL +#define USBD_DEBUG_LEVEL 0U +#endif /* USBD_DEBUG_LEVEL */ +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ +#define USBD_SOF USBD_LL_SOF +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_FunctionsPrototype + * @{ + */ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id); +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); +#if (USBD_USER_REGISTER_CALLBACK == 1U) +USBD_StatusTypeDef USBD_RegisterDevStateCallback(USBD_HandleTypeDef *pdev, USBD_DevStateCallbackTypeDef pUserCallback); +#endif /* USBD_USER_REGISTER_CALLBACK */ + +#ifdef USE_USBD_COMPOSITE +USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass, + USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr); + +USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev); +uint8_t USBD_CoreGetEPAdd(USBD_HandleTypeDef *pdev, uint8_t ep_dir, uint8_t ep_type, uint8_t ClassId); +#endif /* USE_USBD_COMPOSITE */ + +uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index); +uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index); + +USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup); +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata); +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum, uint8_t *pdata); + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed); +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev); + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); + +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); + +/* USBD Low Level Driver */ +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev); + +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, + uint8_t ep_type, uint16_t ep_mps); + +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr); + +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, + uint8_t *pbuf, uint32_t size); + +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, + uint8_t *pbuf, uint32_t size); + +#ifdef USBD_HS_TESTMODE_ENABLE +USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev, uint8_t testmode); +#endif /* USBD_HS_TESTMODE_ENABLE */ + +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr); +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr); + +void USBD_LL_Delay(uint32_t Delay); + +void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr); +USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CORE_H */ + +/** + * @} + */ + +/** + * @} + */ + + diff --git a/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h new file mode 100644 index 0000000..6c45d6c --- /dev/null +++ b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ctlreq.h @@ -0,0 +1,101 @@ +/** + ****************************************************************************** + * @file usbd_req.h + * @author MCD Application Team + * @brief Header file for the usbd_req.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_REQUEST_H +#define __USB_REQUEST_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_REQ + * @brief header file for the usbd_req.c file + * @{ + */ + +/** @defgroup USBD_REQ_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Exported_Types + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_REQ_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_REQ_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_REQ_Exported_FunctionsPrototype + * @{ + */ + +USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata); +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_REQUEST_H */ + +/** + * @} + */ + +/** + * @} + */ + + diff --git a/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h new file mode 100644 index 0000000..2a295d7 --- /dev/null +++ b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h @@ -0,0 +1,523 @@ +/** + ****************************************************************************** + * @file usbd_def.h + * @author MCD Application Team + * @brief General defines for the usb device library + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_DEF_H +#define __USBD_DEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" + +/** @addtogroup STM32_USBD_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USB_DEF + * @brief general defines for the usb device library file + * @{ + */ + +/** @defgroup USB_DEF_Exported_Defines + * @{ + */ + +#ifndef NULL +#define NULL 0U +#endif /* NULL */ + +#ifndef USBD_MAX_NUM_INTERFACES +#define USBD_MAX_NUM_INTERFACES 1U +#endif /* USBD_MAX_NUM_CONFIGURATION */ + +#ifndef USBD_MAX_NUM_CONFIGURATION +#define USBD_MAX_NUM_CONFIGURATION 1U +#endif /* USBD_MAX_NUM_CONFIGURATION */ + +#ifdef USE_USBD_COMPOSITE +#ifndef USBD_MAX_SUPPORTED_CLASS +#define USBD_MAX_SUPPORTED_CLASS 4U +#endif /* USBD_MAX_SUPPORTED_CLASS */ +#else +#ifndef USBD_MAX_SUPPORTED_CLASS +#define USBD_MAX_SUPPORTED_CLASS 1U +#endif /* USBD_MAX_SUPPORTED_CLASS */ +#endif /* USE_USBD_COMPOSITE */ + +#ifndef USBD_MAX_CLASS_ENDPOINTS +#define USBD_MAX_CLASS_ENDPOINTS 5U +#endif /* USBD_MAX_CLASS_ENDPOINTS */ + +#ifndef USBD_MAX_CLASS_INTERFACES +#define USBD_MAX_CLASS_INTERFACES 5U +#endif /* USBD_MAX_CLASS_INTERFACES */ + +#ifndef USBD_LPM_ENABLED +#define USBD_LPM_ENABLED 0U +#endif /* USBD_LPM_ENABLED */ + +#ifndef USBD_SELF_POWERED +#define USBD_SELF_POWERED 1U +#endif /*USBD_SELF_POWERED */ + +#ifndef USBD_MAX_POWER +#define USBD_MAX_POWER 0x32U /* 100 mA */ +#endif /* USBD_MAX_POWER */ + +#ifndef USBD_SUPPORT_USER_STRING_DESC +#define USBD_SUPPORT_USER_STRING_DESC 0U +#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +#ifndef USBD_CLASS_USER_STRING_DESC +#define USBD_CLASS_USER_STRING_DESC 0U +#endif /* USBD_CLASS_USER_STRING_DESC */ + +#define USB_LEN_DEV_QUALIFIER_DESC 0x0AU +#define USB_LEN_DEV_DESC 0x12U +#define USB_LEN_CFG_DESC 0x09U +#define USB_LEN_IF_DESC 0x09U +#define USB_LEN_EP_DESC 0x07U +#define USB_LEN_OTG_DESC 0x03U +#define USB_LEN_LANGID_STR_DESC 0x04U +#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09U + +#define USBD_IDX_LANGID_STR 0x00U +#define USBD_IDX_MFC_STR 0x01U +#define USBD_IDX_PRODUCT_STR 0x02U +#define USBD_IDX_SERIAL_STR 0x03U +#define USBD_IDX_CONFIG_STR 0x04U +#define USBD_IDX_INTERFACE_STR 0x05U + +#define USB_REQ_TYPE_STANDARD 0x00U +#define USB_REQ_TYPE_CLASS 0x20U +#define USB_REQ_TYPE_VENDOR 0x40U +#define USB_REQ_TYPE_MASK 0x60U + +#define USB_REQ_RECIPIENT_DEVICE 0x00U +#define USB_REQ_RECIPIENT_INTERFACE 0x01U +#define USB_REQ_RECIPIENT_ENDPOINT 0x02U +#define USB_REQ_RECIPIENT_MASK 0x03U + +#define USB_REQ_GET_STATUS 0x00U +#define USB_REQ_CLEAR_FEATURE 0x01U +#define USB_REQ_SET_FEATURE 0x03U +#define USB_REQ_SET_ADDRESS 0x05U +#define USB_REQ_GET_DESCRIPTOR 0x06U +#define USB_REQ_SET_DESCRIPTOR 0x07U +#define USB_REQ_GET_CONFIGURATION 0x08U +#define USB_REQ_SET_CONFIGURATION 0x09U +#define USB_REQ_GET_INTERFACE 0x0AU +#define USB_REQ_SET_INTERFACE 0x0BU +#define USB_REQ_SYNCH_FRAME 0x0CU + +#define USB_DESC_TYPE_DEVICE 0x01U +#define USB_DESC_TYPE_CONFIGURATION 0x02U +#define USB_DESC_TYPE_STRING 0x03U +#define USB_DESC_TYPE_INTERFACE 0x04U +#define USB_DESC_TYPE_ENDPOINT 0x05U +#define USB_DESC_TYPE_DEVICE_QUALIFIER 0x06U +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 0x07U +#define USB_DESC_TYPE_IAD 0x0BU +#define USB_DESC_TYPE_BOS 0x0FU + +#define USB_CONFIG_REMOTE_WAKEUP 0x02U +#define USB_CONFIG_SELF_POWERED 0x01U + +#define USB_FEATURE_EP_HALT 0x00U +#define USB_FEATURE_REMOTE_WAKEUP 0x01U +#define USB_FEATURE_TEST_MODE 0x02U + +#define USB_DEVICE_CAPABITY_TYPE 0x10U + +#define USB_CONF_DESC_SIZE 0x09U +#define USB_IF_DESC_SIZE 0x09U +#define USB_EP_DESC_SIZE 0x07U +#define USB_IAD_DESC_SIZE 0x08U + +#define USB_HS_MAX_PACKET_SIZE 512U +#define USB_FS_MAX_PACKET_SIZE 64U +#define USB_MAX_EP0_SIZE 64U + +/* Device Status */ +#define USBD_STATE_DEFAULT 0x01U +#define USBD_STATE_ADDRESSED 0x02U +#define USBD_STATE_CONFIGURED 0x03U +#define USBD_STATE_SUSPENDED 0x04U + + +/* EP0 State */ +#define USBD_EP0_IDLE 0x00U +#define USBD_EP0_SETUP 0x01U +#define USBD_EP0_DATA_IN 0x02U +#define USBD_EP0_DATA_OUT 0x03U +#define USBD_EP0_STATUS_IN 0x04U +#define USBD_EP0_STATUS_OUT 0x05U +#define USBD_EP0_STALL 0x06U + +#define USBD_EP_TYPE_CTRL 0x00U +#define USBD_EP_TYPE_ISOC 0x01U +#define USBD_EP_TYPE_BULK 0x02U +#define USBD_EP_TYPE_INTR 0x03U + +#ifdef USE_USBD_COMPOSITE +#define USBD_EP_IN 0x80U +#define USBD_EP_OUT 0x00U +#define USBD_FUNC_DESCRIPTOR_TYPE 0x24U +#define USBD_DESC_SUBTYPE_ACM 0x0FU +#define USBD_DESC_ECM_BCD_LOW 0x00U +#define USBD_DESC_ECM_BCD_HIGH 0x10U +#endif /* USE_USBD_COMPOSITE */ +/** + * @} + */ + + +/** @defgroup USBD_DEF_Exported_TypesDefinitions + * @{ + */ + +typedef struct usb_setup_req +{ + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} USBD_SetupReqTypedef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} __PACKED USBD_ConfigDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumDeviceCaps; +} USBD_BosDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __PACKED USBD_EpDescTypeDef; + +typedef struct +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDescriptorSubType; +} USBD_DescHeaderTypeDef; + +struct _USBD_HandleTypeDef; + +typedef struct _Device_cb +{ + uint8_t (*Init)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx); + uint8_t (*DeInit)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx); + /* Control Endpoints*/ + uint8_t (*Setup)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + uint8_t (*EP0_TxSent)(struct _USBD_HandleTypeDef *pdev); + uint8_t (*EP0_RxReady)(struct _USBD_HandleTypeDef *pdev); + /* Class Specific Endpoints*/ + uint8_t (*DataIn)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + uint8_t (*DataOut)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + uint8_t (*SOF)(struct _USBD_HandleTypeDef *pdev); + uint8_t (*IsoINIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + uint8_t (*IsoOUTIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum); + + uint8_t *(*GetHSConfigDescriptor)(uint16_t *length); + uint8_t *(*GetFSConfigDescriptor)(uint16_t *length); + uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length); + uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length); +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); +#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +} USBD_ClassTypeDef; + +/* Following USB Device Speed */ +typedef enum +{ + USBD_SPEED_HIGH = 0U, + USBD_SPEED_FULL = 1U, + USBD_SPEED_LOW = 2U, +} USBD_SpeedTypeDef; + +/* Following USB Device status */ +typedef enum +{ + USBD_OK = 0U, + USBD_BUSY, + USBD_EMEM, + USBD_FAIL, +} USBD_StatusTypeDef; + +/* USB Device descriptors structure */ +typedef struct +{ + uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); + uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); +#if (USBD_CLASS_USER_STRING_DESC == 1) + uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length); +#endif /* USBD_CLASS_USER_STRING_DESC */ +#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1)) + uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length); +#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1) */ +} USBD_DescriptorsTypeDef; + +/* USB Device handle structure */ +typedef struct +{ + uint32_t status; + uint32_t total_length; + uint32_t rem_length; + uint32_t maxpacket; + uint16_t is_used; + uint16_t bInterval; +} USBD_EndpointTypeDef; + +#ifdef USE_USBD_COMPOSITE +typedef enum +{ + CLASS_TYPE_NONE = 0, + CLASS_TYPE_HID = 1, + CLASS_TYPE_CDC = 2, + CLASS_TYPE_MSC = 3, + CLASS_TYPE_DFU = 4, + CLASS_TYPE_CHID = 5, + CLASS_TYPE_AUDIO = 6, + CLASS_TYPE_ECM = 7, + CLASS_TYPE_RNDIS = 8, + CLASS_TYPE_MTP = 9, + CLASS_TYPE_VIDEO = 10, + CLASS_TYPE_PRINTER = 11, + CLASS_TYPE_CCID = 12, +} USBD_CompositeClassTypeDef; + + +/* USB Device handle structure */ +typedef struct +{ + uint8_t add; + uint8_t type; + uint8_t size; + uint8_t is_used; +} USBD_EPTypeDef; + +/* USB Device handle structure */ +typedef struct +{ + USBD_CompositeClassTypeDef ClassType; + uint32_t ClassId; + uint32_t Active; + uint32_t NumEps; + USBD_EPTypeDef Eps[USBD_MAX_CLASS_ENDPOINTS]; + uint8_t *EpAdd; + uint32_t NumIf; + uint8_t Ifs[USBD_MAX_CLASS_INTERFACES]; + uint32_t CurrPcktSze; +} USBD_CompositeElementTypeDef; +#endif /* USE_USBD_COMPOSITE */ + +/* USB Device handle structure */ +typedef struct _USBD_HandleTypeDef +{ + uint8_t id; + uint32_t dev_config; + uint32_t dev_default_config; + uint32_t dev_config_status; + USBD_SpeedTypeDef dev_speed; + USBD_EndpointTypeDef ep_in[16]; + USBD_EndpointTypeDef ep_out[16]; + __IO uint32_t ep0_state; + uint32_t ep0_data_len; + __IO uint8_t dev_state; + __IO uint8_t dev_old_state; + uint8_t dev_address; + uint8_t dev_connection_status; + uint8_t dev_test_mode; + uint32_t dev_remote_wakeup; + uint8_t ConfIdx; + + USBD_SetupReqTypedef request; + USBD_DescriptorsTypeDef *pDesc; + USBD_ClassTypeDef *pClass[USBD_MAX_SUPPORTED_CLASS]; + void *pClassData; + void *pClassDataCmsit[USBD_MAX_SUPPORTED_CLASS]; + void *pUserData[USBD_MAX_SUPPORTED_CLASS]; + void *pData; + void *pBosDesc; + void *pConfDesc; + uint32_t classId; + uint32_t NumClasses; +#ifdef USE_USBD_COMPOSITE + USBD_CompositeElementTypeDef tclasslist[USBD_MAX_SUPPORTED_CLASS]; +#endif /* USE_USBD_COMPOSITE */ +#if (USBD_USER_REGISTER_CALLBACK == 1U) + void (* DevStateCallback)(uint8_t dev_state, uint8_t cfgidx); /*!< User Notification callback */ +#endif /* USBD_USER_REGISTER_CALLBACK */ +} USBD_HandleTypeDef; + +#if (USBD_USER_REGISTER_CALLBACK == 1U) +typedef void (*USBD_DevStateCallbackTypeDef)(uint8_t dev_state, uint8_t cfgidx); /*!< pointer to User callback function */ +#endif /* USBD_USER_REGISTER_CALLBACK */ + +/* USB Device endpoint direction */ +typedef enum +{ + OUT = 0x00, + IN = 0x80, +} USBD_EPDirectionTypeDef; + +typedef enum +{ + NETWORK_CONNECTION = 0x00, + RESPONSE_AVAILABLE = 0x01, + CONNECTION_SPEED_CHANGE = 0x2A +} USBD_CDC_NotifCodeTypeDef; +/** + * @} + */ + + + +/** @defgroup USBD_DEF_Exported_Macros + * @{ + */ +__STATIC_INLINE uint16_t SWAPBYTE(uint8_t *addr) +{ + uint16_t _SwapVal; + uint16_t _Byte1; + uint16_t _Byte2; + uint8_t *_pbuff = addr; + + _Byte1 = *(uint8_t *)_pbuff; + _pbuff++; + _Byte2 = *(uint8_t *)_pbuff; + + _SwapVal = (_Byte2 << 8) | _Byte1; + + return _SwapVal; +} + +#ifndef LOBYTE +#define LOBYTE(x) ((uint8_t)((x) & 0x00FFU)) +#endif /* LOBYTE */ + +#ifndef HIBYTE +#define HIBYTE(x) ((uint8_t)(((x) & 0xFF00U) >> 8U)) +#endif /* HIBYTE */ + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif /* MIN */ + +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif /* MAX */ + +#if defined ( __GNUC__ ) +#ifndef __weak +#define __weak __attribute__((weak)) +#endif /* __weak */ +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif /* __packed */ +#endif /* __GNUC__ */ + + +/* In HS mode and when the DMA is used, all variables and data structures dealing + with the DMA during the transaction process should be 4-bytes aligned */ + +#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ +#ifndef __ALIGN_END +#define __ALIGN_END __attribute__ ((aligned (4U))) +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#define __ALIGN_BEGIN +#endif /* __ALIGN_BEGIN */ +#else +#ifndef __ALIGN_END +#define __ALIGN_END +#endif /* __ALIGN_END */ +#ifndef __ALIGN_BEGIN +#if defined (__CC_ARM) /* ARM Compiler */ +#define __ALIGN_BEGIN __align(4U) +#elif defined (__ICCARM__) /* IAR Compiler */ +#define __ALIGN_BEGIN +#endif /* __CC_ARM */ +#endif /* __ALIGN_BEGIN */ +#endif /* __GNUC__ */ + + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_FunctionsPrototype + * @{ + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_DEF_H */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h new file mode 100644 index 0000000..15197b9 --- /dev/null +++ b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_ioreq.h @@ -0,0 +1,113 @@ +/** + ****************************************************************************** + * @file usbd_ioreq.h + * @author MCD Application Team + * @brief Header file for the usbd_ioreq.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_IOREQ_H +#define __USBD_IOREQ_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" +#include "usbd_core.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_IOREQ + * @brief header file for the usbd_ioreq.c file + * @{ + */ + +/** @defgroup USBD_IOREQ_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Exported_Types + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_IOREQ_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_IOREQ_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype + * @{ + */ + +USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len); + +USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len); + +USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len); + +USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len); + +USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev); + +uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_IOREQ_H */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c new file mode 100644 index 0000000..0576c87 --- /dev/null +++ b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c @@ -0,0 +1,1215 @@ +/** + ****************************************************************************** + * @file usbd_core.c + * @author MCD Application Team + * @brief This file provides all the USBD core functions. + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" + +#ifdef USE_USBD_COMPOSITE +#include "usbd_composite_builder.h" +#endif /* USE_USBD_COMPOSITE */ + +/** @addtogroup STM32_USBD_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_CORE + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_CORE_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Private_Functions + * @{ + */ + +/** + * @brief USBD_Init + * Initialize the device stack and load the class driver + * @param pdev: device instance + * @param pdesc: Descriptor structure address + * @param id: Low level core index + * @retval status: USBD Status + */ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, + USBD_DescriptorsTypeDef *pdesc, uint8_t id) +{ + USBD_StatusTypeDef ret; + + /* Check whether the USB Host handle is valid */ + if (pdev == NULL) + { +#if (USBD_DEBUG_LEVEL > 1U) + USBD_ErrLog("Invalid Device handle"); +#endif /* (USBD_DEBUG_LEVEL > 1U) */ + return USBD_FAIL; + } + +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Unlink previous class*/ + pdev->pClass[i] = NULL; + pdev->pUserData[i] = NULL; + + /* Set class as inactive */ + pdev->tclasslist[i].Active = 0; + pdev->NumClasses = 0; + pdev->classId = 0; + } +#else + /* Unlink previous class*/ + pdev->pClass[0] = NULL; + pdev->pUserData[0] = NULL; +#endif /* USE_USBD_COMPOSITE */ + + pdev->pConfDesc = NULL; + + /* Assign USBD Descriptors */ + if (pdesc != NULL) + { + pdev->pDesc = pdesc; + } + + /* Set Device initial State */ + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->id = id; + + /* Initialize low level driver */ + ret = USBD_LL_Init(pdev); + + return ret; +} + +/** + * @brief USBD_DeInit + * De-Initialize the device library + * @param pdev: device instance + * @retval status: USBD Status + */ +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) +{ + USBD_StatusTypeDef ret; + + /* Disconnect the USB Device */ + (void)USBD_LL_Stop(pdev); + + /* Set Default State */ + pdev->dev_state = USBD_STATE_DEFAULT; + +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Free Class Resources */ + pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config); + } + } + } +#else + /* Free Class Resources */ + if (pdev->pClass[0] != NULL) + { + pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config); + } + + pdev->pUserData[0] = NULL; + +#endif /* USE_USBD_COMPOSITE */ + + /* Free Device descriptors resources */ + pdev->pDesc = NULL; + pdev->pConfDesc = NULL; + + /* DeInitialize low level driver */ + ret = USBD_LL_DeInit(pdev); + + return ret; +} + +/** + * @brief USBD_RegisterClass + * Link class driver to Device Core. + * @param pdev: Device Handle + * @param pclass: Class handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass) +{ + uint16_t len = 0U; + + if (pclass == NULL) + { +#if (USBD_DEBUG_LEVEL > 1U) + USBD_ErrLog("Invalid Class handle"); +#endif /* (USBD_DEBUG_LEVEL > 1U) */ + return USBD_FAIL; + } + + /* link the class to the USB Device handle */ + pdev->pClass[0] = pclass; + + /* Get Device Configuration Descriptor */ +#ifdef USE_USB_HS + if (pdev->pClass[pdev->classId]->GetHSConfigDescriptor != NULL) + { + pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetHSConfigDescriptor(&len); + } +#else /* Default USE_USB_FS */ + if (pdev->pClass[pdev->classId]->GetFSConfigDescriptor != NULL) + { + pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetFSConfigDescriptor(&len); + } +#endif /* USE_USB_FS */ + + /* Increment the NumClasses */ + pdev->NumClasses++; + + return USBD_OK; +} + +#ifdef USE_USBD_COMPOSITE +/** + * @brief USBD_RegisterClassComposite + * Link class driver to Device Core. + * @param pdev : Device Handle + * @param pclass: Class handle + * @param classtype: Class type + * @param EpAddr: Endpoint Address handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_RegisterClassComposite(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass, + USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr) +{ + USBD_StatusTypeDef ret = USBD_OK; + uint16_t len = 0U; + + if ((pdev->classId < USBD_MAX_SUPPORTED_CLASS) && (pdev->NumClasses < USBD_MAX_SUPPORTED_CLASS)) + { + if ((uint32_t)pclass != 0U) + { + /* Link the class to the USB Device handle */ + pdev->pClass[pdev->classId] = pclass; + ret = USBD_OK; + + pdev->tclasslist[pdev->classId].EpAdd = EpAddr; + + /* Call the composite class builder */ + (void)USBD_CMPSIT_AddClass(pdev, pclass, classtype, 0); + + /* Increment the ClassId for the next occurrence */ + pdev->classId ++; + pdev->NumClasses ++; + } + else + { +#if (USBD_DEBUG_LEVEL > 1U) + USBD_ErrLog("Invalid Class handle"); +#endif /* (USBD_DEBUG_LEVEL > 1U) */ + ret = USBD_FAIL; + } + } + + if (ret == USBD_OK) + { + /* Get Device Configuration Descriptor */ +#ifdef USE_USB_HS + pdev->pConfDesc = USBD_CMPSIT.GetHSConfigDescriptor(&len); +#else /* Default USE_USB_FS */ + pdev->pConfDesc = USBD_CMPSIT.GetFSConfigDescriptor(&len); +#endif /* USE_USB_FS */ + } + + return ret; +} + +/** + * @brief USBD_UnRegisterClassComposite + * UnLink all composite class drivers from Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_UnRegisterClassComposite(USBD_HandleTypeDef *pdev) +{ + USBD_StatusTypeDef ret = USBD_FAIL; + uint8_t idx1; + uint8_t idx2; + + /* Unroll all activated classes */ + for (idx1 = 0; idx1 < pdev->NumClasses; idx1++) + { + /* Check if the class correspond to the requested type and if it is active */ + if (pdev->tclasslist[idx1].Active == 1U) + { + /* Set the new class ID */ + pdev->classId = idx1; + + /* Free resources used by the selected class */ + if (pdev->pClass[pdev->classId] != NULL) + { + /* Free Class Resources */ + if (pdev->pClass[pdev->classId]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U) + { +#if (USBD_DEBUG_LEVEL > 1U) + USBD_ErrLog("Class DeInit didn't succeed!, can't unregister selected class"); +#endif /* (USBD_DEBUG_LEVEL > 1U) */ + + ret = USBD_FAIL; + } + } + + /* Free the class pointer */ + pdev->pClass[pdev->classId] = NULL; + + /* Free the class location in classes table and reset its parameters to zero */ + pdev->tclasslist[pdev->classId].ClassType = CLASS_TYPE_NONE; + pdev->tclasslist[pdev->classId].ClassId = 0U; + pdev->tclasslist[pdev->classId].Active = 0U; + pdev->tclasslist[pdev->classId].NumEps = 0U; + pdev->tclasslist[pdev->classId].NumIf = 0U; + pdev->tclasslist[pdev->classId].CurrPcktSze = 0U; + + for (idx2 = 0U; idx2 < USBD_MAX_CLASS_ENDPOINTS; idx2++) + { + pdev->tclasslist[pdev->classId].Eps[idx2].add = 0U; + pdev->tclasslist[pdev->classId].Eps[idx2].type = 0U; + pdev->tclasslist[pdev->classId].Eps[idx2].size = 0U; + pdev->tclasslist[pdev->classId].Eps[idx2].is_used = 0U; + } + + for (idx2 = 0U; idx2 < USBD_MAX_CLASS_INTERFACES; idx2++) + { + pdev->tclasslist[pdev->classId].Ifs[idx2] = 0U; + } + } + } + + /* Reset the configuration descriptor */ + (void)USBD_CMPST_ClearConfDesc(pdev); + + /* Reset the class ID and number of classes */ + pdev->classId = 0U; + pdev->NumClasses = 0U; + + return ret; +} +#endif /* USE_USBD_COMPOSITE */ + +#if (USBD_USER_REGISTER_CALLBACK == 1U) +/** + * @brief USBD_RegisterDevStateCallback + * @param pdev : Device Handle + * @param pUserCallback: User Callback + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_RegisterDevStateCallback(USBD_HandleTypeDef *pdev, USBD_DevStateCallbackTypeDef pUserCallback) +{ + pdev->DevStateCallback = pUserCallback; + + return USBD_OK; +} +#endif /* USBD_USER_REGISTER_CALLBACK */ + +/** + * @brief USBD_Start + * Start the USB Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_Start(USBD_HandleTypeDef *pdev) +{ +#ifdef USE_USBD_COMPOSITE + pdev->classId = 0U; +#endif /* USE_USBD_COMPOSITE */ + + /* Start the low level driver */ + return USBD_LL_Start(pdev); +} + +/** + * @brief USBD_Stop + * Stop the USB Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_Stop(USBD_HandleTypeDef *pdev) +{ + /* Disconnect USB Device */ + (void)USBD_LL_Stop(pdev); + + /* Free Class Resources */ +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Free Class Resources */ + (void)pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config); + } + } + } + + /* Reset the class ID */ + pdev->classId = 0U; +#else + if (pdev->pClass[0] != NULL) + { + (void)pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config); + } +#endif /* USE_USBD_COMPOSITE */ + + return USBD_OK; +} + +/** + * @brief USBD_RunTestMode + * Launch test mode process + * @param pdev: device instance + * @retval status + */ +USBD_StatusTypeDef USBD_RunTestMode(USBD_HandleTypeDef *pdev) +{ +#ifdef USBD_HS_TESTMODE_ENABLE + USBD_StatusTypeDef ret; + + /* Run USB HS test mode */ + ret = USBD_LL_SetTestMode(pdev, pdev->dev_test_mode); + + return ret; +#else + /* Prevent unused argument compilation warning */ + UNUSED(pdev); + + return USBD_OK; +#endif /* USBD_HS_TESTMODE_ENABLE */ +} + +/** + * @brief USBD_SetClassConfig + * Configure device and start the interface + * @param pdev: device instance + * @param cfgidx: configuration index + * @retval status + */ + +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + USBD_StatusTypeDef ret = USBD_OK; + +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Set configuration and Start the Class*/ + if (pdev->pClass[i]->Init(pdev, cfgidx) != 0U) + { + ret = USBD_FAIL; + } + } + } + } +#else + if (pdev->pClass[0] != NULL) + { + /* Set configuration and Start the Class */ + ret = (USBD_StatusTypeDef)pdev->pClass[0]->Init(pdev, cfgidx); + } +#endif /* USE_USBD_COMPOSITE */ + + return ret; +} + +/** + * @brief USBD_ClrClassConfig + * Clear current configuration + * @param pdev: device instance + * @param cfgidx: configuration index + * @retval status + */ +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + USBD_StatusTypeDef ret = USBD_OK; + +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Clear configuration and De-initialize the Class process */ + if (pdev->pClass[i]->DeInit(pdev, cfgidx) != 0U) + { + ret = USBD_FAIL; + } + } + } + } +#else + /* Clear configuration and De-initialize the Class process */ + if (pdev->pClass[0]->DeInit(pdev, cfgidx) != 0U) + { + ret = USBD_FAIL; + } +#endif /* USE_USBD_COMPOSITE */ + + return ret; +} + + +/** + * @brief USBD_LL_SetupStage + * Handle the setup stage + * @param pdev: device instance + * @param psetup: setup packet buffer pointer + * @retval status + */ +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) +{ + USBD_StatusTypeDef ret; + + USBD_ParseSetupRequest(&pdev->request, psetup); + + pdev->ep0_state = USBD_EP0_SETUP; + + pdev->ep0_data_len = pdev->request.wLength; + + switch (pdev->request.bmRequest & 0x1FU) + { + case USB_REQ_RECIPIENT_DEVICE: + ret = USBD_StdDevReq(pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_INTERFACE: + ret = USBD_StdItfReq(pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_ENDPOINT: + ret = USBD_StdEPReq(pdev, &pdev->request); + break; + + default: + ret = USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U)); + break; + } + + return ret; +} + +/** + * @brief USBD_LL_DataOutStage + * Handle data OUT stage + * @param pdev: device instance + * @param epnum: endpoint index + * @param pdata: data pointer + * @retval status + */ +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev, + uint8_t epnum, uint8_t *pdata) +{ + USBD_EndpointTypeDef *pep; + USBD_StatusTypeDef ret = USBD_OK; + uint8_t idx; + + if (epnum == 0U) + { + pep = &pdev->ep_out[0]; + + if (pdev->ep0_state == USBD_EP0_DATA_OUT) + { + if (pep->rem_length > pep->maxpacket) + { + pep->rem_length -= pep->maxpacket; + + (void)USBD_CtlContinueRx(pdev, pdata, MIN(pep->rem_length, pep->maxpacket)); + } + else + { + /* Find the class ID relative to the current request */ + switch (pdev->request.bmRequest & 0x1FU) + { + case USB_REQ_RECIPIENT_DEVICE: + /* Device requests must be managed by the first instantiated class + (or duplicated by all classes for simplicity) */ + idx = 0U; + break; + + case USB_REQ_RECIPIENT_INTERFACE: + idx = USBD_CoreFindIF(pdev, LOBYTE(pdev->request.wIndex)); + break; + + case USB_REQ_RECIPIENT_ENDPOINT: + idx = USBD_CoreFindEP(pdev, LOBYTE(pdev->request.wIndex)); + break; + + default: + /* Back to the first class in case of doubt */ + idx = 0U; + break; + } + + if (idx < USBD_MAX_SUPPORTED_CLASS) + { + /* Setup the class ID and route the request to the relative class function */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass[idx]->EP0_RxReady != NULL) + { + pdev->classId = idx; + pdev->pClass[idx]->EP0_RxReady(pdev); + } + } + } + + (void)USBD_CtlSendStatus(pdev); + } + } + } + else + { + /* Get the class index relative to this interface */ + idx = USBD_CoreFindEP(pdev, (epnum & 0x7FU)); + + if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) + { + /* Call the class data out function to manage the request */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass[idx]->DataOut != NULL) + { + pdev->classId = idx; + ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataOut(pdev, epnum); + } + } + if (ret != USBD_OK) + { + return ret; + } + } + } + + return USBD_OK; +} + +/** + * @brief USBD_LL_DataInStage + * Handle data in stage + * @param pdev: device instance + * @param epnum: endpoint index + * @param pdata: data pointer + * @retval status + */ +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, + uint8_t epnum, uint8_t *pdata) +{ + USBD_EndpointTypeDef *pep; + USBD_StatusTypeDef ret; + uint8_t idx; + + if (epnum == 0U) + { + pep = &pdev->ep_in[0]; + + if (pdev->ep0_state == USBD_EP0_DATA_IN) + { + if (pep->rem_length > pep->maxpacket) + { + pep->rem_length -= pep->maxpacket; + + (void)USBD_CtlContinueSendData(pdev, pdata, pep->rem_length); + + /* Prepare endpoint for premature end of transfer */ + (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + } + else + { + /* last packet is MPS multiple, so send ZLP packet */ + if ((pep->maxpacket == pep->rem_length) && + (pep->total_length >= pep->maxpacket) && + (pep->total_length < pdev->ep0_data_len)) + { + (void)USBD_CtlContinueSendData(pdev, NULL, 0U); + pdev->ep0_data_len = 0U; + + /* Prepare endpoint for premature end of transfer */ + (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + } + else + { + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass[0]->EP0_TxSent != NULL) + { + pdev->classId = 0U; + pdev->pClass[0]->EP0_TxSent(pdev); + } + } + (void)USBD_LL_StallEP(pdev, 0x80U); + (void)USBD_CtlReceiveStatus(pdev); + } + } + } + + if (pdev->dev_test_mode != 0U) + { + (void)USBD_RunTestMode(pdev); + pdev->dev_test_mode = 0U; + } + } + else + { + /* Get the class index relative to this interface */ + idx = USBD_CoreFindEP(pdev, ((uint8_t)epnum | 0x80U)); + + if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) + { + /* Call the class data out function to manage the request */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass[idx]->DataIn != NULL) + { + pdev->classId = idx; + ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataIn(pdev, epnum); + + if (ret != USBD_OK) + { + return ret; + } + } + } + } + } + + return USBD_OK; +} + +/** + * @brief USBD_LL_Reset + * Handle Reset event + * @param pdev: device instance + * @retval status + */ +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) +{ + USBD_StatusTypeDef ret = USBD_OK; + + /* Upon Reset call user call back */ + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->ep0_state = USBD_EP0_IDLE; + pdev->dev_config = 0U; + pdev->dev_remote_wakeup = 0U; + pdev->dev_test_mode = 0U; + +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Clear configuration and De-initialize the Class process*/ + + if (pdev->pClass[i]->DeInit != NULL) + { + if (pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config) != USBD_OK) + { + ret = USBD_FAIL; + } + } + } + } + } +#else + + if (pdev->pClass[0] != NULL) + { + if (pdev->pClass[0]->DeInit != NULL) + { + if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != USBD_OK) + { + ret = USBD_FAIL; + } + } + } +#endif /* USE_USBD_COMPOSITE */ + + /* Open EP0 OUT */ + (void)USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); + pdev->ep_out[0x00U & 0xFU].is_used = 1U; + + pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE; + + /* Open EP0 IN */ + (void)USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE); + pdev->ep_in[0x80U & 0xFU].is_used = 1U; + + pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; + + return ret; +} + +/** + * @brief USBD_LL_SetSpeed + * Handle Reset event + * @param pdev: device instance + * @retval status + */ +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, + USBD_SpeedTypeDef speed) +{ + pdev->dev_speed = speed; + + return USBD_OK; +} + +/** + * @brief USBD_LL_Suspend + * Handle Suspend event + * @param pdev: device instance + * @retval status + */ +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) +{ + if (pdev->dev_state != USBD_STATE_SUSPENDED) + { + pdev->dev_old_state = pdev->dev_state; + } + + pdev->dev_state = USBD_STATE_SUSPENDED; + + return USBD_OK; +} + +/** + * @brief USBD_LL_Resume + * Handle Resume event + * @param pdev: device instance + * @retval status + */ +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) +{ + if (pdev->dev_state == USBD_STATE_SUSPENDED) + { + pdev->dev_state = pdev->dev_old_state; + } + + return USBD_OK; +} + +/** + * @brief USBD_LL_SOF + * Handle SOF event + * @param pdev: device instance + * @retval status + */ +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) +{ + /* The SOF event can be distributed for all classes that support it */ + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + if (pdev->pClass[i]->SOF != NULL) + { + pdev->classId = i; + (void)pdev->pClass[i]->SOF(pdev); + } + } + } + } +#else + if (pdev->pClass[0] != NULL) + { + if (pdev->pClass[0]->SOF != NULL) + { + (void)pdev->pClass[0]->SOF(pdev); + } + } +#endif /* USE_USBD_COMPOSITE */ + } + + return USBD_OK; +} + +/** + * @brief USBD_LL_IsoINIncomplete + * Handle iso in incomplete event + * @param pdev: device instance + * @param epnum: Endpoint number + * @retval status + */ +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + if (pdev->pClass[pdev->classId] == NULL) + { + return USBD_FAIL; + } + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass[pdev->classId]->IsoINIncomplete != NULL) + { + (void)pdev->pClass[pdev->classId]->IsoINIncomplete(pdev, epnum); + } + } + + return USBD_OK; +} + +/** + * @brief USBD_LL_IsoOUTIncomplete + * Handle iso out incomplete event + * @param pdev: device instance + * @param epnum: Endpoint number + * @retval status + */ +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + if (pdev->pClass[pdev->classId] == NULL) + { + return USBD_FAIL; + } + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + if (pdev->pClass[pdev->classId]->IsoOUTIncomplete != NULL) + { + (void)pdev->pClass[pdev->classId]->IsoOUTIncomplete(pdev, epnum); + } + } + + return USBD_OK; +} + +/** + * @brief USBD_LL_DevConnected + * Handle device connection event + * @param pdev: device instance + * @retval status + */ +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev) +{ + /* Prevent unused argument compilation warning */ + UNUSED(pdev); + + return USBD_OK; +} + +/** + * @brief USBD_LL_DevDisconnected + * Handle device disconnection event + * @param pdev: device instance + * @retval status + */ +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) +{ + USBD_StatusTypeDef ret = USBD_OK; + + /* Free Class Resources */ + pdev->dev_state = USBD_STATE_DEFAULT; + +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + if (pdev->pClass[i] != NULL) + { + pdev->classId = i; + /* Clear configuration and De-initialize the Class process*/ + if (pdev->pClass[i]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U) + { + ret = USBD_FAIL; + } + } + } + } +#else + if (pdev->pClass[0] != NULL) + { + if (pdev->pClass[0]->DeInit(pdev, (uint8_t)pdev->dev_config) != 0U) + { + ret = USBD_FAIL; + } + } +#endif /* USE_USBD_COMPOSITE */ + + return ret; +} + +/** + * @brief USBD_CoreFindIF + * return the class index relative to the selected interface + * @param pdev: device instance + * @param index : selected interface number + * @retval index of the class using the selected interface number. OxFF if no class found. + */ +uint8_t USBD_CoreFindIF(USBD_HandleTypeDef *pdev, uint8_t index) +{ +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + /* Parse all interfaces listed in the current class */ + for (uint32_t j = 0U; j < pdev->tclasslist[i].NumIf; j++) + { + /* Check if requested Interface matches the current class interface */ + if (pdev->tclasslist[i].Ifs[j] == index) + { + if (pdev->pClass[i]->Setup != NULL) + { + return (uint8_t)i; + } + } + } + } + } + + return 0xFFU; +#else + UNUSED(pdev); + UNUSED(index); + + return 0x00U; +#endif /* USE_USBD_COMPOSITE */ +} + +/** + * @brief USBD_CoreFindEP + * return the class index relative to the selected endpoint + * @param pdev: device instance + * @param index : selected endpoint number + * @retval index of the class using the selected endpoint number. 0xFF if no class found. + */ +uint8_t USBD_CoreFindEP(USBD_HandleTypeDef *pdev, uint8_t index) +{ +#ifdef USE_USBD_COMPOSITE + /* Parse the table of classes in use */ + for (uint32_t i = 0U; i < USBD_MAX_SUPPORTED_CLASS; i++) + { + /* Check if current class is in use */ + if ((pdev->tclasslist[i].Active) == 1U) + { + /* Parse all endpoints listed in the current class */ + for (uint32_t j = 0U; j < pdev->tclasslist[i].NumEps; j++) + { + /* Check if requested endpoint matches the current class endpoint */ + if (pdev->tclasslist[i].Eps[j].add == index) + { + if (pdev->pClass[i]->Setup != NULL) + { + return (uint8_t)i; + } + } + } + } + } + + return 0xFFU; +#else + UNUSED(pdev); + UNUSED(index); + + return 0x00U; +#endif /* USE_USBD_COMPOSITE */ +} + +#ifdef USE_USBD_COMPOSITE +/** + * @brief USBD_CoreGetEPAdd + * Get the endpoint address relative to a selected class + * @param pdev: device instance + * @param ep_dir: USBD_EP_IN or USBD_EP_OUT + * @param ep_type: USBD_EP_TYPE_CTRL, USBD_EP_TYPE_ISOC, USBD_EP_TYPE_BULK or USBD_EP_TYPE_INTR + * @param ClassId: The Class ID + * @retval Address of the selected endpoint or 0xFFU if no endpoint found. + */ +uint8_t USBD_CoreGetEPAdd(USBD_HandleTypeDef *pdev, uint8_t ep_dir, uint8_t ep_type, uint8_t ClassId) +{ + uint8_t idx; + + /* Find the EP address in the selected class table */ + for (idx = 0; idx < pdev->tclasslist[ClassId].NumEps; idx++) + { + if (((pdev->tclasslist[ClassId].Eps[idx].add & USBD_EP_IN) == ep_dir) && \ + (pdev->tclasslist[ClassId].Eps[idx].type == ep_type) && \ + (pdev->tclasslist[ClassId].Eps[idx].is_used != 0U)) + { + return (pdev->tclasslist[ClassId].Eps[idx].add); + } + } + + /* If reaching this point, then no endpoint was found */ + return 0xFFU; +} +#endif /* USE_USBD_COMPOSITE */ + +/** + * @brief USBD_GetEpDesc + * This function return the Endpoint descriptor + * @param pdev: device instance + * @param pConfDesc: pointer to Bos descriptor + * @param EpAddr: endpoint address + * @retval pointer to video endpoint descriptor + */ +void *USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr) +{ + USBD_DescHeaderTypeDef *pdesc = (USBD_DescHeaderTypeDef *)(void *)pConfDesc; + USBD_ConfigDescTypeDef *desc = (USBD_ConfigDescTypeDef *)(void *)pConfDesc; + USBD_EpDescTypeDef *pEpDesc = NULL; + uint16_t ptr; + + if (desc->wTotalLength > desc->bLength) + { + ptr = desc->bLength; + + while (ptr < desc->wTotalLength) + { + pdesc = USBD_GetNextDesc((uint8_t *)pdesc, &ptr); + + if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) + { + pEpDesc = (USBD_EpDescTypeDef *)(void *)pdesc; + + if (pEpDesc->bEndpointAddress == EpAddr) + { + break; + } + else + { + pEpDesc = NULL; + } + } + } + } + + return (void *)pEpDesc; +} + +/** + * @brief USBD_GetNextDesc + * This function return the next descriptor header + * @param buf: Buffer where the descriptor is available + * @param ptr: data pointer inside the descriptor + * @retval next header + */ +USBD_DescHeaderTypeDef *USBD_GetNextDesc(uint8_t *pbuf, uint16_t *ptr) +{ + USBD_DescHeaderTypeDef *pnext = (USBD_DescHeaderTypeDef *)(void *)pbuf; + + *ptr += pnext->bLength; + pnext = (USBD_DescHeaderTypeDef *)(void *)(pbuf + pnext->bLength); + + return (pnext); +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + diff --git a/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c new file mode 100644 index 0000000..814b810 --- /dev/null +++ b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c @@ -0,0 +1,1058 @@ +/** + ****************************************************************************** + * @file usbd_req.c + * @author MCD Application Team + * @brief This file provides the standard USB requests following chapter 9. + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ctlreq.h" +#include "usbd_ioreq.h" + +#ifdef USE_USBD_COMPOSITE +#include "usbd_composite_builder.h" +#endif /* USE_USBD_COMPOSITE */ + +/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_REQ + * @brief USB standard requests module + * @{ + */ + +/** @defgroup USBD_REQ_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Defines + * @{ + */ +#ifndef USBD_MAX_STR_DESC_SIZ +#define USBD_MAX_STR_DESC_SIZ 64U +#endif /* USBD_MAX_STR_DESC_SIZ */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_FunctionPrototypes + * @{ + */ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +static uint8_t USBD_GetLen(uint8_t *buf); + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Functions + * @{ + */ + + +/** + * @brief USBD_StdDevReq + * Handle standard usb device requests + * @param pdev: device instance + * @param req: usb request + * @retval status + */ +USBD_StatusTypeDef USBD_StdDevReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + ret = (USBD_StatusTypeDef)pdev->pClass[pdev->classId]->Setup(pdev, req); + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + USBD_GetDescriptor(pdev, req); + break; + + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + break; + + case USB_REQ_SET_CONFIGURATION: + ret = USBD_SetConfig(pdev, req); + break; + + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig(pdev, req); + break; + + case USB_REQ_GET_STATUS: + USBD_GetStatus(pdev, req); + break; + + case USB_REQ_SET_FEATURE: + USBD_SetFeature(pdev, req); + break; + + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature(pdev, req); + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + + return ret; +} + +/** + * @brief USBD_StdItfReq + * Handle standard usb interface requests + * @param pdev: device instance + * @param req: usb request + * @retval status + */ +USBD_StatusTypeDef USBD_StdItfReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + uint8_t idx; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + case USB_REQ_TYPE_STANDARD: + switch (pdev->dev_state) + { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + + if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) + { + /* Get the class index relative to this interface */ + idx = USBD_CoreFindIF(pdev, LOBYTE(req->wIndex)); + if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) + { + /* Call the class data out function to manage the request */ + if (pdev->pClass[idx]->Setup != NULL) + { + pdev->classId = idx; + ret = (USBD_StatusTypeDef)(pdev->pClass[idx]->Setup(pdev, req)); + } + else + { + /* should never reach this condition */ + ret = USBD_FAIL; + } + } + else + { + /* No relative interface found */ + ret = USBD_FAIL; + } + + if ((req->wLength == 0U) && (ret == USBD_OK)) + { + (void)USBD_CtlSendStatus(pdev); + } + } + else + { + USBD_CtlError(pdev, req); + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + + return ret; +} + +/** + * @brief USBD_StdEPReq + * Handle standard usb endpoint requests + * @param pdev: device instance + * @param req: usb request + * @retval status + */ +USBD_StatusTypeDef USBD_StdEPReq(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_EndpointTypeDef *pep; + uint8_t ep_addr; + uint8_t idx; + USBD_StatusTypeDef ret = USBD_OK; + + ep_addr = LOBYTE(req->wIndex); + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS: + case USB_REQ_TYPE_VENDOR: + /* Get the class index relative to this endpoint */ + idx = USBD_CoreFindEP(pdev, ep_addr); + if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) + { + pdev->classId = idx; + /* Call the class data out function to manage the request */ + if (pdev->pClass[idx]->Setup != NULL) + { + ret = (USBD_StatusTypeDef)pdev->pClass[idx]->Setup(pdev, req); + } + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_SET_FEATURE: + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + (void)USBD_LL_StallEP(pdev, ep_addr); + (void)USBD_LL_StallEP(pdev, 0x80U); + } + else + { + USBD_CtlError(pdev, req); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr != 0x00U) && (ep_addr != 0x80U) && (req->wLength == 0x00U)) + { + (void)USBD_LL_StallEP(pdev, ep_addr); + } + } + (void)USBD_CtlSendStatus(pdev); + + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + case USB_REQ_CLEAR_FEATURE: + + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + (void)USBD_LL_StallEP(pdev, ep_addr); + (void)USBD_LL_StallEP(pdev, 0x80U); + } + else + { + USBD_CtlError(pdev, req); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr & 0x7FU) != 0x00U) + { + (void)USBD_LL_ClearStallEP(pdev, ep_addr); + } + (void)USBD_CtlSendStatus(pdev); + + /* Get the class index relative to this interface */ + idx = USBD_CoreFindEP(pdev, ep_addr); + if (((uint8_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS)) + { + pdev->classId = idx; + /* Call the class data out function to manage the request */ + if (pdev->pClass[idx]->Setup != NULL) + { + ret = (USBD_StatusTypeDef)(pdev->pClass[idx]->Setup(pdev, req)); + } + } + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + case USB_REQ_GET_STATUS: + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00U) && (ep_addr != 0x80U)) + { + USBD_CtlError(pdev, req); + break; + } + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ + &pdev->ep_out[ep_addr & 0x7FU]; + + pep->status = 0x0000U; + + (void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U); + break; + + case USBD_STATE_CONFIGURED: + if ((ep_addr & 0x80U) == 0x80U) + { + if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U) + { + USBD_CtlError(pdev, req); + break; + } + } + else + { + if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U) + { + USBD_CtlError(pdev, req); + break; + } + } + + pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \ + &pdev->ep_out[ep_addr & 0x7FU]; + + if ((ep_addr == 0x00U) || (ep_addr == 0x80U)) + { + pep->status = 0x0000U; + } + else if (USBD_LL_IsStallEP(pdev, ep_addr) != 0U) + { + pep->status = 0x0001U; + } + else + { + pep->status = 0x0000U; + } + + (void)USBD_CtlSendData(pdev, (uint8_t *)&pep->status, 2U); + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } + + return ret; +} + + +/** + * @brief USBD_GetDescriptor + * Handle Get Descriptor requests + * @param pdev: device instance + * @param req: usb request + * @retval None + */ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + uint16_t len = 0U; + uint8_t *pbuf = NULL; + uint8_t err = 0U; + + switch (req->wValue >> 8) + { +#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U)) + case USB_DESC_TYPE_BOS: + if (pdev->pDesc->GetBOSDescriptor != NULL) + { + pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; +#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1U) */ + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); + break; + + case USB_DESC_TYPE_CONFIGURATION: + if (pdev->dev_speed == USBD_SPEED_HIGH) + { +#ifdef USE_USBD_COMPOSITE + if ((uint8_t)(pdev->NumClasses) > 0U) + { + pbuf = (uint8_t *)USBD_CMPSIT.GetHSConfigDescriptor(&len); + } + else +#endif /* USE_USBD_COMPOSITE */ + { + pbuf = (uint8_t *)pdev->pClass[0]->GetHSConfigDescriptor(&len); + } + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + } + else + { +#ifdef USE_USBD_COMPOSITE + if ((uint8_t)(pdev->NumClasses) > 0U) + { + pbuf = (uint8_t *)USBD_CMPSIT.GetFSConfigDescriptor(&len); + } + else +#endif /* USE_USBD_COMPOSITE */ + { + pbuf = (uint8_t *)pdev->pClass[0]->GetFSConfigDescriptor(&len); + } + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + } + break; + + case USB_DESC_TYPE_STRING: + switch ((uint8_t)(req->wValue)) + { + case USBD_IDX_LANGID_STR: + if (pdev->pDesc->GetLangIDStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_MFC_STR: + if (pdev->pDesc->GetManufacturerStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_PRODUCT_STR: + if (pdev->pDesc->GetProductStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_SERIAL_STR: + if (pdev->pDesc->GetSerialStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_CONFIG_STR: + if (pdev->pDesc->GetConfigurationStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USBD_IDX_INTERFACE_STR: + if (pdev->pDesc->GetInterfaceStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + default: +#if (USBD_SUPPORT_USER_STRING_DESC == 1U) + pbuf = NULL; + + for (uint32_t idx = 0U; (idx < pdev->NumClasses); idx++) + { + if (pdev->pClass[idx]->GetUsrStrDescriptor != NULL) + { + pdev->classId = idx; + pbuf = pdev->pClass[idx]->GetUsrStrDescriptor(pdev, LOBYTE(req->wValue), &len); + + if (pbuf == NULL) /* This means that no class recognized the string index */ + { + continue; + } + else + { + break; + } + } + } +#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +#if (USBD_CLASS_USER_STRING_DESC == 1U) + if (pdev->pDesc->GetUserStrDescriptor != NULL) + { + pbuf = pdev->pDesc->GetUserStrDescriptor(pdev->dev_speed, LOBYTE(req->wValue), &len); + } + else + { + USBD_CtlError(pdev, req); + err++; + } +#endif /* USBD_SUPPORT_USER_STRING_DESC */ + +#if ((USBD_CLASS_USER_STRING_DESC == 0U) && (USBD_SUPPORT_USER_STRING_DESC == 0U)) + USBD_CtlError(pdev, req); + err++; +#endif /* (USBD_CLASS_USER_STRING_DESC == 0U) && (USBD_SUPPORT_USER_STRING_DESC == 0U) */ + break; + } + break; + + case USB_DESC_TYPE_DEVICE_QUALIFIER: + if (pdev->dev_speed == USBD_SPEED_HIGH) + { +#ifdef USE_USBD_COMPOSITE + if ((uint8_t)(pdev->NumClasses) > 0U) + { + pbuf = (uint8_t *)USBD_CMPSIT.GetDeviceQualifierDescriptor(&len); + } + else +#endif /* USE_USBD_COMPOSITE */ + { + pbuf = (uint8_t *)pdev->pClass[0]->GetDeviceQualifierDescriptor(&len); + } + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: + if (pdev->dev_speed == USBD_SPEED_HIGH) + { +#ifdef USE_USBD_COMPOSITE + if ((uint8_t)(pdev->NumClasses) > 0U) + { + pbuf = (uint8_t *)USBD_CMPSIT.GetOtherSpeedConfigDescriptor(&len); + } + else +#endif /* USE_USBD_COMPOSITE */ + { + pbuf = (uint8_t *)pdev->pClass[0]->GetOtherSpeedConfigDescriptor(&len); + } + pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; + } + else + { + USBD_CtlError(pdev, req); + err++; + } + break; + + default: + USBD_CtlError(pdev, req); + err++; + break; + } + + if (err != 0U) + { + return; + } + + if (req->wLength != 0U) + { + if (len != 0U) + { + len = MIN(len, req->wLength); + (void)USBD_CtlSendData(pdev, pbuf, len); + } + else + { + USBD_CtlError(pdev, req); + } + } + else + { + (void)USBD_CtlSendStatus(pdev); + } +} + + +/** + * @brief USBD_SetAddress + * Set device address + * @param pdev: device instance + * @param req: usb request + * @retval None + */ +static void USBD_SetAddress(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + uint8_t dev_addr; + + if ((req->wIndex == 0U) && (req->wLength == 0U) && (req->wValue < 128U)) + { + dev_addr = (uint8_t)(req->wValue) & 0x7FU; + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + USBD_CtlError(pdev, req); + } + else + { + pdev->dev_address = dev_addr; + (void)USBD_LL_SetUSBAddress(pdev, dev_addr); + (void)USBD_CtlSendStatus(pdev); + + if (dev_addr != 0U) + { + pdev->dev_state = USBD_STATE_ADDRESSED; + } + else + { + pdev->dev_state = USBD_STATE_DEFAULT; + } + } + } + else + { + USBD_CtlError(pdev, req); + } +} + +/** + * @brief USBD_SetConfig + * Handle Set device configuration request + * @param pdev: device instance + * @param req: usb request + * @retval status + */ +static USBD_StatusTypeDef USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + static uint8_t cfgidx; + + cfgidx = (uint8_t)(req->wValue); + + if (cfgidx > USBD_MAX_NUM_CONFIGURATION) + { + USBD_CtlError(pdev, req); + return USBD_FAIL; + } + + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if (cfgidx != 0U) + { + pdev->dev_config = cfgidx; + + ret = USBD_SetClassConfig(pdev, cfgidx); + + if (ret != USBD_OK) + { + USBD_CtlError(pdev, req); + pdev->dev_state = USBD_STATE_ADDRESSED; + } + else + { + (void)USBD_CtlSendStatus(pdev); + pdev->dev_state = USBD_STATE_CONFIGURED; + +#if (USBD_USER_REGISTER_CALLBACK == 1U) + if (pdev->DevStateCallback != NULL) + { + pdev->DevStateCallback(USBD_STATE_CONFIGURED, cfgidx); + } +#endif /* USBD_USER_REGISTER_CALLBACK */ + } + } + else + { + (void)USBD_CtlSendStatus(pdev); + } + break; + + case USBD_STATE_CONFIGURED: + if (cfgidx == 0U) + { + pdev->dev_state = USBD_STATE_ADDRESSED; + pdev->dev_config = cfgidx; + (void)USBD_ClrClassConfig(pdev, cfgidx); + (void)USBD_CtlSendStatus(pdev); + } + else if (cfgidx != pdev->dev_config) + { + /* Clear old configuration */ + (void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); + + /* set new configuration */ + pdev->dev_config = cfgidx; + + ret = USBD_SetClassConfig(pdev, cfgidx); + + if (ret != USBD_OK) + { + USBD_CtlError(pdev, req); + (void)USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config); + pdev->dev_state = USBD_STATE_ADDRESSED; + } + else + { + (void)USBD_CtlSendStatus(pdev); + } + } + else + { + (void)USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev, req); + (void)USBD_ClrClassConfig(pdev, cfgidx); + ret = USBD_FAIL; + break; + } + + return ret; +} + +/** + * @brief USBD_GetConfig + * Handle Get device configuration request + * @param pdev: device instance + * @param req: usb request + * @retval None + */ +static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + if (req->wLength != 1U) + { + USBD_CtlError(pdev, req); + } + else + { + switch (pdev->dev_state) + { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + pdev->dev_default_config = 0U; + (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_default_config, 1U); + break; + + case USBD_STATE_CONFIGURED: + (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config, 1U); + break; + + default: + USBD_CtlError(pdev, req); + break; + } + } +} + +/** + * @brief USBD_GetStatus + * Handle Get Status request + * @param pdev: device instance + * @param req: usb request + * @retval None + */ +static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + switch (pdev->dev_state) + { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wLength != 0x2U) + { + USBD_CtlError(pdev, req); + break; + } + +#if (USBD_SELF_POWERED == 1U) + pdev->dev_config_status = USB_CONFIG_SELF_POWERED; +#else + pdev->dev_config_status = 0U; +#endif /* USBD_SELF_POWERED */ + + if (pdev->dev_remote_wakeup != 0U) + { + pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; + } + + (void)USBD_CtlSendData(pdev, (uint8_t *)&pdev->dev_config_status, 2U); + break; + + default: + USBD_CtlError(pdev, req); + break; + } +} + + +/** + * @brief USBD_SetFeature + * Handle Set device feature request + * @param pdev: device instance + * @param req: usb request + * @retval None + */ +static void USBD_SetFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev_remote_wakeup = 1U; + (void)USBD_CtlSendStatus(pdev); + } + else if (req->wValue == USB_FEATURE_TEST_MODE) + { + pdev->dev_test_mode = (uint8_t)(req->wIndex >> 8); + (void)USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlError(pdev, req); + } +} + + +/** + * @brief USBD_ClrFeature + * Handle clear device feature request + * @param pdev: device instance + * @param req: usb request + * @retval None + */ +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + switch (pdev->dev_state) + { + case USBD_STATE_DEFAULT: + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev_remote_wakeup = 0U; + (void)USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev, req); + break; + } +} + + +/** + * @brief USBD_ParseSetupRequest + * Copy buffer into setup structure + * @param req: usb request + * @param pdata: setup data pointer + * @retval None + */ +void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) +{ + uint8_t *pbuff = pdata; + + req->bmRequest = *(uint8_t *)(pbuff); + + pbuff++; + req->bRequest = *(uint8_t *)(pbuff); + + pbuff++; + req->wValue = SWAPBYTE(pbuff); + + pbuff++; + pbuff++; + req->wIndex = SWAPBYTE(pbuff); + + pbuff++; + pbuff++; + req->wLength = SWAPBYTE(pbuff); +} + + +/** + * @brief USBD_CtlError + * Handle USB low level Error + * @param pdev: device instance + * @param req: usb request + * @retval None + */ +void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + UNUSED(req); + + (void)USBD_LL_StallEP(pdev, 0x80U); + (void)USBD_LL_StallEP(pdev, 0U); +} + + +/** + * @brief USBD_GetString + * Convert Ascii string into unicode one + * @param desc : descriptor buffer + * @param unicode : Formatted string buffer (unicode) + * @param len : descriptor length + * @retval None + */ +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) +{ + uint8_t idx = 0U; + uint8_t *pdesc; + + if (desc == NULL) + { + return; + } + + pdesc = desc; + *len = MIN(USBD_MAX_STR_DESC_SIZ, ((uint16_t)USBD_GetLen(pdesc) * 2U) + 2U); + + unicode[idx] = *(uint8_t *)len; + idx++; + unicode[idx] = USB_DESC_TYPE_STRING; + idx++; + + while (*pdesc != (uint8_t)'\0') + { + unicode[idx] = *pdesc; + pdesc++; + idx++; + + unicode[idx] = 0U; + idx++; + } +} + + +/** + * @brief USBD_GetLen + * return the string length + * @param buf : pointer to the ascii string buffer + * @retval string length + */ +static uint8_t USBD_GetLen(uint8_t *buf) +{ + uint8_t len = 0U; + uint8_t *pbuff = buf; + + while (*pbuff != (uint8_t)'\0') + { + len++; + pbuff++; + } + + return len; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + diff --git a/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c new file mode 100644 index 0000000..7c8004a --- /dev/null +++ b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c @@ -0,0 +1,224 @@ +/** + ****************************************************************************** + * @file usbd_ioreq.c + * @author MCD Application Team + * @brief This file provides the IO requests APIs for control endpoints. + ****************************************************************************** + * @attention + * + * Copyright (c) 2015 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_IOREQ + * @brief control I/O requests module + * @{ + */ + +/** @defgroup USBD_IOREQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Functions + * @{ + */ + +/** + * @brief USBD_CtlSendData + * send data on the ctl pipe + * @param pdev: device instance + * @param buff: pointer to data buffer + * @param len: length of data to be sent + * @retval status + */ +USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_DATA_IN; + pdev->ep_in[0].total_length = len; + +#ifdef USBD_AVOID_PACKET_SPLIT_MPS + pdev->ep_in[0].rem_length = 0U; +#else + pdev->ep_in[0].rem_length = len; +#endif /* USBD_AVOID_PACKET_SPLIT_MPS */ + + /* Start the transfer */ + (void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len); + + return USBD_OK; +} + +/** + * @brief USBD_CtlContinueSendData + * continue sending data on the ctl pipe + * @param pdev: device instance + * @param buff: pointer to data buffer + * @param len: length of data to be sent + * @retval status + */ +USBD_StatusTypeDef USBD_CtlContinueSendData(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len) +{ + /* Start the next transfer */ + (void)USBD_LL_Transmit(pdev, 0x00U, pbuf, len); + + return USBD_OK; +} + +/** + * @brief USBD_CtlPrepareRx + * receive data on the ctl pipe + * @param pdev: device instance + * @param buff: pointer to data buffer + * @param len: length of data to be received + * @retval status + */ +USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_DATA_OUT; + pdev->ep_out[0].total_length = len; + +#ifdef USBD_AVOID_PACKET_SPLIT_MPS + pdev->ep_out[0].rem_length = 0U; +#else + pdev->ep_out[0].rem_length = len; +#endif /* USBD_AVOID_PACKET_SPLIT_MPS */ + + /* Start the transfer */ + (void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); + + return USBD_OK; +} + +/** + * @brief USBD_CtlContinueRx + * continue receive data on the ctl pipe + * @param pdev: device instance + * @param buff: pointer to data buffer + * @param len: length of data to be received + * @retval status + */ +USBD_StatusTypeDef USBD_CtlContinueRx(USBD_HandleTypeDef *pdev, + uint8_t *pbuf, uint32_t len) +{ + (void)USBD_LL_PrepareReceive(pdev, 0U, pbuf, len); + + return USBD_OK; +} + +/** + * @brief USBD_CtlSendStatus + * send zero lzngth packet on the ctl pipe + * @param pdev: device instance + * @retval status + */ +USBD_StatusTypeDef USBD_CtlSendStatus(USBD_HandleTypeDef *pdev) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_IN; + + /* Start the transfer */ + (void)USBD_LL_Transmit(pdev, 0x00U, NULL, 0U); + + return USBD_OK; +} + +/** + * @brief USBD_CtlReceiveStatus + * receive zero lzngth packet on the ctl pipe + * @param pdev: device instance + * @retval status + */ +USBD_StatusTypeDef USBD_CtlReceiveStatus(USBD_HandleTypeDef *pdev) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_OUT; + + /* Start the transfer */ + (void)USBD_LL_PrepareReceive(pdev, 0U, NULL, 0U); + + return USBD_OK; +} + +/** + * @brief USBD_GetRxCount + * returns the received data length + * @param pdev: device instance + * @param ep_addr: endpoint address + * @retval Rx Data blength + */ +uint32_t USBD_GetRxCount(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return USBD_LL_GetRxDataSize(pdev, ep_addr); +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + diff --git a/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/LICENSE.txt b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/LICENSE.txt new file mode 100644 index 0000000..e66295c --- /dev/null +++ b/board/CubeMX_Config/Middlewares/ST/STM32_USB_Device_Library/LICENSE.txt @@ -0,0 +1,86 @@ +This software component is provided to you as part of a software package and +applicable license terms are in the Package_license file. If you received this +software component outside of a package or without applicable license terms, +the terms of the SLA0044 license shall apply and are fully reproduced below: + +SLA0044 Rev5/February 2018 + +Software license agreement + +ULTIMATE LIBERTY SOFTWARE LICENSE AGREEMENT + +BY INSTALLING, COPYING, DOWNLOADING, ACCESSING OR OTHERWISE USING THIS SOFTWARE +OR ANY PART THEREOF (AND THE RELATED DOCUMENTATION) FROM STMICROELECTRONICS +INTERNATIONAL N.V, SWISS BRANCH AND/OR ITS AFFILIATED COMPANIES +(STMICROELECTRONICS), THE RECIPIENT, ON BEHALF OF HIMSELF OR HERSELF, OR ON +BEHALF OF ANY ENTITY BY WHICH SUCH RECIPIENT IS EMPLOYED AND/OR ENGAGED AGREES +TO BE BOUND BY THIS SOFTWARE LICENSE AGREEMENT. + +Under STMicroelectronics’ intellectual property rights, the redistribution, +reproduction and use in source and binary forms of the software or any part +thereof, with or without modification, are permitted provided that the following +conditions are met: + +1. Redistribution of source code (modified or not) must retain any copyright +notice, this list of conditions and the disclaimer set forth below as items 10 +and 11. + +2. Redistributions in binary form, except as embedded into microcontroller or +microprocessor device manufactured by or for STMicroelectronics or a software +update for such device, must reproduce any copyright notice provided with the +binary code, this list of conditions, and the disclaimer set forth below as +items 10 and 11, in documentation and/or other materials provided with the +distribution. + +3. Neither the name of STMicroelectronics nor the names of other contributors to +this software may be used to endorse or promote products derived from this +software or part thereof without specific written permission. + +4. This software or any part thereof, including modifications and/or derivative +works of this software, must be used and execute solely and exclusively on or in +combination with a microcontroller or microprocessor device manufactured by or +for STMicroelectronics. + +5. No use, reproduction or redistribution of this software partially or totally +may be done in any manner that would subject this software to any Open Source +Terms. “Open Source Terms” shall mean any open source license which requires as +part of distribution of software that the source code of such software is +distributed therewith or otherwise made available, or open source license that +substantially complies with the Open Source definition specified at +www.opensource.org and any other comparable open source license such as for +example GNU General Public License (GPL), Eclipse Public License (EPL), Apache +Software License, BSD license or MIT license. + +6. STMicroelectronics has no obligation to provide any maintenance, support or +updates for the software. + +7. The software is and will remain the exclusive property of STMicroelectronics +and its licensors. The recipient will not take any action that jeopardizes +STMicroelectronics and its licensors' proprietary rights or acquire any rights +in the software, except the limited rights specified hereunder. + +8. The recipient shall comply with all applicable laws and regulations affecting +the use of the software or any part thereof including any applicable export +control law or regulation. + +9. Redistribution and use of this software or any part thereof other than as +permitted under this license is void and will automatically terminate your +rights under this license. + +10. THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY RIGHTS, WHICH ARE +DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT SHALL +STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +11. EXCEPT AS EXPRESSLY PERMITTED HEREUNDER, NO LICENSE OR OTHER RIGHTS, WHETHER +EXPRESS OR IMPLIED, ARE GRANTED UNDER ANY PATENT OR OTHER INTELLECTUAL PROPERTY +RIGHTS OF STMICROELECTRONICS OR ANY THIRD PARTY. + diff --git a/board/CubeMX_Config/Src/main.c b/board/CubeMX_Config/Src/main.c index 743b03b..0e3f4b9 100644 --- a/board/CubeMX_Config/Src/main.c +++ b/board/CubeMX_Config/Src/main.c @@ -18,6 +18,7 @@ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" +#include "usb_device.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -43,8 +44,6 @@ QSPI_HandleTypeDef hqspi; -SPI_HandleTypeDef hspi5; - UART_HandleTypeDef huart1; UART_HandleTypeDef huart2; UART_HandleTypeDef huart3; @@ -58,10 +57,9 @@ void SystemClock_Config(void); static void MPU_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); -static void MX_QUADSPI_Init(void); -static void MX_SPI5_Init(void); static void MX_USART2_UART_Init(void); static void MX_USART3_UART_Init(void); +static void MX_QUADSPI_Init(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ @@ -104,10 +102,10 @@ int main(void) /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART1_UART_Init(); - MX_QUADSPI_Init(); - MX_SPI5_Init(); MX_USART2_UART_Init(); MX_USART3_UART_Init(); + MX_USB_DEVICE_Init(); + MX_QUADSPI_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ @@ -145,17 +143,16 @@ void SystemClock_Config(void) /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; - RCC_OscInitStruct.HSIState = RCC_HSI_DIV1; - RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLM = 4; - RCC_OscInitStruct.PLL.PLLN = 60; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 5; + RCC_OscInitStruct.PLL.PLLN = 192; RCC_OscInitStruct.PLL.PLLP = 2; - RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLQ = 20; RCC_OscInitStruct.PLL.PLLR = 2; - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) @@ -217,54 +214,6 @@ static void MX_QUADSPI_Init(void) } -/** - * @brief SPI5 Initialization Function - * @param None - * @retval None - */ -static void MX_SPI5_Init(void) -{ - - /* USER CODE BEGIN SPI5_Init 0 */ - - /* USER CODE END SPI5_Init 0 */ - - /* USER CODE BEGIN SPI5_Init 1 */ - - /* USER CODE END SPI5_Init 1 */ - /* SPI5 parameter configuration*/ - hspi5.Instance = SPI5; - hspi5.Init.Mode = SPI_MODE_MASTER; - hspi5.Init.Direction = SPI_DIRECTION_2LINES_TXONLY; - hspi5.Init.DataSize = SPI_DATASIZE_4BIT; - hspi5.Init.CLKPolarity = SPI_POLARITY_LOW; - hspi5.Init.CLKPhase = SPI_PHASE_1EDGE; - hspi5.Init.NSS = SPI_NSS_SOFT; - hspi5.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; - hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB; - hspi5.Init.TIMode = SPI_TIMODE_DISABLE; - hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - hspi5.Init.CRCPolynomial = 0x0; - hspi5.Init.NSSPMode = SPI_NSS_PULSE_ENABLE; - hspi5.Init.NSSPolarity = SPI_NSS_POLARITY_LOW; - hspi5.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA; - hspi5.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; - hspi5.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN; - hspi5.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE; - hspi5.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE; - hspi5.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE; - hspi5.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE; - hspi5.Init.IOSwap = SPI_IO_SWAP_DISABLE; - if (HAL_SPI_Init(&hspi5) != HAL_OK) - { - Error_Handler(); - } - /* USER CODE BEGIN SPI5_Init 2 */ - - /* USER CODE END SPI5_Init 2 */ - -} - /** * @brief USART1 Initialization Function * @param None @@ -427,9 +376,7 @@ static void MX_GPIO_Init(void) __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); - __HAL_RCC_GPIOK_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); - __HAL_RCC_GPIOJ_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); /*Configure GPIO pin : PE9 */ diff --git a/board/CubeMX_Config/Src/stm32h7xx_hal_msp.c b/board/CubeMX_Config/Src/stm32h7xx_hal_msp.c index f25d0b4..aa587ec 100644 --- a/board/CubeMX_Config/Src/stm32h7xx_hal_msp.c +++ b/board/CubeMX_Config/Src/stm32h7xx_hal_msp.c @@ -108,7 +108,6 @@ void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi) __HAL_RCC_GPIOF_CLK_ENABLE(); /**QUADSPI GPIO Configuration PG6 ------> QUADSPI_BK1_NCS - PF6 ------> QUADSPI_BK1_IO3 PF7 ------> QUADSPI_BK1_IO2 PF8 ------> QUADSPI_BK1_IO0 PF10 ------> QUADSPI_CLK @@ -121,7 +120,7 @@ void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi) GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); - GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10; + GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; @@ -161,7 +160,6 @@ void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi) /**QUADSPI GPIO Configuration PG6 ------> QUADSPI_BK1_NCS - PF6 ------> QUADSPI_BK1_IO3 PF7 ------> QUADSPI_BK1_IO2 PF8 ------> QUADSPI_BK1_IO0 PF10 ------> QUADSPI_CLK @@ -169,8 +167,7 @@ void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi) */ HAL_GPIO_DeInit(GPIOG, GPIO_PIN_6); - HAL_GPIO_DeInit(GPIOF, GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_10 - |GPIO_PIN_9); + HAL_GPIO_DeInit(GPIOF, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_10|GPIO_PIN_9); /* USER CODE BEGIN QUADSPI_MspDeInit 1 */ @@ -179,93 +176,6 @@ void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi) } -/** - * @brief SPI MSP Initialization - * This function configures the hardware resources used in this example - * @param hspi: SPI handle pointer - * @retval None - */ -void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) -{ - GPIO_InitTypeDef GPIO_InitStruct = {0}; - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; - if(hspi->Instance==SPI5) - { - /* USER CODE BEGIN SPI5_MspInit 0 */ - - /* USER CODE END SPI5_MspInit 0 */ - - /** Initializes the peripherals clock - */ - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI5; - PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) - { - Error_Handler(); - } - - /* Peripheral clock enable */ - __HAL_RCC_SPI5_CLK_ENABLE(); - - __HAL_RCC_GPIOK_CLK_ENABLE(); - __HAL_RCC_GPIOJ_CLK_ENABLE(); - /**SPI5 GPIO Configuration - PK0 ------> SPI5_SCK - PJ10 ------> SPI5_MOSI - */ - GPIO_InitStruct.Pin = GPIO_PIN_0; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI5; - HAL_GPIO_Init(GPIOK, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = GPIO_PIN_10; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Alternate = GPIO_AF5_SPI5; - HAL_GPIO_Init(GPIOJ, &GPIO_InitStruct); - - /* USER CODE BEGIN SPI5_MspInit 1 */ - - /* USER CODE END SPI5_MspInit 1 */ - - } - -} - -/** - * @brief SPI MSP De-Initialization - * This function freeze the hardware resources used in this example - * @param hspi: SPI handle pointer - * @retval None - */ -void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi) -{ - if(hspi->Instance==SPI5) - { - /* USER CODE BEGIN SPI5_MspDeInit 0 */ - - /* USER CODE END SPI5_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_SPI5_CLK_DISABLE(); - - /**SPI5 GPIO Configuration - PK0 ------> SPI5_SCK - PJ10 ------> SPI5_MOSI - */ - HAL_GPIO_DeInit(GPIOK, GPIO_PIN_0); - - HAL_GPIO_DeInit(GPIOJ, GPIO_PIN_10); - - /* USER CODE BEGIN SPI5_MspDeInit 1 */ - - /* USER CODE END SPI5_MspDeInit 1 */ - } - -} - /** * @brief UART MSP Initialization * This function configures the hardware resources used in this example @@ -448,4 +358,81 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) /* USER CODE BEGIN 1 */ +/******************************************************************************* + LL Driver Callbacks (PCD -> USB Device Library) +*******************************************************************************/ +/* MSP Init */ + +void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + if(pcdHandle->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspInit 0 */ + + /* USER CODE END USB_OTG_FS_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Enable USB Voltage detector + */ + HAL_PWREx_EnableUSBVoltageDetector(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USB_OTG_FS GPIO Configuration + PA12 ------> USB_OTG_FS_DP + PA11 ------> USB_OTG_FS_DM + */ + GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + + /* Peripheral interrupt init */ + HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */ + + /* USER CODE END USB_OTG_FS_MspInit 1 */ + } +} + +void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) +{ + if(pcdHandle->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USB_OTG_FS_CLK_DISABLE(); + + /**USB_OTG_FS GPIO Configuration + PA12 ------> USB_OTG_FS_DP + PA11 ------> USB_OTG_FS_DM + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12|GPIO_PIN_11); + + /* Peripheral interrupt Deinit*/ + HAL_NVIC_DisableIRQ(OTG_FS_IRQn); + + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 1 */ + } +} + /* USER CODE END 1 */ diff --git a/board/CubeMX_Config/Src/stm32h7xx_it.c b/board/CubeMX_Config/Src/stm32h7xx_it.c index 3601d79..5af4225 100644 --- a/board/CubeMX_Config/Src/stm32h7xx_it.c +++ b/board/CubeMX_Config/Src/stm32h7xx_it.c @@ -55,7 +55,7 @@ /* USER CODE END 0 */ /* External variables --------------------------------------------------------*/ - +extern PCD_HandleTypeDef hpcd_USB_OTG_FS; /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -198,6 +198,20 @@ void SysTick_Handler(void) /* please refer to the startup file (startup_stm32h7xx.s). */ /******************************************************************************/ +/** + * @brief This function handles USB On The Go FS global interrupt. + */ +void OTG_FS_IRQHandler(void) +{ + /* USER CODE BEGIN OTG_FS_IRQn 0 */ + + /* USER CODE END OTG_FS_IRQn 0 */ + HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS); + /* USER CODE BEGIN OTG_FS_IRQn 1 */ + + /* USER CODE END OTG_FS_IRQn 1 */ +} + /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ diff --git a/board/CubeMX_Config/Src/usb_device.c b/board/CubeMX_Config/Src/usb_device.c new file mode 100644 index 0000000..1cbbe27 --- /dev/null +++ b/board/CubeMX_Config/Src/usb_device.c @@ -0,0 +1,101 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usb_device.c + * @version : v1.0_Cube + * @brief : This file implements the USB Device + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ + +#include "usb_device.h" +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_cdc.h" +#include "usbd_cdc_if.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ + +/* USER CODE END PFP */ + +/* USB Device Core handle declaration. */ +USBD_HandleTypeDef hUsbDeviceFS; + +/* + * -- Insert your variables declaration here -- + */ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* + * -- Insert your external function declaration here -- + */ +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * Init USB device Library, add supported class and start the library + * @retval None + */ +void MX_USB_DEVICE_Init(void) +{ + /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */ + + /* USER CODE END USB_DEVICE_Init_PreTreatment */ + + /* Init Device Library, add supported class and start the library. */ + if (USBD_Init(&hUsbDeviceFS, &FS_Desc, DEVICE_FS) != USBD_OK) + { + Error_Handler(); + } + if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK) + { + Error_Handler(); + } + if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK) + { + Error_Handler(); + } + if (USBD_Start(&hUsbDeviceFS) != USBD_OK) + { + Error_Handler(); + } + + /* USER CODE BEGIN USB_DEVICE_Init_PostTreatment */ + HAL_PWREx_EnableUSBVoltageDetector(); + + /* USER CODE END USB_DEVICE_Init_PostTreatment */ +} + +/** + * @} + */ + +/** + * @} + */ + diff --git a/board/CubeMX_Config/Src/usbd_cdc_if.c b/board/CubeMX_Config/Src/usbd_cdc_if.c new file mode 100644 index 0000000..290e76f --- /dev/null +++ b/board/CubeMX_Config/Src/usbd_cdc_if.c @@ -0,0 +1,328 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_cdc_if.c + * @version : v1.0_Cube + * @brief : Usb device for Virtual Com Port. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc_if.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @brief Usb device library. + * @{ + */ + +/** @addtogroup USBD_CDC_IF + * @{ + */ + +/** @defgroup USBD_CDC_IF_Private_TypesDefinitions USBD_CDC_IF_Private_TypesDefinitions + * @brief Private types. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_TYPES */ + +/* USER CODE END PRIVATE_TYPES */ + +/** + * @} + */ + +/** @defgroup USBD_CDC_IF_Private_Defines USBD_CDC_IF_Private_Defines + * @brief Private defines. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_DEFINES */ +/* USER CODE END PRIVATE_DEFINES */ + +/** + * @} + */ + +/** @defgroup USBD_CDC_IF_Private_Macros USBD_CDC_IF_Private_Macros + * @brief Private macros. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_MACRO */ + +/* USER CODE END PRIVATE_MACRO */ + +/** + * @} + */ + +/** @defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables + * @brief Private variables. + * @{ + */ +/* Create buffer for reception and transmission */ +/* It's up to user to redefine and/or remove those define */ +/** Received data over USB are stored in this buffer */ +uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; + +/** Data to send over USB CDC are stored in this buffer */ +uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; + +/* USER CODE BEGIN PRIVATE_VARIABLES */ + +/* USER CODE END PRIVATE_VARIABLES */ + +/** + * @} + */ + +/** @defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables + * @brief Public variables. + * @{ + */ + +extern USBD_HandleTypeDef hUsbDeviceFS; + +/* USER CODE BEGIN EXPORTED_VARIABLES */ + +/* USER CODE END EXPORTED_VARIABLES */ + +/** + * @} + */ + +/** @defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes + * @brief Private functions declaration. + * @{ + */ + +static int8_t CDC_Init_FS(void); +static int8_t CDC_DeInit_FS(void); +static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length); +static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len); +static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum); + +/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ + +/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ + +/** + * @} + */ + +USBD_CDC_ItfTypeDef USBD_Interface_fops_FS = +{ + CDC_Init_FS, + CDC_DeInit_FS, + CDC_Control_FS, + CDC_Receive_FS, + CDC_TransmitCplt_FS +}; + +/* Private functions ---------------------------------------------------------*/ +/** + * @brief Initializes the CDC media low layer over the FS USB IP + * @retval USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_Init_FS(void) +{ + /* USER CODE BEGIN 3 */ + /* Set Application Buffers */ + USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0); + USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS); + return (USBD_OK); + /* USER CODE END 3 */ +} + +/** + * @brief DeInitializes the CDC media low layer + * @retval USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_DeInit_FS(void) +{ + /* USER CODE BEGIN 4 */ + return (USBD_OK); + /* USER CODE END 4 */ +} + +/** + * @brief Manage the CDC class requests + * @param cmd: Command code + * @param pbuf: Buffer containing command data (request parameters) + * @param length: Number of data to be sent (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) +{ + /* USER CODE BEGIN 5 */ + switch(cmd) + { + case CDC_SEND_ENCAPSULATED_COMMAND: + + break; + + case CDC_GET_ENCAPSULATED_RESPONSE: + + break; + + case CDC_SET_COMM_FEATURE: + + break; + + case CDC_GET_COMM_FEATURE: + + break; + + case CDC_CLEAR_COMM_FEATURE: + + break; + + /*******************************************************************************/ + /* Line Coding Structure */ + /*-----------------------------------------------------------------------------*/ + /* Offset | Field | Size | Value | Description */ + /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/ + /* 4 | bCharFormat | 1 | Number | Stop bits */ + /* 0 - 1 Stop bit */ + /* 1 - 1.5 Stop bits */ + /* 2 - 2 Stop bits */ + /* 5 | bParityType | 1 | Number | Parity */ + /* 0 - None */ + /* 1 - Odd */ + /* 2 - Even */ + /* 3 - Mark */ + /* 4 - Space */ + /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */ + /*******************************************************************************/ + case CDC_SET_LINE_CODING: + + break; + + case CDC_GET_LINE_CODING: + + break; + + case CDC_SET_CONTROL_LINE_STATE: + + break; + + case CDC_SEND_BREAK: + + break; + + default: + break; + } + + return (USBD_OK); + /* USER CODE END 5 */ +} + +/** + * @brief Data received over USB OUT endpoint are sent over CDC interface + * through this function. + * + * @note + * This function will issue a NAK packet on any OUT packet received on + * USB endpoint until exiting this function. If you exit this function + * before transfer is complete on CDC interface (ie. using DMA controller) + * it will result in receiving more data while previous ones are still + * not sent. + * + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) +{ + /* USER CODE BEGIN 6 */ + USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); + USBD_CDC_ReceivePacket(&hUsbDeviceFS); + return (USBD_OK); + /* USER CODE END 6 */ +} + +/** + * @brief CDC_Transmit_FS + * Data to send over USB IN endpoint are sent over CDC interface + * through this function. + * @note + * + * + * @param Buf: Buffer of data to be sent + * @param Len: Number of data to be sent (in bytes) + * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY + */ +uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) +{ + uint8_t result = USBD_OK; + /* USER CODE BEGIN 7 */ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData; + if (hcdc->TxState != 0){ + return USBD_BUSY; + } + USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len); + result = USBD_CDC_TransmitPacket(&hUsbDeviceFS); + /* USER CODE END 7 */ + return result; +} + +/** + * @brief CDC_TransmitCplt_FS + * Data transmitted callback + * + * @note + * This function is IN transfer complete callback used to inform user that + * the submitted Data is successfully sent over USB. + * + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum) +{ + uint8_t result = USBD_OK; + /* USER CODE BEGIN 13 */ + UNUSED(Buf); + UNUSED(Len); + UNUSED(epnum); + /* USER CODE END 13 */ + return result; +} + +/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */ + +/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/board/CubeMX_Config/Src/usbd_conf.c b/board/CubeMX_Config/Src/usbd_conf.c new file mode 100644 index 0000000..de21497 --- /dev/null +++ b/board/CubeMX_Config/Src/usbd_conf.c @@ -0,0 +1,693 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_conf.c + * @version : v1.0_Cube + * @brief : This file implements the board support package for the USB device library + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32h7xx.h" +#include "stm32h7xx_hal.h" +#include "usbd_def.h" +#include "usbd_core.h" +#include "usbd_cdc.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +PCD_HandleTypeDef hpcd_USB_OTG_FS; +void Error_Handler(void); + +/* External functions --------------------------------------------------------*/ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ +USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status); + +/* USER CODE END PFP */ + +/* Private functions ---------------------------------------------------------*/ + +/* USER CODE BEGIN 1 */ +/* USER CODE END 1 */ + +/******************************************************************************* + LL Driver Callbacks (PCD -> USB Device Library) +*******************************************************************************/ +/* MSP Init */ + +void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + if(pcdHandle->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspInit 0 */ + + /* USER CODE END USB_OTG_FS_MspInit 0 */ + + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Enable USB Voltage detector + */ + HAL_PWREx_EnableUSBVoltageDetector(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**USB_OTG_FS GPIO Configuration + PA12 ------> USB_OTG_FS_DP + PA11 ------> USB_OTG_FS_DM + */ + GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_11; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* Peripheral clock enable */ + __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + + /* Peripheral interrupt init */ + HAL_NVIC_SetPriority(OTG_FS_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(OTG_FS_IRQn); + /* USER CODE BEGIN USB_OTG_FS_MspInit 1 */ + + /* USER CODE END USB_OTG_FS_MspInit 1 */ + } +} + +void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) +{ + if(pcdHandle->Instance==USB_OTG_FS) + { + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USB_OTG_FS_CLK_DISABLE(); + + /**USB_OTG_FS GPIO Configuration + PA12 ------> USB_OTG_FS_DP + PA11 ------> USB_OTG_FS_DM + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12|GPIO_PIN_11); + + /* Peripheral interrupt Deinit*/ + HAL_NVIC_DisableIRQ(OTG_FS_IRQn); + + /* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */ + + /* USER CODE END USB_OTG_FS_MspDeInit 1 */ + } +} + +/** + * @brief Setup stage callback + * @param hpcd: PCD handle + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +#else +void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup); +} + +/** + * @brief Data Out stage callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +#else +void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff); +} + +/** + * @brief Data In stage callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +#else +void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff); +} + +/** + * @brief SOF callback. + * @param hpcd: PCD handle + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +#else +void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData); +} + +/** + * @brief Reset callback. + * @param hpcd: PCD handle + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +#else +void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + USBD_SpeedTypeDef speed = USBD_SPEED_FULL; + + if ( hpcd->Init.speed == PCD_SPEED_HIGH) + { + speed = USBD_SPEED_HIGH; + } + else if ( hpcd->Init.speed == PCD_SPEED_FULL) + { + speed = USBD_SPEED_FULL; + } + else + { + Error_Handler(); + } + /* Set Speed. */ + USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed); + + /* Reset Device. */ + USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData); +} + +/** + * @brief Suspend callback. + * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it) + * @param hpcd: PCD handle + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +#else +void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + /* Inform USB library that core enters in suspend Mode. */ + USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData); + __HAL_PCD_GATE_PHYCLOCK(hpcd); + /* Enter in STOP mode. */ + /* USER CODE BEGIN 2 */ + if (hpcd->Init.low_power_enable) + { + /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */ + SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); + } + /* USER CODE END 2 */ +} + +/** + * @brief Resume callback. + * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it) + * @param hpcd: PCD handle + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +#else +void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + /* USER CODE BEGIN 3 */ + + /* USER CODE END 3 */ + USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData); +} + +/** + * @brief ISOOUTIncomplete callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +#else +void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); +} + +/** + * @brief ISOINIncomplete callback. + * @param hpcd: PCD handle + * @param epnum: Endpoint number + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +#else +void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum); +} + +/** + * @brief Connect callback. + * @param hpcd: PCD handle + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) +#else +void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData); +} + +/** + * @brief Disconnect callback. + * @param hpcd: PCD handle + * @retval None + */ +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) +static void PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) +#else +void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ +{ + USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData); +} + +/******************************************************************************* + LL Driver Interface (USB Device Library --> PCD) +*******************************************************************************/ + +/** + * @brief Initializes the low level portion of the device driver. + * @param pdev: Device handle + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) +{ + /* Init USB Ip. */ + if (pdev->id == DEVICE_FS) { + /* Link the driver to the stack. */ + hpcd_USB_OTG_FS.pData = pdev; + pdev->pData = &hpcd_USB_OTG_FS; + + hpcd_USB_OTG_FS.Instance = USB_OTG_FS; + hpcd_USB_OTG_FS.Init.dev_endpoints = 9; + hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL; + hpcd_USB_OTG_FS.Init.dma_enable = ENABLE; + hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED; + hpcd_USB_OTG_FS.Init.Sof_enable = DISABLE; + hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE; + hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE; + hpcd_USB_OTG_FS.Init.battery_charging_enable = DISABLE; + hpcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE; + hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE; + if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK) + { + Error_Handler( ); + } + +#if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U) + /* Register USB PCD CallBacks */ + HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_SOF_CB_ID, PCD_SOFCallback); + HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_SETUPSTAGE_CB_ID, PCD_SetupStageCallback); + HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_RESET_CB_ID, PCD_ResetCallback); + HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_SUSPEND_CB_ID, PCD_SuspendCallback); + HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_RESUME_CB_ID, PCD_ResumeCallback); + HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_CONNECT_CB_ID, PCD_ConnectCallback); + HAL_PCD_RegisterCallback(&hpcd_USB_OTG_FS, HAL_PCD_DISCONNECT_CB_ID, PCD_DisconnectCallback); + + HAL_PCD_RegisterDataOutStageCallback(&hpcd_USB_OTG_FS, PCD_DataOutStageCallback); + HAL_PCD_RegisterDataInStageCallback(&hpcd_USB_OTG_FS, PCD_DataInStageCallback); + HAL_PCD_RegisterIsoOutIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOOUTIncompleteCallback); + HAL_PCD_RegisterIsoInIncpltCallback(&hpcd_USB_OTG_FS, PCD_ISOINIncompleteCallback); +#endif /* USE_HAL_PCD_REGISTER_CALLBACKS */ + /* USER CODE BEGIN TxRx_Configuration */ + HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80); + HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40); + HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80); + /* USER CODE END TxRx_Configuration */ + } + return USBD_OK; +} + +/** + * @brief De-Initializes the low level portion of the device driver. + * @param pdev: Device handle + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_DeInit(pdev->pData); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Starts the low level portion of the device driver. + * @param pdev: Device handle + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_Start(pdev->pData); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Stops the low level portion of the device driver. + * @param pdev: Device handle + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_Stop(pdev->pData); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Opens an endpoint of the low level driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @param ep_type: Endpoint type + * @param ep_mps: Endpoint max packet size + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Closes an endpoint of the low level driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Flushes an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Sets a Stall condition on an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Clears a Stall condition on an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Returns Stall condition. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval Stall (1: Yes, 0: No) + */ +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData; + + if((ep_addr & 0x80) == 0x80) + { + return hpcd->IN_ep[ep_addr & 0x7F].is_stall; + } + else + { + return hpcd->OUT_ep[ep_addr & 0x7F].is_stall; + } +} + +/** + * @brief Assigns a USB address to the device. + * @param pdev: Device handle + * @param dev_addr: Device address + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Transmits data over an endpoint. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @param pbuf: Pointer to data to be sent + * @param size: Data size + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Prepares an endpoint for reception. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @param pbuf: Pointer to data to be received + * @param size: Data size + * @retval USBD status + */ +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size) +{ + HAL_StatusTypeDef hal_status = HAL_OK; + USBD_StatusTypeDef usb_status = USBD_OK; + + hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size); + + usb_status = USBD_Get_USB_Status(hal_status); + + return usb_status; +} + +/** + * @brief Returns the last transferred packet size. + * @param pdev: Device handle + * @param ep_addr: Endpoint number + * @retval Received Data Size + */ +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr); +} + +#ifdef USBD_HS_TESTMODE_ENABLE +/** + * @brief Set High speed Test mode. + * @param pdev: Device handle + * @param testmode: test mode + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_SetTestMode(USBD_HandleTypeDef *pdev, uint8_t testmode) +{ + UNUSED(pdev); + UNUSED(testmode); + + return USBD_OK; +} +#endif /* USBD_HS_TESTMODE_ENABLE */ +/** + * @brief Static single allocation. + * @param size: Size of allocated memory + * @retval None + */ +void *USBD_static_malloc(uint32_t size) +{ + UNUSED(size); + static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */ + return mem; +} + +/** + * @brief Dummy memory free + * @param p: Pointer to allocated memory address + * @retval None + */ +void USBD_static_free(void *p) +{ + UNUSED(p); +} + +/** + * @brief Delays routine for the USB device library. + * @param Delay: Delay in ms + * @retval None + */ +void USBD_LL_Delay(uint32_t Delay) +{ + HAL_Delay(Delay); +} + +/** + * @brief Returns the USB status depending on the HAL status: + * @param hal_status: HAL status + * @retval USB status + */ +USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status) +{ + USBD_StatusTypeDef usb_status = USBD_OK; + + switch (hal_status) + { + case HAL_OK : + usb_status = USBD_OK; + break; + case HAL_ERROR : + usb_status = USBD_FAIL; + break; + case HAL_BUSY : + usb_status = USBD_BUSY; + break; + case HAL_TIMEOUT : + usb_status = USBD_FAIL; + break; + default : + usb_status = USBD_FAIL; + break; + } + return usb_status; +} diff --git a/board/CubeMX_Config/Src/usbd_desc.c b/board/CubeMX_Config/Src/usbd_desc.c new file mode 100644 index 0000000..5145667 --- /dev/null +++ b/board/CubeMX_Config/Src/usbd_desc.c @@ -0,0 +1,418 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : usbd_desc.c + * @version : v1.0_Cube + * @brief : This file implements the USB device descriptors. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_conf.h" + +/* USER CODE BEGIN INCLUDE */ + +/* USER CODE END INCLUDE */ + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY + * @{ + */ + +/** @addtogroup USBD_DESC + * @{ + */ + +/** @defgroup USBD_DESC_Private_TypesDefinitions USBD_DESC_Private_TypesDefinitions + * @brief Private types. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_TYPES */ + +/* USER CODE END PRIVATE_TYPES */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_Defines USBD_DESC_Private_Defines + * @brief Private defines. + * @{ + */ + +#define USBD_VID 1155 +#define USBD_LANGID_STRING 1033 +#define USBD_MANUFACTURER_STRING "STMicroelectronics" +#define USBD_PID_FS 22336 +#define USBD_PRODUCT_STRING_FS "STM32 Virtual ComPort" +#define USBD_CONFIGURATION_STRING_FS "CDC Config" +#define USBD_INTERFACE_STRING_FS "CDC Interface" + +#define USB_SIZ_BOS_DESC 0x0C + +/* USER CODE BEGIN PRIVATE_DEFINES */ + +/* USER CODE END PRIVATE_DEFINES */ + +/** + * @} + */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/** @defgroup USBD_DESC_Private_Macros USBD_DESC_Private_Macros + * @brief Private macros. + * @{ + */ + +/* USER CODE BEGIN PRIVATE_MACRO */ + +/* USER CODE END PRIVATE_MACRO */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes + * @brief Private functions declaration. + * @{ + */ + +static void Get_SerialNum(void); +static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len); + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_FunctionPrototypes USBD_DESC_Private_FunctionPrototypes + * @brief Private functions declaration for FS. + * @{ + */ + +uint8_t * USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables + * @brief Private variables. + * @{ + */ + +USBD_DescriptorsTypeDef FS_Desc = +{ + USBD_FS_DeviceDescriptor +, USBD_FS_LangIDStrDescriptor +, USBD_FS_ManufacturerStrDescriptor +, USBD_FS_ProductStrDescriptor +, USBD_FS_SerialStrDescriptor +, USBD_FS_ConfigStrDescriptor +, USBD_FS_InterfaceStrDescriptor +}; + +#if defined ( __ICCARM__ ) /* IAR Compiler */ + #pragma data_alignment=4 +#endif /* defined ( __ICCARM__ ) */ +/** USB standard device descriptor. */ +__ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = +{ + 0x12, /*bLength */ + USB_DESC_TYPE_DEVICE, /*bDescriptorType*/ + 0x00, /*bcdUSB */ + 0x02, + 0x02, /*bDeviceClass*/ + 0x02, /*bDeviceSubClass*/ + 0x00, /*bDeviceProtocol*/ + USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ + LOBYTE(USBD_VID), /*idVendor*/ + HIBYTE(USBD_VID), /*idVendor*/ + LOBYTE(USBD_PID_FS), /*idProduct*/ + HIBYTE(USBD_PID_FS), /*idProduct*/ + 0x00, /*bcdDevice rel. 2.00*/ + 0x02, + USBD_IDX_MFC_STR, /*Index of manufacturer string*/ + USBD_IDX_PRODUCT_STR, /*Index of product string*/ + USBD_IDX_SERIAL_STR, /*Index of serial number string*/ + USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/ +}; + +/* USB_DeviceDescriptor */ +/** BOS descriptor. */ +#if (USBD_LPM_ENABLED == 1) +#if defined ( __ICCARM__ ) /* IAR Compiler */ + #pragma data_alignment=4 +#endif /* defined ( __ICCARM__ ) */ +__ALIGN_BEGIN uint8_t USBD_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = +{ + 0x5, + USB_DESC_TYPE_BOS, + 0xC, + 0x0, + 0x1, /* 1 device capability*/ + /* device capability*/ + 0x7, + USB_DEVICE_CAPABITY_TYPE, + 0x2, + 0x2, /* LPM capability bit set*/ + 0x0, + 0x0, + 0x0 +}; +#endif /* (USBD_LPM_ENABLED == 1) */ + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables + * @brief Private variables. + * @{ + */ + +#if defined ( __ICCARM__ ) /* IAR Compiler */ + #pragma data_alignment=4 +#endif /* defined ( __ICCARM__ ) */ + +/** USB lang identifier descriptor. */ +__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = +{ + USB_LEN_LANGID_STR_DESC, + USB_DESC_TYPE_STRING, + LOBYTE(USBD_LANGID_STRING), + HIBYTE(USBD_LANGID_STRING) +}; + +#if defined ( __ICCARM__ ) /* IAR Compiler */ + #pragma data_alignment=4 +#endif /* defined ( __ICCARM__ ) */ +/* Internal string descriptor. */ +__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; + +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 +#endif +__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = { + USB_SIZ_STRING_SERIAL, + USB_DESC_TYPE_STRING, +}; + +/** + * @} + */ + +/** @defgroup USBD_DESC_Private_Functions USBD_DESC_Private_Functions + * @brief Private functions. + * @{ + */ + +/** + * @brief Return the device descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_FS_DeviceDesc); + return USBD_FS_DeviceDesc; +} + +/** + * @brief Return the LangID string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_LangIDDesc); + return USBD_LangIDDesc; +} + +/** + * @brief Return the product string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == 0) + { + USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @brief Return the manufacturer string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length); + return USBD_StrDesc; +} + +/** + * @brief Return the serial number string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = USB_SIZ_STRING_SERIAL; + + /* Update the serial number string descriptor with the data from the unique + * ID */ + Get_SerialNum(); + /* USER CODE BEGIN USBD_FS_SerialStrDescriptor */ + + /* USER CODE END USBD_FS_SerialStrDescriptor */ + return (uint8_t *) USBD_StringSerial; +} + +/** + * @brief Return the configuration string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == USBD_SPEED_HIGH) + { + USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_FS, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @brief Return the interface string descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == 0) + { + USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_FS, USBD_StrDesc, length); + } + return USBD_StrDesc; +} + +/** + * @brief Create the serial number string descriptor + * @param None + * @retval None + */ +static void Get_SerialNum(void) +{ + uint32_t deviceserial0; + uint32_t deviceserial1; + uint32_t deviceserial2; + + deviceserial0 = *(uint32_t *) DEVICE_ID1; + deviceserial1 = *(uint32_t *) DEVICE_ID2; + deviceserial2 = *(uint32_t *) DEVICE_ID3; + + deviceserial0 += deviceserial2; + + if (deviceserial0 != 0) + { + IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8); + IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4); + } +} + +/** + * @brief Convert Hex 32Bits value into char + * @param value: value to convert + * @param pbuf: pointer to the buffer + * @param len: buffer length + * @retval None + */ +static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len) +{ + uint8_t idx = 0; + + for (idx = 0; idx < len; idx++) + { + if (((value >> 28)) < 0xA) + { + pbuf[2 * idx] = (value >> 28) + '0'; + } + else + { + pbuf[2 * idx] = (value >> 28) + 'A' - 10; + } + + value = value << 4; + + pbuf[2 * idx + 1] = 0; + } +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + diff --git a/board/CubeMX_Config/cmake/stm32cubemx/CMakeLists.txt b/board/CubeMX_Config/cmake/stm32cubemx/CMakeLists.txt index 4c2665d..d17863c 100644 --- a/board/CubeMX_Config/cmake/stm32cubemx/CMakeLists.txt +++ b/board/CubeMX_Config/cmake/stm32cubemx/CMakeLists.txt @@ -14,24 +14,32 @@ set(MX_Include_Dirs ${CMAKE_CURRENT_SOURCE_DIR}/../../Inc ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Inc ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy + ${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Core/Inc + ${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/CMSIS/Device/ST/STM32H7xx/Include ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/CMSIS/Include ) # STM32CubeMX generated application sources -set(MX_Application_Src +set(MX_Application_Src ${CMAKE_CURRENT_SOURCE_DIR}/../../Src/main.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Src/usb_device.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Src/usbd_conf.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Src/usbd_desc.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Src/usbd_cdc_if.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Src/stm32h7xx_it.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Src/stm32h7xx_hal_msp.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Src/sysmem.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Src/syscalls.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../startup_stm32h750xx.s -) + ${CMAKE_CURRENT_SOURCE_DIR}/../../startup_stm32h750xx.s +) # STM32 HAL/LL Drivers -set(STM32_Drivers_Src +set(STM32_Drivers_Src ${CMAKE_CURRENT_SOURCE_DIR}/../../Src/system_stm32h7xx.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_rcc_ex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_flash.c @@ -43,23 +51,28 @@ set(STM32_Drivers_Src ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_mdma.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pwr_ex.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_cortex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_i2c_ex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_qspi.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_delayblock.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi_ex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c - ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c -) + ${CMAKE_CURRENT_SOURCE_DIR}/../../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c +) # Drivers Midllewares +set(USB_Device_Library_Src + ${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +) # Link directories setup set(MX_LINK_DIRS @@ -69,7 +82,7 @@ set(MX_LINK_DIRS set(MX_LINK_LIBS STM32_Drivers ${TOOLCHAIN_LINK_LIBRARIES} - + USB_Device_Library ) # Interface library for includes and symbols add_library(stm32cubemx INTERFACE) @@ -81,6 +94,11 @@ add_library(STM32_Drivers OBJECT) target_sources(STM32_Drivers PRIVATE ${STM32_Drivers_Src}) target_link_libraries(STM32_Drivers PUBLIC stm32cubemx) + +# Create USB_Device_Library static library +add_library(USB_Device_Library OBJECT) +target_sources(USB_Device_Library PRIVATE ${USB_Device_Library_Src}) +target_link_libraries(USB_Device_Library PUBLIC stm32cubemx) # Add STM32CubeMX generated application sources to the project target_sources(${CMAKE_PROJECT_NAME} PRIVATE ${MX_Application_Src}) diff --git a/board/Kconfig b/board/Kconfig index 9c7d952..749c5b0 100644 --- a/board/Kconfig +++ b/board/Kconfig @@ -52,6 +52,10 @@ menu "On-chip Peripheral Drivers" bool "Enable GPIO" select RT_USING_PIN default y + config BSP_USING_USBD + bool "Enable USB Device" + select RT_USING_USB_DEVICE + default y # menuconfig BSP_USING_UART # bool "Enable UART" diff --git a/board/SConscript b/board/SConscript index 83a064a..5bec199 100644 --- a/board/SConscript +++ b/board/SConscript @@ -8,9 +8,11 @@ cwd = GetCurrentDir() # add the general drivers. src = Glob('board.c') src += Glob('CubeMX_Config/Src/stm32h7xx_hal_msp.c') -src += Glob('ports/qspi_flash_init.c') +# src += Glob('ports/qspi_flash_init.c') +src += Glob('ports/usb/*.c') path = [cwd] path += [cwd + '/CubeMX_Config/Inc'] +path += [cwd + '/ports/usb'] # 这样需要包含 core_cm7.h ROOT = os.path.abspath(os.path.join(cwd, '..')) diff --git a/board/board.c b/board/board.c index 9d7687e..3ecf992 100644 --- a/board/board.c +++ b/board/board.c @@ -11,7 +11,7 @@ #include "board.h" /** - * @brief System Clock Configuration + * @brief System Clock Configuration ,因为boot 开启了QSPI的时钟,故这里也要开启。要和boot 保持一致,如何要和 * @retval None */ void SystemClock_Config(void) @@ -32,17 +32,16 @@ void SystemClock_Config(void) /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; - RCC_OscInitStruct.HSIState = RCC_HSI_DIV1; - RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLM = 4; - RCC_OscInitStruct.PLL.PLLN = 60; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 5; + RCC_OscInitStruct.PLL.PLLN = 192; RCC_OscInitStruct.PLL.PLLP = 2; - RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLQ = 20; RCC_OscInitStruct.PLL.PLLR = 2; - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) @@ -126,9 +125,4 @@ static int ota_app_vtor_reconfig(void) return 0; } INIT_BOARD_EXPORT(ota_app_vtor_reconfig); - - - - - INIT_BOARD_EXPORT(MPU_Config); \ No newline at end of file diff --git a/board/linker_scripts/link.lds b/board/linker_scripts/link.lds index ce9f723..5b8f151 100644 --- a/board/linker_scripts/link.lds +++ b/board/linker_scripts/link.lds @@ -1,14 +1,16 @@ /* STM32H750XBHx - RT-Thread linker script (GCC/ld) - * FLASH 128K @ 0x08000000 (代码/常量/表) - * DTCMRAM 128K @ 0x20000000 (data/bss, MSP stack top) - * AXI SRAM 512K @ 0x24000000 (heap recommended) - * D2 SRAM 288K @ 0x30000000 (no use) - * D3 SRAM 64K @ 0x38000000 (no use) - * ITCMRAM 64K @ 0x00000000 (no use) + * + * XIP QSPI FLASH: 0x9000_0000 (8MB) -> .isr_vector/.text/.rodata/const tables + * DTCM RAM : 0x2000_0000 (128KB)-> .data/.bss (fast CPU access, NOT for DMA) + * AXI SRAM : 0x2400_0000 (512KB)-> system heap recommended + * D2 SRAM : 0x3000_0000 (288KB)-> USB DMA buffers (nocache/buffer) recommended + * D3 SRAM : 0x3800_0000 (64KB) + * ITCM RAM : 0x0000_0000 (64KB) */ ENTRY(Reset_Handler) +/* Memory regions */ MEMORY { ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K @@ -22,11 +24,13 @@ MEMORY /* MSP stack top (startup uses this) */ _estack = ORIGIN(DTCMRAM) + LENGTH(DTCMRAM); -/* Only for link-check (does NOT define RT-Thread heap) */ -_Min_Stack_Size = 0x400; -_Min_Heap_Size = 0x0; +/* Only for link-check / startup template compatibility + * NOTE: RT-Thread thread stacks are NOT defined by this. + */ +_Min_Stack_Size = 0x800; +_Min_Heap_Size = 0x400; -/* RT-Thread heap range in AXI SRAM (use these in board.h) */ +/* RT-Thread heap range in AXI SRAM (use these in board.c/board.h) */ PROVIDE(__heap_start__ = ORIGIN(RAM)); PROVIDE(__heap_end__ = ORIGIN(RAM) + LENGTH(RAM)); @@ -141,15 +145,17 @@ SECTIONS { . = ALIGN(4); _sdata = .; + *(.data) *(.data*) *(.RamFunc) *(.RamFunc*) + . = ALIGN(4); _edata = .; } > DTCMRAM AT> FLASH - /* used by startup to copy .data from FLASH to DTCM */ + /* Used by startup to copy .data from FLASH to DTCM */ _sidata = LOADADDR(.data); /* BSS -> DTCM */ @@ -169,6 +175,25 @@ SECTIONS PROVIDE(__bss_end = .); } > DTCMRAM + /* ---------------- USB DMA buffers in D2 SRAM ---------------- + * Put all USB DMA related buffers here: + * __attribute__((section(".usb_nocache"))) / ".noncacheable" + * Align to 32 bytes for safety (future D-Cache + cache-line ops) + */ + .usb_nocache (NOLOAD) : + { + . = ALIGN(32); + __usb_nocache_start__ = .; + + *(.usb_nocache) + *(.usb_nocache*) + *(.noncacheable) + *(.noncacheable*) + + . = ALIGN(32); + __usb_nocache_end__ = .; + } > RAM_D2 + /* End symbols (end of DTCM used sections) */ PROVIDE(end = .); PROVIDE(_end = .); @@ -181,3 +206,7 @@ SECTIONS . = ALIGN(8); } > DTCMRAM } + +/* Optional: sanity checks */ +ASSERT(_ebss <= (ORIGIN(DTCMRAM) + LENGTH(DTCMRAM)), "DTCMRAM overflow: .data/.bss too large"); +ASSERT(__usb_nocache_end__ <= (ORIGIN(RAM_D2) + LENGTH(RAM_D2)), "D2 overflow: USB nocache section too large"); diff --git a/board/ports/qspi_flash_init.c b/board/ports/qflash/qspi_flash_init.c similarity index 100% rename from board/ports/qspi_flash_init.c rename to board/ports/qflash/qspi_flash_init.c diff --git a/board/ports/usb/usb_cdc_char_device.c b/board/ports/usb/usb_cdc_char_device.c new file mode 100644 index 0000000..1f96a90 --- /dev/null +++ b/board/ports/usb/usb_cdc_char_device.c @@ -0,0 +1,408 @@ +#include "usb_cdc_char_device.h" + +#include +#include + +#include +#include +#include + +#include "usbd_core.h" +#include "usbd_cdc_acm.h" + +#if !defined(RT_USING_DEVICE_OPS) +#error "RT_USING_DEVICE_OPS must be enabled" +#endif + +#if !defined(CONFIG_USBDEV_ADVANCE_DESC) +#error "Please enable CONFIG_USBDEV_ADVANCE_DESC" +#endif + +/* -------------------- FS fixed config -------------------- */ +enum +{ + CDC_IN_EP = 0x81, + CDC_OUT_EP = 0x02, + CDC_INT_EP = 0x83, + + CDC_VID = 0xFFFF, + CDC_PID = 0xFFFF, + + CDC_MAX_POWER_MA = 100, + CDC_MAX_MPS = 64, /* FS */ + + CDC_RX_DMA_SIZE = 2048, /* OUT DMA buffer */ + CDC_TX_DMA_SIZE = 2048, /* IN DMA buffer */ + CDC_RX_RING_SIZE = 8192, /* software RX ringbuffer */ + + CDC_CONFIG_SIZE = (9 + CDC_ACM_DESCRIPTOR_LEN), + + /* 保险丝:防止上层误传超大 size(比如把负数当无符号) */ + CDC_WRITE_SIZE_GUARD = 64 * 1024, /* 64KB */ +}; + +/* -------------------- DMA buffers in nocache RAM -------------------- */ +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX static uint8_t g_rx_dma[CDC_RX_DMA_SIZE]; +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX static uint8_t g_tx_dma[CDC_TX_DMA_SIZE]; + +/* -------------------- descriptors (advance-desc callbacks) -------------------- */ +static const uint8_t g_device_desc[] = { + USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, + CDC_VID, CDC_PID, + 0x0100, 0x01) +}; + +static const uint8_t g_config_desc[] = { + USB_CONFIG_DESCRIPTOR_INIT(CDC_CONFIG_SIZE, 0x02, 0x01, + USB_CONFIG_BUS_POWERED, CDC_MAX_POWER_MA), + CDC_ACM_DESCRIPTOR_INIT(0x00, + CDC_INT_EP, + CDC_OUT_EP, + CDC_IN_EP, + CDC_MAX_MPS, + 0x02) +}; + +/* qualifier:FS 下不是必须,但留着不影响 */ +static const uint8_t g_device_qual_desc[] = { + 0x0a, USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER, + 0x00, 0x02, + 0x00, 0x00, 0x00, + 0x40, + 0x00, 0x00, +}; + +static const char g_langid_bytes[] = { 0x09, 0x04 }; +static const char *g_string_desc[] = { + g_langid_bytes, + "CherryUSB", + "RTT CDC ACM FS", + "000000000001", +}; + +static const uint8_t *device_descriptor_cb(uint8_t speed) { (void)speed; return g_device_desc; } +static const uint8_t *config_descriptor_cb(uint8_t speed) { (void)speed; return g_config_desc; } +static const uint8_t *device_qual_descriptor_cb(uint8_t speed) { (void)speed; return g_device_qual_desc; } +static const char *string_descriptor_cb(uint8_t speed, uint8_t index) +{ + (void)speed; + if (index > 3) return RT_NULL; + return g_string_desc[index]; +} + +static const struct usb_descriptor g_cdc_desc = { + .device_descriptor_callback = device_descriptor_cb, + .config_descriptor_callback = config_descriptor_cb, + .device_quality_descriptor_callback = device_qual_descriptor_cb, + .string_descriptor_callback = string_descriptor_cb +}; + +/* -------------------- driver object -------------------- */ +struct cdc_char_dev +{ + struct rt_device dev; /* must be first */ + + uint8_t busid; + uintptr_t reg_base; + + volatile rt_uint8_t dtr_enable; + volatile rt_uint8_t connected; + volatile rt_uint8_t configured; + + struct rt_ringbuffer *rx_rb; + + rt_sem_t tx_sem; + rt_mutex_t tx_lock; + + uint32_t tx_timeout_ms; + uint8_t require_dtr_tx; + + struct usbd_interface intf0; + struct usbd_interface intf1; + struct usbd_endpoint out_ep; + struct usbd_endpoint in_ep; +}; + +static struct cdc_char_dev g_cdc; + +/* -------------------- forward declarations -------------------- */ +static void usbd_event_handler(uint8_t busid, uint8_t event); +static void cdc_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes); +static void cdc_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes); + +/* -------------------- RT device ops -------------------- */ +static rt_err_t cdc_init(rt_device_t dev) { (void)dev; return RT_EOK; } +static rt_err_t cdc_open(rt_device_t dev, rt_uint16_t oflag) { (void)dev; (void)oflag; return RT_EOK; } +static rt_err_t cdc_close(rt_device_t dev) { (void)dev; return RT_EOK; } + +static rt_ssize_t cdc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + (void)pos; + if (!dev || !buffer) return -RT_EINVAL; + if (size == 0) return 0; + + struct cdc_char_dev *c = (struct cdc_char_dev *)dev; + + /* 未枚举配置完成,不允许读(避免上层误用) */ + if (!c->configured) return -RT_EIO; + + if (!c->rx_rb) return -RT_ERROR; + + rt_base_t level = rt_hw_interrupt_disable(); + rt_size_t got = rt_ringbuffer_get(c->rx_rb, (rt_uint8_t *)buffer, size); + rt_hw_interrupt_enable(level); + + return (rt_ssize_t)got; /* ringbuffer 空则返回 0 */ +} + +static rt_ssize_t cdc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + (void)pos; + if (!dev || !buffer) return -RT_EINVAL; + if (size == 0) return 0; + + /* 保险丝:防止上层把负数当 size 传下来 */ + if (size > CDC_WRITE_SIZE_GUARD) return -RT_EINVAL; + + struct cdc_char_dev *c = (struct cdc_char_dev *)dev; + + /* 未配置/断开,不允许写 */ + if (!c->configured) return -RT_EIO; + if (c->require_dtr_tx && !c->dtr_enable) return -RT_EIO; + + if (!c->tx_sem || !c->tx_lock) return -RT_ERROR; + + rt_mutex_take(c->tx_lock, RT_WAITING_FOREVER); + + rt_size_t sent_total = 0; + const rt_uint8_t *p = (const rt_uint8_t *)buffer; + + while (sent_total < size) + { + /* 如果中途断开/重置,立刻失败 */ + if (!c->configured) + { + rt_mutex_release(c->tx_lock); + return (sent_total > 0) ? (rt_ssize_t)sent_total : -RT_EIO; + } + + rt_size_t chunk = size - sent_total; + if (chunk > CDC_TX_DMA_SIZE) chunk = CDC_TX_DMA_SIZE; + + memcpy(g_tx_dma, p + sent_total, chunk); + + /* 清掉旧 token */ + while (rt_sem_trytake(c->tx_sem) == RT_EOK) {} + + usbd_ep_start_write(c->busid, CDC_IN_EP, g_tx_dma, (uint32_t)chunk); + + rt_tick_t to = rt_tick_from_millisecond(c->tx_timeout_ms); + if (rt_sem_take(c->tx_sem, to) != RT_EOK) + { + rt_mutex_release(c->tx_lock); + return (sent_total > 0) ? (rt_ssize_t)sent_total : -RT_ETIMEOUT; + } + + /* 被唤醒后再次确认仍处于 configured(避免断开时“假完成”) */ + if (!c->configured) + { + rt_mutex_release(c->tx_lock); + return (sent_total > 0) ? (rt_ssize_t)sent_total : -RT_EIO; + } + + sent_total += chunk; + } + + rt_mutex_release(c->tx_lock); + return (rt_ssize_t)sent_total; +} + +static rt_err_t cdc_control(rt_device_t dev, int cmd, void *args) +{ + if (!dev) return -RT_EINVAL; + struct cdc_char_dev *c = (struct cdc_char_dev *)dev; + + switch (cmd) + { + case CDC_CTRL_SET_TX_TIMEOUT_MS: + if (args) c->tx_timeout_ms = *(uint32_t *)args; + return RT_EOK; + + case CDC_CTRL_GET_TX_TIMEOUT_MS: + if (args) *(uint32_t *)args = c->tx_timeout_ms; + return RT_EOK; + + case CDC_CTRL_GET_DTR: + if (args) *(uint8_t *)args = c->dtr_enable; + return RT_EOK; + + case CDC_CTRL_SET_REQUIRE_DTR_TX: + if (args) c->require_dtr_tx = (*(uint8_t *)args) ? 1 : 0; + return RT_EOK; + + case CDC_CTRL_GET_CONFIGURED: /* ✅ 新增:查询是否已枚举配置 */ + if (args) *(uint8_t *)args = c->configured; + return RT_EOK; + + default: + return -RT_ENOSYS; + } +} + +/* ops table */ +static const struct rt_device_ops cdc_ops = +{ + .init = cdc_init, + .open = cdc_open, + .close = cdc_close, + .read = cdc_read, + .write = cdc_write, + .control = cdc_control, +}; + +/* -------------------- CherryUSB callbacks -------------------- */ +static void usbd_event_handler(uint8_t busid, uint8_t event) +{ + (void)busid; + + switch (event) + { + case USBD_EVENT_RESET: + g_cdc.configured = 0; + g_cdc.connected = 0; + + /* 可选:唤醒等待线程,让它能尽快感知状态变化 */ + if (g_cdc.dev.rx_indicate) + g_cdc.dev.rx_indicate((rt_device_t)&g_cdc.dev, 0); + break; + + case USBD_EVENT_CONNECTED: + g_cdc.connected = 1; + break; + + case USBD_EVENT_DISCONNECTED: + g_cdc.configured = 0; + g_cdc.connected = 0; + + /* 可选:唤醒等待线程 */ + if (g_cdc.dev.rx_indicate) + g_cdc.dev.rx_indicate((rt_device_t)&g_cdc.dev, 0); + break; + + case USBD_EVENT_CONFIGURED: + g_cdc.connected = 1; + g_cdc.configured = 1; + + /* 重新启动 OUT 读(防止 reset 后没读) */ + usbd_ep_start_read(g_cdc.busid, CDC_OUT_EP, g_rx_dma, CDC_RX_DMA_SIZE); + + /* 可选:唤醒等待线程,让“先启动线程再插线”也能快速进入工作状态 */ + if (g_cdc.dev.rx_indicate) + g_cdc.dev.rx_indicate((rt_device_t)&g_cdc.dev, 0); + break; + + default: + break; + } +} + +static void cdc_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + (void)busid; + (void)ep; + + /* 未配置时忽略数据,并继续挂下一次读 */ + if (!g_cdc.configured) + { + usbd_ep_start_read(g_cdc.busid, CDC_OUT_EP, g_rx_dma, CDC_RX_DMA_SIZE); + return; + } + + if (nbytes > 0 && nbytes <= CDC_RX_DMA_SIZE && g_cdc.rx_rb) + { + (void)rt_ringbuffer_put(g_cdc.rx_rb, g_rx_dma, (rt_size_t)nbytes); + + if (g_cdc.dev.rx_indicate) + g_cdc.dev.rx_indicate((rt_device_t)&g_cdc.dev, (rt_size_t)nbytes); + } + + usbd_ep_start_read(g_cdc.busid, CDC_OUT_EP, g_rx_dma, CDC_RX_DMA_SIZE); +} + +static void cdc_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + (void)busid; + + /* ZLP:长度是 MPS 整倍数时补 0 包 */ + if ((nbytes % usbd_get_ep_mps(g_cdc.busid, ep)) == 0 && nbytes) + { + usbd_ep_start_write(g_cdc.busid, CDC_IN_EP, RT_NULL, 0); + return; + } + + if (g_cdc.tx_sem) rt_sem_release(g_cdc.tx_sem); + + if (g_cdc.dev.tx_complete) + g_cdc.dev.tx_complete((rt_device_t)&g_cdc.dev, RT_NULL); +} + +/* DTR hook */ +void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr) +{ + (void)busid; + (void)intf; + g_cdc.dtr_enable = dtr ? 1 : 0; +} + +/* endpoints */ +static struct usbd_endpoint g_out_ep = { .ep_addr = CDC_OUT_EP, .ep_cb = cdc_bulk_out }; +static struct usbd_endpoint g_in_ep = { .ep_addr = CDC_IN_EP, .ep_cb = cdc_bulk_in }; + +/* -------------------- public init -------------------- */ +int rt_hw_usbd_cdc_char_init(const char *dev_name, uint8_t busid, uintptr_t reg_base) +{ + if (!dev_name) return -RT_EINVAL; + + memset(&g_cdc, 0, sizeof(g_cdc)); + g_cdc.busid = busid; + g_cdc.reg_base = reg_base; + + g_cdc.tx_timeout_ms = 2000; + g_cdc.require_dtr_tx = 0; + g_cdc.connected = 0; + g_cdc.configured = 0; + + g_cdc.rx_rb = rt_ringbuffer_create(CDC_RX_RING_SIZE); + if (!g_cdc.rx_rb) return -RT_ENOMEM; + + g_cdc.tx_sem = rt_sem_create("cdc_tx", 0, RT_IPC_FLAG_FIFO); + if (!g_cdc.tx_sem) return -RT_ENOMEM; + + g_cdc.tx_lock = rt_mutex_create("cdc_txL", RT_IPC_FLAG_FIFO); + if (!g_cdc.tx_lock) return -RT_ENOMEM; + + /* register char device */ + g_cdc.dev.type = RT_Device_Class_Char; + g_cdc.dev.rx_indicate = RT_NULL; + g_cdc.dev.tx_complete = RT_NULL; + g_cdc.dev.ops = &cdc_ops; + g_cdc.dev.user_data = RT_NULL; + + rt_err_t r = rt_device_register((rt_device_t)&g_cdc.dev, dev_name, RT_DEVICE_FLAG_RDWR); + if (r != RT_EOK) return r; + + /* init CherryUSB CDC */ + usbd_desc_register(g_cdc.busid, &g_cdc_desc); + + usbd_add_interface(g_cdc.busid, usbd_cdc_acm_init_intf(g_cdc.busid, &g_cdc.intf0)); + usbd_add_interface(g_cdc.busid, usbd_cdc_acm_init_intf(g_cdc.busid, &g_cdc.intf1)); + + g_cdc.out_ep = g_out_ep; + g_cdc.in_ep = g_in_ep; + usbd_add_endpoint(g_cdc.busid, &g_cdc.out_ep); + usbd_add_endpoint(g_cdc.busid, &g_cdc.in_ep); + + usbd_initialize(g_cdc.busid, g_cdc.reg_base, usbd_event_handler); + + return 0; +} diff --git a/board/ports/usb/usb_cdc_char_device.h b/board/ports/usb/usb_cdc_char_device.h new file mode 100644 index 0000000..3973a3b --- /dev/null +++ b/board/ports/usb/usb_cdc_char_device.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CDC_CTRL_SET_TX_TIMEOUT_MS 0x10 /* arg: uint32_t* */ +#define CDC_CTRL_GET_TX_TIMEOUT_MS 0x11 /* arg: uint32_t* */ +#define CDC_CTRL_GET_DTR 0x12 /* arg: uint8_t* */ +#define CDC_CTRL_SET_REQUIRE_DTR_TX 0x13 /* arg: uint8_t* (0/1) */ +#define CDC_CTRL_GET_CONFIGURED 0x14 /* arg: uint8_t* (0/1) */ + + int rt_hw_usbd_cdc_char_init(const char *dev_name, uint8_t busid, uintptr_t reg_base); + +#ifdef __cplusplus +} +#endif diff --git a/board/ports/usb/usb_cdc_init.c b/board/ports/usb/usb_cdc_init.c new file mode 100644 index 0000000..7dab00e --- /dev/null +++ b/board/ports/usb/usb_cdc_init.c @@ -0,0 +1,154 @@ +// +// Created by Administrator on 2025/12/31. +// +#include "usb_cdc_char_device.h" +#include + +// 例如在 board init / main 里 +int usb_init(void) +{ + return rt_hw_usbd_cdc_char_init("cdc0", 0, USB_OTG_FS_PERIPH_BASE); +} +// INIT_APP_EXPORT(usb_init); + + +#include "usb_cdc_char_device.h" /* 为了 CDC_CTRL_GET_CONFIGURED */ + +/* 线程参数 */ +#define CDC_ECHO_THREAD_NAME "cdc_echo" +#define CDC_ECHO_THREAD_STACK 4096 +#define CDC_ECHO_THREAD_PRIO 20 +#define CDC_ECHO_THREAD_TICK 10 + +/* 等待策略 */ +#define CDC_WAIT_SEM_TIMEOUT_MS 500 /* 不要 FOREVER,支持先启动后插线/断开重连 */ +#define CDC_NOT_CFG_DELAY_MS 50 + +/* RX 等待信号量 */ +static rt_sem_t s_cdc_rx_sem = RT_NULL; +/* 保存设备句柄 */ +static rt_device_t s_cdc_dev = RT_NULL; + +/* RX 回调:有数据到来时被驱动调用(或驱动事件里用 size=0 唤醒) */ +static rt_err_t cdc_rx_ind(rt_device_t dev, rt_size_t size) +{ + (void)dev; + (void)size; + + if (s_cdc_rx_sem) + { + rt_sem_release(s_cdc_rx_sem); + } + return RT_EOK; +} + +static int cdc_is_configured(rt_device_t dev) +{ + uint8_t cfg = 0; + if (rt_device_control(dev, CDC_CTRL_GET_CONFIGURED, &cfg) == RT_EOK) + { + return cfg ? 1 : 0; + } + /* control 不支持时,保守认为未配置 */ + return 0; +} + +/* echo 线程:等待 -> 读 -> 立刻写回(支持断开重连) */ +static void cdc_echo_thread(void *parameter) +{ + (void)parameter; + + s_cdc_dev = rt_device_find("cdc0"); + if (!s_cdc_dev) + { + rt_kprintf("cdc_echo: cdc0 not found\n"); + return; + } + + if (rt_device_open(s_cdc_dev, RT_DEVICE_OFLAG_RDWR) != RT_EOK) + { + rt_kprintf("cdc_echo: open cdc0 failed\n"); + return; + } + + s_cdc_rx_sem = rt_sem_create("cdc_rx", 0, RT_IPC_FLAG_FIFO); + if (!s_cdc_rx_sem) + { + rt_kprintf("cdc_echo: sem create failed\n"); + rt_device_close(s_cdc_dev); + return; + } + + rt_device_set_rx_indicate(s_cdc_dev, cdc_rx_ind); + + rt_kprintf("cdc_echo: started, supports plug/unplug\n"); + + char buf[1024]; + + while (1) + { + /* 关键:不要 FOREVER,避免未插线/断开时永远卡住 */ + rt_sem_take(s_cdc_rx_sem, rt_tick_from_millisecond(CDC_WAIT_SEM_TIMEOUT_MS)); + + /* 没枚举好/断开:不读不写,稍等继续 */ + if (!cdc_is_configured(s_cdc_dev)) + { + rt_thread_mdelay(CDC_NOT_CFG_DELAY_MS); + continue; + } + + /* 把 ringbuffer 里当前所有数据读光并回写 */ + while (1) + { + rt_ssize_t rn = rt_device_read(s_cdc_dev, 0, buf, sizeof(buf)); + if (rn > 0) + { + rt_ssize_t wn = rt_device_write(s_cdc_dev, 0, buf, (rt_size_t)rn); + if (wn < 0) + { + /* 典型:断开/未配置 => -RT_EIO */ + rt_kprintf("cdc_echo: write err=%d\n", (int)wn); + break; + } + } + else if (rn == 0) + { + /* 暂时没数据 */ + rt_kprintf("cdc_echo: read err=%d\n", (int)rn); + break; + } + else + { + /* rn < 0:典型 -RT_EIO(断开/未配置) */ + rt_kprintf("cdc_echo: read err=%d\n", (int)rn); + break; + } + } + } +} + +/* 创建并启动线程 */ +int cdc_echo_start(void) +{ + if (rt_thread_find(CDC_ECHO_THREAD_NAME)) + { + rt_kprintf("cdc_echo: thread already running\n"); + return -RT_EBUSY; + } + + rt_thread_t tid = rt_thread_create(CDC_ECHO_THREAD_NAME, + cdc_echo_thread, + RT_NULL, + CDC_ECHO_THREAD_STACK, + CDC_ECHO_THREAD_PRIO, + CDC_ECHO_THREAD_TICK); + if (!tid) + { + rt_kprintf("cdc_echo: create thread failed\n"); + return -RT_ENOMEM; + } + + rt_thread_startup(tid); + return RT_EOK; +} +MSH_CMD_EXPORT(cdc_echo_start, start usb cdc echo thread); \ No newline at end of file diff --git a/board/ports/usb/usb_config.h b/board/ports/usb/usb_config.h new file mode 100644 index 0000000..49fa046 --- /dev/null +++ b/board/ports/usb/usb_config.h @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2022, sakumisu + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef CHERRYUSB_CONFIG_H +#define CHERRYUSB_CONFIG_H + +/* ================ USB common Configuration ================ */ + +#ifdef __RTTHREAD__ +#include + +#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define CONFIG_USB_PRINTF(...) printf(__VA_ARGS__) +#endif + +#ifndef CONFIG_USB_DBG_LEVEL +#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO +#endif + +/* Enable print with color */ +#define CONFIG_USB_PRINTF_COLOR_ENABLE + +// #define CONFIG_USB_DCACHE_ENABLE + +/* data align size when use dma or use dcache */ +#ifdef CONFIG_USB_DCACHE_ENABLE +#define CONFIG_USB_ALIGN_SIZE 32 // 32 or 64 +#else +#define CONFIG_USB_ALIGN_SIZE 32 +#endif + +/* attribute data into no cache ram */ +#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable"))) + +/* use usb_memcpy default for high performance but cost more flash memory. + * And, arm libc has a bug that memcpy() may cause data misalignment when the size is not a multiple of 4. +*/ +// #define CONFIG_USB_MEMCPY_DISABLE + +/* ================= USB Device Stack Configuration ================ */ + +/* Ep0 in and out transfer buffer */ +#ifndef CONFIG_USBDEV_REQUEST_BUFFER_LEN +#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 512 +#endif + +/* Send ep0 in data from user buffer instead of copying into ep0 reqdata + * Please note that user buffer must be aligned with CONFIG_USB_ALIGN_SIZE +*/ +// #define CONFIG_USBDEV_EP0_INDATA_NO_COPY + +/* Check if the input descriptor is correct */ +// #define CONFIG_USBDEV_DESC_CHECK + +/* Enable test mode */ +// #define CONFIG_USBDEV_TEST_MODE + +/* enable advance desc register api */ +#define CONFIG_USBDEV_ADVANCE_DESC + +/* move ep0 setup handler from isr to thread */ +// #define CONFIG_USBDEV_EP0_THREAD + +#ifndef CONFIG_USBDEV_EP0_PRIO +#define CONFIG_USBDEV_EP0_PRIO 4 +#endif + +#ifndef CONFIG_USBDEV_EP0_STACKSIZE +#define CONFIG_USBDEV_EP0_STACKSIZE 2048 +#endif + +#ifndef CONFIG_USBDEV_MSC_MAX_LUN +#define CONFIG_USBDEV_MSC_MAX_LUN 1 +#endif + +#ifndef CONFIG_USBDEV_MSC_MAX_BUFSIZE +#define CONFIG_USBDEV_MSC_MAX_BUFSIZE 512 +#endif + +#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING +#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING "" +#endif + +#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING +#define CONFIG_USBDEV_MSC_PRODUCT_STRING "" +#endif + +#ifndef CONFIG_USBDEV_MSC_VERSION_STRING +#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01" +#endif + +/* move msc read & write from isr to while(1), you should call usbd_msc_polling in while(1) */ +// #define CONFIG_USBDEV_MSC_POLLING + +/* move msc read & write from isr to thread */ +// #define CONFIG_USBDEV_MSC_THREAD + +#ifndef CONFIG_USBDEV_MSC_PRIO +#define CONFIG_USBDEV_MSC_PRIO 4 +#endif + +#ifndef CONFIG_USBDEV_MSC_STACKSIZE +#define CONFIG_USBDEV_MSC_STACKSIZE 2048 +#endif + +#ifndef CONFIG_USBDEV_MTP_MAX_BUFSIZE +#define CONFIG_USBDEV_MTP_MAX_BUFSIZE 2048 +#endif + +#ifndef CONFIG_USBDEV_MTP_MAX_OBJECTS +#define CONFIG_USBDEV_MTP_MAX_OBJECTS 256 +#endif + +#ifndef CONFIG_USBDEV_MTP_MAX_PATHNAME +#define CONFIG_USBDEV_MTP_MAX_PATHNAME 256 +#endif + +#define CONFIG_USBDEV_MTP_THREAD + +#ifndef CONFIG_USBDEV_MTP_PRIO +#define CONFIG_USBDEV_MTP_PRIO 4 +#endif + +#ifndef CONFIG_USBDEV_MTP_STACKSIZE +#define CONFIG_USBDEV_MTP_STACKSIZE 4096 +#endif + +#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE +#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156 +#endif + +/* rndis transfer buffer size, must be a multiple of (1536 + 44)*/ +#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE +#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580 +#endif + +#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID +#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff +#endif + +#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC +#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB" +#endif + +#define CONFIG_USBDEV_RNDIS_USING_LWIP +#define CONFIG_USBDEV_CDC_ECM_USING_LWIP + +/* ================ USB HOST Stack Configuration ================== */ + +#define CONFIG_USBHOST_MAX_RHPORTS 1 +#define CONFIG_USBHOST_MAX_EXTHUBS 1 +#define CONFIG_USBHOST_MAX_EHPORTS 4 +#define CONFIG_USBHOST_MAX_INTERFACES 8 +#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2 +#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 +#define CONFIG_USBHOST_PSC_PRIO 0 +#endif +#ifndef CONFIG_USBHOST_PSC_STACKSIZE +#define CONFIG_USBHOST_PSC_STACKSIZE 2048 +#endif + +//#define CONFIG_USBHOST_GET_STRING_DESC + +// #define CONFIG_USBHOST_MSOS_ENABLE +#ifndef CONFIG_USBHOST_MSOS_VENDOR_CODE +#define CONFIG_USBHOST_MSOS_VENDOR_CODE 0x00 +#endif + +/* Ep0 max transfer buffer */ +#ifndef CONFIG_USBHOST_REQUEST_BUFFER_LEN +#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512 +#endif + +#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT +#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500 +#endif + +#ifndef CONFIG_USBHOST_MSC_TIMEOUT +#define CONFIG_USBHOST_MSC_TIMEOUT 5000 +#endif + +/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, + * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. + */ +#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE +#define CONFIG_USBHOST_RNDIS_ETH_MAX_RX_SIZE (2048) +#endif + +/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ +#ifndef CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE +#define CONFIG_USBHOST_RNDIS_ETH_MAX_TX_SIZE (2048) +#endif + +/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, + * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. + */ +#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE +#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_RX_SIZE (2048) +#endif +/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ +#ifndef CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE +#define CONFIG_USBHOST_CDC_NCM_ETH_MAX_TX_SIZE (2048) +#endif + +/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, + * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. + */ +#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE +#define CONFIG_USBHOST_ASIX_ETH_MAX_RX_SIZE (2048) +#endif +/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ +#ifndef CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE +#define CONFIG_USBHOST_ASIX_ETH_MAX_TX_SIZE (2048) +#endif + +/* This parameter affects usb performance, and depends on (TCP_WND)tcp eceive windows size, + * you can change to 2K ~ 16K and must be larger than TCP RX windows size in order to avoid being overflow. + */ +#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE +#define CONFIG_USBHOST_RTL8152_ETH_MAX_RX_SIZE (2048) +#endif +/* Because lwip do not support multi pbuf at a time, so increasing this variable has no performance improvement */ +#ifndef CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE +#define CONFIG_USBHOST_RTL8152_ETH_MAX_TX_SIZE (2048) +#endif + +#define CONFIG_USBHOST_BLUETOOTH_HCI_H4 +// #define CONFIG_USBHOST_BLUETOOTH_HCI_LOG + +#ifndef CONFIG_USBHOST_BLUETOOTH_TX_SIZE +#define CONFIG_USBHOST_BLUETOOTH_TX_SIZE 2048 +#endif +#ifndef CONFIG_USBHOST_BLUETOOTH_RX_SIZE +#define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048 +#endif + +/* ================ USB Device Port Configuration ================*/ + +#ifndef CONFIG_USBDEV_MAX_BUS +#define CONFIG_USBDEV_MAX_BUS 1 +#endif + +// #define CONFIG_USBDEV_SOF_ENABLE + +/* ---------------- FSDEV Configuration ---------------- */ +//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference + +/* ---------------- DWC2 Configuration ---------------- */ +/* enable dwc2 buffer dma mode for device + * in xxx32 chips, only pb14/pb15 can support dma mode, pa11/pa12 is not supported(only a few supports, but we ignore them) +*/ +// #define CONFIG_USB_DWC2_DMA_ENABLE + +/* ---------------- MUSB Configuration ---------------- */ +#define CONFIG_USB_MUSB_EP_NUM 8 +// #define CONFIG_USB_MUSB_SUNXI + +/* ================ USB Host Port Configuration ==================*/ +#ifndef CONFIG_USBHOST_MAX_BUS +#define CONFIG_USBHOST_MAX_BUS 1 +#endif + +/* ---------------- EHCI Configuration ---------------- */ + +#define CONFIG_USB_EHCI_HCCR_OFFSET (0x0) +#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024 +#define CONFIG_USB_EHCI_QH_NUM 10 +#define CONFIG_USB_EHCI_QTD_NUM (CONFIG_USB_EHCI_QH_NUM * 3) +#define CONFIG_USB_EHCI_ITD_NUM 4 +// #define CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE +// #define CONFIG_USB_EHCI_CONFIGFLAG +// #define CONFIG_USB_EHCI_ISO +// #define CONFIG_USB_EHCI_WITH_OHCI +// #define CONFIG_USB_EHCI_DESC_DCACHE_ENABLE + +/* ---------------- OHCI Configuration ---------------- */ +#define CONFIG_USB_OHCI_HCOR_OFFSET (0x0) +#define CONFIG_USB_OHCI_ED_NUM 10 +#define CONFIG_USB_OHCI_TD_NUM 3 +// #define CONFIG_USB_OHCI_DESC_DCACHE_ENABLE + +/* ---------------- XHCI Configuration ---------------- */ +#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0) + +/* ---------------- DWC2 Configuration ---------------- */ +// nothing to define + +/* ---------------- MUSB Configuration ---------------- */ +#define CONFIG_USB_MUSB_PIPE_NUM 8 +// #define CONFIG_USB_MUSB_SUNXI + +/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode, + * the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS. + * + * in xxx32 chips, only pb14/pb15 can support hs mode, pa11/pa12 is not supported(only a few supports, but we ignore them). +*/ +// #define CONFIG_USB_HS + +#ifndef usb_phyaddr2ramaddr +#define usb_phyaddr2ramaddr(addr) (addr) +#endif + +#ifndef usb_ramaddr2phyaddr +#define usb_ramaddr2phyaddr(addr) (addr) +#endif + +#endif diff --git a/packages/Kconfig b/packages/Kconfig index 6bd6e1d..8659f6c 100644 --- a/packages/Kconfig +++ b/packages/Kconfig @@ -41,6 +41,9 @@ menu "Third Packages Drivers" config ERPC_TRANSPORTS_TCP bool "TCP transports" default n + config ERPC_TRANSPORTS_USB_CDC + bool "USB CDC transports" + default n endif endif diff --git a/packages/erpc-1.14.0/SConscript b/packages/erpc-1.14.0/SConscript index 5267221..43f453b 100644 --- a/packages/erpc-1.14.0/SConscript +++ b/packages/erpc-1.14.0/SConscript @@ -35,6 +35,7 @@ src = Split(""" if GetDepend(['ERPC_USING_RTT']): src += Glob('erpc_c/port/erpc_threading_pthreads.cpp') + src += Glob('erpc_c/port/erpc_port_rtt.cpp') # src += Glob('erpc_c/port/erpc_port_threadx.cpp') if GetDepend(['ERPC_TRANSPORTS_SPI','ERPC_MODE_CLIENT']): @@ -52,6 +53,10 @@ if GetDepend(['ERPC_TRANSPORTS_UART']): src += Glob('erpc_c/setup/erpc_setup_serial.cpp') src += Glob('erpc_c/transports/erpc_serial_transport.cpp') +if GetDepend(['ERPC_TRANSPORTS_USB_CDC']): + src += Glob('erpc_c/setup/erpc_setup_usb_cdc.cpp') + src += Glob('erpc_c/transports/erpc_usb_cdc_transport.cpp') + if GetDepend(['ERPC_TRANSPORTS_TCP']): src += Glob('erpc_c/setup/erpc_setup_tcp.cpp') src += Glob('erpc_c/transports/erpc_tcp_transport.cpp') diff --git a/packages/erpc-1.14.0/erpc_c/port/erpc_port_rtt.cpp b/packages/erpc-1.14.0/erpc_c/port/erpc_port_rtt.cpp new file mode 100644 index 0000000..0c069f3 --- /dev/null +++ b/packages/erpc-1.14.0/erpc_c/port/erpc_port_rtt.cpp @@ -0,0 +1,15 @@ +#include "erpc_port.h" + +#include +#include + +extern "C" void *erpc_malloc(std::size_t size) +{ + return rt_malloc(size); +} + +extern "C" void erpc_free(void *ptr) +{ + if (ptr) rt_free(ptr); +} +// 其他的实现在 rt-thread/components/libc/cplusplus/cxx_crt.cpp 中 diff --git a/packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.cpp b/packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.cpp index 67bf300..33fd1ed 100644 --- a/packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.cpp +++ b/packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.cpp @@ -1,182 +1,250 @@ /* - * Copyright 2020-2021 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause + * RT-Thread UsbCdcTransport for eRPC */ #include "erpc_usb_cdc_transport.hpp" -#include +#include + +#include "stm32h750xx.h" + +extern "C" { +#include +#include +} + +/* 你的 CDC 驱动控制命令:用于查询是否已枚举配置 */ +extern "C" { +#include "usb_cdc_char_device.h" // 这里应包含 CDC_CTRL_GET_CONFIGURED +} using namespace erpc; -//////////////////////////////////////////////////////////////////////////////// -// Variables -//////////////////////////////////////////////////////////////////////////////// +/* 仅支持单实例最简单;如需多实例,用 dev->user_data 存 this 即可 */ +static UsbCdcTransport *s_usbcdc_instance = RT_NULL; -static volatile bool s_isTransferReceiveCompleted = false; -static volatile bool s_isTransferSendCompleted = false; -static UsbCdcTransport *s_usbcdc_instance = NULL; - -SDK_ALIGN(static uint8_t s_serialWriteHandleBuffer[SERIAL_MANAGER_WRITE_HANDLE_SIZE], 4); -static serial_write_handle_t s_serialWriteHandle = &s_serialWriteHandleBuffer[0]; /*!< serial manager write handle */ - -SDK_ALIGN(static uint8_t s_serialReadHandleBuffer[SERIAL_MANAGER_READ_HANDLE_SIZE], 4); -static serial_read_handle_t s_serialReadHandle = &s_serialReadHandleBuffer[0]; /*!< serial manager read handle */ -//////////////////////////////////////////////////////////////////////////////// -// Code -//////////////////////////////////////////////////////////////////////////////// - -static void ERPC_SerialManagerTxCallback(const void *callbackParam, const serial_manager_callback_message_t *message, - serial_manager_status_t status) -{ - UsbCdcTransport *transport = s_usbcdc_instance; - if ((NULL != callbackParam) && (NULL != message)) - { - if (kStatus_SerialManager_Success == status) - { - transport->tx_cb(); - } - else - { - /* Handle other status if needed */ - } - } -} - -static void ERPC_SerialManagerRxCallback(const void *callbackParam, const serial_manager_callback_message_t *message, - serial_manager_status_t status) -{ - UsbCdcTransport *transport = s_usbcdc_instance; - if ((NULL != callbackParam) && (NULL != message)) - { - if (kStatus_SerialManager_Success == status) - { - transport->rx_cb(); - } - else - { - /* Handle other status if needed */ - } - } -} - -void UsbCdcTransport::tx_cb(void) -{ -#if !ERPC_THREADS_IS(NONE) - m_txSemaphore.putFromISR(); -#else - s_isTransferSendCompleted = true; -#endif -} - -void UsbCdcTransport::rx_cb(void) -{ -#if !ERPC_THREADS_IS(NONE) - m_rxSemaphore.putFromISR(); -#else - s_isTransferReceiveCompleted = true; -#endif -} - -UsbCdcTransport::UsbCdcTransport(serial_handle_t serialHandle, serial_manager_config_t *serialConfig, - serial_port_usb_cdc_config_t *usbCdcConfig, uint8_t *usbRingBuffer, - uint32_t usbRingBufferLength) : -m_serialHandle(serialHandle), -m_serialConfig(serialConfig), m_usbCdcConfig(usbCdcConfig), m_usbRingBuffer(usbRingBuffer), -m_usbRingBufferLength(usbRingBufferLength) -#if !ERPC_THREADS_IS(NONE) -, -m_rxSemaphore(), m_txSemaphore() -#endif +UsbCdcTransport::UsbCdcTransport(serial_handle_t serialHandle, + serial_manager_config_t *serialConfig, + serial_port_usb_cdc_config_t *usbCdcConfig, + uint8_t *usbRingBuffer, + uint32_t usbRingBufferLength) +: m_rxSem(RT_NULL), + m_txSem(RT_NULL), + m_devName("cdc0"), + m_rxWaitMs(1000), + m_txWaitMs(1000), + m_dev(RT_NULL), + m_serialHandle(serialHandle), + m_serialConfig(serialConfig), + m_usbCdcConfig(usbCdcConfig), + m_usbRingBuffer(usbRingBuffer), + m_usbRingBufferLength(usbRingBufferLength) { s_usbcdc_instance = this; + rt_hw_usbd_cdc_char_init("cdc0", 0, USB_OTG_FS_PERIPH_BASE); + + if (m_usbCdcConfig && m_usbCdcConfig->dev_name) + m_devName = m_usbCdcConfig->dev_name; + + if (m_usbCdcConfig) + { + if (m_usbCdcConfig->rx_wait_ms != 0) m_rxWaitMs = m_usbCdcConfig->rx_wait_ms; + if (m_usbCdcConfig->tx_wait_ms != 0) m_txWaitMs = m_usbCdcConfig->tx_wait_ms; + } } UsbCdcTransport::~UsbCdcTransport(void) { - /* Cleanup */ - SerialManager_CloseWriteHandle(s_serialWriteHandle); - SerialManager_CloseReadHandle(s_serialReadHandle); - SerialManager_Deinit(m_serialHandle); + if (m_dev) + { + /* 取消回调(可选) */ + rt_device_set_rx_indicate(m_dev, RT_NULL); + rt_device_set_tx_complete(m_dev, RT_NULL); + rt_device_close(m_dev); + m_dev = RT_NULL; + } + + if (m_rxSem) { rt_sem_delete(m_rxSem); m_rxSem = RT_NULL; } + if (m_txSem) { rt_sem_delete(m_txSem); m_txSem = RT_NULL; } +} + +rt_err_t UsbCdcTransport::rx_indicate_stub(rt_device_t dev, rt_size_t size) +{ + (void)dev; + (void)size; + if (s_usbcdc_instance) s_usbcdc_instance->rx_cb(); + return RT_EOK; +} + +rt_err_t UsbCdcTransport::tx_complete_stub(rt_device_t dev, void *buffer) +{ + (void)dev; + (void)buffer; + if (s_usbcdc_instance) s_usbcdc_instance->tx_cb(); + return RT_EOK; +} + +void UsbCdcTransport::rx_cb(void) +{ + if (m_rxSem) rt_sem_release(m_rxSem); +} + +void UsbCdcTransport::tx_cb(void) +{ + if (m_txSem) rt_sem_release(m_txSem); +} + +bool UsbCdcTransport::is_configured(void) +{ + if (!m_dev) return false; + + rt_uint8_t cfg = 0; + rt_err_t r = rt_device_control(m_dev, CDC_CTRL_GET_CONFIGURED, &cfg); + if (r != RT_EOK) return false; + return (cfg != 0); +} + +bool UsbCdcTransport::wait_configured(rt_int32_t wait_ms) +{ + if (is_configured()) return true; + + if (wait_ms <= 0) + { + /* 永久等:用轮询 + sleep(避免忙等) */ + while (!is_configured()) + rt_thread_mdelay(10); + return true; + } + + rt_tick_t deadline = rt_tick_get() + rt_tick_from_millisecond((rt_uint32_t)wait_ms); + while (!is_configured()) + { + if ((rt_int32_t)(rt_tick_get() - deadline) >= 0) + return false; + rt_thread_mdelay(10); + } + return true; } erpc_status_t UsbCdcTransport::init(void) { - erpc_status_t status = kErpcStatus_InitFailed; + /* 打开设备 */ + m_dev = rt_device_find(m_devName); + if (!m_dev) + return kErpcStatus_InitFailed; - /* Init Serial Manager for USB CDC */ - m_serialConfig->type = kSerialPort_UsbCdc; - m_serialConfig->ringBuffer = m_usbRingBuffer; - m_serialConfig->ringBufferSize = m_usbRingBufferLength; - m_serialConfig->portConfig = m_usbCdcConfig; + if (rt_device_open(m_dev, RT_DEVICE_OFLAG_RDWR) != RT_EOK) + return kErpcStatus_InitFailed; - if (kStatus_SerialManager_Success == SerialManager_Init(m_serialHandle, m_serialConfig)) + /* 建信号量 */ + if (!m_rxSem) m_rxSem = rt_sem_create("erpc_rx", 0, RT_IPC_FLAG_FIFO); + if (!m_txSem) m_txSem = rt_sem_create("erpc_tx", 0, RT_IPC_FLAG_FIFO); + if (!m_rxSem || !m_txSem) + return kErpcStatus_InitFailed; + + /* 注册回调:RX 数据到来唤醒 Receive */ + rt_device_set_rx_indicate(m_dev, rx_indicate_stub); + rt_device_set_tx_complete(m_dev, tx_complete_stub); + + return kErpcStatus_Success; +} + +/* + * eRPC framed transport 会多次调用 underlyingReceive() 来收 header/payload。 + * 所以:这里必须严格“收满 size 字节”才返回 Success。 + */ +erpc_status_t UsbCdcTransport::underlyingReceive(uint8_t *data, uint32_t size) +{ + if (!data || size == 0) + return kErpcStatus_Success; + + /* 先等枚举,支持“先启动后插线” */ + if (!wait_configured(m_rxWaitMs)) + return kErpcStatus_ReceiveFailed; + + uint32_t got_total = 0; + + while (got_total < size) { - if (kStatus_SerialManager_Success == SerialManager_OpenWriteHandle(m_serialHandle, s_serialWriteHandle)) + /* 断开/重置:立刻失败,避免死等 */ + if (!is_configured()) + return kErpcStatus_ConnectionClosed; + + /* 先尽可能读一次(非阻塞:没数据返回 0) */ + rt_ssize_t rn = rt_device_read(m_dev, 0, data + got_total, (rt_size_t)(size - got_total)); + if (rn > 0) { - if (kStatus_SerialManager_Success == SerialManager_OpenReadHandle(m_serialHandle, s_serialReadHandle)) + got_total += (uint32_t)rn; + continue; + } + else if (rn < 0) + { + /* 负值是错误码,不能当长度用 */ + return kErpcStatus_ReceiveFailed; + } + + /* rn==0:没数据 -> 等 rx 信号量 */ + if (m_rxWaitMs <= 0) + { + (void)rt_sem_take(m_rxSem, RT_WAITING_FOREVER); + } + else + { + rt_tick_t to = rt_tick_from_millisecond((rt_uint32_t)m_rxWaitMs); + if (rt_sem_take(m_rxSem, to) != RT_EOK) { - if (kStatus_SerialManager_Success == SerialManager_InstallTxCallback(s_serialWriteHandle, - ERPC_SerialManagerTxCallback, - s_serialWriteHandle)) - { - if (kStatus_SerialManager_Success == SerialManager_InstallRxCallback(s_serialReadHandle, - ERPC_SerialManagerRxCallback, - s_serialReadHandle)) - { - status = kErpcStatus_Success; - } - } + /* 超时:再确认是否断开;否则认为 receive failed */ + if (!is_configured()) + return kErpcStatus_ConnectionClosed; + return kErpcStatus_ReceiveFailed; } } } + // + // for (int i = 0; i < size; ++i) + // { + // rt_kprintf("%0x ", data[i]); + // } + // rt_kprintf("\r\n "); - return status; -} - -erpc_status_t UsbCdcTransport::underlyingReceive(uint8_t *data, uint32_t size) -{ - erpc_status_t status = kErpcStatus_ReceiveFailed; - - s_isTransferReceiveCompleted = false; - - if (kStatus_SerialManager_Success == SerialManager_ReadNonBlocking(s_serialReadHandle, data, size)) - { -/* wait until the receiving is finished */ -#if !ERPC_THREADS_IS(NONE) - (void)m_rxSemaphore.get(); -#else - while (!s_isTransferReceiveCompleted) - { - } -#endif - status = kErpcStatus_Success; - } - - return status; + return kErpcStatus_Success; } +/* + * 发送:你的 cdc0 驱动 write() 已经“阻塞等待发送完成”(tx_sem), + * 所以这里直接循环 write 即可,确保发满 size。 + */ erpc_status_t UsbCdcTransport::underlyingSend(const uint8_t *data, uint32_t size) { - erpc_status_t status = kErpcStatus_SendFailed; + if (!data || size == 0) + return kErpcStatus_Success; - s_isTransferSendCompleted = false; + /* 先等枚举,避免“未配置仍写”导致上层各种异常 */ + if (!wait_configured(m_txWaitMs)) + return kErpcStatus_SendFailed; - if (kStatus_SerialManager_Success == SerialManager_WriteNonBlocking(s_serialWriteHandle, data, size)) + uint32_t sent_total = 0; + while (sent_total < size) { -/* wait until the sending is finished */ -#if !ERPC_THREADS_IS(NONE) - (void)m_txSemaphore.get(); -#else - while (!s_isTransferSendCompleted) + if (!is_configured()) + return kErpcStatus_ConnectionClosed; + + rt_ssize_t wn = rt_device_write(m_dev, 0, data + sent_total, (rt_size_t)(size - sent_total)); + if (wn > 0) { + sent_total += (uint32_t)wn; + } + else if (wn == 0) + { + /* 理论不该 0,给个让步:稍等再试 */ + rt_thread_mdelay(1); + } + else + { + /* 负值错误码 */ + return kErpcStatus_SendFailed; } -#endif - status = kErpcStatus_Success; } - return status; + return kErpcStatus_Success; } diff --git a/packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.hpp b/packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.hpp index ccd7b5a..7463e9a 100644 --- a/packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.hpp +++ b/packages/erpc-1.14.0/erpc_c/transports/erpc_usb_cdc_transport.hpp @@ -1,128 +1,94 @@ /* - * Copyright 2020 NXP - * All rights reserved. + * RT-Thread UsbCdcTransport for eRPC * - * - * SPDX-License-Identifier: BSD-3-Clause + * Uses RT-Thread rt_device ("cdc0") character device as backend. + * No NXP SerialManager. + * Still keeps the class name UsbCdcTransport and init/rx_cb/tx_cb APIs. */ #ifndef _EMBEDDED_RPC__USB_CDC_TRANSPORT_H_ #define _EMBEDDED_RPC__USB_CDC_TRANSPORT_H_ #include "erpc_config_internal.h" -#include -#if !ERPC_THREADS_IS(NONE) -#include "erpc_threading.h" -#endif - #include "erpc_framed_transport.hpp" extern "C" { -#include "fsl_component_serial_manager.h" +#include +#include } -/*! - * @addtogroup USB_CDC_transport - * @{ - * @file - */ +#ifdef __cplusplus -//////////////////////////////////////////////////////////////////////////////// -// Classes -//////////////////////////////////////////////////////////////////////////////// +/* 复用原 NXP 类型名:保持 transport_setup_usb_cdc.cpp 签名不变 */ +typedef struct serial_port_usb_cdc_config +{ + const char *dev_name; /* e.g. "cdc0" */ + rt_int32_t rx_wait_ms; /* receive 等待超时(ms),<=0 表示永久等待 */ + rt_int32_t tx_wait_ms; /* send 等待超时(ms),<=0 表示永久等待(通常不用,写已阻塞) */ +} serial_port_usb_cdc_config_t; + +/* 保持签名兼容,但 RT-Thread 适配不使用这些参数 */ +typedef void *serial_handle_t; +typedef struct serial_manager_config serial_manager_config_t; namespace erpc { -/*! - * @brief Very basic transport to send/receive messages via virtual USB CDC port. - * - * @ingroup USB_CDC_transport - */ + class UsbCdcTransport : public FramedTransport { public: - /*! - * @brief Constructor. - * - * @param[in] serialHandle Pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE allocated by the - * caller, see serial manager header file. - * @param[in] serialConfig Pointer to user-defined configuration structure allocated by the caller, see serial - * manager header file. - * @param[in] usbCdcConfig Pointer to serial port usb config structure allocated by the caller, see serial manager - * header file. - * @param[in] usbRingBuffer Pointer to point serial manager ring buffer allocated by the caller, see serial manager - * header file. - * @param[in] usbRingBufferLength Serial manager ring buffer size. - */ - UsbCdcTransport(serial_handle_t serialHandle, serial_manager_config_t *serialConfig, - serial_port_usb_cdc_config_t *usbCdcConfig, uint8_t *usbRingBuffer, uint32_t usbRingBufferLength); + UsbCdcTransport(serial_handle_t serialHandle, + serial_manager_config_t *serialConfig, + serial_port_usb_cdc_config_t *usbCdcConfig, + uint8_t *usbRingBuffer, + uint32_t usbRingBufferLength); - /*! - * @brief Destructor. - */ virtual ~UsbCdcTransport(void); - /*! - * @brief Initialize USB CDC peripheral configuration structure with values specified in UsbCdcTransport - * constructor. - * - * @retval kErpcStatus_InitFailed When USB CDC init function failed. - * @retval kErpcStatus_Success When USB CDC init function was executed successfully. - */ + /* 打开 cdc0,注册 rx_indicate/tx_complete,创建信号量 */ virtual erpc_status_t init(void); - /*! - * @brief Function called from Serial Manager Rx Callback to unblock the receive function - * - * Unblocks the receive function. - */ + /* 被 rx_indicate/tx_complete 调用,用信号量唤醒 */ void rx_cb(void); - - /*! - * @brief Function called from Serial Manager Tx Callback to unblock the send function - * - * Unblocks the send function. - */ void tx_cb(void); protected: -#if !ERPC_THREADS_IS(NONE) - Semaphore m_rxSemaphore; /*!< Semaphore used by RTOS to block task until the receiving is not complete */ - Semaphore m_txSemaphore; /*!< Semaphore used by RTOS to block task until the sending is not complete */ -#endif + /* ✅ 不用 erpc::Semaphore,直接用 RT-Thread 信号量 */ + rt_sem_t m_rxSem; + rt_sem_t m_txSem; + private: + using FramedTransport::underlyingReceive; + using FramedTransport::underlyingSend; + + virtual erpc_status_t underlyingReceive(uint8_t *data, uint32_t size) override; + virtual erpc_status_t underlyingSend(const uint8_t *data, uint32_t size) override; + +private: + static rt_err_t rx_indicate_stub(rt_device_t dev, rt_size_t size); + static rt_err_t tx_complete_stub(rt_device_t dev, void *buffer); + + bool is_configured(void); + + /* 等待 configured,避免“先启动再插线” */ + bool wait_configured(rt_int32_t wait_ms); + +private: + const char *m_devName; + rt_int32_t m_rxWaitMs; + rt_int32_t m_txWaitMs; + + rt_device_t m_dev; + + /* keep original members for signature compatibility */ serial_handle_t m_serialHandle; serial_manager_config_t *m_serialConfig; serial_port_usb_cdc_config_t *m_usbCdcConfig; uint8_t *m_usbRingBuffer; uint32_t m_usbRingBufferLength; - - using FramedTransport::underlyingReceive; - using FramedTransport::underlyingSend; - - /*! - * @brief Receive data from USB CDC peripheral. - * - * @param[inout] data Preallocated buffer for receiving data. - * @param[in] size Size of data to read. - * - * @retval kErpcStatus_ReceiveFailed USB CDC failed to receive data. - * @retval kErpcStatus_Success Successfully received all data. - */ - virtual erpc_status_t underlyingReceive(uint8_t *data, uint32_t size) override; - - /*! - * @brief Write data to USB CDC peripheral. - * - * @param[in] data Buffer to send. - * @param[in] size Size of data to send. - * - * @retval kErpcStatus_Success Always returns success status. - */ - virtual erpc_status_t underlyingSend(const uint8_t *data, uint32_t size) override; }; } // namespace erpc -/*! @} */ +#endif /* __cplusplus */ #endif /* _EMBEDDED_RPC__USB_CDC_TRANSPORT_H_ */ diff --git a/packages/packages.dbsqlite b/packages/packages.dbsqlite index ea1413bd4fffa73d97f1657ce1c7fdf9b9d649fa..8d6d03b473b8cf2a030734d069e89e8e7205ee9e 100644 GIT binary patch literal 147456 zcmeFad6Z=NRo|IQMDB~awX~LQb@irh(dyFM7YTt{)g`G>?^WIEC99&}ni-uLnOPB$ zSy@%x)p`+;NFc^Cn|;`~K@1E&3^s7=fiVO4!12KXJYZXRj4{T5S&oMR4$GKf=JSh) z+<)))BC|{Q4_Aqf%E)fseZTGg?()6gd+zDSs?Fq7x>m0R%~R&kn}&vmhdzAj)X-2V z9U2&}?*)H&#_7$kndQG4p8wPk|9A7x%^A2k12<>j<_z4NftxdM za|UkCz|9%BIRiIm;N}e6oPqx?XW;tq_-*&xGn}1i2H{Gw9z@H*Vv<%5{5W#vnX?a{ zKYQx@!ykF^Lxw8`d#xM z5_5m={C}PQ^ZEaK{txGWXZ|0KREw=^WQQ5_vgQU z{T0r5sa2zeGmi($ z$z#<_|UENFr+qdHTOVwh@ zMN%x&Ow33#lh97g)CyzW35~=~-P8;MLyyw;lxoFNeE*^T08ZC8828c9B#a?3^w6_Y z&C%U3(R4G=`3y8I)uZI4`%0fYDkolx8VmL0(nhtO)RNV_sfsLJ^NrZi3@=Uf&^OXZ zx1!M0oj5cd#|-Z+CAkkzlX|ks8Z|c7*VpRJBtBhlNR}gslE6wrE%H1oaeUjfBi%KU zAa!)zjBNelJ*5kUGODX_vL%1MVZ^cTCYBZ^p>CVH-Cep=`2590 zy!m3K(G2oO!WQyO+leAQ^-bG#4a3m1*wH=BN`uHZH=fqBIN9A0@v`zf2o*6bwqEYmlmFiOxBniKoU zyGqMBPu-mnw&g;jS>K478}&r~@{ShyT4>v`ttHHn?Yk~A+$c^XM2AWA&eGx_V#F~< zoLq>8UK2+)4no%tOxH^6(6)kv>|sFH8hf^8J6xiUMO^g;W?2T zc&48?>GIo4mj@9Mt;I=YEv+zzG4m!LkK_AJqMKIadRChHX_}g;?fJTIS!Nu1?lZTQ z&gKhCPp@A&s;rIJ&;r*DQkNO=Z7o7Sm>h^$Xs0MmUwT`vvJM)Jq}gDlF)L0tHW!aR z+}C`x3{PieU2YnKqwGfs8_G*#J#}7uYw6jX7w$it-M=P(wxc;dx>0xZ9Praq|@X=?VJF~Xhi0ajKnc7DWi}kbh$aW3aOhZ2mW6uv0mn$F$pL(ak`Uo^Sb@jml=_IU8oA z$BxMz``nvKj~{*9nJ1q(|IDKwdG`F1&zzHwn|E=NFfsy%VTMtZSU#f-J>+Sr9r-WJ z%hdLnCm%UmdGezbp8v?RXU@wXZF!C!>Xzj@Mr2!h7{pxvsiC<>fc}g8PtKK|Jo?I~ z>q!tdmlAQaoxT#(R*ueviq) zK9L(fFjLdk6Gm8@VC!V;p5iVR_t1qW3YnK}fTr-P{N&WN{ z*=w6ofbpXnZr4`P{a6<>jDg{X0k)R8I9*zk%*PQS;YM{OuGFiIXj3l8<9N5Kd8qI}v%>0Bsc{TJ$!gLFSPR*h;)vDNEuC}Xq?Q$@4ptX7C0fK!Y~NX$ zl-Wl|C$2Z9T4UWZHMu0))>A9ieFJ;d()=XlVu(ZT2R}01$PSVT*=?66DQT?B#dx|F zdLg?hgd74m<|es$u+^jwU*FizaS4}7d8%Z{sK z$62Bvs7FhVB^SjmHa(M>!#+j@xq<6@Z1XTQF&gwJO3N}|VrSykH&#|E!q&%qs5BG& zr=XdfmMOeAbvcZo9lKh@lHd)c=#td8xc*$rur8I#*>L{0d-UA7XU|s7pMCtP$8d2M z(j*Wj$&P6G&`d4FGStO|n0mNOmgf3t=y;xC1woK%i=(O&bx0!jd0JhR3raYm7*$CS z#gXP1spoUoa4XtD6a==H;N;%(nSjr`Kl5Qe@A}L=e4hHu1fO?)dX3L_fBGpt@A$ON z=k1@qmCtv5b&bz=e)U)J`Hru?o6omzU*+?*?el!TZCm`8Z{42f^DQ0mgg1AdHpvK|8M&LO8ggik;}L`=>1O)PkCn6Wf#ohV>Jb^?uo5S|M2*O=Mn^{*r6f@hOAia1 zg_g$#xAnD;9%FjDLYqQre_5A~3bbM^N(mDCfo6Jfl#<&eE*%jO*LBUby_K`2E5{q9 z*ivz|u`C;2Dze^zOInY)Bq60)o^BY4>sYZ9aOjpEk;TAsHg0!#wV=8xlVrO|;tPf$-H1tFI)FlS*VhTUTjVffKS~of z{m60Tfrw zHJ9wN7L&iY_Th5&*1@(#yb-Kaga${y40Z-=$F<2Q1V&1-DvVvz0c7AMJ~}}2JeqRsEO`Q;=pztJpj3wfR_+SIj%t?4oPKQwg*x? zJ*?#JP95OZPsupifl%=L;zFXCfDJuVX6lwFd_YZPB_Km9OcwqJ00G=Y9q_Ja*?E)-`47|X1;&%Dj z(CKn^XR#*li9CoU9?&$3!ww{*#Lz@azDKF|-IP#pePyOj9S-4x~pnz$f#g zwees%n>_hj3j)4<~5(SQero&^xmHFew-*K2&)F_hGy)j#ohYP|QvLQj6O zg#Uln(2owye{TNGbK7$hv)?p(`^@*u+&%q|r_WFQ@zmE&-7)#YlRlaM%J}b(uZ{i5 z*tM}z`LpG@(%&gfj(%?RT_fK=^1$#948Mm*{O$Z{EDtnGOVt=pv9`X}fZm`G-d|+b zz5Yr$yQ6p;3ZdZ|mqvB9nbg5=17w%@2@==U!}uW{W7vj+uLoKVmn-xlM_@-$NBZm4 z8~FkfXC0>xw6>c7H3e7W8G7P@-v_NGKx9~C*OmslL33uHKpDk);9IUkl><;r0JMPs zO&WoRtAbjJ{pR98=3kERJS8Bo(!Q{DgGAI5aJAux0%3EAjaeXV>uEU~J<+1)AIHcF zz&e9C)Cj)-lf;3yC?TOV0?Q#awXLL_&7VkS(T!KM#j}yPoZV9_I=(_}Q8ns^VK(YP zv%0n_-R6>A7J<_wMv?{&2tu21q-Pmn9EL7dKI?5>kILD*-pD%?Y&1ZTm}!=0QV0?H ziDjfQAXOXeeB^0~VO|Rd+U5Ckpb8lI0HI^ku!wkAp^I_|D4gK-k1!nrP-d5dflP9R z@SOOOZULACS!acj)jRCaBzR5lLHoEkJ6xVt8zD6Kc13M19J~9%GnA-9u2k~5Y1Qu)+mwZ6Potqko>7aEyYFR?C=@wq4 zPRuZVPFCqAna}R%^0r81#=b*VB_KAg$EHB+Iwtl#byrakrEd7Ftol$YC0DWW_C(?g ziX2VLPh4y@Y6nQ?;4Y`Q$zFJVP#GuReoN;D$u5YcDcp5LX*jf84wSg+gv!GdPdH$J zgy5LM*Pbb7?B8|%U7beG|EsSai$HB>iEApHArj?gWz~*nTC7i>4A!RrQ!>A zB$qBVy}l8qmZ;@5iBZKafqFpm)Z2LW=2It2#|fKXWe5lnMYUO(}6q0w*MD zWC~LxH0nSYFMrcYciRDn+m|lJCgehm1z38w}(CTR(*R(?r&BO>bnGq^MY*D;` z=34v2AS(XoD&*=aGQZS%P}vrH27-L*ekpH>@pK5XQ-dn}|5HQXGBp1U^LNkv(A??S ze>iK+{M3v;{WH^FG4(@J@4@?jaN_$x{eOPk9Q*09N5T9rlzy{xar8Gw(~&2%uQGLwXx-L zt*2DC={klW&K}h|#KK?C#s>~z@ zR?I`*{sLv-P$5K4G9ajkRZ4vynk~|>q(U>*HnZ|TS4ocO{M}aM?7W&$el>;#W!NUd=`Z zQs(j(DA;g>&vC6&+$$@^#MDh+uyl|LvY|hKjG~bZ4;-sJI{Li57KRBKS;2rniajJ( zssrT#O99Bm;yyQ;+0a0q-q9h8--uM7Jj<1Ga|7nV#e?AktBG)Vpj$*NF=IeEG+%$C zQeTlkv@~JPYoulTG_mk0eb1%pPs3~hp+&x?etjTQ>F8Lysno`4nM^&!y2tY57!xca zrx=kog{1?Fm>{8PTzYLF&+n+rlON;DuMQL%Ix6yw9^h>B+Q4_mZn%9P3Qyt#NGvjp z6TB$+ELdXv0J4rw>`~%QjXIzmBhE&z-srcG++b`du$Kl2F)t!57jT>5=Rv|lc8?QJ_zp2y~DaYboF;3y+mtHkmnKWeyQiZj`O9f$y)J7s%5ofkjFe+#1k8 zB84vgQ0&89qG1;U9F6>J_;NYBYcLZcNAw$a5^mWnXA;7Q!@j#X1Uc_;&^H*sRY+nx z@uJxEAf9m}d^W*8f>QZXN%Q@%NAY%-GZA zUoT%M{Z^?_njZbWQGeu@M=lQk=i#m4iJ@=5(IJ3p_Rt^*Biw{$En3*DHiD-&lKK^? z`3m%2!{Y}ziER-YVA7!7NKCvnAi2J!*RuBwf=}(s>Sy&4TM5?Jw^44qrSteWe=WQp5*ip&ay};yRf^#P)C$K4hW?>7G6*yK){V`Fi6Y60Tx00 z2_xyS%jju9Q3*L+h|{_;EyIZfbB3{+y?2nqvrlNjVT~;^OqywR<$`RCJcwEx6P0OU zHJbWj_JEB0|lJt#+AKCMn01_rraByf}+$6f$~Cfmts>u&LxaHjZG5* zwQ`f}zGKKaxyo72?j0np)L)~b>oS5Eiy$^A#T5K7;OG=AS$86B&;@pSCA(*!1j0rT z8I>hqAW)_adR@YN1F{u?!UZPs72_oU9RbWt=*PC=E7{#QMz&CyGmJQ8V14mT zsT7M~6^yAb09mYUWOogeUOzJKf)i+fm@{pNBSTx925N~StW%;9SS?^XtXg(zAjNig zy7OEU;u}z|x+WBd9)xc=|J3-H8XK2_Io)uUvpWacO$X%Vo{+}cKbkn?rPGktX!_HS1u=E zBdKpDb?LE@Y+Zn!L{mc4cFH6JAPBfa$WM6WhRK1&*RppFl#I%GgMtlA)C!I68aj-k zrp8eT12iN57eE1uLTqO594L~NBRzK?gA7Nc1@#1q<0i6v-r~KHQ!T zFk4nO;$Vr8rSGQPZ@`e4?Rs|GKpR{pIrj_`x&VU`V&~b|c$AfSaE0N|1r$OMVu|b7 z+fFJp|0u^?;1nKU8j!{X)6DHncF8r-$^dfgcq@DBNtd_iKnvzV0PM(yxssm)NIU`R z`#|jg8@k$+>@5S`Lfw?LsBl}^7#PqOz-Fh#E&=EmED5}ZC`=3{DotGKN)v9OHxG0R z9g$sdh)LbLT!8SsQFH-dl$^b5QFZBnJR+H&T+VJCXiFcFyOX!Ch^jDIF(yoN;N(S7 zlu#Z4OoV|4Vul)1D}`<)-$D$?B5V|JJDUu2<77n0A>Ii-AzxiWJ%Re;5_ut$=C-uPKijIq* zBiAYVra%X>=hU`v)IdN02=H_m5}nO#cA!ARUWT^s4Hh{|SZCB>aqR)VBy9rdg`x+| z0Llg!L$kGdHZ$0052U;c4hlG$&?1Bqy7-1f`H8J_w$@fhB;Dj;$lj9#5``NJ%mA_bih5G+* zEoq}aJ^IARZ;xz^Obmb9@Pj<$Z|zS#D}cx>tx;RK1CtOWxV6asEU;p%>A}Wpr2x6IyM09 zrD{#IC9o)!^1RjT;J_=9(W%>&kLcocMi z-(hw}2}12kD-uF&GH?pa9jf_ts*o^vCH60ybFUjKcwd~;nfNH@z6x^WTqY*`MCh-mI zY*v$Q9lQ*dH5}1qxS4&pz+NbjpLalXDugf-2p@~?6hNf8yDc#GlxkF()!7O7~0z*{l!I9MeHAU--e z@`AGq$`-PHqK4$vaN9hZ?Eqq;eGIEWmj`Dx^OVub^lJFEzCAje$f^?GawhtQ#a;vXM>N5CEeNg;H`%E5>*RZb*9> zuHjVElg$jGi2*k9(UBKyWEU$Mwh)mU0)0pIx?sG)R3qgFU`O*;Gh>jAd{l1UMrKHu z&tS!&*#}$6^#|>}xO>qd2_UIUnLZE-?x@6SjShFxI3f;oh0HPM>~3|4B>jfQqN zA!>^oa3#|QIXs6%=EgciSYL;;%K-zP(z!qvi3SEKie6mb3|6xDA75PlSuM)MH!>(E z1|SbQIJ}~>T10dq^8fb@g(Cld$J~$1eQ@>{XV1<2KQrGwb7uOFroVam15^KG%ANd` z$)$-um{=bFgYhMp|G#DIf$}eulX9u_Jtceemqsfie?F3p%nyIh@CSx|kw+c+lV(jB zZP?P~g|M-{K$@D`->pi#Tv@NL?R-7GB5AEd{FoB$#3Fn_|0yt0^os(6>IsgO1k$3F ztRY)3rJ#r6<%f_fbIb+e{)zlk?$>qp0@bL|TFB*`>d zU?G$SBxq`Y+9KH#r}Yd>k)+ICE^;x7dj0e^)+_z3bNbv-p;Y9N><|StY%g3GI2EYR zBl4j^t7)@{*=pgQ+?~`NIVanbwZc7lNYKt#*`8$Te5@#%c8LrUW-7h$VuO?tJ>a+w z;y7C=+><-cU&!B+LsZQvr=%qnGpiN{M3XURA56dEh*cB?9 zHM(#SP9St1>LOkPP6QY`Mj$=a93*QOv#P9JBcw!(?2rOv$fr0=Mcqj?Qi`k-L z2!|y|EE}%fuA>bB5;c(+ID(h}bPeeojgDi{YL?0jjQ$+$3h2S=7sPn9WOFO*Z!(EP z()Hv8j}%c>Dul40_zT3JsHXrSr6*Y;3(M>ZTmvz;R;y6AT5T$4P80TA~f-R;N4lQI5J^fCPy-VOrL2dscXV?M)4{kG?K0+1;}0ekn6pkL2V(Skdcq4 zKaKUEu^uM%`jz!+T#Dx=fXC@A>RUFQ;4rXW%>pTIcHkF?YL;UB4jv{I*x+Eu z<8aC`4d~tEYNVQ>+;jD7*~?N?!3o5lVDL#+8Du-NY1G>pBY}m6)0lh}m5g)(jKQXe zG(MoXI8Nj2;vn1kfSeO;=L-XE=boIL?Oai9XLOqeFDwCfPL>E2KF^g=SfDy=yl_K^rj%@ESBIA= z&_0=cQr0eV7yQ`ma4pq`1l!1ALxRF&gZG82fy5IYCeU(P@cRC9*>keqnY&M}LE|lb zFp(pyiB!Wn!2>50LAO^@cU+pZpab}~kv*%%Jal94JpeZyiq}?F`p~JO7ywX18WW1X zq%c{qc`VI=kCp;&+USznt7YelQ+N`wc_9E(7gWh0cPu!=X|A1!w3n!=v~7#q-MW;W zQ-=WZ#;Hgf>Yxb?m?yAtxisKQ#!RCwfLt5sM*1EvXV1vIq1{E3iOdgm7iA8Yv!{kj zUmSmY>{rL0EB{70DE)`hCrAHu^czO+8~NWxK0N#j!ym)<|8M)}N()@qExBeky+2K( zVfHMD#sXjKNuyCsD-Ba*rIxGBDBoIztrviHq6=5q<5+-0_h1u9!xWs2CmeUuk~XQ%6^=HPAE^Ruc&!DG%D|%pf}GYj zs?AC*!PdnS5VvrD>1F4Mh=~~|#M+|>7sdhYMAZ`X^^{_{Ka~3CI7;;1JE@n(v+eIBTY5x&jo)SOnKPCXt~#0P^z3@ z{1WLok$v4{W3W(O;OG&+W2jI(S zf>shBIrni414jh>#07suM+lU9HryJPqK;1V0w(9Sx?;Q1 zBmrevU=i`T?UdY~AgqKW1XLC_6jW2Ov5>u5dZB27*vR7flJ^g}wn1}(-uEeJpqdVd zr>@i51sfmEUV9BMeG-g+-O17r&fc8AQa6EZHOxKYgSr@! z62fwX=cvh}d`iEVZK)TzH;Vje5`bY`Vy;rapjeVbn*v~O7&+h^eNlUGS>}!RPkld2 zx06V|0h!Rv!c6FH+WH1%LN}!TzkGlY4i^uwjIqyK#Lv5`L* z`Si%U=mTI3eeaD90%S8SaB*(#>8{qc>dhS+w$}Zo)6t=VOTWNB`+k$IBwGzqDXVMs zK7F}-pMyV%A%4QM$1$Yy871wYd8rtIqti(0Es%1OFin4%RIii2_hEm;b+Lq#uc7`? zMC7IdO3FY<(-6bI)B+(le4;t%36%u6p--kO8tpoSH;zKL(p;XpKDOP0-K_K_~n+X&`-OMR=K?d zC<721xFrrOXjUrfg@MW%u!T|XlDd_aqe#LY5h1xIaMV+>lbA=u*=ZVp&xa2W)K3^| z;MT9UY?aruC!)I~^pLBrL(g4VSzBEURx7K)>RR6{lx2Vk+2Pdd31f=cl|nvjs#LwD zbnK%j`$`MkTfUz;xNyl%f%r^7U%0;!WH5a|vNlBZ5NLQH!(MI~icPZjY{e`R+cELiMVlEIb$In| z-!TrJEgC85Y1+~iz>uB@(^xUW{!qF<%f^D;u5oTD(G#SQqRW7Wk1A4=P;1cxG-zpx zAk2P2`AP%FlduSkP>@}dZ^wLsh&_VQmdGyf<@n{+`wQo*H<(-{e+XDwKAT%yz z@wf#vHFUu-LzWgSv`#B5qjasdu~1JI=@8M7nl1F)pxq>uIw7q=NmCQ($I$>YfmtD_ zD#F%7GTe1v)pj2bS>*agvy!gWYe7>g1T_w>kUhm9{7{g1uxC@Th2e4{s9R~hPoWsP zLUtlS)%qoweJ$vFaFhg#FjWC8gQyG@NM{PHs0}ic)`N;T%FCOxz|v4B;rH54x)I0ifGDN1?4G zY#^~HiXG9?T%LF(aC5}gORf7$pDcLoeDDqKFqH`;-7rEaVFT3Qh3s0CF!(hn`<`#T zr|88YVwchqQ7lfpkU*giS{%S12O;LpN5P9;dC;)8?o+7=alWE@Q+sGL*{W9?(WVRx z2L~?)R#Y(peFKoeB)I@@;Gh;&N_6>Y-K)}hLPr0>>aIb)KJuwuBq>TMEs2s4*cUAF zq>4r8nY)=3UhAHsV{lZE=>ILdAYzYdeR>;l zAyDB%l@CV_W~0>e2~PS1fUHNebL3%y9bz`XU;zS$m3^E*JNnl znEQp84`#4UZ6|#z0iR=tgMG(MwEc^%I}`$XVL(%5FB&4E#R}MX;$Z8b>*035qQkbM z6bTSt>vqL1IwT-x7r7A)Kj}+JMJhcnu+r#nfMrjR2j`qClr#xcCq-!z^KTf0A#$?o78dPg4|LD@v1GX~BO|EW59pc$LG6<67V1l$?{| z#4!vgMZr{6(t1aB&JHX}91H*d&Y}NhXnuX}ujf8J`xmo|Gk-dBefqylU!3~=smA1g zoP2uXHzt(ga#0;Ui253VHbI8)8a4q_X zfM&sMOhlPd3c?OW7p;DY=iYfMj0l3Q?0@V)iJ=f)` z68ILm>bHJuVjlZhD0fO zshIQ<`8s-kyZA>KRZ+e5#Ib{={pra+>(Inw&&D8Vh<{MTL`4U9S4s$28H=Xams+$F zI%cr+fKbVaPa~3Z@S9?h(isXDUto60w~5k3(cy!Mr)|)2C;mv3+8Olh6TkrUiQVm> zP(|Q`d>-t{_^CFK)WqX`KJg`cAIU~AeT;rXhl&DjR2WjB%ccuE&L5Szf_Asw`l{n^ zgx>VzZv>BMC~iMs0iqR7La!AloKuvLaCbaSyVQF0_#0urP{~H%1PatGux-o3ixy0C z;D0gfsca*(6C6@7Su z^7jIXTUv+{J|r+sYy-|Akv<^>D)PgT8Pr>6kG%nRmL>Ok5L|3@o+NYcTaeF%pp-)! z7cU}H1b)!x6h3n7Q)nE~3jAiU>p@UffuPp0LQK%%z%)a)MVIOtRx4_qW?E;yWbY%{ z3IvTo#YHv&8`^jf+@eB=8;k&KO7q8v>)|8EUX=dyV)-yCZb4EgbYCJf**nP zip&;V8<$!SA6qLN5Gv6M0_Q*ofvh;CWpKNLT>-tsQqau9L`^gCu*4kmdeH5|b^^Z{ zY$L$1VUnx_i$`#Y)>J7mW2$cRIQ$a;Y0*1Axw@ z<13`B#GDCpk$n~Z|Gh(>ADaKBd3WyD=U$zgnEl4t+h_hM9RU7dx;gdNQ-62rp2;7Z zd~V_|CR!6S<9~nruCbpRi{Su#x%7Lb`siPeetPtlk^gbT8UEt%mEl`>(3j-TQtP^m z!mWQ}0F2q{#$?uXeZzDGP^SBXGz)=$LiiRZ)D}F}xQw)T5s)Hq!`zruEw)}$1gQ^; z%HMo8C2JJDW1ygR$PW8#cX0cuufyC0o_?XFf-E7&ww2LK^1v<{jWiIOTNuL;i8{gM zPEs8|^rhA{MIhtA<0Z${iAAeUP4j?u!v{*bk5r>*^+myo3qXFkbyeX__nzLJn#KYp zaFvzn>axP6ql%2+bV!XRw!94>&4SOIOM_$)`A5xsrFBJtwNpuxX=+MTQH(fqz9?x6 zJ@U*kP%QE=P$Q;pqeYh`2@S{IUSnbUV?%U*Xf*P7)X* zT?9ZbE+(k_*7~K}FE?ld66lpEhc==%{p(p&FiI zs9knvimom4duVowuQe_p$PvL~IFLWrTS}Ny{!n+No?xh(t)>bIe?Vxwwh__+vu2u= zq_@0^(UQL;jRQjnxix_}fk;;LBA^)twnpR_8?A=47*MvIas^8UjJkro7Hl-l@%YPi z2zEiF=wk9h)MLikM2qf7@6UBZibnj{Q)g`Zoa0v_F%QvNJ<%!~sUcOVXi*PHBPD?; z-P)-37A)t&!h_R+a0MWNONyAScoR#d>Nqbra})uycd0`Z+{>c<7Obh9V_ct?TI&U> zZujw0RR?g@5~Zh(ZxBg^OhR3ZWprf{R)S~<~B_oPaOiq%6uP>0f7GLsPz z2_pU+7os>!G-`LDwXEKfx~JNbEE%=hj3;p%gJ1{TPJm*-F%bME@|C>QdPTh@_Z~0V zl2E*0x&jKI*pAcz4SfhLLrY9uEGQW*UTIYo5mn9;Pv5P{qved*2(U5EkI(e`ytZ1W^7U<@^ks*1<#`GF}8x!n- zbV5ZNdstH~3ebK04O&|Aw?!5k^NifS*=QvN=PX}t{>+Lw6^+CM#WNkB;5>o7)v+mN z?D59bTXDfTE0QXiVz_R>=+XK)hA5PHEUYn*x51=l6MVq;TxdlF=S*qk(yD?o7>2_E zfUTMUEYM!eCYrQSY9GWewZejPw)=S5IfHsD44E&g7hvfjLPbR;{V_ncV!4E2vlU30 zPWSF^U1ADSW$ky*8-Gi;2bUJ82@#Znk4h8Fc0QpBc=jmqA)aW~TM(5fZNXfz`MX2M zCFPd!x`hHP4>(_76gYx-CPa}5l~z=~usC>mW6eE(1R%Ly00ME~0A>*xYP7V>} zTY?lACCed&wbpF3?^In>gNT(3mW>BxqY14zNh^#)%ESo35T4=%$Q9|?aQoe=`aZST zqZ1%i!cOhh6}LKNS$;l$N9vJ677aDW<5_SVvVQyN<1_VuX-HLJFQu z4P+Tx9zziPD*a|?dlpfjd9nRA#S|TuAe$mk(4@Wyq|u*RxgvMO4)XgG!AV9xLgHg!~ZY_Ec|%02zXp z+P5eyrdrM1B?Xb~Ho{O|NG%F@GZ;ZcxKFe#0DNp=*TNukrTr!q$g=zRoiQOQ#c$fG z)F^6zOmhEMnJtJx$?XN`F2H&s9?pG6?vF|^N_c6qvftBhNP?0mxtWEpK3xUz|& z;PWSVBnG#5N}h=rw&`7JLx7T>TvEu)*BOF@NYF(=Y$l*5V#T?$5-1+Iz_`0!ZqF(T zerjPNnpb!WJ3q*#lA=d^MmXNOJT55Ih{hWbtN^tT3nfP} z6o`5k{tmbfxGG$t#1vMz zx{NFxxtrD2>x0f=F9^AFqDA6cHizhQdQ_V5Sr9!-4Z^wr^@x7*8qim!f$;zD8G3eT zzB%`obJu47WOi%j|DD;K8Jhl@>2Y%ZZ=d{ny8r#J6Hku+_IPuAa_l?c{{M&N=SqK7 z`i9cIqdzhFz2ustq7u5=)15+O!PI}5%i|t2bUCDO*mm>o67l@oQ)KY?aADpk~?qQP!httcq zL5T0)B&CLPte#3Zg{=$;ajPR~|4-Ggd{ooYpC!4}AKaMn}P?V~id=};bZGaYdfQbcCH94g@}x>UQlb+u=}~Bl2Sxn|riuoa1%Wey zkich?YTHo+!uQF9`$}-WsOm;U|75^KxQgHiT!2{=hIMoftCJ8E8E$2y`rgP8O6N2iTdG!p=M_iUf_|_F{Cl+~smdmQ z?|_?phcvH}!?0XpK6qM4wG4@1dBP{F`$>r+2Hb!PHEO=gpKP5k)8qvQW}e0A(^#y&T8 zNBIZJpD6uCX?65ZMqeE*k7Ofv5C81&6GOi~^ulib|Fw2im9eKc7?xg7VMEi~?0v5g z&R7$D!}xcvkb_aU5twq_wsll{!|F+00{}m$@>~e1ssDPZBzCm0^!SMG&& zs>pT;k-Dz*WyCEA^E_6ofH9M-1w$sl#jvB0HcS`Vi6Yx|@c9yV2Gf+t6KH7ohQK#L z=0+1o(yB4QKUedOY^V(`?ao{!+!xSY6Dae#!(p4O1l83f?tf?MgPLNm;L;Gj0lO26 z&^$3WI!oiMiGxX?!qS^Q~6$EzsuCsFm=1=mPa&-%uVcfcT(%!50}` zqaCX5-a*7l_6uPuZe0+LE`6cEM^S*{1O6xUX95p*(<|*jrTGp@UD;R-Dq;imeqA)t z(CNe=8aO2o#X>VI=G%cdkgkDLX9xO9`(=galOsBRf(;x~m;psE3UY526qfK^K(<3d zHRY&y%k7FHaG?|@nOH)$fE}Ui1*OMw!svlRhxq;3a*PK_#c&;bthpoWgW4<(7<^AcSq zV{4`Tl4678NX*|L1dB!YZBPNQssRrS9Xw-FGPFIV$)IM|+Ak__FMHw^A&jjy>l@5( zxAQYK&C=nKZ3Zn!ID>LWdNZR)0ab@U@Tka#Rm!inUr_k0GI>jvtE<(fZ1KE^aC8U^ z(lFq@1LR8%oL=Li%n(k{C|PMgKhRX}jcxZQnK;3%XAxJ$?}wa@vIWtx7N`eB7+ig+ zUTuH!m_y57Hqyc%2f)6uWFV$3K%Hj7AnD|nGD@x5eoiH89p*)CVZ9oyb(0KLT8z}0 zLV0H$ay_t^y69+u^sq>90{9F?k3A@Kr~tXpepYe4)_bxPC)*=lg4&?nE!?Rv;(&02 z8XbUk>HT(sKZS*V<33G*oYO`l5F>gjynn5D?Cxf5DP*xTsN}a1MqK z_%%Sb`_W77rxYle{ezX!pwTk~-AWY)dx7hOfIe49WTlvM;7mO*Sx+jk4~)PxYS8HB zb5&v=vRrh90SQh15`?**nq6T4HKuxjMkz zi0%TOf3*$wNf*uWUI1NyUKxEIPguTgJ6;{C>#>X4&F>d&@O>eC|j6Tl`M zj*yhG?Kax5s^rh|!SpWpo1Gk9KjF)7WJ4u?Vwpt8ai}lpsYcM=m;z$-QID*QU`Vl z083Q6Kp7^_m%!Z=|iLcV)WUOKOgyfApgH__+32WOZ#W7Go{e6z}y+=)@uAouElG8T^hO1cFB zo6-Xo8^lAcgd_tT8(UW##L3*14@=my#bC`=gknM+aA2-_p!&_G-0lob}y!RJdZL2lJhIPf9bLzMN=juGz~9i4(c zAiL4*lvKK^|NQi`lP%Xu%4%Y=e67^2dj9~?%hN*f2-3T){43`FF?r;g$IwK1AsX(A)TY%(29ojlkYM2Vp zQ1rTvY57E0LGXJ!uXcu2RX7I)HUPi(YGJmj0YSwBU#0V#=rGuUH1kmfki5B^0U*+J zTyfg^UWIF?*NX;5#!K6oJW;3)e?Uoz92 zHxSZHt-80lSl?Cx3oz$XDyVQP7ky@2V%AZLr zB|8ikI0y9;(K6!!>R(^B*olYZFpPqt?+}x z?S(a2f!?nd)u{$isYa?A9#A0O#5|~>0G+~$(|v<#xnQMzSrKW;k(|GcX-`6JnqX?6 zU@E}xP4KL6guCoJ)E+IjHw&Vgds}OFpt)O_+HLSX;B7$OpwdGIh7O=hfUroQir;E) z3_h>>3@>eA|CbZ(;7e^tTk=aN4o>WTX>VZnuC*HlX6D}HN<>OFE>(_H*${~&Z3AB* z5HT>gG)#-|YC`fXS*ZRO}P1o$C3HSK5) zSCym`&_L{J(bhxs{2^RGDIUb*pqa4Tyrj{F<|W^iR=z;~e1lEp{-c=zV0OZ^L=5x< z2riLps@Dl`*4yyBLL`cB}Xd9aKVyqx7cs zR{3b&d*^P<{WmAt^w-`z@;w|H!A9u!ne(b68ZHq~( zs{a+E4{7Zq2vz_dcM$}+w_Q;(eWmk0^;Nz|yl-FfdEZxA^o1}D4lSOG56F~UI@L3P z&;aDXjfN=^uXY|(du;ojFEkEcU(tOMhOij!RceV50!N<9@ zzEas}1ofsuph>n1gmef`GW}J^f55maV1$_B{6lb|^MC?GerTBar(KKpBESl-v=8e!vu=joIjc z-O8^GW?=gzEDXGWG;)o}Pok+qK4bh zDF>ZE$(N?pI`^of8AryrUQ>;bYFWHPe1>ifw1tmB)E-0x`_|Pdg-JShD{9IPFJ=BF z<;c^R7tZH|QaSXBXcP%A8JtOiXd_Br>D;B@@9N9BRBI;DlF%_?l)Z1V4GQoYCTSg> z0uO*YUH0&w5u3BtdH1p8z0s|?+_^*T z^6i^cF}^ppF{94yrA3vYwoh9AwlqZ}9N5kr1LG6oDN5?71&biHL4m@N*XX>fXs6iL z&Q;Wh1;QM+?>Dmj3GqMB83@L~vV#G_0|207XhfGuVevxs4vnsqw(mh1-4kJ3B$9(l zBQJ>r!VTI_LWDG%1y=&WbPB~2q-Y`hzi@gqIyARZn)&%c^9!kHcVP$~Jq8TIHzj3F z4vka>m?*kjM$TgA?dovXA))z8iLXRJl0Ig%fF+BhIW%>Lase107%244h0bjS;d=5U zig3L^Rl#5kD;2tnw6#VA1SA7!52$ic(+i!q6@=^eo-Ya4>u}9eT_DJJp&bVPowus5ntiFI^(z8Q609uj{2+BZic&f&owumXOqs;|^(o5ZEO*|lRv-D| zB*vZrjFb8|j4WJe3e+GTu&9~_K2=h8Hw4 zhLT`3h?A|(Oi{dZZ^rjU0ImJ;PU}Q7eW^2D;PCDn@d45K+nMI%@T{P!K~X?igS~5; z0*Q=~O&B25g#UlH;Q#;Z{Pf)4n>#i8J+tqd`H2~K`is+B)3;6i*wizVzc;x$@n;ju z_JX;LQhRciK)>m&0eNvY(g789&xuET?)>AX@lk5t zpFdOi=wlC``?&l>fz~5kOvm^XHdv^iJcnkqkh%hVgTOo3>VS_@B!%)uFDN6|t1Byt ziKp)m-G$(}g5R1ZpMv6rnntLuF=arYgW3QkHGBN=9}+E@df}{+za<|b=SL6q8SzG1#tf`v8a$>UA-=0pZcJ60u*5;;svs30nru#mxPaxs_Fm&T@#o*ktO0ll$1E`#m+|+xXB$^3KLY2 zl)+*rn4;lMPDqH6496^`?J)O~V_oQ+RhhWmDcvQNlPC!C5Cp`<@d$ik^9Jo80`hCP zL_jCuk7#rrQMw3y0S6R>2AkC;rf9zQXP?j|jz;b@IHA=#0T9|)J0Z2dbRofZt9NJz zrSOJ|rONgvM1z7Hfet^2)*zXSGzfJxMACUCjS#mql3MP(d}qUt|Yf(?-0Yjpm3(5?LEeJ4TRM1%qa#1Qg?Uy^gqGY16(hLd51PePq$Od6j z&;aAFV1WzR84QP$Li8C5Vj}%|c(LQD?vou6`8xrM2bX1_b^yXn2W6NF8bXSJT_`?5 z%wOoZs{16UiQJarzM=xO%dAVK2ezzDCo3B607`_VRs%H}EOZ=o$YkI1CD#?+0p*%B zn4+;A+*AoSA#-HntC2wjD)MT_ERS4=SdEUQRHMD=>#hzL$U*V>YsTY&iNVk3MC=Yg;2=mLhXxu$B8IjD z^^U2$EsLc}PA-L-}ps~zJQGc8`hsPqvbB6hj&>j`IC zKgLWSkf%7|#WSrPW2R+NB{NN7Dy26-sQ^8r!a!j_cn&BB%a67XzV%uM;+1#gUr$0z zPQJN2(V}8KR9s83CeEsd!vt?4xl%j@q8~7NQYFmUGV2{ER}{vWLVo_9hBFG)5aS+D zu0vRyLUO8@EZ`tI8pAV%|9@)eM@9d?JLZ0T?vdGFo_%5FPiERP^V45FJq!E)%;aY$ z-#PI=O}uyfyT{fd621saFxF1Sb!a3YiAuK z!^jC~5J>HXXjuhH#LdP!5NSM^uaGt7rQG>;l`wVgUl1mff#Ri?5+{f|1ydiom6=XDo5TED_eRG2Ng=cG@^4mEc4Wl zQS)F6E-ng54B@uXDC)SUe`mD)W!K#2KBhkX*vdYfr|^yf{H5ZR;HbzZQVj(oed2Ta zA?P^n=_k5=!%sgX9mhTW`(Gn}`N5V$lIs8`qS%AlbION6x5L^2qJewCyxf7P6O|B2okGK`s#DyBl<$0U;yme&D1C^>nRMQRQfJrROiY;3I>k zgbRjlEY!T=DT8By)d0u>wUNeZ=b{SRRUlEa)*g|*kYF|J3ACFbS}cl;=$=MpwxEg( zuXo`1P@s`>CGIS-{fzpggT^IgPh5mMO_cZ&vei8}@+mQ9@=ZG%?JTHR+4?Klv+EnX z<&FJcQ~Y{kmilt%rDL479rXL&TjVdfpVGtwL?SGirs1P%$@*z9<4|=)-<>4h?7UbU zp4q+S^CU}_-h_0SHW6$vYE2PGyG=5lFrbimgmgS2H1Dm(MAe351ZIu z>_Ub?kV-U}=avI?ue*BOc}@ilJt!`JFQvLB_(=d7LGglPMH?ruzMe-DS8Dizw9$FC z*kst9$=>?$wLnXwo^|qzCZTLNav@ZtKNyKkhDLW#$_wh9^GYAGJ388k?vJRZM!^DN z48vSP!UC7Xg8@X;o{B!2gqtAIiM7?vxk62OMCQ&r$d*uWbO{fc&C&%n5!{AV8RSty z>KvTQNBpd_z_%a0oLZz#n$HD$a;&&_ZQWA zSoCTUyb2)GbXY}j(IM+1aR)^j(ZSfQcAhFsobBAJGyqg4&hX^0DN*nAoM6`k0)Q71 zl@^pw^h@gY|2s9bF*N_`+@H^VYHo6Nd**LuK8^SPwbP?hUpMuZ$-%P5}V$T6cW>LjogImX2aV+TZ$4tX@r(rg9v%Mvd#`BaF)OK26&2+umMFx> zBg{e@R?<^s0RT8{Loads6)1{ip&o&ki{K`(TN?Io4cgQz!@G!M7ba$78#)OE7`3ZC z^G4p=Z<2M#OGYGqf~d~Lq#>+|69G4-2|EG+jcjBaE{P&vHc#xJ%T5eUbaJQQ8{gG~ zoSb39wJ1;_lxurp*~gB*?05+KLKsEMj>i&0RIYK#xt2xxn~(}QfBJb)Hyk?6?eg)L zediVO&pSXEm>?+Mr8EV=5pf%+W=LI#IwP`xc4He(isLT(L9vo$$2%i>L9HPatYlfi z(23sH^x@TMIYSnd2_HTAg!h--Ft^SsQvEP|7)0zuxI)05>8OIwO8O*pX^jO#&?i8K4df7G#3>g|U)tP0b0%i;LCwu6LlSDDq(CGH=XMU+i30rER;a zP1!RuU_fxTLg_+-2$=iG2pBH7AZp5hjoKjHUsI)R4+@avRe28n4@gsDE8u}}A5t9* z8y6GT1hWb@=G9`8WY-bwJH4iVz$CE>OcMN13Xx2B(;#wz{R5+fKp)pbOjg{E?TrrP z6-6dV?mOgfS%_-{S`gs`)qEI-C?BA`4PF_8C*s)bTrJj&1#%_37Lp#opFmz=0wKMM zIRbAS6tQ$y!T$0^*aOCjB9kOnZg1yWrjIrHyh2T31nPniSWssA6m5{UhZ>*OkphO` z8y-s!gGG@wdiXVT<5){y6kp%yTt5EN@4ka->0@H+gt-8#iq<*6(I}eXaKR;sYsb=W z9)IZ%$(1a9jO|Z#Ttbg9P%7kI+4)?@Fk4er=~y9454**2mws1nf9Z9jz#4_Tn;a|| z6(1wOba7$fC7}N+<^VxQ(>=0iZd)fQB z?7@PqMa$m9|9@&|{%ffJ|GK%c*}pscj+t+sv8R7+`thlMJ#}&NZzjKEQlI##iI0x| zv+>8r{uR~#|F#^JzF4|2`dg#f=&6w(8#z7vkB1)~`mLc)9VY~^^WR?F){AcJm0et| zEO8GTw@>;Cnt9Qgh;%*7K!UdnAhvS*gsGO60DD1U=)Oj z@a)J=xLR`?)JTCBhk&kX?1wT|2u#Gmx~;Pcm7Jy~6X9kQx` zabdRL_~Cxx>cSr>`q0L7I8A|iL*b`uTiXv5rfdh1E!nB)cehI!ORkdmK3G(IeOizS z&Cm9+vhnTv%h^Nf5Tjalce{R^DR@+E*ijHmg(;hbmmt`I6)iSV>eG+_Oo^8^x8GB! zA@<&+zaW;q|B90-KKP@_&%#{`vXrVW=yS!Ib9(8!Dd=|^+qBmy&=3V;CG$>_gRlnd zfz)`=^cuL7L16==4e-j)9@rdsM8s--;F64i_fB@|hSDdmXMnQ5+0V1|=0h z;7ZUD{$LhkWBZ;$D>nZf6jp4ERY4Crk}qT=h^GP)g2_R&ZJ-oGtn}R{Sm~Xy_vA|E z9O5@$RPGU6fw6*2HN>BgD}fb*x`N!y>)Us!nwK3q;yWA6?ADI#etSa`-q=2Mg1y#z zgZ$~H(Y--?dl0$sd;bh0kes|I3vuO1$pT#1Z93Df=QL3myt^yHjz#&htDPl@i00G+hz$XBkNb~!CqZxA$!&-p3f#$jx!nurV~qcq z0=yBdz15hbo4w9~+eYMxveoLVy zEf6c&xS~UdMK+W)6g3sLNs{jIHqMg%Qgv$3!e z_kNNWw%|7sw@1Oik3%I9T;54a^X2vK1yn=;876Kk5e)Xn!c-qwx(6;$x5JVZ%+Sc7gQ`+ zN)ofK4z!&pEa!kDC`go&`t}nlQ*r>QlC$^!w|D0;lBV~4*yre;``{^tq)3qzNl83b zRn>JhX<1sWR!f>(Yqhi7)$TT@r;fK~dZ(}Ls-EeYz0|b2sw9XCg1~X)IHrRjl4DuU zABJJT31B035C{kyLr!8DMhxYj*n({MiXtJgk$isD)id4GPgPgfE}8tX3wzi*BKvvX z=Y8Ji`5oUwxfgjL9Ni@U^Hs8p1Di7yQ5Qgcu5x|n=`ruBvr=qmpO1Z4EV=l!_+24w z#ADHsuEFA*ooBJutbB9l>to*4BLgJf6^#R~_ED~wllGvhYw~frWLm-~h1mJ#4vmM= z;oaT%J1aR#LgX1I>dxCaNtnx3NRf;dJsNuD93s9%wHjIQX<9&u5=7VNO`S zI!;TR-CJ<9{J;M03#2)YK$R;`)U?269)z zX*fHc8nYh<*Q>F{oE_{#HR1(z;o1&Kr@@gYPNqvtWJlNKn>#-}W|tx`v`D zkrh0h!o0d@aNGkaKKV&fAQgNI64iB4~vbJw33g$l2=w! zY=ErNbDx8K31QG+4rE&7n>*ATMt>N4PdZ{Aqqk^|`v*9FQQA?|`Iiza0*R#H09wBO zT4#rz!x4GU=;t4~No(_A^af#3z>Q;FCQ}X0u{w~z5;JFM=O>Taq|3vcc=@QDIH$Nn z41-q8wS|FHB-oQ}~ z!zz?{lH>F@FbznuxavqS)Ur~gvqOF1h`n*txQR;+92p=PK$r#%tAQEAfmEm>wgWJ&AnLqy1W2PLTvBEftH;#|B?#rsNPzVRv z(A3Flna*6Ty;B_*9SjcNLl1v&*u<|7~ei%h>^>F8tQakwRCFOrb{( zJ6!Tg`3SNe^#xl!CqBq&ws3yp)CEHkC$g}m(AwB3kBd=upFMnw_mxVPj}l+1sH{~X zW#-DhF8b7=?ww=Nr$$ObuT)&!DIJCX*YbR1%)Nh4;s0xT3Eph22q7H>sFsEXY+soc z2t0?^yi+_1|G#g*(MP5VXuYYJPKn7q1}g4~$!WZX&7pQ+qq8%2^ag(TWV*gbuQQz&6ne z$xa%G^@0BXXHWd~6IcJ!t6#qI_pjW({D+r+>GDS}{e?@Px%gjReC)#iaN(5;=g$Ay z`LCS&-E;S70Q~mZJ7+(1=5L&NarXCT-0AYi)i2o6V)Q-9J-$VzL?XVJb1?q2>hmwB1W=uj(8!knsz1 zH+Jr&BxW``U+mo4kex4Vw(E<{Y`6ZfwvieF1QyaETm!;xR^Rw8O6JPC(IPV|tcM zkgI`BAEnBwkJIe+oja*mY~Sx+TD=!T>>4m1u4a(UtMY~SmFL1Nz%a_A(c2PTqN_Ap zJDaJp$-@ES7cZ=|8{Wm8rA9V#AV&zGVepnDv=!RFv0eoYCe7Mb(KL2C6AW}~sd>~u zauIAGzxZOi6Q}57>#H{pf4V{fKr0&qnV7B`4ge{eT3$UtW?st8U*B0Ce>Mz9TWQ`- z4*(f0qLJAvW|698`W&LY^$cVd!J=7uY3KILHx5^09?X8>+7oN5y9e~)*(;Q}1M>HjZ{At0!>(=-!!7K*l9JDQ_{*Pt^6{T~`pLzYzLKocQWwg|!6Ns8g3uMAxCmI? z6l~btc-JrPEX`aSH}~CNpZwhgAvaY)`2RdXE`}r(zuj7Kam`2x6`tFIU1#J&EHx&d^_b@~dA@jUD1w74CQuJt_v% zq?(g#m2JZoEZux-YlkvLLVD#mV}JGWXH!EPOO{7z*Oh?_;JBX$fgpOJ0SCt9p=q7ewAMEAn@DtA$B*{-wWk*!fA;A+m8VlZPz1c#K+&}*YVL(iM9%mWt=Miekj{2~ zZq!k{@7p=Jo~grFhm$1Cxl>{WskV2*!5%~WfKJl#+SAX?t;mZGb zW%c_Tt~X_;VNj?S)^xP(J_n&cAa0%DLY-_m#8%09%L}z>V7hn;f)$*H=j&xKL=wd zp9^zUxnZO7Q3kDP`v} zAenb(r4gkH|1nHlQ%{uTTs!Ousea+-p>NZ|V-P_%1=Ov~IidUUDF#YBQ2_Y$1RC=i z$vN;09fD#|b6WF72V-e|vHP*q7xnNR9eASDqlk=&Drud1Jz{*iapAQZa>x!L0*^Pk z-=F%T9*!XPjQDfRYSjyMu@gmNU#L?pG^Jt52;r;3oQ`mC#_TXt4x5^l24$3NLm)l1d*Qd5XqLYK2r&&0VFSq#YdgQ3$-8(j&xo3`r}x zA0Gd*V}&x)-wn-&-$~*jG)37&DK#R?5UFt^H5ew4b_{1hVnElsNtEKlhfvlTly(MR ze4-)`bP9S(&OTovn(Nzh=V_Y%P$~l*F+k!8)VF;TfHew&Fo8fRFi#5jx+;zz$$#3d;2abHtBul)?gx)GMB*u+LDWzr z6(PK&h*#krp;u7T$OSdXDlc|FFn%))pCYxH#4`qhTIH?cI6@c;Yz*x z{+aA>(zx#xEH#%FR{XK|H6-3MODV-IUEn!6k;XH#5jbQaNRYBcNnrk*A=EB}(<@diUxv21u+=cnVZ$VuF|% zrmQ|!VkzXz_NJ?_D>u4V#&6WUCm8)LD8eINIp|6Ppay=4vYC)56#66t6$k6(V-1md z3aq566OiMExEN^(c>|0BY8)tw?B|Q!OXI(V;ZvmEai(6aKSq1Q$}22ITB-)&+W--1 zX4OXbV#-zV;SOrHHW&Q=MaH+I7s)LKP*$PrBW3VX^mDXcnJi#~C=}Ei-3!MZCACg| zt+QG+R#C`$*}p{^i84{CQmyV-IzRqZ>^;lq2SIlT=(lo{103a|67nbwD)ZuyvL@J# z?zv+Pk$4IRwS2CjpoghLd`Gd;cVW9?aTY7{5N@6jI7q70h9P3f&1B zY;)*PyEQ&+@9vrLQLVcBLe$=OuhCK8wbqn|ZvbCVAm<54hETcSAYUpHwox7G&K`T1 z#7fCPutG#LP9(WaE{oc0(46cjT#@EtcV>KGcHn7J>jhuK4U}MrnmZx4CMZ`)uQezD z5kQLuPLDsJ_C^@BQa(EMMPHr}u%)b(6MTp^=j2l2k5c`5_tY^4NUV`bo7IiLzW!yuMN3Ci#uA9MW46)^gxD9k2Nr|@i!0ljbVU?@Ro!7^Ia{F4(W1d6|%yodyFc))BLaMt(q;S_$vD)Au zQ*Q3OcI;siPorhx3kdH&xdcjEDHrC4HB4uMRN%F{`Tt*y{D1z+Z(q56<-+A(zx>pt ze|qT`FMa;vZ(Y23@$7|PyYTe+e{=p<&sWa&4?rCsW!P&L`l zGm1Toi-Y(DLO(WMj(`ES7!4yN@zP57spF0pPdIWs#_D{B3#IT_Ry`238QC6l$e@hn zYpdO#P9cQGJ>Oug#m>F;EOpc{5_3p0iVq`oHLW75`#daCpdb{lTkS3&Z~`HI^oYyr zsCA3QxzwlgAHSRv<(#qCGCpDq~RTfzA zyBkzYYI@;3kX)tZ0!@b8e0jC|#E}d8D19d0V#zm93C= z6aaAPrS4Crx~{RVYi(Y1@rMX@tC)Hk-5Y_nwibJ5pa`vM5KX5!ARnK-vWz{6?S1r@ z??P}=1JGAi!xA4=7&`Ix^m)+`HvrP+e6>(`srwU0&whQWv6lMfbFeDt2z+Z{RFr_U zYItoC&SLOHW3Td3_s5U^<*RF}$qjA$>fRDj)c#OlQnH=H6|+*5DQLJf7P@~t)sQ~8 zG%NR3v%ATCRM)P=)OFv`n<9n<{x9mLr4a(5*oW7$@LP@ zjk=gMqW2k^+F_m|YVtms`EPXp*v!|`m4F8Wq!!(wVya-KQKD3IRVfF7tmKM(NtCto zweFW^8tLB~kzy1-Z!HcWVa<)D5xr6NKRIpb0%inE7!p#6Zx<0~qQK~=rQ$cbUm7*{ z2V?v5q&N{&)?6G$rSq79>eDQja&U;RdR{^;MExYL1_vQV>>Z-5wqmP7M3WKjxi z8Q+HLbKPnR0T6p-FyC97_0)7B5k-IwH5DUhm^wcIaVR;_D6a7od#+nK^4BJ2i(^%- zkjw#qaO)9_m?y>y2n8o45hyjE>z2p=+D0=qTfBT3S4(X_6aHb+2R1~#fW&D{l2m)S zTN+ic*$u#BYcvGt}AVG=xG^ z40cIi7u`}Tjkh*!Pt>&69cfT;|i`xGT2(76%5Lq*Q7K&_ooGN+^z-t24(4@6$*q1JJKR@b% z+yC2JORePP3{V?dq&ZcRYKRLu!9|7i)LA6Y74xNq?&l`{^@*L&G9BcV9U`4oyGF_; zT~qwg4sZz}4RwEHlKq3Cxp_0SI=;;o4JRQ*i}hh80E66A=k?E(>{X_3bbokcUc2uD zuu}ZC(g>i?EYmN^yYIok!Res_To<}DB(|gp*SkM7$v3w9GLp{_Ra^HbC>;)t_7ykO z=!fEI*sb6W-OrBCXzxgG))oeTj!B#c?zW&t!mbA0E45G%OBgH{D%{o<$TvPfpznK{)M`cHix@rqF^$k_MEFsr)W`z3 zb}*Hi-5)&SF%GxI6U`H?i!#Kn=m7T4ug4mZM36!CP%ZGy$p3%v#D93=>UXYw>B`@^ zQoH;Imw%B0;9tJ<!#S=KnX&e)Y`np1FJG%!EKMIUm;%HRBYb*lAl;90a5 zH@p1orWrRLcg(nXR)X5?sFaw9^I$*%$EMgX#OOJ;&tLB@jXGo=JnmZ5ZsL#BXX6+S zE-IBI%H!&E0W(5SXRl4`URHL!d+QhjB)``x*=yaK zv)dm`2RRQOVRZ{1e51D7Zo1G{+e-qJ*qsOeD)rucsJhnx@H~Pop4y4dtxF#!x#8-p zzSeC`HF~_Zqeq9OqD||%kB~yQMA;c4A0SWx)Rk0yvzsOLy$|fx#Ix_-8IMjNby}gc zsm`@Zp^YO>lcL&4%|NQ=p?j+BE-SjDKGK+gD$e54IPY^(QSKc2T)+?-WY{4Iq(tPjo%kWOlmf`ce88DSHDGyyVY0vEv0(JT zDddIS#mNVXWgIn-Zv!lpg-nnh5Fp(ocB!%)3X>qJxY|wH#U1=KHt#@~uP)FVP?jI; z%-tVTPeyRoXP7}D@FtZkM*0Hai20h=1F4i&yWc$eojn{dU)cQ=4Cu$yfNFkf9~`>E z1e-CkeG*+w zuySxo*EX6P*5X>{W@=>Geh{&AS}T-$U?$+oo$3W_Rx)6KSFd){VBAMW zMgfZAakzSKRd!nryFaGJq*4sBiknTS!ObsmZ@49EEnWuUNmIVlW%PFOh-+*>JK8_y z@E{j};AGrPXTqL{#1zcV9B~~MBoayQ*QIR&`m)R2q}$u*XVql!T0LoUZ9(Kw6g`%m z%2iyo3b{5gZ3Pc60$J`pp8|1@9lnju=m=d9JW>e^8|in#;|lb|>3Nt}ET?5Lyk&iNF9;L{O=SZk^$WJbt@NL+hxk z@!<>I8#&f?_;c!cLC5Qm+q`fG+cxxVg9q+-w!?XkjJ7*7##& zQ-{<}RYjAif^HHEHh3=*BYBW$eM@KIE8StZkGLVcGAOt?8f>2FHJtX}Dj}_+Z z&IK*GpFOfgCbm2HWGn6U;Q6J-1GsaT1M6h-wy88(oygVCm`J&`P%kcZpGh$RN3LXC zim{rhx7N}-P(={UHK-&zW`e7JzQws4-9I_1a`E7%M{pc`b^bH;IE2t$6M2-hsAiHUuQMkO9(6uW&_bczefsFF zpS9OFvUYo^wcw|@LVNcB9sZmeRX`!vSBZr^6pXqZCC>u#2Iy5i0L9&}kAfXOc(4a; z=*8N4GM%As3&Yjqyd$rU8sPW1I zrM1#~PwL1RGvt$7jch%liR5?<4KG+xTr}SmoRNIQE@2nmQ0??J-|SsY(UgUj7> z!;u17Js8LjdnM1r0=jUKSi;MsMd8LNsMgtFB#7yv4OXZ<-@B0Ny9|ayYJDYZbkZbU zz%sct$izUXip*9>=s170p@Ypef30_Z=BdL$;@}sL-c2mC!nDB&!;GLP_mh0e-<7o$ zZ$wQm^v;cHKn>bBYrCIBB9BF2)7hdCAt>P4N~Z;#Rga&ilKiYzdZu@F=JCVxjY~9s zbLxN$sIF@fBq8Wy&XGCga3NO2kG_T6Grcooe`Vrz!H;2a(%3`5Ba`UYb7vsFOSl|d zq*`0+%^nF8xl>yfT!eVWf)iq6X>dOdeo8$A&;~rJTM|9CpwcdiDusxrwi*mhy|UJu zc{?Mfp0N&u>acZkI1*Va;rdF#dAIAj=;Cek`2Hmh{R8n#2lhWArrZ|Ey}=Vc{MXc# ztU6^NF|YEt3K11g6jjRR+=5X{YL!=dr;ZE|I~jQm9k9W0d;gLgEH(yBv%25f~ z1Me>}+9<$QSUCr113)Xf-IVFb;=)9*?WvcEORaR@Ox>MF4L490Nj)CxSp{|^SR%Gs zj8KnUY~Tl@e$u<=~Js@?pf~N%Je+*Qa^B zL3o-PPl!#k5O5R*mY^=SUa(fAG;p4p@{N`5Yg3KaQp-q z7ljXpORL`Q-k)Y~*3%p{uI*TX4B|k~0DeN?C~6n3b+XD1>f7CW#~n=u6JJB>Lq}c; zi&lxBy1!3>?;{!taR=%Vc;JmjcWV@-;z6L_-dx>sm^rRp<4H!g+9&1`oDLEhxF84* z1ujiY(yKCx+Wb=Y?vXj!?kJIs4SpJ#lWE!$w`roacsInFxU?fdI!3tD6HqO@+U2&F z2#ybaZJmV&-}l}Rw4wrSk=h|F?MU_lCX(QY#S7REmIBr-4UCdG=M_8*a^~72Ogp7Dp&CF7`?YT8=uU|QWN?Bkw%Q`H!IiM@-vb=9=&()% zBFHgnqgYTn`r*T(V*#H=D%oc!c5ZaK?WA(tp%o6Vg!JgChgL%aoge@X`GllFWD(0h zbXJtVcxdL9x*JDtqP5j~3ym$a96ayfr_@+A2PIoh1$B@IT3N0@gg7E*cCI>N>y_@S zM_#rY*=p9VwWGdO8chcr3VA7q_0LskNl%kZmai&q~Od114CXd-rcCJk6LR5V35ob zE;*j2RD!Ct=#5BAC;pyt&_cxr5T%)f8z;QN)&@u} zH{R%dZg%^_(`>d@Jp6D5o1LZQc5?9v!b7{t-R2rh5dne24<;aDFrKixrPq4Q3KQUp z30GjfhCDWUbZf1@zz(J06wb5D;}#f{ju4Xu`5j2mrpo)OK&jSSRC`Q#nlZ> z8L^p)GJZv?46Ycn0%mD7t9N@m3lrU=V@)8r@Cv@XJ;77yQ4VCfnT)|kl2^nzgxI^= z<54)($k|4H?3N2t4|kkn1#OwOYL%X3G6T$=bbG<)A^AW`IM+ec=hgRB zwl{lecfzBGRr+jqYO5p01?R*^R(mS6suC9zcjQq`jEt0)T~~6SeQL`4Y`5mRxqHtl zO)WJ?p07j|X_vuNEA>Llx=pEDgn&kovJ6qdH+!F)@*_Ji2}+fl>&fLOcp17K)E%)~ z)d0{@7;{qkgmWcDSJ*z$`$W=QY@+p7dLAyr`tqiGCcOpN6q4#urx#oj&s7I>(Bg8_ zk_aGd!yH%_CY+y-Ifwe@(y}urxemp04L%n27OqsVDf|QFf&nG^q1u_NZS_7r<%hTb zMI?s?=q5w!Obe-;@LmU5FQBk%o5PXNvg>^;sbx38)2~F6X53>7bd{MQSVXv?I|K0) zUi0QL?-Z((-t2wQ?)@s;Gh>eNum zTWcH7gtnuXQ(J95vj$2~U%vO#8#R!yn~$wGTZa=&s5y;&7h=AyEm?{%&zeyIit-q( z1h>HZC%**-(|qpM#@gNIZe`c*E_E8Wo>&w9#9mo#);5~SZOV{NTZ`Tk#a*bDIj51L zpi5aWh7&cw|Np>=)e~1=yL$S{FJJlK$86_`{wM4nfs^zpVNQp^r=(7aPr@rynEuG`kznu&)wcLQ=WZ;`+iKU zSB5vK(ER06K`jVUo0`d>ohP+J%W7<2?D3T=O}HfvR2Vikm$UYuy3khK&DQ-9fv4TM zgbcP(15wzOx&LDBv3&8d{A2f*)^oU?T7NoJlxhK&;r?(S)v}Rq9gKy0J$`fVeVelx zF}9X;Q@m|l#CT*qFS;ZY147i^mk4ZM?!n8 z64at83`W+dzSjHt9}Z+s*B0`nAlB~_3ds9 zup&M725ixY3HZ)PaPb3x^G5Tm8D2$I<7+<0!F?`&ugA^qZR~|c#6+XU#!1vmq!y65 zt7z;ZXmO9Bc%f&iHn`Q}X_t`KJ@Q6g*wy47^FBAU-!NRRI!^d;l#YLLf;ppWW$k#+$0H7f(DU^aP95|HQN6 z?gs3rxD+;d6RPQIJ-0*u-*v-5aS8A)Zn037^nZ^ zQ=a}0Pr6|iw6xk--sFO_cuNElw9{0Xy{6l)7fuYSu5pYSrt+)I3^Pi4LfduwbnhpU zW@Sg8L5C(Z<{;3$jy?$F8F`aH;ku4p$^v(Lm2klJ`5s@s{B#>+?*HS;{=nV*=*vlN4!vRdI=u$0x9Ir8>_xdsoIv*$;nqTM?wf8Q2KAYt zcf|0;jM*Q0fss7}c&gmQhs-cblSzv?+USkaTRm2O)14oOCz4zXFmR@`f)!dui18|w zYK8PojA(9(usg~o0Me8~@$*ZtIwlyj zw&9*gmq<%F&9`t1f@zZ<(d%dJK!;-anfKA(Jw5h1TMPP4H1akCY zSW@k$pGhWYo-=!+(<@Fn?8>-ksF>4&KuX}LEc2+&W6$VqR)bfo=T*#a_U5K+aZ-RA z697vvRNzD;kj^y40<}>NJ_e*gaO(=b=fafV^P^4g%~ehCI?XtP> zeG#9`t5UIs+U@`U+KH=w>gu^G-76O_|H|d}UHUVZzW?HXa`9sqe)+;KQlY~?{oe8vooJL{Z~$Z?$mFd`jL}=>16K2uT7Z#PyJtW4S-}!dJPOK z^OReb*ETnXH^9Q+a@zkl$@N0LCY6BEqOj#kR7s`OT&5)2m?JOVDBSHqX-rzZ-J3{# zlNn5QFOxLYnkyrm8gy#_GxP)LD%a&o89Wi07cvFJa1d%$uayCT&?98h#v#3|NePOGgaMMDf#)_=c3Yj^(&Q)Pg9T8t8ti^@rs?}2 zgcAxt%|b3jt8!M*v;;}Xv@fGOoZsl(n*8cJFzgr~GsGt*s9r9ZCpkKy4iq057gzu( zLrH&%(85$n>b=^^^4KJm-@_&p?;= zVbw^E$q~z2J+cZ@EwxeWY~@D7ZE7$~zTZqG6mrobL(s=%q!b|9X*GRSjmf{N18dz` zTU%ybnKd>8{WT`Em&vGl5B8Y4TXba+cMA?TS_I*vcdu8UvH*8r3dv)YdIqcuOGaWy zw4LXmw8bO&JQDyq_gUkuUTw;>B0|6iEx9pIPsbR2RuO`oh%o!`Boc5NvHSY&k2y|BAFoSeG{F-d0Oee|~D8nI@YUjyj2RAirJBDhQ5C&aMP2V(!SKBDU_9_UY@cvwLAD;U3k(i&7gri4-gA|7PK;A zw-kP&p9v-hlKWbZB*dgm)WpUZ-xo0QNDYVFQ>D`TvJc{P`1Czjfu0 zuB=`DC$#^6{nGi1w=evi3!ggw^XLATb6+_7D`)=YnXkQVu< ztq^2zxRS5(CJNXyEV&4mvPK2!SBf~)0(1K!V{I$mI!D*ME-(KUfKR&e`a<& zVWK_NT1H^-U@6DHWZ)pWl=Mthf^=|^I zY?`B=48KB4RUi-4MB;1v)4jL8=krXgXQio-$+nwpBb#&m94@AM&D6OmuCd44{z&i5 zckT;H?$KD!*qsU5C?>AzGA2BY6453o7>hfN0bG9}Qn_k&Z+wqtmsmSCR;t}d^7tAY zY7}b3rivFxkwFD(ZGX1+`t0`Y@Ah7N^s7m%W7w0Ry8FTzL4kTJF^Hcj-GSeR;?ffKJC8kg$$lRXeDZ%Wr?YcYk*K@dLQ;*5q*C zqe7pN-*jWM-C0{1sMjSG`Wh^ANJN!G%aS})l}b3H7Hd03q z%Uzm~k#oT|Km+Qo6Ecmy0&%H&qiA+_zDKi5ykZ1w^_FN#SE+(Bj>r0TDVk~M*fi?f z-{0Gu-G1S_`I(GG)IpS$5h?Q86oh?9+fnR;l;9YnzY5)Jex2{~{Dv5?bZb4sv|<8N zQeOaX4KWM8BBVw^X|Ve$we6W+dv^PW-l6q-cGzw|+-ac0Ac3msE#sefm0F2f{2-{% zuS6vC+q1om+3g>Br{?kG<3IKElS$mWvIfL+2z0_4uprcdFKR=yLM}z6rJNFi? z>Ts(~CiH8!+ry6XzQ0LE&EPXkSLT)VyrZ&+Y0&%tLUe37s9)+aAA?j2sC!|`w; zW4dew>QhSHp<#}Zg^^Uk6ba>Gj_XB@naKY?dg8ZFTz%!rA6&U}`42CD>+;1*zjWyg z{{KI|@F&mzt@Dqa`_pItknaC?X8+yn;>>T&eDd@gr%#@`fAar0x$b}V|HFUeNcfe< z&5=5)NR3bo*e$2;qMIQILTgUKk@!ERKSYF>8aSa&s-Bz3&KZk|sQDnS*KsIrpXh&T z@_yIe>lU65KmT@w>U%$rD6ZnxOVZ|fCM)uDq(_3x!{C#3mVu)NY@h0Xa&jPQY7UV( z9+*d>mmOU;kcJXsvldi=D_|4n7dZ>qFjI@%KHbN|oV59qn#Dwz0zF4mYg+OO&05)E z8*W*gNN{enILi0>n3$6`JW{h5^YLl$hIJZ=IyW{$(R zHu}FY<%jjYK4Rw+$Glla&thRBzy>)u74;0lnba3)C7LRF7(6M12bs;49Y)xm$32XO zvqC*QcpU9}y^sFi((hK#to~7FTtry}fTkh0lM!q6RbgAo+aK>^gdR8f7&W_tFZR#` z(}z#0T?<#@hP5!%?C#0}~~PMB-A? zPI;X241^tuf($P|r~dkV$FIMRU8c!CXAXswaENBkDJ}4^##8`JrGSgSO(iJ5eWj1s z`sHK36J~~^uy=a;lEDqqPU~V;;&%ecwbF`>yT*21e9UV zmtY(F?>T-{dU)`KF~JZd7_HcnA|0}}vJJ?ClawBYK1@|>^3DF$$>9!rf!NK)+MPij z7C%rY9H)<>+7Ta-SAr6afI|k!--IH+!>5=pcluY353W2gf#lkY_5eI6qA)o`hv?QUAl?L5;DFdd`&W_5P*fgNX-& z4!?!*KwhF&kUmkeLt>zA>4H>G)DEPD3RGHuy?=4a;S-n4;rm5}W{%rYcvt9;7WDjK z-}7|vG;oPiH#Yhgrd;wd`@0Co!lEP8=iP2nu)2e&Kzs(u2*)GaeqaCm@dMP6z3gZ* z=+DNnaBr`lov4&6;ZkFf_qCitP^aWaLD1YDp(l@!8u|anPAr|c+Pd;PS6;aM-(P<6 z(%-)H$1nc%i=VsjpI`X=`M-SrhtB;M=RSD$TW9|HnT6T^b~Zor=VnfwzIWsa?%=_y z?{2YOXwBk!ZG%Kd@|>HeeQz=9s(g^fYHu8W7#?X}=c3G9-k#~B@=aQTJg^iG=dye5 zk0rqB|A4&EgpqMWp3X782zMs5=MurOMnT=-%ahj~M$BV~H5juT1Lq@M-KH8OB}H6p za5thUIs-xi%*NS1Hs7R`&=J#kfF>A2jE1u%^v5I(0Ur2#p7$gf5;O}90g+^3`}_JR zeP4Tfd*tCnhHpr5Vsm44v2$xwu*M8Hy+flCj+SoL)MWply=h?4F0d;9o) zld6IqxkSU6E!|vQ+sGDc8#mLF3gWtR(z)3X@$;2L92Pi%D{3Rp*S0VBE0cp%k2k60 zgoKThN!{8w+#&|tesx5MU4Uv}l}fz7@;m?jvMmsw&SGu#UaVAF<&4808({{giu)mD zNqr8*fOaSjhjL@dQkCBMrP`fYa;aRqP9B#4jSWTa3X2%QCH@wc$9%ckw4sXc{Dx{| z4_sVQoF1-SXqDBP4tfRpFCsybNfc(Ou`~c@VBF>=$GAcZFjYw%PvXN8GnyK>K}2o9 z!KBjP>gOkihaNSZF^zFSF4G4NItthoo-e?;CB+?@f{X^> zsZn*`>Jtr~RGDG#z3iJqM3+xIbmB@RQTo{ws|cFzhH&_~l|dn)Mo?FKeeSJ3;ox^} z28lGME}3UV)8r2wWgLp8j%|0XNS{4xt>(o3p~+9|z3Rypp5&p@_@jTB{8%LM{C0>Y z>+zdf7!d@WJm}I)Cd&0U`=332G3U{d$5oSbQ?Zxki2kU^t8;+;0Ve`ul)<*EV#f>p z&m6xldbhT*N>MMYI0uGfu{9p~yYzCpAVKc8Kh`4=;t)Bo;t_w?+kzj*4a zCx8FsublkCiNEhxO#06^`?Z-=&k3Egy|6^K;sHl`X}ytSSwAf#qNi}N+ zzc`pb2ZRBWBUE{6^_ zo3>T8w9sFed2#&I_slj^lUFYT*`RKYv8|!N;UP^P9N3pn8mS2CXgBye3!Ey!Y9X4=;wmtQ9Z;; zU?D436Rf?G-|D|GIoImYa<61<1pC3q zaJU>t)x|yn6ootSeN_brT6jD=nSPO;EWXx9?mK2V?%_f|@igGu*ZH@#AM0#|PVXbd zK(2&2P~RxNL-^WrXqC{5%Kv;d0hHh9f8*H2$lcK=3)k36!R1@{@Td2NF^mzeeWMa9 zI!3wI`p-@I^n2rvi_=ic0{R&r{l(hTwH4OiS!H0h3ItN+Z~ zc^~2Qw`;Srbbmxb>!nwrFN-`ks9rMqBfP4G%?P#_#>x%p!_OQ$eb~1UgS>8#Rr_O9 zR;?F|;#^k?&NtN?n>lGVg-A*(b4)i%b0$HH_n0}%zDcw@_m-`|Vy!*gnW-(oWeU^2 zNzH{ayGDUGK#mG+Pq_sUZ0>%aB=7sDxq$}X#>S>nt8JMU9U-QYkv8Lz$=Qb_m9AKo z=pK(D!6`V<8-4n_$Lx{pTYy0kd@IopvW@ATX8!5oH_o+L(r2D$q{EQ*VqFHvMB zdxTvY8FqAQsIv5F^G?4I2b8x)91alT+E(aB^kU&|h|z$vP$VgltA(~NzuA9k%AjoU zNeri;=CZP$F8J`j0ee*9CrwSFmO+|Ui5w!QWkr5r?p~ib@1)4kVVKffx;IGB;y+dG z3Dcx2o|M?_L{^%`O87YoRZ2wrF)JY>2tUrf+JAC(`{eO9;=ZwyI}fEtO9QNl(JNfA z7$NU*^`k&yt4xC5>XYU@W))+gw6T)WJ=lHhkVhZ{W6e^oYj?hF&l9dsEZI(IhKXxqs$OKX;K&7sn&X76tN%`JF zcbC6AHQ)dzw3_9}|7Wgz`^42>zxwQz|IH8Y{`2k%yt@MLuE4u1@a_t{y8`d7z`HB( z?h3rS0`IQCyDRYS3VgR$;Ai{UOoG9=hrmvjvSidO_QI$EK!RA7EL)?e1%=%V)1_>+ z-<)|PQAindJz=>Qn;T0pz{0Sdvv_xDbP-_htE|}sA68*o zQil))seiWLn0a#4fStAV$5w79eyJvBC~_2;L8wn>L)O->;AEX|LRF jZ?0}FC0imu@epKeUFND(r3QLz)f{ziRODQhG{XN2TR!e8 delta 38 scmZo@;B0W1AjQVO$iTqBG*Q8hiGgur!UBFaULc=AU}GUa|HOvZ0GOT#jsO4v diff --git a/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.h b/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.h index 5856682..2fa22ae 100644 --- a/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.h +++ b/rt-thread/components/drivers/usb/cherryusb/core/usbd_core.h @@ -15,7 +15,7 @@ extern "C" { #include #include -#include "usb_config.h" +#include "../../../../../../board/ports/usb/usb_config.h" #include "usb_util.h" #include "usb_errno.h" #include "usb_def.h" diff --git a/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.h b/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.h index 060c402..71397a3 100644 --- a/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.h +++ b/rt-thread/components/drivers/usb/cherryusb/core/usbh_core.h @@ -11,7 +11,7 @@ #include #include -#include "usb_config.h" +#include "../../../../../../board/ports/usb/usb_config.h" #include "usb_util.h" #include "usb_errno.h" #include "usb_def.h" diff --git a/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c b/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c index 4a5fb8c..039bf11 100644 --- a/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c +++ b/rt-thread/components/drivers/usb/cherryusb/platform/rtthread/usb_check.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "rtthread.h" -#include "usb_config.h" +#include "../../../../../../../board/ports/usb/usb_config.h" #if defined(PKG_CHERRYUSB_HOST) || defined(RT_CHERRYUSB_HOST) diff --git a/rtconfig.h b/rtconfig.h index 8c98dc9..f7480da 100644 --- a/rtconfig.h +++ b/rtconfig.h @@ -99,6 +99,7 @@ #define RT_USING_HEAP /* end of Memory Management */ #define RT_USING_DEVICE +#define RT_USING_DEVICE_OPS #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 128 #define RT_CONSOLE_DEVICE_NAME "uart1" @@ -142,10 +143,18 @@ #define RT_USING_SERIAL #define RT_USING_SERIAL_V1 #define RT_SERIAL_USING_DMA -#define RT_SERIAL_RB_BUFSZ 1024 +#define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_SPI #define RT_USING_PIN #define RT_USING_KTIME +#define RT_USING_CHERRYUSB +#define RT_CHERRYUSB_DEVICE +#define RT_CHERRYUSB_DEVICE_SPEED_FS +#define RT_CHERRYUSB_DEVICE_DWC2_ST +#define RT_CHERRYUSB_DEVICE_CDC_ACM +#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 1024 +#define CONFIG_USBDEV_MSC_MAX_BUFSIZE 1024 +#define RT_CHERRYUSB_DEVICE_TEMPLATE_NONE /* end of Device Drivers */ /* C/C++ and POSIX layer */ @@ -176,6 +185,7 @@ /* end of Interprocess Communication (IPC) */ /* end of POSIX (Portable Operating System Interface) layer */ #define RT_USING_CPLUSPLUS +#define RT_USING_CPP_EXCEPTIONS /* end of C/C++ and POSIX layer */ /* Network */ @@ -444,9 +454,8 @@ #define ERPC_USING_RTT #define ERPC_MODE #define ERPC_MODE_SERVER -#define ERPC_MODE_CLIENT #define ERPC_TRANSPORTS -#define ERPC_TRANSPORTS_UART +#define ERPC_TRANSPORTS_USB_CDC /* end of Third Packages Drivers */ #endif