From e6cc2b6017e0f68339c56657aac2529b2b44d1fc Mon Sep 17 00:00:00 2001 From: Mateusz Klatecki Date: Thu, 27 Jun 2019 13:54:03 +0200 Subject: [PATCH] Major rework on GC5 platform files --- CMakeLists.txt | 8 +- targets/FreeRTOS/CMakeLists.txt | 10 +- targets/FreeRTOS/GC5/CMakeLists.txt | 36 + .../{UAC18/nanoCLR => GC5}/LwIP/arch/cc.h | 0 .../{UAC18/nanoCLR => GC5}/LwIP/arch/perf.h | 0 .../nanoCLR => GC5}/LwIP/arch/sys_arch.h | 0 .../{UAC18/nanoCLR => GC5}/LwIP/ethernetif.c | 0 .../{UAC18/nanoCLR => GC5}/LwIP/ethernetif.h | 0 .../{UAC18/nanoCLR => GC5}/LwIP/nf_api_msg.c | 0 .../nanoCLR => GC5}/LwIP/nf_lwipthread.c | 0 .../nanoCLR => GC5}/LwIP/nf_lwipthread.h | 0 .../{UAC18/nanoCLR => GC5}/LwIP/nf_sockets.c | 0 .../{UAC18/nanoCLR => GC5}/LwIP/nf_sys_arch.c | 0 .../FreeRTOS/{ => GC5}/UAC18/CMakeLists.txt | 30 +- .../include => GC5/UAC18}/FreeRTOSConfig.h | 318 +- targets/FreeRTOS/{ => GC5}/UAC18/README.md | 0 .../{UAC18/nanoCLR => GC5/UAC18}/lwipopts.h | 0 .../{ => GC5}/UAC18/nanoBooter/CMakeLists.txt | 0 .../{ => GC5}/UAC18/nanoBooter/MIMXRT10xx.ld | 0 .../nanoBooter/WireProtocol_App_Interface.c | 0 .../nanoBooter/WireProtocol_MonitorCommands.c | 0 .../{ => GC5}/UAC18/nanoBooter/main.c | 238 +- .../UAC18/nanoBooter/target_board.h.in | 0 .../FreeRTOS/GC5/UAC18/nanoCLR/CMakeLists.txt | 10 + .../{ => GC5}/UAC18/nanoCLR/MIMXRT10xx.ld | 0 .../FreeRTOS/{ => GC5}/UAC18/nanoCLR/main.c | 0 .../{ => GC5}/UAC18/nanoCLR/target_board.h.in | 0 .../{ => GC5}/UAC18/target_BlockStorage.c | 0 .../{ => GC5}/UAC18/target_BlockStorage.h | 0 .../FreeRTOS/{ => GC5}/UAC18/target_common.c | 0 .../{ => GC5}/UAC18/target_common.h.in | 0 .../UAC18}/target_lwip_sntp_opts.h | 0 ...ows_devices_serialcommunication_config.cpp | 8 + ...ndows_devices_serialcommunication_config.h | 8 + .../GC5/UAC18/target_windows_storage_config.h | 8 + targets/FreeRTOS/GC5/common/CMakeLists.txt | 87 + .../common/Device_BlockStorage.c | 0 .../Target_BlockStorage_iMXRTFlashDriver.c | 0 .../common/Target_Windows_Storage.c | 0 .../common/WireProtocol_HAL_Interface.c | 0 .../common/WireProtocol_ReceiverThread.c | 0 .../{UAC18 => GC5}/common/board/board.c | 0 .../{UAC18 => GC5}/common/board/board.h | 0 .../common/board/clock_config.c | 0 .../common/board/clock_config.h | 0 .../{UAC18 => GC5}/common/board/fsl_phy.c | 0 .../{UAC18 => GC5}/common/board/fsl_phy.h | 0 .../{UAC18 => GC5}/common/board/hyperRAM.c | 0 .../{UAC18 => GC5}/common/board/hyperRAM.h | 0 .../{UAC18 => GC5}/common/board/peripherals.c | 0 .../{UAC18 => GC5}/common/board/peripherals.h | 0 .../{UAC18 => GC5}/common/board/pin_mux.c | 0 .../{UAC18 => GC5}/common/board/pin_mux.h | 0 .../component/serial_manager/serial_manager.c | 0 .../component/serial_manager/serial_manager.h | 0 .../serial_manager/serial_port_uart.c | 0 .../serial_manager/serial_port_uart.h | 0 .../common/component/uart/lpuart_adapter.c | 0 .../common/component/uart/uart.h | 0 .../{UAC18 => GC5}/common/device/MIMXRT1062.h | 0 .../common/device/MIMXRT1062_features.h | 0 .../common/device/fsl_device_registers.h | 0 .../common/device/system_MIMXRT1062.c | 0 .../common/device/system_MIMXRT1062.h | 0 .../drivers/freertos/fsl_lpuart_freertos.c | 0 .../drivers/freertos/fsl_lpuart_freertos.h | 0 .../{UAC18 => GC5}/common/drivers/fsl_cache.c | 0 .../{UAC18 => GC5}/common/drivers/fsl_cache.h | 0 .../{UAC18 => GC5}/common/drivers/fsl_clock.c | 0 .../{UAC18 => GC5}/common/drivers/fsl_clock.h | 0 .../common/drivers/fsl_common.c | 0 .../common/drivers/fsl_common.h | 0 .../FreeRTOS/GC5/common/drivers/fsl_dmamux.c | 91 + .../FreeRTOS/GC5/common/drivers/fsl_dmamux.h | 178 + .../FreeRTOS/GC5/common/drivers/fsl_edma.c | 2674 +++++++++++ .../FreeRTOS/GC5/common/drivers/fsl_edma.h | 931 ++++ .../{UAC18 => GC5}/common/drivers/fsl_enet.c | 0 .../{UAC18 => GC5}/common/drivers/fsl_enet.h | 0 .../common/drivers/fsl_flexspi.c | 0 .../common/drivers/fsl_flexspi.h | 0 .../{UAC18 => GC5}/common/drivers/fsl_gpio.c | 0 .../{UAC18 => GC5}/common/drivers/fsl_gpio.h | 0 .../common/drivers/fsl_gpio_ext.c | 0 .../common/drivers/fsl_gpio_ext.h | 0 .../common/drivers/fsl_iomuxc.h | 0 .../common/drivers/fsl_lpuart.c | 4209 +++++++++-------- .../common/drivers/fsl_lpuart.h | 1713 +++---- .../GC5/common/drivers/fsl_lpuart_edma.c | 432 ++ .../GC5/common/drivers/fsl_lpuart_edma.h | 173 + .../{UAC18 => GC5}/common/drivers/fsl_semc.c | 0 .../{UAC18 => GC5}/common/drivers/fsl_semc.h | 0 .../common/drivers/fsl_snvs_lp.c | 0 .../common/drivers/fsl_snvs_lp.h | 0 .../{UAC18 => GC5}/common/drivers/fsl_trng.c | 0 .../{UAC18 => GC5}/common/drivers/fsl_trng.h | 0 .../common/drivers/fsl_usdhc.c | 0 .../common/drivers/fsl_usdhc.h | 0 .../{UAC18 => GC5}/common/hardfault.c | 0 .../common/platform_BlockStorage.c | 0 .../{UAC18 => GC5}/common/platform_heap.c | 0 .../common/sdmmc/inc/fsl_sd.h | 0 .../common/sdmmc/inc/fsl_sdmmc_common.h | 0 .../common/sdmmc/inc/fsl_sdmmc_host.h | 0 .../common/sdmmc/inc/fsl_sdmmc_spec.h | 0 .../common/sdmmc/port/fsl_sdmmc_event.c | 0 .../common/sdmmc/port/fsl_sdmmc_event.h | 0 .../common/sdmmc/port/fsl_sdmmc_host.c | 0 .../common/sdmmc/src/fsl_sd.c | 0 .../common/sdmmc/src/fsl_sdmmc_common.c | 0 .../common/startup/startup_mimxrt1062.c | 0 .../{UAC18 => GC5}/common/targetHAL.c | 0 .../common/targetHAL_ConfigurationManager.cpp | 0 .../{UAC18 => GC5}/common/targetHAL_Time.cpp | 0 .../common/utilities/flexspi_nor_flash_ops.c | 0 .../common/utilities/flexspi_nor_flash_ops.h | 0 .../common/utilities/fsl_debug_console.c | 0 .../common/utilities/fsl_debug_console.h | 0 .../common/utilities/fsl_debug_console_conf.h | 0 .../{UAC18 => GC5}/common/utilities/fsl_str.c | 0 .../{UAC18 => GC5}/common/utilities/fsl_str.h | 0 .../xip/evkmimxrt1060_flexspi_nor_config.c | 0 .../xip/evkmimxrt1060_flexspi_nor_config.h | 0 .../common/xip/fsl_flexspi_nor_boot.c | 0 .../common/xip/fsl_flexspi_nor_boot.h | 0 .../nanoCLR => GC5}/fatfs/diskio.c | 0 .../{UAC18/nanoCLR => GC5}/fatfs/ffconf.h | 0 .../nanoCLR => GC5}/fatfs/ffsystem.c | 0 .../nanoCLR => GC5}/fatfs/fsl_sd_disk.c | 0 .../nanoCLR => GC5}/fatfs/fsl_sd_disk.h | 0 targets/FreeRTOS/GC5/include/CMakeLists.txt | 14 + .../include/TargetPAL_BlockStorage.h | 0 .../Target_BlockStorage_iMXRTFlashDriver.h | 0 .../include/Target_Windows_Storage.h | 0 .../include/WireProtocol_ReceiverThread.h | 0 .../{UAC18 => GC5}/include/targetHAL.h | 0 .../{UAC18 => GC5}/include/targetHAL_Time.h | 0 .../{UAC18 => GC5}/include/targetPAL_Time.h | 0 .../CLR_RT_InteropAssembliesTable.cpp.in | 0 .../nanoCLR/CLR_Startup_Thread.c | 0 .../nanoCLR/CLR_Startup_Thread.h | 0 targets/FreeRTOS/GC5/nanoCLR/CMakeLists.txt | 61 + .../{UAC18 => GC5}/nanoCLR/Memory.cpp | 0 .../{UAC18 => GC5}/nanoCLR/Target_Network.cpp | 0 .../win_dev_gpio_native.cpp | 0 .../win_dev_gpio_native.h | 0 ...ve_Windows_Devices_Gpio_GpioController.cpp | 0 ...io_native_Windows_Devices_Gpio_GpioPin.cpp | 0 ...vices_SerialCommunication_SerialDevice.cpp | 670 +++ .../win_dev_serial_native_target.h | 77 + .../Windows.Storage/win_storage_native.cpp | 0 .../Windows.Storage/win_storage_native.h | 0 ..._native_Windows_Storage_Devices_SDCard.cpp | 0 ..._storage_native_Windows_Storage_FileIO.cpp | 0 ...age_native_Windows_Storage_StorageFile.cpp | 0 ...e_native_Windows_Storage_StorageFolder.cpp | 0 .../nanoCLR/WireProtocol_App_Interface.c | 0 targets/FreeRTOS/GC5/nanoCLR/lwipopts.h | 329 ++ .../{UAC18 => GC5}/nanoCLR/nanoCRT.cpp | 0 ...ative_nanoFramework_Runtime_Native_Rtc.cpp | 0 .../{UAC18 => GC5}/nanoCLR/nanoHAL.cpp | 0 .../{UAC18 => GC5}/nanoCLR/targetHAL.cpp | 0 .../nanoCLR/targetHAL_Network.cpp | 0 .../{UAC18 => GC5}/nanoCLR/targetHAL_Power.c | 0 .../{UAC18 => GC5}/nanoCLR/targetHAL_Time.cpp | 0 .../{UAC18 => GC5}/nanoCLR/targetHAL_Time.h | 0 .../nanoCLR/targetPAL_Events.cpp | 0 .../{UAC18 => GC5}/nanoCLR/targetPAL_Time.cpp | 0 .../{UAC18 => GC5}/nanoCLR/targetPAL_Time.h | 0 .../{UAC18 => GC5}/nanoCLR/targetRandom.cpp | 0 .../GC5/nanoCLR/target_lwip_sntp_opts.h | 18 + .../common/Target_Windows_Storage.c | 148 - .../NXP_MIMXRT1060_EVK/common/hardfault.c | 67 - .../Windows.Storage/win_storage_native.cpp | 70 - .../Windows.Storage/win_storage_native.h | 64 - ..._storage_native_Windows_Storage_FileIO.cpp | 659 --- ...e_native_Windows_Storage_StorageFolder.cpp | 840 ---- .../NXP_MIMXRT1060_EVK/nanoCLR/fatfs/ffconf.h | 293 -- targets/FreeRTOS/UAC18/common/CMakeLists.txt | 70 - .../FreeRTOS/UAC18/common/drivers/fsl_usdhc.c | 2017 -------- .../FreeRTOS/UAC18/common/drivers/fsl_usdhc.h | 1479 ------ .../FreeRTOS/UAC18/common/sdmmc/inc/fsl_sd.h | 321 -- .../UAC18/common/sdmmc/inc/fsl_sdmmc_common.h | 240 - .../UAC18/common/sdmmc/inc/fsl_sdmmc_host.h | 735 --- .../UAC18/common/sdmmc/inc/fsl_sdmmc_spec.h | 1170 ----- .../UAC18/common/sdmmc/port/fsl_sdmmc_event.c | 151 - .../UAC18/common/sdmmc/port/fsl_sdmmc_event.h | 86 - .../UAC18/common/sdmmc/port/fsl_sdmmc_host.c | 426 -- .../FreeRTOS/UAC18/common/sdmmc/src/fsl_sd.c | 1968 -------- .../UAC18/common/sdmmc/src/fsl_sdmmc_common.c | 298 -- targets/FreeRTOS/UAC18/nanoCLR/CMakeLists.txt | 65 - targets/FreeRTOS/UAC18/nanoCLR/fatfs/diskio.c | 111 - .../FreeRTOS/UAC18/nanoCLR/fatfs/ffsystem.c | 170 - .../UAC18/nanoCLR/fatfs/fsl_sd_disk.c | 126 - .../UAC18/nanoCLR/fatfs/fsl_sd_disk.h | 103 - 194 files changed, 9073 insertions(+), 14935 deletions(-) create mode 100644 targets/FreeRTOS/GC5/CMakeLists.txt rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/LwIP/arch/cc.h (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/LwIP/arch/perf.h (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/LwIP/arch/sys_arch.h (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/LwIP/ethernetif.c (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/LwIP/ethernetif.h (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/LwIP/nf_api_msg.c (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/LwIP/nf_lwipthread.c (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/LwIP/nf_lwipthread.h (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/LwIP/nf_sockets.c (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/LwIP/nf_sys_arch.c (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/CMakeLists.txt (87%) rename targets/FreeRTOS/{UAC18/include => GC5/UAC18}/FreeRTOSConfig.h (97%) rename targets/FreeRTOS/{ => GC5}/UAC18/README.md (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5/UAC18}/lwipopts.h (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/nanoBooter/CMakeLists.txt (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/nanoBooter/MIMXRT10xx.ld (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/nanoBooter/WireProtocol_App_Interface.c (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/nanoBooter/WireProtocol_MonitorCommands.c (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/nanoBooter/main.c (96%) rename targets/FreeRTOS/{ => GC5}/UAC18/nanoBooter/target_board.h.in (100%) create mode 100644 targets/FreeRTOS/GC5/UAC18/nanoCLR/CMakeLists.txt rename targets/FreeRTOS/{ => GC5}/UAC18/nanoCLR/MIMXRT10xx.ld (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/nanoCLR/main.c (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/nanoCLR/target_board.h.in (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/target_BlockStorage.c (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/target_BlockStorage.h (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/target_common.c (100%) rename targets/FreeRTOS/{ => GC5}/UAC18/target_common.h.in (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5/UAC18}/target_lwip_sntp_opts.h (100%) create mode 100644 targets/FreeRTOS/GC5/UAC18/target_windows_devices_serialcommunication_config.cpp create mode 100644 targets/FreeRTOS/GC5/UAC18/target_windows_devices_serialcommunication_config.h create mode 100644 targets/FreeRTOS/GC5/UAC18/target_windows_storage_config.h create mode 100644 targets/FreeRTOS/GC5/common/CMakeLists.txt rename targets/FreeRTOS/{UAC18 => GC5}/common/Device_BlockStorage.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/Target_BlockStorage_iMXRTFlashDriver.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/Target_Windows_Storage.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/WireProtocol_HAL_Interface.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/WireProtocol_ReceiverThread.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/board.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/board.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/clock_config.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/clock_config.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/fsl_phy.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/fsl_phy.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/hyperRAM.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/hyperRAM.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/peripherals.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/peripherals.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/pin_mux.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/board/pin_mux.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/component/serial_manager/serial_manager.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/component/serial_manager/serial_manager.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/component/serial_manager/serial_port_uart.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/component/serial_manager/serial_port_uart.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/component/uart/lpuart_adapter.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/component/uart/uart.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/device/MIMXRT1062.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/device/MIMXRT1062_features.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/device/fsl_device_registers.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/device/system_MIMXRT1062.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/device/system_MIMXRT1062.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/freertos/fsl_lpuart_freertos.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/freertos/fsl_lpuart_freertos.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_cache.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_cache.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_clock.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_clock.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_common.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_common.h (100%) create mode 100644 targets/FreeRTOS/GC5/common/drivers/fsl_dmamux.c create mode 100644 targets/FreeRTOS/GC5/common/drivers/fsl_dmamux.h create mode 100644 targets/FreeRTOS/GC5/common/drivers/fsl_edma.c create mode 100644 targets/FreeRTOS/GC5/common/drivers/fsl_edma.h rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_enet.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_enet.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_flexspi.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_flexspi.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_gpio.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_gpio.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_gpio_ext.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_gpio_ext.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_iomuxc.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_lpuart.c (97%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_lpuart.h (97%) create mode 100644 targets/FreeRTOS/GC5/common/drivers/fsl_lpuart_edma.c create mode 100644 targets/FreeRTOS/GC5/common/drivers/fsl_lpuart_edma.h rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_semc.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_semc.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_snvs_lp.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_snvs_lp.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_trng.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/drivers/fsl_trng.h (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/drivers/fsl_usdhc.c (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/drivers/fsl_usdhc.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/hardfault.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/platform_BlockStorage.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/platform_heap.c (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/sdmmc/inc/fsl_sd.h (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/sdmmc/inc/fsl_sdmmc_common.h (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/sdmmc/inc/fsl_sdmmc_host.h (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/sdmmc/inc/fsl_sdmmc_spec.h (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/sdmmc/port/fsl_sdmmc_event.c (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/sdmmc/port/fsl_sdmmc_event.h (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/sdmmc/port/fsl_sdmmc_host.c (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/sdmmc/src/fsl_sd.c (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK => GC5}/common/sdmmc/src/fsl_sdmmc_common.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/startup/startup_mimxrt1062.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/targetHAL.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/targetHAL_ConfigurationManager.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/targetHAL_Time.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/utilities/flexspi_nor_flash_ops.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/utilities/flexspi_nor_flash_ops.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/utilities/fsl_debug_console.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/utilities/fsl_debug_console.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/utilities/fsl_debug_console_conf.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/utilities/fsl_str.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/utilities/fsl_str.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/xip/evkmimxrt1060_flexspi_nor_config.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/xip/evkmimxrt1060_flexspi_nor_config.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/xip/fsl_flexspi_nor_boot.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/common/xip/fsl_flexspi_nor_boot.h (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK/nanoCLR => GC5}/fatfs/diskio.c (100%) rename targets/FreeRTOS/{UAC18/nanoCLR => GC5}/fatfs/ffconf.h (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK/nanoCLR => GC5}/fatfs/ffsystem.c (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK/nanoCLR => GC5}/fatfs/fsl_sd_disk.c (100%) rename targets/FreeRTOS/{NXP_MIMXRT1060_EVK/nanoCLR => GC5}/fatfs/fsl_sd_disk.h (100%) create mode 100644 targets/FreeRTOS/GC5/include/CMakeLists.txt rename targets/FreeRTOS/{UAC18 => GC5}/include/TargetPAL_BlockStorage.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/include/Target_BlockStorage_iMXRTFlashDriver.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/include/Target_Windows_Storage.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/include/WireProtocol_ReceiverThread.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/include/targetHAL.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/include/targetHAL_Time.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/include/targetPAL_Time.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/CLR_RT_InteropAssembliesTable.cpp.in (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/CLR_Startup_Thread.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/CLR_Startup_Thread.h (100%) create mode 100644 targets/FreeRTOS/GC5/nanoCLR/CMakeLists.txt rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Memory.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Target_Network.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native_Windows_Devices_Gpio_GpioController.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native_Windows_Devices_Gpio_GpioPin.cpp (100%) create mode 100644 targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.SerialCommunication/win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice.cpp create mode 100644 targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.SerialCommunication/win_dev_serial_native_target.h rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Windows.Storage/win_storage_native.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Windows.Storage/win_storage_native.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_Devices_SDCard.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_FileIO.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFile.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFolder.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/WireProtocol_App_Interface.c (100%) create mode 100644 targets/FreeRTOS/GC5/nanoCLR/lwipopts.h rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/nanoCRT.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/nanoHAL.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/targetHAL.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/targetHAL_Network.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/targetHAL_Power.c (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/targetHAL_Time.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/targetHAL_Time.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/targetPAL_Events.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/targetPAL_Time.cpp (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/targetPAL_Time.h (100%) rename targets/FreeRTOS/{UAC18 => GC5}/nanoCLR/targetRandom.cpp (100%) create mode 100644 targets/FreeRTOS/GC5/nanoCLR/target_lwip_sntp_opts.h delete mode 100644 targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/Target_Windows_Storage.c delete mode 100644 targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/hardfault.c delete mode 100644 targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native.cpp delete mode 100644 targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native.h delete mode 100644 targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_FileIO.cpp delete mode 100644 targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFolder.cpp delete mode 100644 targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/ffconf.h delete mode 100644 targets/FreeRTOS/UAC18/common/CMakeLists.txt delete mode 100644 targets/FreeRTOS/UAC18/common/drivers/fsl_usdhc.c delete mode 100644 targets/FreeRTOS/UAC18/common/drivers/fsl_usdhc.h delete mode 100644 targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sd.h delete mode 100644 targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_common.h delete mode 100644 targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_host.h delete mode 100644 targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_spec.h delete mode 100644 targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_event.c delete mode 100644 targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_event.h delete mode 100644 targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_host.c delete mode 100644 targets/FreeRTOS/UAC18/common/sdmmc/src/fsl_sd.c delete mode 100644 targets/FreeRTOS/UAC18/common/sdmmc/src/fsl_sdmmc_common.c delete mode 100644 targets/FreeRTOS/UAC18/nanoCLR/CMakeLists.txt delete mode 100644 targets/FreeRTOS/UAC18/nanoCLR/fatfs/diskio.c delete mode 100644 targets/FreeRTOS/UAC18/nanoCLR/fatfs/ffsystem.c delete mode 100644 targets/FreeRTOS/UAC18/nanoCLR/fatfs/fsl_sd_disk.c delete mode 100644 targets/FreeRTOS/UAC18/nanoCLR/fatfs/fsl_sd_disk.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 618c64af3e..8bb38fe660 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -665,22 +665,22 @@ elseif(RTOS_FREERTOS_CHECK) # now add the subdirectory for the board # try to find board in the targets folder - if(EXISTS ${PROJECT_SOURCE_DIR}/targets/FreeRTOS/NXP/${FREERTOS_BOARD}) + if(EXISTS ${PROJECT_SOURCE_DIR}/targets/FreeRTOS/GC5/${FREERTOS_BOARD}) # board found message(STATUS "Support for target board '${FREERTOS_BOARD}' found") # add TARGET board directory - add_subdirectory("targets/FreeRTOS/NXP/${FREERTOS_BOARD}") + add_subdirectory("targets/FreeRTOS/GC5/${FREERTOS_BOARD}") else() # try to find board in the Community targets folder - if(EXISTS ${PROJECT_SOURCE_DIR}/targets-community/FreeRTOS/NXP/${FREERTOS_BOARD}) + if(EXISTS ${PROJECT_SOURCE_DIR}/targets-community/FreeRTOS/GC5/${FREERTOS_BOARD}) # board found message(STATUS "Support for target board '${FREERTOS_BOARD}' found in Community targets") # add TARGET board directory from Community - add_subdirectory("targets-community/FreeRTOS/NXP/${FREERTOS_BOARD}") + add_subdirectory("targets-community/FreeRTOS/GC5/${FREERTOS_BOARD}") else() # board NOT found in targets folder diff --git a/targets/FreeRTOS/CMakeLists.txt b/targets/FreeRTOS/CMakeLists.txt index 706804e205..20721e10fb 100644 --- a/targets/FreeRTOS/CMakeLists.txt +++ b/targets/FreeRTOS/CMakeLists.txt @@ -413,18 +413,18 @@ else() endif() # Define base path for the class libraries -set(BASE_PATH_FOR_CLASS_LIBRARIES_MODULES "${PROJECT_SOURCE_DIR}/targets/FreeRTOS/NXP/nanoCLR") +set(BASE_PATH_FOR_CLASS_LIBRARIES_MODULES "${PROJECT_SOURCE_DIR}/targets/FreeRTOS/GC5/nanoCLR") # set target base location # this has to be set before the class library modules are pulled in -if(EXISTS ${PROJECT_SOURCE_DIR}/targets/FreeRTOS/NXP/${FREERTOS_BOARD}) +if(EXISTS ${PROJECT_SOURCE_DIR}/targets/FreeRTOS/GC5/${FREERTOS_BOARD}) # set target base location - set(TARGET_BASE_LOCATION "${PROJECT_SOURCE_DIR}/targets/FreeRTOS/NXP/${FREERTOS_BOARD}") + set(TARGET_BASE_LOCATION "${PROJECT_SOURCE_DIR}/targets/FreeRTOS/GC5/${FREERTOS_BOARD}") else() # try to find board in the Community targets folder if(EXISTS ${PROJECT_SOURCE_DIR}/targets-community/FreeRTOS/NXP/${FREERTOS_BOARD}) # set target base location - set(TARGET_BASE_LOCATION "${PROJECT_SOURCE_DIR}/targets-community/FreeRTOS/NXP/${FREERTOS_BOARD}") + set(TARGET_BASE_LOCATION "${PROJECT_SOURCE_DIR}/targets-community/FreeRTOS/GC5/${FREERTOS_BOARD}") else() # board NOT found in targets folder # can't continue @@ -434,4 +434,4 @@ endif() # board folder will be added in main CMakeList -add_subdirectory(NXP) \ No newline at end of file +add_subdirectory(GC5) \ No newline at end of file diff --git a/targets/FreeRTOS/GC5/CMakeLists.txt b/targets/FreeRTOS/GC5/CMakeLists.txt new file mode 100644 index 0000000000..f88f3ce60d --- /dev/null +++ b/targets/FreeRTOS/GC5/CMakeLists.txt @@ -0,0 +1,36 @@ +# +# Copyright (c) 2019 The nanoFramework project contributors +# See LICENSE file in the project root for full license information. +# + +# append FatFS files +if(USE_FILESYSTEM_OPTION) + list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/fatfs/diskio.c") + list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/fatfs/fsl_sd_disk.c") + list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/fatfs/ffsystem.c") + + list(APPEND NANOCLR_PROJECT_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/fatfs) + +endif() + +# append networking files, if enabled +if(USE_NETWORKING_OPTION) + list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/LwIP/ethernetif.c") + + list(APPEND NANOCLR_PROJECT_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/LwIP) + + # append mbed TLS entropy generator, if hardware has it + # if(NF_SECURITY_MBEDTLS AND USE_RNG) + # list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/mbedtls_entropy_hardware_pool.c") + # endif() + +endif() + +# make vars global +set(NANOCLR_PROJECT_SOURCES ${NANOCLR_PROJECT_SOURCES} CACHE INTERNAL "make global") +set(NANOCLR_PROJECT_INCLUDE_DIRS ${NANOCLR_PROJECT_INCLUDE_DIRS} CACHE INTERNAL "make global") + +# add platform dirs +add_subdirectory(include) +add_subdirectory(common) +add_subdirectory(nanoCLR) diff --git a/targets/FreeRTOS/UAC18/nanoCLR/LwIP/arch/cc.h b/targets/FreeRTOS/GC5/LwIP/arch/cc.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/LwIP/arch/cc.h rename to targets/FreeRTOS/GC5/LwIP/arch/cc.h diff --git a/targets/FreeRTOS/UAC18/nanoCLR/LwIP/arch/perf.h b/targets/FreeRTOS/GC5/LwIP/arch/perf.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/LwIP/arch/perf.h rename to targets/FreeRTOS/GC5/LwIP/arch/perf.h diff --git a/targets/FreeRTOS/UAC18/nanoCLR/LwIP/arch/sys_arch.h b/targets/FreeRTOS/GC5/LwIP/arch/sys_arch.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/LwIP/arch/sys_arch.h rename to targets/FreeRTOS/GC5/LwIP/arch/sys_arch.h diff --git a/targets/FreeRTOS/UAC18/nanoCLR/LwIP/ethernetif.c b/targets/FreeRTOS/GC5/LwIP/ethernetif.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/LwIP/ethernetif.c rename to targets/FreeRTOS/GC5/LwIP/ethernetif.c diff --git a/targets/FreeRTOS/UAC18/nanoCLR/LwIP/ethernetif.h b/targets/FreeRTOS/GC5/LwIP/ethernetif.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/LwIP/ethernetif.h rename to targets/FreeRTOS/GC5/LwIP/ethernetif.h diff --git a/targets/FreeRTOS/UAC18/nanoCLR/LwIP/nf_api_msg.c b/targets/FreeRTOS/GC5/LwIP/nf_api_msg.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/LwIP/nf_api_msg.c rename to targets/FreeRTOS/GC5/LwIP/nf_api_msg.c diff --git a/targets/FreeRTOS/UAC18/nanoCLR/LwIP/nf_lwipthread.c b/targets/FreeRTOS/GC5/LwIP/nf_lwipthread.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/LwIP/nf_lwipthread.c rename to targets/FreeRTOS/GC5/LwIP/nf_lwipthread.c diff --git a/targets/FreeRTOS/UAC18/nanoCLR/LwIP/nf_lwipthread.h b/targets/FreeRTOS/GC5/LwIP/nf_lwipthread.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/LwIP/nf_lwipthread.h rename to targets/FreeRTOS/GC5/LwIP/nf_lwipthread.h diff --git a/targets/FreeRTOS/UAC18/nanoCLR/LwIP/nf_sockets.c b/targets/FreeRTOS/GC5/LwIP/nf_sockets.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/LwIP/nf_sockets.c rename to targets/FreeRTOS/GC5/LwIP/nf_sockets.c diff --git a/targets/FreeRTOS/UAC18/nanoCLR/LwIP/nf_sys_arch.c b/targets/FreeRTOS/GC5/LwIP/nf_sys_arch.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/LwIP/nf_sys_arch.c rename to targets/FreeRTOS/GC5/LwIP/nf_sys_arch.c diff --git a/targets/FreeRTOS/UAC18/CMakeLists.txt b/targets/FreeRTOS/GC5/UAC18/CMakeLists.txt similarity index 87% rename from targets/FreeRTOS/UAC18/CMakeLists.txt rename to targets/FreeRTOS/GC5/UAC18/CMakeLists.txt index 61ed6b792e..a604491bc2 100644 --- a/targets/FreeRTOS/UAC18/CMakeLists.txt +++ b/targets/FreeRTOS/GC5/UAC18/CMakeLists.txt @@ -6,14 +6,12 @@ cmake_minimum_required(VERSION 3.0) ENABLE_LANGUAGE(ASM) -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/nanoCLR/target_board.h.in" - "${CMAKE_CURRENT_BINARY_DIR}/nanoCLR/target_board.h" @ONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/nanoBooter/target_board.h.in" "${CMAKE_CURRENT_BINARY_DIR}/nanoBooter/target_board.h" @ONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/nanoCLR/target_board.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/nanoCLR/target_board.h" @ONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/target_common.h.in" "${CMAKE_CURRENT_BINARY_DIR}/target_common.h" @ONLY) -configure_file("${CMAKE_SOURCE_DIR}/CMake/FreeRTOS_target_os.h.in" - "${CMAKE_BINARY_DIR}/targets/FreeRTOS/UAC18/target_os.h" @ONLY) set(NANOBOOTER_PROJECT_NAME "nanoBooter") set(NANOCLR_PROJECT_NAME "nanoCLR") @@ -50,7 +48,6 @@ endif() ####################################### -add_subdirectory("common") add_subdirectory("nanoBooter") add_subdirectory("nanoCLR") @@ -67,7 +64,7 @@ add_executable( # need to add configuration manager to allow get/store configuration blocks "${PROJECT_SOURCE_DIR}/src/HAL/nanoHAL_ConfigurationManager.c" - ${COMMON_PROJECT_SOURCES} + ${TARGET_NXP_COMMON_SOURCES} ${NANOBOOTER_PROJECT_SOURCES} ${FREERTOS_SOURCES} @@ -84,7 +81,8 @@ add_executable( "${CMAKE_CURRENT_SOURCE_DIR}/target_common.c" - ${COMMON_PROJECT_SOURCES} + ${TARGET_NXP_COMMON_SOURCES} + ${TARGET_NXP_NANOCLR_SOURCES} ${NANOCLR_PROJECT_SOURCES} ${FREERTOS_SOURCES} @@ -115,20 +113,10 @@ add_dependencies(${NANOCLR_PROJECT_NAME}.elf FreeRTOS CMSIS) # include common directories include_directories( "${CMAKE_CURRENT_BINARY_DIR}" + ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/common - ${CMAKE_CURRENT_SOURCE_DIR}/common/board - ${CMAKE_CURRENT_SOURCE_DIR}/common/component/serial_manager - ${CMAKE_CURRENT_SOURCE_DIR}/common/component/uart - ${CMAKE_CURRENT_SOURCE_DIR}/common/device - ${CMAKE_CURRENT_SOURCE_DIR}/common/drivers - ${CMAKE_CURRENT_SOURCE_DIR}/common/drivers/freertos - ${CMAKE_CURRENT_SOURCE_DIR}/common/utilities - ${CMAKE_CURRENT_SOURCE_DIR}/common/xip - ${CMAKE_CURRENT_SOURCE_DIR}/common/sdmmc/inc - ${CMAKE_CURRENT_SOURCE_DIR}/common/sdmmc/port - - ${CMAKE_CURRENT_SOURCE_DIR}/include + ${TARGET_NXP_COMMON_INCLUDE_DIRS} + ${TARGET_NXP_NANOCLR_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src/CLR/Core ${PROJECT_SOURCE_DIR}/src/CLR/Include @@ -148,7 +136,6 @@ target_include_directories(${NANOBOOTER_PROJECT_NAME}.elf PUBLIC ${TARGET_CMSIS_NANOBOOTER_INCLUDE_DIRS} ${TARGET_FREERTOS_NANOBOOTER_INCLUDE_DIRS} - ) # include directories for nanoCLR @@ -170,6 +157,7 @@ target_include_directories(${NANOCLR_PROJECT_NAME}.elf PUBLIC # includes for LwIP "${LWIP_INCLUDE_DIRS}" + "${NANOCLR_PROJECT_INCLUDE_DIRS}" # incudes for Networking and TLS "${NF_Networking_INCLUDE_DIRS}" diff --git a/targets/FreeRTOS/UAC18/include/FreeRTOSConfig.h b/targets/FreeRTOS/GC5/UAC18/FreeRTOSConfig.h similarity index 97% rename from targets/FreeRTOS/UAC18/include/FreeRTOSConfig.h rename to targets/FreeRTOS/GC5/UAC18/FreeRTOSConfig.h index c0645be615..880d86fda6 100644 --- a/targets/FreeRTOS/UAC18/include/FreeRTOSConfig.h +++ b/targets/FreeRTOS/GC5/UAC18/FreeRTOSConfig.h @@ -1,159 +1,159 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -/* - * FreeRTOS Kernel V10.0.1 - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://aws.amazon.com/freertos - * http://www.FreeRTOS.org - */ - - -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -#include "stddef.h" -#include "system_MIMXRT1062.h" - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ - -#define configUSE_PREEMPTION 1 -#define configUSE_TICKLESS_IDLE 0 -#define configCPU_CLOCK_HZ (SystemCoreClock) -#define configTICK_RATE_HZ ((TickType_t)1000) -#define configMAX_PRIORITIES 5 -#define configMINIMAL_STACK_SIZE ((unsigned short)90) -#define configMAX_TASK_NAME_LEN 20 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_TASK_NOTIFICATIONS 1 -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ -#define configQUEUE_REGISTRY_SIZE 8 -#define configUSE_QUEUE_SETS 0 -#define configUSE_TIME_SLICING 0 -#define configUSE_NEWLIB_REENTRANT 0 -#define configENABLE_BACKWARD_COMPATIBILITY 0 -#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 - -/* Used memory allocation (heap_x.c) */ -#define configFRTOS_MEMORY_SCHEME 4 -/* Tasks.c additions (e.g. Thread Aware Debug capability) */ -#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0 - -/* Memory allocation related definitions. */ -#define configSUPPORT_STATIC_ALLOCATION 0 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 -#define configTOTAL_HEAP_SIZE ((size_t)(256 * 1024)) -#define configAPPLICATION_ALLOCATED_HEAP 1 - -/* Hook function related definitions. */ -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 0 -#define configCHECK_FOR_STACK_OVERFLOW 0 -#define configUSE_MALLOC_FAILED_HOOK 0 -#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 - -/* Run time and task stats gathering related definitions. */ -#define configGENERATE_RUN_TIME_STATS 0 -#define configUSE_TRACE_FACILITY 1 -#define configUSE_STATS_FORMATTING_FUNCTIONS 0 - -/* Task aware debugging. */ -#define configRECORD_STACK_HIGH_ADDRESS 1 - -/* Co-routine related definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES 2 - -/* Software timer related definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) -#define configTIMER_QUEUE_LENGTH 10 -#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) - -/* Define to trap errors during development. */ -#define configASSERT(x) if(( x) == 0) {taskDISABLE_INTERRUPTS(); for (;;);} - -/* Optional functions - most linkers will remove unused functions anyway. */ -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_xTaskGetSchedulerState 1 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 0 -#define INCLUDE_xTaskGetIdleTaskHandle 0 -#define INCLUDE_eTaskGetState 0 -#define INCLUDE_xTimerPendFunctionCall 1 -#define INCLUDE_xTaskAbortDelay 0 -#define INCLUDE_xTaskGetHandle 0 -#define INCLUDE_xTaskResumeFromISR 1 - - -/* Interrupt nesting behaviour configuration. Cortex-M specific. */ -#ifdef __NVIC_PRIO_BITS -/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ -#define configPRIO_BITS __NVIC_PRIO_BITS -#else -#define configPRIO_BITS 4 /* 15 priority levels */ -#endif - -/* The lowest interrupt priority that can be used in a call to a "set priority" -function. */ -#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1U << (configPRIO_BITS)) - 1) - -/* The highest interrupt priority that can be used by any interrupt service -routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL -INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER -PRIORITY THAN THIS! (higher priorities are lower numeric values. */ -#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 - -/* Interrupt priorities used by the kernel port layer itself. These are generic -to all Cortex-M ports, and do not rely on any particular library functions. */ -#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) -/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! -See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ -#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) - -/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS -standard names. */ -#define vPortSVCHandler SVC_Handler -#define xPortPendSVHandler PendSV_Handler -#define xPortSysTickHandler SysTick_Handler - -#endif /* FREERTOS_CONFIG_H */ +// +// Copyright (c) 2019 The nanoFramework project contributors +// Portions Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +/* + * FreeRTOS Kernel V10.0.1 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://aws.amazon.com/freertos + * http://www.FreeRTOS.org + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "stddef.h" +#include "system_MIMXRT1062.h" + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_TICKLESS_IDLE 0 +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configTICK_RATE_HZ ((TickType_t)1000) +#define configMAX_PRIORITIES 5 +#define configMINIMAL_STACK_SIZE ((unsigned short)90) +#define configMAX_TASK_NAME_LEN 20 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ +#define configQUEUE_REGISTRY_SIZE 8 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 + +/* Used memory allocation (heap_x.c) */ +#define configFRTOS_MEMORY_SCHEME 4 +/* Tasks.c additions (e.g. Thread Aware Debug capability) */ +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0 + +/* Memory allocation related definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE ((size_t)(256 * 1024)) +#define configAPPLICATION_ALLOCATED_HEAP 1 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 1 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Task aware debugging. */ +#define configRECORD_STACK_HIGH_ADDRESS 1 + +/* Co-routine related definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1) +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) + +/* Define to trap errors during development. */ +#define configASSERT(x) if(( x) == 0) {taskDISABLE_INTERRUPTS(); for (;;);} + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 0 +#define INCLUDE_xTaskGetHandle 0 +#define INCLUDE_xTaskResumeFromISR 1 + + +/* Interrupt nesting behaviour configuration. Cortex-M specific. */ +#ifdef __NVIC_PRIO_BITS +/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ +#define configPRIO_BITS __NVIC_PRIO_BITS +#else +#define configPRIO_BITS 4 /* 15 priority levels */ +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1U << (configPRIO_BITS)) - 1) + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS)) + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +standard names. */ +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler + +#endif /* FREERTOS_CONFIG_H */ diff --git a/targets/FreeRTOS/UAC18/README.md b/targets/FreeRTOS/GC5/UAC18/README.md similarity index 100% rename from targets/FreeRTOS/UAC18/README.md rename to targets/FreeRTOS/GC5/UAC18/README.md diff --git a/targets/FreeRTOS/UAC18/nanoCLR/lwipopts.h b/targets/FreeRTOS/GC5/UAC18/lwipopts.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/lwipopts.h rename to targets/FreeRTOS/GC5/UAC18/lwipopts.h diff --git a/targets/FreeRTOS/UAC18/nanoBooter/CMakeLists.txt b/targets/FreeRTOS/GC5/UAC18/nanoBooter/CMakeLists.txt similarity index 100% rename from targets/FreeRTOS/UAC18/nanoBooter/CMakeLists.txt rename to targets/FreeRTOS/GC5/UAC18/nanoBooter/CMakeLists.txt diff --git a/targets/FreeRTOS/UAC18/nanoBooter/MIMXRT10xx.ld b/targets/FreeRTOS/GC5/UAC18/nanoBooter/MIMXRT10xx.ld similarity index 100% rename from targets/FreeRTOS/UAC18/nanoBooter/MIMXRT10xx.ld rename to targets/FreeRTOS/GC5/UAC18/nanoBooter/MIMXRT10xx.ld diff --git a/targets/FreeRTOS/UAC18/nanoBooter/WireProtocol_App_Interface.c b/targets/FreeRTOS/GC5/UAC18/nanoBooter/WireProtocol_App_Interface.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoBooter/WireProtocol_App_Interface.c rename to targets/FreeRTOS/GC5/UAC18/nanoBooter/WireProtocol_App_Interface.c diff --git a/targets/FreeRTOS/UAC18/nanoBooter/WireProtocol_MonitorCommands.c b/targets/FreeRTOS/GC5/UAC18/nanoBooter/WireProtocol_MonitorCommands.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoBooter/WireProtocol_MonitorCommands.c rename to targets/FreeRTOS/GC5/UAC18/nanoBooter/WireProtocol_MonitorCommands.c diff --git a/targets/FreeRTOS/UAC18/nanoBooter/main.c b/targets/FreeRTOS/GC5/UAC18/nanoBooter/main.c similarity index 96% rename from targets/FreeRTOS/UAC18/nanoBooter/main.c rename to targets/FreeRTOS/GC5/UAC18/nanoBooter/main.c index 7af6d83886..614ceb42c8 100644 --- a/targets/FreeRTOS/UAC18/nanoBooter/main.c +++ b/targets/FreeRTOS/GC5/UAC18/nanoBooter/main.c @@ -1,120 +1,120 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// See LICENSE file in the project root for full license information. -// - -#include -#include "board.h" -#include "peripherals.h" -#include "pin_mux.h" -#include "clock_config.h" -#include "MIMXRT1062.h" -#include "fsl_debug_console.h" - -#include "FreeRTOS.h" -#include "task.h" - -#include -#include -#include -#include "nanoHAL_ConfigurationManager.h" -#include "Target_BlockStorage_iMXRTFlashDriver.h" - -//configure heap memory -__attribute__((section(".noinit.$SRAM_OC.ucHeap"))) -uint8_t ucHeap[configTOTAL_HEAP_SIZE]; - -#define LED_GPIO GPIO1 -#define LED_GPIO_PIN (8U) - -static void blink_task(void *pvParameters) -{ - (void)pvParameters; - - /* Define the init structure for the output LED pin*/ - gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; - - /* Init output LED GPIO. */ - GPIO_PinInit(LED_GPIO, LED_GPIO_PIN, &led_config); - - for (;;) - { - vTaskDelay(100); - GPIO_PortToggle(LED_GPIO, 1u << LED_GPIO_PIN); - vTaskDelay(500); - GPIO_PortToggle(LED_GPIO, 1u << LED_GPIO_PIN); - } -} - -static void boot_nanoCLR(void){ - extern uint32_t __nanoCLR_start__; - uint32_t button = 0; - - /* Define the init structure for the output TP6 pin*/ - gpio_pin_config_t tp6_config = { - .direction = kGPIO_DigitalOutput, - .outputLogic = 0, - .interruptMode = kGPIO_NoIntmode - }; - - /* Init input GPIO*/ - GPIO_PinInit(BOARD_USER_TP6_GPIO, BOARD_USER_TP6_GPIO_PIN, &tp6_config); - - /* Define the init structure for the input TP7 pin*/ - gpio_pin_config_t button_config = { - .direction = kGPIO_DigitalInput, - .outputLogic = 0, - .interruptMode = kGPIO_NoIntmode - }; - - /* Init input GPIO*/ - GPIO_PinInit(BOARD_USER_TP7_GPIO, BOARD_USER_TP7_GPIO_PIN, &button_config); - button = GPIO_PinRead(BOARD_USER_TP7_GPIO, BOARD_USER_TP7_GPIO_PIN); - - /* Button is active low. - Load nanoCLR program through resetISR or if button is pressed init reciver Task */ - if (button) - { - void (*nanoCLR)(void); - nanoCLR = (void *) *(&__nanoCLR_start__ + 1); // resetISR address - nanoCLR(); - } -} - -int main(void) -{ - - //delay for development purposes - for (volatile uint32_t i = 0; i < 100000000; i++) { - __asm("nop"); - } - - BOARD_ConfigMPU(); - BOARD_InitBootPins(); - BOARD_InitBootClocks(); - - //SCB_DisableDCache(); - - boot_nanoCLR(); - - iMXRTFlexSPIDriver_InitializeDevice(NULL); - - // initialize block storage list and devices - // in CLR this is called in nanoHAL_Initialize() - // for nanoBooter we have to init it in order to provide the flash map for Monitor_FlashSectorMap command - BlockStorageList_Initialize(); - BlockStorage_AddDevices(); - - // initialize configuration manager - // in CLR this is called in nanoHAL_Initialize() - // for nanoBooter we have to init it here to have access to network configuration blocks - ConfigurationManager_Initialize(); - - xTaskCreate(blink_task, "blink_task", configMINIMAL_STACK_SIZE + 10, NULL, configMAX_PRIORITIES - 1, NULL); - xTaskCreate(ReceiverThread, "ReceiverThread", 2048, NULL, configMAX_PRIORITIES - 1, NULL); - vTaskStartScheduler(); - - for (;;) - ; - return 0; +// +// Copyright (c) 2019 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +#include +#include "board.h" +#include "peripherals.h" +#include "pin_mux.h" +#include "clock_config.h" +#include "MIMXRT1062.h" +#include "fsl_debug_console.h" + +#include "FreeRTOS.h" +#include "task.h" + +#include +#include +#include +#include "nanoHAL_ConfigurationManager.h" +#include "Target_BlockStorage_iMXRTFlashDriver.h" + +//configure heap memory +__attribute__((section(".noinit.$SRAM_OC.ucHeap"))) +uint8_t ucHeap[configTOTAL_HEAP_SIZE]; + +#define LED_GPIO GPIO1 +#define LED_GPIO_PIN (8U) + +static void blink_task(void *pvParameters) +{ + (void)pvParameters; + + /* Define the init structure for the output LED pin*/ + gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode}; + + /* Init output LED GPIO. */ + GPIO_PinInit(LED_GPIO, LED_GPIO_PIN, &led_config); + + for (;;) + { + vTaskDelay(100); + GPIO_PortToggle(LED_GPIO, 1u << LED_GPIO_PIN); + vTaskDelay(500); + GPIO_PortToggle(LED_GPIO, 1u << LED_GPIO_PIN); + } +} + +static void boot_nanoCLR(void){ + extern uint32_t __nanoCLR_start__; + uint32_t button = 0; + + /* Define the init structure for the output TP6 pin*/ + gpio_pin_config_t tp6_config = { + .direction = kGPIO_DigitalOutput, + .outputLogic = 0, + .interruptMode = kGPIO_NoIntmode + }; + + /* Init input GPIO*/ + GPIO_PinInit(BOARD_USER_TP6_GPIO, BOARD_USER_TP6_GPIO_PIN, &tp6_config); + + /* Define the init structure for the input TP7 pin*/ + gpio_pin_config_t button_config = { + .direction = kGPIO_DigitalInput, + .outputLogic = 0, + .interruptMode = kGPIO_NoIntmode + }; + + /* Init input GPIO*/ + GPIO_PinInit(BOARD_USER_TP7_GPIO, BOARD_USER_TP7_GPIO_PIN, &button_config); + button = GPIO_PinRead(BOARD_USER_TP7_GPIO, BOARD_USER_TP7_GPIO_PIN); + + /* Button is active low. + Load nanoCLR program through resetISR or if button is pressed init reciver Task */ + if (button) + { + void (*nanoCLR)(void); + nanoCLR = (void *) *(&__nanoCLR_start__ + 1); // resetISR address + nanoCLR(); + } +} + +int main(void) +{ + + //delay for development purposes + for (volatile uint32_t i = 0; i < 100000000; i++) { + __asm("nop"); + } + + BOARD_ConfigMPU(); + BOARD_InitBootPins(); + BOARD_InitBootClocks(); + + //SCB_DisableDCache(); + + boot_nanoCLR(); + + iMXRTFlexSPIDriver_InitializeDevice(NULL); + + // initialize block storage list and devices + // in CLR this is called in nanoHAL_Initialize() + // for nanoBooter we have to init it in order to provide the flash map for Monitor_FlashSectorMap command + BlockStorageList_Initialize(); + BlockStorage_AddDevices(); + + // initialize configuration manager + // in CLR this is called in nanoHAL_Initialize() + // for nanoBooter we have to init it here to have access to network configuration blocks + ConfigurationManager_Initialize(); + + xTaskCreate(blink_task, "blink_task", configMINIMAL_STACK_SIZE + 10, NULL, configMAX_PRIORITIES - 1, NULL); + xTaskCreate(ReceiverThread, "ReceiverThread", 2048, NULL, configMAX_PRIORITIES - 1, NULL); + vTaskStartScheduler(); + + for (;;) + ; + return 0; } \ No newline at end of file diff --git a/targets/FreeRTOS/UAC18/nanoBooter/target_board.h.in b/targets/FreeRTOS/GC5/UAC18/nanoBooter/target_board.h.in similarity index 100% rename from targets/FreeRTOS/UAC18/nanoBooter/target_board.h.in rename to targets/FreeRTOS/GC5/UAC18/nanoBooter/target_board.h.in diff --git a/targets/FreeRTOS/GC5/UAC18/nanoCLR/CMakeLists.txt b/targets/FreeRTOS/GC5/UAC18/nanoCLR/CMakeLists.txt new file mode 100644 index 0000000000..12202805e3 --- /dev/null +++ b/targets/FreeRTOS/GC5/UAC18/nanoCLR/CMakeLists.txt @@ -0,0 +1,10 @@ +# +# Copyright (c) 2019 The nanoFramework project contributors +# See LICENSE file in the project root for full license information. +# + +# append nanoCLR source files +list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/main.c") + +# make var global +set(NANOCLR_PROJECT_SOURCES ${NANOCLR_PROJECT_SOURCES} CACHE INTERNAL "make global") diff --git a/targets/FreeRTOS/UAC18/nanoCLR/MIMXRT10xx.ld b/targets/FreeRTOS/GC5/UAC18/nanoCLR/MIMXRT10xx.ld similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/MIMXRT10xx.ld rename to targets/FreeRTOS/GC5/UAC18/nanoCLR/MIMXRT10xx.ld diff --git a/targets/FreeRTOS/UAC18/nanoCLR/main.c b/targets/FreeRTOS/GC5/UAC18/nanoCLR/main.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/main.c rename to targets/FreeRTOS/GC5/UAC18/nanoCLR/main.c diff --git a/targets/FreeRTOS/UAC18/nanoCLR/target_board.h.in b/targets/FreeRTOS/GC5/UAC18/nanoCLR/target_board.h.in similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/target_board.h.in rename to targets/FreeRTOS/GC5/UAC18/nanoCLR/target_board.h.in diff --git a/targets/FreeRTOS/UAC18/target_BlockStorage.c b/targets/FreeRTOS/GC5/UAC18/target_BlockStorage.c similarity index 100% rename from targets/FreeRTOS/UAC18/target_BlockStorage.c rename to targets/FreeRTOS/GC5/UAC18/target_BlockStorage.c diff --git a/targets/FreeRTOS/UAC18/target_BlockStorage.h b/targets/FreeRTOS/GC5/UAC18/target_BlockStorage.h similarity index 100% rename from targets/FreeRTOS/UAC18/target_BlockStorage.h rename to targets/FreeRTOS/GC5/UAC18/target_BlockStorage.h diff --git a/targets/FreeRTOS/UAC18/target_common.c b/targets/FreeRTOS/GC5/UAC18/target_common.c similarity index 100% rename from targets/FreeRTOS/UAC18/target_common.c rename to targets/FreeRTOS/GC5/UAC18/target_common.c diff --git a/targets/FreeRTOS/UAC18/target_common.h.in b/targets/FreeRTOS/GC5/UAC18/target_common.h.in similarity index 100% rename from targets/FreeRTOS/UAC18/target_common.h.in rename to targets/FreeRTOS/GC5/UAC18/target_common.h.in diff --git a/targets/FreeRTOS/UAC18/nanoCLR/target_lwip_sntp_opts.h b/targets/FreeRTOS/GC5/UAC18/target_lwip_sntp_opts.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/target_lwip_sntp_opts.h rename to targets/FreeRTOS/GC5/UAC18/target_lwip_sntp_opts.h diff --git a/targets/FreeRTOS/GC5/UAC18/target_windows_devices_serialcommunication_config.cpp b/targets/FreeRTOS/GC5/UAC18/target_windows_devices_serialcommunication_config.cpp new file mode 100644 index 0000000000..4845bf12ac --- /dev/null +++ b/targets/FreeRTOS/GC5/UAC18/target_windows_devices_serialcommunication_config.cpp @@ -0,0 +1,8 @@ +// +// Copyright (c) 2017 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/FreeRTOS/GC5/UAC18/target_windows_devices_serialcommunication_config.h b/targets/FreeRTOS/GC5/UAC18/target_windows_devices_serialcommunication_config.h new file mode 100644 index 0000000000..088b626084 --- /dev/null +++ b/targets/FreeRTOS/GC5/UAC18/target_windows_devices_serialcommunication_config.h @@ -0,0 +1,8 @@ +// +// Copyright (c) 2019 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +/* tx/rx buffer size: 256 bytes */ +#define UART_TX_BUFER_SIZE 256 +#define UART_RX_BUFER_SIZE 256 diff --git a/targets/FreeRTOS/GC5/UAC18/target_windows_storage_config.h b/targets/FreeRTOS/GC5/UAC18/target_windows_storage_config.h new file mode 100644 index 0000000000..d7b7376bc0 --- /dev/null +++ b/targets/FreeRTOS/GC5/UAC18/target_windows_storage_config.h @@ -0,0 +1,8 @@ +// +// Copyright (c) 2019 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS BLANK ON PURPOSE BECAUSE THIS TARGET DOESN'T REQUIRE THIS SPECIFIC CONFIGURATION // +/////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/targets/FreeRTOS/GC5/common/CMakeLists.txt b/targets/FreeRTOS/GC5/common/CMakeLists.txt new file mode 100644 index 0000000000..2c61976f8f --- /dev/null +++ b/targets/FreeRTOS/GC5/common/CMakeLists.txt @@ -0,0 +1,87 @@ +# +# Copyright (c) 2019 The nanoFramework project contributors +# See LICENSE file in the project root for full license information. +# + +# append include directory for target NXP +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}") + +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/board) +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/component/serial_manager) +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/component/uart) +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/device) +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/drivers) +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/drivers/freertos) +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/utilities) +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/xip) +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/sdmmc/inc) +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/sdmmc/port) + +# append common source files +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/hardfault.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/startup/startup_mimxrt1062.c") + +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/board.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/clock_config.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/fsl_phy.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/peripherals.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/pin_mux.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/hyperRAM.c") + +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/component/serial_manager/serial_manager.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/component/serial_manager/serial_port_uart.c") + +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/component/uart/lpuart_adapter.c") + +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_cache.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_clock.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_enet.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_flexspi.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_gpio.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_gpio_ext.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_lpuart.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_lpuart_edma.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_edma.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_dmamux.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_semc.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_snvs_lp.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_trng.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_usdhc.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/sdmmc/src/fsl_sd.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/sdmmc/src/fsl_sdmmc_common.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/sdmmc/port/fsl_sdmmc_host.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/sdmmc/port/fsl_sdmmc_event.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/freertos/fsl_lpuart_freertos.c") + +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/device/system_MIMXRT1062.c") + +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/utilities/fsl_debug_console.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/utilities/fsl_str.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/utilities/flexspi_nor_flash_ops.c") + +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/xip/fsl_flexspi_nor_boot.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/xip/evkmimxrt1060_flexspi_nor_config.c") + + +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_ReceiverThread.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_HAL_Interface.c") + +# append nanoHAL +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Time.cpp") + +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/platform_heap.c") + +# append Target files +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Device_BlockStorage.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Target_BlockStorage_iMXRTFlashDriver.c") +list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/platform_BlockStorage.c") + +# include configuration manager file, if feature is enabled +if(NF_FEATURE_HAS_CONFIG_BLOCK) + list(APPEND TARGET_NXP_COMMON_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_ConfigurationManager.cpp") +endif() + +# make var global +set(TARGET_NXP_COMMON_SOURCES ${TARGET_NXP_COMMON_SOURCES} CACHE INTERNAL "make global") +set(TARGET_NXP_COMMON_INCLUDE_DIRS ${TARGET_NXP_COMMON_INCLUDE_DIRS} CACHE INTERNAL "make global") diff --git a/targets/FreeRTOS/UAC18/common/Device_BlockStorage.c b/targets/FreeRTOS/GC5/common/Device_BlockStorage.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/Device_BlockStorage.c rename to targets/FreeRTOS/GC5/common/Device_BlockStorage.c diff --git a/targets/FreeRTOS/UAC18/common/Target_BlockStorage_iMXRTFlashDriver.c b/targets/FreeRTOS/GC5/common/Target_BlockStorage_iMXRTFlashDriver.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/Target_BlockStorage_iMXRTFlashDriver.c rename to targets/FreeRTOS/GC5/common/Target_BlockStorage_iMXRTFlashDriver.c diff --git a/targets/FreeRTOS/UAC18/common/Target_Windows_Storage.c b/targets/FreeRTOS/GC5/common/Target_Windows_Storage.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/Target_Windows_Storage.c rename to targets/FreeRTOS/GC5/common/Target_Windows_Storage.c diff --git a/targets/FreeRTOS/UAC18/common/WireProtocol_HAL_Interface.c b/targets/FreeRTOS/GC5/common/WireProtocol_HAL_Interface.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/WireProtocol_HAL_Interface.c rename to targets/FreeRTOS/GC5/common/WireProtocol_HAL_Interface.c diff --git a/targets/FreeRTOS/UAC18/common/WireProtocol_ReceiverThread.c b/targets/FreeRTOS/GC5/common/WireProtocol_ReceiverThread.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/WireProtocol_ReceiverThread.c rename to targets/FreeRTOS/GC5/common/WireProtocol_ReceiverThread.c diff --git a/targets/FreeRTOS/UAC18/common/board/board.c b/targets/FreeRTOS/GC5/common/board/board.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/board.c rename to targets/FreeRTOS/GC5/common/board/board.c diff --git a/targets/FreeRTOS/UAC18/common/board/board.h b/targets/FreeRTOS/GC5/common/board/board.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/board.h rename to targets/FreeRTOS/GC5/common/board/board.h diff --git a/targets/FreeRTOS/UAC18/common/board/clock_config.c b/targets/FreeRTOS/GC5/common/board/clock_config.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/clock_config.c rename to targets/FreeRTOS/GC5/common/board/clock_config.c diff --git a/targets/FreeRTOS/UAC18/common/board/clock_config.h b/targets/FreeRTOS/GC5/common/board/clock_config.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/clock_config.h rename to targets/FreeRTOS/GC5/common/board/clock_config.h diff --git a/targets/FreeRTOS/UAC18/common/board/fsl_phy.c b/targets/FreeRTOS/GC5/common/board/fsl_phy.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/fsl_phy.c rename to targets/FreeRTOS/GC5/common/board/fsl_phy.c diff --git a/targets/FreeRTOS/UAC18/common/board/fsl_phy.h b/targets/FreeRTOS/GC5/common/board/fsl_phy.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/fsl_phy.h rename to targets/FreeRTOS/GC5/common/board/fsl_phy.h diff --git a/targets/FreeRTOS/UAC18/common/board/hyperRAM.c b/targets/FreeRTOS/GC5/common/board/hyperRAM.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/hyperRAM.c rename to targets/FreeRTOS/GC5/common/board/hyperRAM.c diff --git a/targets/FreeRTOS/UAC18/common/board/hyperRAM.h b/targets/FreeRTOS/GC5/common/board/hyperRAM.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/hyperRAM.h rename to targets/FreeRTOS/GC5/common/board/hyperRAM.h diff --git a/targets/FreeRTOS/UAC18/common/board/peripherals.c b/targets/FreeRTOS/GC5/common/board/peripherals.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/peripherals.c rename to targets/FreeRTOS/GC5/common/board/peripherals.c diff --git a/targets/FreeRTOS/UAC18/common/board/peripherals.h b/targets/FreeRTOS/GC5/common/board/peripherals.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/peripherals.h rename to targets/FreeRTOS/GC5/common/board/peripherals.h diff --git a/targets/FreeRTOS/UAC18/common/board/pin_mux.c b/targets/FreeRTOS/GC5/common/board/pin_mux.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/pin_mux.c rename to targets/FreeRTOS/GC5/common/board/pin_mux.c diff --git a/targets/FreeRTOS/UAC18/common/board/pin_mux.h b/targets/FreeRTOS/GC5/common/board/pin_mux.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/board/pin_mux.h rename to targets/FreeRTOS/GC5/common/board/pin_mux.h diff --git a/targets/FreeRTOS/UAC18/common/component/serial_manager/serial_manager.c b/targets/FreeRTOS/GC5/common/component/serial_manager/serial_manager.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/component/serial_manager/serial_manager.c rename to targets/FreeRTOS/GC5/common/component/serial_manager/serial_manager.c diff --git a/targets/FreeRTOS/UAC18/common/component/serial_manager/serial_manager.h b/targets/FreeRTOS/GC5/common/component/serial_manager/serial_manager.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/component/serial_manager/serial_manager.h rename to targets/FreeRTOS/GC5/common/component/serial_manager/serial_manager.h diff --git a/targets/FreeRTOS/UAC18/common/component/serial_manager/serial_port_uart.c b/targets/FreeRTOS/GC5/common/component/serial_manager/serial_port_uart.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/component/serial_manager/serial_port_uart.c rename to targets/FreeRTOS/GC5/common/component/serial_manager/serial_port_uart.c diff --git a/targets/FreeRTOS/UAC18/common/component/serial_manager/serial_port_uart.h b/targets/FreeRTOS/GC5/common/component/serial_manager/serial_port_uart.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/component/serial_manager/serial_port_uart.h rename to targets/FreeRTOS/GC5/common/component/serial_manager/serial_port_uart.h diff --git a/targets/FreeRTOS/UAC18/common/component/uart/lpuart_adapter.c b/targets/FreeRTOS/GC5/common/component/uart/lpuart_adapter.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/component/uart/lpuart_adapter.c rename to targets/FreeRTOS/GC5/common/component/uart/lpuart_adapter.c diff --git a/targets/FreeRTOS/UAC18/common/component/uart/uart.h b/targets/FreeRTOS/GC5/common/component/uart/uart.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/component/uart/uart.h rename to targets/FreeRTOS/GC5/common/component/uart/uart.h diff --git a/targets/FreeRTOS/UAC18/common/device/MIMXRT1062.h b/targets/FreeRTOS/GC5/common/device/MIMXRT1062.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/device/MIMXRT1062.h rename to targets/FreeRTOS/GC5/common/device/MIMXRT1062.h diff --git a/targets/FreeRTOS/UAC18/common/device/MIMXRT1062_features.h b/targets/FreeRTOS/GC5/common/device/MIMXRT1062_features.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/device/MIMXRT1062_features.h rename to targets/FreeRTOS/GC5/common/device/MIMXRT1062_features.h diff --git a/targets/FreeRTOS/UAC18/common/device/fsl_device_registers.h b/targets/FreeRTOS/GC5/common/device/fsl_device_registers.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/device/fsl_device_registers.h rename to targets/FreeRTOS/GC5/common/device/fsl_device_registers.h diff --git a/targets/FreeRTOS/UAC18/common/device/system_MIMXRT1062.c b/targets/FreeRTOS/GC5/common/device/system_MIMXRT1062.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/device/system_MIMXRT1062.c rename to targets/FreeRTOS/GC5/common/device/system_MIMXRT1062.c diff --git a/targets/FreeRTOS/UAC18/common/device/system_MIMXRT1062.h b/targets/FreeRTOS/GC5/common/device/system_MIMXRT1062.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/device/system_MIMXRT1062.h rename to targets/FreeRTOS/GC5/common/device/system_MIMXRT1062.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/freertos/fsl_lpuart_freertos.c b/targets/FreeRTOS/GC5/common/drivers/freertos/fsl_lpuart_freertos.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/freertos/fsl_lpuart_freertos.c rename to targets/FreeRTOS/GC5/common/drivers/freertos/fsl_lpuart_freertos.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/freertos/fsl_lpuart_freertos.h b/targets/FreeRTOS/GC5/common/drivers/freertos/fsl_lpuart_freertos.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/freertos/fsl_lpuart_freertos.h rename to targets/FreeRTOS/GC5/common/drivers/freertos/fsl_lpuart_freertos.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_cache.c b/targets/FreeRTOS/GC5/common/drivers/fsl_cache.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_cache.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_cache.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_cache.h b/targets/FreeRTOS/GC5/common/drivers/fsl_cache.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_cache.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_cache.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_clock.c b/targets/FreeRTOS/GC5/common/drivers/fsl_clock.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_clock.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_clock.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_clock.h b/targets/FreeRTOS/GC5/common/drivers/fsl_clock.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_clock.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_clock.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_common.c b/targets/FreeRTOS/GC5/common/drivers/fsl_common.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_common.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_common.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_common.h b/targets/FreeRTOS/GC5/common/drivers/fsl_common.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_common.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_common.h diff --git a/targets/FreeRTOS/GC5/common/drivers/fsl_dmamux.c b/targets/FreeRTOS/GC5/common/drivers/fsl_dmamux.c new file mode 100644 index 0000000000..8bfbe6c367 --- /dev/null +++ b/targets/FreeRTOS/GC5/common/drivers/fsl_dmamux.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_dmamux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.dmamux" +#endif + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for DMAMUX. + * + * @param base DMAMUX peripheral base address. + */ +static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Array to map DMAMUX instance number to base pointer. */ +static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Array to map DMAMUX instance number to clock name. */ +static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_dmamuxBases); instance++) + { + if (s_dmamuxBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_dmamuxBases)); + + return instance; +} + +/*! + * brief Initializes the DMAMUX peripheral. + * + * This function ungates the DMAMUX clock. + * + * param base DMAMUX peripheral base address. + * + */ +void DMAMUX_Init(DMAMUX_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Deinitializes the DMAMUX peripheral. + * + * This function gates the DMAMUX clock. + * + * param base DMAMUX peripheral base address. + */ +void DMAMUX_Deinit(DMAMUX_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} diff --git a/targets/FreeRTOS/GC5/common/drivers/fsl_dmamux.h b/targets/FreeRTOS/GC5/common/drivers/fsl_dmamux.h new file mode 100644 index 0000000000..f458f8de2d --- /dev/null +++ b/targets/FreeRTOS/GC5/common/drivers/fsl_dmamux.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_DMAMUX_H_ +#define _FSL_DMAMUX_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup dmamux + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief DMAMUX driver version 2.0.2. */ +#define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) +/*@}*/ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name DMAMUX Initialization and de-initialization + * @{ + */ + +/*! + * @brief Initializes the DMAMUX peripheral. + * + * This function ungates the DMAMUX clock. + * + * @param base DMAMUX peripheral base address. + * + */ +void DMAMUX_Init(DMAMUX_Type *base); + +/*! + * @brief Deinitializes the DMAMUX peripheral. + * + * This function gates the DMAMUX clock. + * + * @param base DMAMUX peripheral base address. + */ +void DMAMUX_Deinit(DMAMUX_Type *base); + +/* @} */ +/*! + * @name DMAMUX Channel Operation + * @{ + */ + +/*! + * @brief Enables the DMAMUX channel. + * + * This function enables the DMAMUX channel. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_EnableChannel(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] |= DMAMUX_CHCFG_ENBL_MASK; +} + +/*! + * @brief Disables the DMAMUX channel. + * + * This function disables the DMAMUX channel. + * + * @note The user must disable the DMAMUX channel before configuring it. + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_DisableChannel(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] &= ~DMAMUX_CHCFG_ENBL_MASK; +} + +/*! + * @brief Configures the DMAMUX channel source. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + * @param source Channel source, which is used to trigger the DMA transfer. + */ +static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint32_t source) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] = ((base->CHCFG[channel] & ~DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_SOURCE(source)); +} + +#if defined(FSL_FEATURE_DMAMUX_HAS_TRIG) && FSL_FEATURE_DMAMUX_HAS_TRIG > 0U +/*! + * @brief Enables the DMAMUX period trigger. + * + * This function enables the DMAMUX period trigger feature. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_EnablePeriodTrigger(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] |= DMAMUX_CHCFG_TRIG_MASK; +} + +/*! + * @brief Disables the DMAMUX period trigger. + * + * This function disables the DMAMUX period trigger. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + */ +static inline void DMAMUX_DisablePeriodTrigger(DMAMUX_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CHCFG[channel] &= ~DMAMUX_CHCFG_TRIG_MASK; +} +#endif /* FSL_FEATURE_DMAMUX_HAS_TRIG */ + +#if (defined(FSL_FEATURE_DMAMUX_HAS_A_ON) && FSL_FEATURE_DMAMUX_HAS_A_ON) +/*! + * @brief Enables the DMA channel to be always ON. + * + * This function enables the DMAMUX channel always ON feature. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + * @param enable Switcher of the always ON feature. "true" means enabled, "false" means disabled. + */ +static inline void DMAMUX_EnableAlwaysOn(DMAMUX_Type *base, uint32_t channel, bool enable) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + if (enable) + { + base->CHCFG[channel] |= DMAMUX_CHCFG_A_ON_MASK; + } + else + { + base->CHCFG[channel] &= ~DMAMUX_CHCFG_A_ON_MASK; + } +} +#endif /* FSL_FEATURE_DMAMUX_HAS_A_ON */ + +/* @} */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/* @} */ + +#endif /* _FSL_DMAMUX_H_ */ diff --git a/targets/FreeRTOS/GC5/common/drivers/fsl_edma.c b/targets/FreeRTOS/GC5/common/drivers/fsl_edma.c new file mode 100644 index 0000000000..cd4b56b5e9 --- /dev/null +++ b/targets/FreeRTOS/GC5/common/drivers/fsl_edma.c @@ -0,0 +1,2674 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_edma.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.edma" +#endif + +#define EDMA_TRANSFER_ENABLED_MASK 0x80U + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for EDMA. + * + * @param base EDMA peripheral base address. + */ +static uint32_t EDMA_GetInstance(DMA_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Array to map EDMA instance number to base pointer. */ +static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Array to map EDMA instance number to clock name. */ +static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Array to map EDMA instance number to IRQ number. */ +static const IRQn_Type s_edmaIRQNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS; + +/*! @brief Pointers to transfer handle for each EDMA channel. */ +static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t EDMA_GetInstance(DMA_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_edmaBases); instance++) + { + if (s_edmaBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_edmaBases)); + + return instance; +} + +/*! + * brief Push content of TCD structure into hardware TCD register. + * + * param base EDMA peripheral base address. + * param channel EDMA channel number. + * param tcd Point to TCD structure. + */ +void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + /* Push tcd into hardware TCD register */ + base->TCD[channel].SADDR = tcd->SADDR; + base->TCD[channel].SOFF = tcd->SOFF; + base->TCD[channel].ATTR = tcd->ATTR; + base->TCD[channel].NBYTES_MLNO = tcd->NBYTES; + base->TCD[channel].SLAST = tcd->SLAST; + base->TCD[channel].DADDR = tcd->DADDR; + base->TCD[channel].DOFF = tcd->DOFF; + base->TCD[channel].CITER_ELINKNO = tcd->CITER; + base->TCD[channel].DLAST_SGA = tcd->DLAST_SGA; + /* Clear DONE bit first, otherwise ESG cannot be set */ + base->TCD[channel].CSR = 0; + base->TCD[channel].CSR = tcd->CSR; + base->TCD[channel].BITER_ELINKNO = tcd->BITER; +} + +/*! + * brief Initializes the eDMA peripheral. + * + * This function ungates the eDMA clock and configures the eDMA peripheral according + * to the configuration structure. + * + * param base eDMA peripheral base address. + * param config A pointer to the configuration structure, see "edma_config_t". + * note This function enables the minor loop map feature. + */ +void EDMA_Init(DMA_Type *base, const edma_config_t *config) +{ + assert(config != NULL); + + uint32_t tmpreg; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate EDMA peripheral clock */ + CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* clear all the enabled request, status to make sure EDMA status is in normal condition */ + base->ERQ = 0U; + base->INT = 0xFFFFFFFFU; + base->ERR = 0xFFFFFFFFU; + /* Configure EDMA peripheral according to the configuration structure. */ + tmpreg = base->CR; + tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); + tmpreg |= (DMA_CR_ERCA(config->enableRoundRobinArbitration) | DMA_CR_HOE(config->enableHaltOnError) | + DMA_CR_CLM(config->enableContinuousLinkMode) | DMA_CR_EDBG(config->enableDebugMode) | DMA_CR_EMLM(true)); + base->CR = tmpreg; +} + +/*! + * brief Deinitializes the eDMA peripheral. + * + * This function gates the eDMA clock. + * + * param base eDMA peripheral base address. + */ +void EDMA_Deinit(DMA_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate EDMA peripheral clock */ + CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Gets the eDMA default configuration structure. + * + * This function sets the configuration structure to default values. + * The default configuration is set to the following values. + * code + * config.enableContinuousLinkMode = false; + * config.enableHaltOnError = true; + * config.enableRoundRobinArbitration = false; + * config.enableDebugMode = false; + * endcode + * + * param config A pointer to the eDMA configuration structure. + */ +void EDMA_GetDefaultConfig(edma_config_t *config) +{ + assert(config != NULL); + + /* Initializes the configure structure to zero. */ + memset(config, 0, sizeof(*config)); + + config->enableRoundRobinArbitration = false; + config->enableHaltOnError = true; + config->enableContinuousLinkMode = false; + config->enableDebugMode = false; +} + +/*! + * brief Sets all TCD registers to default values. + * + * This function sets TCD registers for this channel to default values. + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * note This function must not be called while the channel transfer is ongoing + * or it causes unpredictable results. + * note This function enables the auto stop request feature. + */ +void EDMA_ResetChannel(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + EDMA_TcdReset((edma_tcd_t *)&base->TCD[channel]); +} + +/*! + * brief Configures the eDMA transfer attribute. + * + * This function configures the transfer attribute, including source address, destination address, + * transfer size, address offset, and so on. It also configures the scatter gather feature if the + * user supplies the TCD address. + * Example: + * code + * edma_transfer_t config; + * edma_tcd_t tcd; + * config.srcAddr = ..; + * config.destAddr = ..; + * ... + * EDMA_SetTransferConfig(DMA0, channel, &config, &stcd); + * endcode + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * param config Pointer to eDMA transfer configuration structure. + * param nextTcd Point to TCD structure. It can be NULL if users + * do not want to enable scatter/gather feature. + * note If nextTcd is not NULL, it means scatter gather feature is enabled + * and DREQ bit is cleared in the previous transfer configuration, which + * is set in the eDMA_ResetChannel. + */ +void EDMA_SetTransferConfig(DMA_Type *base, uint32_t channel, const edma_transfer_config_t *config, edma_tcd_t *nextTcd) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + assert(config != NULL); + assert(((uint32_t)nextTcd & 0x1FU) == 0); + + EDMA_TcdSetTransferConfig((edma_tcd_t *)&base->TCD[channel], config, nextTcd); +} + +/*! + * brief Configures the eDMA minor offset feature. + * + * The minor offset means that the signed-extended value is added to the source address or destination + * address after each minor loop. + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * param config A pointer to the minor offset configuration structure. + */ +void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + assert(config != NULL); + + uint32_t tmpreg; + + tmpreg = base->TCD[channel].NBYTES_MLOFFYES; + tmpreg &= ~(DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK | DMA_NBYTES_MLOFFYES_MLOFF_MASK); + tmpreg |= + (DMA_NBYTES_MLOFFYES_SMLOE(config->enableSrcMinorOffset) | + DMA_NBYTES_MLOFFYES_DMLOE(config->enableDestMinorOffset) | DMA_NBYTES_MLOFFYES_MLOFF(config->minorOffset)); + base->TCD[channel].NBYTES_MLOFFYES = tmpreg; +} + +/*! + * brief Sets the channel link for the eDMA transfer. + * + * This function configures either the minor link or the major link mode. The minor link means that the channel link is + * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is + * exhausted. + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * param type A channel link type, which can be one of the following: + * arg kEDMA_LinkNone + * arg kEDMA_MinorLink + * arg kEDMA_MajorLink + * param linkedChannel The linked channel number. + * note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. + */ +void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + assert(linkedChannel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + EDMA_TcdSetChannelLink((edma_tcd_t *)&base->TCD[channel], type, linkedChannel); +} + +/*! + * brief Sets the bandwidth for the eDMA transfer. + * + * Because the eDMA processes the minor loop, it continuously generates read/write sequences + * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of + * each read/write access to control the bus request bandwidth seen by the crossbar switch. + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * param bandWidth A bandwidth setting, which can be one of the following: + * arg kEDMABandwidthStallNone + * arg kEDMABandwidthStall4Cycle + * arg kEDMABandwidthStall8Cycle + */ +void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + base->TCD[channel].CSR = (base->TCD[channel].CSR & (~DMA_CSR_BWC_MASK)) | DMA_CSR_BWC(bandWidth); +} + +/*! + * brief Sets the source modulo and the destination modulo for the eDMA transfer. + * + * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) + * calculation is performed or the original register value. It provides the ability to implement a circular data + * queue easily. + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * param srcModulo A source modulo value. + * param destModulo A destination modulo value. + */ +void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + uint32_t tmpreg; + + tmpreg = base->TCD[channel].ATTR & (~(DMA_ATTR_SMOD_MASK | DMA_ATTR_DMOD_MASK)); + base->TCD[channel].ATTR = tmpreg | DMA_ATTR_DMOD(destModulo) | DMA_ATTR_SMOD(srcModulo); +} + +/*! + * brief Enables the interrupt source for the eDMA transfer. + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * param mask The mask of interrupt source to be set. Users need to use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + /* Enable error interrupt */ + if (mask & kEDMA_ErrorInterruptEnable) + { + base->EEI |= (0x1U << channel); + } + + /* Enable Major interrupt */ + if (mask & kEDMA_MajorInterruptEnable) + { + base->TCD[channel].CSR |= DMA_CSR_INTMAJOR_MASK; + } + + /* Enable Half major interrupt */ + if (mask & kEDMA_HalfInterruptEnable) + { + base->TCD[channel].CSR |= DMA_CSR_INTHALF_MASK; + } +} + +/*! + * brief Disables the interrupt source for the eDMA transfer. + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * param mask The mask of the interrupt source to be set. Use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + /* Disable error interrupt */ + if (mask & kEDMA_ErrorInterruptEnable) + { + base->EEI &= ~(0x1U << channel); + } + + /* Disable Major interrupt */ + if (mask & kEDMA_MajorInterruptEnable) + { + base->TCD[channel].CSR &= ~DMA_CSR_INTMAJOR_MASK; + } + + /* Disable Half major interrupt */ + if (mask & kEDMA_HalfInterruptEnable) + { + base->TCD[channel].CSR &= ~DMA_CSR_INTHALF_MASK; + } +} + +/*! + * brief Sets all fields to default values for the TCD structure. + * + * This function sets all fields for this TCD structure to default value. + * + * param tcd Pointer to the TCD structure. + * note This function enables the auto stop request feature. + */ +void EDMA_TcdReset(edma_tcd_t *tcd) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + /* Reset channel TCD */ + tcd->SADDR = 0U; + tcd->SOFF = 0U; + tcd->ATTR = 0U; + tcd->NBYTES = 0U; + tcd->SLAST = 0U; + tcd->DADDR = 0U; + tcd->DOFF = 0U; + tcd->CITER = 0U; + tcd->DLAST_SGA = 0U; + /* Enable auto disable request feature */ + tcd->CSR = DMA_CSR_DREQ(true); + tcd->BITER = 0U; +} + +/*! + * brief Configures the eDMA TCD transfer attribute. + * + * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers. + * The STCD is used in the scatter-gather mode. + * This function configures the TCD transfer attribute, including source address, destination address, + * transfer size, address offset, and so on. It also configures the scatter gather feature if the + * user supplies the next TCD address. + * Example: + * code + * edma_transfer_t config = { + * ... + * } + * edma_tcd_t tcd __aligned(32); + * edma_tcd_t nextTcd __aligned(32); + * EDMA_TcdSetTransferConfig(&tcd, &config, &nextTcd); + * endcode + * + * param tcd Pointer to the TCD structure. + * param config Pointer to eDMA transfer configuration structure. + * param nextTcd Pointer to the next TCD structure. It can be NULL if users + * do not want to enable scatter/gather feature. + * note TCD address should be 32 bytes aligned or it causes an eDMA error. + * note If the nextTcd is not NULL, the scatter gather feature is enabled + * and DREQ bit is cleared in the previous transfer configuration, which + * is set in the EDMA_TcdReset. + */ +void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + assert(config != NULL); + assert(((uint32_t)nextTcd & 0x1FU) == 0); + + /* source address */ + tcd->SADDR = config->srcAddr; + /* destination address */ + tcd->DADDR = config->destAddr; + /* Source data and destination data transfer size */ + tcd->ATTR = DMA_ATTR_SSIZE(config->srcTransferSize) | DMA_ATTR_DSIZE(config->destTransferSize); + /* Source address signed offset */ + tcd->SOFF = config->srcOffset; + /* Destination address signed offset */ + tcd->DOFF = config->destOffset; + /* Minor byte transfer count */ + tcd->NBYTES = config->minorLoopBytes; + /* Current major iteration count */ + tcd->CITER = config->majorLoopCounts; + /* Starting major iteration count */ + tcd->BITER = config->majorLoopCounts; + /* Enable scatter/gather processing */ + if (nextTcd != NULL) + { + tcd->DLAST_SGA = (uint32_t)nextTcd; + /* + Before call EDMA_TcdSetTransferConfig or EDMA_SetTransferConfig, + user must call EDMA_TcdReset or EDMA_ResetChannel which will set + DREQ, so must use "|" or "&" rather than "=". + + Clear the DREQ bit because scatter gather has been enabled, so the + previous transfer is not the last transfer, and channel request should + be enabled at the next transfer(the next TCD). + */ + tcd->CSR = (tcd->CSR | DMA_CSR_ESG_MASK) & ~DMA_CSR_DREQ_MASK; + } +} + +/*! + * brief Configures the eDMA TCD minor offset feature. + * + * A minor offset is a signed-extended value added to the source address or a destination + * address after each minor loop. + * + * param tcd A point to the TCD structure. + * param config A pointer to the minor offset configuration structure. + */ +void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + uint32_t tmpreg; + + tmpreg = tcd->NBYTES & + ~(DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK | DMA_NBYTES_MLOFFYES_MLOFF_MASK); + tmpreg |= + (DMA_NBYTES_MLOFFYES_SMLOE(config->enableSrcMinorOffset) | + DMA_NBYTES_MLOFFYES_DMLOE(config->enableDestMinorOffset) | DMA_NBYTES_MLOFFYES_MLOFF(config->minorOffset)); + tcd->NBYTES = tmpreg; +} + +/*! + * brief Sets the channel link for the eDMA TCD. + * + * This function configures either a minor link or a major link. The minor link means the channel link is + * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is + * exhausted. + * + * note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. + * param tcd Point to the TCD structure. + * param type Channel link type, it can be one of: + * arg kEDMA_LinkNone + * arg kEDMA_MinorLink + * arg kEDMA_MajorLink + * param linkedChannel The linked channel number. + */ +void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint32_t linkedChannel) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + assert(linkedChannel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + if (type == kEDMA_MinorLink) /* Minor link config */ + { + uint32_t tmpreg; + + /* Enable minor link */ + tcd->CITER |= DMA_CITER_ELINKYES_ELINK_MASK; + tcd->BITER |= DMA_BITER_ELINKYES_ELINK_MASK; + /* Set linked channel */ + tmpreg = tcd->CITER & (~DMA_CITER_ELINKYES_LINKCH_MASK); + tmpreg |= DMA_CITER_ELINKYES_LINKCH(linkedChannel); + tcd->CITER = tmpreg; + tmpreg = tcd->BITER & (~DMA_BITER_ELINKYES_LINKCH_MASK); + tmpreg |= DMA_BITER_ELINKYES_LINKCH(linkedChannel); + tcd->BITER = tmpreg; + } + else if (type == kEDMA_MajorLink) /* Major link config */ + { + uint32_t tmpreg; + + /* Enable major link */ + tcd->CSR |= DMA_CSR_MAJORELINK_MASK; + /* Set major linked channel */ + tmpreg = tcd->CSR & (~DMA_CSR_MAJORLINKCH_MASK); + tcd->CSR = tmpreg | DMA_CSR_MAJORLINKCH(linkedChannel); + } + else /* Link none */ + { + tcd->CITER &= ~DMA_CITER_ELINKYES_ELINK_MASK; + tcd->BITER &= ~DMA_BITER_ELINKYES_ELINK_MASK; + tcd->CSR &= ~DMA_CSR_MAJORELINK_MASK; + } +} + +/*! + * brief Sets the source modulo and the destination modulo for the eDMA TCD. + * + * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) + * calculation is performed or the original register value. It provides the ability to implement a circular data + * queue easily. + * + * param tcd A pointer to the TCD structure. + * param srcModulo A source modulo value. + * param destModulo A destination modulo value. + */ +void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + uint32_t tmpreg; + + tmpreg = tcd->ATTR & (~(DMA_ATTR_SMOD_MASK | DMA_ATTR_DMOD_MASK)); + tcd->ATTR = tmpreg | DMA_ATTR_DMOD(destModulo) | DMA_ATTR_SMOD(srcModulo); +} + +/*! + * brief Enables the interrupt source for the eDMA TCD. + * + * param tcd Point to the TCD structure. + * param mask The mask of interrupt source to be set. Users need to use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask) +{ + assert(tcd != NULL); + + /* Enable Major interrupt */ + if (mask & kEDMA_MajorInterruptEnable) + { + tcd->CSR |= DMA_CSR_INTMAJOR_MASK; + } + + /* Enable Half major interrupt */ + if (mask & kEDMA_HalfInterruptEnable) + { + tcd->CSR |= DMA_CSR_INTHALF_MASK; + } +} + +/*! + * brief Disables the interrupt source for the eDMA TCD. + * + * param tcd Point to the TCD structure. + * param mask The mask of interrupt source to be set. Users need to use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask) +{ + assert(tcd != NULL); + + /* Disable Major interrupt */ + if (mask & kEDMA_MajorInterruptEnable) + { + tcd->CSR &= ~DMA_CSR_INTMAJOR_MASK; + } + + /* Disable Half major interrupt */ + if (mask & kEDMA_HalfInterruptEnable) + { + tcd->CSR &= ~DMA_CSR_INTHALF_MASK; + } +} + +/*! + * brief Gets the remaining major loop count from the eDMA current channel TCD. + * + * This function checks the TCD (Task Control Descriptor) status for a specified + * eDMA channel and returns the number of major loop count that has not finished. + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * return Major loop count which has not been transferred yet for the current TCD. + * note 1. This function can only be used to get unfinished major loop count of transfer without + * the next TCD, or it might be inaccuracy. + * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while + * the channel is running. + * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO + * register is needed while the eDMA IP does not support getting it while a channel is active. + * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine + * is working with while a channel is running. + * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example + * copied before enabling the channel) is needed. The formula to calculate it is shown below: + * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured) + */ +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + uint32_t remainingCount = 0; + + if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) + { + remainingCount = 0; + } + else + { + /* Calculate the unfinished bytes */ + if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) + { + remainingCount = + (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT; + } + else + { + remainingCount = + (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT; + } + } + + return remainingCount; +} + +/*! + * brief Gets the eDMA channel status flags. + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * return The mask of channel status flags. Users need to use the + * _edma_channel_status_flags type to decode the return variables. + */ +uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + uint32_t retval = 0; + + /* Get DONE bit flag */ + retval |= ((base->TCD[channel].CSR & DMA_CSR_DONE_MASK) >> DMA_CSR_DONE_SHIFT); + /* Get ERROR bit flag */ + retval |= (((base->ERR >> channel) & 0x1U) << 1U); + /* Get INT bit flag */ + retval |= (((base->INT >> channel) & 0x1U) << 2U); + + return retval; +} + +/*! + * brief Clears the eDMA channel status flags. + * + * param base eDMA peripheral base address. + * param channel eDMA channel number. + * param mask The mask of channel status to be cleared. Users need to use + * the defined _edma_channel_status_flags type. + */ +void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + /* Clear DONE bit flag */ + if (mask & kEDMA_DoneFlag) + { + base->CDNE = channel; + } + /* Clear ERROR bit flag */ + if (mask & kEDMA_ErrorFlag) + { + base->CERR = channel; + } + /* Clear INT bit flag */ + if (mask & kEDMA_InterruptFlag) + { + base->CINT = channel; + } +} + +static uint8_t Get_StartInstance(void) +{ + static uint8_t StartInstanceNum; + +#if defined(DMA0) + StartInstanceNum = EDMA_GetInstance(DMA0); +#elif defined(DMA1) + StartInstanceNum = EDMA_GetInstance(DMA1); +#elif defined(DMA2) + StartInstanceNum = EDMA_GetInstance(DMA2); +#elif defined(DMA3) + StartInstanceNum = EDMA_GetInstance(DMA3); +#endif + + return StartInstanceNum; +} + +/*! + * brief Creates the eDMA handle. + * + * This function is called if using the transactional API for eDMA. This function + * initializes the internal state of the eDMA handle. + * + * param handle eDMA handle pointer. The eDMA handle stores callback function and + * parameters. + * param base eDMA peripheral base address. + * param channel eDMA channel number. + */ +void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel) +{ + assert(handle != NULL); + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + + uint32_t edmaInstance; + uint32_t channelIndex; + uint8_t StartInstance; + edma_tcd_t *tcdRegs; + + /* Zero the handle */ + memset(handle, 0, sizeof(*handle)); + + handle->base = base; + handle->channel = channel; + /* Get the DMA instance number */ + edmaInstance = EDMA_GetInstance(base); + StartInstance = Get_StartInstance(); + channelIndex = ((edmaInstance - StartInstance) * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; + s_EDMAHandle[channelIndex] = handle; + + /* Enable NVIC interrupt */ + EnableIRQ(s_edmaIRQNumber[edmaInstance][channel]); + + /* + Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set), + CSR will be 0. Because in order to suit EDMA busy check mechanism in + EDMA_SubmitTransfer, CSR must be set 0. + */ + tcdRegs = (edma_tcd_t *)&handle->base->TCD[handle->channel]; + tcdRegs->SADDR = 0; + tcdRegs->SOFF = 0; + tcdRegs->ATTR = 0; + tcdRegs->NBYTES = 0; + tcdRegs->SLAST = 0; + tcdRegs->DADDR = 0; + tcdRegs->DOFF = 0; + tcdRegs->CITER = 0; + tcdRegs->DLAST_SGA = 0; + tcdRegs->CSR = 0; + tcdRegs->BITER = 0; +} + +/*! + * brief Installs the TCDs memory pool into the eDMA handle. + * + * This function is called after the EDMA_CreateHandle to use scatter/gather feature. This function shall only be used + * while users need to use scatter gather mode. Scatter gather mode enables EDMA to load a new transfer control block + * (tcd) in hardware, and automatically reconfigure that DMA channel for a new transfer. + * Users need to prepare tcd memory and also configure tcds using interface EDMA_SubmitTransfer. + * + * param handle eDMA handle pointer. + * param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned. + * param tcdSize The number of TCD slots. + */ +void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize) +{ + assert(handle != NULL); + assert(((uint32_t)tcdPool & 0x1FU) == 0); + + /* Initialize tcd queue attribute. */ + handle->header = 0; + handle->tail = 0; + handle->tcdUsed = 0; + handle->tcdSize = tcdSize; + handle->flags = 0; + handle->tcdPool = tcdPool; +} + +/*! + * brief Installs a callback function for the eDMA transfer. + * + * This callback is called in the eDMA IRQ handler. Use the callback to do something after + * the current major loop transfer completes. This function will be called every time one tcd finished transfer. + * + * param handle eDMA handle pointer. + * param callback eDMA callback function pointer. + * param userData A parameter for the callback function. + */ +void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData) +{ + assert(handle != NULL); + + handle->callback = callback; + handle->userData = userData; +} + +/*! + * brief Prepares the eDMA transfer structure. + * + * This function prepares the transfer configuration structure according to the user input. + * + * param config The user configuration structure of type edma_transfer_t. + * param srcAddr eDMA transfer source address. + * param srcWidth eDMA transfer source address width(bytes). + * param destAddr eDMA transfer destination address. + * param destWidth eDMA transfer destination address width(bytes). + * param bytesEachRequest eDMA transfer bytes per channel request. + * param transferBytes eDMA transfer bytes to be transferred. + * param type eDMA transfer type. + * note The data address and the data width must be consistent. For example, if the SRC + * is 4 bytes, the source address must be 4 bytes aligned, or it results in + * source address error (SAE). + */ +void EDMA_PrepareTransfer(edma_transfer_config_t *config, + void *srcAddr, + uint32_t srcWidth, + void *destAddr, + uint32_t destWidth, + uint32_t bytesEachRequest, + uint32_t transferBytes, + edma_transfer_type_t type) +{ + assert(config != NULL); + assert(srcAddr != NULL); + assert(destAddr != NULL); + assert((srcWidth == 1U) || (srcWidth == 2U) || (srcWidth == 4U) || (srcWidth == 16U) || (srcWidth == 32U)); + assert((destWidth == 1U) || (destWidth == 2U) || (destWidth == 4U) || (destWidth == 16U) || (destWidth == 32U)); + assert(transferBytes % bytesEachRequest == 0); + + /* Initializes the configure structure to zero. */ + memset(config, 0, sizeof(*config)); + + config->destAddr = (uint32_t)destAddr; + config->srcAddr = (uint32_t)srcAddr; + config->minorLoopBytes = bytesEachRequest; + config->majorLoopCounts = transferBytes / bytesEachRequest; + switch (srcWidth) + { + case 1U: + config->srcTransferSize = kEDMA_TransferSize1Bytes; + break; + case 2U: + config->srcTransferSize = kEDMA_TransferSize2Bytes; + break; + case 4U: + config->srcTransferSize = kEDMA_TransferSize4Bytes; + break; + case 16U: + config->srcTransferSize = kEDMA_TransferSize16Bytes; + break; + case 32U: + config->srcTransferSize = kEDMA_TransferSize32Bytes; + break; + default: + break; + } + switch (destWidth) + { + case 1U: + config->destTransferSize = kEDMA_TransferSize1Bytes; + break; + case 2U: + config->destTransferSize = kEDMA_TransferSize2Bytes; + break; + case 4U: + config->destTransferSize = kEDMA_TransferSize4Bytes; + break; + case 16U: + config->destTransferSize = kEDMA_TransferSize16Bytes; + break; + case 32U: + config->destTransferSize = kEDMA_TransferSize32Bytes; + break; + default: + break; + } + switch (type) + { + case kEDMA_MemoryToMemory: + config->destOffset = destWidth; + config->srcOffset = srcWidth; + break; + case kEDMA_MemoryToPeripheral: + config->destOffset = 0U; + config->srcOffset = srcWidth; + break; + case kEDMA_PeripheralToMemory: + config->destOffset = destWidth; + config->srcOffset = 0U; + break; + default: + break; + } +} + +/*! + * brief Submits the eDMA transfer request. + * + * This function submits the eDMA transfer request according to the transfer configuration structure. + * In scatter gather mode, call this function will add a configured tcd to the circular list of tcd pool. + * The tcd pools is setup by call function EDMA_InstallTCDMemory before. + * + * param handle eDMA handle pointer. + * param config Pointer to eDMA transfer configuration structure. + * retval kStatus_EDMA_Success It means submit transfer request succeed. + * retval kStatus_EDMA_QueueFull It means TCD queue is full. Submit transfer request is not allowed. + * retval kStatus_EDMA_Busy It means the given channel is busy, need to submit request later. + */ +status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config) +{ + assert(handle != NULL); + assert(config != NULL); + + edma_tcd_t *tcdRegs = (edma_tcd_t *)&handle->base->TCD[handle->channel]; + + if (handle->tcdPool == NULL) + { + /* + Check if EDMA is busy: if the given channel started transfer, CSR will be not zero. Because + if it is the last transfer, DREQ will be set. If not, ESG will be set. So in order to suit + this check mechanism, EDMA_CreatHandle will clear CSR register. + */ + if ((tcdRegs->CSR != 0) && ((tcdRegs->CSR & DMA_CSR_DONE_MASK) == 0)) + { + return kStatus_EDMA_Busy; + } + else + { + EDMA_SetTransferConfig(handle->base, handle->channel, config, NULL); + /* Enable auto disable request feature */ + handle->base->TCD[handle->channel].CSR |= DMA_CSR_DREQ_MASK; + /* Enable major interrupt */ + handle->base->TCD[handle->channel].CSR |= DMA_CSR_INTMAJOR_MASK; + + return kStatus_Success; + } + } + else /* Use the TCD queue. */ + { + uint32_t primask; + uint32_t csr; + int8_t currentTcd; + int8_t previousTcd; + int8_t nextTcd; + + /* Check if tcd pool is full. */ + primask = DisableGlobalIRQ(); + if (handle->tcdUsed >= handle->tcdSize) + { + EnableGlobalIRQ(primask); + + return kStatus_EDMA_QueueFull; + } + currentTcd = handle->tail; + handle->tcdUsed++; + /* Calculate index of next TCD */ + nextTcd = currentTcd + 1U; + if (nextTcd == handle->tcdSize) + { + nextTcd = 0U; + } + /* Advance queue tail index */ + handle->tail = nextTcd; + EnableGlobalIRQ(primask); + /* Calculate index of previous TCD */ + previousTcd = currentTcd ? currentTcd - 1U : handle->tcdSize - 1U; + /* Configure current TCD block. */ + EDMA_TcdReset(&handle->tcdPool[currentTcd]); + EDMA_TcdSetTransferConfig(&handle->tcdPool[currentTcd], config, NULL); + /* Enable major interrupt */ + handle->tcdPool[currentTcd].CSR |= DMA_CSR_INTMAJOR_MASK; + /* Link current TCD with next TCD for identification of current TCD */ + handle->tcdPool[currentTcd].DLAST_SGA = (uint32_t)&handle->tcdPool[nextTcd]; + /* Chain from previous descriptor unless tcd pool size is 1(this descriptor is its own predecessor). */ + if (currentTcd != previousTcd) + { + /* Enable scatter/gather feature in the previous TCD block. */ + csr = (handle->tcdPool[previousTcd].CSR | DMA_CSR_ESG_MASK) & ~DMA_CSR_DREQ_MASK; + handle->tcdPool[previousTcd].CSR = csr; + /* + Check if the TCD block in the registers is the previous one (points to current TCD block). It + is used to check if the previous TCD linked has been loaded in TCD register. If so, it need to + link the TCD register in case link the current TCD with the dead chain when TCD loading occurs + before link the previous TCD block. + */ + if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[currentTcd]) + { + /* Clear the DREQ bits for the dynamic scatter gather */ + tcdRegs->CSR |= DMA_CSR_DREQ_MASK; + /* Enable scatter/gather also in the TCD registers. */ + csr = tcdRegs->CSR | DMA_CSR_ESG_MASK; + /* Must write the CSR register one-time, because the transfer maybe finished anytime. */ + tcdRegs->CSR = csr; + /* + It is very important to check the ESG bit! + Because this hardware design: if DONE bit is set, the ESG bit can not be set. So it can + be used to check if the dynamic TCD link operation is successful. If ESG bit is not set + and the DLAST_SGA is not the next TCD address(it means the dynamic TCD link succeed and + the current TCD block has been loaded into TCD registers), it means transfer finished + and TCD link operation fail, so must install TCD content into TCD registers and enable + transfer again. And if ESG is set, it means transfer has not finished, so TCD dynamic + link succeed. + */ + if (tcdRegs->CSR & DMA_CSR_ESG_MASK) + { + tcdRegs->CSR &= ~DMA_CSR_DREQ_MASK; + return kStatus_Success; + } + /* + Check whether the current TCD block is already loaded in the TCD registers. It is another + condition when ESG bit is not set: it means the dynamic TCD link succeed and the current + TCD block has been loaded into TCD registers. + */ + if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[nextTcd]) + { + return kStatus_Success; + } + /* + If go to this, means the previous transfer finished, and the DONE bit is set. + So shall configure TCD registers. + */ + } + else if (tcdRegs->DLAST_SGA != 0) + { + /* The current TCD block has been linked successfully. */ + return kStatus_Success; + } + else + { + /* + DLAST_SGA is 0 and it means the first submit transfer, so shall configure + TCD registers. + */ + } + } + /* There is no live chain, TCD block need to be installed in TCD registers. */ + EDMA_InstallTCD(handle->base, handle->channel, &handle->tcdPool[currentTcd]); + /* Enable channel request again. */ + if (handle->flags & EDMA_TRANSFER_ENABLED_MASK) + { + handle->base->SERQ = DMA_SERQ_SERQ(handle->channel); + } + + return kStatus_Success; + } +} + +/*! + * brief eDMA starts transfer. + * + * This function enables the channel request. Users can call this function after submitting the transfer request + * or before submitting the transfer request. + * + * param handle eDMA handle pointer. + */ +void EDMA_StartTransfer(edma_handle_t *handle) +{ + assert(handle != NULL); + + if (handle->tcdPool == NULL) + { + handle->base->SERQ = DMA_SERQ_SERQ(handle->channel); + } + else /* Use the TCD queue. */ + { + uint32_t primask; + edma_tcd_t *tcdRegs = (edma_tcd_t *)&handle->base->TCD[handle->channel]; + + handle->flags |= EDMA_TRANSFER_ENABLED_MASK; + + /* Check if there was at least one descriptor submitted since reset (TCD in registers is valid) */ + if (tcdRegs->DLAST_SGA != 0U) + { + primask = DisableGlobalIRQ(); + /* Check if channel request is actually disable. */ + if ((handle->base->ERQ & (1U << handle->channel)) == 0U) + { + /* Check if transfer is paused. */ + if ((!(tcdRegs->CSR & DMA_CSR_DONE_MASK)) || (tcdRegs->CSR & DMA_CSR_ESG_MASK)) + { + /* + Re-enable channel request must be as soon as possible, so must put it into + critical section to avoid task switching or interrupt service routine. + */ + handle->base->SERQ = DMA_SERQ_SERQ(handle->channel); + } + } + EnableGlobalIRQ(primask); + } + } +} + +/*! + * brief eDMA stops transfer. + * + * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer() + * again to resume the transfer. + * + * param handle eDMA handle pointer. + */ +void EDMA_StopTransfer(edma_handle_t *handle) +{ + assert(handle != NULL); + + handle->flags &= (~EDMA_TRANSFER_ENABLED_MASK); + handle->base->CERQ = DMA_CERQ_CERQ(handle->channel); +} + +/*! + * brief eDMA aborts transfer. + * + * This function disables the channel request and clear transfer status bits. + * Users can submit another transfer after calling this API. + * + * param handle DMA handle pointer. + */ +void EDMA_AbortTransfer(edma_handle_t *handle) +{ + handle->base->CERQ = DMA_CERQ_CERQ(handle->channel); + /* + Clear CSR to release channel. Because if the given channel started transfer, + CSR will be not zero. Because if it is the last transfer, DREQ will be set. + If not, ESG will be set. + */ + handle->base->TCD[handle->channel].CSR = 0; + /* Cancel all next TCD transfer. */ + handle->base->TCD[handle->channel].DLAST_SGA = 0; + + /* Handle the tcd */ + if (handle->tcdPool != NULL) + { + handle->header = 0; + handle->tail = 0; + handle->tcdUsed = 0; + } +} + +/*! + * brief eDMA IRQ handler for the current major loop transfer completion. + * + * This function clears the channel major interrupt flag and calls + * the callback function if it is not NULL. + * + * Note: + * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed. + * These include the final address adjustments and reloading of the BITER field into the CITER. + * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from + * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled). + * + * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine. + * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index + * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be + * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have + * been loaded into the eDMA engine at this point already.). + * + * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not + * load a new TCD) from the memory pool to the eDMA engine when major loop completes. + * Therefore, ensure that the header and tcdUsed updated are identical for them. + * tcdUsed are both 0 in this case as no TCD to be loaded. + * + * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for + * further details. + * + * param handle eDMA handle pointer. + */ +void EDMA_HandleIRQ(edma_handle_t *handle) +{ + assert(handle != NULL); + + /* Clear EDMA interrupt flag */ + handle->base->CINT = handle->channel; + if ((handle->tcdPool == NULL) && (handle->callback != NULL)) + { + (handle->callback)(handle, handle->userData, true, 0); + } + else /* Use the TCD queue. Please refer to the API descriptions in the eDMA header file for detailed information. */ + { + uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA; + uint32_t sga_index; + int32_t tcds_done; + uint8_t new_header; + bool transfer_done; + + /* Check if transfer is already finished. */ + transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); + /* Get the offset of the next transfer TCD blocks to be loaded into the eDMA engine. */ + sga -= (uint32_t)handle->tcdPool; + /* Get the index of the next transfer TCD blocks to be loaded into the eDMA engine. */ + sga_index = sga / sizeof(edma_tcd_t); + /* Adjust header positions. */ + if (transfer_done) + { + /* New header shall point to the next TCD to be loaded (current one is already finished) */ + new_header = sga_index; + } + else + { + /* New header shall point to this descriptor currently loaded (not finished yet) */ + new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U; + } + /* Calculate the number of finished TCDs */ + if (new_header == handle->header) + { + if (handle->tcdUsed == handle->tcdSize) + { + tcds_done = handle->tcdUsed; + } + else + { + /* No TCD in the memory are going to be loaded or internal error occurs. */ + tcds_done = 0; + } + } + else + { + tcds_done = new_header - handle->header; + if (tcds_done < 0) + { + tcds_done += handle->tcdSize; + } + } + /* Advance header which points to the TCD to be loaded into the eDMA engine from memory. */ + handle->header = new_header; + /* Release TCD blocks. tcdUsed is the TCD number which can be used/loaded in the memory pool. */ + handle->tcdUsed -= tcds_done; + /* Invoke callback function. */ + if (handle->callback) + { + (handle->callback)(handle, handle->userData, transfer_done, tcds_done); + } + + /* clear the DONE bit here is meaningful for below cases: + *1.A new TCD has been loaded to EDMA already: + * need to clear the DONE bit in the IRQ handler to avoid TCD in EDMA been overwritten + * if peripheral request isn't coming before next transfer request. + *2.A new TCD has not been loaded to EDMA: + * for the case that transfer request occur in the privious edma callback, this is a case that doesn't + * need scatter gather, so keep DONE bit during the next transfer request will re-install the TCD. + */ + if (transfer_done) + { + handle->base->CDNE = handle->channel; + } + } +} + +/* 8 channels (Shared): kl28 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 8U + +#if defined(DMA0) +void DMA0_04_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_37_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(DMA1) + +#if defined(DMA0) +void DMA1_04_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_37_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +#else +void DMA1_04_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_37_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif +#endif /* 8 channels (Shared) */ + +/* 16 channels (Shared): K32H844P */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 16U + +void DMA0_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +#if defined(DMA1) +void DMA1_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif /* 16 channels (Shared) */ + +/* 32 channels (Shared): k80 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U + +void DMA0_DMA16_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_DMA17_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA2_DMA18_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA3_DMA19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA4_DMA20_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA5_DMA21_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA6_DMA22_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA7_DMA23_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA8_DMA24_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA9_DMA25_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA10_DMA26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA11_DMA27_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA12_DMA28_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA13_DMA29_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA14_DMA30_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA15_DMA31_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif /* 32 channels (Shared) */ + +/* 32 channels (Shared): MCIMX7U5_M4 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U + +void DMA0_0_4_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_1_5_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_2_6_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_3_7_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_8_12_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_9_13_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_10_14_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_11_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_16_20_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_17_21_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_18_22_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_19_23_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_24_28_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_25_29_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_26_30_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA0_27_31_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif /* 32 channels (Shared): MCIMX7U5 */ + +/* 4 channels (No Shared): kv10 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 + +void DMA0_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[0]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA1_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[1]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA2_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[2]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA3_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[3]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +/* 8 channels (No Shared) */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 4U + +void DMA4_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[4]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA5_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[5]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA6_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[6]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA7_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[7]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 8 */ + +/* 16 channels (No Shared) */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 8U + +void DMA8_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[8]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA9_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[9]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA10_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[10]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA11_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[11]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA12_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[12]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA13_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[13]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA14_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[14]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA15_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[15]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 16 */ + +/* 32 channels (No Shared) */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 16U + +void DMA16_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[16]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA17_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[17]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA18_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[18]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA19_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[19]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA20_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[20]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA21_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[21]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA22_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[22]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA23_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[23]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA24_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[24]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA25_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[25]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA26_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[26]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA27_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[27]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA28_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[28]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA29_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[29]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA30_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[30]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +void DMA31_DriverIRQHandler(void) +{ + EDMA_HandleIRQ(s_EDMAHandle[31]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 32 */ + +#endif /* 4/8/16/32 channels (No Shared) */ diff --git a/targets/FreeRTOS/GC5/common/drivers/fsl_edma.h b/targets/FreeRTOS/GC5/common/drivers/fsl_edma.h new file mode 100644 index 0000000000..802f130359 --- /dev/null +++ b/targets/FreeRTOS/GC5/common/drivers/fsl_edma.h @@ -0,0 +1,931 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2018 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _FSL_EDMA_H_ +#define _FSL_EDMA_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup edma + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief eDMA driver version */ +#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 1, 4)) /*!< Version 2.1.4. */ +/*@}*/ + +/*! @brief Compute the offset unit from DCHPRI3 */ +#define DMA_DCHPRI_INDEX(channel) (((channel) & ~0x03U) | (3 - ((channel)&0x03U))) + +/*! @brief Get the pointer of DCHPRIn */ +#define DMA_DCHPRIn(base, channel) ((volatile uint8_t *)&((base)->DCHPRI3))[DMA_DCHPRI_INDEX(channel)] + +/*! @brief eDMA transfer configuration */ +typedef enum _edma_transfer_size +{ + kEDMA_TransferSize1Bytes = 0x0U, /*!< Source/Destination data transfer size is 1 byte every time */ + kEDMA_TransferSize2Bytes = 0x1U, /*!< Source/Destination data transfer size is 2 bytes every time */ + kEDMA_TransferSize4Bytes = 0x2U, /*!< Source/Destination data transfer size is 4 bytes every time */ + kEDMA_TransferSize8Bytes = 0x3U, /*!< Source/Destination data transfer size is 8 bytes every time */ + kEDMA_TransferSize16Bytes = 0x4U, /*!< Source/Destination data transfer size is 16 bytes every time */ + kEDMA_TransferSize32Bytes = 0x5U, /*!< Source/Destination data transfer size is 32 bytes every time */ +} edma_transfer_size_t; + +/*! @brief eDMA modulo configuration */ +typedef enum _edma_modulo +{ + kEDMA_ModuloDisable = 0x0U, /*!< Disable modulo */ + kEDMA_Modulo2bytes, /*!< Circular buffer size is 2 bytes. */ + kEDMA_Modulo4bytes, /*!< Circular buffer size is 4 bytes. */ + kEDMA_Modulo8bytes, /*!< Circular buffer size is 8 bytes. */ + kEDMA_Modulo16bytes, /*!< Circular buffer size is 16 bytes. */ + kEDMA_Modulo32bytes, /*!< Circular buffer size is 32 bytes. */ + kEDMA_Modulo64bytes, /*!< Circular buffer size is 64 bytes. */ + kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */ + kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */ + kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */ + kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */ + kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */ + kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */ + kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */ + kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */ + kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */ + kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */ + kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */ + kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */ + kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */ + kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */ + kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */ + kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */ + kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */ + kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */ + kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */ + kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */ + kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */ + kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */ + kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */ + kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */ + kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */ +} edma_modulo_t; + +/*! @brief Bandwidth control */ +typedef enum _edma_bandwidth +{ + kEDMA_BandwidthStallNone = 0x0U, /*!< No eDMA engine stalls. */ + kEDMA_BandwidthStall4Cycle = 0x2U, /*!< eDMA engine stalls for 4 cycles after each read/write. */ + kEDMA_BandwidthStall8Cycle = 0x3U, /*!< eDMA engine stalls for 8 cycles after each read/write. */ +} edma_bandwidth_t; + +/*! @brief Channel link type */ +typedef enum _edma_channel_link_type +{ + kEDMA_LinkNone = 0x0U, /*!< No channel link */ + kEDMA_MinorLink, /*!< Channel link after each minor loop */ + kEDMA_MajorLink, /*!< Channel link while major loop count exhausted */ +} edma_channel_link_type_t; + +/*!@brief eDMA channel status flags. */ +enum _edma_channel_status_flags +{ + kEDMA_DoneFlag = 0x1U, /*!< DONE flag, set while transfer finished, CITER value exhausted*/ + kEDMA_ErrorFlag = 0x2U, /*!< eDMA error flag, an error occurred in a transfer */ + kEDMA_InterruptFlag = 0x4U, /*!< eDMA interrupt flag, set while an interrupt occurred of this channel */ +}; + +/*! @brief eDMA channel error status flags. */ +enum _edma_error_status_flags +{ + kEDMA_DestinationBusErrorFlag = DMA_ES_DBE_MASK, /*!< Bus error on destination address */ + kEDMA_SourceBusErrorFlag = DMA_ES_SBE_MASK, /*!< Bus error on the source address */ + kEDMA_ScatterGatherErrorFlag = DMA_ES_SGE_MASK, /*!< Error on the Scatter/Gather address, not 32byte aligned. */ + kEDMA_NbytesErrorFlag = DMA_ES_NCE_MASK, /*!< NBYTES/CITER configuration error */ + kEDMA_DestinationOffsetErrorFlag = DMA_ES_DOE_MASK, /*!< Destination offset not aligned with destination size */ + kEDMA_DestinationAddressErrorFlag = DMA_ES_DAE_MASK, /*!< Destination address not aligned with destination size */ + kEDMA_SourceOffsetErrorFlag = DMA_ES_SOE_MASK, /*!< Source offset not aligned with source size */ + kEDMA_SourceAddressErrorFlag = DMA_ES_SAE_MASK, /*!< Source address not aligned with source size*/ + kEDMA_ErrorChannelFlag = DMA_ES_ERRCHN_MASK, /*!< Error channel number of the cancelled channel number */ + kEDMA_ChannelPriorityErrorFlag = DMA_ES_CPE_MASK, /*!< Channel priority is not unique. */ + kEDMA_TransferCanceledFlag = DMA_ES_ECX_MASK, /*!< Transfer cancelled */ +#if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1 + kEDMA_GroupPriorityErrorFlag = DMA_ES_GPE_MASK, /*!< Group priority is not unique. */ +#endif + kEDMA_ValidFlag = (int)DMA_ES_VLD_MASK, /*!< No error occurred, this bit is 0. Otherwise, it is 1. */ +}; + +/*! @brief eDMA interrupt source */ +typedef enum _edma_interrupt_enable +{ + kEDMA_ErrorInterruptEnable = 0x1U, /*!< Enable interrupt while channel error occurs. */ + kEDMA_MajorInterruptEnable = DMA_CSR_INTMAJOR_MASK, /*!< Enable interrupt while major count exhausted. */ + kEDMA_HalfInterruptEnable = DMA_CSR_INTHALF_MASK, /*!< Enable interrupt while major count to half value. */ +} edma_interrupt_enable_t; + +/*! @brief eDMA transfer type */ +typedef enum _edma_transfer_type +{ + kEDMA_MemoryToMemory = 0x0U, /*!< Transfer from memory to memory */ + kEDMA_PeripheralToMemory, /*!< Transfer from peripheral to memory */ + kEDMA_MemoryToPeripheral, /*!< Transfer from memory to peripheral */ +} edma_transfer_type_t; + +/*! @brief eDMA transfer status */ +enum _edma_transfer_status +{ + kStatus_EDMA_QueueFull = MAKE_STATUS(kStatusGroup_EDMA, 0), /*!< TCD queue is full. */ + kStatus_EDMA_Busy = MAKE_STATUS(kStatusGroup_EDMA, 1), /*!< Channel is busy and can't handle the + transfer request. */ +}; + +/*! @brief eDMA global configuration structure.*/ +typedef struct _edma_config +{ + bool enableContinuousLinkMode; /*!< Enable (true) continuous link mode. Upon minor loop completion, the channel + activates again if that channel has a minor loop channel link enabled and + the link channel is itself. */ + bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. + Subsequently, all service requests are ignored until the HALT bit is cleared.*/ + bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority + arbitration is used for channel selection */ + bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of + a new channel. Executing channels are allowed to complete. */ +} edma_config_t; + +/*! + * @brief eDMA transfer configuration + * + * This structure configures the source/destination transfer attribute. + */ +typedef struct _edma_transfer_config +{ + uint32_t srcAddr; /*!< Source data address. */ + uint32_t destAddr; /*!< Destination data address. */ + edma_transfer_size_t srcTransferSize; /*!< Source data transfer size. */ + edma_transfer_size_t destTransferSize; /*!< Destination data transfer size. */ + int16_t srcOffset; /*!< Sign-extended offset applied to the current source address to + form the next-state value as each source read is completed. */ + int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to + form the next-state value as each destination write is completed. */ + uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ + uint32_t majorLoopCounts; /*!< Major loop iteration count. */ +} edma_transfer_config_t; + +/*! @brief eDMA channel priority configuration */ +typedef struct _edma_channel_Preemption_config +{ + bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */ + bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */ + uint8_t channelPriority; /*!< Channel priority */ +} edma_channel_Preemption_config_t; + +/*! @brief eDMA minor offset configuration */ +typedef struct _edma_minor_offset_config +{ + bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */ + bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */ + uint32_t minorOffset; /*!< Offset for a minor loop mapping. */ +} edma_minor_offset_config_t; + +/*! + * @brief eDMA TCD. + * + * This structure is same as TCD register which is described in reference manual, + * and is used to configure the scatter/gather feature as a next hardware TCD. + */ +typedef struct _edma_tcd +{ + __IO uint32_t SADDR; /*!< SADDR register, used to save source address */ + __IO uint16_t SOFF; /*!< SOFF register, save offset bytes every transfer */ + __IO uint16_t ATTR; /*!< ATTR register, source/destination transfer size and modulo */ + __IO uint32_t NBYTES; /*!< Nbytes register, minor loop length in bytes */ + __IO uint32_t SLAST; /*!< SLAST register */ + __IO uint32_t DADDR; /*!< DADDR register, used for destination address */ + __IO uint16_t DOFF; /*!< DOFF register, used for destination offset */ + __IO uint16_t CITER; /*!< CITER register, current minor loop numbers, for unfinished minor loop.*/ + __IO uint32_t DLAST_SGA; /*!< DLASTSGA register, next tcd address used in scatter-gather mode */ + __IO uint16_t CSR; /*!< CSR register, for TCD control status */ + __IO uint16_t BITER; /*!< BITER register, begin minor loop count. */ +} edma_tcd_t; + +/*! @brief Callback for eDMA */ +struct _edma_handle; + +/*! @brief Define callback function for eDMA. + * + * This callback function is called in the EDMA interrupt handle. + * In normal mode, run into callback function means the transfer users need is done. + * In scatter gather mode, run into callback function means a transfer control block (tcd) is finished. Not + * all transfer finished, users can get the finished tcd numbers using interface EDMA_GetUnusedTCDNumber. + * + * @param handle EDMA handle pointer, users shall not touch the values inside. + * @param userData The callback user parameter pointer. Users can use this parameter to involve things users need to + * change in EDMA callback function. + * @param transferDone If the current loaded transfer done. In normal mode it means if all transfer done. In scatter + * gather mode, this parameter shows is the current transfer block in EDMA register is done. As the + * load of core is different, it will be different if the new tcd loaded into EDMA registers while + * this callback called. If true, it always means new tcd still not loaded into registers, while + * false means new tcd already loaded into registers. + * @param tcds How many tcds are done from the last callback. This parameter only used in scatter gather mode. It + * tells user how many tcds are finished between the last callback and this. + */ +typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds); + +/*! @brief eDMA transfer handle structure */ +typedef struct _edma_handle +{ + edma_callback callback; /*!< Callback function for major count exhausted. */ + void *userData; /*!< Callback function parameter. */ + DMA_Type *base; /*!< eDMA peripheral base address. */ + edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ + uint8_t channel; /*!< eDMA channel number. */ + volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */ + volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */ + volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in + the memory. */ + volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */ + uint8_t flags; /*!< The status of the current channel. */ +} edma_handle_t; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name eDMA initialization and de-initialization + * @{ + */ + +/*! + * @brief Initializes the eDMA peripheral. + * + * This function ungates the eDMA clock and configures the eDMA peripheral according + * to the configuration structure. + * + * @param base eDMA peripheral base address. + * @param config A pointer to the configuration structure, see "edma_config_t". + * @note This function enables the minor loop map feature. + */ +void EDMA_Init(DMA_Type *base, const edma_config_t *config); + +/*! + * @brief Deinitializes the eDMA peripheral. + * + * This function gates the eDMA clock. + * + * @param base eDMA peripheral base address. + */ +void EDMA_Deinit(DMA_Type *base); + +/*! + * @brief Push content of TCD structure into hardware TCD register. + * + * @param base EDMA peripheral base address. + * @param channel EDMA channel number. + * @param tcd Point to TCD structure. + */ +void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd); + +/*! + * @brief Gets the eDMA default configuration structure. + * + * This function sets the configuration structure to default values. + * The default configuration is set to the following values. + * @code + * config.enableContinuousLinkMode = false; + * config.enableHaltOnError = true; + * config.enableRoundRobinArbitration = false; + * config.enableDebugMode = false; + * @endcode + * + * @param config A pointer to the eDMA configuration structure. + */ +void EDMA_GetDefaultConfig(edma_config_t *config); + +/* @} */ +/*! + * @name eDMA Channel Operation + * @{ + */ + +/*! + * @brief Sets all TCD registers to default values. + * + * This function sets TCD registers for this channel to default values. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @note This function must not be called while the channel transfer is ongoing + * or it causes unpredictable results. + * @note This function enables the auto stop request feature. + */ +void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); + +/*! + * @brief Configures the eDMA transfer attribute. + * + * This function configures the transfer attribute, including source address, destination address, + * transfer size, address offset, and so on. It also configures the scatter gather feature if the + * user supplies the TCD address. + * Example: + * @code + * edma_transfer_t config; + * edma_tcd_t tcd; + * config.srcAddr = ..; + * config.destAddr = ..; + * ... + * EDMA_SetTransferConfig(DMA0, channel, &config, &stcd); + * @endcode + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param config Pointer to eDMA transfer configuration structure. + * @param nextTcd Point to TCD structure. It can be NULL if users + * do not want to enable scatter/gather feature. + * @note If nextTcd is not NULL, it means scatter gather feature is enabled + * and DREQ bit is cleared in the previous transfer configuration, which + * is set in the eDMA_ResetChannel. + */ +void EDMA_SetTransferConfig(DMA_Type *base, + uint32_t channel, + const edma_transfer_config_t *config, + edma_tcd_t *nextTcd); + +/*! + * @brief Configures the eDMA minor offset feature. + * + * The minor offset means that the signed-extended value is added to the source address or destination + * address after each minor loop. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param config A pointer to the minor offset configuration structure. + */ +void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config); + +/*! + * @brief Configures the eDMA channel preemption feature. + * + * This function configures the channel preemption attribute and the priority of the channel. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number + * @param config A pointer to the channel preemption configuration structure. + */ +static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, + uint32_t channel, + const edma_channel_Preemption_config_t *config) +{ + assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); + assert(config != NULL); + + DMA_DCHPRIn(base, channel) = + (DMA_DCHPRI0_DPA(!config->enablePreemptAbility) | DMA_DCHPRI0_ECP(config->enableChannelPreemption) | + DMA_DCHPRI0_CHPRI(config->channelPriority)); +} + +/*! + * @brief Sets the channel link for the eDMA transfer. + * + * This function configures either the minor link or the major link mode. The minor link means that the channel link is + * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is + * exhausted. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param type A channel link type, which can be one of the following: + * @arg kEDMA_LinkNone + * @arg kEDMA_MinorLink + * @arg kEDMA_MajorLink + * @param linkedChannel The linked channel number. + * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. + */ +void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel); + +/*! + * @brief Sets the bandwidth for the eDMA transfer. + * + * Because the eDMA processes the minor loop, it continuously generates read/write sequences + * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of + * each read/write access to control the bus request bandwidth seen by the crossbar switch. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param bandWidth A bandwidth setting, which can be one of the following: + * @arg kEDMABandwidthStallNone + * @arg kEDMABandwidthStall4Cycle + * @arg kEDMABandwidthStall8Cycle + */ +void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth); + +/*! + * @brief Sets the source modulo and the destination modulo for the eDMA transfer. + * + * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) + * calculation is performed or the original register value. It provides the ability to implement a circular data + * queue easily. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. + */ +void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo); + +#if defined(FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT) && FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT +/*! + * @brief Enables an async request for the eDMA transfer. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param enable The command to enable (true) or disable (false). + */ +static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->EARS = (base->EARS & (~(1U << channel))) | ((uint32_t)enable << channel); +} +#endif /* FSL_FEATURE_EDMA_ASYNCHRO_REQUEST_CHANNEL_COUNT */ + +/*! + * @brief Enables an auto stop request for the eDMA transfer. + * + * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param enable The command to enable (true) or disable (false). + */ +static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->TCD[channel].CSR = (base->TCD[channel].CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ(enable); +} + +/*! + * @brief Enables the interrupt source for the eDMA transfer. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param mask The mask of interrupt source to be set. Users need to use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); + +/*! + * @brief Disables the interrupt source for the eDMA transfer. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param mask The mask of the interrupt source to be set. Use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); + +/* @} */ +/*! + * @name eDMA TCD Operation + * @{ + */ + +/*! + * @brief Sets all fields to default values for the TCD structure. + * + * This function sets all fields for this TCD structure to default value. + * + * @param tcd Pointer to the TCD structure. + * @note This function enables the auto stop request feature. + */ +void EDMA_TcdReset(edma_tcd_t *tcd); + +/*! + * @brief Configures the eDMA TCD transfer attribute. + * + * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers. + * The STCD is used in the scatter-gather mode. + * This function configures the TCD transfer attribute, including source address, destination address, + * transfer size, address offset, and so on. It also configures the scatter gather feature if the + * user supplies the next TCD address. + * Example: + * @code + * edma_transfer_t config = { + * ... + * } + * edma_tcd_t tcd __aligned(32); + * edma_tcd_t nextTcd __aligned(32); + * EDMA_TcdSetTransferConfig(&tcd, &config, &nextTcd); + * @endcode + * + * @param tcd Pointer to the TCD structure. + * @param config Pointer to eDMA transfer configuration structure. + * @param nextTcd Pointer to the next TCD structure. It can be NULL if users + * do not want to enable scatter/gather feature. + * @note TCD address should be 32 bytes aligned or it causes an eDMA error. + * @note If the nextTcd is not NULL, the scatter gather feature is enabled + * and DREQ bit is cleared in the previous transfer configuration, which + * is set in the EDMA_TcdReset. + */ +void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd); + +/*! + * @brief Configures the eDMA TCD minor offset feature. + * + * A minor offset is a signed-extended value added to the source address or a destination + * address after each minor loop. + * + * @param tcd A point to the TCD structure. + * @param config A pointer to the minor offset configuration structure. + */ +void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config); + +/*! + * @brief Sets the channel link for the eDMA TCD. + * + * This function configures either a minor link or a major link. The minor link means the channel link is + * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is + * exhausted. + * + * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. + * @param tcd Point to the TCD structure. + * @param type Channel link type, it can be one of: + * @arg kEDMA_LinkNone + * @arg kEDMA_MinorLink + * @arg kEDMA_MajorLink + * @param linkedChannel The linked channel number. + */ +void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint32_t linkedChannel); + +/*! + * @brief Sets the bandwidth for the eDMA TCD. + * + * Because the eDMA processes the minor loop, it continuously generates read/write sequences + * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of + * each read/write access to control the bus request bandwidth seen by the crossbar switch. + * @param tcd A pointer to the TCD structure. + * @param bandWidth A bandwidth setting, which can be one of the following: + * @arg kEDMABandwidthStallNone + * @arg kEDMABandwidthStall4Cycle + * @arg kEDMABandwidthStall8Cycle + */ +static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWidth) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + tcd->CSR = (tcd->CSR & (~DMA_CSR_BWC_MASK)) | DMA_CSR_BWC(bandWidth); +} + +/*! + * @brief Sets the source modulo and the destination modulo for the eDMA TCD. + * + * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) + * calculation is performed or the original register value. It provides the ability to implement a circular data + * queue easily. + * + * @param tcd A pointer to the TCD structure. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. + */ +void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); + +/*! + * @brief Sets the auto stop request for the eDMA TCD. + * + * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. + * + * @param tcd A pointer to the TCD structure. + * @param enable The command to enable (true) or disable (false). + */ +static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) +{ + assert(tcd != NULL); + assert(((uint32_t)tcd & 0x1FU) == 0); + + tcd->CSR = (tcd->CSR & (~DMA_CSR_DREQ_MASK)) | DMA_CSR_DREQ(enable); +} + +/*! + * @brief Enables the interrupt source for the eDMA TCD. + * + * @param tcd Point to the TCD structure. + * @param mask The mask of interrupt source to be set. Users need to use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask); + +/*! + * @brief Disables the interrupt source for the eDMA TCD. + * + * @param tcd Point to the TCD structure. + * @param mask The mask of interrupt source to be set. Users need to use + * the defined edma_interrupt_enable_t type. + */ +void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask); + +/*! @} */ +/*! + * @name eDMA Channel Transfer Operation + * @{ + */ + +/*! + * @brief Enables the eDMA hardware channel request. + * + * This function enables the hardware channel request. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + */ +static inline void EDMA_EnableChannelRequest(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->SERQ = DMA_SERQ_SERQ(channel); +} + +/*! + * @brief Disables the eDMA hardware channel request. + * + * This function disables the hardware channel request. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + */ +static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->CERQ = DMA_CERQ_CERQ(channel); +} + +/*! + * @brief Starts the eDMA transfer by using the software trigger. + * + * This function starts a minor loop transfer. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + */ +static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + base->SSRT = DMA_SSRT_SSRT(channel); +} + +/*! @} */ +/*! + * @name eDMA Channel Status Operation + * @{ + */ + +/*! + * @brief Gets the remaining major loop count from the eDMA current channel TCD. + * + * This function checks the TCD (Task Control Descriptor) status for a specified + * eDMA channel and returns the number of major loop count that has not finished. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @return Major loop count which has not been transferred yet for the current TCD. + * @note 1. This function can only be used to get unfinished major loop count of transfer without + * the next TCD, or it might be inaccuracy. + * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while + * the channel is running. + * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO + * register is needed while the eDMA IP does not support getting it while a channel is active. + * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine + * is working with while a channel is running. + * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example + * copied before enabling the channel) is needed. The formula to calculate it is shown below: + * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured) + */ +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel); + +/*! + * @brief Gets the eDMA channel error status flags. + * + * @param base eDMA peripheral base address. + * @return The mask of error status flags. Users need to use the +* _edma_error_status_flags type to decode the return variables. + */ +static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) +{ + return base->ES; +} + +/*! + * @brief Gets the eDMA channel status flags. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @return The mask of channel status flags. Users need to use the + * _edma_channel_status_flags type to decode the return variables. + */ +uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel); + +/*! + * @brief Clears the eDMA channel status flags. + * + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + * @param mask The mask of channel status to be cleared. Users need to use + * the defined _edma_channel_status_flags type. + */ +void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask); + +/*! @} */ +/*! + * @name eDMA Transactional Operation + */ + +/*! + * @brief Creates the eDMA handle. + * + * This function is called if using the transactional API for eDMA. This function + * initializes the internal state of the eDMA handle. + * + * @param handle eDMA handle pointer. The eDMA handle stores callback function and + * parameters. + * @param base eDMA peripheral base address. + * @param channel eDMA channel number. + */ +void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel); + +/*! + * @brief Installs the TCDs memory pool into the eDMA handle. + * + * This function is called after the EDMA_CreateHandle to use scatter/gather feature. This function shall only be used + * while users need to use scatter gather mode. Scatter gather mode enables EDMA to load a new transfer control block + * (tcd) in hardware, and automatically reconfigure that DMA channel for a new transfer. + * Users need to prepare tcd memory and also configure tcds using interface EDMA_SubmitTransfer. + * + * @param handle eDMA handle pointer. + * @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned. + * @param tcdSize The number of TCD slots. + */ +void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); + +/*! + * @brief Installs a callback function for the eDMA transfer. + * + * This callback is called in the eDMA IRQ handler. Use the callback to do something after + * the current major loop transfer completes. This function will be called every time one tcd finished transfer. + * + * @param handle eDMA handle pointer. + * @param callback eDMA callback function pointer. + * @param userData A parameter for the callback function. + */ +void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData); + +/*! + * @brief Prepares the eDMA transfer structure. + * + * This function prepares the transfer configuration structure according to the user input. + * + * @param config The user configuration structure of type edma_transfer_t. + * @param srcAddr eDMA transfer source address. + * @param srcWidth eDMA transfer source address width(bytes). + * @param destAddr eDMA transfer destination address. + * @param destWidth eDMA transfer destination address width(bytes). + * @param bytesEachRequest eDMA transfer bytes per channel request. + * @param transferBytes eDMA transfer bytes to be transferred. + * @param type eDMA transfer type. + * @note The data address and the data width must be consistent. For example, if the SRC + * is 4 bytes, the source address must be 4 bytes aligned, or it results in + * source address error (SAE). + */ +void EDMA_PrepareTransfer(edma_transfer_config_t *config, + void *srcAddr, + uint32_t srcWidth, + void *destAddr, + uint32_t destWidth, + uint32_t bytesEachRequest, + uint32_t transferBytes, + edma_transfer_type_t type); + +/*! + * @brief Submits the eDMA transfer request. + * + * This function submits the eDMA transfer request according to the transfer configuration structure. + * In scatter gather mode, call this function will add a configured tcd to the circular list of tcd pool. + * The tcd pools is setup by call function EDMA_InstallTCDMemory before. + * + * @param handle eDMA handle pointer. + * @param config Pointer to eDMA transfer configuration structure. + * @retval kStatus_EDMA_Success It means submit transfer request succeed. + * @retval kStatus_EDMA_QueueFull It means TCD queue is full. Submit transfer request is not allowed. + * @retval kStatus_EDMA_Busy It means the given channel is busy, need to submit request later. + */ +status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config); + +/*! + * @brief eDMA starts transfer. + * + * This function enables the channel request. Users can call this function after submitting the transfer request + * or before submitting the transfer request. + * + * @param handle eDMA handle pointer. + */ +void EDMA_StartTransfer(edma_handle_t *handle); + +/*! + * @brief eDMA stops transfer. + * + * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer() + * again to resume the transfer. + * + * @param handle eDMA handle pointer. + */ +void EDMA_StopTransfer(edma_handle_t *handle); + +/*! + * @brief eDMA aborts transfer. + * + * This function disables the channel request and clear transfer status bits. + * Users can submit another transfer after calling this API. + * + * @param handle DMA handle pointer. + */ +void EDMA_AbortTransfer(edma_handle_t *handle); + +/*! + * @brief Get unused TCD slot number. + * + * This function gets current tcd index which is run. If the TCD pool pointer is NULL, it will return 0. + * + * @param handle DMA handle pointer. + * @return The unused tcd slot number. + */ +static inline uint32_t EDMA_GetUnusedTCDNumber(edma_handle_t *handle) +{ + return (handle->tcdSize - handle->tcdUsed); +} + +/*! + * @brief Get the next tcd address. + * + * This function gets the next tcd address. If this is last TCD, return 0. + * + * @param handle DMA handle pointer. + * @return The next TCD address. + */ +static inline uint32_t EDMA_GetNextTCDAddress(edma_handle_t *handle) +{ + return (handle->base->TCD[handle->channel].DLAST_SGA); +} + +/*! + * @brief eDMA IRQ handler for the current major loop transfer completion. + * + * This function clears the channel major interrupt flag and calls + * the callback function if it is not NULL. + * + * Note: + * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed. + * These include the final address adjustments and reloading of the BITER field into the CITER. + * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from + * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled). + * + * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine. + * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index + * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be + * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have + * been loaded into the eDMA engine at this point already.). + * + * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not + * load a new TCD) from the memory pool to the eDMA engine when major loop completes. + * Therefore, ensure that the header and tcdUsed updated are identical for them. + * tcdUsed are both 0 in this case as no TCD to be loaded. + * + * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for + * further details. + * + * @param handle eDMA handle pointer. + */ +void EDMA_HandleIRQ(edma_handle_t *handle); + +/* @} */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/* @} */ + +#endif /*_FSL_EDMA_H_*/ diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_enet.c b/targets/FreeRTOS/GC5/common/drivers/fsl_enet.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_enet.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_enet.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_enet.h b/targets/FreeRTOS/GC5/common/drivers/fsl_enet.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_enet.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_enet.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_flexspi.c b/targets/FreeRTOS/GC5/common/drivers/fsl_flexspi.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_flexspi.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_flexspi.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_flexspi.h b/targets/FreeRTOS/GC5/common/drivers/fsl_flexspi.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_flexspi.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_flexspi.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_gpio.c b/targets/FreeRTOS/GC5/common/drivers/fsl_gpio.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_gpio.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_gpio.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_gpio.h b/targets/FreeRTOS/GC5/common/drivers/fsl_gpio.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_gpio.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_gpio.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_gpio_ext.c b/targets/FreeRTOS/GC5/common/drivers/fsl_gpio_ext.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_gpio_ext.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_gpio_ext.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_gpio_ext.h b/targets/FreeRTOS/GC5/common/drivers/fsl_gpio_ext.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_gpio_ext.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_gpio_ext.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_iomuxc.h b/targets/FreeRTOS/GC5/common/drivers/fsl_iomuxc.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_iomuxc.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_iomuxc.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_lpuart.c b/targets/FreeRTOS/GC5/common/drivers/fsl_lpuart.c similarity index 97% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_lpuart.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_lpuart.c index 214c8c2de3..9c094c2b4c 100644 --- a/targets/FreeRTOS/UAC18/common/drivers/fsl_lpuart.c +++ b/targets/FreeRTOS/GC5/common/drivers/fsl_lpuart.c @@ -1,2095 +1,2114 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015-2016, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2017 NXP. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#include "fsl_lpuart.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.lpuart" -#endif - -/* LPUART transfer state. */ -enum _lpuart_transfer_states -{ - kLPUART_TxIdle, /*!< TX idle. */ - kLPUART_TxBusy, /*!< TX busy. */ - kLPUART_RxIdle, /*!< RX idle. */ - kLPUART_RxBusy /*!< RX busy. */ -}; - -/* Typedef for interrupt handler. */ -typedef void (*lpuart_isr_t)(LPUART_Type *base, lpuart_handle_t *handle); - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Check whether the RX ring buffer is full. - * - * @userData handle LPUART handle pointer. - * @retval true RX ring buffer is full. - * @retval false RX ring buffer is not full. - */ -static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle); - -/*! - * @brief Write to TX register using non-blocking method. - * - * This function writes data to the TX register directly, upper layer must make - * sure the TX register is empty or TX FIFO has empty room before calling this function. - * - * @note This function does not check whether all the data has been sent out to bus, - * so before disable TX, check kLPUART_TransmissionCompleteFlag to ensure the TX is - * finished. - * - * @param base LPUART peripheral base address. - * @param data Start address of the data to write. - * @param length Size of the buffer to be sent. - */ -static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length); - -/*! - * @brief Read RX register using non-blocking method. - * - * This function reads data from the TX register directly, upper layer must make - * sure the RX register is full or TX FIFO has data before calling this function. - * - * @param base LPUART peripheral base address. - * @param data Start address of the buffer to store the received data. - * @param length Size of the buffer. - */ -static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* Array of LPUART peripheral base address. */ -static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS; -/* Array of LPUART handle. */ -static lpuart_handle_t *s_lpuartHandle[ARRAY_SIZE(s_lpuartBases)]; -/* Array of LPUART IRQ number. */ -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -static const IRQn_Type s_lpuartRxIRQ[] = LPUART_RX_IRQS; -static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS; -#else -static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS; -#endif -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Array of LPUART clock name. */ -static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS; - -#if defined(LPUART_PERIPH_CLOCKS) -/* Array of LPUART functional clock name. */ -static const clock_ip_name_t s_lpuartPeriphClocks[] = LPUART_PERIPH_CLOCKS; -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/* LPUART ISR for transactional APIs. */ -static lpuart_isr_t s_lpuartIsr; - -/******************************************************************************* - * Code - ******************************************************************************/ -/*! - * brief Get the LPUART instance from peripheral base address. - * - * param base LPUART peripheral base address. - * return LPUART instance. - */ -uint32_t LPUART_GetInstance(LPUART_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_lpuartBases); instance++) - { - if (s_lpuartBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_lpuartBases)); - - return instance; -} - -/*! - * brief Get the length of received data in RX ring buffer. - * - * userData handle LPUART handle pointer. - * return Length of received data in RX ring buffer. - */ -size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle) -{ - (void)base; - - assert(handle); - - size_t size; - - if (handle->rxRingBufferTail > handle->rxRingBufferHead) - { - size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail); - } - else - { - size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail); - } - - return size; -} - -static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle) -{ - assert(handle); - - bool full; - - if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U)) - { - full = true; - } - else - { - full = false; - } - return full; -} - -static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length) -{ - assert(data); - - size_t i; - - /* The Non Blocking write data API assume user have ensured there is enough space in - peripheral to write. */ - for (i = 0; i < length; i++) - { - base->DATA = data[i]; - } -} - -static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length) -{ - assert(data); - - size_t i; -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - uint32_t ctrl = base->CTRL; - bool isSevenDataBits = - ((ctrl & LPUART_CTRL_M7_MASK) || ((!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); -#endif - - /* The Non Blocking read data API assume user have ensured there is enough space in - peripheral to write. */ - for (i = 0; i < length; i++) - { -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - if (isSevenDataBits) - { - data[i] = (base->DATA & 0x7F); - } - else - { - data[i] = base->DATA; - } -#else - data[i] = base->DATA; -#endif - } -} - -/*! - * brief Initializes an LPUART instance with the user configuration structure and the peripheral clock. - * - * This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function - * to configure the configuration structure and get the default configuration. - * The example below shows how to use this API to configure the LPUART. - * code - * lpuart_config_t lpuartConfig; - * lpuartConfig.baudRate_Bps = 115200U; - * lpuartConfig.parityMode = kLPUART_ParityDisabled; - * lpuartConfig.dataBitsCount = kLPUART_EightDataBits; - * lpuartConfig.isMsb = false; - * lpuartConfig.stopBitCount = kLPUART_OneStopBit; - * lpuartConfig.txFifoWatermark = 0; - * lpuartConfig.rxFifoWatermark = 1; - * LPUART_Init(LPUART1, &lpuartConfig, 20000000U); - * endcode - * - * param base LPUART peripheral base address. - * param config Pointer to a user-defined configuration structure. - * param srcClock_Hz LPUART clock source frequency in HZ. - * retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source. - * retval kStatus_Success LPUART initialize succeed - */ -status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz) -{ - assert(config); - assert(config->baudRate_Bps); -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->txFifoWatermark); - assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->rxFifoWatermark); -#endif - - uint32_t temp; - uint16_t sbr, sbrTemp; - uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff; - - /* This LPUART instantiation uses a slightly different baud rate calculation - * The idea is to use the best OSR (over-sampling rate) possible - * Note, OSR is typically hard-set to 16 in other LPUART instantiations - * loop to find the best OSR value possible, one that generates minimum baudDiff - * iterate through the rest of the supported values of OSR */ - - baudDiff = config->baudRate_Bps; - osr = 0; - sbr = 0; - for (osrTemp = 4; osrTemp <= 32; osrTemp++) - { - /* calculate the temporary sbr value */ - sbrTemp = (srcClock_Hz / (config->baudRate_Bps * osrTemp)); - /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/ - if (sbrTemp == 0) - { - sbrTemp = 1; - } - /* Calculate the baud rate based on the temporary OSR and SBR values */ - calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp)); - - tempDiff = calculatedBaud - config->baudRate_Bps; - - /* Select the better value between srb and (sbr + 1) */ - if (tempDiff > (config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))))) - { - tempDiff = config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))); - sbrTemp++; - } - - if (tempDiff <= baudDiff) - { - baudDiff = tempDiff; - osr = osrTemp; /* update and store the best OSR value calculated */ - sbr = sbrTemp; /* update store the best SBR value calculated */ - } - } - - /* Check to see if actual baud rate is within 3% of desired baud rate - * based on the best calculate OSR value */ - if (baudDiff > ((config->baudRate_Bps / 100) * 3)) - { - /* Unacceptable baud rate difference of more than 3%*/ - return kStatus_LPUART_BaudrateNotSupport; - } - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - - uint32_t instance = LPUART_GetInstance(base); - - /* Enable lpuart clock */ - CLOCK_EnableClock(s_lpuartClock[instance]); -#if defined(LPUART_PERIPH_CLOCKS) - CLOCK_EnableClock(s_lpuartPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL - /*Reset all internal logic and registers, except the Global Register */ - LPUART_SoftwareReset(base); -#else - /* Disable LPUART TX RX before setting. */ - base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); -#endif - - temp = base->BAUD; - - /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. - * If so, then "BOTHEDGE" sampling must be turned on */ - if ((osr > 3) && (osr < 8)) - { - temp |= LPUART_BAUD_BOTHEDGE_MASK; - } - - /* program the osr value (bit value is one less than actual value) */ - temp &= ~LPUART_BAUD_OSR_MASK; - temp |= LPUART_BAUD_OSR(osr - 1); - - /* write the sbr value to the BAUD registers */ - temp &= ~LPUART_BAUD_SBR_MASK; - base->BAUD = temp | LPUART_BAUD_SBR(sbr); - - /* Set bit count and parity mode. */ - base->BAUD &= ~LPUART_BAUD_M10_MASK; - - temp = base->CTRL & - ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK | LPUART_CTRL_ILT_MASK | - LPUART_CTRL_IDLECFG_MASK); - - temp |= - (uint8_t)config->parityMode | LPUART_CTRL_IDLECFG(config->rxIdleConfig) | LPUART_CTRL_ILT(config->rxIdleType); - -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - if (kLPUART_SevenDataBits == config->dataBitsCount) - { - if (kLPUART_ParityDisabled != config->parityMode) - { - temp &= ~LPUART_CTRL_M7_MASK; /* Seven data bits and one parity bit */ - } - else - { - temp |= LPUART_CTRL_M7_MASK; - } - } - else -#endif - { - if (kLPUART_ParityDisabled != config->parityMode) - { - temp |= LPUART_CTRL_M_MASK; /* Eight data bits and one parity bit */ - } - } - - base->CTRL = temp; - -#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT - /* set stop bit per char */ - temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK; - base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)config->stopBitCount); -#endif - -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - /* Set tx/rx WATER watermark - Note: - Take care of the RX FIFO, RX interrupt request only assert when received bytes - equal or more than RX water mark, there is potential issue if RX water - mark larger than 1. - For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and - 5 bytes are received. the last byte will be saved in FIFO but not trigger - RX interrupt because the water mark is 2. - */ - base->WATER = (((uint32_t)(config->rxFifoWatermark) << 16) | config->txFifoWatermark); - - /* Enable tx/rx FIFO */ - base->FIFO |= (LPUART_FIFO_TXFE_MASK | LPUART_FIFO_RXFE_MASK); - - /* Flush FIFO */ - base->FIFO |= (LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK); -#endif - - /* Clear all status flags */ - temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | - LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); - -#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - temp |= LPUART_STAT_LBKDIF_MASK; -#endif - -#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING - temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); -#endif - -#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT - /* Set the CTS configuration/TX CTS source. */ - base->MODIR |= LPUART_MODIR_TXCTSC(config->txCtsConfig) | LPUART_MODIR_TXCTSSRC(config->txCtsSource); - if (config->enableRxRTS) - { - /* Enable the receiver RTS(request-to-send) function. */ - base->MODIR |= LPUART_MODIR_RXRTSE_MASK; - } - if (config->enableTxCTS) - { - /* Enable the CTS(clear-to-send) function. */ - base->MODIR |= LPUART_MODIR_TXCTSE_MASK; - } -#endif - - /* Set data bits order. */ - if (config->isMsb) - { - temp |= LPUART_STAT_MSBF_MASK; - } - else - { - temp &= ~LPUART_STAT_MSBF_MASK; - } - - base->STAT |= temp; - - /* Enable TX/RX base on configure structure. */ - temp = base->CTRL; - if (config->enableTx) - { - temp |= LPUART_CTRL_TE_MASK; - } - - if (config->enableRx) - { - temp |= LPUART_CTRL_RE_MASK; - } - - base->CTRL = temp; - - return kStatus_Success; -} -/*! - * brief Deinitializes a LPUART instance. - * - * This function waits for transmit to complete, disables TX and RX, and disables the LPUART clock. - * - * param base LPUART peripheral base address. - */ -void LPUART_Deinit(LPUART_Type *base) -{ - uint32_t temp; - -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - /* Wait tx FIFO send out*/ - while (0 != ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXWATER_SHIFT)) - { - } -#endif - /* Wait last char shift out */ - while (0 == (base->STAT & LPUART_STAT_TC_MASK)) - { - } - - /* Clear all status flags */ - temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | - LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); - -#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - temp |= LPUART_STAT_LBKDIF_MASK; -#endif - -#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING - temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); -#endif - - base->STAT |= temp; - - /* Disable the module. */ - base->CTRL = 0; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance = LPUART_GetInstance(base); - - /* Disable lpuart clock */ - CLOCK_DisableClock(s_lpuartClock[instance]); - -#if defined(LPUART_PERIPH_CLOCKS) - CLOCK_DisableClock(s_lpuartPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Gets the default configuration structure. - * - * This function initializes the LPUART configuration structure to a default value. The default - * values are: - * lpuartConfig->baudRate_Bps = 115200U; - * lpuartConfig->parityMode = kLPUART_ParityDisabled; - * lpuartConfig->dataBitsCount = kLPUART_EightDataBits; - * lpuartConfig->isMsb = false; - * lpuartConfig->stopBitCount = kLPUART_OneStopBit; - * lpuartConfig->txFifoWatermark = 0; - * lpuartConfig->rxFifoWatermark = 1; - * lpuartConfig->rxIdleType = kLPUART_IdleTypeStartBit; - * lpuartConfig->rxIdleConfig = kLPUART_IdleCharacter1; - * lpuartConfig->enableTx = false; - * lpuartConfig->enableRx = false; - * - * param config Pointer to a configuration structure. - */ -void LPUART_GetDefaultConfig(lpuart_config_t *config) -{ - assert(config); - - /* Initializes the configure structure to zero. */ - memset(config, 0, sizeof(*config)); - - config->baudRate_Bps = 115200U; - config->parityMode = kLPUART_ParityDisabled; - config->dataBitsCount = kLPUART_EightDataBits; - config->isMsb = false; -#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT - config->stopBitCount = kLPUART_OneStopBit; -#endif -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - config->txFifoWatermark = 0; - config->rxFifoWatermark = 0; -#endif -#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT - config->enableRxRTS = false; - config->enableTxCTS = false; - config->txCtsConfig = kLPUART_CtsSampleAtStart; - config->txCtsSource = kLPUART_CtsSourcePin; -#endif - config->rxIdleType = kLPUART_IdleTypeStartBit; - config->rxIdleConfig = kLPUART_IdleCharacter1; - config->enableTx = false; - config->enableRx = false; -} - -/*! - * brief Sets the LPUART instance baudrate. - * - * This function configures the LPUART module baudrate. This function is used to update - * the LPUART module baudrate after the LPUART module is initialized by the LPUART_Init. - * code - * LPUART_SetBaudRate(LPUART1, 115200U, 20000000U); - * endcode - * - * param base LPUART peripheral base address. - * param baudRate_Bps LPUART baudrate to be set. - * param srcClock_Hz LPUART clock source frequency in HZ. - * retval kStatus_LPUART_BaudrateNotSupport Baudrate is not supported in the current clock source. - * retval kStatus_Success Set baudrate succeeded. - */ -status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) -{ - assert(baudRate_Bps); - - uint32_t temp, oldCtrl; - uint16_t sbr, sbrTemp; - uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff; - - /* This LPUART instantiation uses a slightly different baud rate calculation - * The idea is to use the best OSR (over-sampling rate) possible - * Note, OSR is typically hard-set to 16 in other LPUART instantiations - * loop to find the best OSR value possible, one that generates minimum baudDiff - * iterate through the rest of the supported values of OSR */ - - baudDiff = baudRate_Bps; - osr = 0; - sbr = 0; - for (osrTemp = 4; osrTemp <= 32; osrTemp++) - { - /* calculate the temporary sbr value */ - sbrTemp = (srcClock_Hz / (baudRate_Bps * osrTemp)); - /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/ - if (sbrTemp == 0) - { - sbrTemp = 1; - } - /* Calculate the baud rate based on the temporary OSR and SBR values */ - calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp)); - - tempDiff = calculatedBaud - baudRate_Bps; - - /* Select the better value between srb and (sbr + 1) */ - if (tempDiff > (baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))))) - { - tempDiff = baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))); - sbrTemp++; - } - - if (tempDiff <= baudDiff) - { - baudDiff = tempDiff; - osr = osrTemp; /* update and store the best OSR value calculated */ - sbr = sbrTemp; /* update store the best SBR value calculated */ - } - } - - /* Check to see if actual baud rate is within 3% of desired baud rate - * based on the best calculate OSR value */ - if (baudDiff < ((baudRate_Bps / 100) * 3)) - { - /* Store CTRL before disable Tx and Rx */ - oldCtrl = base->CTRL; - - /* Disable LPUART TX RX before setting. */ - base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); - - temp = base->BAUD; - - /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. - * If so, then "BOTHEDGE" sampling must be turned on */ - if ((osr > 3) && (osr < 8)) - { - temp |= LPUART_BAUD_BOTHEDGE_MASK; - } - - /* program the osr value (bit value is one less than actual value) */ - temp &= ~LPUART_BAUD_OSR_MASK; - temp |= LPUART_BAUD_OSR(osr - 1); - - /* write the sbr value to the BAUD registers */ - temp &= ~LPUART_BAUD_SBR_MASK; - base->BAUD = temp | LPUART_BAUD_SBR(sbr); - - /* Restore CTRL. */ - base->CTRL = oldCtrl; - - return kStatus_Success; - } - else - { - /* Unacceptable baud rate difference of more than 3%*/ - return kStatus_LPUART_BaudrateNotSupport; - } -} - -/*! - * brief Enables LPUART interrupts according to a provided mask. - * - * This function enables the LPUART interrupts according to a provided mask. The mask - * is a logical OR of enumeration members. See the ref _lpuart_interrupt_enable. - * This examples shows how to enable TX empty interrupt and RX full interrupt: - * code - * LPUART_EnableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); - * endcode - * - * param base LPUART peripheral base address. - * param mask The interrupts to enable. Logical OR of ref _uart_interrupt_enable. - */ -void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask) -{ - base->BAUD |= ((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) | - ((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); -#endif - mask &= 0xFFFFFF00U; - base->CTRL |= mask; -} - -/*! - * brief Disables LPUART interrupts according to a provided mask. - * - * This function disables the LPUART interrupts according to a provided mask. The mask - * is a logical OR of enumeration members. See ref _lpuart_interrupt_enable. - * This example shows how to disable the TX empty interrupt and RX full interrupt: - * code - * LPUART_DisableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); - * endcode - * - * param base LPUART peripheral base address. - * param mask The interrupts to disable. Logical OR of ref _lpuart_interrupt_enable. - */ -void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask) -{ - base->BAUD &= ~((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) & - ~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); -#endif - mask &= 0xFFFFFF00U; - base->CTRL &= ~mask; -} - -/*! - * brief Gets enabled LPUART interrupts. - * - * This function gets the enabled LPUART interrupts. The enabled interrupts are returned - * as the logical OR value of the enumerators ref _lpuart_interrupt_enable. To check - * a specific interrupt enable status, compare the return value with enumerators - * in ref _lpuart_interrupt_enable. - * For example, to check whether the TX empty interrupt is enabled: - * code - * uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(LPUART1); - * - * if (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts) - * { - * ... - * } - * endcode - * - * param base LPUART peripheral base address. - * return LPUART interrupt flags which are logical OR of the enumerators in ref _lpuart_interrupt_enable. - */ -uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base) -{ - uint32_t temp; - temp = (base->BAUD & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)) >> 8; -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - temp |= (base->FIFO & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)) >> 8; -#endif - temp |= (base->CTRL & 0xFF0C000); - - return temp; -} - -/*! - * brief Gets LPUART status flags. - * - * This function gets all LPUART status flags. The flags are returned as the logical - * OR value of the enumerators ref _lpuart_flags. To check for a specific status, - * compare the return value with enumerators in the ref _lpuart_flags. - * For example, to check whether the TX is empty: - * code - * if (kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1)) - * { - * ... - * } - * endcode - * - * param base LPUART peripheral base address. - * return LPUART status flags which are ORed by the enumerators in the _lpuart_flags. - */ -uint32_t LPUART_GetStatusFlags(LPUART_Type *base) -{ - uint32_t temp; - temp = base->STAT; -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - temp |= (base->FIFO & - (LPUART_FIFO_TXEMPT_MASK | LPUART_FIFO_RXEMPT_MASK | LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) >> - 16; -#endif - return temp; -} - -/*! - * brief Clears status flags with a provided mask. - * - * This function clears LPUART status flags with a provided mask. Automatically cleared flags - * can't be cleared by this function. - * Flags that can only cleared or set by hardware are: - * kLPUART_TxDataRegEmptyFlag, kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, - * kLPUART_RxActiveFlag, kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, - * kLPUART_TxFifoEmptyFlag,kLPUART_RxFifoEmptyFlag - * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects. - * - * param base LPUART peripheral base address. - * param mask the status flags to be cleared. The user can use the enumerators in the - * _lpuart_status_flag_t to do the OR operation and get the mask. - * return 0 succeed, others failed. - * retval kStatus_LPUART_FlagCannotClearManually The flag can't be cleared by this function but - * it is cleared automatically by hardware. - * retval kStatus_Success Status in the mask are cleared. - */ -status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask) -{ - uint32_t temp; - status_t status; -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - temp = (uint32_t)base->FIFO; - temp &= (uint32_t)(~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)); - temp |= (mask << 16) & (LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK); - base->FIFO = temp; -#endif - temp = (uint32_t)base->STAT; -#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - temp &= (uint32_t)(~(LPUART_STAT_LBKDIF_MASK)); - temp |= mask & LPUART_STAT_LBKDIF_MASK; -#endif - temp &= (uint32_t)(~(LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | - LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK)); - temp |= mask & (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | - LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); -#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING - temp &= (uint32_t)(~(LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK)); - temp |= mask & (LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK); -#endif - base->STAT = temp; - /* If some flags still pending. */ - if (mask & LPUART_GetStatusFlags(base)) - { - /* Some flags can only clear or set by the hardware itself, these flags are: kLPUART_TxDataRegEmptyFlag, - kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, kLPUART_RxActiveFlag, - kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, - kLPUART_TxFifoEmptyFlag, kLPUART_RxFifoEmptyFlag. */ - status = kStatus_LPUART_FlagCannotClearManually; /* flags can not clear manually */ - } - else - { - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Writes to the transmitter register using a blocking method. - * - * This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have - * room, and writes data to the transmitter buffer. - * - * note This function does not check whether all data has been sent out to the bus. - * Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is - * finished. - * - * param base LPUART peripheral base address. - * param data Start address of the data to write. - * param length Size of the data to write. - */ -void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length) -{ - assert(data); - - /* This API can only ensure that the data is written into the data buffer but can't - ensure all data in the data buffer are sent into the transmit shift buffer. */ - while (length--) - { - while (!(base->STAT & LPUART_STAT_TDRE_MASK)) - { - } - base->DATA = *(data++); - } -} - -/*! -* brief Reads the receiver data register using a blocking method. - * - * This function polls the receiver register, waits for the receiver register full or receiver FIFO - * has data, and reads data from the TX register. - * - * param base LPUART peripheral base address. - * param data Start address of the buffer to store the received data. - * param length Size of the buffer. - * retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data. - * retval kStatus_LPUART_NoiseError Noise error happened while receiving data. - * retval kStatus_LPUART_FramingError Framing error happened while receiving data. - * retval kStatus_LPUART_ParityError Parity error happened while receiving data. - * retval kStatus_Success Successfully received all data. - */ -status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length) -{ - assert(data); - - uint32_t statusFlag; -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - uint32_t ctrl = base->CTRL; - bool isSevenDataBits = - ((ctrl & LPUART_CTRL_M7_MASK) || ((!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); -#endif - - while (length--) - { -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - while (0 == ((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)) -#else - while (!(base->STAT & LPUART_STAT_RDRF_MASK)) -#endif - { - statusFlag = LPUART_GetStatusFlags(base); - - if (statusFlag & kLPUART_RxOverrunFlag) - { - LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag); - return kStatus_LPUART_RxHardwareOverrun; - } - - if (statusFlag & kLPUART_NoiseErrorFlag) - { - LPUART_ClearStatusFlags(base, kLPUART_NoiseErrorFlag); - return kStatus_LPUART_NoiseError; - } - - if (statusFlag & kLPUART_FramingErrorFlag) - { - LPUART_ClearStatusFlags(base, kLPUART_FramingErrorFlag); - return kStatus_LPUART_FramingError; - } - - if (statusFlag & kLPUART_ParityErrorFlag) - { - LPUART_ClearStatusFlags(base, kLPUART_ParityErrorFlag); - return kStatus_LPUART_ParityError; - } - } -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - if (isSevenDataBits) - { - *(data++) = (base->DATA & 0x7F); - } - else - { - *(data++) = base->DATA; - } -#else - *(data++) = base->DATA; -#endif - } - - return kStatus_Success; -} - -/*! - * brief Initializes the LPUART handle. - * - * This function initializes the LPUART handle, which can be used for other LPUART - * transactional APIs. Usually, for a specified LPUART instance, - * call this API once to get the initialized handle. - * - * The LPUART driver supports the "background" receiving, which means that user can set up - * an RX ring buffer optionally. Data received is stored into the ring buffer even when the - * user doesn't call the LPUART_TransferReceiveNonBlocking() API. If there is already data received - * in the ring buffer, the user can get the received data from the ring buffer directly. - * The ring buffer is disabled if passing NULL as p ringBuffer. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param callback Callback function. - * param userData User data. - */ -void LPUART_TransferCreateHandle(LPUART_Type *base, - lpuart_handle_t *handle, - lpuart_transfer_callback_t callback, - void *userData) -{ - assert(handle); - - uint32_t instance; -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - uint32_t ctrl = base->CTRL; - bool isSevenDataBits = - ((ctrl & LPUART_CTRL_M7_MASK) || ((!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); -#endif - - /* Zero the handle. */ - memset(handle, 0, sizeof(lpuart_handle_t)); - - /* Set the TX/RX state. */ - handle->rxState = kLPUART_RxIdle; - handle->txState = kLPUART_TxIdle; - - /* Set the callback and user data. */ - handle->callback = callback; - handle->userData = userData; - -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - /* Initial seven data bits flag */ - handle->isSevenDataBits = isSevenDataBits; -#endif - - /* Get instance from peripheral base address. */ - instance = LPUART_GetInstance(base); - - /* Save the handle in global variables to support the double weak mechanism. */ - s_lpuartHandle[instance] = handle; - - s_lpuartIsr = LPUART_TransferHandleIRQ; - -/* Enable interrupt in NVIC. */ -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ - EnableIRQ(s_lpuartRxIRQ[instance]); - EnableIRQ(s_lpuartTxIRQ[instance]); -#else - EnableIRQ(s_lpuartIRQ[instance]); -#endif -} - -/*! - * brief Sets up the RX ring buffer. - * - * This function sets up the RX ring buffer to a specific UART handle. - * - * When the RX ring buffer is used, data received is stored into the ring buffer even when - * the user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received - * in the ring buffer, the user can get the received data from the ring buffer directly. - * - * note When using RX ring buffer, one byte is reserved for internal use. In other - * words, if p ringBufferSize is 32, then only 31 bytes are used for saving data. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer. - * param ringBufferSize size of the ring buffer. - */ -void LPUART_TransferStartRingBuffer(LPUART_Type *base, - lpuart_handle_t *handle, - uint8_t *ringBuffer, - size_t ringBufferSize) -{ - assert(handle); - assert(ringBuffer); - - /* Setup the ring buffer address */ - handle->rxRingBuffer = ringBuffer; - handle->rxRingBufferSize = ringBufferSize; - handle->rxRingBufferHead = 0U; - handle->rxRingBufferTail = 0U; - - /* Enable the interrupt to accept the data when user need the ring buffer. */ - LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); -} - -/*! - * brief Aborts the background transfer and uninstalls the ring buffer. - * - * This function aborts the background transfer and uninstalls the ring buffer. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - */ -void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle) -{ - assert(handle); - - if (handle->rxState == kLPUART_RxIdle) - { - LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); - } - - handle->rxRingBuffer = NULL; - handle->rxRingBufferSize = 0U; - handle->rxRingBufferHead = 0U; - handle->rxRingBufferTail = 0U; -} - -/*! - * brief Transmits a buffer of data using the interrupt method. - * - * This function send data using an interrupt method. This is a non-blocking function, which - * returns directly without waiting for all data written to the transmitter register. When - * all data is written to the TX register in the ISR, the LPUART driver calls the callback - * function and passes the ref kStatus_LPUART_TxIdle as status parameter. - * - * note The kStatus_LPUART_TxIdle is passed to the upper layer when all data are written - * to the TX register. However, there is no check to ensure that all the data sent out. Before disabling the TX, - * check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is finished. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param xfer LPUART transfer structure, see #lpuart_transfer_t. - * retval kStatus_Success Successfully start the data transmission. - * retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register. - * retval kStatus_InvalidArgument Invalid argument. - */ -status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer) -{ - assert(handle); - assert(xfer); - assert(xfer->data); - assert(xfer->dataSize); - - status_t status; - - /* Return error if current TX busy. */ - if (kLPUART_TxBusy == handle->txState) - { - status = kStatus_LPUART_TxBusy; - } - else - { - handle->txData = xfer->data; - handle->txDataSize = xfer->dataSize; - handle->txDataSizeAll = xfer->dataSize; - handle->txState = kLPUART_TxBusy; - - /* Enable transmitter interrupt. */ - LPUART_EnableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable); - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Aborts the interrupt-driven data transmit. - * - * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out - * how many bytes are not sent out. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - */ -void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle) -{ - assert(handle); - - LPUART_DisableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_TransmissionCompleteInterruptEnable); - - handle->txDataSize = 0; - handle->txState = kLPUART_TxIdle; -} - -/*! - * brief Gets the number of bytes that have been written to the LPUART transmitter register. - * - * This function gets the number of bytes that have been written to LPUART TX - * register by an interrupt method. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param count Send bytes count. - * retval kStatus_NoTransferInProgress No send in progress. - * retval kStatus_InvalidArgument Parameter is invalid. - * retval kStatus_Success Get successfully through the parameter \p count; - */ -status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) -{ - (void)base; - - assert(handle); - assert(count); - - if (kLPUART_TxIdle == handle->txState) - { - return kStatus_NoTransferInProgress; - } - - *count = handle->txDataSizeAll - handle->txDataSize; - - return kStatus_Success; -} - -/*! - * brief Receives a buffer of data using the interrupt method. - * - * This function receives data using an interrupt method. This is a non-blocking function - * which returns without waiting to ensure that all data are received. - * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and - * the parameter p receivedBytes shows how many bytes are copied from the ring buffer. - * After copying, if the data in the ring buffer is not enough for read, the receive - * request is saved by the LPUART driver. When the new data arrives, the receive request - * is serviced first. When all data is received, the LPUART driver notifies the upper layer - * through a callback function and passes a status parameter ref kStatus_UART_RxIdle. - * For example, the upper layer needs 10 bytes but there are only 5 bytes in ring buffer. - * The 5 bytes are copied to xfer->data, which returns with the - * parameter p receivedBytes set to 5. For the remaining 5 bytes, the newly arrived data is - * saved from xfer->data[5]. When 5 bytes are received, the LPUART driver notifies the upper layer. - * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt - * to receive data to xfer->data. When all data is received, the upper layer is notified. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param xfer LPUART transfer structure, see #uart_transfer_t. - * param receivedBytes Bytes received from the ring buffer directly. - * retval kStatus_Success Successfully queue the transfer into the transmit queue. - * retval kStatus_LPUART_RxBusy Previous receive request is not finished. - * retval kStatus_InvalidArgument Invalid argument. - */ -status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, - lpuart_handle_t *handle, - lpuart_transfer_t *xfer, - size_t *receivedBytes) -{ - assert(handle); - assert(xfer); - assert(xfer->data); - assert(xfer->dataSize); - - uint32_t i; - status_t status; - /* How many bytes to copy from ring buffer to user memory. */ - size_t bytesToCopy = 0U; - /* How many bytes to receive. */ - size_t bytesToReceive; - /* How many bytes currently have received. */ - size_t bytesCurrentReceived; - - /* How to get data: - 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize - to lpuart handle, enable interrupt to store received data to xfer->data. When - all data received, trigger callback. - 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. - If there are enough data in ring buffer, copy them to xfer->data and return. - If there are not enough data in ring buffer, copy all of them to xfer->data, - save the xfer->data remained empty space to lpuart handle, receive data - to this empty space and trigger callback when finished. */ - - if (kLPUART_RxBusy == handle->rxState) - { - status = kStatus_LPUART_RxBusy; - } - else - { - bytesToReceive = xfer->dataSize; - bytesCurrentReceived = 0; - - /* If RX ring buffer is used. */ - if (handle->rxRingBuffer) - { - /* Disable LPUART RX IRQ, protect ring buffer. */ - LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable); - - /* How many bytes in RX ring buffer currently. */ - bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle); - - if (bytesToCopy) - { - bytesToCopy = MIN(bytesToReceive, bytesToCopy); - - bytesToReceive -= bytesToCopy; - - /* Copy data from ring buffer to user memory. */ - for (i = 0U; i < bytesToCopy; i++) - { - xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; - - /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ - if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) - { - handle->rxRingBufferTail = 0U; - } - else - { - handle->rxRingBufferTail++; - } - } - } - - /* If ring buffer does not have enough data, still need to read more data. */ - if (bytesToReceive) - { - /* No data in ring buffer, save the request to LPUART handle. */ - handle->rxData = xfer->data + bytesCurrentReceived; - handle->rxDataSize = bytesToReceive; - handle->rxDataSizeAll = bytesToReceive; - handle->rxState = kLPUART_RxBusy; - } - /* Enable LPUART RX IRQ if previously enabled. */ - LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable); - - /* Call user callback since all data are received. */ - if (0 == bytesToReceive) - { - if (handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); - } - } - } - /* Ring buffer not used. */ - else - { - handle->rxData = xfer->data + bytesCurrentReceived; - handle->rxDataSize = bytesToReceive; - handle->rxDataSizeAll = bytesToReceive; - handle->rxState = kLPUART_RxBusy; - - /* Enable RX interrupt. */ - LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable | - kLPUART_IdleLineInterruptEnable); - } - - /* Return the how many bytes have read. */ - if (receivedBytes) - { - *receivedBytes = bytesCurrentReceived; - } - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Aborts the interrupt-driven data receiving. - * - * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out - * how many bytes not received yet. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - */ -void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle) -{ - (void)base; - - assert(handle); - - /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ - if (!handle->rxRingBuffer) - { - /* Disable RX interrupt. */ - LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable | - kLPUART_IdleLineInterruptEnable); - } - - handle->rxDataSize = 0U; - handle->rxState = kLPUART_RxIdle; -} - -/*! - * brief Gets the number of bytes that have been received. - * - * This function gets the number of bytes that have been received. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param count Receive bytes count. - * retval kStatus_NoTransferInProgress No receive in progress. - * retval kStatus_InvalidArgument Parameter is invalid. - * retval kStatus_Success Get successfully through the parameter \p count; - */ -status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) -{ - (void)base; - - assert(handle); - assert(count); - - if (kLPUART_RxIdle == handle->rxState) - { - return kStatus_NoTransferInProgress; - } - - *count = handle->rxDataSizeAll - handle->rxDataSize; - - return kStatus_Success; -} - -/*! - * brief LPUART IRQ handle function. - * - * This function handles the LPUART transmit and receive IRQ request. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - */ -void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle) -{ - assert(handle); - - uint8_t count; - uint8_t tempCount; - uint32_t status = LPUART_GetStatusFlags(base); - uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(base); - - /* If RX overrun. */ - if (kLPUART_RxOverrunFlag & status) - { - /* Clear overrun flag, otherwise the RX does not work. */ - base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK); - - /* Trigger callback. */ - if (handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_RxHardwareOverrun, handle->userData); - } - } - - /* If IDLE flag is set and the IDLE interrupt is enabled. */ - if ((kLPUART_IdleLineFlag & status) && (kLPUART_IdleLineInterruptEnable & enabledInterrupts)) - { -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)); - - while ((count) && (handle->rxDataSize)) - { - tempCount = MIN(handle->rxDataSize, count); - - /* Using non block API to read the data from the registers. */ - LPUART_ReadNonBlocking(base, handle->rxData, tempCount); - handle->rxData += tempCount; - handle->rxDataSize -= tempCount; - count -= tempCount; - - /* If rxDataSize is 0, disable idle line interrupt.*/ - if (!(handle->rxDataSize)) - { - handle->rxState = kLPUART_RxIdle; - - LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); - if (handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); - } - } - } -#endif - /* Clear IDLE flag.*/ - base->STAT |= LPUART_STAT_IDLE_MASK; - - /* If rxDataSize is 0, disable idle line interrupt.*/ - if (!(handle->rxDataSize)) - { - LPUART_DisableInterrupts(base, kLPUART_IdleLineInterruptEnable); - } - /* If callback is not NULL and rxDataSize is not 0. */ - if ((handle->callback) && (handle->rxDataSize)) - { - handle->callback(base, handle, kStatus_LPUART_IdleLineDetected, handle->userData); - } - } - /* Receive data register full */ - if ((kLPUART_RxDataRegFullFlag & status) && (kLPUART_RxDataRegFullInterruptEnable & enabledInterrupts)) - { -/* Get the size that can be stored into buffer for this interrupt. */ -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)); -#else - count = 1; -#endif - - /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ - while ((count) && (handle->rxDataSize)) - { -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - tempCount = MIN(handle->rxDataSize, count); -#else - tempCount = 1; -#endif - - /* Using non block API to read the data from the registers. */ - LPUART_ReadNonBlocking(base, handle->rxData, tempCount); - handle->rxData += tempCount; - handle->rxDataSize -= tempCount; - count -= tempCount; - - /* If all the data required for upper layer is ready, trigger callback. */ - if (!handle->rxDataSize) - { - handle->rxState = kLPUART_RxIdle; - - if (handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); - } - } - } - - /* If use RX ring buffer, receive data to ring buffer. */ - if (handle->rxRingBuffer) - { - while (count--) - { - /* If RX ring buffer is full, trigger callback to notify over run. */ - if (LPUART_TransferIsRxRingBufferFull(base, handle)) - { - if (handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_RxRingBufferOverrun, handle->userData); - } - } - - /* If ring buffer is still full after callback function, the oldest data is overrided. */ - if (LPUART_TransferIsRxRingBufferFull(base, handle)) - { - /* Increase handle->rxRingBufferTail to make room for new data. */ - if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) - { - handle->rxRingBufferTail = 0U; - } - else - { - handle->rxRingBufferTail++; - } - } - -/* Read data. */ -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - if (handle->isSevenDataBits) - { - handle->rxRingBuffer[handle->rxRingBufferHead] = (base->DATA & 0x7F); - } - else - { - handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA; - } -#else - handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA; -#endif - - /* Increase handle->rxRingBufferHead. */ - if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) - { - handle->rxRingBufferHead = 0U; - } - else - { - handle->rxRingBufferHead++; - } - } - } - /* If no receive requst pending, stop RX interrupt. */ - else if (!handle->rxDataSize) - { - LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); - } - else - { - } - } - - /* Send data register empty and the interrupt is enabled. */ - if ((kLPUART_TxDataRegEmptyFlag & status) && (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts)) - { -/* Get the bytes that available at this moment. */ -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - count = FSL_FEATURE_LPUART_FIFO_SIZEn(base) - - ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT); -#else - count = 1; -#endif - - while ((count) && (handle->txDataSize)) - { -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - tempCount = MIN(handle->txDataSize, count); -#else - tempCount = 1; -#endif - - /* Using non block API to write the data to the registers. */ - LPUART_WriteNonBlocking(base, handle->txData, tempCount); - handle->txData += tempCount; - handle->txDataSize -= tempCount; - count -= tempCount; - - /* If all the data are written to data register, notify user with the callback, then TX finished. */ - if (!handle->txDataSize) - { - handle->txState = kLPUART_TxIdle; - - /* Disable TX register empty interrupt. */ - base->CTRL = (base->CTRL & ~LPUART_CTRL_TIE_MASK); - - /* Trigger callback. */ - if (handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData); - } - } - } - } -} - -/*! - * brief LPUART Error IRQ handle function. - * - * This function handles the LPUART error IRQ request. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - */ -void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle) -{ - (void)base; - (void)handle; - - /* To be implemented by User. */ -} -#if defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1 -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART0_LPUART1_RX_DriverIRQHandler(void) -{ - if (CLOCK_isEnabledClock(s_lpuartClock[0])) - { - if ((LPUART_STAT_OR_MASK & LPUART0->STAT) || - ((LPUART_STAT_RDRF_MASK & LPUART0->STAT) && (LPUART_CTRL_RIE_MASK & LPUART0->CTRL))) - { - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); - } - } - if (CLOCK_isEnabledClock(s_lpuartClock[1])) - { - if ((LPUART_STAT_OR_MASK & LPUART1->STAT) || - ((LPUART_STAT_RDRF_MASK & LPUART1->STAT) && (LPUART_CTRL_RIE_MASK & LPUART1->CTRL))) - { - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); - } - } -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void LPUART0_LPUART1_TX_DriverIRQHandler(void) -{ - if (CLOCK_isEnabledClock(s_lpuartClock[0])) - { - if ((LPUART_STAT_OR_MASK & LPUART0->STAT) || - ((LPUART0->STAT & LPUART_STAT_TDRE_MASK) && (LPUART0->CTRL & LPUART_CTRL_TIE_MASK))) - { - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); - } - } - if (CLOCK_isEnabledClock(s_lpuartClock[1])) - { - if ((LPUART_STAT_OR_MASK & LPUART1->STAT) || - ((LPUART1->STAT & LPUART_STAT_TDRE_MASK) && (LPUART1->CTRL & LPUART_CTRL_TIE_MASK))) - { - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); - } - } -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#else -void LPUART0_LPUART1_DriverIRQHandler(void) -{ - if (CLOCK_isEnabledClock(s_lpuartClock[0])) - { - if ((LPUART_STAT_OR_MASK & LPUART0->STAT) || - ((LPUART_STAT_RDRF_MASK & LPUART0->STAT) && (LPUART_CTRL_RIE_MASK & LPUART0->CTRL)) || - ((LPUART0->STAT & LPUART_STAT_TDRE_MASK) && (LPUART0->CTRL & LPUART_CTRL_TIE_MASK))) - { - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); - } - } - if (CLOCK_isEnabledClock(s_lpuartClock[1])) - { - if ((LPUART_STAT_OR_MASK & LPUART1->STAT) || - ((LPUART_STAT_RDRF_MASK & LPUART1->STAT) && (LPUART_CTRL_RIE_MASK & LPUART1->CTRL)) || - ((LPUART1->STAT & LPUART_STAT_TDRE_MASK) && (LPUART1->CTRL & LPUART_CTRL_TIE_MASK))) - { - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); - } - } -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif - -#if defined(LPUART0) -#if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART0_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void LPUART0_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#else -void LPUART0_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif -#endif - -#if defined(LPUART1) -#if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART1_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void LPUART1_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#else -void LPUART1_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif -#endif - -#if defined(LPUART2) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART2_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART2, s_lpuartHandle[2]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void LPUART2_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART2, s_lpuartHandle[2]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#else -void LPUART2_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART2, s_lpuartHandle[2]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif - -#if defined(LPUART3) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART3_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART3, s_lpuartHandle[3]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void LPUART3_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART3, s_lpuartHandle[3]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#else -void LPUART3_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART3, s_lpuartHandle[3]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif - -#if defined(LPUART4) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART4_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART4, s_lpuartHandle[4]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void LPUART4_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART4, s_lpuartHandle[4]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#else -void LPUART4_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART4, s_lpuartHandle[4]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif - -#if defined(LPUART5) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART5_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART5, s_lpuartHandle[5]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void LPUART5_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART5, s_lpuartHandle[5]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#else -void LPUART5_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART5, s_lpuartHandle[5]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif - -#if defined(LPUART6) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART6_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART6, s_lpuartHandle[6]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void LPUART6_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART6, s_lpuartHandle[6]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#else -void LPUART6_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART6, s_lpuartHandle[6]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif - -#if defined(LPUART7) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART7_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART7, s_lpuartHandle[7]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void LPUART7_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART7, s_lpuartHandle[7]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#else -void LPUART7_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART7, s_lpuartHandle[7]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif - -#if defined(LPUART8) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART8_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART8, s_lpuartHandle[8]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void LPUART8_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART8, s_lpuartHandle[8]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#else -void LPUART8_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART8, s_lpuartHandle[8]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif - -#if defined(CM4_0__LPUART) -void M4_0_LPUART_DriverIRQHandler(void) -{ - s_lpuartIsr(CM4_0__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_0__LPUART)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(CM4_1__LPUART) -void M4_1_LPUART_DriverIRQHandler(void) -{ - s_lpuartIsr(CM4_1__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_1__LPUART)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(CM4__LPUART) -void M4_LPUART_DriverIRQHandler(void) -{ - s_lpuartIsr(CM4__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4__LPUART)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(DMA__LPUART0) -void DMA_UART0_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(DMA__LPUART0, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART0)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(DMA__LPUART1) -void DMA_UART1_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(DMA__LPUART1, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART1)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(DMA__LPUART2) -void DMA_UART2_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(DMA__LPUART2, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART2)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(DMA__LPUART3) -void DMA_UART3_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(DMA__LPUART3, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART3)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(DMA__LPUART4) -void DMA_UART4_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(DMA__LPUART4, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART4)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(ADMA__LPUART0) -void ADMA_UART0_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(ADMA__LPUART0, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART0)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(ADMA__LPUART1) -void ADMA_UART1_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(ADMA__LPUART1, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART1)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(ADMA__LPUART2) -void ADMA_UART2_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(ADMA__LPUART2, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART2)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#if defined(ADMA__LPUART3) -void ADMA_UART3_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(ADMA__LPUART3, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART3)]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif +// +// Copyright (c) 2019 The nanoFramework project contributors +// Portions Copyright (c) 2015-2016, Freescale Semiconductor, Inc. All rights reserved. +// Portions Copyright 2016-2017 NXP. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "fsl_lpuart.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.lpuart" +#endif + +/* LPUART transfer state. */ +enum _lpuart_transfer_states +{ + kLPUART_TxIdle, /*!< TX idle. */ + kLPUART_TxBusy, /*!< TX busy. */ + kLPUART_RxIdle, /*!< RX idle. */ + kLPUART_RxBusy /*!< RX busy. */ +}; + +/* Typedef for interrupt handler. */ +typedef void (*lpuart_isr_t)(LPUART_Type *base, lpuart_handle_t *handle); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Check whether the RX ring buffer is full. + * + * @userData handle LPUART handle pointer. + * @retval true RX ring buffer is full. + * @retval false RX ring buffer is not full. + */ +static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Write to TX register using non-blocking method. + * + * This function writes data to the TX register directly, upper layer must make + * sure the TX register is empty or TX FIFO has empty room before calling this function. + * + * @note This function does not check whether all the data has been sent out to bus, + * so before disable TX, check kLPUART_TransmissionCompleteFlag to ensure the TX is + * finished. + * + * @param base LPUART peripheral base address. + * @param data Start address of the data to write. + * @param length Size of the buffer to be sent. + */ +static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length); + +/*! + * @brief Read RX register using non-blocking method. + * + * This function reads data from the TX register directly, upper layer must make + * sure the RX register is full or TX FIFO has data before calling this function. + * + * @param base LPUART peripheral base address. + * @param data Start address of the buffer to store the received data. + * @param length Size of the buffer. + */ +static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Array of LPUART peripheral base address. */ +static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS; +/* Array of LPUART handle. */ +static lpuart_handle_t *s_lpuartHandle[ARRAY_SIZE(s_lpuartBases)]; +/* Array of LPUART IRQ number. */ +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +static const IRQn_Type s_lpuartRxIRQ[] = LPUART_RX_IRQS; +static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS; +#else +static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS; +#endif +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/* Array of LPUART clock name. */ +static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS; + +#if defined(LPUART_PERIPH_CLOCKS) +/* Array of LPUART functional clock name. */ +static const clock_ip_name_t s_lpuartPeriphClocks[] = LPUART_PERIPH_CLOCKS; +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/* LPUART ISR for transactional APIs. */ +static lpuart_isr_t s_lpuartIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ +/*! + * brief Get the LPUART instance from peripheral base address. + * + * param base LPUART peripheral base address. + * return LPUART instance. + */ +uint32_t LPUART_GetInstance(LPUART_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_lpuartBases); instance++) + { + if (s_lpuartBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_lpuartBases)); + + return instance; +} + +/*! + * brief Get the length of received data in RX ring buffer. + * + * userData handle LPUART handle pointer. + * return Length of received data in RX ring buffer. + */ +size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle) +{ + (void)base; + + assert(handle); + + size_t size; + + if (handle->rxRingBufferTail > handle->rxRingBufferHead) + { + size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail); + } + else + { + size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail); + } + + return size; +} + +static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + bool full; + + if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U)) + { + full = true; + } + else + { + full = false; + } + return full; +} + +static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length) +{ + assert(data); + + size_t i; + + /* The Non Blocking write data API assume user have ensured there is enough space in + peripheral to write. */ + for (i = 0; i < length; i++) + { + base->DATA = data[i]; + } +} + +static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length) +{ + assert(data); + + size_t i; +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || ((!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); +#endif + + /* The Non Blocking read data API assume user have ensured there is enough space in + peripheral to write. */ + for (i = 0; i < length; i++) + { +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (isSevenDataBits) + { + data[i] = (base->DATA & 0x7F); + } + else + { + data[i] = base->DATA; + } +#else + data[i] = base->DATA; +#endif + } +} + +/*! + * brief Initializes an LPUART instance with the user configuration structure and the peripheral clock. + * + * This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function + * to configure the configuration structure and get the default configuration. + * The example below shows how to use this API to configure the LPUART. + * code + * lpuart_config_t lpuartConfig; + * lpuartConfig.baudRate_Bps = 115200U; + * lpuartConfig.parityMode = kLPUART_ParityDisabled; + * lpuartConfig.dataBitsCount = kLPUART_EightDataBits; + * lpuartConfig.isMsb = false; + * lpuartConfig.stopBitCount = kLPUART_OneStopBit; + * lpuartConfig.txFifoWatermark = 0; + * lpuartConfig.rxFifoWatermark = 1; + * LPUART_Init(LPUART1, &lpuartConfig, 20000000U); + * endcode + * + * param base LPUART peripheral base address. + * param config Pointer to a user-defined configuration structure. + * param srcClock_Hz LPUART clock source frequency in HZ. + * retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source. + * retval kStatus_Success LPUART initialize succeed + */ +status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz) +{ + assert(config); + assert(config->baudRate_Bps); +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->txFifoWatermark); + assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->rxFifoWatermark); +#endif + + uint32_t temp; + uint16_t sbr, sbrTemp; + uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff; + + /* This LPUART instantiation uses a slightly different baud rate calculation + * The idea is to use the best OSR (over-sampling rate) possible + * Note, OSR is typically hard-set to 16 in other LPUART instantiations + * loop to find the best OSR value possible, one that generates minimum baudDiff + * iterate through the rest of the supported values of OSR */ + + baudDiff = config->baudRate_Bps; + osr = 0; + sbr = 0; + for (osrTemp = 4; osrTemp <= 32; osrTemp++) + { + /* calculate the temporary sbr value */ + sbrTemp = (srcClock_Hz / (config->baudRate_Bps * osrTemp)); + /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/ + if (sbrTemp == 0) + { + sbrTemp = 1; + } + /* Calculate the baud rate based on the temporary OSR and SBR values */ + calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp)); + + tempDiff = calculatedBaud - config->baudRate_Bps; + + /* Select the better value between srb and (sbr + 1) */ + if (tempDiff > (config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))))) + { + tempDiff = config->baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))); + sbrTemp++; + } + + if (tempDiff <= baudDiff) + { + baudDiff = tempDiff; + osr = osrTemp; /* update and store the best OSR value calculated */ + sbr = sbrTemp; /* update store the best SBR value calculated */ + } + } + + /* Check to see if actual baud rate is within 3% of desired baud rate + * based on the best calculate OSR value */ + if (baudDiff > ((config->baudRate_Bps / 100) * 3)) + { + /* Unacceptable baud rate difference of more than 3%*/ + return kStatus_LPUART_BaudrateNotSupport; + } + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + + uint32_t instance = LPUART_GetInstance(base); + + /* Enable lpuart clock */ + CLOCK_EnableClock(s_lpuartClock[instance]); +#if defined(LPUART_PERIPH_CLOCKS) + CLOCK_EnableClock(s_lpuartPeriphClocks[instance]); +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL + /*Reset all internal logic and registers, except the Global Register */ + LPUART_SoftwareReset(base); +#else + /* Disable LPUART TX RX before setting. */ + base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); +#endif + + temp = base->BAUD; + + /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. + * If so, then "BOTHEDGE" sampling must be turned on */ + if ((osr > 3) && (osr < 8)) + { + temp |= LPUART_BAUD_BOTHEDGE_MASK; + } + + /* program the osr value (bit value is one less than actual value) */ + temp &= ~LPUART_BAUD_OSR_MASK; + temp |= LPUART_BAUD_OSR(osr - 1); + + /* write the sbr value to the BAUD registers */ + temp &= ~LPUART_BAUD_SBR_MASK; + base->BAUD = temp | LPUART_BAUD_SBR(sbr); + + /* Set bit count and parity mode. */ + base->BAUD &= ~LPUART_BAUD_M10_MASK; + + temp = base->CTRL & + ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK | LPUART_CTRL_ILT_MASK | + LPUART_CTRL_IDLECFG_MASK); + + temp |= + (uint8_t)config->parityMode | LPUART_CTRL_IDLECFG(config->rxIdleConfig) | LPUART_CTRL_ILT(config->rxIdleType); + +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (kLPUART_SevenDataBits == config->dataBitsCount) + { + if (kLPUART_ParityDisabled != config->parityMode) + { + temp &= ~LPUART_CTRL_M7_MASK; /* Seven data bits and one parity bit */ + } + else + { + temp |= LPUART_CTRL_M7_MASK; + } + } + else +#endif + { + if (kLPUART_ParityDisabled != config->parityMode) + { + temp |= LPUART_CTRL_M_MASK; /* Eight data bits and one parity bit */ + } + } + + base->CTRL = temp; + +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + /* set stop bit per char */ + temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK; + base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)config->stopBitCount); +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Set tx/rx WATER watermark + Note: + Take care of the RX FIFO, RX interrupt request only assert when received bytes + equal or more than RX water mark, there is potential issue if RX water + mark larger than 1. + For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and + 5 bytes are received. the last byte will be saved in FIFO but not trigger + RX interrupt because the water mark is 2. + */ + base->WATER = (((uint32_t)(config->rxFifoWatermark) << 16) | config->txFifoWatermark); + + /* Enable tx/rx FIFO */ + base->FIFO |= (LPUART_FIFO_TXFE_MASK | LPUART_FIFO_RXFE_MASK); + + /* Flush FIFO */ + base->FIFO |= (LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK); +#endif + + /* Clear all status flags */ + temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); + +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + temp |= LPUART_STAT_LBKDIF_MASK; +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT + /* Set the CTS configuration/TX CTS source. */ + base->MODIR |= LPUART_MODIR_TXCTSC(config->txCtsConfig) | LPUART_MODIR_TXCTSSRC(config->txCtsSource); + if (config->enableRxRTS) + { + /* Enable the receiver RTS(request-to-send) function. */ + base->MODIR |= LPUART_MODIR_RXRTSE_MASK; + } + if (config->enableTxCTS) + { + /* Enable the CTS(clear-to-send) function. */ + base->MODIR |= LPUART_MODIR_TXCTSE_MASK; + } +#endif + + /* Set data bits order. */ + if (config->isMsb) + { + temp |= LPUART_STAT_MSBF_MASK; + } + else + { + temp &= ~LPUART_STAT_MSBF_MASK; + } + + base->STAT |= temp; + + /* Enable TX/RX base on configure structure. */ + temp = base->CTRL; + if (config->enableTx) + { + temp |= LPUART_CTRL_TE_MASK; + } + + if (config->enableRx) + { + temp |= LPUART_CTRL_RE_MASK; + } + + base->CTRL = temp; + + return kStatus_Success; +} +/*! + * brief Deinitializes a LPUART instance. + * + * This function waits for transmit to complete, disables TX and RX, and disables the LPUART clock. + * + * param base LPUART peripheral base address. + */ +void LPUART_Deinit(LPUART_Type *base) +{ + uint32_t temp; + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Wait tx FIFO send out*/ + while (0 != ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXWATER_SHIFT)) + { + } +#endif + /* Wait last char shift out */ + while (0 == (base->STAT & LPUART_STAT_TC_MASK)) + { + } + + /* Clear all status flags */ + temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); + +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + temp |= LPUART_STAT_LBKDIF_MASK; +#endif + +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); +#endif + + base->STAT |= temp; + + /* Disable the module. */ + base->CTRL = 0; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + uint32_t instance = LPUART_GetInstance(base); + + /* Disable lpuart clock */ + CLOCK_DisableClock(s_lpuartClock[instance]); + +#if defined(LPUART_PERIPH_CLOCKS) + CLOCK_DisableClock(s_lpuartPeriphClocks[instance]); +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * brief Gets the default configuration structure. + * + * This function initializes the LPUART configuration structure to a default value. The default + * values are: + * lpuartConfig->baudRate_Bps = 115200U; + * lpuartConfig->parityMode = kLPUART_ParityDisabled; + * lpuartConfig->dataBitsCount = kLPUART_EightDataBits; + * lpuartConfig->isMsb = false; + * lpuartConfig->stopBitCount = kLPUART_OneStopBit; + * lpuartConfig->txFifoWatermark = 0; + * lpuartConfig->rxFifoWatermark = 1; + * lpuartConfig->rxIdleType = kLPUART_IdleTypeStartBit; + * lpuartConfig->rxIdleConfig = kLPUART_IdleCharacter1; + * lpuartConfig->enableTx = false; + * lpuartConfig->enableRx = false; + * + * param config Pointer to a configuration structure. + */ +void LPUART_GetDefaultConfig(lpuart_config_t *config) +{ + assert(config); + + /* Initializes the configure structure to zero. */ + memset(config, 0, sizeof(*config)); + + config->baudRate_Bps = 115200U; + config->parityMode = kLPUART_ParityDisabled; + config->dataBitsCount = kLPUART_EightDataBits; + config->isMsb = false; +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + config->stopBitCount = kLPUART_OneStopBit; +#endif +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + config->txFifoWatermark = 0; + config->rxFifoWatermark = 0; +#endif +#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT + config->enableRxRTS = false; + config->enableTxCTS = false; + config->txCtsConfig = kLPUART_CtsSampleAtStart; + config->txCtsSource = kLPUART_CtsSourcePin; +#endif + config->rxIdleType = kLPUART_IdleTypeStartBit; + config->rxIdleConfig = kLPUART_IdleCharacter1; + config->enableTx = false; + config->enableRx = false; +} + +/*! + * brief Sets the LPUART instance baudrate. + * + * This function configures the LPUART module baudrate. This function is used to update + * the LPUART module baudrate after the LPUART module is initialized by the LPUART_Init. + * code + * LPUART_SetBaudRate(LPUART1, 115200U, 20000000U); + * endcode + * + * param base LPUART peripheral base address. + * param baudRate_Bps LPUART baudrate to be set. + * param srcClock_Hz LPUART clock source frequency in HZ. + * retval kStatus_LPUART_BaudrateNotSupport Baudrate is not supported in the current clock source. + * retval kStatus_Success Set baudrate succeeded. + */ +status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +{ + assert(baudRate_Bps); + + uint32_t temp, oldCtrl; + uint16_t sbr, sbrTemp; + uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff; + + /* This LPUART instantiation uses a slightly different baud rate calculation + * The idea is to use the best OSR (over-sampling rate) possible + * Note, OSR is typically hard-set to 16 in other LPUART instantiations + * loop to find the best OSR value possible, one that generates minimum baudDiff + * iterate through the rest of the supported values of OSR */ + + baudDiff = baudRate_Bps; + osr = 0; + sbr = 0; + for (osrTemp = 4; osrTemp <= 32; osrTemp++) + { + /* calculate the temporary sbr value */ + sbrTemp = (srcClock_Hz / (baudRate_Bps * osrTemp)); + /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/ + if (sbrTemp == 0) + { + sbrTemp = 1; + } + /* Calculate the baud rate based on the temporary OSR and SBR values */ + calculatedBaud = (srcClock_Hz / (osrTemp * sbrTemp)); + + tempDiff = calculatedBaud - baudRate_Bps; + + /* Select the better value between srb and (sbr + 1) */ + if (tempDiff > (baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))))) + { + tempDiff = baudRate_Bps - (srcClock_Hz / (osrTemp * (sbrTemp + 1))); + sbrTemp++; + } + + if (tempDiff <= baudDiff) + { + baudDiff = tempDiff; + osr = osrTemp; /* update and store the best OSR value calculated */ + sbr = sbrTemp; /* update store the best SBR value calculated */ + } + } + + /* Check to see if actual baud rate is within 3% of desired baud rate + * based on the best calculate OSR value */ + if (baudDiff < ((baudRate_Bps / 100) * 3)) + { + /* Store CTRL before disable Tx and Rx */ + oldCtrl = base->CTRL; + + /* Disable LPUART TX RX before setting. */ + base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); + + temp = base->BAUD; + + /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. + * If so, then "BOTHEDGE" sampling must be turned on */ + if ((osr > 3) && (osr < 8)) + { + temp |= LPUART_BAUD_BOTHEDGE_MASK; + } + + /* program the osr value (bit value is one less than actual value) */ + temp &= ~LPUART_BAUD_OSR_MASK; + temp |= LPUART_BAUD_OSR(osr - 1); + + /* write the sbr value to the BAUD registers */ + temp &= ~LPUART_BAUD_SBR_MASK; + base->BAUD = temp | LPUART_BAUD_SBR(sbr); + + /* Restore CTRL. */ + base->CTRL = oldCtrl; + + return kStatus_Success; + } + else + { + /* Unacceptable baud rate difference of more than 3%*/ + return kStatus_LPUART_BaudrateNotSupport; + } +} + +/*! + * brief Enables LPUART interrupts according to a provided mask. + * + * This function enables the LPUART interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See the ref _lpuart_interrupt_enable. + * This examples shows how to enable TX empty interrupt and RX full interrupt: + * code + * LPUART_EnableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); + * endcode + * + * param base LPUART peripheral base address. + * param mask The interrupts to enable. Logical OR of ref _uart_interrupt_enable. + */ +void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask) +{ + base->BAUD |= ((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) | + ((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); +#endif + mask &= 0xFFFFFF00U; + base->CTRL |= mask; +} + +/*! + * brief Disables LPUART interrupts according to a provided mask. + * + * This function disables the LPUART interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See ref _lpuart_interrupt_enable. + * This example shows how to disable the TX empty interrupt and RX full interrupt: + * code + * LPUART_DisableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); + * endcode + * + * param base LPUART peripheral base address. + * param mask The interrupts to disable. Logical OR of ref _lpuart_interrupt_enable. + */ +void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask) +{ + base->BAUD &= ~((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) & + ~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); +#endif + mask &= 0xFFFFFF00U; + base->CTRL &= ~mask; +} + +/*! + * brief Gets enabled LPUART interrupts. + * + * This function gets the enabled LPUART interrupts. The enabled interrupts are returned + * as the logical OR value of the enumerators ref _lpuart_interrupt_enable. To check + * a specific interrupt enable status, compare the return value with enumerators + * in ref _lpuart_interrupt_enable. + * For example, to check whether the TX empty interrupt is enabled: + * code + * uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(LPUART1); + * + * if (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts) + * { + * ... + * } + * endcode + * + * param base LPUART peripheral base address. + * return LPUART interrupt flags which are logical OR of the enumerators in ref _lpuart_interrupt_enable. + */ +uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base) +{ + uint32_t temp; + temp = (base->BAUD & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)) >> 8; +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + temp |= (base->FIFO & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)) >> 8; +#endif + temp |= (base->CTRL & 0xFF0C000); + + return temp; +} + +/*! + * brief Gets LPUART status flags. + * + * This function gets all LPUART status flags. The flags are returned as the logical + * OR value of the enumerators ref _lpuart_flags. To check for a specific status, + * compare the return value with enumerators in the ref _lpuart_flags. + * For example, to check whether the TX is empty: + * code + * if (kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1)) + * { + * ... + * } + * endcode + * + * param base LPUART peripheral base address. + * return LPUART status flags which are ORed by the enumerators in the _lpuart_flags. + */ +uint32_t LPUART_GetStatusFlags(LPUART_Type *base) +{ + uint32_t temp; + temp = base->STAT; +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + temp |= (base->FIFO & + (LPUART_FIFO_TXEMPT_MASK | LPUART_FIFO_RXEMPT_MASK | LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) >> + 16; +#endif + return temp; +} + +/*! + * brief Clears status flags with a provided mask. + * + * This function clears LPUART status flags with a provided mask. Automatically cleared flags + * can't be cleared by this function. + * Flags that can only cleared or set by hardware are: + * kLPUART_TxDataRegEmptyFlag, kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, + * kLPUART_RxActiveFlag, kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, + * kLPUART_TxFifoEmptyFlag,kLPUART_RxFifoEmptyFlag + * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects. + * + * param base LPUART peripheral base address. + * param mask the status flags to be cleared. The user can use the enumerators in the + * _lpuart_status_flag_t to do the OR operation and get the mask. + * return 0 succeed, others failed. + * retval kStatus_LPUART_FlagCannotClearManually The flag can't be cleared by this function but + * it is cleared automatically by hardware. + * retval kStatus_Success Status in the mask are cleared. + */ +status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask) +{ + uint32_t temp; + status_t status; +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + temp = (uint32_t)base->FIFO; + temp &= (uint32_t)(~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)); + temp |= (mask << 16) & (LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK); + base->FIFO = temp; +#endif + temp = (uint32_t)base->STAT; +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + temp &= (uint32_t)(~(LPUART_STAT_LBKDIF_MASK)); + temp |= mask & LPUART_STAT_LBKDIF_MASK; +#endif + temp &= (uint32_t)(~(LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK)); + temp |= mask & (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + temp &= (uint32_t)(~(LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK)); + temp |= mask & (LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK); +#endif + base->STAT = temp; + /* If some flags still pending. */ + if (mask & LPUART_GetStatusFlags(base)) + { + /* Some flags can only clear or set by the hardware itself, these flags are: kLPUART_TxDataRegEmptyFlag, + kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, kLPUART_RxActiveFlag, + kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, + kLPUART_TxFifoEmptyFlag, kLPUART_RxFifoEmptyFlag. */ + status = kStatus_LPUART_FlagCannotClearManually; /* flags can not clear manually */ + } + else + { + status = kStatus_Success; + } + + return status; +} + +/*! + * brief Writes to the transmitter register using a blocking method. + * + * This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have + * room, and writes data to the transmitter buffer. + * + * note This function does not check whether all data has been sent out to the bus. + * Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is + * finished. + * + * param base LPUART peripheral base address. + * param data Start address of the data to write. + * param length Size of the data to write. + */ +void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length) +{ + assert(data); + + /* This API can only ensure that the data is written into the data buffer but can't + ensure all data in the data buffer are sent into the transmit shift buffer. */ + while (length--) + { + while (!(base->STAT & LPUART_STAT_TDRE_MASK)) + { + } + base->DATA = *(data++); + } +} + +/*! +* brief Reads the receiver data register using a blocking method. + * + * This function polls the receiver register, waits for the receiver register full or receiver FIFO + * has data, and reads data from the TX register. + * + * param base LPUART peripheral base address. + * param data Start address of the buffer to store the received data. + * param length Size of the buffer. + * retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data. + * retval kStatus_LPUART_NoiseError Noise error happened while receiving data. + * retval kStatus_LPUART_FramingError Framing error happened while receiving data. + * retval kStatus_LPUART_ParityError Parity error happened while receiving data. + * retval kStatus_Success Successfully received all data. + */ +status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length) +{ + assert(data); + + uint32_t statusFlag; +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || ((!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); +#endif + + while (length--) + { +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + while (0 == ((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)) +#else + while (!(base->STAT & LPUART_STAT_RDRF_MASK)) +#endif + { + statusFlag = LPUART_GetStatusFlags(base); + + if (statusFlag & kLPUART_RxOverrunFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_RxOverrunFlag); + return kStatus_LPUART_RxHardwareOverrun; + } + + if (statusFlag & kLPUART_NoiseErrorFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_NoiseErrorFlag); + return kStatus_LPUART_NoiseError; + } + + if (statusFlag & kLPUART_FramingErrorFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_FramingErrorFlag); + return kStatus_LPUART_FramingError; + } + + if (statusFlag & kLPUART_ParityErrorFlag) + { + LPUART_ClearStatusFlags(base, kLPUART_ParityErrorFlag); + return kStatus_LPUART_ParityError; + } + } +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (isSevenDataBits) + { + *(data++) = (base->DATA & 0x7F); + } + else + { + *(data++) = base->DATA; + } +#else + *(data++) = base->DATA; +#endif + } + + return kStatus_Success; +} + +/*! + * brief Initializes the LPUART handle. + * + * This function initializes the LPUART handle, which can be used for other LPUART + * transactional APIs. Usually, for a specified LPUART instance, + * call this API once to get the initialized handle. + * + * The LPUART driver supports the "background" receiving, which means that user can set up + * an RX ring buffer optionally. Data received is stored into the ring buffer even when the + * user doesn't call the LPUART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * The ring buffer is disabled if passing NULL as p ringBuffer. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + * param callback Callback function. + * param userData User data. + */ +void LPUART_TransferCreateHandle(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_callback_t callback, + void *userData) +{ + assert(handle); + + uint32_t instance; +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || ((!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); +#endif + + /* Zero the handle. */ + memset(handle, 0, sizeof(lpuart_handle_t)); + + /* Set the TX/RX state. */ + handle->rxState = kLPUART_RxIdle; + handle->txState = kLPUART_TxIdle; + + /* Set the callback and user data. */ + handle->callback = callback; + handle->userData = userData; + +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + /* Initial seven data bits flag */ + handle->isSevenDataBits = isSevenDataBits; +#endif + + /* Get instance from peripheral base address. */ + instance = LPUART_GetInstance(base); + + /* Save the handle in global variables to support the double weak mechanism. */ + s_lpuartHandle[instance] = handle; + + s_lpuartIsr = LPUART_TransferHandleIRQ; + +/* Enable interrupt in NVIC. */ +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ + EnableIRQ(s_lpuartRxIRQ[instance]); + EnableIRQ(s_lpuartTxIRQ[instance]); +#else + EnableIRQ(s_lpuartIRQ[instance]); +#endif +} + +/*! + * brief Sets up the RX ring buffer. + * + * This function sets up the RX ring buffer to a specific UART handle. + * + * When the RX ring buffer is used, data received is stored into the ring buffer even when + * the user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * + * note When using RX ring buffer, one byte is reserved for internal use. In other + * words, if p ringBufferSize is 32, then only 31 bytes are used for saving data. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + * param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer. + * param ringBufferSize size of the ring buffer. + */ +void LPUART_TransferStartRingBuffer(LPUART_Type *base, + lpuart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize) +{ + assert(handle); + assert(ringBuffer); + + /* Setup the ring buffer address */ + handle->rxRingBuffer = ringBuffer; + handle->rxRingBufferSize = ringBufferSize; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; + + /* Enable the interrupt to accept the data when user need the ring buffer. */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); +} + +/*! + * brief Aborts the background transfer and uninstalls the ring buffer. + * + * This function aborts the background transfer and uninstalls the ring buffer. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + */ +void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + if (handle->rxState == kLPUART_RxIdle) + { + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } + + handle->rxRingBuffer = NULL; + handle->rxRingBufferSize = 0U; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; +} + +/*! + * brief Transmits a buffer of data using the interrupt method. + * + * This function send data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data written to the transmitter register. When + * all data is written to the TX register in the ISR, the LPUART driver calls the callback + * function and passes the ref kStatus_LPUART_TxIdle as status parameter. + * + * note The kStatus_LPUART_TxIdle is passed to the upper layer when all data are written + * to the TX register. However, there is no check to ensure that all the data sent out. Before disabling the TX, + * check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is finished. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + * param xfer LPUART transfer structure, see #lpuart_transfer_t. + * retval kStatus_Success Successfully start the data transmission. + * retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register. + * retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer) +{ + assert(handle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + + status_t status; + + /* Return error if current TX busy. */ + if (kLPUART_TxBusy == handle->txState) + { + status = kStatus_LPUART_TxBusy; + } + else + { + handle->txData = xfer->data; + handle->txDataSize = xfer->dataSize; + handle->txDataSizeAll = xfer->dataSize; + handle->txState = kLPUART_TxBusy; + + /* Enable transmitter interrupt. */ + LPUART_EnableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable); + + status = kStatus_Success; + } + + return status; +} + +/*! + * brief Aborts the interrupt-driven data transmit. + * + * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out + * how many bytes are not sent out. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + */ +void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + LPUART_DisableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_TransmissionCompleteInterruptEnable); + + handle->txDataSize = 0; + handle->txState = kLPUART_TxIdle; +} + +/*! + * brief Gets the number of bytes that have been written to the LPUART transmitter register. + * + * This function gets the number of bytes that have been written to LPUART TX + * register by an interrupt method. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + * param count Send bytes count. + * retval kStatus_NoTransferInProgress No send in progress. + * retval kStatus_InvalidArgument Parameter is invalid. + * retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) +{ + (void)base; + + assert(handle); + assert(count); + + if (kLPUART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->txDataSizeAll - handle->txDataSize; + + return kStatus_Success; +} + +/*! + * brief Receives a buffer of data using the interrupt method. + * + * This function receives data using an interrupt method. This is a non-blocking function + * which returns without waiting to ensure that all data are received. + * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and + * the parameter p receivedBytes shows how many bytes are copied from the ring buffer. + * After copying, if the data in the ring buffer is not enough for read, the receive + * request is saved by the LPUART driver. When the new data arrives, the receive request + * is serviced first. When all data is received, the LPUART driver notifies the upper layer + * through a callback function and passes a status parameter ref kStatus_UART_RxIdle. + * For example, the upper layer needs 10 bytes but there are only 5 bytes in ring buffer. + * The 5 bytes are copied to xfer->data, which returns with the + * parameter p receivedBytes set to 5. For the remaining 5 bytes, the newly arrived data is + * saved from xfer->data[5]. When 5 bytes are received, the LPUART driver notifies the upper layer. + * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt + * to receive data to xfer->data. When all data is received, the upper layer is notified. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + * param xfer LPUART transfer structure, see #uart_transfer_t. + * param receivedBytes Bytes received from the ring buffer directly. + * retval kStatus_Success Successfully queue the transfer into the transmit queue. + * retval kStatus_LPUART_RxBusy Previous receive request is not finished. + * retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_t *xfer, + size_t *receivedBytes) +{ + assert(handle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + + uint32_t i; + status_t status; + /* How many bytes to copy from ring buffer to user memory. */ + size_t bytesToCopy = 0U; + /* How many bytes to receive. */ + size_t bytesToReceive; + /* How many bytes currently have received. */ + size_t bytesCurrentReceived; + + /* How to get data: + 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize + to lpuart handle, enable interrupt to store received data to xfer->data. When + all data received, trigger callback. + 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. + If there are enough data in ring buffer, copy them to xfer->data and return. + If there are not enough data in ring buffer, copy all of them to xfer->data, + save the xfer->data remained empty space to lpuart handle, receive data + to this empty space and trigger callback when finished. */ + + if (kLPUART_RxBusy == handle->rxState) + { + status = kStatus_LPUART_RxBusy; + } + else + { + bytesToReceive = xfer->dataSize; + bytesCurrentReceived = 0; + + /* If RX ring buffer is used. */ + if (handle->rxRingBuffer) + { + /* Disable LPUART RX IRQ, protect ring buffer. */ + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable); + + /* How many bytes in RX ring buffer currently. */ + bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle); + + if (bytesToCopy) + { + bytesToCopy = MIN(bytesToReceive, bytesToCopy); + + bytesToReceive -= bytesToCopy; + + /* Copy data from ring buffer to user memory. */ + for (i = 0U; i < bytesToCopy; i++) + { + xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; + + /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + } + + /* If ring buffer does not have enough data, still need to read more data. */ + if (bytesToReceive) + { + /* No data in ring buffer, save the request to LPUART handle. */ + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kLPUART_RxBusy; + } + /* Enable LPUART RX IRQ if previously enabled. */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable); + + /* Call user callback since all data are received. */ + if (0 == bytesToReceive) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); + } + } + } + /* Ring buffer not used. */ + else + { + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kLPUART_RxBusy; + + /* Enable RX interrupt. */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable | + kLPUART_IdleLineInterruptEnable); + } + + /* Return the how many bytes have read. */ + if (receivedBytes) + { + *receivedBytes = bytesCurrentReceived; + } + + status = kStatus_Success; + } + + return status; +} + +/*! + * brief Aborts the interrupt-driven data receiving. + * + * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out + * how many bytes not received yet. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + */ +void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle) +{ + (void)base; + + assert(handle); + + /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ + if (!handle->rxRingBuffer) + { + /* Disable RX interrupt. */ + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable | + kLPUART_IdleLineInterruptEnable); + } + + handle->rxDataSize = 0U; + handle->rxState = kLPUART_RxIdle; +} + +/*! + * brief Gets the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + * param count Receive bytes count. + * retval kStatus_NoTransferInProgress No receive in progress. + * retval kStatus_InvalidArgument Parameter is invalid. + * retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) +{ + (void)base; + + assert(handle); + assert(count); + + if (kLPUART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->rxDataSizeAll - handle->rxDataSize; + + return kStatus_Success; +} + +/*! + * brief LPUART IRQ handle function. + * + * This function handles the LPUART transmit and receive IRQ request. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + */ +void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle) +{ + assert(handle); + + uint8_t count; + uint8_t tempCount; + uint32_t status = LPUART_GetStatusFlags(base); + uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(base); + + /* If RX overrun. */ + if (kLPUART_RxOverrunFlag & status) + { + /* Clear overrun flag, otherwise the RX does not work. */ + base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK); + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxHardwareOverrun, handle->userData); + } + } + + /* If IDLE flag is set and the IDLE interrupt is enabled. */ + if ((kLPUART_IdleLineFlag & status) && (kLPUART_IdleLineInterruptEnable & enabledInterrupts)) + { +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)); + + while ((count) && (handle->rxDataSize)) + { + tempCount = MIN(handle->rxDataSize, count); + + /* Using non block API to read the data from the registers. */ + LPUART_ReadNonBlocking(base, handle->rxData, tempCount); + handle->rxData += tempCount; + handle->rxDataSize -= tempCount; + count -= tempCount; + + /* If rxDataSize is 0, disable idle line interrupt.*/ + if (!(handle->rxDataSize)) + { + handle->rxState = kLPUART_RxIdle; + + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); + } + } + } +#endif + /* Clear IDLE flag.*/ + base->STAT |= LPUART_STAT_IDLE_MASK; + + /* If rxDataSize is 0, disable idle line interrupt.*/ + if (!(handle->rxDataSize)) + { + LPUART_DisableInterrupts(base, kLPUART_IdleLineInterruptEnable); + } + /* If callback is not NULL and rxDataSize is not 0. */ + if ((handle->callback) && (handle->rxDataSize)) + { + handle->callback(base, handle, kStatus_LPUART_IdleLineDetected, handle->userData); + } + } + /* Receive data register full */ + if ((kLPUART_RxDataRegFullFlag & status) && (kLPUART_RxDataRegFullInterruptEnable & enabledInterrupts)) + { +/* Get the size that can be stored into buffer for this interrupt. */ +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)); +#else + count = 1; +#endif + + /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ + while ((count) && (handle->rxDataSize)) + { +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + tempCount = MIN(handle->rxDataSize, count); +#else + tempCount = 1; +#endif + + /* Using non block API to read the data from the registers. */ + LPUART_ReadNonBlocking(base, handle->rxData, tempCount); + handle->rxData += tempCount; + handle->rxDataSize -= tempCount; + count -= tempCount; + + /* If all the data required for upper layer is ready, trigger callback. */ + if (!handle->rxDataSize) + { + handle->rxState = kLPUART_RxIdle; + + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); + } + } + } + + /* If use RX ring buffer, receive data to ring buffer. */ + if (handle->rxRingBuffer) + { + while (count--) + { + /* If RX ring buffer is full, trigger callback to notify over run. */ + if (LPUART_TransferIsRxRingBufferFull(base, handle)) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_RxRingBufferOverrun, handle->userData); + } + } + + /* If ring buffer is still full after callback function, the oldest data is overrided. */ + if (LPUART_TransferIsRxRingBufferFull(base, handle)) + { + /* Increase handle->rxRingBufferTail to make room for new data. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + +/* Read data. */ +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (handle->isSevenDataBits) + { + handle->rxRingBuffer[handle->rxRingBufferHead] = (base->DATA & 0x7F); + } + else + { + handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA; + } +#else + handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA; +#endif + + /* Increase handle->rxRingBufferHead. */ + if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferHead = 0U; + } + else + { + handle->rxRingBufferHead++; + } + } + } + /* If no receive requst pending, stop RX interrupt. */ + else if (!handle->rxDataSize) + { + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + } + else + { + } + } + + /* Send data register empty and the interrupt is enabled. */ + if ((kLPUART_TxDataRegEmptyFlag & status) && (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts)) + { +/* Get the bytes that available at this moment. */ +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + count = FSL_FEATURE_LPUART_FIFO_SIZEn(base) - + ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT); +#else + count = 1; +#endif + + while ((count) && (handle->txDataSize)) + { +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + tempCount = MIN(handle->txDataSize, count); +#else + tempCount = 1; +#endif + + /* Using non block API to write the data to the registers. */ + LPUART_WriteNonBlocking(base, handle->txData, tempCount); + handle->txData += tempCount; + handle->txDataSize -= tempCount; + count -= tempCount; + + /* If all the data are written to data register, notify user with the callback, then TX finished. */ + if (!handle->txDataSize) + { + handle->txState = kLPUART_TxIdle; + + /* Disable TX register empty interrupt. */ + base->CTRL = (base->CTRL & ~LPUART_CTRL_TIE_MASK); + + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData); + } + } + } + } +} + +/*! + * brief LPUART Error IRQ handle function. + * + * This function handles the LPUART error IRQ request. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + */ +void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle) +{ + (void)base; + (void)handle; + + /* To be implemented by User. */ +} +#if defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1 +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART0_LPUART1_RX_DriverIRQHandler(void) +{ + if (CLOCK_isEnabledClock(s_lpuartClock[0])) + { + if ((LPUART_STAT_OR_MASK & LPUART0->STAT) || + ((LPUART_STAT_RDRF_MASK & LPUART0->STAT) && (LPUART_CTRL_RIE_MASK & LPUART0->CTRL))) + { + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); + } + } + if (CLOCK_isEnabledClock(s_lpuartClock[1])) + { + if ((LPUART_STAT_OR_MASK & LPUART1->STAT) || + ((LPUART_STAT_RDRF_MASK & LPUART1->STAT) && (LPUART_CTRL_RIE_MASK & LPUART1->CTRL))) + { + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); + } + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +void LPUART0_LPUART1_TX_DriverIRQHandler(void) +{ + if (CLOCK_isEnabledClock(s_lpuartClock[0])) + { + if ((LPUART_STAT_OR_MASK & LPUART0->STAT) || + ((LPUART0->STAT & LPUART_STAT_TDRE_MASK) && (LPUART0->CTRL & LPUART_CTRL_TIE_MASK))) + { + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); + } + } + if (CLOCK_isEnabledClock(s_lpuartClock[1])) + { + if ((LPUART_STAT_OR_MASK & LPUART1->STAT) || + ((LPUART1->STAT & LPUART_STAT_TDRE_MASK) && (LPUART1->CTRL & LPUART_CTRL_TIE_MASK))) + { + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); + } + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#else +void LPUART0_LPUART1_DriverIRQHandler(void) +{ + if (CLOCK_isEnabledClock(s_lpuartClock[0])) + { + if ((LPUART_STAT_OR_MASK & LPUART0->STAT) || + ((LPUART_STAT_RDRF_MASK & LPUART0->STAT) && (LPUART_CTRL_RIE_MASK & LPUART0->CTRL)) || + ((LPUART0->STAT & LPUART_STAT_TDRE_MASK) && (LPUART0->CTRL & LPUART_CTRL_TIE_MASK))) + { + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); + } + } + if (CLOCK_isEnabledClock(s_lpuartClock[1])) + { + if ((LPUART_STAT_OR_MASK & LPUART1->STAT) || + ((LPUART_STAT_RDRF_MASK & LPUART1->STAT) && (LPUART_CTRL_RIE_MASK & LPUART1->CTRL)) || + ((LPUART1->STAT & LPUART_STAT_TDRE_MASK) && (LPUART1->CTRL & LPUART_CTRL_TIE_MASK))) + { + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); + } + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif + +#if defined(LPUART0) +#if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART0_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +void LPUART0_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#else +void LPUART0_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif +#endif + +#if defined(LPUART1) +#if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART1_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +void LPUART1_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#else +void LPUART1_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif +#endif + +#if defined(LPUART2) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART2_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART2, s_lpuartHandle[2]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +void LPUART2_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART2, s_lpuartHandle[2]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#else +void LPUART2_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART2, s_lpuartHandle[2]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif + +#if defined(LPUART3) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART3_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART3, s_lpuartHandle[3]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +void LPUART3_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART3, s_lpuartHandle[3]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#else +void LPUART3_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART3, s_lpuartHandle[3]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif + +#if defined(LPUART4) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART4_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART4, s_lpuartHandle[4]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +void LPUART4_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART4, s_lpuartHandle[4]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#else +void LPUART4_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART4, s_lpuartHandle[4]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif + +#if defined(LPUART5) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART5_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART5, s_lpuartHandle[5]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +void LPUART5_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART5, s_lpuartHandle[5]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#else +void LPUART5_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART5, s_lpuartHandle[5]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif + +#if defined(LPUART6) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART6_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART6, s_lpuartHandle[6]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +void LPUART6_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART6, s_lpuartHandle[6]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#else +void LPUART6_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART6, s_lpuartHandle[6]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif + +#if defined(LPUART7) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART7_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART7, s_lpuartHandle[7]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +void LPUART7_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART7, s_lpuartHandle[7]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#else +void LPUART7_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART7, s_lpuartHandle[7]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif + +#if defined(LPUART8) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART8_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART8, s_lpuartHandle[8]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +void LPUART8_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART8, s_lpuartHandle[8]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#else +void LPUART8_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART8, s_lpuartHandle[8]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#endif + +#if defined(CM4_0__LPUART) +void M4_0_LPUART_DriverIRQHandler(void) +{ + s_lpuartIsr(CM4_0__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_0__LPUART)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(CM4_1__LPUART) +void M4_1_LPUART_DriverIRQHandler(void) +{ + s_lpuartIsr(CM4_1__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_1__LPUART)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(CM4__LPUART) +void M4_LPUART_DriverIRQHandler(void) +{ + s_lpuartIsr(CM4__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4__LPUART)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(DMA__LPUART0) +void DMA_UART0_INT_DriverIRQHandler(void) +{ + s_lpuartIsr(DMA__LPUART0, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART0)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(DMA__LPUART1) +void DMA_UART1_INT_DriverIRQHandler(void) +{ + s_lpuartIsr(DMA__LPUART1, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART1)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(DMA__LPUART2) +void DMA_UART2_INT_DriverIRQHandler(void) +{ + s_lpuartIsr(DMA__LPUART2, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART2)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(DMA__LPUART3) +void DMA_UART3_INT_DriverIRQHandler(void) +{ + s_lpuartIsr(DMA__LPUART3, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART3)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(DMA__LPUART4) +void DMA_UART4_INT_DriverIRQHandler(void) +{ + s_lpuartIsr(DMA__LPUART4, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART4)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(ADMA__LPUART0) +void ADMA_UART0_INT_DriverIRQHandler(void) +{ + s_lpuartIsr(ADMA__LPUART0, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART0)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(ADMA__LPUART1) +void ADMA_UART1_INT_DriverIRQHandler(void) +{ + s_lpuartIsr(ADMA__LPUART1, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART1)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(ADMA__LPUART2) +void ADMA_UART2_INT_DriverIRQHandler(void) +{ + s_lpuartIsr(ADMA__LPUART2, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART2)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(ADMA__LPUART3) +void ADMA_UART3_INT_DriverIRQHandler(void) +{ + s_lpuartIsr(ADMA__LPUART3, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART3)]); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +uint32_t GetSrcFreq(void) +{ + uint32_t freq; + + /* To make it simple, we assume default PLL and divider settings, and the only variable + from application is use PLL3 source or OSC source */ + if (CLOCK_GetMux(kCLOCK_UartMux) == 0) /* PLL3 div6 80M */ + { + freq = (CLOCK_GetPllFreq(kCLOCK_PllUsb1) / 6U) / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); + } + else + { + freq = CLOCK_GetOscFreq() / (CLOCK_GetDiv(kCLOCK_UartDiv) + 1U); + } + + return freq; +} + diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_lpuart.h b/targets/FreeRTOS/GC5/common/drivers/fsl_lpuart.h similarity index 97% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_lpuart.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_lpuart.h index 5678812a9d..d68e6e5cdb 100644 --- a/targets/FreeRTOS/UAC18/common/drivers/fsl_lpuart.h +++ b/targets/FreeRTOS/GC5/common/drivers/fsl_lpuart.h @@ -1,855 +1,858 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015-2016, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2017 NXP. All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#ifndef _FSL_LPUART_H_ -#define _FSL_LPUART_H_ - -#include "fsl_common.h" - -/*! - * @addtogroup lpuart_driver - * @{ - */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/*! @name Driver version */ -/*@{*/ -/*! @brief LPUART driver version 2.2.6. */ -#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 6)) -/*@}*/ - -/*! @brief Error codes for the LPUART driver. */ -enum _lpuart_status -{ - kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */ - kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */ - kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */ - kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */ - kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */ - kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */ - kStatus_LPUART_FlagCannotClearManually = MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */ - kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */ - kStatus_LPUART_RxRingBufferOverrun = - MAKE_STATUS(kStatusGroup_LPUART, 8), /*!< LPUART RX software ring buffer overrun. */ - kStatus_LPUART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPUART, 9), /*!< LPUART RX receiver overrun. */ - kStatus_LPUART_NoiseError = MAKE_STATUS(kStatusGroup_LPUART, 10), /*!< LPUART noise error. */ - kStatus_LPUART_FramingError = MAKE_STATUS(kStatusGroup_LPUART, 11), /*!< LPUART framing error. */ - kStatus_LPUART_ParityError = MAKE_STATUS(kStatusGroup_LPUART, 12), /*!< LPUART parity error. */ - kStatus_LPUART_BaudrateNotSupport = - MAKE_STATUS(kStatusGroup_LPUART, 13), /*!< Baudrate is not support in current clock source */ - kStatus_LPUART_IdleLineDetected = MAKE_STATUS(kStatusGroup_LPUART, 14), /*!< IDLE flag. */ -}; - -/*! @brief LPUART parity mode. */ -typedef enum _lpuart_parity_mode -{ - kLPUART_ParityDisabled = 0x0U, /*!< Parity disabled */ - kLPUART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */ - kLPUART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */ -} lpuart_parity_mode_t; - -/*! @brief LPUART data bits count. */ -typedef enum _lpuart_data_bits -{ - kLPUART_EightDataBits = 0x0U, /*!< Eight data bit */ -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - kLPUART_SevenDataBits = 0x1U, /*!< Seven data bit */ -#endif -} lpuart_data_bits_t; - -/*! @brief LPUART stop bit count. */ -typedef enum _lpuart_stop_bit_count -{ - kLPUART_OneStopBit = 0U, /*!< One stop bit */ - kLPUART_TwoStopBit = 1U, /*!< Two stop bits */ -} lpuart_stop_bit_count_t; - -#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT -/*! @brief LPUART transmit CTS source. */ -typedef enum _lpuart_transmit_cts_source -{ - kLPUART_CtsSourcePin = 0U, /*!< CTS resource is the LPUART_CTS pin. */ - kLPUART_CtsSourceMatchResult = 1U, /*!< CTS resource is the match result. */ -} lpuart_transmit_cts_source_t; - -/*! @brief LPUART transmit CTS configure. */ -typedef enum _lpuart_transmit_cts_config -{ - kLPUART_CtsSampleAtStart = 0U, /*!< CTS input is sampled at the start of each character. */ - kLPUART_CtsSampleAtIdle = 1U, /*!< CTS input is sampled when the transmitter is idle */ -} lpuart_transmit_cts_config_t; -#endif - -/*! @brief LPUART idle flag type defines when the receiver starts counting. */ -typedef enum _lpuart_idle_type_select -{ - kLPUART_IdleTypeStartBit = 0U, /*!< Start counting after a valid start bit. */ - kLPUART_IdleTypeStopBit = 1U, /*!< Start counting after a stop bit. */ -} lpuart_idle_type_select_t; - -/*! @brief LPUART idle detected configuration. - * This structure defines the number of idle characters that must be received before - * the IDLE flag is set. - */ -typedef enum _lpuart_idle_config -{ - kLPUART_IdleCharacter1 = 0U, /*!< the number of idle characters. */ - kLPUART_IdleCharacter2 = 1U, /*!< the number of idle characters. */ - kLPUART_IdleCharacter4 = 2U, /*!< the number of idle characters. */ - kLPUART_IdleCharacter8 = 3U, /*!< the number of idle characters. */ - kLPUART_IdleCharacter16 = 4U, /*!< the number of idle characters. */ - kLPUART_IdleCharacter32 = 5U, /*!< the number of idle characters. */ - kLPUART_IdleCharacter64 = 6U, /*!< the number of idle characters. */ - kLPUART_IdleCharacter128 = 7U, /*!< the number of idle characters. */ -} lpuart_idle_config_t; - -/*! - * @brief LPUART interrupt configuration structure, default settings all disabled. - * - * This structure contains the settings for all LPUART interrupt configurations. - */ -enum _lpuart_interrupt_enable -{ -#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - kLPUART_LinBreakInterruptEnable = (LPUART_BAUD_LBKDIE_MASK >> 8), /*!< LIN break detect. */ -#endif - kLPUART_RxActiveEdgeInterruptEnable = (LPUART_BAUD_RXEDGIE_MASK >> 8), /*!< Receive Active Edge. */ - kLPUART_TxDataRegEmptyInterruptEnable = (LPUART_CTRL_TIE_MASK), /*!< Transmit data register empty. */ - kLPUART_TransmissionCompleteInterruptEnable = (LPUART_CTRL_TCIE_MASK), /*!< Transmission complete. */ - kLPUART_RxDataRegFullInterruptEnable = (LPUART_CTRL_RIE_MASK), /*!< Receiver data register full. */ - kLPUART_IdleLineInterruptEnable = (LPUART_CTRL_ILIE_MASK), /*!< Idle line. */ - kLPUART_RxOverrunInterruptEnable = (LPUART_CTRL_ORIE_MASK), /*!< Receiver Overrun. */ - kLPUART_NoiseErrorInterruptEnable = (LPUART_CTRL_NEIE_MASK), /*!< Noise error flag. */ - kLPUART_FramingErrorInterruptEnable = (LPUART_CTRL_FEIE_MASK), /*!< Framing error flag. */ - kLPUART_ParityErrorInterruptEnable = (LPUART_CTRL_PEIE_MASK), /*!< Parity error flag. */ -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - kLPUART_TxFifoOverflowInterruptEnable = (LPUART_FIFO_TXOFE_MASK >> 8), /*!< Transmit FIFO Overflow. */ - kLPUART_RxFifoUnderflowInterruptEnable = (LPUART_FIFO_RXUFE_MASK >> 8), /*!< Receive FIFO Underflow. */ -#endif -}; - -/*! - * @brief LPUART status flags. - * - * This provides constants for the LPUART status flags for use in the LPUART functions. - */ -enum _lpuart_flags -{ - kLPUART_TxDataRegEmptyFlag = - (LPUART_STAT_TDRE_MASK), /*!< Transmit data register empty flag, sets when transmit buffer is empty */ - kLPUART_TransmissionCompleteFlag = - (LPUART_STAT_TC_MASK), /*!< Transmission complete flag, sets when transmission activity complete */ - kLPUART_RxDataRegFullFlag = - (LPUART_STAT_RDRF_MASK), /*!< Receive data register full flag, sets when the receive data buffer is full */ - kLPUART_IdleLineFlag = (LPUART_STAT_IDLE_MASK), /*!< Idle line detect flag, sets when idle line detected */ - kLPUART_RxOverrunFlag = (LPUART_STAT_OR_MASK), /*!< Receive Overrun, sets when new data is received before data is - read from receive register */ - kLPUART_NoiseErrorFlag = (LPUART_STAT_NF_MASK), /*!< Receive takes 3 samples of each received bit. If any of these - samples differ, noise flag sets */ - kLPUART_FramingErrorFlag = - (LPUART_STAT_FE_MASK), /*!< Frame error flag, sets if logic 0 was detected where stop bit expected */ - kLPUART_ParityErrorFlag = (LPUART_STAT_PF_MASK), /*!< If parity enabled, sets upon parity error detection */ -#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - kLPUART_LinBreakFlag = - (int)(LPUART_STAT_LBKDIF_MASK), /*!< LIN break detect interrupt flag, sets when LIN break char - detected and LIN circuit enabled */ -#endif - kLPUART_RxActiveEdgeFlag = - (LPUART_STAT_RXEDGIF_MASK), /*!< Receive pin active edge interrupt flag, sets when active edge detected */ - kLPUART_RxActiveFlag = - (LPUART_STAT_RAF_MASK), /*!< Receiver Active Flag (RAF), sets at beginning of valid start bit */ -#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING - kLPUART_DataMatch1Flag = LPUART_STAT_MA1F_MASK, /*!< The next character to be read from LPUART_DATA matches MA1*/ - kLPUART_DataMatch2Flag = LPUART_STAT_MA2F_MASK, /*!< The next character to be read from LPUART_DATA matches MA2*/ -#endif -#if defined(FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS - kLPUART_NoiseErrorInRxDataRegFlag = - (LPUART_DATA_NOISY_MASK >> 10), /*!< NOISY bit, sets if noise detected in current data word */ - kLPUART_ParityErrorInRxDataRegFlag = - (LPUART_DATA_PARITYE_MASK >> 10), /*!< PARITYE bit, sets if noise detected in current data word */ -#endif -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - kLPUART_TxFifoEmptyFlag = (LPUART_FIFO_TXEMPT_MASK >> 16), /*!< TXEMPT bit, sets if transmit buffer is empty */ - kLPUART_RxFifoEmptyFlag = (LPUART_FIFO_RXEMPT_MASK >> 16), /*!< RXEMPT bit, sets if receive buffer is empty */ - kLPUART_TxFifoOverflowFlag = - (LPUART_FIFO_TXOF_MASK >> 16), /*!< TXOF bit, sets if transmit buffer overflow occurred */ - kLPUART_RxFifoUnderflowFlag = - (LPUART_FIFO_RXUF_MASK >> 16), /*!< RXUF bit, sets if receive buffer underflow occurred */ -#endif -}; - -/*! @brief LPUART configuration structure. */ -typedef struct _lpuart_config -{ - uint32_t baudRate_Bps; /*!< LPUART baud rate */ - lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */ - lpuart_data_bits_t dataBitsCount; /*!< Data bits count, eight (default), seven */ - bool isMsb; /*!< Data bits order, LSB (default), MSB */ -#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT - lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */ -#endif -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - uint8_t txFifoWatermark; /*!< TX FIFO watermark */ - uint8_t rxFifoWatermark; /*!< RX FIFO watermark */ -#endif -#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT - bool enableRxRTS; /*!< RX RTS enable */ - bool enableTxCTS; /*!< TX CTS enable */ - lpuart_transmit_cts_source_t txCtsSource; /*!< TX CTS source */ - lpuart_transmit_cts_config_t txCtsConfig; /*!< TX CTS configure */ -#endif - lpuart_idle_type_select_t rxIdleType; /*!< RX IDLE type. */ - lpuart_idle_config_t rxIdleConfig; /*!< RX IDLE configuration. */ - bool enableTx; /*!< Enable TX */ - bool enableRx; /*!< Enable RX */ -} lpuart_config_t; - -/*! @brief LPUART transfer structure. */ -typedef struct _lpuart_transfer -{ - uint8_t *data; /*!< The buffer of data to be transfer.*/ - size_t dataSize; /*!< The byte count to be transfer. */ -} lpuart_transfer_t; - -/* Forward declaration of the handle typedef. */ -typedef struct _lpuart_handle lpuart_handle_t; - -/*! @brief LPUART transfer callback function. */ -typedef void (*lpuart_transfer_callback_t)(LPUART_Type *base, lpuart_handle_t *handle, status_t status, void *userData); - -/*! @brief LPUART handle structure. */ -struct _lpuart_handle -{ - uint8_t *volatile txData; /*!< Address of remaining data to send. */ - volatile size_t txDataSize; /*!< Size of the remaining data to send. */ - size_t txDataSizeAll; /*!< Size of the data to send out. */ - uint8_t *volatile rxData; /*!< Address of remaining data to receive. */ - volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */ - size_t rxDataSizeAll; /*!< Size of the data to receive. */ - - uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */ - size_t rxRingBufferSize; /*!< Size of the ring buffer. */ - volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */ - volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */ - - lpuart_transfer_callback_t callback; /*!< Callback function. */ - void *userData; /*!< LPUART callback function parameter.*/ - - volatile uint8_t txState; /*!< TX transfer state. */ - volatile uint8_t rxState; /*!< RX transfer state. */ - -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - bool isSevenDataBits; /*!< Seven data bits flag. */ -#endif -}; - -/******************************************************************************* - * API - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif /* _cplusplus */ - -#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL - -/*! - * @name Software Reset - * @{ - */ - -/*! - * @brief Resets the LPUART using software. - * - * This function resets all internal logic and registers except the Global Register. - * Remains set until cleared by software. - * - * @param base LPUART peripheral base address. - */ -static inline void LPUART_SoftwareReset(LPUART_Type *base) -{ - base->GLOBAL |= LPUART_GLOBAL_RST_MASK; - base->GLOBAL &= ~LPUART_GLOBAL_RST_MASK; -} -/* @} */ -#endif /*FSL_FEATURE_LPUART_HAS_GLOBAL*/ - -/*! - * @name Initialization and deinitialization - * @{ - */ - -/*! - * @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock. - * - * This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function - * to configure the configuration structure and get the default configuration. - * The example below shows how to use this API to configure the LPUART. - * @code - * lpuart_config_t lpuartConfig; - * lpuartConfig.baudRate_Bps = 115200U; - * lpuartConfig.parityMode = kLPUART_ParityDisabled; - * lpuartConfig.dataBitsCount = kLPUART_EightDataBits; - * lpuartConfig.isMsb = false; - * lpuartConfig.stopBitCount = kLPUART_OneStopBit; - * lpuartConfig.txFifoWatermark = 0; - * lpuartConfig.rxFifoWatermark = 1; - * LPUART_Init(LPUART1, &lpuartConfig, 20000000U); - * @endcode - * - * @param base LPUART peripheral base address. - * @param config Pointer to a user-defined configuration structure. - * @param srcClock_Hz LPUART clock source frequency in HZ. - * @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source. - * @retval kStatus_Success LPUART initialize succeed - */ -status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz); - -/*! - * @brief Deinitializes a LPUART instance. - * - * This function waits for transmit to complete, disables TX and RX, and disables the LPUART clock. - * - * @param base LPUART peripheral base address. - */ -void LPUART_Deinit(LPUART_Type *base); - -/*! - * @brief Gets the default configuration structure. - * - * This function initializes the LPUART configuration structure to a default value. The default - * values are: - * lpuartConfig->baudRate_Bps = 115200U; - * lpuartConfig->parityMode = kLPUART_ParityDisabled; - * lpuartConfig->dataBitsCount = kLPUART_EightDataBits; - * lpuartConfig->isMsb = false; - * lpuartConfig->stopBitCount = kLPUART_OneStopBit; - * lpuartConfig->txFifoWatermark = 0; - * lpuartConfig->rxFifoWatermark = 1; - * lpuartConfig->rxIdleType = kLPUART_IdleTypeStartBit; - * lpuartConfig->rxIdleConfig = kLPUART_IdleCharacter1; - * lpuartConfig->enableTx = false; - * lpuartConfig->enableRx = false; - * - * @param config Pointer to a configuration structure. - */ -void LPUART_GetDefaultConfig(lpuart_config_t *config); - -/*! - * @brief Sets the LPUART instance baudrate. - * - * This function configures the LPUART module baudrate. This function is used to update - * the LPUART module baudrate after the LPUART module is initialized by the LPUART_Init. - * @code - * LPUART_SetBaudRate(LPUART1, 115200U, 20000000U); - * @endcode - * - * @param base LPUART peripheral base address. - * @param baudRate_Bps LPUART baudrate to be set. - * @param srcClock_Hz LPUART clock source frequency in HZ. - * @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not supported in the current clock source. - * @retval kStatus_Success Set baudrate succeeded. - */ -status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); - -/* @} */ - -/*! - * @name Status - * @{ - */ - -/*! - * @brief Gets LPUART status flags. - * - * This function gets all LPUART status flags. The flags are returned as the logical - * OR value of the enumerators @ref _lpuart_flags. To check for a specific status, - * compare the return value with enumerators in the @ref _lpuart_flags. - * For example, to check whether the TX is empty: - * @code - * if (kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1)) - * { - * ... - * } - * @endcode - * - * @param base LPUART peripheral base address. - * @return LPUART status flags which are ORed by the enumerators in the _lpuart_flags. - */ -uint32_t LPUART_GetStatusFlags(LPUART_Type *base); - -/*! - * @brief Clears status flags with a provided mask. - * - * This function clears LPUART status flags with a provided mask. Automatically cleared flags - * can't be cleared by this function. - * Flags that can only cleared or set by hardware are: - * kLPUART_TxDataRegEmptyFlag, kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, - * kLPUART_RxActiveFlag, kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, - * kLPUART_TxFifoEmptyFlag,kLPUART_RxFifoEmptyFlag - * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects. - * - * @param base LPUART peripheral base address. - * @param mask the status flags to be cleared. The user can use the enumerators in the - * _lpuart_status_flag_t to do the OR operation and get the mask. - * @return 0 succeed, others failed. - * @retval kStatus_LPUART_FlagCannotClearManually The flag can't be cleared by this function but - * it is cleared automatically by hardware. - * @retval kStatus_Success Status in the mask are cleared. - */ -status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask); - -/* @} */ - -/*! - * @name Interrupts - * @{ - */ - -/*! - * @brief Enables LPUART interrupts according to a provided mask. - * - * This function enables the LPUART interrupts according to a provided mask. The mask - * is a logical OR of enumeration members. See the @ref _lpuart_interrupt_enable. - * This examples shows how to enable TX empty interrupt and RX full interrupt: - * @code - * LPUART_EnableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); - * @endcode - * - * @param base LPUART peripheral base address. - * @param mask The interrupts to enable. Logical OR of @ref _uart_interrupt_enable. - */ -void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask); - -/*! - * @brief Disables LPUART interrupts according to a provided mask. - * - * This function disables the LPUART interrupts according to a provided mask. The mask - * is a logical OR of enumeration members. See @ref _lpuart_interrupt_enable. - * This example shows how to disable the TX empty interrupt and RX full interrupt: - * @code - * LPUART_DisableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); - * @endcode - * - * @param base LPUART peripheral base address. - * @param mask The interrupts to disable. Logical OR of @ref _lpuart_interrupt_enable. - */ -void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask); - -/*! - * @brief Gets enabled LPUART interrupts. - * - * This function gets the enabled LPUART interrupts. The enabled interrupts are returned - * as the logical OR value of the enumerators @ref _lpuart_interrupt_enable. To check - * a specific interrupt enable status, compare the return value with enumerators - * in @ref _lpuart_interrupt_enable. - * For example, to check whether the TX empty interrupt is enabled: - * @code - * uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(LPUART1); - * - * if (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts) - * { - * ... - * } - * @endcode - * - * @param base LPUART peripheral base address. - * @return LPUART interrupt flags which are logical OR of the enumerators in @ref _lpuart_interrupt_enable. - */ -uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base); - -#if defined(FSL_FEATURE_LPUART_HAS_DMA_ENABLE) && FSL_FEATURE_LPUART_HAS_DMA_ENABLE -/*! - * @brief Gets the LPUART data register address. - * - * This function returns the LPUART data register address, which is mainly used by the DMA/eDMA. - * - * @param base LPUART peripheral base address. - * @return LPUART data register addresses which are used both by the transmitter and receiver. - */ -static inline uint32_t LPUART_GetDataRegisterAddress(LPUART_Type *base) -{ - return (uint32_t) & (base->DATA); -} - -/*! - * @brief Enables or disables the LPUART transmitter DMA request. - * - * This function enables or disables the transmit data register empty flag, STAT[TDRE], to generate DMA requests. - * - * @param base LPUART peripheral base address. - * @param enable True to enable, false to disable. - */ -static inline void LPUART_EnableTxDMA(LPUART_Type *base, bool enable) -{ - if (enable) - { - base->BAUD |= LPUART_BAUD_TDMAE_MASK; - } - else - { - base->BAUD &= ~LPUART_BAUD_TDMAE_MASK; - } -} - -/*! - * @brief Enables or disables the LPUART receiver DMA. - * - * This function enables or disables the receiver data register full flag, STAT[RDRF], to generate DMA requests. - * - * @param base LPUART peripheral base address. - * @param enable True to enable, false to disable. - */ -static inline void LPUART_EnableRxDMA(LPUART_Type *base, bool enable) -{ - if (enable) - { - base->BAUD |= LPUART_BAUD_RDMAE_MASK; - } - else - { - base->BAUD &= ~LPUART_BAUD_RDMAE_MASK; - } -} - -/* @} */ -#endif /* FSL_FEATURE_LPUART_HAS_DMA_ENABLE */ - -/*! - * @name Bus Operations - * @{ - */ - -/*! - * @brief Get the LPUART instance from peripheral base address. - * - * @param base LPUART peripheral base address. - * @return LPUART instance. - */ -uint32_t LPUART_GetInstance(LPUART_Type *base); - -/*! - * @brief Enables or disables the LPUART transmitter. - * - * This function enables or disables the LPUART transmitter. - * - * @param base LPUART peripheral base address. - * @param enable True to enable, false to disable. - */ -static inline void LPUART_EnableTx(LPUART_Type *base, bool enable) -{ - if (enable) - { - base->CTRL |= LPUART_CTRL_TE_MASK; - } - else - { - base->CTRL &= ~LPUART_CTRL_TE_MASK; - } -} - -/*! - * @brief Enables or disables the LPUART receiver. - * - * This function enables or disables the LPUART receiver. - * - * @param base LPUART peripheral base address. - * @param enable True to enable, false to disable. - */ -static inline void LPUART_EnableRx(LPUART_Type *base, bool enable) -{ - if (enable) - { - base->CTRL |= LPUART_CTRL_RE_MASK; - } - else - { - base->CTRL &= ~LPUART_CTRL_RE_MASK; - } -} - -/*! - * @brief Writes to the transmitter register. - * - * This function writes data to the transmitter register directly. The upper layer must - * ensure that the TX register is empty or that the TX FIFO has room before calling this function. - * - * @param base LPUART peripheral base address. - * @param data Data write to the TX register. - */ -static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data) -{ - base->DATA = data; -} - -/*! - * @brief Reads the receiver register. - * - * This function reads data from the receiver register directly. The upper layer must - * ensure that the receiver register is full or that the RX FIFO has data before calling this function. - * - * @param base LPUART peripheral base address. - * @return Data read from data register. - */ -static inline uint8_t LPUART_ReadByte(LPUART_Type *base) -{ -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - uint32_t ctrl = base->CTRL; - bool isSevenDataBits = - ((ctrl & LPUART_CTRL_M7_MASK) || - ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); - - if (isSevenDataBits) - { - return (base->DATA & 0x7F); - } - else - { - return base->DATA; - } -#else - return base->DATA; -#endif -} - -/*! - * @brief Writes to the transmitter register using a blocking method. - * - * This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have - * room, and writes data to the transmitter buffer. - * - * @note This function does not check whether all data has been sent out to the bus. - * Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is - * finished. - * - * @param base LPUART peripheral base address. - * @param data Start address of the data to write. - * @param length Size of the data to write. - */ -void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length); - -/*! -* @brief Reads the receiver data register using a blocking method. - * - * This function polls the receiver register, waits for the receiver register full or receiver FIFO - * has data, and reads data from the TX register. - * - * @param base LPUART peripheral base address. - * @param data Start address of the buffer to store the received data. - * @param length Size of the buffer. - * @retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data. - * @retval kStatus_LPUART_NoiseError Noise error happened while receiving data. - * @retval kStatus_LPUART_FramingError Framing error happened while receiving data. - * @retval kStatus_LPUART_ParityError Parity error happened while receiving data. - * @retval kStatus_Success Successfully received all data. - */ -status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length); - -/* @} */ - -/*! - * @name Transactional - * @{ - */ - -/*! - * @brief Initializes the LPUART handle. - * - * This function initializes the LPUART handle, which can be used for other LPUART - * transactional APIs. Usually, for a specified LPUART instance, - * call this API once to get the initialized handle. - * - * The LPUART driver supports the "background" receiving, which means that user can set up - * an RX ring buffer optionally. Data received is stored into the ring buffer even when the - * user doesn't call the LPUART_TransferReceiveNonBlocking() API. If there is already data received - * in the ring buffer, the user can get the received data from the ring buffer directly. - * The ring buffer is disabled if passing NULL as @p ringBuffer. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - * @param callback Callback function. - * @param userData User data. - */ -void LPUART_TransferCreateHandle(LPUART_Type *base, - lpuart_handle_t *handle, - lpuart_transfer_callback_t callback, - void *userData); -/*! - * @brief Transmits a buffer of data using the interrupt method. - * - * This function send data using an interrupt method. This is a non-blocking function, which - * returns directly without waiting for all data written to the transmitter register. When - * all data is written to the TX register in the ISR, the LPUART driver calls the callback - * function and passes the @ref kStatus_LPUART_TxIdle as status parameter. - * - * @note The kStatus_LPUART_TxIdle is passed to the upper layer when all data are written - * to the TX register. However, there is no check to ensure that all the data sent out. Before disabling the TX, - * check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is finished. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - * @param xfer LPUART transfer structure, see #lpuart_transfer_t. - * @retval kStatus_Success Successfully start the data transmission. - * @retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register. - * @retval kStatus_InvalidArgument Invalid argument. - */ -status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer); - -/*! - * @brief Sets up the RX ring buffer. - * - * This function sets up the RX ring buffer to a specific UART handle. - * - * When the RX ring buffer is used, data received is stored into the ring buffer even when - * the user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received - * in the ring buffer, the user can get the received data from the ring buffer directly. - * - * @note When using RX ring buffer, one byte is reserved for internal use. In other - * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - * @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer. - * @param ringBufferSize size of the ring buffer. - */ -void LPUART_TransferStartRingBuffer(LPUART_Type *base, - lpuart_handle_t *handle, - uint8_t *ringBuffer, - size_t ringBufferSize); - -/*! - * @brief Aborts the background transfer and uninstalls the ring buffer. - * - * This function aborts the background transfer and uninstalls the ring buffer. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - */ -void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle); - -/*! - * @brief Get the length of received data in RX ring buffer. - * - * @param handle LPUART handle pointer. - * @return Length of received data in RX ring buffer. - */ -size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle); - -/*! - * @brief Aborts the interrupt-driven data transmit. - * - * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out - * how many bytes are not sent out. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - */ -void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle); - -/*! - * @brief Gets the number of bytes that have been written to the LPUART transmitter register. - * - * This function gets the number of bytes that have been written to LPUART TX - * register by an interrupt method. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - * @param count Send bytes count. - * @retval kStatus_NoTransferInProgress No send in progress. - * @retval kStatus_InvalidArgument Parameter is invalid. - * @retval kStatus_Success Get successfully through the parameter \p count; - */ -status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count); - -/*! - * @brief Receives a buffer of data using the interrupt method. - * - * This function receives data using an interrupt method. This is a non-blocking function - * which returns without waiting to ensure that all data are received. - * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and - * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer. - * After copying, if the data in the ring buffer is not enough for read, the receive - * request is saved by the LPUART driver. When the new data arrives, the receive request - * is serviced first. When all data is received, the LPUART driver notifies the upper layer - * through a callback function and passes a status parameter @ref kStatus_UART_RxIdle. - * For example, the upper layer needs 10 bytes but there are only 5 bytes in ring buffer. - * The 5 bytes are copied to xfer->data, which returns with the - * parameter @p receivedBytes set to 5. For the remaining 5 bytes, the newly arrived data is - * saved from xfer->data[5]. When 5 bytes are received, the LPUART driver notifies the upper layer. - * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt - * to receive data to xfer->data. When all data is received, the upper layer is notified. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - * @param xfer LPUART transfer structure, see #uart_transfer_t. - * @param receivedBytes Bytes received from the ring buffer directly. - * @retval kStatus_Success Successfully queue the transfer into the transmit queue. - * @retval kStatus_LPUART_RxBusy Previous receive request is not finished. - * @retval kStatus_InvalidArgument Invalid argument. - */ -status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, - lpuart_handle_t *handle, - lpuart_transfer_t *xfer, - size_t *receivedBytes); - -/*! - * @brief Aborts the interrupt-driven data receiving. - * - * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out - * how many bytes not received yet. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - */ -void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle); - -/*! - * @brief Gets the number of bytes that have been received. - * - * This function gets the number of bytes that have been received. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - * @param count Receive bytes count. - * @retval kStatus_NoTransferInProgress No receive in progress. - * @retval kStatus_InvalidArgument Parameter is invalid. - * @retval kStatus_Success Get successfully through the parameter \p count; - */ -status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count); - -/*! - * @brief LPUART IRQ handle function. - * - * This function handles the LPUART transmit and receive IRQ request. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - */ -void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle); - -/*! - * @brief LPUART Error IRQ handle function. - * - * This function handles the LPUART error IRQ request. - * - * @param base LPUART peripheral base address. - * @param handle LPUART handle pointer. - */ -void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle); - -/* @} */ - -#if defined(__cplusplus) -} -#endif - -/*! @}*/ - -#endif /* _FSL_LPUART_H_ */ +// +// Copyright (c) 2019 The nanoFramework project contributors +// Portions Copyright (c) 2015-2016, Freescale Semiconductor, Inc. All rights reserved. +// Portions Copyright 2016-2017 NXP. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#ifndef _FSL_LPUART_H_ +#define _FSL_LPUART_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup lpuart_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief LPUART driver version 2.2.6. */ +#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 6)) +/*@}*/ + +/*! @brief Error codes for the LPUART driver. */ +enum _lpuart_status +{ + kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */ + kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */ + kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */ + kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */ + kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */ + kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */ + kStatus_LPUART_FlagCannotClearManually = MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */ + kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */ + kStatus_LPUART_RxRingBufferOverrun = + MAKE_STATUS(kStatusGroup_LPUART, 8), /*!< LPUART RX software ring buffer overrun. */ + kStatus_LPUART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPUART, 9), /*!< LPUART RX receiver overrun. */ + kStatus_LPUART_NoiseError = MAKE_STATUS(kStatusGroup_LPUART, 10), /*!< LPUART noise error. */ + kStatus_LPUART_FramingError = MAKE_STATUS(kStatusGroup_LPUART, 11), /*!< LPUART framing error. */ + kStatus_LPUART_ParityError = MAKE_STATUS(kStatusGroup_LPUART, 12), /*!< LPUART parity error. */ + kStatus_LPUART_BaudrateNotSupport = + MAKE_STATUS(kStatusGroup_LPUART, 13), /*!< Baudrate is not support in current clock source */ + kStatus_LPUART_IdleLineDetected = MAKE_STATUS(kStatusGroup_LPUART, 14), /*!< IDLE flag. */ +}; + +/*! @brief LPUART parity mode. */ +typedef enum _lpuart_parity_mode +{ + kLPUART_ParityDisabled = 0x0U, /*!< Parity disabled */ + kLPUART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */ + kLPUART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */ +} lpuart_parity_mode_t; + +/*! @brief LPUART data bits count. */ +typedef enum _lpuart_data_bits +{ + kLPUART_EightDataBits = 0x0U, /*!< Eight data bit */ +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + kLPUART_SevenDataBits = 0x1U, /*!< Seven data bit */ +#endif +} lpuart_data_bits_t; + +/*! @brief LPUART stop bit count. */ +typedef enum _lpuart_stop_bit_count +{ + kLPUART_OneStopBit = 0U, /*!< One stop bit */ + kLPUART_TwoStopBit = 1U, /*!< Two stop bits */ +} lpuart_stop_bit_count_t; + +#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT +/*! @brief LPUART transmit CTS source. */ +typedef enum _lpuart_transmit_cts_source +{ + kLPUART_CtsSourcePin = 0U, /*!< CTS resource is the LPUART_CTS pin. */ + kLPUART_CtsSourceMatchResult = 1U, /*!< CTS resource is the match result. */ +} lpuart_transmit_cts_source_t; + +/*! @brief LPUART transmit CTS configure. */ +typedef enum _lpuart_transmit_cts_config +{ + kLPUART_CtsSampleAtStart = 0U, /*!< CTS input is sampled at the start of each character. */ + kLPUART_CtsSampleAtIdle = 1U, /*!< CTS input is sampled when the transmitter is idle */ +} lpuart_transmit_cts_config_t; +#endif + +/*! @brief LPUART idle flag type defines when the receiver starts counting. */ +typedef enum _lpuart_idle_type_select +{ + kLPUART_IdleTypeStartBit = 0U, /*!< Start counting after a valid start bit. */ + kLPUART_IdleTypeStopBit = 1U, /*!< Start counting after a stop bit. */ +} lpuart_idle_type_select_t; + +/*! @brief LPUART idle detected configuration. + * This structure defines the number of idle characters that must be received before + * the IDLE flag is set. + */ +typedef enum _lpuart_idle_config +{ + kLPUART_IdleCharacter1 = 0U, /*!< the number of idle characters. */ + kLPUART_IdleCharacter2 = 1U, /*!< the number of idle characters. */ + kLPUART_IdleCharacter4 = 2U, /*!< the number of idle characters. */ + kLPUART_IdleCharacter8 = 3U, /*!< the number of idle characters. */ + kLPUART_IdleCharacter16 = 4U, /*!< the number of idle characters. */ + kLPUART_IdleCharacter32 = 5U, /*!< the number of idle characters. */ + kLPUART_IdleCharacter64 = 6U, /*!< the number of idle characters. */ + kLPUART_IdleCharacter128 = 7U, /*!< the number of idle characters. */ +} lpuart_idle_config_t; + +/*! + * @brief LPUART interrupt configuration structure, default settings all disabled. + * + * This structure contains the settings for all LPUART interrupt configurations. + */ +enum _lpuart_interrupt_enable +{ +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + kLPUART_LinBreakInterruptEnable = (LPUART_BAUD_LBKDIE_MASK >> 8), /*!< LIN break detect. */ +#endif + kLPUART_RxActiveEdgeInterruptEnable = (LPUART_BAUD_RXEDGIE_MASK >> 8), /*!< Receive Active Edge. */ + kLPUART_TxDataRegEmptyInterruptEnable = (LPUART_CTRL_TIE_MASK), /*!< Transmit data register empty. */ + kLPUART_TransmissionCompleteInterruptEnable = (LPUART_CTRL_TCIE_MASK), /*!< Transmission complete. */ + kLPUART_RxDataRegFullInterruptEnable = (LPUART_CTRL_RIE_MASK), /*!< Receiver data register full. */ + kLPUART_IdleLineInterruptEnable = (LPUART_CTRL_ILIE_MASK), /*!< Idle line. */ + kLPUART_RxOverrunInterruptEnable = (LPUART_CTRL_ORIE_MASK), /*!< Receiver Overrun. */ + kLPUART_NoiseErrorInterruptEnable = (LPUART_CTRL_NEIE_MASK), /*!< Noise error flag. */ + kLPUART_FramingErrorInterruptEnable = (LPUART_CTRL_FEIE_MASK), /*!< Framing error flag. */ + kLPUART_ParityErrorInterruptEnable = (LPUART_CTRL_PEIE_MASK), /*!< Parity error flag. */ +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + kLPUART_TxFifoOverflowInterruptEnable = (LPUART_FIFO_TXOFE_MASK >> 8), /*!< Transmit FIFO Overflow. */ + kLPUART_RxFifoUnderflowInterruptEnable = (LPUART_FIFO_RXUFE_MASK >> 8), /*!< Receive FIFO Underflow. */ +#endif +}; + +/*! + * @brief LPUART status flags. + * + * This provides constants for the LPUART status flags for use in the LPUART functions. + */ +enum _lpuart_flags +{ + kLPUART_TxDataRegEmptyFlag = + (LPUART_STAT_TDRE_MASK), /*!< Transmit data register empty flag, sets when transmit buffer is empty */ + kLPUART_TransmissionCompleteFlag = + (LPUART_STAT_TC_MASK), /*!< Transmission complete flag, sets when transmission activity complete */ + kLPUART_RxDataRegFullFlag = + (LPUART_STAT_RDRF_MASK), /*!< Receive data register full flag, sets when the receive data buffer is full */ + kLPUART_IdleLineFlag = (LPUART_STAT_IDLE_MASK), /*!< Idle line detect flag, sets when idle line detected */ + kLPUART_RxOverrunFlag = (LPUART_STAT_OR_MASK), /*!< Receive Overrun, sets when new data is received before data is + read from receive register */ + kLPUART_NoiseErrorFlag = (LPUART_STAT_NF_MASK), /*!< Receive takes 3 samples of each received bit. If any of these + samples differ, noise flag sets */ + kLPUART_FramingErrorFlag = + (LPUART_STAT_FE_MASK), /*!< Frame error flag, sets if logic 0 was detected where stop bit expected */ + kLPUART_ParityErrorFlag = (LPUART_STAT_PF_MASK), /*!< If parity enabled, sets upon parity error detection */ +#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT + kLPUART_LinBreakFlag = + (int)(LPUART_STAT_LBKDIF_MASK), /*!< LIN break detect interrupt flag, sets when LIN break char + detected and LIN circuit enabled */ +#endif + kLPUART_RxActiveEdgeFlag = + (LPUART_STAT_RXEDGIF_MASK), /*!< Receive pin active edge interrupt flag, sets when active edge detected */ + kLPUART_RxActiveFlag = + (LPUART_STAT_RAF_MASK), /*!< Receiver Active Flag (RAF), sets at beginning of valid start bit */ +#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING + kLPUART_DataMatch1Flag = LPUART_STAT_MA1F_MASK, /*!< The next character to be read from LPUART_DATA matches MA1*/ + kLPUART_DataMatch2Flag = LPUART_STAT_MA2F_MASK, /*!< The next character to be read from LPUART_DATA matches MA2*/ +#endif +#if defined(FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_LPUART_HAS_EXTENDED_DATA_REGISTER_FLAGS + kLPUART_NoiseErrorInRxDataRegFlag = + (LPUART_DATA_NOISY_MASK >> 10), /*!< NOISY bit, sets if noise detected in current data word */ + kLPUART_ParityErrorInRxDataRegFlag = + (LPUART_DATA_PARITYE_MASK >> 10), /*!< PARITYE bit, sets if noise detected in current data word */ +#endif +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + kLPUART_TxFifoEmptyFlag = (LPUART_FIFO_TXEMPT_MASK >> 16), /*!< TXEMPT bit, sets if transmit buffer is empty */ + kLPUART_RxFifoEmptyFlag = (LPUART_FIFO_RXEMPT_MASK >> 16), /*!< RXEMPT bit, sets if receive buffer is empty */ + kLPUART_TxFifoOverflowFlag = + (LPUART_FIFO_TXOF_MASK >> 16), /*!< TXOF bit, sets if transmit buffer overflow occurred */ + kLPUART_RxFifoUnderflowFlag = + (LPUART_FIFO_RXUF_MASK >> 16), /*!< RXUF bit, sets if receive buffer underflow occurred */ +#endif +}; + +/*! @brief LPUART configuration structure. */ +typedef struct _lpuart_config +{ + uint32_t baudRate_Bps; /*!< LPUART baud rate */ + lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */ + lpuart_data_bits_t dataBitsCount; /*!< Data bits count, eight (default), seven */ + bool isMsb; /*!< Data bits order, LSB (default), MSB */ +#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT + lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */ +#endif +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + uint8_t txFifoWatermark; /*!< TX FIFO watermark */ + uint8_t rxFifoWatermark; /*!< RX FIFO watermark */ +#endif +#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT + bool enableRxRTS; /*!< RX RTS enable */ + bool enableTxCTS; /*!< TX CTS enable */ + lpuart_transmit_cts_source_t txCtsSource; /*!< TX CTS source */ + lpuart_transmit_cts_config_t txCtsConfig; /*!< TX CTS configure */ +#endif + lpuart_idle_type_select_t rxIdleType; /*!< RX IDLE type. */ + lpuart_idle_config_t rxIdleConfig; /*!< RX IDLE configuration. */ + bool enableTx; /*!< Enable TX */ + bool enableRx; /*!< Enable RX */ +} lpuart_config_t; + +/*! @brief LPUART transfer structure. */ +typedef struct _lpuart_transfer +{ + uint8_t *data; /*!< The buffer of data to be transfer.*/ + size_t dataSize; /*!< The byte count to be transfer. */ +} lpuart_transfer_t; + +/* Forward declaration of the handle typedef. */ +typedef struct _lpuart_handle lpuart_handle_t; + +/*! @brief LPUART transfer callback function. */ +typedef void (*lpuart_transfer_callback_t)(LPUART_Type *base, lpuart_handle_t *handle, status_t status, void *userData); + +/*! @brief LPUART handle structure. */ +struct _lpuart_handle +{ + uint8_t *volatile txData; /*!< Address of remaining data to send. */ + volatile size_t txDataSize; /*!< Size of the remaining data to send. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + uint8_t *volatile rxData; /*!< Address of remaining data to receive. */ + volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + + uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */ + size_t rxRingBufferSize; /*!< Size of the ring buffer. */ + volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */ + volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */ + + lpuart_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< LPUART callback function parameter.*/ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state. */ + +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + bool isSevenDataBits; /*!< Seven data bits flag. */ +#endif +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL + +/*! + * @name Software Reset + * @{ + */ + +/*! + * @brief Resets the LPUART using software. + * + * This function resets all internal logic and registers except the Global Register. + * Remains set until cleared by software. + * + * @param base LPUART peripheral base address. + */ +static inline void LPUART_SoftwareReset(LPUART_Type *base) +{ + base->GLOBAL |= LPUART_GLOBAL_RST_MASK; + base->GLOBAL &= ~LPUART_GLOBAL_RST_MASK; +} +/* @} */ +#endif /*FSL_FEATURE_LPUART_HAS_GLOBAL*/ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock. + * + * This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function + * to configure the configuration structure and get the default configuration. + * The example below shows how to use this API to configure the LPUART. + * @code + * lpuart_config_t lpuartConfig; + * lpuartConfig.baudRate_Bps = 115200U; + * lpuartConfig.parityMode = kLPUART_ParityDisabled; + * lpuartConfig.dataBitsCount = kLPUART_EightDataBits; + * lpuartConfig.isMsb = false; + * lpuartConfig.stopBitCount = kLPUART_OneStopBit; + * lpuartConfig.txFifoWatermark = 0; + * lpuartConfig.rxFifoWatermark = 1; + * LPUART_Init(LPUART1, &lpuartConfig, 20000000U); + * @endcode + * + * @param base LPUART peripheral base address. + * @param config Pointer to a user-defined configuration structure. + * @param srcClock_Hz LPUART clock source frequency in HZ. + * @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source. + * @retval kStatus_Success LPUART initialize succeed + */ +status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief Deinitializes a LPUART instance. + * + * This function waits for transmit to complete, disables TX and RX, and disables the LPUART clock. + * + * @param base LPUART peripheral base address. + */ +void LPUART_Deinit(LPUART_Type *base); + +/*! + * @brief Gets the default configuration structure. + * + * This function initializes the LPUART configuration structure to a default value. The default + * values are: + * lpuartConfig->baudRate_Bps = 115200U; + * lpuartConfig->parityMode = kLPUART_ParityDisabled; + * lpuartConfig->dataBitsCount = kLPUART_EightDataBits; + * lpuartConfig->isMsb = false; + * lpuartConfig->stopBitCount = kLPUART_OneStopBit; + * lpuartConfig->txFifoWatermark = 0; + * lpuartConfig->rxFifoWatermark = 1; + * lpuartConfig->rxIdleType = kLPUART_IdleTypeStartBit; + * lpuartConfig->rxIdleConfig = kLPUART_IdleCharacter1; + * lpuartConfig->enableTx = false; + * lpuartConfig->enableRx = false; + * + * @param config Pointer to a configuration structure. + */ +void LPUART_GetDefaultConfig(lpuart_config_t *config); + +/*! + * @brief Sets the LPUART instance baudrate. + * + * This function configures the LPUART module baudrate. This function is used to update + * the LPUART module baudrate after the LPUART module is initialized by the LPUART_Init. + * @code + * LPUART_SetBaudRate(LPUART1, 115200U, 20000000U); + * @endcode + * + * @param base LPUART peripheral base address. + * @param baudRate_Bps LPUART baudrate to be set. + * @param srcClock_Hz LPUART clock source frequency in HZ. + * @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not supported in the current clock source. + * @retval kStatus_Success Set baudrate succeeded. + */ +status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets LPUART status flags. + * + * This function gets all LPUART status flags. The flags are returned as the logical + * OR value of the enumerators @ref _lpuart_flags. To check for a specific status, + * compare the return value with enumerators in the @ref _lpuart_flags. + * For example, to check whether the TX is empty: + * @code + * if (kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1)) + * { + * ... + * } + * @endcode + * + * @param base LPUART peripheral base address. + * @return LPUART status flags which are ORed by the enumerators in the _lpuart_flags. + */ +uint32_t LPUART_GetStatusFlags(LPUART_Type *base); + +/*! + * @brief Clears status flags with a provided mask. + * + * This function clears LPUART status flags with a provided mask. Automatically cleared flags + * can't be cleared by this function. + * Flags that can only cleared or set by hardware are: + * kLPUART_TxDataRegEmptyFlag, kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, + * kLPUART_RxActiveFlag, kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, + * kLPUART_TxFifoEmptyFlag,kLPUART_RxFifoEmptyFlag + * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects. + * + * @param base LPUART peripheral base address. + * @param mask the status flags to be cleared. The user can use the enumerators in the + * _lpuart_status_flag_t to do the OR operation and get the mask. + * @return 0 succeed, others failed. + * @retval kStatus_LPUART_FlagCannotClearManually The flag can't be cleared by this function but + * it is cleared automatically by hardware. + * @retval kStatus_Success Status in the mask are cleared. + */ +status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask); + +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables LPUART interrupts according to a provided mask. + * + * This function enables the LPUART interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See the @ref _lpuart_interrupt_enable. + * This examples shows how to enable TX empty interrupt and RX full interrupt: + * @code + * LPUART_EnableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); + * @endcode + * + * @param base LPUART peripheral base address. + * @param mask The interrupts to enable. Logical OR of @ref _uart_interrupt_enable. + */ +void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask); + +/*! + * @brief Disables LPUART interrupts according to a provided mask. + * + * This function disables the LPUART interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See @ref _lpuart_interrupt_enable. + * This example shows how to disable the TX empty interrupt and RX full interrupt: + * @code + * LPUART_DisableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); + * @endcode + * + * @param base LPUART peripheral base address. + * @param mask The interrupts to disable. Logical OR of @ref _lpuart_interrupt_enable. + */ +void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask); + +/*! + * @brief Gets enabled LPUART interrupts. + * + * This function gets the enabled LPUART interrupts. The enabled interrupts are returned + * as the logical OR value of the enumerators @ref _lpuart_interrupt_enable. To check + * a specific interrupt enable status, compare the return value with enumerators + * in @ref _lpuart_interrupt_enable. + * For example, to check whether the TX empty interrupt is enabled: + * @code + * uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(LPUART1); + * + * if (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts) + * { + * ... + * } + * @endcode + * + * @param base LPUART peripheral base address. + * @return LPUART interrupt flags which are logical OR of the enumerators in @ref _lpuart_interrupt_enable. + */ +uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base); + +#if defined(FSL_FEATURE_LPUART_HAS_DMA_ENABLE) && FSL_FEATURE_LPUART_HAS_DMA_ENABLE +/*! + * @brief Gets the LPUART data register address. + * + * This function returns the LPUART data register address, which is mainly used by the DMA/eDMA. + * + * @param base LPUART peripheral base address. + * @return LPUART data register addresses which are used both by the transmitter and receiver. + */ +static inline uint32_t LPUART_GetDataRegisterAddress(LPUART_Type *base) +{ + return (uint32_t) & (base->DATA); +} + +/*! + * @brief Enables or disables the LPUART transmitter DMA request. + * + * This function enables or disables the transmit data register empty flag, STAT[TDRE], to generate DMA requests. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableTxDMA(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->BAUD |= LPUART_BAUD_TDMAE_MASK; + } + else + { + base->BAUD &= ~LPUART_BAUD_TDMAE_MASK; + } +} + +/*! + * @brief Enables or disables the LPUART receiver DMA. + * + * This function enables or disables the receiver data register full flag, STAT[RDRF], to generate DMA requests. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableRxDMA(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->BAUD |= LPUART_BAUD_RDMAE_MASK; + } + else + { + base->BAUD &= ~LPUART_BAUD_RDMAE_MASK; + } +} + +/* @} */ +#endif /* FSL_FEATURE_LPUART_HAS_DMA_ENABLE */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Get the LPUART instance from peripheral base address. + * + * @param base LPUART peripheral base address. + * @return LPUART instance. + */ +uint32_t LPUART_GetInstance(LPUART_Type *base); + +/*! + * @brief Enables or disables the LPUART transmitter. + * + * This function enables or disables the LPUART transmitter. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableTx(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->CTRL |= LPUART_CTRL_TE_MASK; + } + else + { + base->CTRL &= ~LPUART_CTRL_TE_MASK; + } +} + +/*! + * @brief Enables or disables the LPUART receiver. + * + * This function enables or disables the LPUART receiver. + * + * @param base LPUART peripheral base address. + * @param enable True to enable, false to disable. + */ +static inline void LPUART_EnableRx(LPUART_Type *base, bool enable) +{ + if (enable) + { + base->CTRL |= LPUART_CTRL_RE_MASK; + } + else + { + base->CTRL &= ~LPUART_CTRL_RE_MASK; + } +} + +/*! + * @brief Writes to the transmitter register. + * + * This function writes data to the transmitter register directly. The upper layer must + * ensure that the TX register is empty or that the TX FIFO has room before calling this function. + * + * @param base LPUART peripheral base address. + * @param data Data write to the TX register. + */ +static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data) +{ + base->DATA = data; +} + +/*! + * @brief Reads the receiver register. + * + * This function reads data from the receiver register directly. The upper layer must + * ensure that the receiver register is full or that the RX FIFO has data before calling this function. + * + * @param base LPUART peripheral base address. + * @return Data read from data register. + */ +static inline uint8_t LPUART_ReadByte(LPUART_Type *base) +{ +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || + ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); + + if (isSevenDataBits) + { + return (base->DATA & 0x7F); + } + else + { + return base->DATA; + } +#else + return base->DATA; +#endif +} + +/*! + * @brief Writes to the transmitter register using a blocking method. + * + * This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have + * room, and writes data to the transmitter buffer. + * + * @note This function does not check whether all data has been sent out to the bus. + * Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is + * finished. + * + * @param base LPUART peripheral base address. + * @param data Start address of the data to write. + * @param length Size of the data to write. + */ +void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length); + +/*! +* @brief Reads the receiver data register using a blocking method. + * + * This function polls the receiver register, waits for the receiver register full or receiver FIFO + * has data, and reads data from the TX register. + * + * @param base LPUART peripheral base address. + * @param data Start address of the buffer to store the received data. + * @param length Size of the buffer. + * @retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data. + * @retval kStatus_LPUART_NoiseError Noise error happened while receiving data. + * @retval kStatus_LPUART_FramingError Framing error happened while receiving data. + * @retval kStatus_LPUART_ParityError Parity error happened while receiving data. + * @retval kStatus_Success Successfully received all data. + */ +status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length); + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the LPUART handle. + * + * This function initializes the LPUART handle, which can be used for other LPUART + * transactional APIs. Usually, for a specified LPUART instance, + * call this API once to get the initialized handle. + * + * The LPUART driver supports the "background" receiving, which means that user can set up + * an RX ring buffer optionally. Data received is stored into the ring buffer even when the + * user doesn't call the LPUART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * The ring buffer is disabled if passing NULL as @p ringBuffer. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param callback Callback function. + * @param userData User data. + */ +void LPUART_TransferCreateHandle(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_callback_t callback, + void *userData); +/*! + * @brief Transmits a buffer of data using the interrupt method. + * + * This function send data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data written to the transmitter register. When + * all data is written to the TX register in the ISR, the LPUART driver calls the callback + * function and passes the @ref kStatus_LPUART_TxIdle as status parameter. + * + * @note The kStatus_LPUART_TxIdle is passed to the upper layer when all data are written + * to the TX register. However, there is no check to ensure that all the data sent out. Before disabling the TX, + * check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is finished. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param xfer LPUART transfer structure, see #lpuart_transfer_t. + * @retval kStatus_Success Successfully start the data transmission. + * @retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer); + +/*! + * @brief Sets up the RX ring buffer. + * + * This function sets up the RX ring buffer to a specific UART handle. + * + * When the RX ring buffer is used, data received is stored into the ring buffer even when + * the user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * + * @note When using RX ring buffer, one byte is reserved for internal use. In other + * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer. + * @param ringBufferSize size of the ring buffer. + */ +void LPUART_TransferStartRingBuffer(LPUART_Type *base, + lpuart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize); + +/*! + * @brief Aborts the background transfer and uninstalls the ring buffer. + * + * This function aborts the background transfer and uninstalls the ring buffer. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Get the length of received data in RX ring buffer. + * + * @param handle LPUART handle pointer. + * @return Length of received data in RX ring buffer. + */ +size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Aborts the interrupt-driven data transmit. + * + * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out + * how many bytes are not sent out. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Gets the number of bytes that have been written to the LPUART transmitter register. + * + * This function gets the number of bytes that have been written to LPUART TX + * register by an interrupt method. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Send bytes count. + * @retval kStatus_NoTransferInProgress No send in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count); + +/*! + * @brief Receives a buffer of data using the interrupt method. + * + * This function receives data using an interrupt method. This is a non-blocking function + * which returns without waiting to ensure that all data are received. + * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and + * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer. + * After copying, if the data in the ring buffer is not enough for read, the receive + * request is saved by the LPUART driver. When the new data arrives, the receive request + * is serviced first. When all data is received, the LPUART driver notifies the upper layer + * through a callback function and passes a status parameter @ref kStatus_UART_RxIdle. + * For example, the upper layer needs 10 bytes but there are only 5 bytes in ring buffer. + * The 5 bytes are copied to xfer->data, which returns with the + * parameter @p receivedBytes set to 5. For the remaining 5 bytes, the newly arrived data is + * saved from xfer->data[5]. When 5 bytes are received, the LPUART driver notifies the upper layer. + * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt + * to receive data to xfer->data. When all data is received, the upper layer is notified. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param xfer LPUART transfer structure, see #uart_transfer_t. + * @param receivedBytes Bytes received from the ring buffer directly. + * @retval kStatus_Success Successfully queue the transfer into the transmit queue. + * @retval kStatus_LPUART_RxBusy Previous receive request is not finished. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, + lpuart_handle_t *handle, + lpuart_transfer_t *xfer, + size_t *receivedBytes); + +/*! + * @brief Aborts the interrupt-driven data receiving. + * + * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out + * how many bytes not received yet. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief Gets the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count); + +/*! + * @brief LPUART IRQ handle function. + * + * This function handles the LPUART transmit and receive IRQ request. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle); + +/*! + * @brief LPUART Error IRQ handle function. + * + * This function handles the LPUART error IRQ request. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + */ +void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle); + +uint32_t GetSrcFreq(void); + + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_LPUART_H_ */ diff --git a/targets/FreeRTOS/GC5/common/drivers/fsl_lpuart_edma.c b/targets/FreeRTOS/GC5/common/drivers/fsl_lpuart_edma.c new file mode 100644 index 0000000000..47668478e8 --- /dev/null +++ b/targets/FreeRTOS/GC5/common/drivers/fsl_lpuart_edma.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_lpuart_edma.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.lpuart_edma" +#endif + +/*base, lpuartPrivateHandle->handle); + + if (lpuartPrivateHandle->handle->callback) + { + lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle, + kStatus_LPUART_TxIdle, lpuartPrivateHandle->handle->userData); + } + } +} + +static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) +{ + assert(param); + + lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param; + + /* Avoid warning for unused parameters. */ + handle = handle; + tcds = tcds; + + if (transferDone) + { + /* Disable transfer. */ + LPUART_TransferAbortReceiveEDMA(lpuartPrivateHandle->base, lpuartPrivateHandle->handle); + + if (lpuartPrivateHandle->handle->callback) + { + lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle, + kStatus_LPUART_RxIdle, lpuartPrivateHandle->handle->userData); + } + } +} + +/*! + * brief Initializes the LPUART handle which is used in transactional functions. + * param base LPUART peripheral base address. + * param handle Pointer to lpuart_edma_handle_t structure. + * param callback Callback function. + * param userData User data. + * param txEdmaHandle User requested DMA handle for TX DMA transfer. + * param rxEdmaHandle User requested DMA handle for RX DMA transfer. + */ +void LPUART_TransferCreateHandleEDMA(LPUART_Type *base, + lpuart_edma_handle_t *handle, + lpuart_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txEdmaHandle, + edma_handle_t *rxEdmaHandle) +{ + assert(handle); + + uint32_t instance = LPUART_GetInstance(base); + + s_edmaPrivateHandle[instance].base = base; + s_edmaPrivateHandle[instance].handle = handle; + + memset(handle, 0, sizeof(*handle)); + + handle->rxState = kLPUART_RxIdle; + handle->txState = kLPUART_TxIdle; + + handle->rxEdmaHandle = rxEdmaHandle; + handle->txEdmaHandle = txEdmaHandle; + + handle->callback = callback; + handle->userData = userData; + +#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO + /* Note: + Take care of the RX FIFO, EDMA request only assert when received bytes + equal or more than RX water mark, there is potential issue if RX water + mark larger than 1. + For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and + 5 bytes are received. the last byte will be saved in FIFO but not trigger + EDMA transfer because the water mark is 2. + */ + if (rxEdmaHandle) + { + base->WATER &= (~LPUART_WATER_RXWATER_MASK); + } +#endif + + /* Configure TX. */ + if (txEdmaHandle) + { + EDMA_SetCallback(handle->txEdmaHandle, LPUART_SendEDMACallback, &s_edmaPrivateHandle[instance]); + } + + /* Configure RX. */ + if (rxEdmaHandle) + { + EDMA_SetCallback(handle->rxEdmaHandle, LPUART_ReceiveEDMACallback, &s_edmaPrivateHandle[instance]); + } +} + +/*! + * brief Sends data using eDMA. + * + * This function sends data using eDMA. This is a non-blocking function, which returns + * right away. When all data is sent, the send callback function is called. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + * param xfer LPUART eDMA transfer structure. See #lpuart_transfer_t. + * retval kStatus_Success if succeed, others failed. + * retval kStatus_LPUART_TxBusy Previous transfer on going. + * retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer) +{ + assert(handle); + assert(handle->txEdmaHandle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + + edma_transfer_config_t xferConfig; + status_t status; + + /* If previous TX not finished. */ + if (kLPUART_TxBusy == handle->txState) + { + status = kStatus_LPUART_TxBusy; + } + else + { + handle->txState = kLPUART_TxBusy; + handle->txDataSizeAll = xfer->dataSize; + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)LPUART_GetDataRegisterAddress(base), + sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_MemoryToPeripheral); + + /* Store the initially configured eDMA minor byte transfer count into the LPUART handle */ + handle->nbytes = sizeof(uint8_t); + + /* Submit transfer. */ + EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig); + EDMA_StartTransfer(handle->txEdmaHandle); + + /* Enable LPUART TX EDMA. */ + LPUART_EnableTxDMA(base, true); + + status = kStatus_Success; + } + + return status; +} + +/*! + * brief Receives data using eDMA. + * + * This function receives data using eDMA. This is non-blocking function, which returns + * right away. When all data is received, the receive callback function is called. + * + * param base LPUART peripheral base address. + * param handle Pointer to lpuart_edma_handle_t structure. + * param xfer LPUART eDMA transfer structure, see #lpuart_transfer_t. + * retval kStatus_Success if succeed, others fail. + * retval kStatus_LPUART_RxBusy Previous transfer ongoing. + * retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer) +{ + assert(handle); + assert(handle->rxEdmaHandle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + + edma_transfer_config_t xferConfig; + status_t status; + + /* If previous RX not finished. */ + if (kLPUART_RxBusy == handle->rxState) + { + status = kStatus_LPUART_RxBusy; + } + else + { + handle->rxState = kLPUART_RxBusy; + handle->rxDataSizeAll = xfer->dataSize; + + /* Prepare transfer. */ + EDMA_PrepareTransfer(&xferConfig, (void *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data, + sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory); + + /* Store the initially configured eDMA minor byte transfer count into the LPUART handle */ + handle->nbytes = sizeof(uint8_t); + + /* Submit transfer. */ + EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig); + EDMA_StartTransfer(handle->rxEdmaHandle); + + /* Enable LPUART RX EDMA. */ + LPUART_EnableRxDMA(base, true); + + status = kStatus_Success; + } + + return status; +} + +/*! + * brief Aborts the sent data using eDMA. + * + * This function aborts the sent data using eDMA. + * + * param base LPUART peripheral base address. + * param handle Pointer to lpuart_edma_handle_t structure. + */ +void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle) +{ + assert(handle); + assert(handle->txEdmaHandle); + + /* Disable LPUART TX EDMA. */ + LPUART_EnableTxDMA(base, false); + + /* Stop transfer. */ + EDMA_AbortTransfer(handle->txEdmaHandle); + + handle->txState = kLPUART_TxIdle; +} + +/*! + * brief Aborts the received data using eDMA. + * + * This function aborts the received data using eDMA. + * + * param base LPUART peripheral base address. + * param handle Pointer to lpuart_edma_handle_t structure. + */ +void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle) +{ + assert(handle); + assert(handle->rxEdmaHandle); + + /* Disable LPUART RX EDMA. */ + LPUART_EnableRxDMA(base, false); + + /* Stop transfer. */ + EDMA_AbortTransfer(handle->rxEdmaHandle); + + handle->rxState = kLPUART_RxIdle; +} + +/*! + * brief Gets the number of received bytes. + * + * This function gets the number of received bytes. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + * param count Receive bytes count. + * retval kStatus_NoTransferInProgress No receive in progress. + * retval kStatus_InvalidArgument Parameter is invalid. + * retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count) +{ + assert(handle); + assert(handle->rxEdmaHandle); + assert(count); + (void) base; + + if (kLPUART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->rxDataSizeAll - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel); + + return kStatus_Success; +} + +/*! + * brief Gets the number of bytes written to the LPUART TX register. + * + * This function gets the number of bytes written to the LPUART TX + * register by DMA. + * + * param base LPUART peripheral base address. + * param handle LPUART handle pointer. + * param count Send bytes count. + * retval kStatus_NoTransferInProgress No send in progress. + * retval kStatus_InvalidArgument Parameter is invalid. + * retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count) +{ + assert(handle); + assert(handle->txEdmaHandle); + assert(count); + (void) base; + + if (kLPUART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->txDataSizeAll - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel); + + return kStatus_Success; +} diff --git a/targets/FreeRTOS/GC5/common/drivers/fsl_lpuart_edma.h b/targets/FreeRTOS/GC5/common/drivers/fsl_lpuart_edma.h new file mode 100644 index 0000000000..70e456fbd8 --- /dev/null +++ b/targets/FreeRTOS/GC5/common/drivers/fsl_lpuart_edma.h @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _FSL_LPUART_EDMA_H_ +#define _FSL_LPUART_EDMA_H_ + +#include "fsl_lpuart.h" +#include "fsl_edma.h" + +/*! + * @addtogroup lpuart_edma_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief LPUART EDMA driver version 2.2.6. */ +#define FSL_LPUART_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 2, 6)) +/*@}*/ + +/* Forward declaration of the handle typedef. */ +typedef struct _lpuart_edma_handle lpuart_edma_handle_t; + +/*! @brief LPUART transfer callback function. */ +typedef void (*lpuart_edma_transfer_callback_t)(LPUART_Type *base, + lpuart_edma_handle_t *handle, + status_t status, + void *userData); + +/*! +* @brief LPUART eDMA handle +*/ +struct _lpuart_edma_handle +{ + lpuart_edma_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< LPUART callback function parameter.*/ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + + edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */ + edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */ + + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name eDMA transactional + * @{ + */ + +/*! + * @brief Initializes the LPUART handle which is used in transactional functions. + * @param base LPUART peripheral base address. + * @param handle Pointer to lpuart_edma_handle_t structure. + * @param callback Callback function. + * @param userData User data. + * @param txEdmaHandle User requested DMA handle for TX DMA transfer. + * @param rxEdmaHandle User requested DMA handle for RX DMA transfer. + */ +void LPUART_TransferCreateHandleEDMA(LPUART_Type *base, + lpuart_edma_handle_t *handle, + lpuart_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txEdmaHandle, + edma_handle_t *rxEdmaHandle); + +/*! + * @brief Sends data using eDMA. + * + * This function sends data using eDMA. This is a non-blocking function, which returns + * right away. When all data is sent, the send callback function is called. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param xfer LPUART eDMA transfer structure. See #lpuart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_LPUART_TxBusy Previous transfer on going. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer); + +/*! + * @brief Receives data using eDMA. + * + * This function receives data using eDMA. This is non-blocking function, which returns + * right away. When all data is received, the receive callback function is called. + * + * @param base LPUART peripheral base address. + * @param handle Pointer to lpuart_edma_handle_t structure. + * @param xfer LPUART eDMA transfer structure, see #lpuart_transfer_t. + * @retval kStatus_Success if succeed, others fail. + * @retval kStatus_LPUART_RxBusy Previous transfer ongoing. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer); + +/*! + * @brief Aborts the sent data using eDMA. + * + * This function aborts the sent data using eDMA. + * + * @param base LPUART peripheral base address. + * @param handle Pointer to lpuart_edma_handle_t structure. + */ +void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle); + +/*! + * @brief Aborts the received data using eDMA. + * + * This function aborts the received data using eDMA. + * + * @param base LPUART peripheral base address. + * @param handle Pointer to lpuart_edma_handle_t structure. + */ +void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle); + +/*! + * @brief Gets the number of bytes written to the LPUART TX register. + * + * This function gets the number of bytes written to the LPUART TX + * register by DMA. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Send bytes count. + * @retval kStatus_NoTransferInProgress No send in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count); + +/*! + * @brief Gets the number of received bytes. + * + * This function gets the number of received bytes. + * + * @param base LPUART peripheral base address. + * @param handle LPUART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_LPUART_EDMA_H_ */ diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_semc.c b/targets/FreeRTOS/GC5/common/drivers/fsl_semc.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_semc.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_semc.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_semc.h b/targets/FreeRTOS/GC5/common/drivers/fsl_semc.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_semc.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_semc.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_snvs_lp.c b/targets/FreeRTOS/GC5/common/drivers/fsl_snvs_lp.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_snvs_lp.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_snvs_lp.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_snvs_lp.h b/targets/FreeRTOS/GC5/common/drivers/fsl_snvs_lp.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_snvs_lp.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_snvs_lp.h diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_trng.c b/targets/FreeRTOS/GC5/common/drivers/fsl_trng.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_trng.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_trng.c diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_trng.h b/targets/FreeRTOS/GC5/common/drivers/fsl_trng.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/drivers/fsl_trng.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_trng.h diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/drivers/fsl_usdhc.c b/targets/FreeRTOS/GC5/common/drivers/fsl_usdhc.c similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/drivers/fsl_usdhc.c rename to targets/FreeRTOS/GC5/common/drivers/fsl_usdhc.c diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/drivers/fsl_usdhc.h b/targets/FreeRTOS/GC5/common/drivers/fsl_usdhc.h similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/drivers/fsl_usdhc.h rename to targets/FreeRTOS/GC5/common/drivers/fsl_usdhc.h diff --git a/targets/FreeRTOS/UAC18/common/hardfault.c b/targets/FreeRTOS/GC5/common/hardfault.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/hardfault.c rename to targets/FreeRTOS/GC5/common/hardfault.c diff --git a/targets/FreeRTOS/UAC18/common/platform_BlockStorage.c b/targets/FreeRTOS/GC5/common/platform_BlockStorage.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/platform_BlockStorage.c rename to targets/FreeRTOS/GC5/common/platform_BlockStorage.c diff --git a/targets/FreeRTOS/UAC18/common/platform_heap.c b/targets/FreeRTOS/GC5/common/platform_heap.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/platform_heap.c rename to targets/FreeRTOS/GC5/common/platform_heap.c diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/inc/fsl_sd.h b/targets/FreeRTOS/GC5/common/sdmmc/inc/fsl_sd.h similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/inc/fsl_sd.h rename to targets/FreeRTOS/GC5/common/sdmmc/inc/fsl_sd.h diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/inc/fsl_sdmmc_common.h b/targets/FreeRTOS/GC5/common/sdmmc/inc/fsl_sdmmc_common.h similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/inc/fsl_sdmmc_common.h rename to targets/FreeRTOS/GC5/common/sdmmc/inc/fsl_sdmmc_common.h diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/inc/fsl_sdmmc_host.h b/targets/FreeRTOS/GC5/common/sdmmc/inc/fsl_sdmmc_host.h similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/inc/fsl_sdmmc_host.h rename to targets/FreeRTOS/GC5/common/sdmmc/inc/fsl_sdmmc_host.h diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/inc/fsl_sdmmc_spec.h b/targets/FreeRTOS/GC5/common/sdmmc/inc/fsl_sdmmc_spec.h similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/inc/fsl_sdmmc_spec.h rename to targets/FreeRTOS/GC5/common/sdmmc/inc/fsl_sdmmc_spec.h diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/port/fsl_sdmmc_event.c b/targets/FreeRTOS/GC5/common/sdmmc/port/fsl_sdmmc_event.c similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/port/fsl_sdmmc_event.c rename to targets/FreeRTOS/GC5/common/sdmmc/port/fsl_sdmmc_event.c diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/port/fsl_sdmmc_event.h b/targets/FreeRTOS/GC5/common/sdmmc/port/fsl_sdmmc_event.h similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/port/fsl_sdmmc_event.h rename to targets/FreeRTOS/GC5/common/sdmmc/port/fsl_sdmmc_event.h diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/port/fsl_sdmmc_host.c b/targets/FreeRTOS/GC5/common/sdmmc/port/fsl_sdmmc_host.c similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/port/fsl_sdmmc_host.c rename to targets/FreeRTOS/GC5/common/sdmmc/port/fsl_sdmmc_host.c diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/src/fsl_sd.c b/targets/FreeRTOS/GC5/common/sdmmc/src/fsl_sd.c similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/src/fsl_sd.c rename to targets/FreeRTOS/GC5/common/sdmmc/src/fsl_sd.c diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/src/fsl_sdmmc_common.c b/targets/FreeRTOS/GC5/common/sdmmc/src/fsl_sdmmc_common.c similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/sdmmc/src/fsl_sdmmc_common.c rename to targets/FreeRTOS/GC5/common/sdmmc/src/fsl_sdmmc_common.c diff --git a/targets/FreeRTOS/UAC18/common/startup/startup_mimxrt1062.c b/targets/FreeRTOS/GC5/common/startup/startup_mimxrt1062.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/startup/startup_mimxrt1062.c rename to targets/FreeRTOS/GC5/common/startup/startup_mimxrt1062.c diff --git a/targets/FreeRTOS/UAC18/common/targetHAL.c b/targets/FreeRTOS/GC5/common/targetHAL.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/targetHAL.c rename to targets/FreeRTOS/GC5/common/targetHAL.c diff --git a/targets/FreeRTOS/UAC18/common/targetHAL_ConfigurationManager.cpp b/targets/FreeRTOS/GC5/common/targetHAL_ConfigurationManager.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/common/targetHAL_ConfigurationManager.cpp rename to targets/FreeRTOS/GC5/common/targetHAL_ConfigurationManager.cpp diff --git a/targets/FreeRTOS/UAC18/common/targetHAL_Time.cpp b/targets/FreeRTOS/GC5/common/targetHAL_Time.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/common/targetHAL_Time.cpp rename to targets/FreeRTOS/GC5/common/targetHAL_Time.cpp diff --git a/targets/FreeRTOS/UAC18/common/utilities/flexspi_nor_flash_ops.c b/targets/FreeRTOS/GC5/common/utilities/flexspi_nor_flash_ops.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/utilities/flexspi_nor_flash_ops.c rename to targets/FreeRTOS/GC5/common/utilities/flexspi_nor_flash_ops.c diff --git a/targets/FreeRTOS/UAC18/common/utilities/flexspi_nor_flash_ops.h b/targets/FreeRTOS/GC5/common/utilities/flexspi_nor_flash_ops.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/utilities/flexspi_nor_flash_ops.h rename to targets/FreeRTOS/GC5/common/utilities/flexspi_nor_flash_ops.h diff --git a/targets/FreeRTOS/UAC18/common/utilities/fsl_debug_console.c b/targets/FreeRTOS/GC5/common/utilities/fsl_debug_console.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/utilities/fsl_debug_console.c rename to targets/FreeRTOS/GC5/common/utilities/fsl_debug_console.c diff --git a/targets/FreeRTOS/UAC18/common/utilities/fsl_debug_console.h b/targets/FreeRTOS/GC5/common/utilities/fsl_debug_console.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/utilities/fsl_debug_console.h rename to targets/FreeRTOS/GC5/common/utilities/fsl_debug_console.h diff --git a/targets/FreeRTOS/UAC18/common/utilities/fsl_debug_console_conf.h b/targets/FreeRTOS/GC5/common/utilities/fsl_debug_console_conf.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/utilities/fsl_debug_console_conf.h rename to targets/FreeRTOS/GC5/common/utilities/fsl_debug_console_conf.h diff --git a/targets/FreeRTOS/UAC18/common/utilities/fsl_str.c b/targets/FreeRTOS/GC5/common/utilities/fsl_str.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/utilities/fsl_str.c rename to targets/FreeRTOS/GC5/common/utilities/fsl_str.c diff --git a/targets/FreeRTOS/UAC18/common/utilities/fsl_str.h b/targets/FreeRTOS/GC5/common/utilities/fsl_str.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/utilities/fsl_str.h rename to targets/FreeRTOS/GC5/common/utilities/fsl_str.h diff --git a/targets/FreeRTOS/UAC18/common/xip/evkmimxrt1060_flexspi_nor_config.c b/targets/FreeRTOS/GC5/common/xip/evkmimxrt1060_flexspi_nor_config.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/xip/evkmimxrt1060_flexspi_nor_config.c rename to targets/FreeRTOS/GC5/common/xip/evkmimxrt1060_flexspi_nor_config.c diff --git a/targets/FreeRTOS/UAC18/common/xip/evkmimxrt1060_flexspi_nor_config.h b/targets/FreeRTOS/GC5/common/xip/evkmimxrt1060_flexspi_nor_config.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/xip/evkmimxrt1060_flexspi_nor_config.h rename to targets/FreeRTOS/GC5/common/xip/evkmimxrt1060_flexspi_nor_config.h diff --git a/targets/FreeRTOS/UAC18/common/xip/fsl_flexspi_nor_boot.c b/targets/FreeRTOS/GC5/common/xip/fsl_flexspi_nor_boot.c similarity index 100% rename from targets/FreeRTOS/UAC18/common/xip/fsl_flexspi_nor_boot.c rename to targets/FreeRTOS/GC5/common/xip/fsl_flexspi_nor_boot.c diff --git a/targets/FreeRTOS/UAC18/common/xip/fsl_flexspi_nor_boot.h b/targets/FreeRTOS/GC5/common/xip/fsl_flexspi_nor_boot.h similarity index 100% rename from targets/FreeRTOS/UAC18/common/xip/fsl_flexspi_nor_boot.h rename to targets/FreeRTOS/GC5/common/xip/fsl_flexspi_nor_boot.h diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/diskio.c b/targets/FreeRTOS/GC5/fatfs/diskio.c similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/diskio.c rename to targets/FreeRTOS/GC5/fatfs/diskio.c diff --git a/targets/FreeRTOS/UAC18/nanoCLR/fatfs/ffconf.h b/targets/FreeRTOS/GC5/fatfs/ffconf.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/fatfs/ffconf.h rename to targets/FreeRTOS/GC5/fatfs/ffconf.h diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/ffsystem.c b/targets/FreeRTOS/GC5/fatfs/ffsystem.c similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/ffsystem.c rename to targets/FreeRTOS/GC5/fatfs/ffsystem.c diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/fsl_sd_disk.c b/targets/FreeRTOS/GC5/fatfs/fsl_sd_disk.c similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/fsl_sd_disk.c rename to targets/FreeRTOS/GC5/fatfs/fsl_sd_disk.c diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/fsl_sd_disk.h b/targets/FreeRTOS/GC5/fatfs/fsl_sd_disk.h similarity index 100% rename from targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/fsl_sd_disk.h rename to targets/FreeRTOS/GC5/fatfs/fsl_sd_disk.h diff --git a/targets/FreeRTOS/GC5/include/CMakeLists.txt b/targets/FreeRTOS/GC5/include/CMakeLists.txt new file mode 100644 index 0000000000..2fe0279bd4 --- /dev/null +++ b/targets/FreeRTOS/GC5/include/CMakeLists.txt @@ -0,0 +1,14 @@ +# +# Copyright (c) 2019 The nanoFramework project contributors +# See LICENSE file in the project root for full license information. +# + +# append include directory for target NXP +list(APPEND TARGET_NXP_COMMON_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}") + +# make var global +set(TARGET_NXP_COMMON_INCLUDE_DIRS ${TARGET_NXP_COMMON_INCLUDE_DIRS} CACHE INTERNAL "make global") + +# add header with target platform definitions +configure_file("${CMAKE_SOURCE_DIR}/CMake/FreeRTOS_target_os.h.in" + "${CMAKE_BINARY_DIR}/targets/FreeRTOS/GC5/UAC18/target_os.h" @ONLY) \ No newline at end of file diff --git a/targets/FreeRTOS/UAC18/include/TargetPAL_BlockStorage.h b/targets/FreeRTOS/GC5/include/TargetPAL_BlockStorage.h similarity index 100% rename from targets/FreeRTOS/UAC18/include/TargetPAL_BlockStorage.h rename to targets/FreeRTOS/GC5/include/TargetPAL_BlockStorage.h diff --git a/targets/FreeRTOS/UAC18/include/Target_BlockStorage_iMXRTFlashDriver.h b/targets/FreeRTOS/GC5/include/Target_BlockStorage_iMXRTFlashDriver.h similarity index 100% rename from targets/FreeRTOS/UAC18/include/Target_BlockStorage_iMXRTFlashDriver.h rename to targets/FreeRTOS/GC5/include/Target_BlockStorage_iMXRTFlashDriver.h diff --git a/targets/FreeRTOS/UAC18/include/Target_Windows_Storage.h b/targets/FreeRTOS/GC5/include/Target_Windows_Storage.h similarity index 100% rename from targets/FreeRTOS/UAC18/include/Target_Windows_Storage.h rename to targets/FreeRTOS/GC5/include/Target_Windows_Storage.h diff --git a/targets/FreeRTOS/UAC18/include/WireProtocol_ReceiverThread.h b/targets/FreeRTOS/GC5/include/WireProtocol_ReceiverThread.h similarity index 100% rename from targets/FreeRTOS/UAC18/include/WireProtocol_ReceiverThread.h rename to targets/FreeRTOS/GC5/include/WireProtocol_ReceiverThread.h diff --git a/targets/FreeRTOS/UAC18/include/targetHAL.h b/targets/FreeRTOS/GC5/include/targetHAL.h similarity index 100% rename from targets/FreeRTOS/UAC18/include/targetHAL.h rename to targets/FreeRTOS/GC5/include/targetHAL.h diff --git a/targets/FreeRTOS/UAC18/include/targetHAL_Time.h b/targets/FreeRTOS/GC5/include/targetHAL_Time.h similarity index 100% rename from targets/FreeRTOS/UAC18/include/targetHAL_Time.h rename to targets/FreeRTOS/GC5/include/targetHAL_Time.h diff --git a/targets/FreeRTOS/UAC18/include/targetPAL_Time.h b/targets/FreeRTOS/GC5/include/targetPAL_Time.h similarity index 100% rename from targets/FreeRTOS/UAC18/include/targetPAL_Time.h rename to targets/FreeRTOS/GC5/include/targetPAL_Time.h diff --git a/targets/FreeRTOS/UAC18/nanoCLR/CLR_RT_InteropAssembliesTable.cpp.in b/targets/FreeRTOS/GC5/nanoCLR/CLR_RT_InteropAssembliesTable.cpp.in similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/CLR_RT_InteropAssembliesTable.cpp.in rename to targets/FreeRTOS/GC5/nanoCLR/CLR_RT_InteropAssembliesTable.cpp.in diff --git a/targets/FreeRTOS/UAC18/nanoCLR/CLR_Startup_Thread.c b/targets/FreeRTOS/GC5/nanoCLR/CLR_Startup_Thread.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/CLR_Startup_Thread.c rename to targets/FreeRTOS/GC5/nanoCLR/CLR_Startup_Thread.c diff --git a/targets/FreeRTOS/UAC18/nanoCLR/CLR_Startup_Thread.h b/targets/FreeRTOS/GC5/nanoCLR/CLR_Startup_Thread.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/CLR_Startup_Thread.h rename to targets/FreeRTOS/GC5/nanoCLR/CLR_Startup_Thread.h diff --git a/targets/FreeRTOS/GC5/nanoCLR/CMakeLists.txt b/targets/FreeRTOS/GC5/nanoCLR/CMakeLists.txt new file mode 100644 index 0000000000..958aca3908 --- /dev/null +++ b/targets/FreeRTOS/GC5/nanoCLR/CMakeLists.txt @@ -0,0 +1,61 @@ +# +# Copyright (c) 2019 The nanoFramework project contributors +# See LICENSE file in the project root for full license information. +# + +include(NF_NativeAssemblies) + +# append nanoCLR source files +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Memory.cpp") +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/nanoHAL.cpp") +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/CLR_Startup_Thread.c") +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_App_Interface.c") + +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/TargetHAL.cpp") + +# append target HAL source files +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/TargetHAL_Time.cpp") +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/TargetHAL_Power.c") + +# append nanoCRT +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/nanoCRT.cpp") + +# append target PAL source files +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetPAL_Events.cpp") +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetPAL_Time.cpp") + +# append Random number generator files +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetRandom.cpp") + +# append networking files, if enabled +if(USE_NETWORKING_OPTION) + list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Network.cpp") + list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/target_Network.cpp") + + # list(APPEND LWIP_INCLUDE_DIRS ${LWIP_INCLUDE_DIRS}/LwIP) + + # append mbed TLS entropy generator, if hardware has it + # if(NF_SECURITY_MBEDTLS AND USE_RNG) + # list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/mbedtls_entropy_hardware_pool.c") + # endif() + +endif() + +# append files from Runtime.Native +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp") + +# add native assemblies +ParseNativeAssemblies() + +# configure code file with Interop Assemblies table and... +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CLR_RT_InteropAssembliesTable.cpp.in" + "${CMAKE_CURRENT_BINARY_DIR}/CLR_RT_InteropAssembliesTable.cpp" @ONLY) +# ... now add Interop Assemblies table to nanoCLR sources list +list(APPEND TARGET_NXP_NANOCLR_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/CLR_RT_InteropAssembliesTable.cpp") + +# append target nanoCLR include directory +list(APPEND TARGET_NXP_NANOCLR_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}) + +# make vars global +set(TARGET_NXP_NANOCLR_SOURCES ${TARGET_NXP_NANOCLR_SOURCES} CACHE INTERNAL "make global") +set(TARGET_NXP_NANOCLR_INCLUDE_DIRS ${TARGET_NXP_NANOCLR_INCLUDE_DIRS} CACHE INTERNAL "make global") diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Memory.cpp b/targets/FreeRTOS/GC5/nanoCLR/Memory.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Memory.cpp rename to targets/FreeRTOS/GC5/nanoCLR/Memory.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Target_Network.cpp b/targets/FreeRTOS/GC5/nanoCLR/Target_Network.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Target_Network.cpp rename to targets/FreeRTOS/GC5/nanoCLR/Target_Network.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native.cpp b/targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native.cpp rename to targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native.h b/targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native.h rename to targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native.h diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native_Windows_Devices_Gpio_GpioController.cpp b/targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native_Windows_Devices_Gpio_GpioController.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native_Windows_Devices_Gpio_GpioController.cpp rename to targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native_Windows_Devices_Gpio_GpioController.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native_Windows_Devices_Gpio_GpioPin.cpp b/targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native_Windows_Devices_Gpio_GpioPin.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native_Windows_Devices_Gpio_GpioPin.cpp rename to targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.Gpio/win_dev_gpio_native_Windows_Devices_Gpio_GpioPin.cpp diff --git a/targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.SerialCommunication/win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice.cpp b/targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.SerialCommunication/win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice.cpp new file mode 100644 index 0000000000..827d97a14d --- /dev/null +++ b/targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.SerialCommunication/win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice.cpp @@ -0,0 +1,670 @@ +// +// Copyright (c) 2019 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +#include "FreeRTOS.h" +#include +#include "win_dev_serial_native_target.h" + + + +static void vRwEvent( void * pvParameters ); + +const size_t xStreamBufferSizeBytes = UART_RX_BUFER_SIZE; +const size_t xTriggerLevel = 10; + +///////////////////////////////////////////////////////// +// UART PAL strucs delcared in win_dev_serial_native.h // +///////////////////////////////////////////////////////// + +/* Static UART config/data structs. */ +NF_PAL_UART Uart_PAL1; +NF_PAL_UART Uart_PAL2; +NF_PAL_UART Uart_PAL3; +NF_PAL_UART Uart_PAL4; +NF_PAL_UART Uart_PAL5; +NF_PAL_UART Uart_PAL6; +NF_PAL_UART Uart_PAL7; +NF_PAL_UART Uart_PAL8; + +/* Array of pointers to above config UART structs. */ +NF_PAL_UART* Uart_PAL[] { + NULL, + &Uart_PAL1, + &Uart_PAL2, + &Uart_PAL3, + &Uart_PAL4, + &Uart_PAL5, + &Uart_PAL6, + &Uart_PAL7, + &Uart_PAL8 +}; + +/* Interrupt handler invoked when a transmission buffer is completely transfered by DMA */ +static void TxEnd(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *data) +{ + (void) base; + (void) handle; + (void) status; + + uint8_t uartNum = *(uint8_t *) data; + + NATIVE_INTERRUPT_START + + BaseType_t xHigherPriorityTaskWoken = pdTRUE; + + xTaskNotifyFromISR( Uart_PAL[uartNum]->xReadTaskToNotify, 0x01, eSetBits, &xHigherPriorityTaskWoken); + + /* At this point xTaskToNotify should not be NULL as a transmission was in progress. */ + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + + NATIVE_INTERRUPT_END +} + +/* Interrupt handler, reads one byte from UART and puts it in the xStreamBuffer. */ +static void UART_Handle(LPUART_Type *base, uint8_t uartNum) +{ + uint32_t status = 0; + char byte; + BaseType_t xHigherPriorityTaskWoken; + + status = LPUART_GetStatusFlags(base); + + if (kLPUART_RxOverrunFlag & status) + { + /* Clear overrun flag, otherwise the RX does not work. */ + base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK); + } + + if (kLPUART_RxDataRegFullFlag & status) + { + if (!xStreamBufferIsFull( Uart_PAL[uartNum]->xReceiveBuffer )) + { + byte = LPUART_ReadByte(base); + xHigherPriorityTaskWoken = pdFALSE; /* Initialised to pdFALSE. */ + xStreamBufferSendFromISR( Uart_PAL[uartNum]->xReceiveBuffer, + &byte, + sizeof(byte), + &xHigherPriorityTaskWoken); + } + } + + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +/* + Override of the default MIMXRT1060 UART interrupt routines to simple UART_Handle function, which + reads 1 byte of input data to RTOS stream buffer, if theres buffer overflow it drops data and clears interrupts. +*/ +extern "C" +{ + /* LPUART1 is currently used for debugging, disable it or will collide with debugger */ + /* void LPUART1_IRQHandler(void) + { + RX_Handle(LPUART1); + } + */ + void LPUART2_IRQHandler(void) + { + UART_Handle(LPUART2, 2); + } + void LPUART3_IRQHandler(void) + { + UART_Handle(LPUART3, 3); + } + void LPUART4_IRQHandler(void) + { + UART_Handle(LPUART4 ,4); + } + void LPUART5_IRQHandler(void) + { + UART_Handle(LPUART5, 5); + } + void LPUART6_IRQHandler(void) + { + UART_Handle(LPUART6, 6); + } + void LPUART7_IRQHandler(void) + { + UART_Handle(LPUART7, 7); + } + void LPUART8_IRQHandler(void) + { + UART_Handle(LPUART8, 8); + } +} + +/* Deinitialize serial port and allocated free memory */ +HRESULT Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::NativeDispose___VOID( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); + { + CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); + + uint8_t uartNum = 0; + LPUART_Type *base = NULL; + + uartNum = pThis[ FIELD___portIndex ].NumericByRef().s4; + base = lpuart_bases[uartNum]; + + /* Quit if parameters or device is invalid or out of range */ + if (base == NULL || uartNum > 8) NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + + /* Free ring buffers memory */ + free(Uart_PAL[uartNum]->TxBuffer); + + /* Deinitialize device and delete FreeRTOS idle tasks */ + LPUART_Deinit(base); + vTaskDelete( Uart_PAL[uartNum]->xReadTaskToNotify ); + } + NANOCLR_NOCLEANUP(); +} + +/* Initialise a new Serial port, allocate buffer memory and create FreeRTOS idle tasks */ +HRESULT Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::NativeInit___VOID( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); + { + CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); + + status_t status = 0; + uint8_t uartNum = 0; + lpuart_config_t *config = NULL; + BaseType_t xReturned = NULL; + LPUART_Type *base = NULL; + + uartNum = pThis[ FIELD___portIndex ].NumericByRef().s4; + Uart_PAL[uartNum]->uart_data.uartNum = uartNum; + config = &Uart_PAL[uartNum]->uartCfg; + base = lpuart_bases[uartNum]; + + /* Quit if parameters or device is invalid or out of range */ + if (config == NULL || base == NULL || uartNum > 8) NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + + /* Allocate memory for TX circular buffer */ + Uart_PAL[uartNum]->TxBuffer = (uint8_t *) platform_malloc(UART_TX_BUFER_SIZE * sizeof(uint8_t)); + if (Uart_PAL[uartNum]->TxBuffer == NULL) NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + + /* Initialize TX buffer */ + Uart_PAL[uartNum]->TxRingBuffer.Initialize(Uart_PAL[uartNum]->TxBuffer, UART_TX_BUFER_SIZE); + Uart_PAL[uartNum]->TxOngoingCount = 0; + Uart_PAL[uartNum]->WatchChar = 0; + + /* Allocate stream buffer for RX */ + Uart_PAL[uartNum]->xReceiveBuffer = xStreamBufferCreate(xStreamBufferSizeBytes, xTriggerLevel); + Uart_PAL[uartNum]->xRxSemaphore = xSemaphoreCreateMutex(); + + /* Get default config structure for initializing given UART peripheral and enable TX, RX */ + LPUART_GetDefaultConfig(config); + config->enableRx = true; + config->enableTx = true; + + /* Initialize UART peripheral with default config */ + status = LPUART_Init(base, config, GetSrcFreq()); + if (status != kStatus_Success) NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + + /* Enable RX interrupts */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); + EnableIRQ((IRQn_Type) (19 + uartNum)); + NVIC_SetPriority((IRQn_Type) (19 + uartNum), 8U); + + /* Set lower priority of DMA UART interrupt for FreeRTOS interrupt task to work */ + NVIC_SetPriority(DMA0_DMA16_IRQn, 10U); + + /* Initalize DMAMUX and setup channel for LPUART */ + /* TODO: Implement different mux than LPUART3 */ + DMAMUX_Init(DMAMUX); + DMAMUX_SetSource(DMAMUX, LPUART_TX_DMA_CHANNEL, kDmaRequestMuxLPUART3Tx); + DMAMUX_EnableChannel(DMAMUX, LPUART_TX_DMA_CHANNEL); + + /* Initialize DMA with default config and setup callback handles */ + EDMA_GetDefaultConfig(&Uart_PAL[uartNum]->edmaCfg); + EDMA_Init(DMA0, &Uart_PAL[uartNum]->edmaCfg); + EDMA_CreateHandle(&Uart_PAL[uartNum]->g_lpuartTxEdmaHandle, DMA0, LPUART_TX_DMA_CHANNEL); + + /* FreeRTOS Task needs parameter data survive after this function finish, so write this parameter to Uart_PAL structure. */ + Uart_PAL[uartNum]->dma_num = uartNum; + + /* UART DMA TX finished handle */ + LPUART_TransferCreateHandleEDMA(base, + &Uart_PAL[uartNum]->g_lpuartEdmaHandle, + TxEnd, + &Uart_PAL[uartNum]->dma_num, + &Uart_PAL[uartNum]->g_lpuartTxEdmaHandle, + NULL); + + /* Create idle task waiting for read/write. */ + xReturned = xTaskCreate(vRwEvent, + "UART Read Event", + configMINIMAL_STACK_SIZE + 10, + (void *) Uart_PAL[uartNum], + tskIDLE_PRIORITY + 5, + &Uart_PAL[uartNum]->xReadTaskToNotify ); + if (xReturned == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); + } + NANOCLR_NOCLEANUP(); +} + +/* Set up serial port Configuration */ +HRESULT Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::NativeConfig___VOID( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); + { + CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); + + status_t status = 0; + uint8_t uartNum = 0; + lpuart_config_t *config = NULL; + LPUART_Type *base = NULL; + + uartNum = pThis[ FIELD___portIndex ].NumericByRef().s4; + config = &Uart_PAL[uartNum]->uartCfg; + base = lpuart_bases[uartNum]; + + if (config == NULL || base == NULL || uartNum > 8) NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + + config->baudRate_Bps = (uint32_t)pThis[ FIELD___baudRate ].NumericByRef().s4; + + switch( pThis[ FIELD___dataBits ].NumericByRef().s4 ) + { + default: + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); break; + case 7: + config->dataBitsCount = kLPUART_SevenDataBits; break; + case 8: + config->dataBitsCount = kLPUART_EightDataBits; break; + } + + switch ( pThis[ FIELD___parity ].NumericByRef().s4 ) + { + default: + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); break; + case SerialParity_None: + config->parityMode = kLPUART_ParityDisabled; break; + case SerialParity_Even: + config->parityMode = kLPUART_ParityEven; break; + case SerialParity_Odd: + config->parityMode = kLPUART_ParityOdd; break; + } + + /* TODO: Implement the rest of handshake */ + switch ( pThis[ FIELD___handshake ].NumericByRef().s4 ) + { + default: + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); break; + case SerialHandshake_None: + config->enableRxRTS = false; + config->enableTxCTS = false; + break; + case SerialHandshake_RequestToSend: + config->enableRxRTS = true; + config->enableTxCTS = false; + break; + /* case SerialHandshake_RequestToSendXOnXOff: */ + } + + /* write config to UART peripheral */ + status = LPUART_Init(base, config, GetSrcFreq()); + if (status != kStatus_Success) NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + pThis = NULL; + + /* Reenable interrupts after setting configuration */ + /* Disable transmitter */ + base->CTRL &= ~(1U << 19); + /* Disable receiver */ + base->CTRL &= ~(1U << 18); + /* Enable receiver interrupt */ + base->CTRL |= 1U << 21; + /* Enable overrun interrupt */ + // base->CTRL |= 1U << 27; + /* Renable receiver and transmitter */ + base->CTRL |= 1U << 19; + base->CTRL |= 1U << 18; + } + NANOCLR_NOCLEANUP(); +} + +/* Write data into buffer */ +HRESULT Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::NativeWrite___VOID__SZARRAY_U1( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); + { + // get a pointer to the managed object instance and check that it's not NULL + CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); + + uint8_t * data; + uint8_t uartNum = 0; + size_t length = 0; + + if(pThis[ FIELD___disposed ].NumericByRef().u1 != 0) NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + + /* Get UART device number */ + uartNum = pThis[ FIELD___portIndex ].NumericByRef().s4; + + /* Quit if parameters or device is invalid or out of range */ + if (uartNum > 8) NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + + /* dereference the data buffer from the argument */ + CLR_RT_HeapBlock_Array* dataBuffer = stack.Arg1().DereferenceArray(); + + /* get a the pointer to the array by using the first element of the array */ + data =dataBuffer->GetFirstElement(); + + /* get the size of the buffer */ + length = dataBuffer->m_numOfElements; + + /* check if there is enough room in the buffer */ + if(Uart_PAL[uartNum]->TxRingBuffer.Capacity() - Uart_PAL[uartNum]->TxRingBuffer.Length() < length) + { + /* not enough room in the buffer */ + NANOCLR_SET_AND_LEAVE(CLR_E_BUFFER_TOO_SMALL); + } + + /* push data to buffer */ + size_t bytesWritten = Uart_PAL[uartNum]->TxRingBuffer.Push(data, length); + + /* check if all requested bytes were written */ + if(bytesWritten != length) + { + /* not sure if this is the best exception to throw here... */ + NANOCLR_SET_AND_LEAVE(CLR_E_FAIL); + } + + /* need to update the _unstoredBufferLength field in the SerialDeviceOutputStream */ + /* get pointer to outputStream field */ + CLR_RT_HeapBlock* outputStream = pThis[Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::FIELD___outputStream].Dereference(); + /* get pointer to _unstoredBufferLength field and udpate field value */ + outputStream[Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDeviceOutputStream::FIELD___unstoredBufferLength].NumericByRef().s4 = Uart_PAL[uartNum]->TxRingBuffer.Length(); + } + NANOCLR_NOCLEANUP(); +} + +/* Store - Send buffer and wait */ +HRESULT Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::NativeStore___U4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); + { + size_t length = 0; + + CLR_RT_HeapBlock* writeTimeout; + int64_t* timeoutTicks; + bool eventResult = true; + bool txOk = false; + + uint8_t uartNum = NULL; + lpuart_transfer_t xfer; + uint32_t timeout; + + /* get a pointer to the managed object instance and check that it's not NULL */ + CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); + + uartNum = pThis[ FIELD___portIndex ].NumericByRef().s4; + + if(pThis[ FIELD___disposed ].NumericByRef().u1 != 0) NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + + /* Quit if parameters or device is invalid or out of range */ + if (uartNum > 8) NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + + /* get value for _readtimeout field (pointer!) */ + writeTimeout = &pThis[ Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::FIELD___writeTimeout ]; + + timeout = (uint32_t) pThis[Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::FIELD___writeTimeout].NumericByRef().u4; + + /* setup timeout */ + NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks(*writeTimeout, timeoutTicks)); + + /* push dummy length value onto the eval stack */ + /* this is going to be used to store how many bytes where buffered to Tx */ + if(stack.m_customState == 1) + { + stack.PushValueI4(0); + /* bump custom state so the read value above is pushed only once */ + stack.m_customState = 2; + } + + /* check if there is anything the buffer */ + if(Uart_PAL[uartNum]->TxRingBuffer.Length() > 0) + { + /* check if there is a TX operation ongoing */ + if(Uart_PAL[uartNum]->TxOngoingCount == 0) + { + /* OK to Tx */ + txOk = true; + } + else + { + /* need to wait for the ongoing operation to complete before starting a new one */ + } + } + + if(txOk) + { + /* Optimize buffer for sequential reading */ + Uart_PAL[uartNum]->TxRingBuffer.OptimizeSequence(); + + /* Get data length available in the buffer */ + length = Uart_PAL[uartNum]->TxRingBuffer.Length(); + + /* Push to the stack how many bytes bytes where buffered for Tx */ + stack.m_evalStack[1].NumericByRef().s4 = length; + + /* Set TX ongoing count */ + Uart_PAL[uartNum]->TxOngoingCount = length; + + /* Set up DMA transfer structure */ + xfer.data = (uint8_t*) Uart_PAL[uartNum]->TxRingBuffer.Reader(); + xfer.dataSize = length; + + /* Initiate DMA transfer to UART peripheral with xfer data structure */ + LPUART_SendEDMA(lpuart_bases[uartNum], &Uart_PAL[uartNum]->g_lpuartEdmaHandle, &xfer); + } + + while(eventResult) + { + NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, timeout, CLR_RT_ExecutionEngine::c_Event_SerialPortOut, eventResult)); + if(eventResult) + { + /* Event occurred, get from the eval stack how many bytes were buffered to Tx */ + /* Pop elements from ring buffer, just pop. */ + Uart_PAL[uartNum]->TxRingBuffer.Pop(Uart_PAL[uartNum]->TxOngoingCount); + + /* reset Tx ongoing count */ + Uart_PAL[uartNum]->TxOngoingCount = 0; + + /* Notify the task that the transmission is complete. */ + length = stack.m_evalStack[1].NumericByRef().s4; + + break; + } + else + { + asm("nop"); + /* NANOCLR_SET_AND_LEAVE( CLR_E_TIMEOUT ); */ + } + } + /* pop length/timeout heap block from stack */ + stack.PopValue(); + stack.PopValue(); + + stack.SetResult_U4(length); + NANOCLR_NOCLEANUP(); + } +} + +HRESULT Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::NativeRead___U4__SZARRAY_U1__I4__I4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); + { + + CLR_RT_HeapBlock_Array* dataBuffer = NULL; + CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); + InputStreamOptions options = InputStreamOptions_None; + + bool eventResult = true; + + size_t read_count = 0; + uint8_t uartNum = 0; + uart_data_t * rx_p = NULL; + + if(pThis[ FIELD___disposed ].NumericByRef().u1 != 0) NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + + uartNum = pThis[ FIELD___portIndex ].NumericByRef().s4; + rx_p = &Uart_PAL[uartNum]->uart_data; + + /* Dereference the data buffer from the argument */ + dataBuffer = stack.Arg1().DereferenceArray(); + + /* Get a the pointer to the array by using the first element of the array */ + rx_p->out_data = dataBuffer->GetFirstElement(); + + /* Get the InputStreamOptions option */ + /* TODO: Implement transfer options. */ + options = (InputStreamOptions)stack.Arg3().NumericByRef().s4; + + /* Get how many bytes are requested to read */ + read_count = stack.Arg2().NumericByRef().s4; + + /* Get the length of the data buffer */ + rx_p->bytes_to_read = dataBuffer->m_numOfElements; + + /* Zero out bytes received. */ + rx_p->bytes_received = 0; + + /* Set up timeout. */ + rx_p->timeout = (uint32_t) pThis[Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::FIELD___readTimeout].NumericByRef().u4; + + /* Calculate timeout to FreeRTOS ticks */ + rx_p->f_timeout = (rx_p->timeout/10000) - 1000; + + /* Set trigger level (number of bytes after xStreamBuffer function receiving data returns.) */ + xStreamBufferSetTriggerLevel(Uart_PAL[uartNum]->xReceiveBuffer, + rx_p->bytes_to_read); + + /* We have enough bytes so retrive it directly. */ + if (xStreamBufferBytesAvailable( Uart_PAL[uartNum]->xReceiveBuffer) >= read_count) + { + { + rx_p->bytes_received = xStreamBufferReceive(Uart_PAL[uartNum]->xReceiveBuffer, + (void *) rx_p->out_data, + rx_p->bytes_to_read, + rx_p->f_timeout); + } + } + + /* Not enough bytes in buffer, fire task waiting for more data. */ + else + { + /* Notify task that we want to receive data. */ + xTaskNotify( Uart_PAL[uartNum]->xReadTaskToNotify, 0x02, eSetBits); + + /* Wait for event from task. */ + NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents(stack.m_owningThread, rx_p->timeout, CLR_RT_ExecutionEngine::c_Event_SerialPortIn, eventResult)); + } + + /* Timeout! */ + if (!eventResult) + { + asm("nop"); + /* NANOCLR_SET_AND_LEAVE( CLR_E_TIMEOUT ); */ + } + + /* Return how many bytes were read */ + stack.SetResult_U4(rx_p->bytes_received); + + (void) options; + } + NANOCLR_NOCLEANUP(); +} + +/* TODO: Implement watch char. Currently this funtion does nothing. */ +HRESULT Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::NativeSetWatchChar___VOID( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); + { + /* get a pointer to the managed object instance and check that it's not NULL */ + CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); + + /* Choose the driver for this SerialDevice */ + uint8_t uartNum = (uint8_t)pThis[ FIELD___portIndex ].NumericByRef().s4; + + /* set watch char */ + Uart_PAL[uartNum] ->WatchChar = (uint8_t)pThis[ FIELD___watchChar ].NumericByRef().u1; + } + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::get_BytesToRead___U4( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); + { + + CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); + + uint8_t uartNum = 0; + size_t read_count = 0; + + if(pThis[ FIELD___disposed ].NumericByRef().u1 != 0) NANOCLR_SET_AND_LEAVE(CLR_E_OBJECT_DISPOSED); + + uartNum = pThis[ FIELD___portIndex ].NumericByRef().s4; + + /* Check how many bytes are avaliable in buffer */ + read_count = xStreamBufferBytesAvailable(Uart_PAL[uartNum]->xReceiveBuffer); + + stack.SetResult_U4(read_count); + } + NANOCLR_NOCLEANUP(); +} + +/* Return available devices */ +/* TODO: implement checking for available devices */ +HRESULT Library_win_dev_serial_native_Windows_Devices_SerialCommunication_SerialDevice::GetDeviceSelector___STATIC__STRING( CLR_RT_StackFrame& stack ) +{ + NANOCLR_HEADER(); + { + /* declare the device selector string whose max size is "COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8" + terminator */ + char deviceSelectorString[ 40 ] = "COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8"; + + /* because the caller is expecting a result to be returned */ + /* we need set a return result in the stack argument using the a ppropriate SetResult according to the variable type (a string here) */ + stack.SetResult_String(deviceSelectorString); + } + NANOCLR_NOCLEANUP_NOLABEL(); +} + +/* Task wait for notify from DMA interrupt or notify from read function. + When notify comes it fires events to inform nanoFramework that read/write is finished */ +static void vRwEvent(void * pvParameters) +{ + /* This is main UART struct, holding config, handlers, and the rest of variables.d */ + NF_PAL_UART * rx_Uart_PAL = (NF_PAL_UART *) pvParameters; + /* UART data struct, holding variables needed for this task, also holding incoming data in xReceiveStream. */ + uart_data_t * rx_p = &rx_Uart_PAL->uart_data; + + while(1) + { + /* Task is in block state until receives event. */ + xTaskNotifyWait(0x00, 0xffffffff, &rx_Uart_PAL->ulNotifiedValue, portMAX_DELAY); + + /* Check for dma event, if theres is one unblock it. */ + if ((rx_Uart_PAL->ulNotifiedValue & 0x01) != 0) + { + /* Send event to nanoFramework that write is complete. */ + Events_Set(SYSTEM_EVENT_FLAG_COM_OUT); + } + + /* Check is there event from task reading bytes. */ + if ((rx_Uart_PAL->ulNotifiedValue & 0x02) != 0) + { + /* If there is read until trigger or timeout and send event to nanoFramework. */ + rx_p->bytes_received = xStreamBufferReceive(rx_Uart_PAL->xReceiveBuffer, + (void *) rx_p->out_data, + rx_p->bytes_to_read, + rx_p->f_timeout); + Events_Set(SYSTEM_EVENT_FLAG_COM_IN); + } + } + + (void) pvParameters; + vTaskDelete(NULL); +} \ No newline at end of file diff --git a/targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.SerialCommunication/win_dev_serial_native_target.h b/targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.SerialCommunication/win_dev_serial_native_target.h new file mode 100644 index 0000000000..ff1741532c --- /dev/null +++ b/targets/FreeRTOS/GC5/nanoCLR/Windows.Devices.SerialCommunication/win_dev_serial_native_target.h @@ -0,0 +1,77 @@ +// +// Copyright (c) 2019 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef _WIN_DEV_SERIAL_NATIVE_TARGET_H_ +#define _WIN_DEV_SERIAL_NATIVE_TARGET_H_ + +#define LPUART_TX_DMA_CHANNEL 0U + +#include +#include + +#include +#include +#include +#include + +#include "fsl_lpuart.h" +#include "fsl_lpuart_edma.h" +#include "fsl_dmamux.h" +#include "fsl_edma.h" + +#include "stream_buffer.h" +#include "semphr.h" + +typedef struct { + size_t bytes_received; + size_t bytes_to_read; + uint32_t timeout; + uint32_t f_timeout; + uint8_t * out_data; + uint8_t uartNum; +} uart_data_t; +typedef struct +{ + uint8_t dma_num; + + lpuart_config_t uartCfg; + edma_config_t edmaCfg; + + lpuart_edma_handle_t g_lpuartEdmaHandle; + edma_handle_t g_lpuartTxEdmaHandle; + + HAL_RingBuffer TxRingBuffer; + uint8_t* TxBuffer; + uint16_t TxOngoingCount; + uint8_t WatchChar; + SemaphoreHandle_t xRxSemaphore = NULL; + TaskHandle_t xWriteTaskToNotify = NULL; + TaskHandle_t xReadTaskToNotify = NULL; + + StreamBufferHandle_t xReceiveBuffer; + uint32_t ulNotifiedValue; + uart_data_t uart_data; +} NF_PAL_UART; + +//////////////////////////////////////////// +// declaration of the the UART PAL strucs // +//////////////////////////////////////////// + +/* TODO: This is implementation of one UART devices, need to add the rest of structures or find better way to keep uarts config */ + +LPUART_Type *const lpuart_bases[] = LPUART_BASE_PTRS; + +extern NF_PAL_UART Uart_PAL1; +extern NF_PAL_UART Uart_PAL2; +extern NF_PAL_UART Uart_PAL3; +extern NF_PAL_UART Uart_PAL4; +extern NF_PAL_UART Uart_PAL5; +extern NF_PAL_UART Uart_PAL6; +extern NF_PAL_UART Uart_PAL7; +extern NF_PAL_UART Uart_PAL8; + +extern NF_PAL_UART* Uart_PAL[]; + +#endif //_WIN_DEV_SERIAL_NATIVE_TARGET_H_ diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native.cpp b/targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native.cpp rename to targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native.h b/targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native.h rename to targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native.h diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_Devices_SDCard.cpp b/targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_Devices_SDCard.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_Devices_SDCard.cpp rename to targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_Devices_SDCard.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_FileIO.cpp b/targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_FileIO.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_FileIO.cpp rename to targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_FileIO.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFile.cpp b/targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFile.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFile.cpp rename to targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFile.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFolder.cpp b/targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFolder.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFolder.cpp rename to targets/FreeRTOS/GC5/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFolder.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/WireProtocol_App_Interface.c b/targets/FreeRTOS/GC5/nanoCLR/WireProtocol_App_Interface.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/WireProtocol_App_Interface.c rename to targets/FreeRTOS/GC5/nanoCLR/WireProtocol_App_Interface.c diff --git a/targets/FreeRTOS/GC5/nanoCLR/lwipopts.h b/targets/FreeRTOS/GC5/nanoCLR/lwipopts.h new file mode 100644 index 0000000000..dabc44b3ca --- /dev/null +++ b/targets/FreeRTOS/GC5/nanoCLR/lwipopts.h @@ -0,0 +1,329 @@ +// +// Copyright (c) 2019 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +#include + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#define MEM_LIBC_MALLOC 0 + +/** + * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. + * Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution + * speed (heap alloc can be much slower than pool alloc) and usage from interrupts + * (especially if your netif driver allocates PBUF_POOL pbufs for received frames + * from interrupt)! + * ATTENTION: Currently, this uses the heap for ALL pools (also for private pools, + * not only for internal pools defined in memp_std.h)! + */ +#define MEMP_MEM_MALLOC 0 + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> \#define MEM_ALIGNMENT 4 + * 2 byte alignment -> \#define MEM_ALIGNMENT 2 + */ +#define MEM_ALIGNMENT 4 + + +/** + * MEM_SIZE: the size of the heap memory. If the application will send + * a lot of data that needs to be copied, this should be set high. + */ +#define MEM_SIZE (22 * 1024) + +/** + * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. + * (requires the LWIP_TCP option) + */ +#define MEMP_NUM_TCP_SEG 25 + +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#define IP_REASS_MAXAGE 3 + + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#define LWIP_RAW 1 + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#define LWIP_DHCP 1 + +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#define LWIP_IGMP 1 + +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#define LWIP_DNS 1 + +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ + +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#define TCP_QUEUE_OOSEQ 0 + +/** + * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, + * you might want to increase this.) + * For the receive side, this MSS is advertised to the remote side + * when opening a connection. For the transmit size, this MSS sets + * an upper limit on the MSS advertised by the remote host. + */ +#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */ + +/** + * TCP_SND_BUF: TCP sender buffer space (bytes). + * To achieve good performance, this should be at least 2 * TCP_MSS. + */ +#define TCP_SND_BUF (6 * TCP_MSS) + +/** + * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. + */ +#define TCP_LISTEN_BACKLOG 1 + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#define LWIP_NETIF_HOSTNAME 1 + +/** + * LWIP_NETIF_API==1: Support netif api (in netifapi.c) + */ +#define LWIP_NETIF_API 1 + +/** + * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface + * changes its up/down status (i.e., due to DHCP IP acquisition) + */ +#define LWIP_NETIF_STATUS_CALLBACK 1 + +/** + * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface + * whenever the link changes (i.e., link down) + */ +#define LWIP_NETIF_LINK_CALLBACK 1 + +/** + * LWIP_NUM_NETIF_CLIENT_DATA: Number of clients that may store + * data in client_data member array of struct netif (max. 256). + */ +#define LWIP_NUM_NETIF_CLIENT_DATA 1 + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define TCPIP_THREAD_STACKSIZE 1024 + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define TCPIP_THREAD_PRIO 8 + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#define TCPIP_MBOX_SIZE MEMP_NUM_PBUF + +/** + * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define DEFAULT_THREAD_STACKSIZE 3000 + +/** + * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define DEFAULT_THREAD_PRIO 3 + +/** + * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_RAW_RECVMBOX_SIZE 12 + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_UDP_RECVMBOX_SIZE 12 + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_TCP_RECVMBOX_SIZE 40 + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#define DEFAULT_ACCEPTMBOX_SIZE 12 + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ +/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout to create + * timers running in tcpip_thread from another thread. + */ +#define LWIP_TCPIP_TIMEOUT 1 + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#define LWIP_SO_SNDTIMEO 1 + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. + */ +#define LWIP_SO_RCVTIMEO 1 + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#define LWIP_SO_RCVBUF 1 + +/** + * LWIP_SO_LINGER==1: Enable SO_LINGER processing. + */ +#define LWIP_SO_LINGER 1 + +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#define SO_REUSE 1 + +/** + * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets + * to all local matches if SO_REUSEADDR is turned on. + * WARNING: Adds a memcpy for every packet if passing to more than one pcb! + */ +#define SO_REUSE_RXTOALL 1 + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#define LWIP_STATS 0 +#define LWIP_PROVIDE_ERRNO 1 +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +/** + * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable + * debug messages of certain types. + * @see debugging_levels + */ +#define LWIP_DBG_TYPES_ON LWIP_DBG_OFF + +#if (LWIP_DNS || LWIP_IGMP || LWIP_IPV6) && !defined(LWIP_RAND) +/* When using IGMP or IPv6, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value*/ +#include "lwip/arch.h" +u32_t lwip_rand(void); +#define LWIP_RAND() lwip_rand() +#endif + +/** + * LWIP_MDNS_RESPONDER==1: Turn on multicast DNS module. UDP must be available for MDNS + * transport. IGMP is needed for IPv4 multicast. + */ +#define LWIP_MDNS_RESPONDER 1 + +#endif /* __LWIPOPTS_H__ */ + +/*****END OF FILE****/ diff --git a/targets/FreeRTOS/UAC18/nanoCLR/nanoCRT.cpp b/targets/FreeRTOS/GC5/nanoCLR/nanoCRT.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/nanoCRT.cpp rename to targets/FreeRTOS/GC5/nanoCLR/nanoCRT.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp b/targets/FreeRTOS/GC5/nanoCLR/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp rename to targets/FreeRTOS/GC5/nanoCLR/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/nanoHAL.cpp b/targets/FreeRTOS/GC5/nanoCLR/nanoHAL.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/nanoHAL.cpp rename to targets/FreeRTOS/GC5/nanoCLR/nanoHAL.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/targetHAL.cpp b/targets/FreeRTOS/GC5/nanoCLR/targetHAL.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/targetHAL.cpp rename to targets/FreeRTOS/GC5/nanoCLR/targetHAL.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/targetHAL_Network.cpp b/targets/FreeRTOS/GC5/nanoCLR/targetHAL_Network.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/targetHAL_Network.cpp rename to targets/FreeRTOS/GC5/nanoCLR/targetHAL_Network.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/targetHAL_Power.c b/targets/FreeRTOS/GC5/nanoCLR/targetHAL_Power.c similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/targetHAL_Power.c rename to targets/FreeRTOS/GC5/nanoCLR/targetHAL_Power.c diff --git a/targets/FreeRTOS/UAC18/nanoCLR/targetHAL_Time.cpp b/targets/FreeRTOS/GC5/nanoCLR/targetHAL_Time.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/targetHAL_Time.cpp rename to targets/FreeRTOS/GC5/nanoCLR/targetHAL_Time.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/targetHAL_Time.h b/targets/FreeRTOS/GC5/nanoCLR/targetHAL_Time.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/targetHAL_Time.h rename to targets/FreeRTOS/GC5/nanoCLR/targetHAL_Time.h diff --git a/targets/FreeRTOS/UAC18/nanoCLR/targetPAL_Events.cpp b/targets/FreeRTOS/GC5/nanoCLR/targetPAL_Events.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/targetPAL_Events.cpp rename to targets/FreeRTOS/GC5/nanoCLR/targetPAL_Events.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/targetPAL_Time.cpp b/targets/FreeRTOS/GC5/nanoCLR/targetPAL_Time.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/targetPAL_Time.cpp rename to targets/FreeRTOS/GC5/nanoCLR/targetPAL_Time.cpp diff --git a/targets/FreeRTOS/UAC18/nanoCLR/targetPAL_Time.h b/targets/FreeRTOS/GC5/nanoCLR/targetPAL_Time.h similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/targetPAL_Time.h rename to targets/FreeRTOS/GC5/nanoCLR/targetPAL_Time.h diff --git a/targets/FreeRTOS/UAC18/nanoCLR/targetRandom.cpp b/targets/FreeRTOS/GC5/nanoCLR/targetRandom.cpp similarity index 100% rename from targets/FreeRTOS/UAC18/nanoCLR/targetRandom.cpp rename to targets/FreeRTOS/GC5/nanoCLR/targetRandom.cpp diff --git a/targets/FreeRTOS/GC5/nanoCLR/target_lwip_sntp_opts.h b/targets/FreeRTOS/GC5/nanoCLR/target_lwip_sntp_opts.h new file mode 100644 index 0000000000..8cabc85f88 --- /dev/null +++ b/targets/FreeRTOS/GC5/nanoCLR/target_lwip_sntp_opts.h @@ -0,0 +1,18 @@ +// +// Copyright (c) 2019 The nanoFramework project contributors +// See LICENSE file in the project root for full license information. +// + +#define SNTP_SERVER_DEFAULT_ADDRESS "0.pool.ntp.org" + +// update delay (default 1 hour) +// (value in milliseconds) +#define SNTP_UPDATE_DELAY 3600000 + +// better have a startup delay because we can have DHCP enabled (default 30 seconds) +// value in milliseconds +#define SNTP_STARTUP_DELAY 30000 + +// retry timeout (15 minutes) +// value in milliseconds +#define SNTP_RETRY_TIMEOUT 900000 diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/Target_Windows_Storage.c b/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/Target_Windows_Storage.c deleted file mode 100644 index 867279401a..0000000000 --- a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/Target_Windows_Storage.c +++ /dev/null @@ -1,148 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// See LICENSE file in the project root for full license information. -// - -#include "FreeRTOS.h" -#include "semphr.h" -#include "task.h" - -#include "ff.h" -#include -#include -#include - -#include "fsl_sd.h" - - -// need to declare this here as extern -extern void PostManagedEvent(uint8_t category, uint8_t subCategory, uint16_t data1, uint32_t data2); - -#define SD_CARD_DRIVE_INDEX "0" - - -/////////////////////////////////////////// -// code specific to SD Card - -// FS for SD Card mounted and ready -bool sdCardFileSystemReady; - -static FATFS sdCard_FS; - -/*! -* call back function for SD card detect. -* -* @param isInserted true, indicate the card is insert. -* false, indicate the card is remove. -* @param userData -*/ -static void SDCARD_DetectCallBack(bool isInserted, void *userData); - -/*! Card descriptor. */ -sd_card_t g_sd; - -/*! SDMMC host detect card configuration */ -static const sdmmchost_detect_card_t s_sdCardDetect = { -#ifndef BOARD_SD_DETECT_TYPE - .cdType = kSDMMCHOST_DetectCardByGpioCD, -#else - .cdType = BOARD_SD_DETECT_TYPE, -#endif - .cdTimeOut_ms = (~0U), - .cardInserted = SDCARD_DetectCallBack, - .cardRemoved = SDCARD_DetectCallBack, -}; - -/*! SD card detect flag */ -static bool s_cardInserted = false; -/*! Card semaphore */ -static SemaphoreHandle_t s_CardDetectSemaphore = NULL; - -static void SDCARD_DetectCallBack(bool isInserted, void *userData) -{ - (void)userData; - s_cardInserted = isInserted; - xSemaphoreGiveFromISR(s_CardDetectSemaphore, NULL); -} - -static void CardDetectTask(void *pvParameters) -{ - (void)pvParameters; - - while (true) - { - if (!s_cardInserted) - { - /* power off card */ - SD_PowerOffCard(g_sd.host.base, g_sd.usrParam.pwr); - } - - /* take card detect semaphore */ - xSemaphoreTake(s_CardDetectSemaphore, portMAX_DELAY); - vTaskDelay(100 / portTICK_PERIOD_MS); - if (s_cardInserted) - { - //Card inserted. - /* power on the card */ - SD_PowerOnCard(g_sd.host.base, g_sd.usrParam.pwr); - /* Init card. */ - if (SD_CardInit(&g_sd)) - { - //SD card init failed. - continue; - } - - FRESULT err = f_mount(&sdCard_FS, "0", 1U); - if (err != FR_OK) { - vTaskDelay(1000 / portTICK_PERIOD_MS); - SD_CardDeinit(&g_sd); - continue; - } - sdCardFileSystemReady = true; - - // post event to managed app - PostManagedEvent( EVENT_STORAGE, 0, EVENT_STORAGE_DEVICE_INSERTION, Storage_Drives_SDCard ); - } - else - { - SD_CardDeinit(&g_sd); - - //Card removed - sdCardFileSystemReady = false; - - // post event to managed app - PostManagedEvent( EVENT_STORAGE, 0, EVENT_STORAGE_DEVICE_REMOVAL, Storage_Drives_SDCard ); - } - } -} - -void SdCardThread(void * argument) -{ - (void)argument; - - s_CardDetectSemaphore = xSemaphoreCreateBinary(); - - sdCardFileSystemReady = false; - - g_sd.host.base = SD_HOST_BASEADDR; - g_sd.host.sourceClock_Hz = SD_HOST_CLK_FREQ; - g_sd.usrParam.cd = &s_sdCardDetect; - - NVIC_SetPriority(SD_HOST_IRQ, 5U); - - /* SD host init function */ - if (SD_HostInit(&g_sd) != kStatus_Success) - { - //SD host init fail - vTaskDelete(NULL); - return; - } - - xTaskCreate(CardDetectTask, "CardDetectTask", configMINIMAL_STACK_SIZE + 500, NULL, configMAX_PRIORITIES - 2, NULL); - - vTaskDelete(NULL); -} - - -/////////////////////////////////////////// - diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/hardfault.c b/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/hardfault.c deleted file mode 100644 index 51c172ee7f..0000000000 --- a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/common/hardfault.c +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// See LICENSE file in the project root for full license information. -// - -#include "MIMXRT1062.h" - -void prvGetRegistersFromStack( unsigned int *pulFaultStackAddress ) -{ - /* These are volatile to try and prevent the compiler/linker optimising them - away as the variables never actually get used. If the debugger won't show the - values of the variables, make them global my moving their declaration outside - of this function. */ - volatile unsigned int r0; - volatile unsigned int r1; - volatile unsigned int r2; - volatile unsigned int r3; - volatile unsigned int r12; - volatile unsigned int lr; /* Link register. */ - volatile unsigned int pc; /* Program counter. */ - volatile unsigned int psr;/* Program status register. */ - - r0 = pulFaultStackAddress[ 0 ]; - r1 = pulFaultStackAddress[ 1 ]; - r2 = pulFaultStackAddress[ 2 ]; - r3 = pulFaultStackAddress[ 3 ]; - - r12 = pulFaultStackAddress[ 4 ]; - lr = pulFaultStackAddress[ 5 ]; - pc = pulFaultStackAddress[ 6 ]; - psr = pulFaultStackAddress[ 7 ]; - - (void)r0; - (void)r1; - (void)r2; - (void)r3; - (void)r12; - (void)lr; - (void)pc; - (void)psr; - - // forces a breakpoint causing the debugger to stop - // if no debugger is attached this is ignored - __asm volatile("BKPT #0\n"); - - // If no debugger connected, just reset the board - NVIC_SystemReset(); - - for( ;; ); -} - -__attribute__((naked)) -void HardFault_Handler(void) -{ - __asm volatile - ( - " tst lr, #4 \n" - " ite eq \n" - " mrseq r0, msp \n" - " mrsne r0, psp \n" - " ldr r1, [r0, #24] \n" - " ldr r2, handler2_address_const \n" - " bx r2 \n" - " handler2_address_const: .word prvGetRegistersFromStack \n" - ); -} - diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native.cpp b/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native.cpp deleted file mode 100644 index 3e7deae37b..0000000000 --- a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// See LICENSE file in the project root for full license information. -// - -#include "win_storage_native.h" - - -static const CLR_RT_MethodHandler method_lookup[] = -{ - NULL, - NULL, - NULL, - NULL, - Library_win_storage_native_Windows_Storage_FileIO::WriteBytes___STATIC__VOID__WindowsStorageIStorageFile__SZARRAY_U1, - Library_win_storage_native_Windows_Storage_FileIO::WriteText___STATIC__VOID__WindowsStorageIStorageFile__STRING, - Library_win_storage_native_Windows_Storage_FileIO::ReadBufferNative___STATIC__VOID__WindowsStorageIStorageFile__BYREF_SZARRAY_U1, - Library_win_storage_native_Windows_Storage_FileIO::ReadTextNative___STATIC__VOID__WindowsStorageIStorageFile__BYREF_STRING, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - Library_win_storage_native_Windows_Storage_StorageFolder::GetRemovableStorageFoldersNative___SZARRAY_WindowsStorageStorageFolder, - Library_win_storage_native_Windows_Storage_StorageFolder::GetStorageFoldersNative___SZARRAY_WindowsStorageStorageFolder, - Library_win_storage_native_Windows_Storage_StorageFolder::GetStorageFilesNative___SZARRAY_WindowsStorageStorageFile__U4__U4, - Library_win_storage_native_Windows_Storage_StorageFolder::CreateFileNative___WindowsStorageStorageFile__STRING__U4, - Library_win_storage_native_Windows_Storage_StorageFolder::CreateFolderNative___WindowsStorageStorageFolder__STRING__U4, - NULL, - NULL, - NULL, -}; - -const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_Windows_Storage = -{ - "Windows.Storage", - 0xD730861C, - method_lookup, - { 1, 0, 0, 0 } -}; diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native.h b/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native.h deleted file mode 100644 index a269784a12..0000000000 --- a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native.h +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// See LICENSE file in the project root for full license information. -// - - -#ifndef _WIN_STORAGE_NATIVE_H_ -#define _WIN_STORAGE_NATIVE_H_ - -#include -#include - -struct Library_win_storage_native_Windows_Storage_FileIO -{ - NANOCLR_NATIVE_DECLARE(WriteBytes___STATIC__VOID__WindowsStorageIStorageFile__SZARRAY_U1); - NANOCLR_NATIVE_DECLARE(WriteText___STATIC__VOID__WindowsStorageIStorageFile__STRING); - NANOCLR_NATIVE_DECLARE(ReadBufferNative___STATIC__VOID__WindowsStorageIStorageFile__BYREF_SZARRAY_U1); - NANOCLR_NATIVE_DECLARE(ReadTextNative___STATIC__VOID__WindowsStorageIStorageFile__BYREF_STRING); - - //--// - -}; - -struct Library_win_storage_native_Windows_Storage_StorageFile -{ - static const int FIELD___dateCreated = 1; - static const int FIELD___name = 2; - static const int FIELD___path = 3; - - - //--// - -}; - -struct Library_win_storage_native_Windows_Storage_StorageFolder -{ - static const int FIELD___knownFolderId = 1; - static const int FIELD___dateCreated = 2; - static const int FIELD___name = 3; - static const int FIELD___path = 4; - - NANOCLR_NATIVE_DECLARE(GetRemovableStorageFoldersNative___SZARRAY_WindowsStorageStorageFolder); - NANOCLR_NATIVE_DECLARE(GetStorageFoldersNative___SZARRAY_WindowsStorageStorageFolder); - NANOCLR_NATIVE_DECLARE(GetStorageFilesNative___SZARRAY_WindowsStorageStorageFile__U4__U4); - NANOCLR_NATIVE_DECLARE(CreateFileNative___WindowsStorageStorageFile__STRING__U4); - NANOCLR_NATIVE_DECLARE(CreateFolderNative___WindowsStorageStorageFolder__STRING__U4); - - //--// - -}; - -struct Library_win_storage_native_Windows_Storage_StorageProvider -{ - static const int FIELD___displayName = 1; - static const int FIELD___id = 2; - - - //--// - -}; - -extern const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_Windows_Storage; - -#endif //_WIN_STORAGE_NATIVE_H_ diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_FileIO.cpp b/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_FileIO.cpp deleted file mode 100644 index 1a2d31dab7..0000000000 --- a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_FileIO.cpp +++ /dev/null @@ -1,659 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// See LICENSE file in the project root for full license information. -// - -#include -#include "win_storage_native.h" -#include - -#if HAL_USBH_USE_MSD -#include "usbh/dev/msd.h" -#endif - -// defining these types here to make it shorter and improve code readability -typedef Library_win_storage_native_Windows_Storage_StorageFolder StorageFolder; -typedef Library_win_storage_native_Windows_Storage_StorageFile StorageFile; - -////////////////////////////////////////// - -struct FileOperation -{ - FIL* File; - char* Content; - uint32_t ContentLength; -}; - -// this is the FileIO working thread -static volatile FRESULT threadOperationResult; - -// ReadText working thread -static void ReadTextWorkingThread(void * arg) -{ - - FileOperation* fileIoOperation = (FileOperation*)arg; - - // need an extra one for the terminator - uint32_t readLength = fileIoOperation->ContentLength + 1; - - // read string - if(f_gets((TCHAR*)fileIoOperation->Content, readLength, fileIoOperation->File)) - { - threadOperationResult = FR_OK; - } - else - { - threadOperationResult = (FRESULT)f_error(fileIoOperation->File); - } - - // close file - f_close(fileIoOperation->File); - - // free memory - platform_free(fileIoOperation->File); - platform_free(fileIoOperation); - - // fire event for FileIO operation complete - Events_Set(SYSTEM_EVENT_FLAG_STORAGE_IO); - - vTaskDelete(NULL); -} - -// WriteText working thread -static void WriteTextWorkingThread(void *arg) -{ - - FileOperation* fileIoOperation = (FileOperation*)arg; - if(f_puts(fileIoOperation->Content, fileIoOperation->File) == (int)fileIoOperation->ContentLength) - { - // expected number of bytes written - threadOperationResult = FR_OK; - } - - // close file - f_close(fileIoOperation->File); - - // free memory - platform_free(fileIoOperation->File); - platform_free(fileIoOperation); - - // fire event for FileIO operation complete - Events_Set(SYSTEM_EVENT_FLAG_STORAGE_IO); - - vTaskDelete(NULL); -} - -// WriteBinary working thread -static void WriteBinaryWorkingThread(void *arg) -{ - UINT bytesWritten; - - FileOperation* fileIoOperation = (FileOperation*)arg; - - threadOperationResult = f_write(fileIoOperation->File, fileIoOperation->Content, fileIoOperation->ContentLength, &bytesWritten); - - if( (threadOperationResult == FR_OK) && - (bytesWritten == fileIoOperation->ContentLength)) - { - // expected number of bytes written - threadOperationResult = FR_OK; - } - - // close file - f_close(fileIoOperation->File); - - // free memory - platform_free(fileIoOperation->File); - platform_free(fileIoOperation); - - // fire event for FileIO operation complete - Events_Set(SYSTEM_EVENT_FLAG_STORAGE_IO); - - vTaskDelete(NULL); -} - -// ReadBinary working thread -static void ReadBinaryWorkingThread(void *arg) -{ - UINT bytesRead; - - FileOperation* fileIoOperation = (FileOperation*)arg; - - threadOperationResult = f_read(fileIoOperation->File, fileIoOperation->Content, fileIoOperation->ContentLength, &bytesRead); - - if( (threadOperationResult == FR_OK) && - (bytesRead == fileIoOperation->ContentLength)) - { - // expected number of bytes read - threadOperationResult = FR_OK; - } - - // close file - f_close(fileIoOperation->File); - - // free memory - platform_free(fileIoOperation->File); - platform_free(fileIoOperation); - - // fire event for FileIO operation complete - Events_Set(SYSTEM_EVENT_FLAG_STORAGE_IO); - - vTaskDelete(NULL); -} - -//////////////////////////////////////////////// -// Developer notes: -// Depending on the content size these operations have the potential to be a long running ones as the string or buffer is written to the storage. -// Despite we are not (yet!) async this is better handled by spawning a thread where the actual data transfer occurs and not blocking the execution. -// The underlying RTOS inheritably takes care of making this happen "in the background". -// When the operation is completed a CLR event is fired and the thread execution resumes. -// Being hard to estimate the expected duration of the operation (depends on storage hardware, CPU clock, transfer speed, etc) -// the timeout is set to an infinite timeout -// the catch is that the working thread MUST ALWAYS return at some point -//////////////////////////////////////////////// - -HRESULT Library_win_storage_native_Windows_Storage_FileIO::WriteBytes___STATIC__VOID__WindowsStorageIStorageFile__SZARRAY_U1( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); - - CLR_RT_HeapBlock_Array* bufferArray; - - char workingDrive[DRIVE_LETTER_LENGTH]; - - CLR_RT_HeapBlock hbTimeout; - CLR_INT64* timeout; - bool eventResult = true; - - FileOperation* fileIoOperation; - - char* buffer; - uint32_t bufferLength; - - const TCHAR* filePath; - FIL* file; - FRESULT operationResult; - - // get a pointer to the managed object instance and check that it's not NULL - CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); - - // get a pointer to the buffer - bufferArray = stack.Arg1().DereferenceArray(); - - buffer = (char*)bufferArray->GetFirstElement(); - - bufferLength = bufferArray->m_numOfElements; - - // get a pointer to the file path - filePath = (TCHAR*)pThis[ StorageFile::FIELD___path ].DereferenceString()->StringText(); - - // !! need to cast to CLR_INT64 otherwise it wont setup a proper timeout infinite - hbTimeout.SetInteger((CLR_INT64)-1); - - NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks( hbTimeout, timeout )); - - if(stack.m_customState == 1) - { - // copy the first 2 letters of the path for the drive - // path is 'D:\folder\file.txt', so we need 'D:' - memcpy(workingDrive, filePath, DRIVE_LETTER_LENGTH); - - // create file struct - file = (FIL*)platform_malloc(sizeof(FIL)); - // check allocation - if(file == NULL) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - - // open file (which is supposed to already exist) - // need to use FA_OPEN_ALWAYS because we are writting the file content from start - operationResult = f_open(file, filePath, FA_OPEN_ALWAYS | FA_WRITE); - - if(operationResult != FR_OK) - { - NANOCLR_SET_AND_LEAVE(CLR_E_FILE_NOT_FOUND); - } - else - { - // protect the StorageFile and the content buffer from GC so the working thread can access those - CLR_RT_ProtectFromGC gcStorageFile( *pThis ); - CLR_RT_ProtectFromGC gcContent( *bufferArray ); - - // setup FileIO operation - fileIoOperation = (FileOperation*)platform_malloc(sizeof(FileOperation)); - - fileIoOperation->File = file; - fileIoOperation->Content = buffer; - fileIoOperation->ContentLength = bufferLength; - - // spawn working thread to perform the write transaction - BaseType_t ret; - ret = xTaskCreate(WriteBinaryWorkingThread, "WriteBin", 2048, fileIoOperation, configMAX_PRIORITIES - 2, NULL); - - if (ret != pdPASS) - { - NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); - } - - // bump custom state - stack.m_customState = 2; - } - } - - while(eventResult) - { - // non-blocking wait allowing other threads to run while we wait for the write operation to complete - NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_StorageIo, eventResult )); - - if(eventResult) - { - // event occurred - - if(operationResult == FR_DISK_ERR) - { - NANOCLR_SET_AND_LEAVE( CLR_E_FILE_IO ); - } - else if(operationResult == FR_NO_FILE) - { - NANOCLR_SET_AND_LEAVE( CLR_E_FILE_NOT_FOUND ); - } - else if(operationResult == FR_INVALID_DRIVE) - { - // failed to change drive - NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND); - } - - // done here - break; - } - else - { - NANOCLR_SET_AND_LEAVE( CLR_E_TIMEOUT ); - } - } - - // pop timeout heap block from stack - stack.PopValue(); - - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_win_storage_native_Windows_Storage_FileIO::WriteText___STATIC__VOID__WindowsStorageIStorageFile__STRING( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); - - CLR_RT_HeapBlock_String* content; - - char workingDrive[DRIVE_LETTER_LENGTH]; - - CLR_RT_HeapBlock hbTimeout; - CLR_INT64* timeout; - bool eventResult = true; - - FileOperation* fileIoOperation; - - const TCHAR* filePath; - FIL* file; - FRESULT operationResult; - - // get a pointer to the managed object instance and check that it's not NULL - CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); - - // get a pointer to the content - content = stack.Arg1().DereferenceString(); - - // get a pointer to the file path - filePath = (TCHAR*)pThis[ StorageFile::FIELD___path ].DereferenceString()->StringText(); - - // !! need to cast to CLR_INT64 otherwise it wont setup a proper timeout infinite - hbTimeout.SetInteger((CLR_INT64)-1); - - NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks( hbTimeout, timeout )); - - if(stack.m_customState == 1) - { - // copy the first 2 letters of the path for the drive - // path is 'D:\folder\file.txt', so we need 'D:' - memcpy(workingDrive, filePath, DRIVE_LETTER_LENGTH); - - // create file struct - file = (FIL*)platform_malloc(sizeof(FIL)); - // check allocation - if(file == NULL) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - - // open file (which is supposed to already exist) - // need to use FA_OPEN_ALWAYS because we are writting the file content from start - operationResult = f_open(file, filePath, FA_OPEN_ALWAYS | FA_WRITE); - - if(operationResult != FR_OK) - { - NANOCLR_SET_AND_LEAVE(CLR_E_FILE_NOT_FOUND); - } - else - { - // protect the StorageFile and the content buffer from GC so the working thread can access those - CLR_RT_ProtectFromGC gcStorageFile( *pThis ); - CLR_RT_ProtectFromGC gcContent( *content ); - - // setup FileIO operation - fileIoOperation = (FileOperation*)platform_malloc(sizeof(FileOperation)); - - fileIoOperation->File = file; - fileIoOperation->Content = (char*)content->StringText(); - fileIoOperation->ContentLength = hal_strlen_s(fileIoOperation->Content); - - // spawn working thread to perform the write transaction - BaseType_t ret; - ret = xTaskCreate(WriteTextWorkingThread, "WriteText", 2048, fileIoOperation, configMAX_PRIORITIES - 2, NULL); - - if (ret != pdPASS) - { - NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); - } - - // bump custom state - stack.m_customState = 2; - } - } - - while(eventResult) - { - // non-blocking wait allowing other threads to run while we wait for the write operation to complete - NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_StorageIo, eventResult )); - - if(eventResult) - { - // event occurred - - if(threadOperationResult == FR_DISK_ERR) - { - NANOCLR_SET_AND_LEAVE( CLR_E_FILE_IO ); - } - else if(threadOperationResult == FR_NO_FILE) - { - NANOCLR_SET_AND_LEAVE( CLR_E_FILE_NOT_FOUND ); - } - else if(threadOperationResult == FR_INVALID_DRIVE) - { - // failed to change drive - NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND); - } - - // done here - break; - } - else - { - NANOCLR_SET_AND_LEAVE( CLR_E_TIMEOUT ); - } - } - - // pop timeout heap block from stack - stack.PopValue(); - - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_win_storage_native_Windows_Storage_FileIO::ReadBufferNative___STATIC__VOID__WindowsStorageIStorageFile__BYREF_SZARRAY_U1( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); - - CLR_RT_HeapBlock hbTimeout; - CLR_INT64* timeout; - bool eventResult = true; - - FileOperation* fileIoOperation; - - char workingDrive[DRIVE_LETTER_LENGTH]; - const TCHAR* filePath; - - FIL* file; - static FILINFO fileInfo; - FRESULT operationResult; - - // get a pointer to the managed object instance and check that it's not NULL - CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); - - // !! need to cast to CLR_INT64 otherwise it wont setup a proper timeout infinite - hbTimeout.SetInteger((CLR_INT64)-1); - - NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks( hbTimeout, timeout )); - - // get a pointer to the file path - filePath = (TCHAR*)pThis[ StorageFile::FIELD___path ].DereferenceString()->StringText(); - - if(stack.m_customState == 1) - { - // protect the StorageFile from GC - CLR_RT_ProtectFromGC gcStorageFile( *pThis ); - - // copy the first 2 letters of the path for the drive - // path is 'D:\folder\file.txt', so we need 'D:' - memcpy(workingDrive, filePath, DRIVE_LETTER_LENGTH); - - // create file struct - file = (FIL*)platform_malloc(sizeof(FIL)); - // check allocation - if(file == NULL) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - - // open file (which is supposed to already exist) - // need to use FA_OPEN_EXISTING because we are reading an existing file content from start - operationResult = f_open(file, filePath, FA_OPEN_EXISTING | FA_READ); - - if(operationResult != FR_OK) - { - NANOCLR_SET_AND_LEAVE(CLR_E_FILE_NOT_FOUND); - } - else - { - // get file details - f_stat(filePath, &fileInfo); - - CLR_RT_HeapBlock buffer; - buffer.SetObjectReference( NULL ); - CLR_RT_ProtectFromGC gc2( buffer ); - - // create a new byte array with the appropriate size (and type) - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( buffer, (CLR_INT32)fileInfo.fsize, g_CLR_RT_WellKnownTypes.m_UInt8 )); - - // store this to the argument passed byref - NANOCLR_CHECK_HRESULT(buffer.StoreToReference( stack.Arg1(), 0 )); - - // get a pointer to the buffer array to improve readability on the code ahead - CLR_RT_HeapBlock_Array* bufferArray = buffer.DereferenceArray(); - - // setup FileIO operation - fileIoOperation = (FileOperation*)platform_malloc(sizeof(FileOperation)); - - fileIoOperation->File = file; - fileIoOperation->Content = (char*)bufferArray->GetFirstElement(); - fileIoOperation->ContentLength = bufferArray->m_numOfElements; - - // spawn working thread to perform the read transaction - BaseType_t ret; - ret = xTaskCreate(ReadBinaryWorkingThread, "ReadBin", 2048, fileIoOperation, configMAX_PRIORITIES - 2, NULL); - - if (ret != pdPASS) - { - NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); - } - - // bump custom state - stack.m_customState = 2; - } - } - - while(eventResult) - { - // non-blocking wait allowing other threads to run while we wait for the write operation to complete - NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_StorageIo, eventResult )); - - if(eventResult) - { - // event occurred - - if(operationResult == FR_DISK_ERR) - { - NANOCLR_SET_AND_LEAVE( CLR_E_FILE_IO ); - } - else if(operationResult == FR_NO_FILE) - { - NANOCLR_SET_AND_LEAVE( CLR_E_FILE_NOT_FOUND ); - } - else if(operationResult == FR_INVALID_DRIVE) - { - // failed to change drive - NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND); - } - - // done here - break; - } - else - { - NANOCLR_SET_AND_LEAVE( CLR_E_TIMEOUT ); - } - } - - // pop timeout heap block from stack - stack.PopValue(); - - NANOCLR_NOCLEANUP(); -} - -HRESULT Library_win_storage_native_Windows_Storage_FileIO::ReadTextNative___STATIC__VOID__WindowsStorageIStorageFile__BYREF_STRING( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); - - CLR_RT_HeapBlock hbTimeout; - CLR_INT64* timeout; - bool eventResult = true; - - FileOperation* fileIoOperation; - - char workingDrive[DRIVE_LETTER_LENGTH]; - const TCHAR* filePath; - - FIL* file; - static FILINFO fileInfo; - FRESULT operationResult; - - // get a pointer to the managed object instance and check that it's not NULL - CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); - - // !! need to cast to CLR_INT64 otherwise it wont setup a proper timeout infinite - hbTimeout.SetInteger((CLR_INT64)-1); - - NANOCLR_CHECK_HRESULT(stack.SetupTimeoutFromTicks( hbTimeout, timeout )); - - // get a pointer to the file path - filePath = (TCHAR*)pThis[ StorageFile::FIELD___path ].DereferenceString()->StringText(); - - if(stack.m_customState == 1) - { - // protect the StorageFile and the content buffer from GC so the working thread can access those - CLR_RT_ProtectFromGC gcStorageFile( *pThis ); - - // copy the first 2 letters of the path for the drive - // path is 'D:\folder\file.txt', so we need 'D:' - memcpy(workingDrive, filePath, DRIVE_LETTER_LENGTH); - - // create file struct - file = (FIL*)platform_malloc(sizeof(FIL)); - // check allocation - if(file == NULL) - { - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - - // open file (which is supposed to already exist) - // need to use FA_OPEN_EXISTING because we are reading an existing file content from start - operationResult = f_open(file, filePath, FA_OPEN_EXISTING | FA_READ); - - if(operationResult != FR_OK) - { - NANOCLR_SET_AND_LEAVE(CLR_E_FILE_NOT_FOUND); - } - else - { - // get file details - f_stat(filePath, &fileInfo); - - // create a new string object with the appropriate size - CLR_RT_HeapBlock hbText; - hbText.SetObjectReference( NULL ); - CLR_RT_ProtectFromGC gc( hbText ); - - CLR_RT_HeapBlock_String* textString = CLR_RT_HeapBlock_String::CreateInstance( hbText, (CLR_UINT32)fileInfo.fsize ); - FAULT_ON_NULL(textString); - - // store this to the argument passed byref - NANOCLR_CHECK_HRESULT(hbText.StoreToReference( stack.Arg1(), 0 )); - - // get a pointer to the buffer array to improve readability on the code ahead - hbText.DereferenceString(); - - // setup FileIO operation - fileIoOperation = (FileOperation*)platform_malloc(sizeof(FileOperation)); - - fileIoOperation->File = file; - fileIoOperation->Content = (char*)textString->StringText(); - fileIoOperation->ContentLength = fileInfo.fsize; - - // spawn working thread to perform the read transaction - BaseType_t ret; - ret = xTaskCreate(ReadTextWorkingThread, "ReadText", 2048, fileIoOperation, configMAX_PRIORITIES - 2, NULL); - - if (ret != pdPASS) - { - NANOCLR_SET_AND_LEAVE(CLR_E_PROCESS_EXCEPTION); - } - - // bump custom state - stack.m_customState = 2; - } - } - - while(eventResult) - { - // non-blocking wait allowing other threads to run while we wait for the write operation to complete - NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_StorageIo, eventResult )); - - if(eventResult) - { - // event occurred - - if(threadOperationResult == FR_DISK_ERR) - { - NANOCLR_SET_AND_LEAVE( CLR_E_FILE_IO ); - } - else if(threadOperationResult == FR_NO_FILE) - { - NANOCLR_SET_AND_LEAVE( CLR_E_FILE_NOT_FOUND ); - } - else if(threadOperationResult == FR_INVALID_DRIVE) - { - // failed to change drive - NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND); - } - - // done here - break; - } - else - { - NANOCLR_SET_AND_LEAVE( CLR_E_TIMEOUT ); - } - } - - // pop timeout heap block from stack - stack.PopValue(); - - NANOCLR_NOCLEANUP(); -} diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFolder.cpp b/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFolder.cpp deleted file mode 100644 index d172a54d80..0000000000 --- a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/Windows.Storage/win_storage_native_Windows_Storage_StorageFolder.cpp +++ /dev/null @@ -1,840 +0,0 @@ -// -// Copyright (c) 2018 The nanoFramework project contributors -// See LICENSE file in the project root for full license information. -// - -#include -#include "win_storage_native.h" -#include -#include - -// flags for file system ready -extern bool sdCardFileSystemReady; - -// defining these types here to make it shorter and improve code readability -typedef Library_win_storage_native_Windows_Storage_StorageFolder StorageFolder; -typedef Library_win_storage_native_Windows_Storage_StorageFile StorageFile; - -SYSTEMTIME GetDateTime(uint16_t date, uint16_t time) -{ - SYSTEMTIME fileTime; - - memset(&fileTime, 0, sizeof(SYSTEMTIME)); - - // date (bit15:9) Year origin from 1980 (0..127) - fileTime.wYear = (date >> 9) + 1980; - // date (bit8:5) Month (1..12) - fileTime.wMonth = (date >> 5) & 0x000F; - // date (bit4:0) Day (1..31) - fileTime.wDay = date & 0x001F; - - // time (bit15:11) Hour (0..23) - fileTime.wHour = (time >> 11) & 0x001F; - // time (bit10:5) Minute (0..59) - fileTime.wMinute = (time >> 5) & 0x003F; - // time (bit4:0) Second / 2 (0..29) - fileTime.wSecond = time & 0x001F; - - return fileTime; -} - -HRESULT StorageFolder::GetRemovableStorageFoldersNative___SZARRAY_WindowsStorageStorageFolder( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); - - char* stringBuffer; - uint32_t driveCount = 0; - char workingDrive[sizeof(DRIVE_PATH_LENGTH)]; - uint16_t driveIterator = (uint16_t)Storage_Drives_SDCard; - - CLR_RT_HeapBlock* storageFolder; - CLR_RT_TypeDef_Index storageFolderTypeDef; - CLR_RT_HeapBlock* hbObj; - CLR_RT_HeapBlock& top = stack.PushValue(); - - // default to NULL (which is the expected outcome when no devices are connected) - hbObj = top.Dereference(); - hbObj->SetObjectReference( NULL ); - - // is the SD card file system ready? - if(sdCardFileSystemReady) - { - // add count - driveCount++; - } - - // start composing the reply - // find type definition, don't bother checking the result as it exists for sure - g_CLR_RT_TypeSystem.FindTypeDef( "StorageFolder", "Windows.Storage", storageFolderTypeDef ); - - // create an array of - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, driveCount, storageFolderTypeDef )); - - if(driveCount > 0) - { - // there are driver present and enumerated - - // get a pointer to the first object in the array (which is of type ) - storageFolder = (CLR_RT_HeapBlock*)top.DereferenceArray()->GetFirstElement(); - - // create an instance of - NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(*storageFolder, storageFolderTypeDef)); - - // loop until we've loaded all the possible drives - // because we are iterating through an enum, need to use its integer values - for(; driveIterator < driveCount; driveIterator++ ) - { - // fill the folder name and path - switch(driveIterator) - { - case 0: - memcpy(workingDrive, INDEX0_DRIVE_PATH, DRIVE_PATH_LENGTH); - break; - - case 1: - memcpy(workingDrive, INDEX1_DRIVE_PATH, DRIVE_PATH_LENGTH); - break; - - default: - // shouldn't reach here - NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); - break; - } - - // dereference the object in order to reach its fields - hbObj = storageFolder->Dereference(); - - // set the managed fields - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbObj[ StorageFolder::FIELD___name ], workingDrive )); - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbObj[ StorageFolder::FIELD___path ], workingDrive )); - - // malloc stringBuffer to work with FS - stringBuffer = (char*)platform_malloc(FF_LFN_BUF + 1); - - // sanity check for successfull malloc - if(stringBuffer == NULL) - { - // failed to allocate memory - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - else - { - // clear buffer - memset(stringBuffer, 0, FF_LFN_BUF + 1); - - // read the drive volume label - // don't bother checking the result, if anything goes wrong we'll end up with an empty string which is OK - f_getlabel(workingDrive, stringBuffer, NULL); - - // add the driver letter separated it with an empty space, if the volume label isn't empty - if(*stringBuffer != '\0') - { - strcat(stringBuffer, " "); - } - strcat(stringBuffer, "("); - strcat(stringBuffer, workingDrive); - strcat(stringBuffer, ")"); - - // set the field with the volume label - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbObj[ StorageFolder::FIELD___name ], stringBuffer )); - - - // free stringBuffer - platform_free(stringBuffer); - } - - // move pointer to the next folder item - storageFolder++; - } - } - - NANOCLR_NOCLEANUP(); -} - -HRESULT StorageFolder::GetStorageFoldersNative___SZARRAY_WindowsStorageStorageFolder( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); - - CLR_RT_TypeDef_Index storageFolderTypeDef; - CLR_RT_HeapBlock* storageFolder; - CLR_RT_HeapBlock* hbObj; - SYSTEMTIME fileInfoTime; - - const char* workingPath; - - DIR currentDirectory; - FRESULT operationResult; - static FILINFO fileInfo; - uint16_t directoryCount = 0; - char* stringBuffer = NULL; - char* workingBuffer = NULL; - - CLR_RT_HeapBlock& top = stack.PushValue(); - - // get a pointer to the managed object instance and check that it's not NULL - CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); - - // get a pointer to the path in managed field - workingPath = pThis[ StorageFolder::FIELD___path ].DereferenceString()->StringText(); - - // open directory - operationResult = f_opendir(¤tDirectory, workingPath); - - if(operationResult != FR_OK) - { - if(operationResult == FR_INVALID_DRIVE) - { - // failed to change drive - NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND); - } - - // error or directory empty - // find type, don't bother checking the result as it exists for sure - g_CLR_RT_TypeSystem.FindTypeDef( "StorageFolder", "Windows.Storage", storageFolderTypeDef ); - - // create an array of - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, directoryCount, storageFolderTypeDef )); - } - else - { - // need to perform this in two steps - // 1st: count the directory objects - // 2nd: create the array items with each directory object - - // perform 1st pass - for (;;) - { - // read next directory item - operationResult = f_readdir(¤tDirectory, &fileInfo); - - // break on error or at end of dir - if (operationResult != FR_OK || fileInfo.fname[0] == 0) - { - break; - } - - // check if this is a directory - // but skip if: - // - has system attribute set - // - has hidden attribute set - if ((fileInfo.fattrib & AM_DIR) && - !(fileInfo.fattrib & AM_SYS) && - !(fileInfo.fattrib & AM_HID)) - { - directoryCount++; - } - } - - // find type, don't bother checking the result as it exists for sure - g_CLR_RT_TypeSystem.FindTypeDef( "StorageFolder", "Windows.Storage", storageFolderTypeDef ); - - // create an array of - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, directoryCount, storageFolderTypeDef )); - - // get a pointer to the first object in the array (which is of type ) - storageFolder = (CLR_RT_HeapBlock*)top.DereferenceArray()->GetFirstElement(); - - if(directoryCount > 0) - { - // allocate memory for buffers - stringBuffer = (char*)platform_malloc(FF_LFN_BUF + 1); - workingBuffer = (char*)platform_malloc(2 * FF_LFN_BUF + 1); - - // sanity check for successfull malloc - if(stringBuffer == NULL || workingBuffer == NULL) - { - // failed to allocate memory - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - - // perform 2nd pass - // need to rewind the directory read index first - f_readdir(¤tDirectory, NULL); - - for (;;) - { - // read next directory item - operationResult = f_readdir(¤tDirectory, &fileInfo); - - // break on error or at end of dir - if (operationResult != FR_OK || fileInfo.fname[0] == 0) - { - break; - } - - // check if this is a directory - // but skip if: - // - has system attribute set - // - has hidden attribute set - if ((fileInfo.fattrib & AM_DIR) && - !(fileInfo.fattrib & AM_SYS) && - !(fileInfo.fattrib & AM_HID)) - { - // create an instance of - NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(*storageFolder, storageFolderTypeDef)); - - // dereference the object in order to reach its fields - hbObj = storageFolder->Dereference(); - - // directory name - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbObj[ StorageFolder::FIELD___name ], fileInfo.fname )); - - // clear working buffer - memset(workingBuffer, 0, 2 * FF_LFN_BUF + 1); - - // compose directory path - strcat(workingBuffer, workingPath); - strcat(workingBuffer, "\\"); - strcat(workingBuffer, fileInfo.fname); - - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbObj[ StorageFolder::FIELD___path ], workingBuffer )); - - // compute directory date - fileInfoTime = GetDateTime(fileInfo.fdate, fileInfo.ftime); - - // get a reference to the dateCreated managed field... - CLR_RT_HeapBlock& dateFieldRef = hbObj[ StorageFolder::FIELD___dateCreated ]; - CLR_INT64* pRes = (CLR_INT64*)&dateFieldRef.NumericByRef().s8; - // ...and set it with the fileInfoTime - *pRes = HAL_Time_ConvertFromSystemTime( &fileInfoTime ); - - // move the storage folder pointer to the next item in the array - storageFolder++; - } - } - } - } - - NANOCLR_CLEANUP(); - - // close directory - f_closedir(¤tDirectory); - - // free buffers memory, if allocated - if(stringBuffer != NULL) - { - platform_free(stringBuffer); - } - if(workingBuffer != NULL) - { - platform_free(workingBuffer); - } - - NANOCLR_CLEANUP_END(); -} - -HRESULT StorageFolder::GetStorageFilesNative___SZARRAY_WindowsStorageStorageFile__U4__U4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); - - CLR_RT_TypeDef_Index storageFileTypeDef; - CLR_RT_HeapBlock* storageFile; - CLR_RT_HeapBlock* hbObj; - SYSTEMTIME fileInfoTime; - - const char* workingPath; - char workingDrive[DRIVE_LETTER_LENGTH]; - - uint32_t startIndex; - uint32_t maxItemsToRetrieve; - uint32_t itemIndex = 0; - - DIR currentDirectory; - FRESULT operationResult; - static FILINFO fileInfo; - uint16_t fileCount = 0; - char* stringBuffer = NULL; - char* workingBuffer = NULL; - - CLR_RT_HeapBlock& top = stack.PushValue(); - - // get a pointer to the managed object instance and check that it's not NULL - CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); - - // get start index - startIndex = stack.Arg1().NumericByRef().u4; - - // get max items to retrieve - maxItemsToRetrieve = stack.Arg2().NumericByRef().u4; - - // copy the first 2 letters of the path for the drive - // path is 'D:\folder\file.txt', so we need 'D:' - memcpy(workingDrive, pThis[ StorageFolder::FIELD___path ].DereferenceString()->StringText(), DRIVE_LETTER_LENGTH); - - // get a pointer to the path in managed field - workingPath = pThis[ StorageFolder::FIELD___path ].DereferenceString()->StringText(); - - // change drive - if(f_chdrive(workingDrive) == FR_OK) - { - // open directory - operationResult = f_opendir(¤tDirectory, workingPath); - - if(operationResult != FR_OK) - { - // error or directory empty - // find type, don't bother checking the result as it exists for sure - g_CLR_RT_TypeSystem.FindTypeDef( "StorageFile", "Windows.Storage", storageFileTypeDef ); - - // create an array of - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, fileCount, storageFileTypeDef )); - } - else - { - // need to perform this in two steps - // 1st: count the file objects - // 2nd: create the array items with each file object - - // perform 1st pass - for (;;) - { - // read next directory item - operationResult = f_readdir(¤tDirectory, &fileInfo); - - // break on error or at end of dir - if (operationResult != FR_OK || fileInfo.fname[0] == 0) - { - break; - } - - // check if this is a file - // but skip if: - // - has system attribute set - // - has hidden attribute set - if ((fileInfo.fattrib & AM_ARC) && - !(fileInfo.fattrib & AM_SYS) && - !(fileInfo.fattrib & AM_HID)) - { - // check if this file is within the requested parameters - if( (itemIndex >= startIndex) && - (fileCount < maxItemsToRetrieve)) - { - fileCount++; - } - - itemIndex++; - } - } - - // find type, don't bother checking the result as it exists for sure - g_CLR_RT_TypeSystem.FindTypeDef( "StorageFile", "Windows.Storage", storageFileTypeDef ); - - // create an array of - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, fileCount, storageFileTypeDef )); - - // get a pointer to the first object in the array (which is of type ) - storageFile = (CLR_RT_HeapBlock*)top.DereferenceArray()->GetFirstElement(); - - if(fileCount > 0) - { - // allocate memory for buffers - stringBuffer = (char*)platform_malloc(FF_LFN_BUF + 1); - workingBuffer = (char*)platform_malloc(2 * FF_LFN_BUF + 1); - - // sanity check for successfull malloc - if(stringBuffer == NULL || workingBuffer == NULL) - { - // failed to allocate memory - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - - // perform 2nd pass - // need to rewind the directory read index first - f_readdir(¤tDirectory, NULL); - - // and reset the file iterator vars too - itemIndex = 0; - fileCount = 0; - - - for (;;) - { - // read next directory item - operationResult = f_readdir(¤tDirectory, &fileInfo); - - // break on error or at end of dir - if (operationResult != FR_OK || fileInfo.fname[0] == 0) - { - break; - } - - // check if this is a file - // but skip if: - // - has system attribute set - // - has hidden attribute set - if ((fileInfo.fattrib & AM_ARC) && - !(fileInfo.fattrib & AM_SYS) && - !(fileInfo.fattrib & AM_HID)) - { - // check if this file is within the requested parameters - if( (itemIndex >= startIndex) && - (fileCount < maxItemsToRetrieve)) - { - // create an instance of - NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(*storageFile, storageFileTypeDef)); - - // dereference the object in order to reach its fields - hbObj = storageFile->Dereference(); - - // file name - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbObj[ StorageFile::FIELD___name ], fileInfo.fname )); - - // clear working buffer - memset(workingBuffer, 0, 2 * FF_LFN_BUF + 1); - - // compose file path - strcat(workingBuffer, workingPath); - strcat(workingBuffer, fileInfo.fname); - - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( hbObj[ StorageFile::FIELD___path ], workingBuffer )); - - // compute directory date - fileInfoTime = GetDateTime(fileInfo.fdate, fileInfo.ftime); - - // get a reference to the dateCreated managed field... - CLR_RT_HeapBlock& dateFieldRef = hbObj[ StorageFile::FIELD___dateCreated ]; - CLR_INT64* pRes = (CLR_INT64*)&dateFieldRef.NumericByRef().s8; - // ...and set it with the fileInfoTime - *pRes = HAL_Time_ConvertFromSystemTime( &fileInfoTime ); - - // move the storage folder pointer to the next item in the array - storageFile++; - - // update iterator var - fileCount++; - } - - // update iterator var - itemIndex++; - } - } - } - else - { - // empty directory - // find type, don't bother checking the result as it exists for sure - g_CLR_RT_TypeSystem.FindTypeDef( "StorageFile", "Windows.Storage", storageFileTypeDef ); - - // create an array of - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( top, fileCount, storageFileTypeDef )); - } - } - } - else - { - // failed to change drive - NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND); - } - - NANOCLR_CLEANUP(); - - // close directory - f_closedir(¤tDirectory); - - // free buffers memory, if allocated - if(stringBuffer != NULL) - { - platform_free(stringBuffer); - } - if(workingBuffer != NULL) - { - platform_free(workingBuffer); - } - - NANOCLR_CLEANUP_END(); -} - -HRESULT StorageFolder::CreateFileNative___WindowsStorageStorageFile__STRING__U4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); - - CLR_RT_TypeDef_Index storageFileTypeDef; - CLR_RT_HeapBlock* storageFile; - - const char* fileName; - const char* workingPath; - - CreationCollisionOption options; - - FIL file; - static FILINFO fileInfo; - SYSTEMTIME fileInfoTime; - FRESULT operationResult; - uint8_t modeFlags = 0; - char* filePath = NULL; - - // get a pointer to the managed object instance and check that it's not NULL - CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); - - // get creation collision options - options = (CreationCollisionOption)stack.Arg2().NumericByRef().u4; - - // get a pointer to the StorageFolder path in managed field - workingPath = pThis[ StorageFolder::FIELD___path ].DereferenceString()->StringText(); - - // get a pointer to the desired file name - fileName = stack.Arg1().DereferenceString()->StringText(); - - // setup file path - filePath = (char*)platform_malloc(2 * FF_LFN_BUF + 1); - - // sanity check for successfull malloc - if(filePath == NULL) - { - // failed to allocate memory - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - - // clear working buffer - memset(filePath, 0, 2 * FF_LFN_BUF + 1); - - // compose file path - strcat(filePath, workingPath); - strcat(filePath, fileName); - - // change directory - operationResult = f_chdir(workingPath); - - if(operationResult != FR_OK) - { - if(operationResult == FR_INVALID_DRIVE) - { - // failed to change drive - NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND); - } - // error opening the directoty - NANOCLR_SET_AND_LEAVE(CLR_E_DIRECTORY_NOT_FOUND); - } - else - { - // compute mode flags from CreationCollisionOption - switch (options) - { - case CreationCollisionOption_ReplaceExisting: - modeFlags = FA_CREATE_ALWAYS; - break; - - case CreationCollisionOption_FailIfExists: - modeFlags = FA_CREATE_NEW; - break; - - case CreationCollisionOption_OpenIfExists: - modeFlags = FA_OPEN_EXISTING; - break; - - case CreationCollisionOption_GenerateUniqueName: - // this operation is not supported in nanoFramework - NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); - break; - - default: - break; - } - - // open file - operationResult = f_open(&file, filePath, modeFlags); - - // process operation result according to creation options - if( (operationResult == FR_EXIST) && - (options == CreationCollisionOption_FailIfExists)) - { - // file already exists - NANOCLR_SET_AND_LEAVE(CLR_E_PATH_ALREADY_EXISTS); - } - if( (operationResult == FR_NO_FILE) && - (options == CreationCollisionOption_OpenIfExists)) - { - // file doesn't exist - NANOCLR_SET_AND_LEAVE(CLR_E_FILE_NOT_FOUND); - } - - if(operationResult == FR_OK) - { - // file created (or opened) succesfully - // OK to close it - f_close(&file); - - // now get the details - f_stat(fileName, &fileInfo); - - // compose return object - // find type, don't bother checking the result as it exists for sure - g_CLR_RT_TypeSystem.FindTypeDef( "StorageFile", "Windows.Storage", storageFileTypeDef ); - - // create a - NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(stack.PushValue(), storageFileTypeDef)); - - // get a handle to the storage file - storageFile = stack.TopValue().Dereference(); - - // file name - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( storageFile[ StorageFile::FIELD___name ], fileName )); - - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( storageFile[ StorageFile::FIELD___path ], filePath )); - - // get the date time details and fill in the managed field - // compute directory date - fileInfoTime = GetDateTime(fileInfo.fdate, fileInfo.ftime); - - // get a reference to the dateCreated managed field... - CLR_RT_HeapBlock& dateFieldRef = storageFile[ StorageFile::FIELD___dateCreated ]; - CLR_INT64* pRes = (CLR_INT64*)&dateFieldRef.NumericByRef().s8; - // ...and set it with the fileInfoTime - *pRes = HAL_Time_ConvertFromSystemTime( &fileInfoTime ); - } - else - { - // failed to create the file - NANOCLR_SET_AND_LEAVE(CLR_E_FILE_IO); - } - } - - NANOCLR_CLEANUP(); - - // free buffer memory, if allocated - if(filePath != NULL) - { - platform_free(filePath); - } - - NANOCLR_CLEANUP_END(); -} - -HRESULT StorageFolder::CreateFolderNative___WindowsStorageStorageFolder__STRING__U4( CLR_RT_StackFrame& stack ) -{ - NANOCLR_HEADER(); - - CLR_RT_TypeDef_Index storageFolderTypeDef; - CLR_RT_HeapBlock* storageFolder; - - const char* folderName; - const char* workingPath; - - CreationCollisionOption options; - - static FILINFO fileInfo; - SYSTEMTIME fileInfoTime; - FRESULT operationResult; - char* folderPath = NULL; - - // get a pointer to the managed object instance and check that it's not NULL - CLR_RT_HeapBlock* pThis = stack.This(); FAULT_ON_NULL(pThis); - - // get creation collision options - options = (CreationCollisionOption)stack.Arg2().NumericByRef().u4; - - // get a pointer to the path in managed field - workingPath = pThis[ StorageFolder::FIELD___path ].DereferenceString()->StringText(); - - // get a pointer to the desired folder name - folderName = stack.Arg1().DereferenceString()->StringText(); - - folderPath = (char*)platform_malloc(2 * FF_LFN_BUF + 1); - - // sanity check for successfull malloc - if(folderPath == NULL) - { - // failed to allocate memory - NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_MEMORY); - } - - // clear working buffer - memset(folderPath, 0, 2 * FF_LFN_BUF + 1); - - // compose folder path - strcat(folderPath, workingPath); - strcat(folderPath, folderName); - - // change directory - operationResult = f_chdir(workingPath); - - if(operationResult != FR_OK) - { - if(operationResult == FR_INVALID_DRIVE) - { - // failed to change drive - NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND); - } - - // error opening the directoty - NANOCLR_SET_AND_LEAVE(CLR_E_DIRECTORY_NOT_FOUND); - } - else - { - // handle request for open if it exists and replace existing - if( (options == CreationCollisionOption_OpenIfExists) || - (options == CreationCollisionOption_ReplaceExisting)) - { - operationResult = f_stat(folderPath, &fileInfo); - } - else - { - // create directory - operationResult = f_mkdir(folderPath); - } - - // process operation result according to creation options - if( (operationResult != FR_OK) && - (options == CreationCollisionOption_FailIfExists)) - { - // folder already exists - NANOCLR_SET_AND_LEAVE(CLR_E_PATH_ALREADY_EXISTS); - } - if( (operationResult == FR_NO_FILE) && - (options == CreationCollisionOption_OpenIfExists)) - { - // folder doesn't exist - NANOCLR_SET_AND_LEAVE(CLR_E_DIRECTORY_NOT_FOUND); - } - - if(operationResult == FR_OK) - { - // folder created get the details or... - // ...(if already exists) skip - if(fileInfo.fattrib == 0) - { - f_stat(folderPath, &fileInfo); - } - - // compose return object - // find type, don't bother checking the result as it exists for sure - g_CLR_RT_TypeSystem.FindTypeDef( "StorageFolder", "Windows.Storage", storageFolderTypeDef ); - - // create a - NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(stack.PushValue(), storageFolderTypeDef)); - - // get a handle to the storage folder - storageFolder = stack.TopValue().Dereference(); - - // folder name - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( storageFolder[ StorageFolder::FIELD___name ], folderName )); - - NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( storageFolder[ StorageFolder::FIELD___path ], folderPath )); - - // get the date time details and fill in the managed field - // compute directory date - fileInfoTime = GetDateTime(fileInfo.fdate, fileInfo.ftime); - - // get a reference to the dateCreated managed field... - CLR_RT_HeapBlock& dateFieldRef = storageFolder[ StorageFolder::FIELD___dateCreated ]; - CLR_INT64* pRes = (CLR_INT64*)&dateFieldRef.NumericByRef().s8; - // ...and set it with the fileInfoTime - *pRes = HAL_Time_ConvertFromSystemTime( &fileInfoTime ); - } - else - { - // failed to create the folder - NANOCLR_SET_AND_LEAVE(CLR_E_FILE_IO); - } - } - - NANOCLR_CLEANUP(); - - // free buffer memory, if allocated - if(folderPath != NULL) - { - platform_free(folderPath); - } - - NANOCLR_CLEANUP_END(); -} diff --git a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/ffconf.h b/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/ffconf.h deleted file mode 100644 index 1baf5d8d7b..0000000000 --- a/targets/FreeRTOS/NXP_MIMXRT1060_EVK/nanoCLR/fatfs/ffconf.h +++ /dev/null @@ -1,293 +0,0 @@ -/*---------------------------------------------------------------------------/ -/ FatFs Functional Configurations -/---------------------------------------------------------------------------*/ - -#define FFCONF_DEF 86604 /* Revision ID */ - -#define SD_DISK_ENABLE - -/* Definitions of physical drive number for each drive */ -#define SDDISK 0 /* sd disk to physical drive 0 */ - -/*---------------------------------------------------------------------------/ -/ Function Configurations -/---------------------------------------------------------------------------*/ - -#define FF_FS_READONLY 0 -/* This option switches read-only configuration. (0:Read/Write or 1:Read-only) -/ Read-only configuration removes writing API functions, f_write(), f_sync(), -/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() -/ and optional writing functions as well. */ - - -#define FF_FS_MINIMIZE 0 -/* This option defines minimization level to remove some basic API functions. -/ -/ 0: Basic functions are fully enabled. -/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() -/ are removed. -/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. -/ 3: f_lseek() function is removed in addition to 2. */ - - -#define FF_USE_STRFUNC 1 -/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf(). -/ -/ 0: Disable string functions. -/ 1: Enable without LF-CRLF conversion. -/ 2: Enable with LF-CRLF conversion. */ - - -#define FF_USE_FIND 1 -/* This option switches filtered directory read functions, f_findfirst() and -/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ - - -#define FF_USE_MKFS 0 -/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ - - -#define FF_USE_FASTSEEK 0 -/* This option switches fast seek function. (0:Disable or 1:Enable) */ - - -#define FF_USE_EXPAND 0 -/* This option switches f_expand function. (0:Disable or 1:Enable) */ - - -#define FF_USE_CHMOD 0 -/* This option switches attribute manipulation functions, f_chmod() and f_utime(). -/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ - - -#define FF_USE_LABEL 1 -/* This option switches volume label functions, f_getlabel() and f_setlabel(). -/ (0:Disable or 1:Enable) */ - - -#define FF_USE_FORWARD 0 -/* This option switches f_forward() function. (0:Disable or 1:Enable) */ - - -/*---------------------------------------------------------------------------/ -/ Locale and Namespace Configurations -/---------------------------------------------------------------------------*/ - -#define FF_CODE_PAGE 850 -/* This option specifies the OEM code page to be used on the target system. -/ Incorrect code page setting can cause a file open failure. -/ -/ 437 - U.S. -/ 720 - Arabic -/ 737 - Greek -/ 771 - KBL -/ 775 - Baltic -/ 850 - Latin 1 -/ 852 - Latin 2 -/ 855 - Cyrillic -/ 857 - Turkish -/ 860 - Portuguese -/ 861 - Icelandic -/ 862 - Hebrew -/ 863 - Canadian French -/ 864 - Arabic -/ 865 - Nordic -/ 866 - Russian -/ 869 - Greek 2 -/ 932 - Japanese (DBCS) -/ 936 - Simplified Chinese (DBCS) -/ 949 - Korean (DBCS) -/ 950 - Traditional Chinese (DBCS) -/ 0 - Include all code pages above and configured by f_setcp() -*/ - - -#define FF_USE_LFN 3 -#define FF_MAX_LFN 255 -/* The FF_USE_LFN switches the support for LFN (long file name). -/ -/ 0: Disable LFN. FF_MAX_LFN has no effect. -/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. -/ 2: Enable LFN with dynamic working buffer on the STACK. -/ 3: Enable LFN with dynamic working buffer on the HEAP. -/ -/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function -/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and -/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled. -/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can -/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN -/ specification. -/ When use stack for the working buffer, take care on stack overflow. When use heap -/ memory for the working buffer, memory management functions, ff_memalloc() and -/ ff_memfree() in ffsystem.c, need to be added to the project. */ - - -#define FF_LFN_UNICODE 2 -/* This option switches the character encoding on the API when LFN is enabled. -/ -/ 0: ANSI/OEM in current CP (TCHAR = char) -/ 1: Unicode in UTF-16 (TCHAR = WCHAR) -/ 2: Unicode in UTF-8 (TCHAR = char) -/ 3: Unicode in UTF-32 (TCHAR = DWORD) -/ -/ Also behavior of string I/O functions will be affected by this option. -/ When LFN is not enabled, this option has no effect. */ - - -#define FF_LFN_BUF 255 -#define FF_SFN_BUF 12 -/* This set of options defines size of file name members in the FILINFO structure -/ which is used to read out directory items. These values should be suffcient for -/ the file names to read. The maximum possible length of the read file name depends -/ on character encoding. When LFN is not enabled, these options have no effect. */ - - -#define FF_STRF_ENCODE 3 -/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(), -/ f_putc(), f_puts and f_printf() convert the character encoding in it. -/ This option selects assumption of character encoding ON THE FILE to be -/ read/written via those functions. -/ -/ 0: ANSI/OEM in current CP -/ 1: Unicode in UTF-16LE -/ 2: Unicode in UTF-16BE -/ 3: Unicode in UTF-8 -*/ - - -#define FF_FS_RPATH 2 -/* This option configures support for relative path. -/ -/ 0: Disable relative path and remove related functions. -/ 1: Enable relative path. f_chdir() and f_chdrive() are available. -/ 2: f_getcwd() function is available in addition to 1. -*/ - - -/*---------------------------------------------------------------------------/ -/ Drive/Volume Configurations -/---------------------------------------------------------------------------*/ - -#define FF_VOLUMES 1 -/* Number of volumes (logical drives) to be used. (1-10) */ - - -#define FF_STR_VOLUME_ID 1 -#define FF_VOLUME_STRS "D" -/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. -/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive -/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each -/ logical drives. Number of items must not be less than FF_VOLUMES. Valid -/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are -/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is -/ not defined, a user defined volume string table needs to be defined as: -/ -/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",... -*/ - - -#define FF_MULTI_PARTITION 0 -/* This option switches support for multiple volumes on the physical drive. -/ By default (0), each logical drive number is bound to the same physical drive -/ number and only an FAT volume found on the physical drive will be mounted. -/ When this function is enabled (1), each logical drive number can be bound to -/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() -/ funciton will be available. */ - - -#define FF_MIN_SS 512 -#define FF_MAX_SS 512 -/* This set of options configures the range of sector size to be supported. (512, -/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and -/ harddisk. But a larger value may be required for on-board flash memory and some -/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured -/ for variable sector size mode and disk_ioctl() function needs to implement -/ GET_SECTOR_SIZE command. */ - - -#define FF_USE_TRIM 0 -/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) -/ To enable Trim function, also CTRL_TRIM command should be implemented to the -/ disk_ioctl() function. */ - - -#define FF_FS_NOFSINFO 0 -/* If you need to know correct free space on the FAT32 volume, set bit 0 of this -/ option, and f_getfree() function at first time after volume mount will force -/ a full FAT scan. Bit 1 controls the use of last allocated cluster number. -/ -/ bit0=0: Use free cluster count in the FSINFO if available. -/ bit0=1: Do not trust free cluster count in the FSINFO. -/ bit1=0: Use last allocated cluster number in the FSINFO if available. -/ bit1=1: Do not trust last allocated cluster number in the FSINFO. -*/ - - - -/*---------------------------------------------------------------------------/ -/ System Configurations -/---------------------------------------------------------------------------*/ - -#define FF_FS_TINY 0 -/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) -/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. -/ Instead of private sector buffer eliminated from the file object, common sector -/ buffer in the filesystem object (FATFS) is used for the file data transfer. */ - - -#define FF_FS_EXFAT 0 -/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) -/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) -/ Note that enabling exFAT discards ANSI C (C89) compatibility. */ - - -#define FF_FS_NORTC 1 -#define FF_NORTC_MON 1 -#define FF_NORTC_MDAY 1 -#define FF_NORTC_YEAR 2018 -/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have -/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable -/ the timestamp function. Every object modified by FatFs will have a fixed timestamp -/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time. -/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be -/ added to the project to read current time form real-time clock. FF_NORTC_MON, -/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. -/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */ - - -#define FF_FS_LOCK 0 -/* The option FF_FS_LOCK switches file lock function to control duplicated file open -/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY -/ is 1. -/ -/ 0: Disable file lock function. To avoid volume corruption, application program -/ should avoid illegal open, remove and rename to the open objects. -/ >0: Enable file lock function. The value defines how many files/sub-directories -/ can be opened simultaneously under file lock control. Note that the file -/ lock control is independent of re-entrancy. */ - - -/* #include // O/S definitions */ -#define FF_FS_REENTRANT 0 -#define FF_FS_TIMEOUT 1000 -#define FF_SYNC_t HANDLE -/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs -/ module itself. Note that regardless of this option, file access to different -/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs() -/ and f_fdisk() function, are always not re-entrant. Only file/directory access -/ to the same volume is under control of this function. -/ -/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect. -/ 1: Enable re-entrancy. Also user provided synchronization handlers, -/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() -/ function, must be added to the project. Samples are available in -/ option/syscall.c. -/ -/ The FF_FS_TIMEOUT defines timeout period in unit of time tick. -/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, -/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be -/ included somewhere in the scope of ff.h. */ - - - -/*--- End of configuration options ---*/ diff --git a/targets/FreeRTOS/UAC18/common/CMakeLists.txt b/targets/FreeRTOS/UAC18/common/CMakeLists.txt deleted file mode 100644 index 291b5f09a8..0000000000 --- a/targets/FreeRTOS/UAC18/common/CMakeLists.txt +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright (c) 2019 The nanoFramework project contributors -# See LICENSE file in the project root for full license information. -# - -# append common source files -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/hardfault.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/startup/startup_mimxrt1062.c") - -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/board.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/clock_config.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/fsl_phy.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/peripherals.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/pin_mux.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/board/hyperRAM.c") - -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/component/serial_manager/serial_manager.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/component/serial_manager/serial_port_uart.c") - -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/component/uart/lpuart_adapter.c") - -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_cache.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_clock.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_enet.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_flexspi.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_gpio.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_gpio_ext.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_lpuart.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_semc.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_snvs_lp.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_trng.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/fsl_usdhc.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/sdmmc/src/fsl_sd.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/sdmmc/src/fsl_sdmmc_common.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/sdmmc/port/fsl_sdmmc_host.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/sdmmc/port/fsl_sdmmc_event.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/drivers/freertos/fsl_lpuart_freertos.c") - -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/device/system_MIMXRT1062.c") - -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/utilities/fsl_debug_console.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/utilities/fsl_str.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/utilities/flexspi_nor_flash_ops.c") - -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/xip/fsl_flexspi_nor_boot.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/xip/evkmimxrt1060_flexspi_nor_config.c") - - -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_ReceiverThread.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_HAL_Interface.c") - -# append nanoHAL -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Time.cpp") - -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/platform_heap.c") - -# append Target files -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Device_BlockStorage.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Target_BlockStorage_iMXRTFlashDriver.c") -list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/platform_BlockStorage.c") - -# include configuration manager file, if feature is enabled -if(NF_FEATURE_HAS_CONFIG_BLOCK) - list(APPEND COMMON_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_ConfigurationManager.cpp") -endif() - -# make var global -set(COMMON_PROJECT_SOURCES ${COMMON_PROJECT_SOURCES} CACHE INTERNAL "make global") - diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_usdhc.c b/targets/FreeRTOS/UAC18/common/drivers/fsl_usdhc.c deleted file mode 100644 index 19d5c5e234..0000000000 --- a/targets/FreeRTOS/UAC18/common/drivers/fsl_usdhc.c +++ /dev/null @@ -1,2017 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2016, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2017 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#include "fsl_usdhc.h" -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL -#include "fsl_cache.h" -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.usdhc" -#endif - -/*! @brief Clock setting */ -/* Max SD clock divisor from base clock */ -#define USDHC_MAX_DVS ((USDHC_SYS_CTRL_DVS_MASK >> USDHC_SYS_CTRL_DVS_SHIFT) + 1U) -#define USDHC_MAX_CLKFS ((USDHC_SYS_CTRL_SDCLKFS_MASK >> USDHC_SYS_CTRL_SDCLKFS_SHIFT) + 1U) -#define USDHC_PREV_DVS(x) ((x) -= 1U) -#define USDHC_PREV_CLKFS(x, y) ((x) >>= (y)) - -/* Typedef for interrupt handler. */ -typedef void (*usdhc_isr_t)(USDHC_Type *base, usdhc_handle_t *handle); -/*! @brief Dummy data buffer for mmc boot mode */ -AT_NONCACHEABLE_SECTION_ALIGN(uint32_t s_usdhcBootDummy, USDHC_ADMA2_ADDRESS_ALIGN); -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get the instance. - * - * @param base USDHC peripheral base address. - * @return Instance number. - */ -static uint32_t USDHC_GetInstance(USDHC_Type *base); - -/*! - * @brief Set transfer interrupt. - * - * @param base USDHC peripheral base address. - * @param usingInterruptSignal True to use IRQ signal. - */ -static void USDHC_SetTransferInterrupt(USDHC_Type *base, bool usingInterruptSignal); - -/*! - * @brief Start transfer according to current transfer state - * - * @param base USDHC peripheral base address. - * @param data Data to be transferred. - * @param flag data present flag - * @param enDMA DMA enable flag - */ -static status_t USDHC_SetDataTransferConfig(USDHC_Type *base, - usdhc_data_t *data, - uint32_t *dataPresentFlag, - bool enDMA); - -/*! - * @brief Receive command response - * - * @param base USDHC peripheral base address. - * @param command Command to be sent. - */ -static status_t USDHC_ReceiveCommandResponse(USDHC_Type *base, usdhc_command_t *command); - -/*! - * @brief Read DATAPORT when buffer enable bit is set. - * - * @param base USDHC peripheral base address. - * @param data Data to be read. - * @param transferredWords The number of data words have been transferred last time transaction. - * @return The number of total data words have been transferred after this time transaction. - */ -static uint32_t USDHC_ReadDataPort(USDHC_Type *base, usdhc_data_t *data, uint32_t transferredWords); - -/*! - * @brief Read data by using DATAPORT polling way. - * - * @param base USDHC peripheral base address. - * @param data Data to be read. - * @retval kStatus_Fail Read DATAPORT failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t USDHC_ReadByDataPortBlocking(USDHC_Type *base, usdhc_data_t *data); - -/*! - * @brief Write DATAPORT when buffer enable bit is set. - * - * @param base USDHC peripheral base address. - * @param data Data to be read. - * @param transferredWords The number of data words have been transferred last time. - * @return The number of total data words have been transferred after this time transaction. - */ -static uint32_t USDHC_WriteDataPort(USDHC_Type *base, usdhc_data_t *data, uint32_t transferredWords); - -/*! - * @brief Write data by using DATAPORT polling way. - * - * @param base USDHC peripheral base address. - * @param data Data to be transferred. - * @retval kStatus_Fail Write DATAPORT failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t USDHC_WriteByDataPortBlocking(USDHC_Type *base, usdhc_data_t *data); - -/*! - * @brief Transfer data by polling way. - * - * @param base USDHC peripheral base address. - * @param data Data to be transferred. - * @param use DMA flag. - * @retval kStatus_Fail Transfer data failed. - * @retval kStatus_InvalidArgument Argument is invalid. - * @retval kStatus_Success Operate successfully. - */ -static status_t USDHC_TransferDataBlocking(USDHC_Type *base, usdhc_data_t *data, bool enDMA); - -/*! - * @brief Handle card detect interrupt. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - * @param interruptFlags Card detect related interrupt flags. - */ -static void USDHC_TransferHandleCardDetect(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags); - -/*! - * @brief Handle command interrupt. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - * @param interruptFlags Command related interrupt flags. - */ -static void USDHC_TransferHandleCommand(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags); - -/*! - * @brief Handle data interrupt. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - * @param interruptFlags Data related interrupt flags. - */ -static void USDHC_TransferHandleData(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags); - -/*! - * @brief Handle SDIO card interrupt signal. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - */ -static void USDHC_TransferHandleSdioInterrupt(USDHC_Type *base, usdhc_handle_t *handle); - -/*! - * @brief Handle SDIO block gap event. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - */ -static void USDHC_TransferHandleBlockGap(USDHC_Type *base, usdhc_handle_t *handle); - -/*! -* @brief Handle retuning -* -* @param base USDHC peripheral base address. -* @param handle USDHC handle. -* @param interrupt flags -*/ -static void USDHC_TransferHandleReTuning(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags); - -/*! -* @brief wait command done -* -* @param base USDHC peripheral base address. -* @param command configuration -* @param pollingCmdDone polling command done flag -*/ -static status_t USDHC_WaitCommandDone(USDHC_Type *base, usdhc_command_t *command, bool pollingCmdDone); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief USDHC base pointer array */ -static USDHC_Type *const s_usdhcBase[] = USDHC_BASE_PTRS; - -/*! @brief USDHC internal handle pointer array */ -static usdhc_handle_t *s_usdhcHandle[ARRAY_SIZE(s_usdhcBase)] = {NULL}; - -/*! @brief USDHC IRQ name array */ -static const IRQn_Type s_usdhcIRQ[] = USDHC_IRQS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief USDHC clock array name */ -static const clock_ip_name_t s_usdhcClock[] = USDHC_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/* USDHC ISR for transactional APIs. */ -static usdhc_isr_t s_usdhcIsr; - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t USDHC_GetInstance(USDHC_Type *base) -{ - uint8_t instance = 0; - - while ((instance < ARRAY_SIZE(s_usdhcBase)) && (s_usdhcBase[instance] != base)) - { - instance++; - } - - assert(instance < ARRAY_SIZE(s_usdhcBase)); - - return instance; -} - -static void USDHC_SetTransferInterrupt(USDHC_Type *base, bool usingInterruptSignal) -{ - uint32_t interruptEnabled; /* The Interrupt status flags to be enabled */ - - /* Disable all interrupts */ - USDHC_DisableInterruptStatus(base, (uint32_t)kUSDHC_AllInterruptFlags); - USDHC_DisableInterruptSignal(base, (uint32_t)kUSDHC_AllInterruptFlags); - DisableIRQ(s_usdhcIRQ[USDHC_GetInstance(base)]); - - interruptEnabled = (kUSDHC_CommandFlag | kUSDHC_CardInsertionFlag | kUSDHC_DataFlag | kUSDHC_CardRemovalFlag | - kUSDHC_SDR104TuningFlag | kUSDHC_BlockGapEventFlag); - - USDHC_EnableInterruptStatus(base, interruptEnabled); - - if (usingInterruptSignal) - { - USDHC_EnableInterruptSignal(base, interruptEnabled); - } -} - -static status_t USDHC_SetDataTransferConfig(USDHC_Type *base, usdhc_data_t *data, uint32_t *dataPresentFlag, bool enDMA) -{ - uint32_t mixCtrl = base->MIX_CTRL; - - if (data != NULL) - { - /* if transfer boot continous, only need set the CREQ bit, leave others as it is */ - if (data->dataType == kUSDHC_TransferDataBootcontinous) - { - /* clear stop at block gap request */ - base->PROT_CTRL &= ~USDHC_PROT_CTRL_SABGREQ_MASK; - /* continous transfer data */ - base->PROT_CTRL |= USDHC_PROT_CTRL_CREQ_MASK; - return kStatus_Success; - } - - /* check data inhibit flag */ - if (base->PRES_STATE & kUSDHC_DataInhibitFlag) - { - return kStatus_USDHC_BusyTransferring; - } - /* check transfer block count */ - if ((data->blockCount > USDHC_MAX_BLOCK_COUNT) || ((data->txData == NULL) && (data->rxData == NULL))) - { - return kStatus_InvalidArgument; - } - - /* config mix parameter */ - mixCtrl &= ~(USDHC_MIX_CTRL_MSBSEL_MASK | USDHC_MIX_CTRL_BCEN_MASK | USDHC_MIX_CTRL_DTDSEL_MASK | - USDHC_MIX_CTRL_AC12EN_MASK); - - if (data->rxData) - { - mixCtrl |= USDHC_MIX_CTRL_DTDSEL_MASK; - } - if (data->blockCount > 1U) - { - mixCtrl |= USDHC_MIX_CTRL_MSBSEL_MASK | USDHC_MIX_CTRL_BCEN_MASK; - /* auto command 12 */ - if (data->enableAutoCommand12) - { - mixCtrl |= USDHC_MIX_CTRL_AC12EN_MASK; - } - } - - /* auto command 23, auto send set block count cmd before multiple read/write */ - if ((data->enableAutoCommand23)) - { - mixCtrl |= USDHC_MIX_CTRL_AC23EN_MASK; - base->VEND_SPEC2 |= USDHC_VEND_SPEC2_ACMD23_ARGU2_EN_MASK; - /* config the block count to DS_ADDR */ - base->DS_ADDR = data->blockCount; - } - else - { - mixCtrl &= ~USDHC_MIX_CTRL_AC23EN_MASK; - base->VEND_SPEC2 &= ~USDHC_VEND_SPEC2_ACMD23_ARGU2_EN_MASK; - } - - /* if transfer boot data, leave the block count to USDHC_SetMmcBootConfig function */ - if (data->dataType != kUSDHC_TransferDataBoot) - { - /* config data block size/block count */ - base->BLK_ATT = ((base->BLK_ATT & ~(USDHC_BLK_ATT_BLKSIZE_MASK | USDHC_BLK_ATT_BLKCNT_MASK)) | - (USDHC_BLK_ATT_BLKSIZE(data->blockSize) | USDHC_BLK_ATT_BLKCNT(data->blockCount))); - } - else - { - mixCtrl |= USDHC_MIX_CTRL_MSBSEL_MASK | USDHC_MIX_CTRL_BCEN_MASK; - base->PROT_CTRL |= USDHC_PROT_CTRL_RD_DONE_NO_8CLK_MASK; - } - - /* data present flag */ - *dataPresentFlag |= kUSDHC_DataPresentFlag; - /* Disable useless interrupt */ - if (enDMA) - { - base->INT_SIGNAL_EN &= ~(kUSDHC_BufferWriteReadyFlag | kUSDHC_BufferReadReadyFlag | kUSDHC_DmaCompleteFlag); - base->INT_STATUS_EN &= ~(kUSDHC_BufferWriteReadyFlag | kUSDHC_BufferReadReadyFlag | kUSDHC_DmaCompleteFlag); - } - else - { - base->INT_SIGNAL_EN |= kUSDHC_BufferWriteReadyFlag | kUSDHC_BufferReadReadyFlag; - base->INT_STATUS_EN |= kUSDHC_BufferWriteReadyFlag | kUSDHC_BufferReadReadyFlag; - } - } - else - { - /* clear data flags */ - mixCtrl &= ~(USDHC_MIX_CTRL_MSBSEL_MASK | USDHC_MIX_CTRL_BCEN_MASK | USDHC_MIX_CTRL_DTDSEL_MASK | - USDHC_MIX_CTRL_AC12EN_MASK | USDHC_MIX_CTRL_AC23EN_MASK); - - if (base->PRES_STATE & kUSDHC_CommandInhibitFlag) - { - return kStatus_USDHC_BusyTransferring; - } - } - - /* config the mix parameter */ - base->MIX_CTRL = mixCtrl; - - return kStatus_Success; -} - -static status_t USDHC_ReceiveCommandResponse(USDHC_Type *base, usdhc_command_t *command) -{ - uint32_t i; - - if (command->responseType != kCARD_ResponseTypeNone) - { - command->response[0U] = base->CMD_RSP0; - if (command->responseType == kCARD_ResponseTypeR2) - { - command->response[1U] = base->CMD_RSP1; - command->response[2U] = base->CMD_RSP2; - command->response[3U] = base->CMD_RSP3; - - i = 4U; - /* R3-R2-R1-R0(lowest 8 bit is invalid bit) has the same format as R2 format in SD specification document - after removed internal CRC7 and end bit. */ - do - { - command->response[i - 1U] <<= 8U; - if (i > 1U) - { - command->response[i - 1U] |= ((command->response[i - 2U] & 0xFF000000U) >> 24U); - } - } while (i--); - } - } - /* check response error flag */ - if ((command->responseErrorFlags != 0U) && - ((command->responseType == kCARD_ResponseTypeR1) || (command->responseType == kCARD_ResponseTypeR1b) || - (command->responseType == kCARD_ResponseTypeR6) || (command->responseType == kCARD_ResponseTypeR5))) - { - if (((command->responseErrorFlags) & (command->response[0U])) != 0U) - { - return kStatus_USDHC_SendCommandFailed; - } - } - - return kStatus_Success; -} - -static uint32_t USDHC_ReadDataPort(USDHC_Type *base, usdhc_data_t *data, uint32_t transferredWords) -{ - uint32_t i; - uint32_t totalWords; - uint32_t wordsCanBeRead; /* The words can be read at this time. */ - uint32_t readWatermark = ((base->WTMK_LVL & USDHC_WTMK_LVL_RD_WML_MASK) >> USDHC_WTMK_LVL_RD_WML_SHIFT); - - /* If DMA is enable, do not need to polling data port */ - if ((base->MIX_CTRL & USDHC_MIX_CTRL_DMAEN_MASK) == 0U) - { - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (data->blockSize % sizeof(uint32_t) != 0U) - { - data->blockSize += - sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ - } - - totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); - - /* If watermark level is equal or bigger than totalWords, transfers totalWords data. */ - if (readWatermark >= totalWords) - { - wordsCanBeRead = totalWords; - } - /* If watermark level is less than totalWords and left words to be sent is equal or bigger than readWatermark, - transfers watermark level words. */ - else if ((readWatermark < totalWords) && ((totalWords - transferredWords) >= readWatermark)) - { - wordsCanBeRead = readWatermark; - } - /* If watermark level is less than totalWords and left words to be sent is less than readWatermark, transfers - left - words. */ - else - { - wordsCanBeRead = (totalWords - transferredWords); - } - - i = 0U; - while (i < wordsCanBeRead) - { - data->rxData[transferredWords++] = USDHC_ReadData(base); - i++; - } - } - - return transferredWords; -} - -static status_t USDHC_ReadByDataPortBlocking(USDHC_Type *base, usdhc_data_t *data) -{ - uint32_t totalWords; - uint32_t transferredWords = 0U, interruptStatus = 0U; - status_t error = kStatus_Success; - - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (data->blockSize % sizeof(uint32_t) != 0U) - { - data->blockSize += - sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ - } - - totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); - - while ((error == kStatus_Success) && (transferredWords < totalWords)) - { - while (!(interruptStatus & (kUSDHC_BufferReadReadyFlag | kUSDHC_DataErrorFlag | kUSDHC_TuningErrorFlag))) - { - interruptStatus = USDHC_GetInterruptStatusFlags(base); - } - - /* during std tuning process, software do not need to read data, but wait BRR is enough */ - if ((data->dataType == kUSDHC_TransferDataTuning) && (interruptStatus & kUSDHC_BufferReadReadyFlag)) - { - USDHC_ClearInterruptStatusFlags(base, kUSDHC_BufferReadReadyFlag | kUSDHC_TuningPassFlag); - - return kStatus_Success; - } - else if ((interruptStatus & kUSDHC_TuningErrorFlag) != 0U) - { - USDHC_ClearInterruptStatusFlags(base, kUSDHC_TuningErrorFlag); - /* if tuning error occur ,return directly */ - error = kStatus_USDHC_TuningError; - } - else if ((interruptStatus & kUSDHC_DataErrorFlag) != 0U) - { - if (!(data->enableIgnoreError)) - { - error = kStatus_Fail; - } - /* clear data error flag */ - USDHC_ClearInterruptStatusFlags(base, kUSDHC_DataErrorFlag); - } - else - { - } - - if (error == kStatus_Success) - { - transferredWords = USDHC_ReadDataPort(base, data, transferredWords); - /* clear buffer read ready */ - USDHC_ClearInterruptStatusFlags(base, kUSDHC_BufferReadReadyFlag); - interruptStatus = 0U; - } - } - - /* Clear data complete flag after the last read operation. */ - USDHC_ClearInterruptStatusFlags(base, kUSDHC_DataCompleteFlag); - - return error; -} - -static uint32_t USDHC_WriteDataPort(USDHC_Type *base, usdhc_data_t *data, uint32_t transferredWords) -{ - uint32_t i; - uint32_t totalWords; - uint32_t wordsCanBeWrote; /* Words can be wrote at this time. */ - uint32_t writeWatermark = ((base->WTMK_LVL & USDHC_WTMK_LVL_WR_WML_MASK) >> USDHC_WTMK_LVL_WR_WML_SHIFT); - - /* If DMA is enable, do not need to polling data port */ - if ((base->MIX_CTRL & USDHC_MIX_CTRL_DMAEN_MASK) == 0U) - { - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (data->blockSize % sizeof(uint32_t) != 0U) - { - data->blockSize += - sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ - } - - totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); - - /* If watermark level is equal or bigger than totalWords, transfers totalWords data.*/ - if (writeWatermark >= totalWords) - { - wordsCanBeWrote = totalWords; - } - /* If watermark level is less than totalWords and left words to be sent is equal or bigger than watermark, - transfers watermark level words. */ - else if ((writeWatermark < totalWords) && ((totalWords - transferredWords) >= writeWatermark)) - { - wordsCanBeWrote = writeWatermark; - } - /* If watermark level is less than totalWords and left words to be sent is less than watermark, transfers left - words. */ - else - { - wordsCanBeWrote = (totalWords - transferredWords); - } - - i = 0U; - while (i < wordsCanBeWrote) - { - USDHC_WriteData(base, data->txData[transferredWords++]); - i++; - } - } - - return transferredWords; -} - -static status_t USDHC_WriteByDataPortBlocking(USDHC_Type *base, usdhc_data_t *data) -{ - uint32_t totalWords; - - uint32_t transferredWords = 0U, interruptStatus = 0U; - status_t error = kStatus_Success; - - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (data->blockSize % sizeof(uint32_t) != 0U) - { - data->blockSize += - sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ - } - - totalWords = (data->blockCount * data->blockSize) / sizeof(uint32_t); - - while ((error == kStatus_Success) && (transferredWords < totalWords)) - { - while (!(interruptStatus & (kUSDHC_BufferWriteReadyFlag | kUSDHC_DataErrorFlag | kUSDHC_TuningErrorFlag))) - { - interruptStatus = USDHC_GetInterruptStatusFlags(base); - } - - if ((interruptStatus & kUSDHC_TuningErrorFlag) != 0U) - { - USDHC_ClearInterruptStatusFlags(base, kUSDHC_TuningErrorFlag); - /* if tuning error occur ,return directly */ - return kStatus_USDHC_TuningError; - } - else if ((interruptStatus & kUSDHC_DataErrorFlag) != 0U) - { - if (!(data->enableIgnoreError)) - { - error = kStatus_Fail; - } - /* clear data error flag */ - USDHC_ClearInterruptStatusFlags(base, kUSDHC_DataErrorFlag); - } - else - { - } - - if (error == kStatus_Success) - { - transferredWords = USDHC_WriteDataPort(base, data, transferredWords); - /* clear buffer write ready */ - USDHC_ClearInterruptStatusFlags(base, kUSDHC_BufferWriteReadyFlag); - interruptStatus = 0U; - } - } - - /* Wait write data complete or data transfer error after the last writing operation. */ - while (!(interruptStatus & (kUSDHC_DataCompleteFlag | kUSDHC_DataErrorFlag))) - { - interruptStatus = USDHC_GetInterruptStatusFlags(base); - } - - if ((interruptStatus & kUSDHC_DataErrorFlag) != 0U) - { - if (!(data->enableIgnoreError)) - { - error = kStatus_Fail; - } - } - USDHC_ClearInterruptStatusFlags(base, (kUSDHC_DataCompleteFlag | kUSDHC_DataErrorFlag)); - - return error; -} - -/*! -* brief send command function -* -* param base USDHC peripheral base address. -* param command configuration -*/ -void USDHC_SendCommand(USDHC_Type *base, usdhc_command_t *command) -{ - assert(NULL != command); - - uint32_t xferType = base->CMD_XFR_TYP, flags = command->flags; - - if (((base->PRES_STATE & kUSDHC_CommandInhibitFlag) == 0U) && (command->type != kCARD_CommandTypeEmpty)) - { - /* Define the flag corresponding to each response type. */ - switch (command->responseType) - { - case kCARD_ResponseTypeNone: - break; - case kCARD_ResponseTypeR1: /* Response 1 */ - case kCARD_ResponseTypeR5: /* Response 5 */ - case kCARD_ResponseTypeR6: /* Response 6 */ - case kCARD_ResponseTypeR7: /* Response 7 */ - flags |= (kUSDHC_ResponseLength48Flag | kUSDHC_EnableCrcCheckFlag | kUSDHC_EnableIndexCheckFlag); - break; - - case kCARD_ResponseTypeR1b: /* Response 1 with busy */ - case kCARD_ResponseTypeR5b: /* Response 5 with busy */ - flags |= (kUSDHC_ResponseLength48BusyFlag | kUSDHC_EnableCrcCheckFlag | kUSDHC_EnableIndexCheckFlag); - break; - - case kCARD_ResponseTypeR2: /* Response 2 */ - flags |= (kUSDHC_ResponseLength136Flag | kUSDHC_EnableCrcCheckFlag); - break; - - case kCARD_ResponseTypeR3: /* Response 3 */ - case kCARD_ResponseTypeR4: /* Response 4 */ - flags |= (kUSDHC_ResponseLength48Flag); - break; - - default: - break; - } - - if (command->type == kCARD_CommandTypeAbort) - { - flags |= kUSDHC_CommandTypeAbortFlag; - } - - /* config cmd index */ - xferType &= ~(USDHC_CMD_XFR_TYP_CMDINX_MASK | USDHC_CMD_XFR_TYP_CMDTYP_MASK | USDHC_CMD_XFR_TYP_CICEN_MASK | - USDHC_CMD_XFR_TYP_CCCEN_MASK | USDHC_CMD_XFR_TYP_RSPTYP_MASK | USDHC_CMD_XFR_TYP_DPSEL_MASK); - - xferType |= - (((command->index << USDHC_CMD_XFR_TYP_CMDINX_SHIFT) & USDHC_CMD_XFR_TYP_CMDINX_MASK) | - ((flags) & (USDHC_CMD_XFR_TYP_CMDTYP_MASK | USDHC_CMD_XFR_TYP_CICEN_MASK | USDHC_CMD_XFR_TYP_CCCEN_MASK | - USDHC_CMD_XFR_TYP_RSPTYP_MASK | USDHC_CMD_XFR_TYP_DPSEL_MASK))); - - /* config the command xfertype and argument */ - base->CMD_ARG = command->argument; - base->CMD_XFR_TYP = xferType; - } - - if (command->type == kCARD_CommandTypeEmpty) - { - /* disable CMD done interrupt for empty command */ - base->INT_SIGNAL_EN &= ~USDHC_INT_SIGNAL_EN_CCIEN_MASK; - } -} - -static status_t USDHC_WaitCommandDone(USDHC_Type *base, usdhc_command_t *command, bool pollingCmdDone) -{ - assert(NULL != command); - - status_t error = kStatus_Success; - uint32_t interruptStatus = 0U; - /* check if need polling command done or not */ - if (pollingCmdDone) - { - /* Wait command complete or USDHC encounters error. */ - while (!(interruptStatus & (kUSDHC_CommandCompleteFlag | kUSDHC_CommandErrorFlag))) - { - interruptStatus = USDHC_GetInterruptStatusFlags(base); - } - - if ((interruptStatus & kUSDHC_TuningErrorFlag) != 0U) - { - error = kStatus_USDHC_TuningError; - } - else if ((interruptStatus & kUSDHC_CommandErrorFlag) != 0U) - { - error = kStatus_Fail; - } - else - { - } - /* Receive response when command completes successfully. */ - if (error == kStatus_Success) - { - error = USDHC_ReceiveCommandResponse(base, command); - } - - USDHC_ClearInterruptStatusFlags( - base, (kUSDHC_CommandCompleteFlag | kUSDHC_CommandErrorFlag | kUSDHC_TuningErrorFlag)); - } - - return error; -} - -static status_t USDHC_TransferDataBlocking(USDHC_Type *base, usdhc_data_t *data, bool enDMA) -{ - status_t error = kStatus_Success; - uint32_t interruptStatus = 0U; - - if (enDMA) - { - /* Wait data complete or USDHC encounters error. */ - while (!((interruptStatus & - (kUSDHC_DataCompleteFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag | kUSDHC_TuningErrorFlag)))) - { - interruptStatus = USDHC_GetInterruptStatusFlags(base); - } - - if ((interruptStatus & kUSDHC_TuningErrorFlag) != 0U) - { - error = kStatus_USDHC_TuningError; - } - else if (((interruptStatus & (kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag)) != 0U)) - { - if ((!(data->enableIgnoreError)) || (interruptStatus & kUSDHC_DataTimeoutFlag)) - { - error = kStatus_Fail; - } - } - else - { - } - /* load dummy data */ - if ((data->dataType == kUSDHC_TransferDataBootcontinous) && (error == kStatus_Success)) - { - *(data->rxData) = s_usdhcBootDummy; - } - - USDHC_ClearInterruptStatusFlags(base, (kUSDHC_DataCompleteFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag | - kUSDHC_TuningPassFlag | kUSDHC_TuningErrorFlag)); - } - else - { - if (data->rxData) - { - error = USDHC_ReadByDataPortBlocking(base, data); - } - else - { - error = USDHC_WriteByDataPortBlocking(base, data); - } - } - - return error; -} - -/*! - * brief USDHC module initialization function. - * - * Configures the USDHC according to the user configuration. - * - * Example: - code - usdhc_config_t config; - config.cardDetectDat3 = false; - config.endianMode = kUSDHC_EndianModeLittle; - config.dmaMode = kUSDHC_DmaModeAdma2; - config.readWatermarkLevel = 128U; - config.writeWatermarkLevel = 128U; - USDHC_Init(USDHC, &config); - endcode - * - * param base USDHC peripheral base address. - * param config USDHC configuration information. - * retval kStatus_Success Operate successfully. - */ -void USDHC_Init(USDHC_Type *base, const usdhc_config_t *config) -{ - assert(config); - assert((config->writeWatermarkLevel >= 1U) && (config->writeWatermarkLevel <= 128U)); - assert((config->readWatermarkLevel >= 1U) && (config->readWatermarkLevel <= 128U)); - assert(config->writeBurstLen <= 16U); - - uint32_t proctl, sysctl, wml; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable USDHC clock. */ - CLOCK_EnableClock(s_usdhcClock[USDHC_GetInstance(base)]); -#endif - - /* Reset USDHC. */ - USDHC_Reset(base, kUSDHC_ResetAll, 100U); - - proctl = base->PROT_CTRL; - wml = base->WTMK_LVL; - sysctl = base->SYS_CTRL; - - proctl &= ~(USDHC_PROT_CTRL_EMODE_MASK | USDHC_PROT_CTRL_DMASEL_MASK); - /* Endian mode*/ - proctl |= USDHC_PROT_CTRL_EMODE(config->endianMode); - - /* Watermark level */ - wml &= ~(USDHC_WTMK_LVL_RD_WML_MASK | USDHC_WTMK_LVL_WR_WML_MASK | USDHC_WTMK_LVL_RD_BRST_LEN_MASK | - USDHC_WTMK_LVL_WR_BRST_LEN_MASK); - wml |= (USDHC_WTMK_LVL_RD_WML(config->readWatermarkLevel) | USDHC_WTMK_LVL_WR_WML(config->writeWatermarkLevel) | - USDHC_WTMK_LVL_RD_BRST_LEN(config->readBurstLen) | USDHC_WTMK_LVL_WR_BRST_LEN(config->writeBurstLen)); - - /* config the data timeout value */ - sysctl &= ~USDHC_SYS_CTRL_DTOCV_MASK; - sysctl |= USDHC_SYS_CTRL_DTOCV(config->dataTimeout); - - base->SYS_CTRL = sysctl; - base->WTMK_LVL = wml; - base->PROT_CTRL = proctl; - -#if FSL_FEATURE_USDHC_HAS_EXT_DMA - /* disable external DMA */ - base->VEND_SPEC &= ~USDHC_VEND_SPEC_EXT_DMA_EN_MASK; -#endif - /* disable internal DMA and DDR mode */ - base->MIX_CTRL &= ~(USDHC_MIX_CTRL_DMAEN_MASK | USDHC_MIX_CTRL_DDR_EN_MASK); - /* Enable interrupt status but doesn't enable interrupt signal. */ - USDHC_SetTransferInterrupt(base, false); -} - -/*! - * brief Deinitializes the USDHC. - * - * param base USDHC peripheral base address. - */ -void USDHC_Deinit(USDHC_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable clock. */ - CLOCK_DisableClock(s_usdhcClock[USDHC_GetInstance(base)]); -#endif -} - -/*! - * brief Resets the USDHC. - * - * param base USDHC peripheral base address. - * param mask The reset type mask(_usdhc_reset). - * param timeout Timeout for reset. - * retval true Reset successfully. - * retval false Reset failed. - */ -bool USDHC_Reset(USDHC_Type *base, uint32_t mask, uint32_t timeout) -{ - base->SYS_CTRL |= (mask & (USDHC_SYS_CTRL_RSTA_MASK | USDHC_SYS_CTRL_RSTC_MASK | USDHC_SYS_CTRL_RSTD_MASK)); - /* Delay some time to wait reset success. */ - while ((base->SYS_CTRL & mask) != 0U) - { - if (timeout == 0U) - { - break; - } - timeout--; - } - - return ((!timeout) ? false : true); -} - -/*! - * brief Gets the capability information. - * - * param base USDHC peripheral base address. - * param capability Structure to save capability information. - */ -void USDHC_GetCapability(USDHC_Type *base, usdhc_capability_t *capability) -{ - assert(capability); - - uint32_t htCapability; - uint32_t maxBlockLength; - - htCapability = base->HOST_CTRL_CAP; - - /* Get the capability of USDHC. */ - maxBlockLength = ((htCapability & USDHC_HOST_CTRL_CAP_MBL_MASK) >> USDHC_HOST_CTRL_CAP_MBL_SHIFT); - capability->maxBlockLength = (512U << maxBlockLength); - /* Other attributes not in HTCAPBLT register. */ - capability->maxBlockCount = USDHC_MAX_BLOCK_COUNT; - capability->flags = (htCapability & (kUSDHC_SupportAdmaFlag | kUSDHC_SupportHighSpeedFlag | kUSDHC_SupportDmaFlag | - kUSDHC_SupportSuspendResumeFlag | kUSDHC_SupportV330Flag)); - capability->flags |= (htCapability & kUSDHC_SupportV300Flag); - capability->flags |= (htCapability & kUSDHC_SupportV180Flag); - capability->flags |= - (htCapability & (kUSDHC_SupportDDR50Flag | kUSDHC_SupportSDR104Flag | kUSDHC_SupportSDR50Flag)); - /* USDHC support 4/8 bit data bus width. */ - capability->flags |= (kUSDHC_Support4BitFlag | kUSDHC_Support8BitFlag); -} - -/*! - * brief Sets the SD bus clock frequency. - * - * param base USDHC peripheral base address. - * param srcClock_Hz USDHC source clock frequency united in Hz. - * param busClock_Hz SD bus clock frequency united in Hz. - * - * return The nearest frequency of busClock_Hz configured to SD bus. - */ -uint32_t USDHC_SetSdClock(USDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz) -{ - assert(srcClock_Hz != 0U); - assert((busClock_Hz != 0U) && (busClock_Hz <= srcClock_Hz)); - - uint32_t totalDiv = 0U; - uint32_t divisor = 0U; - uint32_t prescaler = 0U; - uint32_t sysctl = 0U; - uint32_t nearestFrequency = 0U; - - /* calucate total divisor first */ - if ((totalDiv = srcClock_Hz / busClock_Hz) > (USDHC_MAX_CLKFS * USDHC_MAX_DVS)) - { - return 0U; - } - - if (totalDiv != 0U) - { - /* calucate the divisor (srcClock_Hz / divisor) <= busClock_Hz */ - if ((srcClock_Hz / totalDiv) > busClock_Hz) - { - totalDiv++; - } - - /* divide the total divisor to div and prescaler */ - if (totalDiv > USDHC_MAX_DVS) - { - prescaler = totalDiv / USDHC_MAX_DVS; - /* prescaler must be a value which equal 2^n and smaller than SDHC_MAX_CLKFS */ - while (((USDHC_MAX_CLKFS % prescaler) != 0U) || (prescaler == 1U)) - { - prescaler++; - } - /* calucate the divisor */ - divisor = totalDiv / prescaler; - /* fine tuning the divisor until divisor * prescaler >= totalDiv */ - while ((divisor * prescaler) < totalDiv) - { - divisor++; - if (divisor > USDHC_MAX_DVS) - { - if ((prescaler <<= 1U) > USDHC_MAX_CLKFS) - { - return 0; - } - divisor = totalDiv / prescaler; - } - } - } - else - { - /* in this situation , divsior and SDCLKFS can generate same clock - use SDCLKFS*/ - if (((totalDiv % 2U) != 0U) & (totalDiv != 1U)) - { - divisor = totalDiv; - prescaler = 1U; - } - else - { - divisor = 1U; - prescaler = totalDiv; - } - } - nearestFrequency = srcClock_Hz / (divisor == 0U ? 1U : divisor) / prescaler; - } - /* in this condition , srcClock_Hz = busClock_Hz, */ - else - { - /* in DDR mode , set SDCLKFS to 0, divisor = 0, actually the - totoal divider = 2U */ - divisor = 0U; - prescaler = 0U; - nearestFrequency = srcClock_Hz; - } - - /* calucate the value write to register */ - if (divisor != 0U) - { - USDHC_PREV_DVS(divisor); - } - /* calucate the value write to register */ - if (prescaler != 0U) - { - USDHC_PREV_CLKFS(prescaler, 1U); - } - - /* Set the SD clock frequency divisor, SD clock frequency select, data timeout counter value. */ - sysctl = base->SYS_CTRL; - sysctl &= ~(USDHC_SYS_CTRL_DVS_MASK | USDHC_SYS_CTRL_SDCLKFS_MASK); - sysctl |= (USDHC_SYS_CTRL_DVS(divisor) | USDHC_SYS_CTRL_SDCLKFS(prescaler)); - base->SYS_CTRL = sysctl; - - /* Wait until the SD clock is stable. */ - while (!(base->PRES_STATE & USDHC_PRES_STATE_SDSTB_MASK)) - { - } - - return nearestFrequency; -} - -/*! - * brief Sends 80 clocks to the card to set it to the active state. - * - * This function must be called each time the card is inserted to ensure that the card can receive the command - * correctly. - * - * param base USDHC peripheral base address. - * param timeout Timeout to initialize card. - * retval true Set card active successfully. - * retval false Set card active failed. - */ -bool USDHC_SetCardActive(USDHC_Type *base, uint32_t timeout) -{ - base->SYS_CTRL |= USDHC_SYS_CTRL_INITA_MASK; - /* Delay some time to wait card become active state. */ - while ((base->SYS_CTRL & USDHC_SYS_CTRL_INITA_MASK) == USDHC_SYS_CTRL_INITA_MASK) - { - if (!timeout) - { - break; - } - timeout--; - } - - return ((!timeout) ? false : true); -} - -/*! - * brief the enable/disable DDR mode - * - * param base USDHC peripheral base address. - * param enable/disable flag - * param nibble position - */ -void USDHC_EnableDDRMode(USDHC_Type *base, bool enable, uint32_t nibblePos) -{ - uint32_t prescaler = (base->SYS_CTRL & USDHC_SYS_CTRL_SDCLKFS_MASK) >> USDHC_SYS_CTRL_SDCLKFS_SHIFT; - - if (enable) - { - base->MIX_CTRL &= ~USDHC_MIX_CTRL_NIBBLE_POS_MASK; - base->MIX_CTRL |= (USDHC_MIX_CTRL_DDR_EN_MASK | USDHC_MIX_CTRL_NIBBLE_POS(nibblePos)); - prescaler >>= 1U; - } - else - { - base->MIX_CTRL &= ~USDHC_MIX_CTRL_DDR_EN_MASK; - - if (prescaler == 0U) - { - prescaler += 1U; - } - else - { - prescaler <<= 1U; - } - } - - base->SYS_CTRL = (base->SYS_CTRL & (~USDHC_SYS_CTRL_SDCLKFS_MASK)) | USDHC_SYS_CTRL_SDCLKFS(prescaler); -} - -/*! - * brief Configures the MMC boot feature. - * - * Example: - code - usdhc_boot_config_t config; - config.ackTimeoutCount = 4; - config.bootMode = kUSDHC_BootModeNormal; - config.blockCount = 5; - config.enableBootAck = true; - config.enableBoot = true; - config.enableAutoStopAtBlockGap = true; - USDHC_SetMmcBootConfig(USDHC, &config); - endcode - * - * param base USDHC peripheral base address. - * param config The MMC boot configuration information. - */ -void USDHC_SetMmcBootConfig(USDHC_Type *base, const usdhc_boot_config_t *config) -{ - assert(config); - assert(config->ackTimeoutCount <= (USDHC_MMC_BOOT_DTOCV_ACK_MASK >> USDHC_MMC_BOOT_DTOCV_ACK_SHIFT)); - assert(config->blockCount <= (USDHC_MMC_BOOT_BOOT_BLK_CNT_MASK >> USDHC_MMC_BOOT_BOOT_BLK_CNT_SHIFT)); - - uint32_t mmcboot = base->MMC_BOOT; - - mmcboot &= ~(USDHC_MMC_BOOT_DTOCV_ACK_MASK | USDHC_MMC_BOOT_BOOT_MODE_MASK | USDHC_MMC_BOOT_BOOT_BLK_CNT_MASK); - mmcboot |= USDHC_MMC_BOOT_DTOCV_ACK(config->ackTimeoutCount) | USDHC_MMC_BOOT_BOOT_MODE(config->bootMode); - - if (config->enableBootAck) - { - mmcboot |= USDHC_MMC_BOOT_BOOT_ACK_MASK; - } - if (config->enableAutoStopAtBlockGap) - { - mmcboot |= - USDHC_MMC_BOOT_AUTO_SABG_EN_MASK | USDHC_MMC_BOOT_BOOT_BLK_CNT(USDHC_MAX_BLOCK_COUNT - config->blockCount); - /* always set the block count to USDHC_MAX_BLOCK_COUNT to use auto stop at block gap feature */ - base->BLK_ATT = ((base->BLK_ATT & ~(USDHC_BLK_ATT_BLKSIZE_MASK | USDHC_BLK_ATT_BLKCNT_MASK)) | - (USDHC_BLK_ATT_BLKSIZE(config->blockSize) | USDHC_BLK_ATT_BLKCNT(USDHC_MAX_BLOCK_COUNT))); - } - else - { - base->BLK_ATT = ((base->BLK_ATT & ~(USDHC_BLK_ATT_BLKSIZE_MASK | USDHC_BLK_ATT_BLKCNT_MASK)) | - (USDHC_BLK_ATT_BLKSIZE(config->blockSize) | USDHC_BLK_ATT_BLKCNT(config->blockCount))); - } - - base->MMC_BOOT = mmcboot; -} - -/*! - * brief Sets the ADMA1 descriptor table configuration. - * - * param admaTable Adma table address. - * param admaTableWords Adma table length. - * param dataBufferAddr Data buffer address. - * param dataBytes Data length. - * param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please - * reference _usdhc_adma_flag. - * retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetADMA1Descriptor( - uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags) -{ - assert(NULL != admaTable); - assert(NULL != dataBufferAddr); - - uint32_t miniEntries, startEntries = 0U, - maxEntries = (admaTableWords * sizeof(uint32_t)) / sizeof(usdhc_adma1_descriptor_t); - usdhc_adma1_descriptor_t *adma1EntryAddress = (usdhc_adma1_descriptor_t *)(admaTable); - uint32_t i, dmaBufferLen = 0U; - const uint32_t *data = dataBufferAddr; - - if (((uint32_t)data % USDHC_ADMA1_ADDRESS_ALIGN) != 0U) - { - return kStatus_USDHC_DMADataAddrNotAlign; - } - - if (flags == kUSDHC_AdmaDescriptorMultipleFlag) - { - return kStatus_USDHC_NotSupport; - } - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (dataBytes % sizeof(uint32_t) != 0U) - { - /* make the data length as word-aligned */ - dataBytes += sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); - } - - /* Check if ADMA descriptor's number is enough. */ - if ((dataBytes % USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) == 0U) - { - miniEntries = dataBytes / USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY; - } - else - { - miniEntries = ((dataBytes / USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U); - } - - /* ADMA1 needs two descriptors to finish a transfer */ - miniEntries <<= 1U; - - if (miniEntries + startEntries > maxEntries) - { - return kStatus_OutOfRange; - } - - for (i = startEntries; i < (miniEntries + startEntries); i += 2U) - { - if (dataBytes > USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) - { - dmaBufferLen = USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY; - } - else - { - dmaBufferLen = dataBytes; - } - - adma1EntryAddress[i] = (dmaBufferLen << USDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT); - adma1EntryAddress[i] |= kUSDHC_Adma1DescriptorTypeSetLength; - adma1EntryAddress[i + 1U] = (uint32_t)(data); - adma1EntryAddress[i + 1U] |= kUSDHC_Adma1DescriptorTypeTransfer; - data += dmaBufferLen / sizeof(uint32_t); - dataBytes -= dmaBufferLen; - } - /* the end of the descriptor */ - adma1EntryAddress[i - 1U] |= kUSDHC_Adma1DescriptorEndFlag; - - return kStatus_Success; -} - -/*! - * brief Sets the ADMA2 descriptor table configuration. - * - * param admaTable Adma table address. - * param admaTableWords Adma table length. - * param dataBufferAddr Data buffer address. - * param dataBytes Data Data length. - * param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please - * reference _usdhc_adma_flag. - * retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetADMA2Descriptor( - uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags) -{ - assert(NULL != admaTable); - assert(NULL != dataBufferAddr); - - uint32_t miniEntries, startEntries = 0U, - maxEntries = (admaTableWords * sizeof(uint32_t)) / sizeof(usdhc_adma2_descriptor_t); - usdhc_adma2_descriptor_t *adma2EntryAddress = (usdhc_adma2_descriptor_t *)(admaTable); - uint32_t i, dmaBufferLen = 0U; - const uint32_t *data = dataBufferAddr; - - if (((uint32_t)data % USDHC_ADMA2_ADDRESS_ALIGN) != 0U) - { - return kStatus_USDHC_DMADataAddrNotAlign; - } - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (dataBytes % sizeof(uint32_t) != 0U) - { - /* make the data length as word-aligned */ - dataBytes += sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); - } - - /* Check if ADMA descriptor's number is enough. */ - if ((dataBytes % USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) == 0U) - { - miniEntries = dataBytes / USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY; - } - else - { - miniEntries = ((dataBytes / USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U); - } - /* calucate the start entry for multiple descriptor mode, ADMA engine is not stop, so update the descriptor - data adress and data size is enough */ - if (flags == kUSDHC_AdmaDescriptorMultipleFlag) - { - for (i = 0U; i < maxEntries; i++) - { - if ((adma2EntryAddress[i].attribute & kUSDHC_Adma2DescriptorValidFlag) == 0U) - { - break; - } - } - startEntries = i; - /* add one entry for dummy entry */ - miniEntries += 1U; - } - - if ((miniEntries + startEntries) > maxEntries) - { - return kStatus_OutOfRange; - } - - for (i = startEntries; i < (miniEntries + startEntries); i++) - { - if (dataBytes > USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) - { - dmaBufferLen = USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY; - } - else - { - dmaBufferLen = (dataBytes == 0U ? sizeof(uint32_t) : - dataBytes); /* adma don't support 0 data length transfer descriptor */ - } - - /* Each descriptor for ADMA2 is 64-bit in length */ - adma2EntryAddress[i].address = (dataBytes == 0U) ? &s_usdhcBootDummy : data; - adma2EntryAddress[i].attribute = (dmaBufferLen << USDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT); - adma2EntryAddress[i].attribute |= - (dataBytes == 0U) ? 0U : (kUSDHC_Adma2DescriptorTypeTransfer | kUSDHC_Adma2DescriptorInterruptFlag); - data += (dmaBufferLen / sizeof(uint32_t)); - - if (dataBytes != 0U) - { - dataBytes -= dmaBufferLen; - } - } - - /* add a dummy valid ADMA descriptor for multiple descriptor mode, this is useful when transfer boot data, the ADMA - engine - will not stop at block gap */ - if (flags == kUSDHC_AdmaDescriptorMultipleFlag) - { - adma2EntryAddress[startEntries + 1U].attribute |= kUSDHC_Adma2DescriptorTypeTransfer; - } - else - { - /* set the end bit */ - adma2EntryAddress[i - 1U].attribute |= kUSDHC_Adma2DescriptorEndFlag; - } - - return kStatus_Success; -} - -/*! - * brief Internal DMA configuration. - * This function is used to config the USDHC DMA related registers. - * param base USDHC peripheral base address. - * param adma configuration - * param dataAddr tranfer data address, a simple DMA parameter, if ADMA is used, leave it to NULL. - * param enAutoCmd23 flag to indicate Auto CMD23 is enable or not, a simple DMA parameter,if ADMA is used, leave it to - * false. - * retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetInternalDmaConfig(USDHC_Type *base, - usdhc_adma_config_t *dmaConfig, - const uint32_t *dataAddr, - bool enAutoCmd23) -{ - assert(dmaConfig); - assert(dataAddr); - -#if FSL_FEATURE_USDHC_HAS_EXT_DMA - /* disable the external DMA if support */ - base->VEND_SPEC &= ~USDHC_VEND_SPEC_EXT_DMA_EN_MASK; -#endif - - if (dmaConfig->dmaMode == kUSDHC_DmaModeSimple) - { - /* check DMA data buffer address align or not */ - if (((uint32_t)dataAddr % USDHC_ADMA2_ADDRESS_ALIGN) != 0U) - { - return kStatus_USDHC_DMADataAddrNotAlign; - } - /* in simple DMA mode if use auto CMD23, address should load to ADMA addr, - and block count should load to DS_ADDR*/ - if (enAutoCmd23) - { - base->ADMA_SYS_ADDR = (uint32_t)dataAddr; - } - else - { - base->DS_ADDR = (uint32_t)dataAddr; - } - } - else - { - /* When use ADMA, disable simple DMA */ - base->DS_ADDR = 0U; - base->ADMA_SYS_ADDR = (uint32_t)(dmaConfig->admaTable); - } - - /* select DMA mode and config the burst length */ - base->PROT_CTRL &= ~(USDHC_PROT_CTRL_DMASEL_MASK | USDHC_PROT_CTRL_BURST_LEN_EN_MASK); - base->PROT_CTRL |= USDHC_PROT_CTRL_DMASEL(dmaConfig->dmaMode) | USDHC_PROT_CTRL_BURST_LEN_EN(dmaConfig->burstLen); - /* enable DMA */ - base->MIX_CTRL |= USDHC_MIX_CTRL_DMAEN_MASK; - - return kStatus_Success; -} - -/*! - * brief Sets the DMA descriptor table configuration. - * A high level DMA descriptor configuration function. - * param base USDHC peripheral base address. - * param adma configuration - * param data Data descriptor - * param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please - * reference _usdhc_adma_flag - * retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetAdmaTableConfig(USDHC_Type *base, - usdhc_adma_config_t *dmaConfig, - usdhc_data_t *dataConfig, - uint32_t flags) -{ - assert(NULL != dmaConfig); - assert(NULL != dmaConfig->admaTable); - assert(NULL != dataConfig); - - status_t error = kStatus_Fail; - uint32_t bootDummyOffset = dataConfig->dataType == kUSDHC_TransferDataBootcontinous ? sizeof(uint32_t) : 0U; - const uint32_t *data = - (const uint32_t *)((uint32_t)((dataConfig->rxData == NULL) ? dataConfig->txData : dataConfig->rxData) + - bootDummyOffset); - uint32_t blockSize = dataConfig->blockSize * dataConfig->blockCount - bootDummyOffset; - - switch (dmaConfig->dmaMode) - { -#if FSL_FEATURE_USDHC_HAS_EXT_DMA - case kUSDHC_ExternalDMA: - /* enable the external DMA */ - base->VEND_SPEC |= USDHC_VEND_SPEC_EXT_DMA_EN_MASK; - break; -#endif - case kUSDHC_DmaModeSimple: - error = kStatus_Success; - break; - - case kUSDHC_DmaModeAdma1: - error = USDHC_SetADMA1Descriptor(dmaConfig->admaTable, dmaConfig->admaTableWords, data, blockSize, flags); - break; - - case kUSDHC_DmaModeAdma2: - error = USDHC_SetADMA2Descriptor(dmaConfig->admaTable, dmaConfig->admaTableWords, data, blockSize, flags); - break; - default: - return kStatus_USDHC_PrepareAdmaDescriptorFailed; - } - - /* for internal dma, internal DMA configurations should not update the configurations when continous transfer the - * boot data, only the DMA descriptor need update */ - if ((dmaConfig->dmaMode != kUSDHC_ExternalDMA) && (error == kStatus_Success) && - (dataConfig->dataType != kUSDHC_TransferDataBootcontinous)) - { - error = USDHC_SetInternalDmaConfig(base, dmaConfig, data, dataConfig->enableAutoCommand23); - } - - return error; -} - -/*! - * brief Transfers the command/data using a blocking method. - * - * This function waits until the command response/data is received or the USDHC encounters an error by polling the - * status - * flag. - * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support - * the re-entry mechanism. - * - * note There is no need to call the API 'USDHC_TransferCreateHandle' when calling this API. - * - * param base USDHC peripheral base address. - * param adma configuration - * param transfer Transfer content. - * retval kStatus_InvalidArgument Argument is invalid. - * retval kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. - * retval kStatus_USDHC_SendCommandFailed Send command failed. - * retval kStatus_USDHC_TransferDataFailed Transfer data failed. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_TransferBlocking(USDHC_Type *base, usdhc_adma_config_t *dmaConfig, usdhc_transfer_t *transfer) -{ - assert(transfer); - - status_t error = kStatus_Fail; - usdhc_command_t *command = transfer->command; - usdhc_data_t *data = transfer->data; - bool enDMA = true; - bool executeTuning = ((data == NULL) ? false : data->dataType == kUSDHC_TransferDataTuning); - - /*check re-tuning request*/ - if ((USDHC_GetInterruptStatusFlags(base) & kUSDHC_ReTuningEventFlag) != 0U) - { - USDHC_ClearInterruptStatusFlags(base, kUSDHC_ReTuningEventFlag); - return kStatus_USDHC_ReTuningRequest; - } - - /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ - if ((data != NULL) && (dmaConfig != NULL) && (!executeTuning)) - { - error = USDHC_SetAdmaTableConfig(base, dmaConfig, data, (data->dataType & kUSDHC_TransferDataBoot) ? - kUSDHC_AdmaDescriptorMultipleFlag : - kUSDHC_AdmaDescriptorSingleFlag); - } - - /* if the DMA desciptor configure fail or not needed , disable it */ - if (error != kStatus_Success) - { - enDMA = false; - /* disable DMA, using polling mode in this situation */ - USDHC_EnableInternalDMA(base, false); - } -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - else - { - if (data->txData != NULL) - { - /* clear the DCACHE */ - DCACHE_CleanByRange((uint32_t)data->txData, (data->blockSize) * (data->blockCount)); - } - else - { - /* clear the DCACHE */ - DCACHE_CleanInvalidateByRange((uint32_t)data->rxData, (data->blockSize) * (data->blockCount)); - } - } -#endif - - /* config the data transfer parameter */ - error = USDHC_SetDataTransferConfig(base, data, &(command->flags), enDMA); - if (kStatus_Success != error) - { - return error; - } - /* send command first */ - USDHC_SendCommand(base, command); - /* wait command done */ - error = USDHC_WaitCommandDone(base, command, (data == NULL) || (data->dataType == kUSDHC_TransferDataNormal)); - - /* wait transfer data finsih */ - if ((data != NULL) && (error == kStatus_Success)) - { - return USDHC_TransferDataBlocking(base, data, enDMA); - } - - return error; -} - -/*! - * brief Transfers the command/data using an interrupt and an asynchronous method. - * - * This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an - * error. - * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support - * the re-entry mechanism. - * - * note Call the API 'USDHC_TransferCreateHandle' when calling this API. - * - * param base USDHC peripheral base address. - * param handle USDHC handle. - * param adma configuration. - * param transfer Transfer content. - * retval kStatus_InvalidArgument Argument is invalid. - * retval kStatus_USDHC_BusyTransferring Busy transferring. - * retval kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_TransferNonBlocking(USDHC_Type *base, - usdhc_handle_t *handle, - usdhc_adma_config_t *dmaConfig, - usdhc_transfer_t *transfer) -{ - assert(handle); - assert(transfer); - - status_t error = kStatus_Fail; - usdhc_command_t *command = transfer->command; - usdhc_data_t *data = transfer->data; - bool executeTuning = ((data == NULL) ? false : data->dataType == kUSDHC_TransferDataTuning); - bool enDMA = true; - - /*check re-tuning request*/ - if ((USDHC_GetInterruptStatusFlags(base) & (kUSDHC_ReTuningEventFlag)) != 0U) - { - USDHC_ClearInterruptStatusFlags(base, kUSDHC_ReTuningEventFlag); - return kStatus_USDHC_ReTuningRequest; - } - - /* Save command and data into handle before transferring. */ - handle->command = command; - handle->data = data; - handle->interruptFlags = 0U; - /* transferredWords will only be updated in ISR when transfer way is DATAPORT. */ - handle->transferredWords = 0U; - - /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ - if ((data != NULL) && (dmaConfig != NULL) && (!executeTuning)) - { - error = USDHC_SetAdmaTableConfig(base, dmaConfig, data, (data->dataType & kUSDHC_TransferDataBoot) ? - kUSDHC_AdmaDescriptorMultipleFlag : - kUSDHC_AdmaDescriptorSingleFlag); - } - - /* if the DMA desciptor configure fail or not needed , disable it */ - if (error != kStatus_Success) - { - /* disable DMA, using polling mode in this situation */ - USDHC_EnableInternalDMA(base, false); - enDMA = false; - } -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - else - { - if (data->txData != NULL) - { - /* clear the DCACHE */ - DCACHE_CleanByRange((uint32_t)data->txData, (data->blockSize) * (data->blockCount)); - } - else - { - /* clear the DCACHE */ - DCACHE_CleanInvalidateByRange((uint32_t)data->rxData, (data->blockSize) * (data->blockCount)); - } - } -#endif - - error = USDHC_SetDataTransferConfig(base, data, &(command->flags), enDMA); - if (kStatus_Success != error) - { - return error; - } - - /* send command first */ - USDHC_SendCommand(base, command); - - return kStatus_Success; -} - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) -/*! - * brief manual tuning trigger or abort - * User should handle the tuning cmd and find the boundary of the delay - * then calucate a average value which will be config to the CLK_TUNE_CTRL_STATUS - * This function should called before USDHC_AdjustDelayforSDR104 function - * param base USDHC peripheral base address. - * param tuning enable flag - */ -void USDHC_EnableManualTuning(USDHC_Type *base, bool enable) -{ - if (enable) - { - /* make sure std_tun_en bit is clear */ - base->TUNING_CTRL &= ~USDHC_TUNING_CTRL_STD_TUNING_EN_MASK; - /* disable auto tuning here */ - base->MIX_CTRL &= ~USDHC_MIX_CTRL_AUTO_TUNE_EN_MASK; - /* execute tuning for SDR104 mode */ - base->MIX_CTRL |= - USDHC_MIX_CTRL_EXE_TUNE_MASK | USDHC_MIX_CTRL_SMP_CLK_SEL_MASK | USDHC_MIX_CTRL_FBCLK_SEL_MASK; - } - else - { /* abort the tuning */ - base->MIX_CTRL &= ~(USDHC_MIX_CTRL_EXE_TUNE_MASK | USDHC_MIX_CTRL_SMP_CLK_SEL_MASK); - } -} - -/*! - * brief the SDR104 mode delay setting adjust - * This function should called after USDHC_ManualTuningForSDR104 - * param base USDHC peripheral base address. - * param delay setting configuration - * retval kStatus_Fail config the delay setting fail - * retval kStatus_Success config the delay setting success - */ -status_t USDHC_AdjustDelayForManualTuning(USDHC_Type *base, uint32_t delay) -{ - uint32_t clkTuneCtrl = 0U; - - clkTuneCtrl = base->CLK_TUNE_CTRL_STATUS; - - clkTuneCtrl &= ~USDHC_CLK_TUNE_CTRL_STATUS_DLY_CELL_SET_PRE_MASK; - - clkTuneCtrl |= USDHC_CLK_TUNE_CTRL_STATUS_DLY_CELL_SET_PRE(delay); - - /* load the delay setting */ - base->CLK_TUNE_CTRL_STATUS = clkTuneCtrl; - /* check delat setting error */ - if (base->CLK_TUNE_CTRL_STATUS & - (USDHC_CLK_TUNE_CTRL_STATUS_PRE_ERR_MASK | USDHC_CLK_TUNE_CTRL_STATUS_NXT_ERR_MASK)) - { - return kStatus_Fail; - } - - return kStatus_Success; -} - -/*! - * brief the enable standard tuning function - * The standard tuning window and tuning counter use the default config - * tuning cmd is send by the software, user need to check the tuning result - * can be used for SDR50,SDR104,HS200 mode tuning - * param base USDHC peripheral base address. - * param tuning start tap - * param tuning step - * param enable/disable flag - */ -void USDHC_EnableStandardTuning(USDHC_Type *base, uint32_t tuningStartTap, uint32_t step, bool enable) -{ - uint32_t tuningCtrl = 0U; - - if (enable) - { - /* feedback clock */ - base->MIX_CTRL |= USDHC_MIX_CTRL_FBCLK_SEL_MASK; - /* config tuning start and step */ - tuningCtrl = base->TUNING_CTRL; - tuningCtrl &= ~(USDHC_TUNING_CTRL_TUNING_START_TAP_MASK | USDHC_TUNING_CTRL_TUNING_STEP_MASK); - tuningCtrl |= (USDHC_TUNING_CTRL_TUNING_START_TAP(tuningStartTap) | USDHC_TUNING_CTRL_TUNING_STEP(step) | - USDHC_TUNING_CTRL_STD_TUNING_EN_MASK); - base->TUNING_CTRL = tuningCtrl; - - /* excute tuning */ - base->AUTOCMD12_ERR_STATUS |= - (USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK | USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK); - } - else - { - /* disable the standard tuning */ - base->TUNING_CTRL &= ~USDHC_TUNING_CTRL_STD_TUNING_EN_MASK; - /* clear excute tuning */ - base->AUTOCMD12_ERR_STATUS &= - ~(USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK | USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK); - } -} - -/*! - * brief the auto tuning enbale for CMD/DATA line - * - * param base USDHC peripheral base address. - */ -void USDHC_EnableAutoTuningForCmdAndData(USDHC_Type *base) -{ - uint32_t busWidth = 0U; - - base->VEND_SPEC2 |= USDHC_VEND_SPEC2_TUNING_CMD_EN_MASK; - busWidth = (base->PROT_CTRL & USDHC_PROT_CTRL_DTW_MASK) >> USDHC_PROT_CTRL_DTW_SHIFT; - if (busWidth == kUSDHC_DataBusWidth1Bit) - { - base->VEND_SPEC2 &= ~USDHC_VEND_SPEC2_TUNING_8bit_EN_MASK; - base->VEND_SPEC2 |= USDHC_VEND_SPEC2_TUNING_1bit_EN_MASK; - } - else if (busWidth == kUSDHC_DataBusWidth4Bit) - { - base->VEND_SPEC2 &= ~USDHC_VEND_SPEC2_TUNING_8bit_EN_MASK; - base->VEND_SPEC2 &= ~USDHC_VEND_SPEC2_TUNING_1bit_EN_MASK; - } - else if (busWidth == kUSDHC_DataBusWidth8Bit) - { - base->VEND_SPEC2 |= USDHC_VEND_SPEC2_TUNING_8bit_EN_MASK; - base->VEND_SPEC2 &= ~USDHC_VEND_SPEC2_TUNING_1bit_EN_MASK; - } - else - { - } -} -#endif /* FSL_FEATURE_USDHC_HAS_SDR50_MODE */ - -static void USDHC_TransferHandleCardDetect(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags) -{ - if (interruptFlags & kUSDHC_CardInsertionFlag) - { - if (handle->callback.CardInserted) - { - handle->callback.CardInserted(base, handle->userData); - } - } - else - { - if (handle->callback.CardRemoved) - { - handle->callback.CardRemoved(base, handle->userData); - } - } -} - -static void USDHC_TransferHandleCommand(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags) -{ - assert(handle->command); - - if (interruptFlags & kUSDHC_CommandErrorFlag) - { - if (handle->callback.TransferComplete) - { - handle->callback.TransferComplete(base, handle, kStatus_USDHC_SendCommandFailed, handle->userData); - } - } - else - { - /* Receive response */ - if (kStatus_Success != USDHC_ReceiveCommandResponse(base, handle->command)) - { - if (handle->callback.TransferComplete) - { - handle->callback.TransferComplete(base, handle, kStatus_USDHC_SendCommandFailed, handle->userData); - } - } - else if ((!(handle->data)) && (handle->callback.TransferComplete)) - { - if (handle->callback.TransferComplete) - { - handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData); - } - } - else - { - } - } -} - -static void USDHC_TransferHandleData(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags) -{ - assert(handle->data); - - if ((!(handle->data->enableIgnoreError)) && ((interruptFlags & (kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag)))) - { - if (handle->callback.TransferComplete) - { - handle->callback.TransferComplete(base, handle, kStatus_USDHC_TransferDataFailed, handle->userData); - } - } - else - { - if (interruptFlags & kUSDHC_BufferReadReadyFlag) - { - /* std tuning process only need to wait BRR */ - if (handle->data->dataType == kUSDHC_TransferDataTuning) - { - if (handle->callback.TransferComplete) - { - handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData); - } - } - else - { - handle->transferredWords = USDHC_ReadDataPort(base, handle->data, handle->transferredWords); - } - } - else if (interruptFlags & kUSDHC_BufferWriteReadyFlag) - { - handle->transferredWords = USDHC_WriteDataPort(base, handle->data, handle->transferredWords); - } - else - { - if ((interruptFlags & kUSDHC_DmaCompleteFlag) && - (handle->data->dataType == kUSDHC_TransferDataBootcontinous)) - { - *(handle->data->rxData) = s_usdhcBootDummy; - } - - if ((handle->callback.TransferComplete) && (interruptFlags & kUSDHC_DataCompleteFlag)) - { - handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData); - } - } - } -} - -static void USDHC_TransferHandleSdioInterrupt(USDHC_Type *base, usdhc_handle_t *handle) -{ - if (handle->callback.SdioInterrupt) - { - handle->callback.SdioInterrupt(base, handle->userData); - } -} - -static void USDHC_TransferHandleReTuning(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags) -{ - assert(handle->callback.ReTuning); - /* retuning request */ - if ((interruptFlags & kUSDHC_TuningErrorFlag) == kUSDHC_TuningErrorFlag) - { - handle->callback.ReTuning(base, handle->userData); /* retuning fail */ - } -} - -static void USDHC_TransferHandleBlockGap(USDHC_Type *base, usdhc_handle_t *handle) -{ - if (handle->callback.BlockGap) - { - handle->callback.BlockGap(base, handle->userData); - } -} - -/*! - * brief Creates the USDHC handle. - * - * param base USDHC peripheral base address. - * param handle USDHC handle pointer. - * param callback Structure pointer to contain all callback functions. - * param userData Callback function parameter. - */ -void USDHC_TransferCreateHandle(USDHC_Type *base, - usdhc_handle_t *handle, - const usdhc_transfer_callback_t *callback, - void *userData) -{ - assert(handle); - assert(callback); - - /* Zero the handle. */ - memset(handle, 0, sizeof(*handle)); - - /* Set the callback. */ - handle->callback.CardInserted = callback->CardInserted; - handle->callback.CardRemoved = callback->CardRemoved; - handle->callback.SdioInterrupt = callback->SdioInterrupt; - handle->callback.BlockGap = callback->BlockGap; - handle->callback.TransferComplete = callback->TransferComplete; - handle->callback.ReTuning = callback->ReTuning; - handle->userData = userData; - - /* Save the handle in global variables to support the double weak mechanism. */ - s_usdhcHandle[USDHC_GetInstance(base)] = handle; - - /* Enable interrupt in NVIC. */ - USDHC_SetTransferInterrupt(base, true); - /* save IRQ handler */ - s_usdhcIsr = USDHC_TransferHandleIRQ; - - EnableIRQ(s_usdhcIRQ[USDHC_GetInstance(base)]); -} - -/*! - * brief IRQ handler for the USDHC. - * - * This function deals with the IRQs on the given host controller. - * - * param base USDHC peripheral base address. - * param handle USDHC handle. - */ -void USDHC_TransferHandleIRQ(USDHC_Type *base, usdhc_handle_t *handle) -{ - assert(handle); - - uint32_t interruptFlags; - - interruptFlags = USDHC_GetInterruptStatusFlags(base); - handle->interruptFlags = interruptFlags; - - if (interruptFlags & kUSDHC_CardDetectFlag) - { - USDHC_TransferHandleCardDetect(base, handle, (interruptFlags & kUSDHC_CardDetectFlag)); - } - if (interruptFlags & kUSDHC_CommandFlag) - { - USDHC_TransferHandleCommand(base, handle, (interruptFlags & kUSDHC_CommandFlag)); - } - if (interruptFlags & kUSDHC_DataFlag) - { - USDHC_TransferHandleData(base, handle, (interruptFlags & kUSDHC_DataFlag)); - } - if (interruptFlags & kUSDHC_CardInterruptFlag) - { - USDHC_TransferHandleSdioInterrupt(base, handle); - } - if (interruptFlags & kUSDHC_BlockGapEventFlag) - { - USDHC_TransferHandleBlockGap(base, handle); - } - if (interruptFlags & kUSDHC_SDR104TuningFlag) - { - USDHC_TransferHandleReTuning(base, handle, (interruptFlags & kUSDHC_SDR104TuningFlag)); - } - USDHC_ClearInterruptStatusFlags(base, interruptFlags); -} - -#ifdef USDHC0 -void USDHC0_DriverIRQHandler(void) -{ - s_usdhcIsr(s_usdhcBase[0U], s_usdhcHandle[0U]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#ifdef USDHC1 -void USDHC1_DriverIRQHandler(void) -{ - s_usdhcIsr(s_usdhcBase[1U], s_usdhcHandle[1U]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif - -#ifdef USDHC2 -void USDHC2_DriverIRQHandler(void) -{ - s_usdhcIsr(s_usdhcBase[2U], s_usdhcHandle[2U]); -/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping - exception return operation might vector to incorrect interrupt */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} - -#endif diff --git a/targets/FreeRTOS/UAC18/common/drivers/fsl_usdhc.h b/targets/FreeRTOS/UAC18/common/drivers/fsl_usdhc.h deleted file mode 100644 index 2a2bedb603..0000000000 --- a/targets/FreeRTOS/UAC18/common/drivers/fsl_usdhc.h +++ /dev/null @@ -1,1479 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2016, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2017 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// -#ifndef _FSL_USDHC_H_ -#define _FSL_USDHC_H_ - -#include "fsl_common.h" - -/*! - * @addtogroup usdhc - * @{ - */ - -/****************************************************************************** - * Definitions. - *****************************************************************************/ - -/*! @name Driver version */ -/*@{*/ -/*! @brief Driver version 2.2.5. */ -#define FSL_USDHC_DRIVER_VERSION (MAKE_VERSION(2U, 2U, 5U)) -/*@}*/ - -/*! @brief Maximum block count can be set one time */ -#define USDHC_MAX_BLOCK_COUNT (USDHC_BLK_ATT_BLKCNT_MASK >> USDHC_BLK_ATT_BLKCNT_SHIFT) - -/*! @brief USDHC status */ -enum _usdhc_status -{ - kStatus_USDHC_BusyTransferring = MAKE_STATUS(kStatusGroup_USDHC, 0U), /*!< Transfer is on-going */ - kStatus_USDHC_PrepareAdmaDescriptorFailed = MAKE_STATUS(kStatusGroup_USDHC, 1U), /*!< Set DMA descriptor failed */ - kStatus_USDHC_SendCommandFailed = MAKE_STATUS(kStatusGroup_USDHC, 2U), /*!< Send command failed */ - kStatus_USDHC_TransferDataFailed = MAKE_STATUS(kStatusGroup_USDHC, 3U), /*!< Transfer data failed */ - kStatus_USDHC_DMADataAddrNotAlign = MAKE_STATUS(kStatusGroup_USDHC, 4U), /*!< data address not align */ - kStatus_USDHC_ReTuningRequest = MAKE_STATUS(kStatusGroup_USDHC, 5U), /*!< re-tuning request */ - kStatus_USDHC_TuningError = MAKE_STATUS(kStatusGroup_USDHC, 6U), /*!< tuning error */ - kStatus_USDHC_NotSupport = MAKE_STATUS(kStatusGroup_USDHC, 7U), /*!< not support */ -}; - -/*! @brief Host controller capabilities flag mask */ -enum _usdhc_capability_flag -{ - kUSDHC_SupportAdmaFlag = USDHC_HOST_CTRL_CAP_ADMAS_MASK, /*!< Support ADMA */ - kUSDHC_SupportHighSpeedFlag = USDHC_HOST_CTRL_CAP_HSS_MASK, /*!< Support high-speed */ - kUSDHC_SupportDmaFlag = USDHC_HOST_CTRL_CAP_DMAS_MASK, /*!< Support DMA */ - kUSDHC_SupportSuspendResumeFlag = USDHC_HOST_CTRL_CAP_SRS_MASK, /*!< Support suspend/resume */ - kUSDHC_SupportV330Flag = USDHC_HOST_CTRL_CAP_VS33_MASK, /*!< Support voltage 3.3V */ - kUSDHC_SupportV300Flag = USDHC_HOST_CTRL_CAP_VS30_MASK, /*!< Support voltage 3.0V */ - kUSDHC_SupportV180Flag = USDHC_HOST_CTRL_CAP_VS18_MASK, /*!< Support voltage 1.8V */ - /* Put additional two flags in HTCAPBLT_MBL's position. */ - kUSDHC_Support4BitFlag = (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 0U), /*!< Support 4 bit mode */ - kUSDHC_Support8BitFlag = (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 1U), /*!< Support 8 bit mode */ - /* sd version 3.0 new feature */ - kUSDHC_SupportDDR50Flag = USDHC_HOST_CTRL_CAP_DDR50_SUPPORT_MASK, /*!< support DDR50 mode */ - -#if defined(FSL_FEATURE_USDHC_HAS_SDR104_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR104_MODE) - kUSDHC_SupportSDR104Flag = 0, /*!< not support SDR104 mode */ -#else - kUSDHC_SupportSDR104Flag = USDHC_HOST_CTRL_CAP_SDR104_SUPPORT_MASK, /*!< support SDR104 mode */ -#endif -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE) - kUSDHC_SupportSDR50Flag = 0U, /*!< not support SDR50 mode */ -#else - kUSDHC_SupportSDR50Flag = USDHC_HOST_CTRL_CAP_SDR50_SUPPORT_MASK, /*!< support SDR50 mode */ -#endif -}; - -/*! @brief Wakeup event mask */ -enum _usdhc_wakeup_event -{ - kUSDHC_WakeupEventOnCardInt = USDHC_PROT_CTRL_WECINT_MASK, /*!< Wakeup on card interrupt */ - kUSDHC_WakeupEventOnCardInsert = USDHC_PROT_CTRL_WECINS_MASK, /*!< Wakeup on card insertion */ - kUSDHC_WakeupEventOnCardRemove = USDHC_PROT_CTRL_WECRM_MASK, /*!< Wakeup on card removal */ - - kUSDHC_WakeupEventsAll = (kUSDHC_WakeupEventOnCardInt | kUSDHC_WakeupEventOnCardInsert | - kUSDHC_WakeupEventOnCardRemove), /*!< All wakeup events */ -}; - -/*! @brief Reset type mask */ -enum _usdhc_reset -{ - kUSDHC_ResetAll = USDHC_SYS_CTRL_RSTA_MASK, /*!< Reset all except card detection */ - kUSDHC_ResetCommand = USDHC_SYS_CTRL_RSTC_MASK, /*!< Reset command line */ - kUSDHC_ResetData = USDHC_SYS_CTRL_RSTD_MASK, /*!< Reset data line */ - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE) - kUSDHC_ResetTuning = 0U, /*!< no reset tuning circuit bit */ -#else - kUSDHC_ResetTuning = USDHC_SYS_CTRL_RSTT_MASK, /*!< reset tuning circuit */ -#endif - - kUSDHC_ResetsAll = - (kUSDHC_ResetAll | kUSDHC_ResetCommand | kUSDHC_ResetData | kUSDHC_ResetTuning), /*!< All reset types */ -}; - -/*! @brief Transfer flag mask */ -enum _usdhc_transfer_flag -{ - kUSDHC_EnableDmaFlag = USDHC_MIX_CTRL_DMAEN_MASK, /*!< Enable DMA */ - - kUSDHC_CommandTypeSuspendFlag = (USDHC_CMD_XFR_TYP_CMDTYP(1U)), /*!< Suspend command */ - kUSDHC_CommandTypeResumeFlag = (USDHC_CMD_XFR_TYP_CMDTYP(2U)), /*!< Resume command */ - kUSDHC_CommandTypeAbortFlag = (USDHC_CMD_XFR_TYP_CMDTYP(3U)), /*!< Abort command */ - - kUSDHC_EnableBlockCountFlag = USDHC_MIX_CTRL_BCEN_MASK, /*!< Enable block count */ - kUSDHC_EnableAutoCommand12Flag = USDHC_MIX_CTRL_AC12EN_MASK, /*!< Enable auto CMD12 */ - kUSDHC_DataReadFlag = USDHC_MIX_CTRL_DTDSEL_MASK, /*!< Enable data read */ - kUSDHC_MultipleBlockFlag = USDHC_MIX_CTRL_MSBSEL_MASK, /*!< Multiple block data read/write */ - kUSDHC_EnableAutoCommand23Flag = USDHC_MIX_CTRL_AC23EN_MASK, /*!< Enable auto CMD23 */ - - kUSDHC_ResponseLength136Flag = USDHC_CMD_XFR_TYP_RSPTYP(1U), /*!< 136 bit response length */ - kUSDHC_ResponseLength48Flag = USDHC_CMD_XFR_TYP_RSPTYP(2U), /*!< 48 bit response length */ - kUSDHC_ResponseLength48BusyFlag = USDHC_CMD_XFR_TYP_RSPTYP(3U), /*!< 48 bit response length with busy status */ - - kUSDHC_EnableCrcCheckFlag = USDHC_CMD_XFR_TYP_CCCEN_MASK, /*!< Enable CRC check */ - kUSDHC_EnableIndexCheckFlag = USDHC_CMD_XFR_TYP_CICEN_MASK, /*!< Enable index check */ - kUSDHC_DataPresentFlag = USDHC_CMD_XFR_TYP_DPSEL_MASK, /*!< Data present flag */ -}; - -/*! @brief Present status flag mask */ -enum _usdhc_present_status_flag -{ - kUSDHC_CommandInhibitFlag = USDHC_PRES_STATE_CIHB_MASK, /*!< Command inhibit */ - kUSDHC_DataInhibitFlag = USDHC_PRES_STATE_CDIHB_MASK, /*!< Data inhibit */ - kUSDHC_DataLineActiveFlag = USDHC_PRES_STATE_DLA_MASK, /*!< Data line active */ - kUSDHC_SdClockStableFlag = USDHC_PRES_STATE_SDSTB_MASK, /*!< SD bus clock stable */ - kUSDHC_WriteTransferActiveFlag = USDHC_PRES_STATE_WTA_MASK, /*!< Write transfer active */ - kUSDHC_ReadTransferActiveFlag = USDHC_PRES_STATE_RTA_MASK, /*!< Read transfer active */ - kUSDHC_BufferWriteEnableFlag = USDHC_PRES_STATE_BWEN_MASK, /*!< Buffer write enable */ - kUSDHC_BufferReadEnableFlag = USDHC_PRES_STATE_BREN_MASK, /*!< Buffer read enable */ - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE) - kUSDHC_DelaySettingFinishedFlag = 0U, /*!< not support */ - kUSDHC_ReTuningRequestFlag = 0U, /*!< not support */ -#else - kUSDHC_ReTuningRequestFlag = USDHC_PRES_STATE_RTR_MASK, /*!< re-tuning request flag ,only used for SDR104 mode */ - kUSDHC_DelaySettingFinishedFlag = USDHC_PRES_STATE_TSCD_MASK, /*!< delay setting finished flag */ -#endif - - kUSDHC_CardInsertedFlag = USDHC_PRES_STATE_CINST_MASK, /*!< Card inserted */ - kUSDHC_CommandLineLevelFlag = USDHC_PRES_STATE_CLSL_MASK, /*!< Command line signal level */ - - kUSDHC_Data0LineLevelFlag = 1U << USDHC_PRES_STATE_DLSL_SHIFT, /*!< Data0 line signal level */ - kUSDHC_Data1LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 1U), /*!< Data1 line signal level */ - kUSDHC_Data2LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 2U), /*!< Data2 line signal level */ - kUSDHC_Data3LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 3U), /*!< Data3 line signal level */ - kUSDHC_Data4LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 4U), /*!< Data4 line signal level */ - kUSDHC_Data5LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 5U), /*!< Data5 line signal level */ - kUSDHC_Data6LineLevelFlag = 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 6U), /*!< Data6 line signal level */ - kUSDHC_Data7LineLevelFlag = (int)(1U << (USDHC_PRES_STATE_DLSL_SHIFT + 7U)), /*!< Data7 line signal level */ -}; - -/*! @brief Interrupt status flag mask */ -enum _usdhc_interrupt_status_flag -{ - kUSDHC_CommandCompleteFlag = USDHC_INT_STATUS_CC_MASK, /*!< Command complete */ - kUSDHC_DataCompleteFlag = USDHC_INT_STATUS_TC_MASK, /*!< Data complete */ - kUSDHC_BlockGapEventFlag = USDHC_INT_STATUS_BGE_MASK, /*!< Block gap event */ - kUSDHC_DmaCompleteFlag = USDHC_INT_STATUS_DINT_MASK, /*!< DMA interrupt */ - kUSDHC_BufferWriteReadyFlag = USDHC_INT_STATUS_BWR_MASK, /*!< Buffer write ready */ - kUSDHC_BufferReadReadyFlag = USDHC_INT_STATUS_BRR_MASK, /*!< Buffer read ready */ - kUSDHC_CardInsertionFlag = USDHC_INT_STATUS_CINS_MASK, /*!< Card inserted */ - kUSDHC_CardRemovalFlag = USDHC_INT_STATUS_CRM_MASK, /*!< Card removed */ - kUSDHC_CardInterruptFlag = USDHC_INT_STATUS_CINT_MASK, /*!< Card interrupt */ - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE) - kUSDHC_ReTuningEventFlag = 0U, /*!< Re-Tuning event,only for SD3.0 SDR104 mode */ - kUSDHC_TuningPassFlag = 0U, /*!< SDR104 mode tuning pass flag */ - kUSDHC_TuningErrorFlag = 0U, /*!< SDR104 tuning error flag */ -#else - kUSDHC_ReTuningEventFlag = USDHC_INT_STATUS_RTE_MASK, /*!< Re-Tuning event,only for SD3.0 SDR104 mode */ - kUSDHC_TuningPassFlag = USDHC_INT_STATUS_TP_MASK, /*!< SDR104 mode tuning pass flag */ - kUSDHC_TuningErrorFlag = USDHC_INT_STATUS_TNE_MASK, /*!< SDR104 tuning error flag */ -#endif - - kUSDHC_CommandTimeoutFlag = USDHC_INT_STATUS_CTOE_MASK, /*!< Command timeout error */ - kUSDHC_CommandCrcErrorFlag = USDHC_INT_STATUS_CCE_MASK, /*!< Command CRC error */ - kUSDHC_CommandEndBitErrorFlag = USDHC_INT_STATUS_CEBE_MASK, /*!< Command end bit error */ - kUSDHC_CommandIndexErrorFlag = USDHC_INT_STATUS_CIE_MASK, /*!< Command index error */ - kUSDHC_DataTimeoutFlag = USDHC_INT_STATUS_DTOE_MASK, /*!< Data timeout error */ - kUSDHC_DataCrcErrorFlag = USDHC_INT_STATUS_DCE_MASK, /*!< Data CRC error */ - kUSDHC_DataEndBitErrorFlag = USDHC_INT_STATUS_DEBE_MASK, /*!< Data end bit error */ - kUSDHC_AutoCommand12ErrorFlag = USDHC_INT_STATUS_AC12E_MASK, /*!< Auto CMD12 error */ - kUSDHC_DmaErrorFlag = USDHC_INT_STATUS_DMAE_MASK, /*!< DMA error */ - - kUSDHC_CommandErrorFlag = (kUSDHC_CommandTimeoutFlag | kUSDHC_CommandCrcErrorFlag | kUSDHC_CommandEndBitErrorFlag | - kUSDHC_CommandIndexErrorFlag), /*!< Command error */ - kUSDHC_DataErrorFlag = (kUSDHC_DataTimeoutFlag | kUSDHC_DataCrcErrorFlag | kUSDHC_DataEndBitErrorFlag | - kUSDHC_AutoCommand12ErrorFlag), /*!< Data error */ - kUSDHC_ErrorFlag = (kUSDHC_CommandErrorFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag), /*!< All error */ - kUSDHC_DataFlag = (kUSDHC_DataCompleteFlag | kUSDHC_DmaCompleteFlag | kUSDHC_BufferWriteReadyFlag | - kUSDHC_BufferReadReadyFlag | kUSDHC_DataErrorFlag | kUSDHC_DmaErrorFlag), /*!< Data interrupts */ - kUSDHC_CommandFlag = (kUSDHC_CommandErrorFlag | kUSDHC_CommandCompleteFlag), /*!< Command interrupts */ - kUSDHC_CardDetectFlag = (kUSDHC_CardInsertionFlag | kUSDHC_CardRemovalFlag), /*!< Card detection interrupts */ - kUSDHC_SDR104TuningFlag = (kUSDHC_TuningErrorFlag | kUSDHC_TuningPassFlag | kUSDHC_ReTuningEventFlag), - - kUSDHC_AllInterruptFlags = (kUSDHC_BlockGapEventFlag | kUSDHC_CardInterruptFlag | kUSDHC_CommandFlag | - kUSDHC_DataFlag | kUSDHC_ErrorFlag | kUSDHC_SDR104TuningFlag), /*!< All flags mask */ -}; - -/*! @brief Auto CMD12 error status flag mask */ -enum _usdhc_auto_command12_error_status_flag -{ - kUSDHC_AutoCommand12NotExecutedFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12NE_MASK, /*!< Not executed error */ - kUSDHC_AutoCommand12TimeoutFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12TOE_MASK, /*!< Timeout error */ - kUSDHC_AutoCommand12EndBitErrorFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12EBE_MASK, /*!< End bit error */ - kUSDHC_AutoCommand12CrcErrorFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12CE_MASK, /*!< CRC error */ - kUSDHC_AutoCommand12IndexErrorFlag = USDHC_AUTOCMD12_ERR_STATUS_AC12IE_MASK, /*!< Index error */ - kUSDHC_AutoCommand12NotIssuedFlag = USDHC_AUTOCMD12_ERR_STATUS_CNIBAC12E_MASK, /*!< Not issued error */ -}; - -/*! @brief standard tuning flag */ -enum _usdhc_standard_tuning -{ -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE) - kUSDHC_ExecuteTuning = 0U, /*!< not support */ - kUSDHC_TuningSampleClockSel = 0U, /*!< not support */ -#else - kUSDHC_ExecuteTuning = USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK, /*!< used to start tuning procedure */ - kUSDHC_TuningSampleClockSel = - USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK, /*!< when std_tuning_en bit is set, this bit is used - select sampleing clock */ -#endif -}; - -/*! @brief ADMA error status flag mask */ -enum _usdhc_adma_error_status_flag -{ - kUSDHC_AdmaLenghMismatchFlag = USDHC_ADMA_ERR_STATUS_ADMALME_MASK, /*!< Length mismatch error */ - kUSDHC_AdmaDescriptorErrorFlag = USDHC_ADMA_ERR_STATUS_ADMADCE_MASK, /*!< Descriptor error */ -}; - -/*! - * @brief ADMA error state - * - * This state is the detail state when ADMA error has occurred. - */ -enum _usdhc_adma_error_state -{ - kUSDHC_AdmaErrorStateStopDma = - 0x00U, /*!< Stop DMA, previous location set in the ADMA system address is error address */ - kUSDHC_AdmaErrorStateFetchDescriptor = - 0x01U, /*!< Fetch descriptor, current location set in the ADMA system address is error address */ - kUSDHC_AdmaErrorStateChangeAddress = 0x02U, /*!< Change address, no DMA error is occured */ - kUSDHC_AdmaErrorStateTransferData = - 0x03U, /*!< Transfer data, previous location set in the ADMA system address is error address */ - kUSDHC_AdmaErrorStateInvalidLength = 0x04U, /*!< Invalid length in ADMA descriptor */ - kUSDHC_AdmaErrorStateInvalidDescriptor = 0x08U, /*!< Invalid descriptor fetched by ADMA */ - - kUSDHC_AdmaErrorState = kUSDHC_AdmaErrorStateInvalidLength | kUSDHC_AdmaErrorStateInvalidDescriptor | - kUSDHC_AdmaErrorStateFetchDescriptor, /*!< ADMA error state */ -}; - -/*! @brief Force event bit position */ -enum _usdhc_force_event -{ - kUSDHC_ForceEventAutoCommand12NotExecuted = USDHC_FORCE_EVENT_FEVTAC12NE_MASK, /*!< Auto CMD12 not executed error */ - kUSDHC_ForceEventAutoCommand12Timeout = USDHC_FORCE_EVENT_FEVTAC12TOE_MASK, /*!< Auto CMD12 timeout error */ - kUSDHC_ForceEventAutoCommand12CrcError = USDHC_FORCE_EVENT_FEVTAC12CE_MASK, /*!< Auto CMD12 CRC error */ - kUSDHC_ForceEventEndBitError = USDHC_FORCE_EVENT_FEVTAC12EBE_MASK, /*!< Auto CMD12 end bit error */ - kUSDHC_ForceEventAutoCommand12IndexError = USDHC_FORCE_EVENT_FEVTAC12IE_MASK, /*!< Auto CMD12 index error */ - kUSDHC_ForceEventAutoCommand12NotIssued = USDHC_FORCE_EVENT_FEVTCNIBAC12E_MASK, /*!< Auto CMD12 not issued error */ - kUSDHC_ForceEventCommandTimeout = USDHC_FORCE_EVENT_FEVTCTOE_MASK, /*!< Command timeout error */ - kUSDHC_ForceEventCommandCrcError = USDHC_FORCE_EVENT_FEVTCCE_MASK, /*!< Command CRC error */ - kUSDHC_ForceEventCommandEndBitError = USDHC_FORCE_EVENT_FEVTCEBE_MASK, /*!< Command end bit error */ - kUSDHC_ForceEventCommandIndexError = USDHC_FORCE_EVENT_FEVTCIE_MASK, /*!< Command index error */ - kUSDHC_ForceEventDataTimeout = USDHC_FORCE_EVENT_FEVTDTOE_MASK, /*!< Data timeout error */ - kUSDHC_ForceEventDataCrcError = USDHC_FORCE_EVENT_FEVTDCE_MASK, /*!< Data CRC error */ - kUSDHC_ForceEventDataEndBitError = USDHC_FORCE_EVENT_FEVTDEBE_MASK, /*!< Data end bit error */ - kUSDHC_ForceEventAutoCommand12Error = USDHC_FORCE_EVENT_FEVTAC12E_MASK, /*!< Auto CMD12 error */ - kUSDHC_ForceEventCardInt = (int)USDHC_FORCE_EVENT_FEVTCINT_MASK, /*!< Card interrupt */ - kUSDHC_ForceEventDmaError = USDHC_FORCE_EVENT_FEVTDMAE_MASK, /*!< Dma error */ -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE) - kUSDHC_ForceEventTuningError = 0U, /*!< not support */ -#else - kUSDHC_ForceEventTuningError = USDHC_FORCE_EVENT_FEVTTNE_MASK, /*!< Tuning error */ -#endif - - kUSDHC_ForceEventsAll = - (int)(USDHC_FORCE_EVENT_FEVTAC12NE_MASK | USDHC_FORCE_EVENT_FEVTAC12TOE_MASK | - USDHC_FORCE_EVENT_FEVTAC12CE_MASK | USDHC_FORCE_EVENT_FEVTAC12EBE_MASK | - USDHC_FORCE_EVENT_FEVTAC12IE_MASK | USDHC_FORCE_EVENT_FEVTCNIBAC12E_MASK | - USDHC_FORCE_EVENT_FEVTCTOE_MASK | USDHC_FORCE_EVENT_FEVTCCE_MASK | USDHC_FORCE_EVENT_FEVTCEBE_MASK | - USDHC_FORCE_EVENT_FEVTCIE_MASK | USDHC_FORCE_EVENT_FEVTDTOE_MASK | USDHC_FORCE_EVENT_FEVTDCE_MASK | - USDHC_FORCE_EVENT_FEVTDEBE_MASK | USDHC_FORCE_EVENT_FEVTAC12E_MASK | USDHC_FORCE_EVENT_FEVTCINT_MASK | - USDHC_FORCE_EVENT_FEVTDMAE_MASK | kUSDHC_ForceEventTuningError), /*!< All force event flags mask */ -}; - -/*! @brief Data transfer width */ -typedef enum _usdhc_data_bus_width -{ - kUSDHC_DataBusWidth1Bit = 0U, /*!< 1-bit mode */ - kUSDHC_DataBusWidth4Bit = 1U, /*!< 4-bit mode */ - kUSDHC_DataBusWidth8Bit = 2U, /*!< 8-bit mode */ -} usdhc_data_bus_width_t; - -/*! @brief Endian mode */ -typedef enum _usdhc_endian_mode -{ - kUSDHC_EndianModeBig = 0U, /*!< Big endian mode */ - kUSDHC_EndianModeHalfWordBig = 1U, /*!< Half word big endian mode */ - kUSDHC_EndianModeLittle = 2U, /*!< Little endian mode */ -} usdhc_endian_mode_t; - -/*! @brief DMA mode */ -typedef enum _usdhc_dma_mode -{ - kUSDHC_DmaModeSimple = 0U, /*!< external DMA */ - kUSDHC_DmaModeAdma1 = 1U, /*!< ADMA1 is selected */ - kUSDHC_DmaModeAdma2 = 2U, /*!< ADMA2 is selected */ - kUSDHC_ExternalDMA = 3U, /*!< external dma mode select */ -} usdhc_dma_mode_t; - -/*! @brief SDIO control flag mask */ -enum _usdhc_sdio_control_flag -{ - kUSDHC_StopAtBlockGapFlag = USDHC_PROT_CTRL_SABGREQ_MASK, /*!< Stop at block gap */ - kUSDHC_ReadWaitControlFlag = USDHC_PROT_CTRL_RWCTL_MASK, /*!< Read wait control */ - kUSDHC_InterruptAtBlockGapFlag = USDHC_PROT_CTRL_IABG_MASK, /*!< Interrupt at block gap */ - kUSDHC_ReadDoneNo8CLK = USDHC_PROT_CTRL_RD_DONE_NO_8CLK_MASK, /*!< read done without 8 clk for block gap */ - kUSDHC_ExactBlockNumberReadFlag = USDHC_PROT_CTRL_NON_EXACT_BLK_RD_MASK, /*!< Exact block number read */ -}; - -/*! @brief MMC card boot mode */ -typedef enum _usdhc_boot_mode -{ - kUSDHC_BootModeNormal = 0U, /*!< Normal boot */ - kUSDHC_BootModeAlternative = 1U, /*!< Alternative boot */ -} usdhc_boot_mode_t; - -/*! @brief The command type */ -typedef enum _usdhc_card_command_type -{ - kCARD_CommandTypeNormal = 0U, /*!< Normal command */ - kCARD_CommandTypeSuspend = 1U, /*!< Suspend command */ - kCARD_CommandTypeResume = 2U, /*!< Resume command */ - kCARD_CommandTypeAbort = 3U, /*!< Abort command */ - kCARD_CommandTypeEmpty = 4U, /*!< Empty command */ -} usdhc_card_command_type_t; - -/*! - * @brief The command response type. - * - * Define the command response type from card to host controller. - */ -typedef enum _usdhc_card_response_type -{ - kCARD_ResponseTypeNone = 0U, /*!< Response type: none */ - kCARD_ResponseTypeR1 = 1U, /*!< Response type: R1 */ - kCARD_ResponseTypeR1b = 2U, /*!< Response type: R1b */ - kCARD_ResponseTypeR2 = 3U, /*!< Response type: R2 */ - kCARD_ResponseTypeR3 = 4U, /*!< Response type: R3 */ - kCARD_ResponseTypeR4 = 5U, /*!< Response type: R4 */ - kCARD_ResponseTypeR5 = 6U, /*!< Response type: R5 */ - kCARD_ResponseTypeR5b = 7U, /*!< Response type: R5b */ - kCARD_ResponseTypeR6 = 8U, /*!< Response type: R6 */ - kCARD_ResponseTypeR7 = 9U, /*!< Response type: R7 */ -} usdhc_card_response_type_t; - -/*! @brief The alignment size for ADDRESS filed in ADMA1's descriptor */ -#define USDHC_ADMA1_ADDRESS_ALIGN (4096U) -/*! @brief The alignment size for LENGTH field in ADMA1's descriptor */ -#define USDHC_ADMA1_LENGTH_ALIGN (4096U) -/*! @brief The alignment size for ADDRESS field in ADMA2's descriptor */ -#define USDHC_ADMA2_ADDRESS_ALIGN (4U) -/*! @brief The alignment size for LENGTH filed in ADMA2's descriptor */ -#define USDHC_ADMA2_LENGTH_ALIGN (4U) - -/* ADMA1 descriptor table - * |------------------------|---------|--------------------------| - * | Address/page field |Reserved | Attribute | - * |------------------------|---------|--------------------------| - * |31 12|11 6|05 |04 |03|02 |01 |00 | - * |------------------------|---------|----|----|--|---|---|-----| - * | address or data length | 000000 |Act2|Act1| 0|Int|End|Valid| - * |------------------------|---------|----|----|--|---|---|-----| - * - * - * |------|------|-----------------|-------|-------------| - * | Act2 | Act1 | Comment | 31-28 | 27 - 12 | - * |------|------|-----------------|---------------------| - * | 0 | 0 | No op | Don't care | - * |------|------|-----------------|-------|-------------| - * | 0 | 1 | Set data length | 0000 | Data Length | - * |------|------|-----------------|-------|-------------| - * | 1 | 0 | Transfer data | Data address | - * |------|------|-----------------|---------------------| - * | 1 | 1 | Link descriptor | Descriptor address | - * |------|------|-----------------|---------------------| - */ -/*! @brief The bit shift for ADDRESS filed in ADMA1's descriptor */ -#define USDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT (12U) -/*! @brief The bit mask for ADDRESS field in ADMA1's descriptor */ -#define USDHC_ADMA1_DESCRIPTOR_ADDRESS_MASK (0xFFFFFU) -/*! @brief The bit shift for LENGTH filed in ADMA1's descriptor */ -#define USDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT (12U) -/*! @brief The mask for LENGTH field in ADMA1's descriptor */ -#define USDHC_ADMA1_DESCRIPTOR_LENGTH_MASK (0xFFFFU) -/*! @brief The maximum value of LENGTH filed in ADMA1's descriptor */ -#define USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (USDHC_ADMA1_DESCRIPTOR_LENGTH_MASK - 3U) - -/*! @brief The mask for the control/status field in ADMA1 descriptor */ -enum _usdhc_adma1_descriptor_flag -{ - kUSDHC_Adma1DescriptorValidFlag = (1U << 0U), /*!< Valid flag */ - kUSDHC_Adma1DescriptorEndFlag = (1U << 1U), /*!< End flag */ - kUSDHC_Adma1DescriptorInterrupFlag = (1U << 2U), /*!< Interrupt flag */ - kUSDHC_Adma1DescriptorActivity1Flag = (1U << 4U), /*!< Activity 1 flag */ - kUSDHC_Adma1DescriptorActivity2Flag = (1U << 5U), /*!< Activity 2 flag */ - kUSDHC_Adma1DescriptorTypeNop = (kUSDHC_Adma1DescriptorValidFlag), /*!< No operation */ - kUSDHC_Adma1DescriptorTypeTransfer = - (kUSDHC_Adma1DescriptorActivity2Flag | kUSDHC_Adma1DescriptorValidFlag), /*!< Transfer data */ - kUSDHC_Adma1DescriptorTypeLink = (kUSDHC_Adma1DescriptorActivity1Flag | kUSDHC_Adma1DescriptorActivity2Flag | - kUSDHC_Adma1DescriptorValidFlag), /*!< Link descriptor */ - kUSDHC_Adma1DescriptorTypeSetLength = - (kUSDHC_Adma1DescriptorActivity1Flag | kUSDHC_Adma1DescriptorValidFlag), /*!< Set data length */ -}; - -/* ADMA2 descriptor table - * |----------------|---------------|-------------|--------------------------| - * | Address field | Length | Reserved | Attribute | - * |----------------|---------------|-------------|--------------------------| - * |63 32|31 16|15 06|05 |04 |03|02 |01 |00 | - * |----------------|---------------|-------------|----|----|--|---|---|-----| - * | 32-bit address | 16-bit length | 0000000000 |Act2|Act1| 0|Int|End|Valid| - * |----------------|---------------|-------------|----|----|--|---|---|-----| - * - * - * | Act2 | Act1 | Comment | Operation | - * |------|------|-----------------|-------------------------------------------------------------------| - * | 0 | 0 | No op | Don't care | - * |------|------|-----------------|-------------------------------------------------------------------| - * | 0 | 1 | Reserved | Read this line and go to next one | - * |------|------|-----------------|-------------------------------------------------------------------| - * | 1 | 0 | Transfer data | Transfer data with address and length set in this descriptor line | - * |------|------|-----------------|-------------------------------------------------------------------| - * | 1 | 1 | Link descriptor | Link to another descriptor | - * |------|------|-----------------|-------------------------------------------------------------------| - */ -/*! @brief The bit shift for LENGTH field in ADMA2's descriptor */ -#define USDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT (16U) -/*! @brief The bit mask for LENGTH field in ADMA2's descriptor */ -#define USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK (0xFFFFU) -/*! @brief The maximum value of LENGTH field in ADMA2's descriptor */ -#define USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK - 3U) - -/*! @brief ADMA1 descriptor control and status mask */ -enum _usdhc_adma2_descriptor_flag -{ - kUSDHC_Adma2DescriptorValidFlag = (1U << 0U), /*!< Valid flag */ - kUSDHC_Adma2DescriptorEndFlag = (1U << 1U), /*!< End flag */ - kUSDHC_Adma2DescriptorInterruptFlag = (1U << 2U), /*!< Interrupt flag */ - kUSDHC_Adma2DescriptorActivity1Flag = (1U << 4U), /*!< Activity 1 mask */ - kUSDHC_Adma2DescriptorActivity2Flag = (1U << 5U), /*!< Activity 2 mask */ - - kUSDHC_Adma2DescriptorTypeNop = (kUSDHC_Adma2DescriptorValidFlag), /*!< No operation */ - kUSDHC_Adma2DescriptorTypeReserved = - (kUSDHC_Adma2DescriptorActivity1Flag | kUSDHC_Adma2DescriptorValidFlag), /*!< Reserved */ - kUSDHC_Adma2DescriptorTypeTransfer = - (kUSDHC_Adma2DescriptorActivity2Flag | kUSDHC_Adma2DescriptorValidFlag), /*!< Transfer type */ - kUSDHC_Adma2DescriptorTypeLink = (kUSDHC_Adma2DescriptorActivity1Flag | kUSDHC_Adma2DescriptorActivity2Flag | - kUSDHC_Adma2DescriptorValidFlag), /*!< Link type */ -}; - -/*! @brief ADMA descriptor configuration flag */ -enum _usdhc_adma_flag -{ - kUSDHC_AdmaDescriptorSingleFlag = - 0U, /*!< try to finish the transfer in a single ADMA descriptor, if transfer size is bigger than one - ADMA descriptor's ability, new another descriptor for data transfer */ - kUSDHC_AdmaDescriptorMultipleFlag = 1U, /*!< create multiple ADMA descriptor within the ADMA table, this is used for - mmc boot mode specifically, which need - to modify the ADMA descriptor on the fly, so the flag should be used - combine with stop at block gap feature */ -}; - -/*! @brief dma transfer burst len config. */ -typedef enum _usdhc_burst_len -{ - kUSDHC_EnBurstLenForINCR = 0x01U, /*!< enable burst len for INCR */ - kUSDHC_EnBurstLenForINCR4816 = 0x02U, /*!< enable burst len for INCR4/INCR8/INCR16 */ - kUSDHC_EnBurstLenForINCR4816WRAP = 0x04U, /*!< enable burst len for INCR4/8/16 WRAP */ -} usdhc_burst_len_t; - -/*! @brief transfer data type definition. */ -enum _usdhc_transfer_data_type -{ - kUSDHC_TransferDataNormal = 0U, /*!< transfer normal read/write data */ - kUSDHC_TransferDataTuning = 1U, /*!< transfer tuning data */ - kUSDHC_TransferDataBoot = 2U, /*!< transfer boot data */ - kUSDHC_TransferDataBootcontinous = 3U, /*!< transfer boot data continous */ -}; - -/*! @brief Defines the adma1 descriptor structure. */ -typedef uint32_t usdhc_adma1_descriptor_t; - -/*! @brief Defines the ADMA2 descriptor structure. */ -typedef struct _usdhc_adma2_descriptor -{ - uint32_t attribute; /*!< The control and status field */ - const uint32_t *address; /*!< The address field */ -} usdhc_adma2_descriptor_t; - -/*! - * @brief USDHC capability information. - * - * Defines a structure to save the capability information of USDHC. - */ -typedef struct _usdhc_capability -{ - uint32_t sdVersion; /*!< support SD card/sdio version */ - uint32_t mmcVersion; /*!< support emmc card version */ - uint32_t maxBlockLength; /*!< Maximum block length united as byte */ - uint32_t maxBlockCount; /*!< Maximum block count can be set one time */ - uint32_t flags; /*!< Capability flags to indicate the support information(_usdhc_capability_flag) */ -} usdhc_capability_t; - -/*! @brief Data structure to configure the MMC boot feature */ -typedef struct _usdhc_boot_config -{ - uint32_t ackTimeoutCount; /*!< Timeout value for the boot ACK. The available range is 0 ~ 15. */ - usdhc_boot_mode_t bootMode; /*!< Boot mode selection. */ - uint32_t blockCount; /*!< Stop at block gap value of automatic mode. Available range is 0 ~ 65535. */ - size_t blockSize; /*!< Block size */ - bool enableBootAck; /*!< Enable or disable boot ACK */ - bool enableAutoStopAtBlockGap; /*!< Enable or disable auto stop at block gap function in boot period */ -} usdhc_boot_config_t; - -/*! @brief Data structure to initialize the USDHC */ -typedef struct _usdhc_config -{ - uint32_t dataTimeout; /*!< Data timeout value */ - usdhc_endian_mode_t endianMode; /*!< Endian mode */ - uint8_t readWatermarkLevel; /*!< Watermark level for DMA read operation. Available range is 1 ~ 128. */ - uint8_t writeWatermarkLevel; /*!< Watermark level for DMA write operation. Available range is 1 ~ 128. */ - uint8_t readBurstLen; /*!< Read burst len */ - uint8_t writeBurstLen; /*!< Write burst len */ -} usdhc_config_t; - -/*! - * @brief Card data descriptor - * - * Defines a structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card - * driver - * want to ignore the error event to read/write all the data not to stop read/write immediately when error event - * happen for example bus testing procedure for MMC card. - */ -typedef struct _usdhc_data -{ - bool enableAutoCommand12; /*!< Enable auto CMD12 */ - bool enableAutoCommand23; /*!< Enable auto CMD23 */ - bool enableIgnoreError; /*!< Enable to ignore error event to read/write all the data */ - uint8_t dataType; /*!< this is used to distinguish the normal/tuning/boot data */ - size_t blockSize; /*!< Block size */ - uint32_t blockCount; /*!< Block count */ - uint32_t *rxData; /*!< Buffer to save data read */ - const uint32_t *txData; /*!< Data buffer to write */ -} usdhc_data_t; - -/*! - * @brief Card command descriptor - * - * Define card command-related attribute. - */ -typedef struct _usdhc_command -{ - uint32_t index; /*!< Command index */ - uint32_t argument; /*!< Command argument */ - usdhc_card_command_type_t type; /*!< Command type */ - usdhc_card_response_type_t responseType; /*!< Command response type */ - uint32_t response[4U]; /*!< Response for this command */ - uint32_t responseErrorFlags; /*!< response error flag, the flag which need to check - the command reponse*/ - uint32_t flags; /*!< Cmd flags */ -} usdhc_command_t; - -/*! @brief ADMA configuration */ -typedef struct _usdhc_adma_config -{ - usdhc_dma_mode_t dmaMode; /*!< DMA mode */ - - usdhc_burst_len_t burstLen; /*!< burst len config */ - - uint32_t *admaTable; /*!< ADMA table address, can't be null if transfer way is ADMA1/ADMA2 */ - uint32_t admaTableWords; /*!< ADMA table length united as words, can't be 0 if transfer way is ADMA1/ADMA2 */ -} usdhc_adma_config_t; - -/*! @brief Transfer state */ -typedef struct _usdhc_transfer -{ - usdhc_data_t *data; /*!< Data to transfer */ - usdhc_command_t *command; /*!< Command to send */ -} usdhc_transfer_t; - -/*! @brief USDHC handle typedef */ -typedef struct _usdhc_handle usdhc_handle_t; - -/*! @brief USDHC callback functions. */ -typedef struct _usdhc_transfer_callback -{ - void (*CardInserted)(USDHC_Type *base, - void *userData); /*!< Card inserted occurs when DAT3/CD pin is for card detect */ - void (*CardRemoved)(USDHC_Type *base, void *userData); /*!< Card removed occurs */ - void (*SdioInterrupt)(USDHC_Type *base, void *userData); /*!< SDIO card interrupt occurs */ - void (*BlockGap)(USDHC_Type *base, void *userData); /*!< stopped at block gap event */ - void (*TransferComplete)(USDHC_Type *base, - usdhc_handle_t *handle, - status_t status, - void *userData); /*!< Transfer complete callback */ - void (*ReTuning)(USDHC_Type *base, void *userData); /*!< handle the re-tuning */ -} usdhc_transfer_callback_t; - -/*! - * @brief USDHC handle - * - * Defines the structure to save the USDHC state information and callback function. The detailed interrupt status when - * sending a command or transfering data can be obtained from the interruptFlags field by using the mask defined in - * usdhc_interrupt_flag_t. - * - * @note All the fields except interruptFlags and transferredWords must be allocated by the user. - */ -struct _usdhc_handle -{ - /* Transfer parameter */ - usdhc_data_t *volatile data; /*!< Data to transfer */ - usdhc_command_t *volatile command; /*!< Command to send */ - - /* Transfer status */ - volatile uint32_t interruptFlags; /*!< Interrupt flags of last transaction */ - volatile uint32_t transferredWords; /*!< Words transferred by DATAPORT way */ - - /* Callback functions */ - usdhc_transfer_callback_t callback; /*!< Callback function */ - void *userData; /*!< Parameter for transfer complete callback */ -}; - -/*! @brief USDHC transfer function. */ -typedef status_t (*usdhc_transfer_function_t)(USDHC_Type *base, usdhc_transfer_t *content); - -/*! @brief USDHC host descriptor */ -typedef struct _usdhc_host -{ - USDHC_Type *base; /*!< USDHC peripheral base address */ - uint32_t sourceClock_Hz; /*!< USDHC source clock frequency united in Hz */ - usdhc_config_t config; /*!< USDHC configuration */ - usdhc_capability_t capability; /*!< USDHC capability information */ - usdhc_transfer_function_t transfer; /*!< USDHC transfer function */ -} usdhc_host_t; - -/************************************************************************************************* - * API - ************************************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @name Initialization and deinitialization - * @{ - */ - -/*! - * @brief USDHC module initialization function. - * - * Configures the USDHC according to the user configuration. - * - * Example: - @code - usdhc_config_t config; - config.cardDetectDat3 = false; - config.endianMode = kUSDHC_EndianModeLittle; - config.dmaMode = kUSDHC_DmaModeAdma2; - config.readWatermarkLevel = 128U; - config.writeWatermarkLevel = 128U; - USDHC_Init(USDHC, &config); - @endcode - * - * @param base USDHC peripheral base address. - * @param config USDHC configuration information. - * @retval kStatus_Success Operate successfully. - */ -void USDHC_Init(USDHC_Type *base, const usdhc_config_t *config); - -/*! - * @brief Deinitializes the USDHC. - * - * @param base USDHC peripheral base address. - */ -void USDHC_Deinit(USDHC_Type *base); - -/*! - * @brief Resets the USDHC. - * - * @param base USDHC peripheral base address. - * @param mask The reset type mask(_usdhc_reset). - * @param timeout Timeout for reset. - * @retval true Reset successfully. - * @retval false Reset failed. - */ -bool USDHC_Reset(USDHC_Type *base, uint32_t mask, uint32_t timeout); - -/* @} */ - -/*! - * @name DMA Control - * @{ - */ - -/*! - * @brief Sets the DMA descriptor table configuration. - * A high level DMA descriptor configuration function. - * @param base USDHC peripheral base address. - * @param adma configuration - * @param data Data descriptor - * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please - * reference _usdhc_adma_flag - * @retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * @retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetAdmaTableConfig(USDHC_Type *base, - usdhc_adma_config_t *dmaConfig, - usdhc_data_t *dataConfig, - uint32_t flags); - -/*! - * @brief Internal DMA configuration. - * This function is used to config the USDHC DMA related registers. - * @param base USDHC peripheral base address. - * @param adma configuration - * @param dataAddr tranfer data address, a simple DMA parameter, if ADMA is used, leave it to NULL. - * @param enAutoCmd23 flag to indicate Auto CMD23 is enable or not, a simple DMA parameter,if ADMA is used, leave it to - * false. - * @retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * @retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetInternalDmaConfig(USDHC_Type *base, - usdhc_adma_config_t *dmaConfig, - const uint32_t *dataAddr, - bool enAutoCmd23); - -/*! - * @brief Sets the ADMA2 descriptor table configuration. - * - * @param admaTable Adma table address. - * @param admaTableWords Adma table length. - * @param dataBufferAddr Data buffer address. - * @param dataBytes Data Data length. - * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please - * reference _usdhc_adma_flag. - * @retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * @retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetADMA2Descriptor( - uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags); - -/*! - * @brief Sets the ADMA1 descriptor table configuration. - * - * @param admaTable Adma table address. - * @param admaTableWords Adma table length. - * @param dataBufferAddr Data buffer address. - * @param dataBytes Data length. - * @param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please - * reference _usdhc_adma_flag. - * @retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * @retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetADMA1Descriptor( - uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags); - -/*! - * @brief enable internal DMA. - * - * @param base USDHC peripheral base address. - * @param enable enable or disable flag - */ -static inline void USDHC_EnableInternalDMA(USDHC_Type *base, bool enable) -{ - if (enable) - { - base->MIX_CTRL |= USDHC_MIX_CTRL_DMAEN_MASK; - } - else - { - base->MIX_CTRL &= ~USDHC_MIX_CTRL_DMAEN_MASK; - base->PROT_CTRL &= ~USDHC_PROT_CTRL_DMASEL_MASK; - } -} - -/* @} */ - -/*! - * @name Interrupts - * @{ - */ - -/*! - * @brief Enables the interrupt status. - * - * @param base USDHC peripheral base address. - * @param mask Interrupt status flags mask(_usdhc_interrupt_status_flag). - */ -static inline void USDHC_EnableInterruptStatus(USDHC_Type *base, uint32_t mask) -{ - base->INT_STATUS_EN |= mask; -} - -/*! - * @brief Disables the interrupt status. - * - * @param base USDHC peripheral base address. - * @param mask The interrupt status flags mask(_usdhc_interrupt_status_flag). - */ -static inline void USDHC_DisableInterruptStatus(USDHC_Type *base, uint32_t mask) -{ - base->INT_STATUS_EN &= ~mask; -} - -/*! - * @brief Enables the interrupt signal corresponding to the interrupt status flag. - * - * @param base USDHC peripheral base address. - * @param mask The interrupt status flags mask(_usdhc_interrupt_status_flag). - */ -static inline void USDHC_EnableInterruptSignal(USDHC_Type *base, uint32_t mask) -{ - base->INT_SIGNAL_EN |= mask; -} - -/*! - * @brief Disables the interrupt signal corresponding to the interrupt status flag. - * - * @param base USDHC peripheral base address. - * @param mask The interrupt status flags mask(_usdhc_interrupt_status_flag). - */ -static inline void USDHC_DisableInterruptSignal(USDHC_Type *base, uint32_t mask) -{ - base->INT_SIGNAL_EN &= ~mask; -} - -/* @} */ - -/*! - * @name Status - * @{ - */ - -/*! - * @brief Gets the current interrupt status. - * - * @param base USDHC peripheral base address. - * @return Current interrupt status flags mask(_usdhc_interrupt_status_flag). - */ -static inline uint32_t USDHC_GetInterruptStatusFlags(USDHC_Type *base) -{ - return base->INT_STATUS; -} - -/*! - * @brief Clears a specified interrupt status. - * write 1 clears - * @param base USDHC peripheral base address. - * @param mask The interrupt status flags mask(_usdhc_interrupt_status_flag). - */ -static inline void USDHC_ClearInterruptStatusFlags(USDHC_Type *base, uint32_t mask) -{ - base->INT_STATUS = mask; -} - -/*! - * @brief Gets the status of auto command 12 error. - * - * @param base USDHC peripheral base address. - * @return Auto command 12 error status flags mask(_usdhc_auto_command12_error_status_flag). - */ -static inline uint32_t USDHC_GetAutoCommand12ErrorStatusFlags(USDHC_Type *base) -{ - return base->AUTOCMD12_ERR_STATUS; -} - -/*! - * @brief Gets the status of the ADMA error. - * - * @param base USDHC peripheral base address. - * @return ADMA error status flags mask(_usdhc_adma_error_status_flag). - */ -static inline uint32_t USDHC_GetAdmaErrorStatusFlags(USDHC_Type *base) -{ - return base->ADMA_ERR_STATUS & 0xFU; -} - -/*! - * @brief Gets a present status. - * - * This function gets the present USDHC's status except for an interrupt status and an error status. - * - * @param base USDHC peripheral base address. - * @return Present USDHC's status flags mask(_usdhc_present_status_flag). - */ -static inline uint32_t USDHC_GetPresentStatusFlags(USDHC_Type *base) -{ - return base->PRES_STATE; -} - -/* @} */ - -/*! - * @name Bus Operations - * @{ - */ - -/*! - * @brief Gets the capability information. - * - * @param base USDHC peripheral base address. - * @param capability Structure to save capability information. - */ -void USDHC_GetCapability(USDHC_Type *base, usdhc_capability_t *capability); - -/*! - * @brief force the card clock on. - * - * @param base USDHC peripheral base address. - * @param enable/disable flag. - */ -static inline void USDHC_ForceClockOn(USDHC_Type *base, bool enable) -{ - if (enable) - { - base->VEND_SPEC |= USDHC_VEND_SPEC_FRC_SDCLK_ON_MASK; - } - else - { - base->VEND_SPEC &= ~USDHC_VEND_SPEC_FRC_SDCLK_ON_MASK; - } -} - -/*! - * @brief Sets the SD bus clock frequency. - * - * @param base USDHC peripheral base address. - * @param srcClock_Hz USDHC source clock frequency united in Hz. - * @param busClock_Hz SD bus clock frequency united in Hz. - * - * @return The nearest frequency of busClock_Hz configured to SD bus. - */ -uint32_t USDHC_SetSdClock(USDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz); - -/*! - * @brief Sends 80 clocks to the card to set it to the active state. - * - * This function must be called each time the card is inserted to ensure that the card can receive the command - * correctly. - * - * @param base USDHC peripheral base address. - * @param timeout Timeout to initialize card. - * @retval true Set card active successfully. - * @retval false Set card active failed. - */ -bool USDHC_SetCardActive(USDHC_Type *base, uint32_t timeout); - -/*! - * @brief trigger a hardware reset. - * - * @param base USDHC peripheral base address. - * @param 1 or 0 level - */ -static inline void USDHC_AssertHardwareReset(USDHC_Type *base, bool high) -{ - if (high) - { - base->SYS_CTRL |= USDHC_SYS_CTRL_IPP_RST_N_MASK; - } - else - { - base->SYS_CTRL &= ~USDHC_SYS_CTRL_IPP_RST_N_MASK; - } -} - -/*! - * @brief Sets the data transfer width. - * - * @param base USDHC peripheral base address. - * @param width Data transfer width. - */ -static inline void USDHC_SetDataBusWidth(USDHC_Type *base, usdhc_data_bus_width_t width) -{ - base->PROT_CTRL = ((base->PROT_CTRL & ~USDHC_PROT_CTRL_DTW_MASK) | USDHC_PROT_CTRL_DTW(width)); -} - -/*! - * @brief Fills the data port. - * - * This function is used to implement the data transfer by Data Port instead of DMA. - * - * @param base USDHC peripheral base address. - * @param data The data about to be sent. - */ -static inline void USDHC_WriteData(USDHC_Type *base, uint32_t data) -{ - base->DATA_BUFF_ACC_PORT = data; -} - -/*! - * @brief Retrieves the data from the data port. - * - * This function is used to implement the data transfer by Data Port instead of DMA. - * - * @param base USDHC peripheral base address. - * @return The data has been read. - */ -static inline uint32_t USDHC_ReadData(USDHC_Type *base) -{ - return base->DATA_BUFF_ACC_PORT; -} - -/*! -* @brief send command function -* -* @param base USDHC peripheral base address. -* @param command configuration -*/ -void USDHC_SendCommand(USDHC_Type *base, usdhc_command_t *command); - -/*! - * @brief Enables or disables a wakeup event in low-power mode. - * - * @param base USDHC peripheral base address. - * @param mask Wakeup events mask(_usdhc_wakeup_event). - * @param enable True to enable, false to disable. - */ -static inline void USDHC_EnableWakeupEvent(USDHC_Type *base, uint32_t mask, bool enable) -{ - if (enable) - { - base->PROT_CTRL |= mask; - } - else - { - base->PROT_CTRL &= ~mask; - } -} - -/*! - * @brief detect card insert status. - * - * @param base USDHC peripheral base address. - * @param enable/disable flag - */ -static inline void USDHC_CardDetectByData3(USDHC_Type *base, bool enable) -{ - if (enable) - { - base->PROT_CTRL |= USDHC_PROT_CTRL_D3CD_MASK; - } - else - { - base->PROT_CTRL &= ~USDHC_PROT_CTRL_D3CD_MASK; - } -} - -/*! - * @brief detect card insert status. - * - * @param base USDHC peripheral base address. - */ -static inline bool USDHC_DetectCardInsert(USDHC_Type *base) -{ - return (base->PRES_STATE & kUSDHC_CardInsertedFlag) ? true : false; -} - -/*! - * @brief Enables or disables the SDIO card control. - * - * @param base USDHC peripheral base address. - * @param mask SDIO card control flags mask(_usdhc_sdio_control_flag). - * @param enable True to enable, false to disable. - */ -static inline void USDHC_EnableSdioControl(USDHC_Type *base, uint32_t mask, bool enable) -{ - if (enable) - { - base->PROT_CTRL |= mask; - } - else - { - base->PROT_CTRL &= ~mask; - } -} - -/*! - * @brief Restarts a transaction which has stopped at the block GAP for the SDIO card. - * - * @param base USDHC peripheral base address. - */ -static inline void USDHC_SetContinueRequest(USDHC_Type *base) -{ - base->PROT_CTRL |= USDHC_PROT_CTRL_CREQ_MASK; -} - -/*! - * @brief Request stop at block gap function. - * - * @param base USDHC peripheral base address. - * @param enable true to stop at block gap, false to normal transfer - */ -static inline void USDHC_RequestStopAtBlockGap(USDHC_Type *base, bool enable) -{ - if (enable) - { - base->PROT_CTRL |= USDHC_PROT_CTRL_SABGREQ_MASK; - } - else - { - base->PROT_CTRL &= ~USDHC_PROT_CTRL_SABGREQ_MASK; - } -} - -/*! - * @brief Configures the MMC boot feature. - * - * Example: - @code - usdhc_boot_config_t config; - config.ackTimeoutCount = 4; - config.bootMode = kUSDHC_BootModeNormal; - config.blockCount = 5; - config.enableBootAck = true; - config.enableBoot = true; - config.enableAutoStopAtBlockGap = true; - USDHC_SetMmcBootConfig(USDHC, &config); - @endcode - * - * @param base USDHC peripheral base address. - * @param config The MMC boot configuration information. - */ -void USDHC_SetMmcBootConfig(USDHC_Type *base, const usdhc_boot_config_t *config); - -/*! - * @brief Enables or disables the mmc boot mode. - * - * @param base USDHC peripheral base address. - * @param enable True to enable, false to disable. - */ -static inline void USDHC_EnableMmcBoot(USDHC_Type *base, bool enable) -{ - if (enable) - { - base->MMC_BOOT |= USDHC_MMC_BOOT_BOOT_EN_MASK; - } - else - { - base->MMC_BOOT &= ~USDHC_MMC_BOOT_BOOT_EN_MASK; - } -} - -/*! - * @brief Forces generating events according to the given mask. - * - * @param base USDHC peripheral base address. - * @param mask The force events bit posistion (_usdhc_force_event). - */ -static inline void USDHC_SetForceEvent(USDHC_Type *base, uint32_t mask) -{ - base->FORCE_EVENT = mask; -} - -/*! - * @brief select the usdhc output voltage - * - * @param base USDHC peripheral base address. - * @param true 1.8V, false 3.0V - */ -static inline void UDSHC_SelectVoltage(USDHC_Type *base, bool en18v) -{ - if (en18v) - { - base->VEND_SPEC |= USDHC_VEND_SPEC_VSELECT_MASK; - } - else - { - base->VEND_SPEC &= ~USDHC_VEND_SPEC_VSELECT_MASK; - } -} - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) -/*! -* @brief check the SDR50 mode request tuning bit -* When this bit set, user should call USDHC_StandardTuning function -* @param base USDHC peripheral base address. -*/ -static inline bool USDHC_RequestTuningForSDR50(USDHC_Type *base) -{ - return base->HOST_CTRL_CAP & USDHC_HOST_CTRL_CAP_USE_TUNING_SDR50_MASK ? true : false; -} - -/*! - * @brief check the request re-tuning bit - * When this bit is set, user should do manual tuning or standard tuning function - * @param base USDHC peripheral base address. - */ -static inline bool USDHC_RequestReTuning(USDHC_Type *base) -{ - return base->PRES_STATE & USDHC_PRES_STATE_RTR_MASK ? true : false; -} - -/*! - * @brief the SDR104 mode auto tuning enable and disable - * This function should call after tuning function execute pass, auto tuning will handle - * by hardware - * @param base USDHC peripheral base address. - * @param enable/disable flag - */ -static inline void USDHC_EnableAutoTuning(USDHC_Type *base, bool enable) -{ - if (enable) - { - base->MIX_CTRL |= USDHC_MIX_CTRL_AUTO_TUNE_EN_MASK; - } - else - { - base->MIX_CTRL &= ~USDHC_MIX_CTRL_AUTO_TUNE_EN_MASK; - } -} - -/*! - * @brief the config the re-tuning timer for mode 1 and mode 3 - * This timer is used for standard tuning auto re-tuning, - * @param base USDHC peripheral base address. - * @param timer counter value - */ -static inline void USDHC_SetRetuningTimer(USDHC_Type *base, uint32_t counter) -{ - base->HOST_CTRL_CAP &= ~USDHC_HOST_CTRL_CAP_TIME_COUNT_RETUNING_MASK; - base->HOST_CTRL_CAP |= USDHC_HOST_CTRL_CAP_TIME_COUNT_RETUNING(counter); -} - -/*! - * @brief the auto tuning enbale for CMD/DATA line - * - * @param base USDHC peripheral base address. - */ -void USDHC_EnableAutoTuningForCmdAndData(USDHC_Type *base); - -/*! - * @brief manual tuning trigger or abort - * User should handle the tuning cmd and find the boundary of the delay - * then calucate a average value which will be config to the CLK_TUNE_CTRL_STATUS - * This function should called before USDHC_AdjustDelayforSDR104 function - * @param base USDHC peripheral base address. - * @param tuning enable flag - */ -void USDHC_EnableManualTuning(USDHC_Type *base, bool enable); - -/*! - * @brief the SDR104 mode delay setting adjust - * This function should called after USDHC_ManualTuningForSDR104 - * @param base USDHC peripheral base address. - * @param delay setting configuration - * @retval kStatus_Fail config the delay setting fail - * @retval kStatus_Success config the delay setting success - */ -status_t USDHC_AdjustDelayForManualTuning(USDHC_Type *base, uint32_t delay); - -/*! - * @brief the enable standard tuning function - * The standard tuning window and tuning counter use the default config - * tuning cmd is send by the software, user need to check the tuning result - * can be used for SDR50,SDR104,HS200 mode tuning - * @param base USDHC peripheral base address. - * @param tuning start tap - * @param tuning step - * @param enable/disable flag - */ -void USDHC_EnableStandardTuning(USDHC_Type *base, uint32_t tuningStartTap, uint32_t step, bool enable); - -/*! - * @brief Get execute std tuning status - * - * @param base USDHC peripheral base address. - */ -static inline uint32_t USDHC_GetExecuteStdTuningStatus(USDHC_Type *base) -{ - return (base->AUTOCMD12_ERR_STATUS & USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK); -} - -/*! - * @brief check std tuning result - * - * @param base USDHC peripheral base address. - */ -static inline uint32_t USDHC_CheckStdTuningResult(USDHC_Type *base) -{ - return (base->AUTOCMD12_ERR_STATUS & USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK); -} - -/*! - * @brief check tuning error - * - * @param base USDHC peripheral base address. - */ -static inline uint32_t USDHC_CheckTuningError(USDHC_Type *base) -{ - return (base->CLK_TUNE_CTRL_STATUS & - (USDHC_CLK_TUNE_CTRL_STATUS_NXT_ERR_MASK | USDHC_CLK_TUNE_CTRL_STATUS_PRE_ERR_MASK)); -} - -#endif -/*! - * @brief the enable/disable DDR mode - * - * @param base USDHC peripheral base address. - * @param enable/disable flag - * @param nibble position - */ -void USDHC_EnableDDRMode(USDHC_Type *base, bool enable, uint32_t nibblePos); - -/*! - * @brief the enable/disable HS400 mode - * - * @param base USDHC peripheral base address. - * @param enable/disable flag - */ -#if FSL_FEATURE_USDHC_HAS_HS400_MODE -static inline void USDHC_EnableHS400Mode(USDHC_Type *base, bool enable) -{ - if (enable) - { - base->MIX_CTRL |= USDHC_MIX_CTRL_HS400_MODE_MASK; - } - else - { - base->MIX_CTRL &= ~USDHC_MIX_CTRL_HS400_MODE_MASK; - } -} - -/*! - * @brief reset the strobe DLL - * - * @param base USDHC peripheral base address. - */ -static inline void USDHC_ResetStrobeDLL(USDHC_Type *base) -{ - base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_RESET_MASK; -} - -/*! - * @brief enable/disable the strobe DLL - * - * @param base USDHC peripheral base address. - * @param enable/disable flag - */ -static inline void USDHC_EnableStrobeDLL(USDHC_Type *base, bool enable) -{ - if (enable) - { - base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK; - } - else - { - base->STROBE_DLL_CTRL &= ~USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK; - } -} - -/*! - * @brief config the strobe DLL delay target and update interval - * - * @param base USDHC peripheral base address. - * @param delay target - * @param update interval - */ -static inline void USDHC_ConfigStrobeDLL(USDHC_Type *base, uint32_t delayTarget, uint32_t updateInterval) -{ - base->STROBE_DLL_CTRL &= (USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_UPDATE_INT_MASK | - USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_DLY_TARGET_MASK); - - base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_UPDATE_INT(updateInterval) | - USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_DLY_TARGET(delayTarget); -} - -/*! - * @brief get the strobe DLL status - * - * @param base USDHC peripheral base address. - */ -static inline uint32_t USDHC_GetStrobeDLLStatus(USDHC_Type *base) -{ - return base->STROBE_DLL_STATUS; -} - -#endif - -/* @} */ - -/*! - * @name Transactional - * @{ - */ - -/*! - * @brief Transfers the command/data using a blocking method. - * - * This function waits until the command response/data is received or the USDHC encounters an error by polling the - * status - * flag. - * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support - * the re-entry mechanism. - * - * @note There is no need to call the API 'USDHC_TransferCreateHandle' when calling this API. - * - * @param base USDHC peripheral base address. - * @param adma configuration - * @param transfer Transfer content. - * @retval kStatus_InvalidArgument Argument is invalid. - * @retval kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. - * @retval kStatus_USDHC_SendCommandFailed Send command failed. - * @retval kStatus_USDHC_TransferDataFailed Transfer data failed. - * @retval kStatus_Success Operate successfully. - */ -status_t USDHC_TransferBlocking(USDHC_Type *base, usdhc_adma_config_t *dmaConfig, usdhc_transfer_t *transfer); - -/*! - * @brief Creates the USDHC handle. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle pointer. - * @param callback Structure pointer to contain all callback functions. - * @param userData Callback function parameter. - */ -void USDHC_TransferCreateHandle(USDHC_Type *base, - usdhc_handle_t *handle, - const usdhc_transfer_callback_t *callback, - void *userData); - -/*! - * @brief Transfers the command/data using an interrupt and an asynchronous method. - * - * This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an - * error. - * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support - * the re-entry mechanism. - * - * @note Call the API 'USDHC_TransferCreateHandle' when calling this API. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - * @param adma configuration. - * @param transfer Transfer content. - * @retval kStatus_InvalidArgument Argument is invalid. - * @retval kStatus_USDHC_BusyTransferring Busy transferring. - * @retval kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. - * @retval kStatus_Success Operate successfully. - */ -status_t USDHC_TransferNonBlocking(USDHC_Type *base, - usdhc_handle_t *handle, - usdhc_adma_config_t *dmaConfig, - usdhc_transfer_t *transfer); - -/*! - * @brief IRQ handler for the USDHC. - * - * This function deals with the IRQs on the given host controller. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - */ -void USDHC_TransferHandleIRQ(USDHC_Type *base, usdhc_handle_t *handle); - -/* @} */ - -#if defined(__cplusplus) -} -#endif -/*! @} */ - -#endif /* _FSL_USDHC_H_*/ diff --git a/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sd.h b/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sd.h deleted file mode 100644 index a328835b5e..0000000000 --- a/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sd.h +++ /dev/null @@ -1,321 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2018 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#ifndef _FSL_SD_H_ -#define _FSL_SD_H_ - -#include "fsl_sdmmc_common.h" -/*! - * @addtogroup SDCARD - * @{ - */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ -/*! @brief SD card flags */ -enum _sd_card_flag -{ - kSD_SupportHighCapacityFlag = (1U << 1U), /*!< Support high capacity */ - kSD_Support4BitWidthFlag = (1U << 2U), /*!< Support 4-bit data width */ - kSD_SupportSdhcFlag = (1U << 3U), /*!< Card is SDHC */ - kSD_SupportSdxcFlag = (1U << 4U), /*!< Card is SDXC */ - kSD_SupportVoltage180v = (1U << 5U), /*!< card support 1.8v voltage*/ - kSD_SupportSetBlockCountCmd = (1U << 6U), /*!< card support cmd23 flag*/ - kSD_SupportSpeedClassControlCmd = (1U << 7U), /*!< card support speed class control flag */ -}; - -/*! @brief card user parameter, user can define the parameter according the board, card capability */ -typedef struct _sdcard_usr_param -{ - const sdmmchost_detect_card_t *cd; /*!< card detect type */ - const sdmmchost_pwr_card_t *pwr; /*!< power control configuration */ -} sdcard_usr_param_t; - -/*! - * @brief SD card state - * - * Define the card structure including the necessary fields to identify and describe the card. - */ -typedef struct _sd_card -{ - SDMMCHOST_CONFIG host; /*!< Host information */ - - sdcard_usr_param_t usrParam; /*!< user parameter */ - bool isHostReady; /*!< use this flag to indicate if need host re-init or not*/ - bool noInteralAlign; /*!< use this flag to disable sdmmc align. If disable, sdmmc will not make sure the - data buffer address is word align, otherwise all the transfer are align to low level driver */ - uint32_t busClock_Hz; /*!< SD bus clock frequency united in Hz */ - uint32_t relativeAddress; /*!< Relative address of the card */ - uint32_t version; /*!< Card version */ - uint32_t flags; /*!< Flags in _sd_card_flag */ - uint32_t rawCid[4U]; /*!< Raw CID content */ - uint32_t rawCsd[4U]; /*!< Raw CSD content */ - uint32_t rawScr[2U]; /*!< Raw CSD content */ - uint32_t ocr; /*!< Raw OCR content */ - sd_cid_t cid; /*!< CID */ - sd_csd_t csd; /*!< CSD */ - sd_scr_t scr; /*!< SCR */ - sd_status_t stat; /*!< sd 512 bit status */ - uint32_t blockCount; /*!< Card total block number */ - uint32_t blockSize; /*!< Card block size */ - sd_timing_mode_t currentTiming; /*!< current timing mode */ - sd_driver_strength_t driverStrength; /*!< driver strength */ - sd_max_current_t maxCurrent; /*!< card current limit */ - sdmmc_operation_voltage_t operationVoltage; /*!< card operation voltage */ -} sd_card_t; - -/************************************************************************************************* - * API - ************************************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @name SDCARD Function - * @{ - */ - -/*! - * @brief Initializes the card on a specific host controller. - * @deprecated Do not use this function. It has been superceded by @ref SD_HostInit,SD_CardInit. - - * This function initializes the card on a specific host controller, it is consist of - * host init, card detect, card init function, however user can ignore this high level function, - * instead of use the low level function, such as SD_CardInit, SD_HostInit, SD_CardDetect. - * - * @param card Card descriptor. - * @retval kStatus_SDMMC_HostNotReady host is not ready. - * @retval kStatus_SDMMC_GoIdleFailed Go idle failed. - * @retval kStatus_SDMMC_NotSupportYet Card not support. - * @retval kStatus_SDMMC_SendOperationConditionFailed Send operation condition failed. - * @retval kStatus_SDMMC_AllSendCidFailed Send CID failed. - * @retval kStatus_SDMMC_SendRelativeAddressFailed Send relative address failed. - * @retval kStatus_SDMMC_SendCsdFailed Send CSD failed. - * @retval kStatus_SDMMC_SelectCardFailed Send SELECT_CARD command failed. - * @retval kStatus_SDMMC_SendScrFailed Send SCR failed. - * @retval kStatus_SDMMC_SetBusWidthFailed Set bus width failed. - * @retval kStatus_SDMMC_SwitchHighSpeedFailed Switch high speed failed. - * @retval kStatus_SDMMC_SetCardBlockSizeFailed Set card block size failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SD_Init(sd_card_t *card); - -/*! - * @brief Deinitializes the card. - * @deprecated Do not use this function. It has been superceded by @ref SD_HostDeinit,SD_CardDeinit. - * This function deinitializes the specific card and host. - * - * @param card Card descriptor. - */ -void SD_Deinit(sd_card_t *card); - -/*! - * @brief Initializes the card. - * - * This function initializes the card only, make sure the host is ready when call this function, - * otherwise it will return kStatus_SDMMC_HostNotReady. - * - * @param card Card descriptor. - * @retval kStatus_SDMMC_HostNotReady host is not ready. - * @retval kStatus_SDMMC_GoIdleFailed Go idle failed. - * @retval kStatus_SDMMC_NotSupportYet Card not support. - * @retval kStatus_SDMMC_SendOperationConditionFailed Send operation condition failed. - * @retval kStatus_SDMMC_AllSendCidFailed Send CID failed. - * @retval kStatus_SDMMC_SendRelativeAddressFailed Send relative address failed. - * @retval kStatus_SDMMC_SendCsdFailed Send CSD failed. - * @retval kStatus_SDMMC_SelectCardFailed Send SELECT_CARD command failed. - * @retval kStatus_SDMMC_SendScrFailed Send SCR failed. - * @retval kStatus_SDMMC_SetBusWidthFailed Set bus width failed. - * @retval kStatus_SDMMC_SwitchHighSpeedFailed Switch high speed failed. - * @retval kStatus_SDMMC_SetCardBlockSizeFailed Set card block size failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SD_CardInit(sd_card_t *card); - -/*! - * @brief Deinitializes the card. - * - * This function deinitializes the specific card. - * - * @param card Card descriptor. - */ -void SD_CardDeinit(sd_card_t *card); - -/*! - * @brief initialize the host. - * - * This function deinitializes the specific host. - * - * @param card Card descriptor. - */ -status_t SD_HostInit(sd_card_t *card); - -/*! - * @brief Deinitializes the host. - * - * This function deinitializes the host. - * - * @param card Card descriptor. - */ -void SD_HostDeinit(sd_card_t *card); - -/*! - * @brief reset the host. - * - * This function reset the specific host. - * - * @param host host descriptor. - */ -void SD_HostReset(SDMMCHOST_CONFIG *host); - -/*! - * @brief power on card. - * - * The power on operation depend on host or the user define power on function. - * @param base host base address. - * @param pwr user define power control configuration - */ -void SD_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr); - -/*! - * @brief power off card. - * - * The power off operation depend on host or the user define power on function. - * @param base host base address. - * @param pwr user define power control configuration - */ -void SD_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr); - -/*! - * @brief sd wait card detect function. - * - * Detect card through GPIO, CD, DATA3. - * - * @param card card descriptor. - * @param card detect configuration - * @param waitCardStatus wait card detect status - */ -status_t SD_WaitCardDetectStatus(SDMMCHOST_TYPE *hostBase, const sdmmchost_detect_card_t *cd, bool waitCardStatus); - -/*! - * @brief sd card present check function. - * - * @param card card descriptor. - */ -bool SD_IsCardPresent(sd_card_t *card); - -/*! - * @brief Checks whether the card is write-protected. - * - * This function checks if the card is write-protected via the CSD register. - * - * @param card The specific card. - * @retval true Card is read only. - * @retval false Card isn't read only. - */ -bool SD_CheckReadOnly(sd_card_t *card); - -/*! - * @brief Send SELECT_CARD command to set the card to be transfer state or not. - * - * @param card Card descriptor. - * @param isSelected True to set the card into transfer state, false to disselect. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SD_SelectCard(sd_card_t *card, bool isSelected); - -/*! - * @brief Send ACMD13 to get the card current status. - * - * @param card Card descriptor. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_SDMMC_SendApplicationCommandFailed send application command failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SD_ReadStatus(sd_card_t *card); - -/*! - * @brief Reads blocks from the specific card. - * - * This function reads blocks from the specific card with default block size defined by the - * SDHC_CARD_DEFAULT_BLOCK_SIZE. - * - * @param card Card descriptor. - * @param buffer The buffer to save the data read from card. - * @param startBlock The start block index. - * @param blockCount The number of blocks to read. - * @retval kStatus_InvalidArgument Invalid argument. - * @retval kStatus_SDMMC_CardNotSupport Card not support. - * @retval kStatus_SDMMC_NotSupportYet Not support now. - * @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_SDMMC_StopTransmissionFailed Stop transmission failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SD_ReadBlocks(sd_card_t *card, uint8_t *buffer, uint32_t startBlock, uint32_t blockCount); - -/*! - * @brief Writes blocks of data to the specific card. - * - * This function writes blocks to the specific card with default block size 512 bytes. - * - * @param card Card descriptor. - * @param buffer The buffer holding the data to be written to the card. - * @param startBlock The start block index. - * @param blockCount The number of blocks to write. - * @retval kStatus_InvalidArgument Invalid argument. - * @retval kStatus_SDMMC_NotSupportYet Not support now. - * @retval kStatus_SDMMC_CardNotSupport Card not support. - * @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_SDMMC_StopTransmissionFailed Stop transmission failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SD_WriteBlocks(sd_card_t *card, const uint8_t *buffer, uint32_t startBlock, uint32_t blockCount); - -/*! - * @brief Erases blocks of the specific card. - * - * This function erases blocks of the specific card with default block size 512 bytes. - * - * @param card Card descriptor. - * @param startBlock The start block index. - * @param blockCount The number of blocks to erase. - * @retval kStatus_InvalidArgument Invalid argument. - * @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_SDMMC_WaitWriteCompleteFailed Send status failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SD_EraseBlocks(sd_card_t *card, uint32_t startBlock, uint32_t blockCount); - -/*! - * @brief select card driver strength - * select card driver strength - * @param card Card descriptor. - * @param driverStrength Driver strength - */ -status_t SD_SetDriverStrength(sd_card_t *card, sd_driver_strength_t driverStrength); - -/*! - * @brief select max current - * select max operation current - * @param card Card descriptor. - * @param maxCurrent Max current - */ -status_t SD_SetMaxCurrent(sd_card_t *card, sd_max_current_t maxCurrent); - -/* @} */ - -#if defined(__cplusplus) -} -#endif -/*! @} */ -#endif /* _FSL_SD_H_*/ diff --git a/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_common.h b/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_common.h deleted file mode 100644 index ec0394fb67..0000000000 --- a/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_common.h +++ /dev/null @@ -1,240 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2018 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#ifndef _FSL_SDMMC_COMMON_H_ -#define _FSL_SDMMC_COMMON_H_ - -#include "fsl_common.h" -#include "fsl_sdmmc_host.h" -#include "fsl_sdmmc_spec.h" -#include "stdlib.h" - -/*! - * @addtogroup CARD - * @{ - */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ -/*! @brief Middleware version. */ -#define FSL_SDMMC_DRIVER_VERSION (MAKE_VERSION(2U, 2U, 6U)) /*2.2.6*/ - -/*! @brief Reverse byte sequence in uint32_t */ -#define SWAP_WORD_BYTE_SEQUENCE(x) (__REV(x)) -/*! @brief Reverse byte sequence for each half word in uint32_t */ -#define SWAP_HALF_WROD_BYTE_SEQUENCE(x) (__REV16(x)) -/*! @brief Maximum loop count to check the card operation voltage range */ -#define FSL_SDMMC_MAX_VOLTAGE_RETRIES (1000U) -/*! @brief Maximum loop count to send the cmd */ -#define FSL_SDMMC_MAX_CMD_RETRIES (10U) -/*! @brief Default block size */ -#define FSL_SDMMC_DEFAULT_BLOCK_SIZE (512U) -#ifndef SDMMC_GLOBAL_BUFFER_SIZE -/*! @brief SDMMC global data buffer size, word unit*/ -#define SDMMC_GLOBAL_BUFFER_SIZE (128U) -#endif -/*! @brief SDMMC enable software tuning */ -#define SDMMC_ENABLE_SOFTWARE_TUNING (0U) -/* Common definition for cache line size align */ -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL -#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) -#if defined(FSL_FEATURE_L2DCACHE_LINESIZE_BYTE) -#define SDMMC_DATA_BUFFER_ALIGN_CACHE MAX(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE, FSL_FEATURE_L2DCACHE_LINESIZE_BYTE) -#else -#define SDMMC_DATA_BUFFER_ALIGN_CACHE FSL_FEATURE_L1DCACHE_LINESIZE_BYTE -#endif -#else -#define SDMMC_DATA_BUFFER_ALIGN_CACHE 1 -#endif -#else -#define SDMMC_DATA_BUFFER_ALIGN_CACHE 1 -#endif - -/*! @brief SD/MMC error log. */ -#if defined SDMMC_ENABLE_LOG_PRINT -#include "fsl_debug_console.h" -#define SDMMC_LOG(...) PRINTF(__VA_ARGS__) -#else -#define SDMMC_LOG(format, ...) -#endif - -/*! @brief SD/MMC card API's running status. */ -enum _sdmmc_status -{ - kStatus_SDMMC_NotSupportYet = MAKE_STATUS(kStatusGroup_SDMMC, 0U), /*!< Haven't supported */ - kStatus_SDMMC_TransferFailed = MAKE_STATUS(kStatusGroup_SDMMC, 1U), /*!< Send command failed */ - kStatus_SDMMC_SetCardBlockSizeFailed = MAKE_STATUS(kStatusGroup_SDMMC, 2U), /*!< Set block size failed */ - kStatus_SDMMC_HostNotSupport = MAKE_STATUS(kStatusGroup_SDMMC, 3U), /*!< Host doesn't support */ - kStatus_SDMMC_CardNotSupport = MAKE_STATUS(kStatusGroup_SDMMC, 4U), /*!< Card doesn't support */ - kStatus_SDMMC_AllSendCidFailed = MAKE_STATUS(kStatusGroup_SDMMC, 5U), /*!< Send CID failed */ - kStatus_SDMMC_SendRelativeAddressFailed = MAKE_STATUS(kStatusGroup_SDMMC, 6U), /*!< Send relative address failed */ - kStatus_SDMMC_SendCsdFailed = MAKE_STATUS(kStatusGroup_SDMMC, 7U), /*!< Send CSD failed */ - kStatus_SDMMC_SelectCardFailed = MAKE_STATUS(kStatusGroup_SDMMC, 8U), /*!< Select card failed */ - kStatus_SDMMC_SendScrFailed = MAKE_STATUS(kStatusGroup_SDMMC, 9U), /*!< Send SCR failed */ - kStatus_SDMMC_SetDataBusWidthFailed = MAKE_STATUS(kStatusGroup_SDMMC, 10U), /*!< Set bus width failed */ - kStatus_SDMMC_GoIdleFailed = MAKE_STATUS(kStatusGroup_SDMMC, 11U), /*!< Go idle failed */ - kStatus_SDMMC_HandShakeOperationConditionFailed = - MAKE_STATUS(kStatusGroup_SDMMC, 12U), /*!< Send Operation Condition failed */ - kStatus_SDMMC_SendApplicationCommandFailed = - MAKE_STATUS(kStatusGroup_SDMMC, 13U), /*!< Send application command failed */ - kStatus_SDMMC_SwitchFailed = MAKE_STATUS(kStatusGroup_SDMMC, 14U), /*!< Switch command failed */ - kStatus_SDMMC_StopTransmissionFailed = MAKE_STATUS(kStatusGroup_SDMMC, 15U), /*!< Stop transmission failed */ - kStatus_SDMMC_WaitWriteCompleteFailed = MAKE_STATUS(kStatusGroup_SDMMC, 16U), /*!< Wait write complete failed */ - kStatus_SDMMC_SetBlockCountFailed = MAKE_STATUS(kStatusGroup_SDMMC, 17U), /*!< Set block count failed */ - kStatus_SDMMC_SetRelativeAddressFailed = MAKE_STATUS(kStatusGroup_SDMMC, 18U), /*!< Set relative address failed */ - kStatus_SDMMC_SwitchBusTimingFailed = MAKE_STATUS(kStatusGroup_SDMMC, 19U), /*!< Switch high speed failed */ - kStatus_SDMMC_SendExtendedCsdFailed = MAKE_STATUS(kStatusGroup_SDMMC, 20U), /*!< Send EXT_CSD failed */ - kStatus_SDMMC_ConfigureBootFailed = MAKE_STATUS(kStatusGroup_SDMMC, 21U), /*!< Configure boot failed */ - kStatus_SDMMC_ConfigureExtendedCsdFailed = MAKE_STATUS(kStatusGroup_SDMMC, 22U), /*!< Configure EXT_CSD failed */ - kStatus_SDMMC_EnableHighCapacityEraseFailed = - MAKE_STATUS(kStatusGroup_SDMMC, 23U), /*!< Enable high capacity erase failed */ - kStatus_SDMMC_SendTestPatternFailed = MAKE_STATUS(kStatusGroup_SDMMC, 24U), /*!< Send test pattern failed */ - kStatus_SDMMC_ReceiveTestPatternFailed = MAKE_STATUS(kStatusGroup_SDMMC, 25U), /*!< Receive test pattern failed */ - kStatus_SDMMC_SDIO_ResponseError = MAKE_STATUS(kStatusGroup_SDMMC, 26U), /*!< sdio response error */ - kStatus_SDMMC_SDIO_InvalidArgument = - MAKE_STATUS(kStatusGroup_SDMMC, 27U), /*!< sdio invalid argument response error */ - kStatus_SDMMC_SDIO_SendOperationConditionFail = - MAKE_STATUS(kStatusGroup_SDMMC, 28U), /*!< sdio send operation condition fail */ - kStatus_SDMMC_InvalidVoltage = MAKE_STATUS(kStatusGroup_SDMMC, 29U), /*!< invaild voltage */ - kStatus_SDMMC_SDIO_SwitchHighSpeedFail = MAKE_STATUS(kStatusGroup_SDMMC, 30U), /*!< switch to high speed fail */ - kStatus_SDMMC_SDIO_ReadCISFail = MAKE_STATUS(kStatusGroup_SDMMC, 31U), /*!< read CIS fail */ - kStatus_SDMMC_SDIO_InvalidCard = MAKE_STATUS(kStatusGroup_SDMMC, 32U), /*!< invaild SDIO card */ - kStatus_SDMMC_TuningFail = MAKE_STATUS(kStatusGroup_SDMMC, 33U), /*!< tuning fail */ - - kStatus_SDMMC_SwitchVoltageFail = MAKE_STATUS(kStatusGroup_SDMMC, 34U), /*!< switch voltage fail*/ - kStatus_SDMMC_SwitchVoltage18VFail33VSuccess = MAKE_STATUS(kStatusGroup_SDMMC, 35U), /*!< switch voltage fail*/ - - kStatus_SDMMC_ReTuningRequest = MAKE_STATUS(kStatusGroup_SDMMC, 36U), /*!< retuning request */ - kStatus_SDMMC_SetDriverStrengthFail = MAKE_STATUS(kStatusGroup_SDMMC, 37U), /*!< set driver strength fail */ - kStatus_SDMMC_SetPowerClassFail = MAKE_STATUS(kStatusGroup_SDMMC, 38U), /*!< set power class fail */ - kStatus_SDMMC_HostNotReady = MAKE_STATUS(kStatusGroup_SDMMC, 39U), /*!< host controller not ready */ - kStatus_SDMMC_CardDetectFailed = MAKE_STATUS(kStatusGroup_SDMMC, 40U), /*!< card detect failed */ - kStatus_SDMMC_AuSizeNotSetProperly = MAKE_STATUS(kStatusGroup_SDMMC, 41U), /*!< AU size not set properly */ - -}; - -/*! @brief card operation voltage */ -typedef enum _sdmmc_operation_voltage -{ - kCARD_OperationVoltageNone = 0U, /*!< indicate current voltage setting is not setting bu suser*/ - kCARD_OperationVoltage330V = 1U, /*!< card operation voltage around 3.3v */ - kCARD_OperationVoltage300V = 2U, /*!< card operation voltage around 3.0v */ - kCARD_OperationVoltage180V = 3U, /*!< card operation voltage around 31.8v */ -} sdmmc_operation_voltage_t; - -/************************************************************************************************* - * API - ************************************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @brief Selects the card to put it into transfer state. - * - * @param base SDMMCHOST peripheral base address. - * @param transfer SDMMCHOST transfer function. - * @param relativeAddress Relative address. - * @param isSelected True to put card into transfer state. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SDMMC_SelectCard(SDMMCHOST_TYPE *base, - SDMMCHOST_TRANSFER_FUNCTION transfer, - uint32_t relativeAddress, - bool isSelected); - -/*! - * @brief Sends an application command. - * - * @param base SDMMCHOST peripheral base address. - * @param transfer SDMMCHOST transfer function. - * @param relativeAddress Card relative address. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_SDMMC_CardNotSupport Card doesn't support. - * @retval kStatus_Success Operate successfully. - */ -status_t SDMMC_SendApplicationCommand(SDMMCHOST_TYPE *base, - SDMMCHOST_TRANSFER_FUNCTION transfer, - uint32_t relativeAddress); - -/*! - * @brief Sets the block count. - * - * @param base SDMMCHOST peripheral base address. - * @param transfer SDMMCHOST transfer function. - * @param blockCount Block count. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SDMMC_SetBlockCount(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer, uint32_t blockCount); - -/*! - * @brief Sets the card to be idle state. - * - * @param base SDMMCHOST peripheral base address. - * @param transfer SDMMCHOST transfer function. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SDMMC_GoIdle(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer); - -/*! - * @brief Sets data block size. - * - * @param base SDMMCHOST peripheral base address. - * @param transfer SDMMCHOST transfer function. - * @param blockSize Block size. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SDMMC_SetBlockSize(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer, uint32_t blockSize); - -/*! - * @brief Sets card to inactive status - * - * @param base SDMMCHOST peripheral base address. - * @param transfer SDMMCHOST transfer function. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -status_t SDMMC_SetCardInactive(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer); - -/*! - * @brief provide a simple delay function for sdmmc - * - * @param num Delay num*10000. - */ -void SDMMC_Delay(uint32_t num); - -/*! - * @brief provide a voltage switch function for SD/SDIO card - * - * @param base SDMMCHOST peripheral base address. - * @param transfer SDMMCHOST transfer function. - */ -status_t SDMMC_SwitchVoltage(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer); - -/*! - * @brief excute tuning - * - * @param base SDMMCHOST peripheral base address. - * @param transfer Host transfer function - * @param tuningCmd Tuning cmd - * @param blockSize Tuning block size - */ -status_t SDMMC_ExecuteTuning(SDMMCHOST_TYPE *base, - SDMMCHOST_TRANSFER_FUNCTION transfer, - uint32_t tuningCmd, - uint32_t blockSize); - -#if defined(__cplusplus) -} -#endif -/* @} */ -#endif /* _FSL_SDMMC_COMMON_H_ */ diff --git a/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_host.h b/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_host.h deleted file mode 100644 index d89fcf4d0e..0000000000 --- a/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_host.h +++ /dev/null @@ -1,735 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2018 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#ifndef _FSL_SDMMC_HOST_H -#define _FSL_SDMMC_HOST_H - -#include "fsl_common.h" -#include "board.h" -#if defined(FSL_FEATURE_SOC_SDHC_COUNT) && FSL_FEATURE_SOC_SDHC_COUNT > 0U -#include "fsl_sdhc.h" -#elif defined(FSL_FEATURE_SOC_SDIF_COUNT) && FSL_FEATURE_SOC_SDIF_COUNT > 0U -#include "fsl_sdif.h" -#elif defined(FSL_FEATURE_SOC_USDHC_COUNT) && FSL_FEATURE_SOC_USDHC_COUNT > 0U -#include "fsl_usdhc.h" -#endif - -/*! - * @addtogroup SDMMCHOST - * @{ - */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Common definition for support and not support macro */ -#define SDMMCHOST_NOT_SUPPORT 0U /*!< use this define to indicate the host not support feature*/ -#define SDMMCHOST_SUPPORT 1U /*!< use this define to indicate the host support feature*/ - -/* Common definition for board support SDR104/HS200/HS400 frequency */ -/* SDR104 mode freq */ -#if defined BOARD_SD_HOST_SUPPORT_SDR104_FREQ -#define SDMMCHOST_SUPPORT_SDR104_FREQ BOARD_SD_HOST_SUPPORT_SDR104_FREQ -#else -#define SDMMCHOST_SUPPORT_SDR104_FREQ SD_CLOCK_208MHZ -#endif -/* HS200 mode freq */ -#if defined BOARD_SD_HOST_SUPPORT_HS200_FREQ -#define SDMMCHOST_SUPPORT_HS200_FREQ BOARD_SD_HOST_SUPPORT_HS200_FREQ -#else -#define SDMMCHOST_SUPPORT_HS200_FREQ MMC_CLOCK_HS200 -#endif -/* HS400 mode freq */ -#if defined BOARD_SD_HOST_SUPPORT_HS400_FREQ -#define SDMMCHOST_SUPPORT_HS400_FREQ BOARD_SD_HOST_SUPPORT_HS400_FREQ -#else -#define SDMMCHOST_SUPPORT_HS400_FREQ MMC_CLOCK_HS400 -#endif - -/* Common definition for SDMMCHOST transfer complete timeout */ -#define SDMMCHOST_TRANSFER_COMPLETE_TIMEOUT (500U) -/* Common definition for card detect timeout */ -#define SDMMCHOST_CARD_DETECT_TIMEOUT (~0U) - -/* Common definition for IRQ */ -#if defined(__CORTEX_M) -#define SDMMCHOST_SET_IRQ_PRIORITY(id, priority) (NVIC_SetPriority(id, priority)) -#else -#define SDMMCHOST_SET_IRQ_PRIORITY(id, priority) (GIC_SetPriority(id, priority)) -#endif - -#define SDMMCHOST_ENABLE_IRQ(id) (EnableIRQ(id)) - -/*********************************************************SDHC**********************************************************/ -#if (defined(FSL_FEATURE_SOC_SDHC_COUNT) && (FSL_FEATURE_SOC_SDHC_COUNT > 0U)) - -/*define host baseaddr ,clk freq, IRQ number*/ -#define MMC_HOST_BASEADDR BOARD_SDHC_BASEADDR -#define MMC_HOST_CLK_FREQ BOARD_SDHC_CLK_FREQ -#define MMC_HOST_IRQ BOARD_SDHC_IRQ -#define SD_HOST_BASEADDR BOARD_SDHC_BASEADDR -#define SD_HOST_CLK_FREQ BOARD_SDHC_CLK_FREQ -#define SD_HOST_IRQ BOARD_SDHC_IRQ - -/* define for card bus speed/strength cnofig */ -#define CARD_BUS_FREQ_50MHZ (0U) -#define CARD_BUS_FREQ_100MHZ0 (0U) -#define CARD_BUS_FREQ_100MHZ1 (0U) -#define CARD_BUS_FREQ_200MHZ (0U) - -#define CARD_BUS_STRENGTH_0 (0U) -#define CARD_BUS_STRENGTH_1 (0U) -#define CARD_BUS_STRENGTH_2 (0U) -#define CARD_BUS_STRENGTH_3 (0U) -#define CARD_BUS_STRENGTH_4 (0U) -#define CARD_BUS_STRENGTH_5 (0U) -#define CARD_BUS_STRENGTH_6 (0U) -#define CARD_BUS_STRENGTH_7 (0U) - -#define SDMMCHOST_TYPE SDHC_Type -#define SDMMCHOST_CONFIG sdhc_host_t -#define SDMMCHOST_TRANSFER sdhc_transfer_t -#define SDMMCHOST_COMMAND sdhc_command_t -#define SDMMCHOST_DATA sdhc_data_t -#define SDMMCHOST_BUS_WIDTH_TYPE sdhc_data_bus_width_t -#define SDMMCHOST_CAPABILITY sdhc_capability_t -#define SDMMCHOST_BOOT_CONFIG sdhc_boot_config_t - -#define CARD_DATA0_STATUS_MASK (kSDHC_Data0LineLevelFlag) -#define CARD_DATA0_NOT_BUSY (kSDHC_Data0LineLevelFlag) -#define CARD_DATA1_STATUS_MASK (kSDHC_Data1LineLevelFlag) -#define CARD_DATA2_STATUS_MASK (kSDHC_Data2LineLevelFlag) -#define CARD_DATA3_STATUS_MASK (kSDHC_Data3LineLevelFlag) - -#define kSDMMCHOST_DATABUSWIDTH1BIT kSDHC_DataBusWidth1Bit /*!< 1-bit mode */ -#define kSDMMCHOST_DATABUSWIDTH4BIT kSDHC_DataBusWidth4Bit /*!< 4-bit mode */ -#define kSDMMCHOST_DATABUSWIDTH8BIT kSDHC_DataBusWidth8Bit /*!< 8-bit mode */ - -#define SDMMCHOST_STANDARD_TUNING_START (0U) /*!< standard tuning start point */ -#define SDMMCHOST_TUINIG_STEP (1U) /*!< standard tuning step */ -#define SDMMCHOST_RETUNING_TIMER_COUNT (4U) /*!< Re-tuning timer */ -#define SDMMCHOST_TUNING_DELAY_MAX (0x7FU) -#define SDMMCHOST_RETUNING_REQUEST (1U) -#define SDMMCHOST_TUNING_ERROR (2U) - -/* function pointer define */ -#define SDMMCHOST_TRANSFER_FUNCTION sdhc_transfer_function_t -#define GET_SDMMCHOST_CAPABILITY(base, capability) (SDHC_GetCapability(base, capability)) -#define GET_SDMMCHOST_STATUS(base) (SDHC_GetPresentStatusFlags(base)) -#define SDMMCHOST_SET_CARD_CLOCK(base, sourceClock_HZ, busClock_HZ) (SDHC_SetSdClock(base, sourceClock_HZ, busClock_HZ)) -#define SDMMCHOST_SET_CARD_BUS_WIDTH(base, busWidth) (SDHC_SetDataBusWidth(base, busWidth)) -#define SDMMCHOST_SEND_CARD_ACTIVE(base, timeout) (SDHC_SetCardActive(base, timeout)) -#define SDMMCHOST_SWITCH_VOLTAGE180V(base, enable18v) -#define SDMMCHOST_SWITCH_VOLTAGE120V(base, enable12v) -#define SDMMCHOST_CONFIG_IO_STRENGTH(speed, strength) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, flag) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_STATUS(base) (0U) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_RESULT(base) (1U) -#define SDMMCHOST_CONFIG_SD_IO(speed, strength) -#define SDMMCHOST_CONFIG_MMC_IO(speed, strength) -#define SDMMCHOST_ENABLE_DDR_MODE(base, flag, nibblePos) -#define SDMMCHOST_FORCE_SDCLOCK_ON(base, enable) -#define SDMMCHOST_EXECUTE_MANUAL_TUNING_ENABLE(base, flag) -#define SDMMCHOST_ADJUST_MANUAL_TUNING_DELAY(base, delay) -#define SDMMCHOST_AUTO_MANUAL_TUNING_ENABLE(base, flag) -#define SDMMCHOST_ENABLE_CARD_CLOCK(base, enable) (SDHC_EnableSdClock(base, enable)) -#define SDMMCHOST_RESET_TUNING(base, timeout) -#define SDMMCHOST_CHECK_TUNING_ERROR(base) (0U) -#define SDMMCHOST_ADJUST_TUNING_DELAY(base, delay) -#define SDMMCHOST_AUTO_STANDARD_RETUNING_TIMER(base) -#define SDMMCHOST_TRANSFER_DATA_ERROR kStatus_SDHC_TransferDataFailed -#define SDMMCHOST_TRANSFER_CMD_ERROR kStatus_SDHC_SendCommandFailed -#define SDMMCHOST_ENABLE_HS400_MODE(base, flag) -#define SDMMCHOST_RESET_STROBE_DLL(base) -#define SDMMCHOST_ENABLE_STROBE_DLL(base, flag) -#define SDMMCHOST_CONFIG_STROBE_DLL(base, delay, updateInterval) -#define SDMMCHOST_GET_STROBE_DLL_STATUS(base) -/* sd card power */ -#define SDMMCHOST_INIT_SD_POWER() -#define SDMMCHOST_ENABLE_SD_POWER(enable) -#define SDMMCHOST_SWITCH_VCC_TO_180V() -#define SDMMCHOST_SWITCH_VCC_TO_330V() -/* mmc card power */ -#define SDMMCHOST_INIT_MMC_POWER() -#define SDMMCHOST_ENABLE_MMC_POWER(enable) -#define SDMMCHOST_ENABLE_TUNING_FLAG(data) -#define SDMMCHOST_ENABLE_BOOT_FLAG(data) -#define SDMMCHOST_ENABLE_BOOT_CONTINOUS_FLAG(data) -#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_SIZE(config) (0U) -#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_COUNT(config) (0U) -#define SDMMCHOST_GET_HOST_CONFIG_BOOT_MODE(config) (0U) -#define SDMMCHOST_EMPTY_CMD_FLAG(command) -#define SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_HANDLER BOARD_SDHC_CD_PORT_IRQ_HANDLER -#define SDMMCHOST_CARD_DETECT_IRQ BOARD_SDHC_CD_PORT_IRQ -/* sd card detect through host CD */ -#define SDMMCHOST_CARD_DETECT_INSERT_ENABLE(base) (SDHC_EnableInterruptStatus(base, kSDHC_CardInsertionFlag)) -#define SDMMCHOST_CARD_DETECT_REMOVE_ENABLE(base) (SDHC_EnableInterruptStatus(base, kSDHC_CardRemovalFlag)) -#define SDMMCHOST_CARD_DETECT_INSERT_STATUS(base) (SDHC_GetInterruptStatusFlags(base) & kSDHC_CardInsertionFlag) -#define SDMMCHOST_CARD_DETECT_REMOVE_STATUS(base) (SDHC_GetInterruptStatusFlags(base, kSDHC_CardRemovalFlag)) -#define SDMMCHOST_CARD_DETECT_INSERT_INTERRUPT_ENABLE(base) (SDHC_EnableInterruptSignal(base, kSDHC_CardInsertionFlag)) -#define SDMMCHOST_CARD_DETECT_INSERT_INTERRUPT_DISABLE(base) \ - (SDHC_DisableInterruptSignal(base, kSDHC_CardInsertionFlag)) -#define SDMMCHOST_CARD_DETECT_REMOVE_INTERRUPT_ENABLE(base) (SDHC_EnableInterruptSignal(base, kSDHC_CardRemovalFlag)) -#define SDMMCHOST_CARD_DETECT_DATA3_ENABLE(base, flag) (SDHC_CardDetectByData3(base, flag)) -#define SDMMCHOST_ENABLE_MMC_BOOT(base, flag) -#define SDMMCHOST_SETMMCBOOTCONFIG(base, config) (SDHC_SetMmcBootConfig(base, config)) -/* define card detect pin voltage level when card inserted */ -#if defined BOARD_SDHC_CARD_INSERT_CD_LEVEL -#define SDMMCHOST_CARD_INSERT_CD_LEVEL BOARD_SDHC_CARD_INSERT_CD_LEVEL -#else -#define SDMMCHOST_CARD_INSERT_CD_LEVEL (0U) -#endif -#define SDMMCHOST_AUTO_TUNING_ENABLE(base, flag) - -/*! @brief SDHC host capability*/ -enum _host_capability -{ - kSDMMCHOST_SupportAdma = kSDHC_SupportAdmaFlag, - kSDMMCHOST_SupportHighSpeed = kSDHC_SupportHighSpeedFlag, - kSDMMCHOST_SupportDma = kSDHC_SupportDmaFlag, - kSDMMCHOST_SupportSuspendResume = kSDHC_SupportSuspendResumeFlag, - kSDMMCHOST_SupportV330 = kSDHC_SupportV330Flag, - kSDMMCHOST_SupportV300 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportV180 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportV120 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_Support4BitBusWidth = kSDHC_Support4BitFlag, - kSDMMCHOST_Support8BitBusWidth = kSDHC_Support8BitFlag, - kSDMMCHOST_SupportDDR50 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportSDR104 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportSDR50 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportHS200 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportHS400 = SDMMCHOST_NOT_SUPPORT, -}; - -/* Endian mode. */ -#define SDHC_ENDIAN_MODE kSDHC_EndianModeLittle - -/* DMA mode */ -#define SDHC_DMA_MODE kSDHC_DmaModeAdma2 -/* address align */ -#define SDMMCHOST_DMA_BUFFER_ADDR_ALIGN (SDHC_ADMA2_ADDRESS_ALIGN) - -/* Read/write watermark level. The bigger value indicates DMA has higher read/write performance. */ -#define SDHC_READ_WATERMARK_LEVEL (0x80U) -#define SDHC_WRITE_WATERMARK_LEVEL (0x80U) - -/* ADMA table length united as word. - * - * SD card driver can't support ADMA1 transfer mode currently. - * One ADMA2 table item occupy two words which can transfer maximum 0xFFFFU bytes one time. - * The more data to be transferred in one time, the bigger value of SDHC_ADMA_TABLE_WORDS need to be set. - */ -#define SDHC_ADMA_TABLE_WORDS (8U) - -/*********************************************************SDIF**********************************************************/ -#elif(defined(FSL_FEATURE_SOC_SDIF_COUNT) && (FSL_FEATURE_SOC_SDIF_COUNT > 0U)) - -/*define host baseaddr ,clk freq, IRQ number*/ -#define MMC_HOST_BASEADDR BOARD_SDIF_BASEADDR -#define MMC_HOST_CLK_FREQ BOARD_SDIF_CLK_FREQ -#define MMC_HOST_IRQ BOARD_SDIF_IRQ -#define SD_HOST_BASEADDR BOARD_SDIF_BASEADDR -#define SD_HOST_CLK_FREQ BOARD_SDIF_CLK_FREQ -#define SD_HOST_IRQ BOARD_SDIF_IRQ - -/* define for card bus speed/strength cnofig */ -#define CARD_BUS_FREQ_50MHZ (0U) -#define CARD_BUS_FREQ_100MHZ0 (0U) -#define CARD_BUS_FREQ_100MHZ1 (0U) -#define CARD_BUS_FREQ_200MHZ (0U) - -#define CARD_BUS_STRENGTH_0 (0U) -#define CARD_BUS_STRENGTH_1 (0U) -#define CARD_BUS_STRENGTH_2 (0U) -#define CARD_BUS_STRENGTH_3 (0U) -#define CARD_BUS_STRENGTH_4 (0U) -#define CARD_BUS_STRENGTH_5 (0U) -#define CARD_BUS_STRENGTH_6 (0U) -#define CARD_BUS_STRENGTH_7 (0U) - -#define SDMMCHOST_TYPE SDIF_Type -#define SDMMCHOST_CONFIG sdif_host_t -#define SDMMCHOST_TRANSFER sdif_transfer_t -#define SDMMCHOST_COMMAND sdif_command_t -#define SDMMCHOST_DATA sdif_data_t -#define SDMMCHOST_BUS_WIDTH_TYPE sdif_bus_width_t -#define SDMMCHOST_CAPABILITY sdif_capability_t -#define SDMMCHOST_BOOT_CONFIG void - -#define CARD_DATA0_STATUS_MASK SDIF_STATUS_DATA_BUSY_MASK -#define CARD_DATA0_NOT_BUSY 0U - -#define CARD_DATA1_STATUS_MASK (0U) -#define CARD_DATA2_STATUS_MASK (0U) -#define CARD_DATA3_STATUS_MASK (0U) - -#define kSDMMCHOST_DATABUSWIDTH1BIT kSDIF_Bus1BitWidth /*!< 1-bit mode */ -#define kSDMMCHOST_DATABUSWIDTH4BIT kSDIF_Bus4BitWidth /*!< 4-bit mode */ -#define kSDMMCHOST_DATABUSWIDTH8BIT kSDIF_Bus8BitWidth /*!< 8-bit mode */ - -#define SDMMCHOST_STANDARD_TUNING_START (0U) /*!< standard tuning start point */ -#define SDMMCHOST_TUINIG_STEP (1U) /*!< standard tuning step */ -#define SDMMCHOST_RETUNING_TIMER_COUNT (4U) /*!< Re-tuning timer */ -#define SDMMCHOST_TUNING_DELAY_MAX (0x7FU) -#define SDMMCHOST_RETUNING_REQUEST (1U) -#define SDMMCHOST_TUNING_ERROR (2U) -/* function pointer define */ -#define SDMMCHOST_TRANSFER_FUNCTION sdif_transfer_function_t -#define GET_SDMMCHOST_CAPABILITY(base, capability) (SDIF_GetCapability(base, capability)) -#define GET_SDMMCHOST_STATUS(base) (SDIF_GetControllerStatus(base)) -#define SDMMCHOST_SET_CARD_CLOCK(base, sourceClock_HZ, busClock_HZ) \ - (SDIF_SetCardClock(base, sourceClock_HZ, busClock_HZ)) -#define SDMMCHOST_SET_CARD_BUS_WIDTH(base, busWidth) (SDIF_SetCardBusWidth(base, busWidth)) -#define SDMMCHOST_SEND_CARD_ACTIVE(base, timeout) (SDIF_SendCardActive(base, timeout)) -#define SDMMCHOST_SWITCH_VOLTAGE180V(base, enable18v) -#define SDMMCHOST_SWITCH_VOLTAGE120V(base, enable12v) -#define SDMMCHOST_CONFIG_IO_STRENGTH(speed, strength) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, flag) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_STATUS(base) (0U) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_RESULT(base) (1U) -#define SDMMCHOST_CONFIG_SD_IO(speed, strength) -#define SDMMCHOST_CONFIG_MMC_IO(speed, strength) -#define SDMMCHOST_ENABLE_DDR_MODE(base, flag, nibblePos) -#define SDMMCHOST_FORCE_SDCLOCK_ON(base, enable) -#define SDMMCHOST_EXECUTE_MANUAL_TUNING_ENABLE(base, flag) -#define SDMMCHOST_ADJUST_MANUAL_TUNING_DELAY(base, delay) -#define SDMMCHOST_AUTO_MANUAL_TUNING_ENABLE(base, flag) -#define SDMMCHOST_ENABLE_CARD_CLOCK(base, enable) (SDIF_EnableCardClock(base, enable)) -#define SDMMCHOST_RESET_TUNING(base, timeout) -#define SDMMCHOST_CHECK_TUNING_ERROR(base) (0U) -#define SDMMCHOST_ADJUST_TUNING_DELAY(base, delay) -#define SDMMCHOST_AUTO_STANDARD_RETUNING_TIMER(base) - -#define SDMMCHOST_ENABLE_HS400_MODE(base, flag) -#define SDMMCHOST_RESET_STROBE_DLL(base) -#define SDMMCHOST_ENABLE_STROBE_DLL(base, flag) -#define SDMMCHOST_CONFIG_STROBE_DLL(base, delay, updateInterval) -#define SDMMCHOST_GET_STROBE_DLL_STATUS(base) -/* sd card power */ -#define SDMMCHOST_INIT_SD_POWER() -#define SDMMCHOST_ENABLE_SD_POWER(enable) -#define SDMMCHOST_SWITCH_VCC_TO_180V() -#define SDMMCHOST_SWITCH_VCC_TO_330V() -/* mmc card power */ -#define SDMMCHOST_INIT_MMC_POWER() -#define SDMMCHOST_ENABLE_MMC_POWER(enable) -#define SDMMCHOST_ENABLE_TUNING_FLAG(data) -#define SDMMCHOST_ENABLE_MMC_BOOT(base, flag) -#define SDMMCHOST_SETMMCBOOTCONFIG(base, config) -#define SDMMCHOST_ENABLE_BOOT_FLAG(data) -#define SDMMCHOST_ENABLE_BOOT_CONTINOUS_FLAG(data) -#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_SIZE(config) (0U) -#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_COUNT(config) (0U) -#define SDMMCHOST_GET_HOST_CONFIG_BOOT_MODE(config) (0U) -#define SDMMCHOST_EMPTY_CMD_FLAG(command) -#define SDMMCHOST_CARD_DETECT_STATUS() BOARD_SDIF_CD_STATUS() -#define SDMMCHOST_CARD_DETECT_INIT() BOARD_SDIF_CD_GPIO_INIT() -#define SDMMCHOST_CARD_DETECT_INTERRUPT_STATUS() BOARD_SDIF_CD_INTERRUPT_STATUS() -#define SDMMCHOST_CARD_DETECT_INTERRUPT_CLEAR(flag) BOARD_SDIF_CD_CLEAR_INTERRUPT(flag) -#define SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_HANDLER BOARD_SDIF_CD_PORT_IRQ_HANDLER -#define SDMMCHOST_CARD_DETECT_IRQ BOARD_SDIF_CD_PORT_IRQ -#define SDMMCHOST_TRANSFER_DATA_ERROR kStatus_SDIF_DataTransferFail -#define SDMMCHOST_TRANSFER_CMD_ERROR kStatus_SDIF_SendCmdFail -/* define card detect pin voltage level when card inserted */ -#if defined BOARD_SDIF_CARD_INSERT_CD_LEVEL -#define SDMMCHOST_CARD_INSERT_CD_LEVEL BOARD_SDIF_CARD_INSERT_CD_LEVEL -#else -#define SDMMCHOST_CARD_INSERT_CD_LEVEL (0U) -#endif -#define SDMMCHOST_AUTO_TUNING_ENABLE(base, flag) -/* sd card detect through host CD */ -#define SDMMCHOST_CARD_DETECT_INSERT_ENABLE(base) (SDIF_EnableInterrupt(base, kSDIF_CardDetect)) -#define SDMMCHOST_CARD_DETECT_INSERT_STATUS(base, data3) (SDIF_DetectCardInsert(base, data3)) - -/*! @brief SDIF host capability*/ -enum _host_capability -{ - kSDMMCHOST_SupportHighSpeed = kSDIF_SupportHighSpeedFlag, - kSDMMCHOST_SupportDma = kSDIF_SupportDmaFlag, - kSDMMCHOST_SupportSuspendResume = kSDIF_SupportSuspendResumeFlag, - kSDMMCHOST_SupportV330 = kSDIF_SupportV330Flag, - kSDMMCHOST_SupportV300 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportV180 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportV120 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_Support4BitBusWidth = kSDIF_Support4BitFlag, - kSDMMCHOST_Support8BitBusWidth = - SDMMCHOST_NOT_SUPPORT, /* mask the 8 bit here,user can change depend on your board */ - kSDMMCHOST_SupportDDR50 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportSDR104 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportSDR50 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportHS200 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_SupportHS400 = SDMMCHOST_NOT_SUPPORT, - -}; - -/*! @brief DMA table length united as word - * One dma table item occupy four words which can transfer maximum 2*8188 bytes in dual DMA mode - * and 8188 bytes in chain mode - * The more data to be transferred in one time, the bigger value of SDHC_ADMA_TABLE_WORDS need to be set. - * user need check the DMA descriptor table lenght if bigger enough. - */ -#define SDIF_DMA_TABLE_WORDS (0x40U) -/* address align */ -#define SDMMCHOST_DMA_BUFFER_ADDR_ALIGN (4U) - -/*********************************************************USDHC**********************************************************/ -#elif(defined(FSL_FEATURE_SOC_USDHC_COUNT) && (FSL_FEATURE_SOC_USDHC_COUNT > 0U)) - -/*define host baseaddr ,clk freq, IRQ number*/ -#define MMC_HOST_BASEADDR BOARD_MMC_HOST_BASEADDR -#define MMC_HOST_CLK_FREQ BOARD_MMC_HOST_CLK_FREQ -#define MMC_HOST_IRQ BOARD_MMC_HOST_IRQ -#define SD_HOST_BASEADDR BOARD_SD_HOST_BASEADDR -#define SD_HOST_CLK_FREQ BOARD_SD_HOST_CLK_FREQ -#define SD_HOST_IRQ BOARD_SD_HOST_IRQ - -#define SDMMCHOST_TYPE USDHC_Type -#define SDMMCHOST_CONFIG usdhc_host_t -#define SDMMCHOST_TRANSFER usdhc_transfer_t -#define SDMMCHOST_COMMAND usdhc_command_t -#define SDMMCHOST_DATA usdhc_data_t -#define SDMMCHOST_BOOT_CONFIG usdhc_boot_config_t -#define CARD_DATA0_STATUS_MASK (kUSDHC_Data0LineLevelFlag) -#define CARD_DATA1_STATUS_MASK (kUSDHC_Data1LineLevelFlag) -#define CARD_DATA2_STATUS_MASK (kUSDHC_Data2LineLevelFlag) -#define CARD_DATA3_STATUS_MASK (kUSDHC_Data3LineLevelFlag) -#define CARD_DATA0_NOT_BUSY (kUSDHC_Data0LineLevelFlag) - -#define SDMMCHOST_BUS_WIDTH_TYPE usdhc_data_bus_width_t -#define SDMMCHOST_CAPABILITY usdhc_capability_t - -#define kSDMMCHOST_DATABUSWIDTH1BIT kUSDHC_DataBusWidth1Bit /*!< 1-bit mode */ -#define kSDMMCHOST_DATABUSWIDTH4BIT kUSDHC_DataBusWidth4Bit /*!< 4-bit mode */ -#define kSDMMCHOST_DATABUSWIDTH8BIT kUSDHC_DataBusWidth8Bit /*!< 8-bit mode */ - -#define SDMMCHOST_STANDARD_TUNING_START (10U) /*!< standard tuning start point */ -#define SDMMCHOST_TUINIG_STEP (2U) /*!< standard tuning step */ -#define SDMMCHOST_RETUNING_TIMER_COUNT (0U) /*!< Re-tuning timer */ -#define SDMMCHOST_TUNING_DELAY_MAX (0x7FU) -#define SDMMCHOST_RETUNING_REQUEST kStatus_USDHC_ReTuningRequest -#define SDMMCHOST_TUNING_ERROR kStatus_USDHC_TuningError -#define SDMMCHOST_TRANSFER_DATA_ERROR kStatus_USDHC_TransferDataFailed -#define SDMMCHOST_TRANSFER_CMD_ERROR kStatus_USDHC_SendCommandFailed -/* define for card bus speed/strength cnofig */ -#define CARD_BUS_FREQ_50MHZ (0U) -#define CARD_BUS_FREQ_100MHZ0 (1U) -#define CARD_BUS_FREQ_100MHZ1 (2U) -#define CARD_BUS_FREQ_200MHZ (3U) - -#define CARD_BUS_STRENGTH_0 (0U) -#define CARD_BUS_STRENGTH_1 (1U) -#define CARD_BUS_STRENGTH_2 (2U) -#define CARD_BUS_STRENGTH_3 (3U) -#define CARD_BUS_STRENGTH_4 (4U) -#define CARD_BUS_STRENGTH_5 (5U) -#define CARD_BUS_STRENGTH_6 (6U) -#define CARD_BUS_STRENGTH_7 (7U) - -#define SDMMCHOST_STROBE_DLL_DELAY_TARGET (7U) -#define SDMMCHOST_STROBE_DLL_DELAY_UPDATE_INTERVAL (4U) - -/* function pointer define */ -#define SDMMCHOST_TRANSFER_FUNCTION usdhc_transfer_function_t -#define GET_SDMMCHOST_CAPABILITY(base, capability) (USDHC_GetCapability(base, capability)) -#define GET_SDMMCHOST_STATUS(base) (USDHC_GetPresentStatusFlags(base)) -#define SDMMCHOST_SET_CARD_CLOCK(base, sourceClock_HZ, busClock_HZ) \ - (USDHC_SetSdClock(base, sourceClock_HZ, busClock_HZ)) -#define SDMMCHOST_ENABLE_CARD_CLOCK(base, enable) -#define SDMMCHOST_FORCE_SDCLOCK_ON(base, enable) (USDHC_ForceClockOn(base, enable)) -#define SDMMCHOST_SET_CARD_BUS_WIDTH(base, busWidth) (USDHC_SetDataBusWidth(base, busWidth)) -#define SDMMCHOST_SEND_CARD_ACTIVE(base, timeout) (USDHC_SetCardActive(base, timeout)) -#define SDMMCHOST_SWITCH_VOLTAGE180V(base, enable18v) (UDSHC_SelectVoltage(base, enable18v)) -#define SDMMCHOST_SWITCH_VOLTAGE120V(base, enable12v) -#define SDMMCHOST_CONFIG_SD_IO(speed, strength) BOARD_SD_Pin_Config(speed, strength) -#define SDMMCHOST_CONFIG_MMC_IO(speed, strength) BOARD_MMC_Pin_Config(speed, strength) -#define SDMMCHOST_SWITCH_VCC_TO_180V() -#define SDMMCHOST_SWITCH_VCC_TO_330V() - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (!FSL_FEATURE_USDHC_HAS_SDR50_MODE) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_STATUS(base) (0U) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_RESULT(base) (1U) -#define SDMMCHOST_AUTO_STANDARD_RETUNING_TIMER(base) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, flag) -#define SDMMCHOST_CHECK_TUNING_ERROR(base) (0U) -#define SDMMCHOST_ADJUST_TUNING_DELAY(base, delay) -#else -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, flag) \ - (USDHC_EnableStandardTuning(base, SDMMCHOST_STANDARD_TUNING_START, SDMMCHOST_TUINIG_STEP, flag)) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_STATUS(base) (USDHC_GetExecuteStdTuningStatus(base)) -#define SDMMCHOST_EXECUTE_STANDARD_TUNING_RESULT(base) (USDHC_CheckStdTuningResult(base)) -#define SDMMCHOST_AUTO_STANDARD_RETUNING_TIMER(base) (USDHC_SetRetuningTimer(base, SDMMCHOST_RETUNING_TIMER_COUNT)) -#define SDMMCHOST_EXECUTE_MANUAL_TUNING_ENABLE(base, flag) (USDHC_EnableManualTuning(base, flag)) -#define SDMMCHOST_ADJUST_TUNING_DELAY(base, delay) (USDHC_AdjustDelayForManualTuning(base, delay)) -#define SDMMCHOST_AUTO_TUNING_ENABLE(base, flag) (USDHC_EnableAutoTuning(base, flag)) -#define SDMMCHOST_CHECK_TUNING_ERROR(base) (USDHC_CheckTuningError(base)) -#endif - -#define SDMMCHOST_AUTO_TUNING_CONFIG(base) (USDHC_EnableAutoTuningForCmdAndData(base)) -#define SDMMCHOST_RESET_TUNING(base, timeout) \ - { \ - (USDHC_Reset(base, kUSDHC_ResetTuning | kUSDHC_ResetData | kUSDHC_ResetCommand, timeout)); \ - } - -#define SDMMCHOST_ENABLE_DDR_MODE(base, flag, nibblePos) (USDHC_EnableDDRMode(base, flag, nibblePos)) - -#if FSL_FEATURE_USDHC_HAS_HS400_MODE -#define SDMMCHOST_ENABLE_HS400_MODE(base, flag) (USDHC_EnableHS400Mode(base, flag)) -#define SDMMCHOST_RESET_STROBE_DLL(base) (USDHC_ResetStrobeDLL(base)) -#define SDMMCHOST_ENABLE_STROBE_DLL(base, flag) (USDHC_EnableStrobeDLL(base, flag)) -#define SDMMCHOST_CONFIG_STROBE_DLL(base, delay, updateInterval) (USDHC_ConfigStrobeDLL(base, delay, updateInterval)) -#define SDMMCHOST_GET_STROBE_DLL_STATUS (base)(USDHC_GetStrobeDLLStatus(base)) -#else -#define SDMMCHOST_ENABLE_HS400_MODE(base, flag) -#define SDMMCHOST_RESET_STROBE_DLL(base) -#define SDMMCHOST_ENABLE_STROBE_DLL(base, flag) -#define SDMMCHOST_CONFIG_STROBE_DLL(base, delay, updateInterval) -#define SDMMCHOST_GET_STROBE_DLL_STATUS(base) -#endif - -#define SDMMCHOST_ENABLE_MMC_BOOT(base, flag) (USDHC_EnableMmcBoot(base, flag)) -#define SDMMCHOST_SETMMCBOOTCONFIG(base, config) (USDHC_SetMmcBootConfig(base, config)) -/* sd card power */ -#define SDMMCHOST_INIT_SD_POWER() BOARD_USDHC_SDCARD_POWER_CONTROL_INIT() -#define SDMMCHOST_ENABLE_SD_POWER(enable) BOARD_USDHC_SDCARD_POWER_CONTROL(enable) -/* mmc card power */ -#define SDMMCHOST_INIT_MMC_POWER() BOARD_USDHC_MMCCARD_POWER_CONTROL_INIT() -#define SDMMCHOST_ENABLE_MMC_POWER(enable) BOARD_USDHC_MMCCARD_POWER_CONTROL(enable) -/* sd card detect through gpio */ -#define SDMMCHOST_CARD_DETECT_GPIO_STATUS() BOARD_USDHC_CD_STATUS() -#define SDMMCHOST_CARD_DETECT_GPIO_INIT() BOARD_USDHC_CD_GPIO_INIT() -#define SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_STATUS() BOARD_USDHC_CD_INTERRUPT_STATUS() -#define SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_STATUS_CLEAR(flag) BOARD_USDHC_CD_CLEAR_INTERRUPT(flag) -#define SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_HANDLER BOARD_USDHC_CD_PORT_IRQ_HANDLER -#define SDMMCHOST_CARD_DETECT_GPIO_IRQ BOARD_USDHC_CD_PORT_IRQ -/* sd card detect through host CD */ -#define SDMMCHOST_CARD_DETECT_INSERT_ENABLE(base) (USDHC_EnableInterruptStatus(base, kUSDHC_CardInsertionFlag)) -#define SDMMCHOST_CARD_DETECT_REMOVE_ENABLE(base) (USDHC_EnableInterruptStatus(base, kUSDHC_CardRemovalFlag)) -#define SDMMCHOST_CARD_DETECT_INSERT_STATUS(base) (USDHC_DetectCardInsert(base)) -#define SDMMCHOST_CARD_DETECT_REMOVE_STATUS(base) (USDHC_GetInterruptStatusFlags(base, kUSDHC_CardRemovalFlag)) -#define SDMMCHOST_CARD_DETECT_INSERT_INTERRUPT_ENABLE(base) \ - (USDHC_EnableInterruptSignal(base, kUSDHC_CardInsertionFlag)) -#define SDMMCHOST_CARD_DETECT_REMOVE_INTERRUPT_ENABLE(base) (USDHC_EnableInterruptSignal(base, kUSDHC_CardRemovalFlag)) -#define SDMMCHOST_CARD_DETECT_DATA3_ENABLE(base, flag) (USDHC_CardDetectByData3(base, flag)) - -/* define card detect pin voltage level when card inserted */ -#if defined BOARD_USDHC_CARD_INSERT_CD_LEVEL -#define SDMMCHOST_CARD_INSERT_CD_LEVEL BOARD_USDHC_CARD_INSERT_CD_LEVEL -#else -#define SDMMCHOST_CARD_INSERT_CD_LEVEL (0U) -#endif -#define SDMMCHOST_ENABLE_TUNING_FLAG(data) (data.dataType = kUSDHC_TransferDataTuning) -#define SDMMCHOST_ENABLE_BOOT_FLAG(data) (data.dataType = kUSDHC_TransferDataBoot) -#define SDMMCHOST_ENABLE_BOOT_CONTINOUS_FLAG(data) (data.dataType = kUSDHC_TransferDataBootcontinous) -#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_SIZE(config) (config->blockSize) -#define SDMMCHOST_GET_HOST_CONFIG_BLOCK_COUNT(config) (config->blockCount) -#define SDMMCHOST_GET_HOST_CONFIG_BOOT_MODE(config) (config->bootMode) -#define SDMMCHOST_EMPTY_CMD_FLAG(command) (command.type = kCARD_CommandTypeEmpty) -/*! @brief USDHC host capability*/ -enum _host_capability -{ - kSDMMCHOST_SupportAdma = kUSDHC_SupportAdmaFlag, - kSDMMCHOST_SupportHighSpeed = kUSDHC_SupportHighSpeedFlag, - kSDMMCHOST_SupportDma = kUSDHC_SupportDmaFlag, - kSDMMCHOST_SupportSuspendResume = kUSDHC_SupportSuspendResumeFlag, - kSDMMCHOST_SupportV330 = kUSDHC_SupportV330Flag, /* this define should depend on your board config */ - kSDMMCHOST_SupportV300 = kUSDHC_SupportV300Flag, /* this define should depend on your board config */ -#if defined(BOARD_SD_SUPPORT_180V) && !BOARD_SD_SUPPORT_180V - kSDMMCHOST_SupportV180 = SDMMCHOST_NOT_SUPPORT, /* this define should depend on you board config */ -#else - kSDMMCHOST_SupportV180 = kUSDHC_SupportV180Flag, /* this define should depend on you board config */ -#endif - kSDMMCHOST_SupportV120 = SDMMCHOST_NOT_SUPPORT, - kSDMMCHOST_Support4BitBusWidth = kUSDHC_Support4BitFlag, -#if defined(BOARD_MMC_SUPPORT_8BIT_BUS) -#if BOARD_MMC_SUPPORT_8BIT_BUS - kSDMMCHOST_Support8BitBusWidth = kUSDHC_Support8BitFlag, -#else - kSDMMCHOST_Support8BitBusWidth = SDMMCHOST_NOT_SUPPORT, -#endif -#else - kSDMMCHOST_Support8BitBusWidth = kUSDHC_Support8BitFlag, -#endif - kSDMMCHOST_SupportDDR50 = kUSDHC_SupportDDR50Flag, - kSDMMCHOST_SupportSDR104 = kUSDHC_SupportSDR104Flag, - kSDMMCHOST_SupportSDR50 = kUSDHC_SupportSDR50Flag, - kSDMMCHOST_SupportHS200 = kUSDHC_SupportSDR104Flag, -#if FSL_FEATURE_USDHC_HAS_HS400_MODE - kSDMMCHOST_SupportHS400 = SDMMCHOST_SUPPORT -#else - kSDMMCHOST_SupportHS400 = SDMMCHOST_NOT_SUPPORT, -#endif -}; - -/* Endian mode. */ -#define USDHC_ENDIAN_MODE kUSDHC_EndianModeLittle - -/* DMA mode */ -#define USDHC_DMA_MODE kUSDHC_DmaModeAdma2 -/* address align */ -#define SDMMCHOST_DMA_BUFFER_ADDR_ALIGN (USDHC_ADMA2_ADDRESS_ALIGN) - -/* Read/write watermark level. The bigger value indicates DMA has higher read/write performance. */ -#define USDHC_READ_WATERMARK_LEVEL (0x80U) -#define USDHC_WRITE_WATERMARK_LEVEL (0x80U) - -/* ADMA table length united as word. - * - * One ADMA2 table item occupy two words which can transfer maximum 0xFFFFU bytes one time. - * The more data to be transferred in one time, the bigger value of SDHC_ADMA_TABLE_WORDS need to be set. - */ -#define USDHC_ADMA_TABLE_WORDS (8U) /* define the ADMA descriptor table length */ -#define USDHC_ADMA2_ADDR_ALIGN (4U) /* define the ADMA2 descriptor table addr align size */ -#define USDHC_READ_BURST_LEN (8U) /*!< number of words USDHC read in a single burst */ -#define USDHC_WRITE_BURST_LEN (8U) /*!< number of words USDHC write in a single burst */ -#define USDHC_DATA_TIMEOUT (0xFU) /*!< data timeout counter value */ - -#endif /* (defined(FSL_FEATURE_SOC_SDHC_COUNT) && (FSL_FEATURE_SOC_SDHC_COUNT > 0U)) */ - -/*! @brief card detect callback definition */ -typedef void (*sdmmchost_cd_callback_t)(bool isInserted, void *userData); - -/*! @brief host Endian mode -* corresponding to driver define -*/ -enum _sdmmchost_endian_mode -{ - kSDMMCHOST_EndianModeBig = 0U, /*!< Big endian mode */ - kSDMMCHOST_EndianModeHalfWordBig = 1U, /*!< Half word big endian mode */ - kSDMMCHOST_EndianModeLittle = 2U, /*!< Little endian mode */ -}; - -/*! @brief sd card detect type */ -typedef enum _sdmmchost_detect_card_type -{ - kSDMMCHOST_DetectCardByGpioCD, /*!< sd card detect by CD pin through GPIO */ - kSDMMCHOST_DetectCardByHostCD, /*!< sd card detect by CD pin through host */ - kSDMMCHOST_DetectCardByHostDATA3, /*!< sd card detect by DAT3 pin through host */ -} sdmmchost_detect_card_type_t; - -/*! @brief sd card detect */ -typedef struct _sdmmchost_detect_card -{ - sdmmchost_detect_card_type_t cdType; /*!< card detect type */ - uint32_t cdTimeOut_ms; /*!< card detect timeout which allow 0 - 0xFFFFFFF, value 0 will return immediately, value - 0xFFFFFFFF will block until card is insert */ - - sdmmchost_cd_callback_t cardInserted; /*!< card inserted callback which is meaningful for interrupt case */ - sdmmchost_cd_callback_t cardRemoved; /*!< card removed callback which is meaningful for interrupt case */ - - void *userData; /*!< user data */ -} sdmmchost_detect_card_t; - -/*! @brief card power control function pointer */ -typedef void (*sdmmchost_pwr_t)(void); - -/*! @brief card power control */ -typedef struct _sdmmchost_pwr_card -{ - sdmmchost_pwr_t powerOn; /*!< power on function pointer */ - uint32_t powerOnDelay_ms; /*!< power on delay */ - - sdmmchost_pwr_t powerOff; /*!< power off function pointer */ - uint32_t powerOffDelay_ms; /*!< power off delay */ -} sdmmchost_pwr_card_t; - -/******************************************************************************* - * API - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @name adaptor function - * @{ - */ - -/*! - * @brief host not support function, this function is used for host not support feature - * @param void parameter ,used to avoid build warning - * @retval kStatus_Fail ,host do not suppport - */ -static inline status_t SDMMCHOST_NotSupport(void *parameter) -{ - parameter = parameter; - return kStatus_Success; -} - -/*! - * @brief Detect card insert, only need for SD cases. - * @param base the pointer to host base address - * @param cd card detect configuration - * @param waitCardStatus status which user want to wait - * @retval kStatus_Success detect card insert - * @retval kStatus_Fail card insert event fail - */ -status_t SDMMCHOST_WaitCardDetectStatus(SDMMCHOST_TYPE *hostBase, - const sdmmchost_detect_card_t *cd, - bool waitCardStatus); - -/*! - * @brief check card is present or not. - * @retval true card is present - * @retval false card is not present - */ -bool SDMMCHOST_IsCardPresent(void); - -/*! - * @brief Init host controller. - * @param host the pointer to host structure in card structure. - * @param userData specific user data - * @retval kStatus_Success host init success - * @retval kStatus_Fail event fail - */ -status_t SDMMCHOST_Init(SDMMCHOST_CONFIG *host, void *userData); - -/*! - * @brief reset host controller. - * @param host base address. - */ -void SDMMCHOST_Reset(SDMMCHOST_TYPE *base); - -/*! - * @brief host controller error recovery. - * @param host base address. - */ -void SDMMCHOST_ErrorRecovery(SDMMCHOST_TYPE *base); - -/*! - * @brief Deinit host controller. - * @param host the pointer to host structure in card structure. - */ -void SDMMCHOST_Deinit(void *host); - -/*! - * @brief host power off card function. - * @param base host base address. - * @param pwr depend on user define power configuration. - */ -void SDMMCHOST_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr); - -/*! - * @brief host power on card function. - * @param base host base address. - * @param pwr depend on user define power configuration. - */ -void SDMMCHOST_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr); - -/*! - * @brief SDMMC host delay function. - * @param milliseconds delay counter. - */ -void SDMMCHOST_Delay(uint32_t milliseconds); - -/* @} */ - -#if defined(__cplusplus) -} -#endif -/* @} */ -#endif /* _FSL_SDMMC_HOST_H */ diff --git a/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_spec.h b/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_spec.h deleted file mode 100644 index 735ecf3dde..0000000000 --- a/targets/FreeRTOS/UAC18/common/sdmmc/inc/fsl_sdmmc_spec.h +++ /dev/null @@ -1,1170 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2018 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#ifndef _FSL_SDMMC_SPEC_H_ -#define _FSL_SDMMC_SPEC_H_ - -#include - -/*! - * @addtogroup CARD - * @{ - */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ -/*! @brief SD/MMC card initialization clock frequency */ -#define SDMMC_CLOCK_400KHZ (400000U) -/*! @brief SD card bus frequency 1 in high-speed mode */ -#define SD_CLOCK_25MHZ (25000000U) -/*! @brief SD card bus frequency 2 in high-speed mode */ -#define SD_CLOCK_50MHZ (50000000U) -/*! @brief SD card bus frequency in SDR50 mode */ -#define SD_CLOCK_100MHZ (100000000U) -/*! @brief SD card bus frequency in SDR104 mode */ -#define SD_CLOCK_208MHZ (208000000U) -/*! @brief MMC card bus frequency 1 in high-speed mode */ -#define MMC_CLOCK_26MHZ (26000000U) -/*! @brief MMC card bus frequency 2 in high-speed mode */ -#define MMC_CLOCK_52MHZ (52000000U) -/*! @brief MMC card bus frequency in high-speed DDR52 mode */ -#define MMC_CLOCK_DDR52 (52000000U) -/*! @brief MMC card bus frequency in high-speed HS200 mode */ -#define MMC_CLOCK_HS200 (200000000U) -/*! @brief MMC card bus frequency in high-speed HS400 mode */ -#define MMC_CLOCK_HS400 (400000000U) - -/*!@brief mask convert */ -#define SDMMC_MASK(bit) (1U << (bit)) - -/*! @brief Card status bit in R1 */ -enum _sdmmc_r1_card_status_flag -{ - kSDMMC_R1OutOfRangeFlag = 31, /*!< Out of range status bit */ - kSDMMC_R1AddressErrorFlag = 30, /*!< Address error status bit */ - kSDMMC_R1BlockLengthErrorFlag = 29, /*!< Block length error status bit */ - kSDMMC_R1EraseSequenceErrorFlag = 28, /*!< Erase sequence error status bit */ - kSDMMC_R1EraseParameterErrorFlag = 27, /*!< Erase parameter error status bit */ - kSDMMC_R1WriteProtectViolationFlag = 26, /*!< Write protection violation status bit */ - kSDMMC_R1CardIsLockedFlag = 25, /*!< Card locked status bit */ - kSDMMC_R1LockUnlockFailedFlag = 24, /*!< lock/unlock error status bit */ - kSDMMC_R1CommandCrcErrorFlag = 23, /*!< CRC error status bit */ - kSDMMC_R1IllegalCommandFlag = 22, /*!< Illegal command status bit */ - kSDMMC_R1CardEccFailedFlag = 21, /*!< Card ecc error status bit */ - kSDMMC_R1CardControllerErrorFlag = 20, /*!< Internal card controller error status bit */ - kSDMMC_R1ErrorFlag = 19, /*!< A general or an unknown error status bit */ - kSDMMC_R1CidCsdOverwriteFlag = 16, /*!< Cid/csd overwrite status bit */ - kSDMMC_R1WriteProtectEraseSkipFlag = 15, /*!< Write protection erase skip status bit */ - kSDMMC_R1CardEccDisabledFlag = 14, /*!< Card ecc disabled status bit */ - kSDMMC_R1EraseResetFlag = 13, /*!< Erase reset status bit */ - kSDMMC_R1ReadyForDataFlag = 8, /*!< Ready for data status bit */ - kSDMMC_R1SwitchErrorFlag = 7, /*!< Switch error status bit */ - kSDMMC_R1ApplicationCommandFlag = 5, /*!< Application command enabled status bit */ - kSDMMC_R1AuthenticationSequenceErrorFlag = 3, /*!< error in the sequence of authentication process */ -}; - -/*! @brief R1 all the error flag */ -#define SDMMC_R1_ALL_ERROR_FLAG \ - (SDMMC_MASK(kSDMMC_R1OutOfRangeFlag) | SDMMC_MASK(kSDMMC_R1AddressErrorFlag) | \ - SDMMC_MASK(kSDMMC_R1BlockLengthErrorFlag) | SDMMC_MASK(kSDMMC_R1EraseSequenceErrorFlag) | \ - SDMMC_MASK(kSDMMC_R1EraseParameterErrorFlag) | SDMMC_MASK(kSDMMC_R1WriteProtectViolationFlag) | \ - SDMMC_MASK(kSDMMC_R1CardIsLockedFlag) | SDMMC_MASK(kSDMMC_R1LockUnlockFailedFlag) | \ - SDMMC_MASK(kSDMMC_R1CommandCrcErrorFlag) | SDMMC_MASK(kSDMMC_R1IllegalCommandFlag) | \ - SDMMC_MASK(kSDMMC_R1CardEccFailedFlag) | SDMMC_MASK(kSDMMC_R1CardControllerErrorFlag) | \ - SDMMC_MASK(kSDMMC_R1ErrorFlag) | SDMMC_MASK(kSDMMC_R1CidCsdOverwriteFlag) | \ - SDMMC_MASK(kSDMMC_R1AuthenticationSequenceErrorFlag)) - -/*! @brief R1: current state */ -#define SDMMC_R1_CURRENT_STATE(x) (((x)&0x00001E00U) >> 9U) - -/*! @brief CURRENT_STATE filed in R1 */ -typedef enum _sdmmc_r1_current_state -{ - kSDMMC_R1StateIdle = 0U, /*!< R1: current state: idle */ - kSDMMC_R1StateReady = 1U, /*!< R1: current state: ready */ - kSDMMC_R1StateIdentify = 2U, /*!< R1: current state: identification */ - kSDMMC_R1StateStandby = 3U, /*!< R1: current state: standby */ - kSDMMC_R1StateTransfer = 4U, /*!< R1: current state: transfer */ - kSDMMC_R1StateSendData = 5U, /*!< R1: current state: sending data */ - kSDMMC_R1StateReceiveData = 6U, /*!< R1: current state: receiving data */ - kSDMMC_R1StateProgram = 7U, /*!< R1: current state: programming */ - kSDMMC_R1StateDisconnect = 8U, /*!< R1: current state: disconnect */ -} sdmmc_r1_current_state_t; - -/*! @brief Error bit in SPI mode R1 */ -enum _sdspi_r1_error_status_flag -{ - kSDSPI_R1InIdleStateFlag = (1U << 0U), /*!< In idle state */ - kSDSPI_R1EraseResetFlag = (1U << 1U), /*!< Erase reset */ - kSDSPI_R1IllegalCommandFlag = (1U << 2U), /*!< Illegal command */ - kSDSPI_R1CommandCrcErrorFlag = (1U << 3U), /*!< Com crc error */ - kSDSPI_R1EraseSequenceErrorFlag = (1U << 4U), /*!< Erase sequence error */ - kSDSPI_R1AddressErrorFlag = (1U << 5U), /*!< Address error */ - kSDSPI_R1ParameterErrorFlag = (1U << 6U), /*!< Parameter error */ -}; - -/*! @brief Error bit in SPI mode R2 */ -enum _sdspi_r2_error_status_flag -{ - kSDSPI_R2CardLockedFlag = (1U << 0U), /*!< Card is locked */ - kSDSPI_R2WriteProtectEraseSkip = (1U << 1U), /*!< Write protect erase skip */ - kSDSPI_R2LockUnlockFailed = (1U << 1U), /*!< Lock/unlock command failed */ - kSDSPI_R2ErrorFlag = (1U << 2U), /*!< Unknown error */ - kSDSPI_R2CardControllerErrorFlag = (1U << 3U), /*!< Card controller error */ - kSDSPI_R2CardEccFailedFlag = (1U << 4U), /*!< Card ecc failed */ - kSDSPI_R2WriteProtectViolationFlag = (1U << 5U), /*!< Write protect violation */ - kSDSPI_R2EraseParameterErrorFlag = (1U << 6U), /*!< Erase parameter error */ - kSDSPI_R2OutOfRangeFlag = (1U << 7U), /*!< Out of range */ - kSDSPI_R2CsdOverwriteFlag = (1U << 7U), /*!< CSD overwrite */ -}; - -/*! @brief The bit mask for COMMAND VERSION field in R7 */ -#define SDSPI_R7_VERSION_SHIFT (28U) -/*! @brief The bit mask for COMMAND VERSION field in R7 */ -#define SDSPI_R7_VERSION_MASK (0xFU) -/*! @brief The bit shift for VOLTAGE ACCEPTED field in R7 */ -#define SDSPI_R7_VOLTAGE_SHIFT (8U) -/*! @brief The bit mask for VOLTAGE ACCEPTED field in R7 */ -#define SDSPI_R7_VOLTAGE_MASK (0xFU) -/*! @brief The bit mask for VOLTAGE 2.7V to 3.6V field in R7 */ -#define SDSPI_R7_VOLTAGE_27_36_MASK (0x1U << SDSPI_R7_VOLTAGE_SHIFT) -/*! @brief The bit shift for ECHO field in R7 */ -#define SDSPI_R7_ECHO_SHIFT (0U) -/*! @brief The bit mask for ECHO field in R7 */ -#define SDSPI_R7_ECHO_MASK (0xFFU) - -/*! @brief Data error token mask */ -#define SDSPI_DATA_ERROR_TOKEN_MASK (0xFU) -/*! @brief Data Error Token mask bit */ -enum _sdspi_data_error_token -{ - kSDSPI_DataErrorTokenError = (1U << 0U), /*!< Data error */ - kSDSPI_DataErrorTokenCardControllerError = (1U << 1U), /*!< Card controller error */ - kSDSPI_DataErrorTokenCardEccFailed = (1U << 2U), /*!< Card ecc error */ - kSDSPI_DataErrorTokenOutOfRange = (1U << 3U), /*!< Out of range */ -}; - -/*! @brief Data Token */ -typedef enum _sdspi_data_token -{ - kSDSPI_DataTokenBlockRead = 0xFEU, /*!< Single block read, multiple block read */ - kSDSPI_DataTokenSingleBlockWrite = 0xFEU, /*!< Single block write */ - kSDSPI_DataTokenMultipleBlockWrite = 0xFCU, /*!< Multiple block write */ - kSDSPI_DataTokenStopTransfer = 0xFDU, /*!< Stop transmission */ -} sdspi_data_token_t; - -/* Data Response Token mask */ -#define SDSPI_DATA_RESPONSE_TOKEN_MASK (0x1FU) /*!< Mask for data response bits */ -/*! @brief Data Response Token */ -typedef enum _sdspi_data_response_token -{ - kSDSPI_DataResponseTokenAccepted = 0x05U, /*!< Data accepted */ - kSDSPI_DataResponseTokenCrcError = 0x0BU, /*!< Data rejected due to CRC error */ - kSDSPI_DataResponseTokenWriteError = 0x0DU, /*!< Data rejected due to write error */ -} sdspi_data_response_token_t; - -/*! @brief SD card individual commands */ -typedef enum _sd_command -{ - kSD_SendRelativeAddress = 3U, /*!< Send Relative Address */ - kSD_Switch = 6U, /*!< Switch Function */ - kSD_SendInterfaceCondition = 8U, /*!< Send Interface Condition */ - kSD_VoltageSwitch = 11U, /*!< Voltage Switch */ - kSD_SpeedClassControl = 20U, /*!< Speed Class control */ - kSD_EraseWriteBlockStart = 32U, /*!< Write Block Start */ - kSD_EraseWriteBlockEnd = 33U, /*!< Write Block End */ - kSD_SendTuningBlock = 19U, /*!< Send Tuning Block */ -} sd_command_t; - -/*! @brief SDSPI individual commands */ -typedef enum _sdspi_command -{ - kSDSPI_CommandCrc = 59U, /*!< Command crc protection on/off */ -} sdspi_command_t; - -/*! @brief SD card individual application commands */ -typedef enum _sd_application_command -{ - kSD_ApplicationSetBusWdith = 6U, /*!< Set Bus Width */ - kSD_ApplicationStatus = 13U, /*!< Send SD status */ - kSD_ApplicationSendNumberWriteBlocks = 22U, /*!< Send Number Of Written Blocks */ - kSD_ApplicationSetWriteBlockEraseCount = 23U, /*!< Set Write Block Erase Count */ - kSD_ApplicationSendOperationCondition = 41U, /*!< Send Operation Condition */ - kSD_ApplicationSetClearCardDetect = 42U, /*!< Set Connnect/Disconnect pull up on detect pin */ - kSD_ApplicationSendScr = 51U, /*!< Send Scr */ -} sd_application_command_t; - -/*! @brief SD card command class */ -enum _sdmmc_command_class -{ - kSDMMC_CommandClassBasic = (1U << 0U), /*!< Card command class 0 */ - kSDMMC_CommandClassBlockRead = (1U << 2U), /*!< Card command class 2 */ - kSDMMC_CommandClassBlockWrite = (1U << 4U), /*!< Card command class 4 */ - kSDMMC_CommandClassErase = (1U << 5U), /*!< Card command class 5 */ - kSDMMC_CommandClassWriteProtect = (1U << 6U), /*!< Card command class 6 */ - kSDMMC_CommandClassLockCard = (1U << 7U), /*!< Card command class 7 */ - kSDMMC_CommandClassApplicationSpecific = (1U << 8U), /*!< Card command class 8 */ - kSDMMC_CommandClassInputOutputMode = (1U << 9U), /*!< Card command class 9 */ - kSDMMC_CommandClassSwitch = (1U << 10U), /*!< Card command class 10 */ -}; - -/*! @brief OCR register in SD card */ -enum _sd_ocr_flag -{ - kSD_OcrPowerUpBusyFlag = 31, /*!< Power up busy status */ - kSD_OcrHostCapacitySupportFlag = 30, /*!< Card capacity status */ - kSD_OcrCardCapacitySupportFlag = kSD_OcrHostCapacitySupportFlag, /*!< Card capacity status */ - kSD_OcrSwitch18RequestFlag = 24, /*!< Switch to 1.8V request */ - kSD_OcrSwitch18AcceptFlag = kSD_OcrSwitch18RequestFlag, /*!< Switch to 1.8V accepted */ - kSD_OcrVdd27_28Flag = 15, /*!< VDD 2.7-2.8 */ - kSD_OcrVdd28_29Flag = 16, /*!< VDD 2.8-2.9 */ - kSD_OcrVdd29_30Flag = 17, /*!< VDD 2.9-3.0 */ - kSD_OcrVdd30_31Flag = 18, /*!< VDD 2.9-3.0 */ - kSD_OcrVdd31_32Flag = 19, /*!< VDD 3.0-3.1 */ - kSD_OcrVdd32_33Flag = 20, /*!< VDD 3.1-3.2 */ - kSD_OcrVdd33_34Flag = 21, /*!< VDD 3.2-3.3 */ - kSD_OcrVdd34_35Flag = 22, /*!< VDD 3.3-3.4 */ - kSD_OcrVdd35_36Flag = 23, /*!< VDD 3.4-3.5 */ -}; - -/*! @brief SD card specification version number */ -enum _sd_specification_version -{ - kSD_SpecificationVersion1_0 = (1U << 0U), /*!< SD card version 1.0-1.01 */ - kSD_SpecificationVersion1_1 = (1U << 1U), /*!< SD card version 1.10 */ - kSD_SpecificationVersion2_0 = (1U << 2U), /*!< SD card version 2.00 */ - kSD_SpecificationVersion3_0 = (1U << 3U), /*!< SD card version 3.0 */ -}; - -/*! @brief SD card bus width */ -typedef enum _sd_data_bus_width -{ - kSD_DataBusWidth1Bit = 0U, /*!< SD data bus width 1-bit mode */ - kSD_DataBusWidth4Bit = 1U, /*!< SD data bus width 4-bit mode */ -} sd_data_bus_width_t; - -/*! @brief SD card switch mode */ -typedef enum _sd_switch_mode -{ - kSD_SwitchCheck = 0U, /*!< SD switch mode 0: check function */ - kSD_SwitchSet = 1U, /*!< SD switch mode 1: set function */ -} sd_switch_mode_t; - -/*! @brief SD card CSD register flags */ -enum _sd_csd_flag -{ - kSD_CsdReadBlockPartialFlag = (1U << 0U), /*!< Partial blocks for read allowed [79:79] */ - kSD_CsdWriteBlockMisalignFlag = (1U << 1U), /*!< Write block misalignment [78:78] */ - kSD_CsdReadBlockMisalignFlag = (1U << 2U), /*!< Read block misalignment [77:77] */ - kSD_CsdDsrImplementedFlag = (1U << 3U), /*!< DSR implemented [76:76] */ - kSD_CsdEraseBlockEnabledFlag = (1U << 4U), /*!< Erase single block enabled [46:46] */ - kSD_CsdWriteProtectGroupEnabledFlag = (1U << 5U), /*!< Write protect group enabled [31:31] */ - kSD_CsdWriteBlockPartialFlag = (1U << 6U), /*!< Partial blocks for write allowed [21:21] */ - kSD_CsdFileFormatGroupFlag = (1U << 7U), /*!< File format group [15:15] */ - kSD_CsdCopyFlag = (1U << 8U), /*!< Copy flag [14:14] */ - kSD_CsdPermanentWriteProtectFlag = (1U << 9U), /*!< Permanent write protection [13:13] */ - kSD_CsdTemporaryWriteProtectFlag = (1U << 10U), /*!< Temporary write protection [12:12] */ -}; - -/*! @brief SD card SCR register flags */ -enum _sd_scr_flag -{ - kSD_ScrDataStatusAfterErase = (1U << 0U), /*!< Data status after erases [55:55] */ - kSD_ScrSdSpecification3 = (1U << 1U), /*!< Specification version 3.00 or higher [47:47]*/ -}; - -/*! @brief SD timing function number */ -enum _sd_timing_function -{ - kSD_FunctionSDR12Deafult = 0U, /*!< SDR12 mode & default*/ - kSD_FunctionSDR25HighSpeed = 1U, /*!< SDR25 & high speed*/ - kSD_FunctionSDR50 = 2U, /*!< SDR50 mode*/ - kSD_FunctionSDR104 = 3U, /*!< SDR104 mode*/ - kSD_FunctionDDR50 = 4U, /*!< DDR50 mode*/ -}; - -/*! @brief SD group number */ -enum _sd_group_num -{ - kSD_GroupTimingMode = 0U, /*!< acess mode group*/ - kSD_GroupCommandSystem = 1U, /*!< command system group*/ - kSD_GroupDriverStrength = 2U, /*!< driver strength group*/ - kSD_GroupCurrentLimit = 3U, /*!< current limit group*/ -}; - -/*! @brief SD card timing mode flags */ -typedef enum _sd_timing_mode -{ - kSD_TimingSDR12DefaultMode = 0U, /*!< Identification mode & SDR12 */ - kSD_TimingSDR25HighSpeedMode = 1U, /*!< High speed mode & SDR25 */ - kSD_TimingSDR50Mode = 2U, /*!< SDR50 mode*/ - kSD_TimingSDR104Mode = 3U, /*!< SDR104 mode */ - kSD_TimingDDR50Mode = 4U, /*!< DDR50 mode */ -} sd_timing_mode_t; - -/*! @brief SD card driver strength */ -typedef enum _sd_driver_strength -{ - kSD_DriverStrengthTypeB = 0U, /*!< default driver strength*/ - kSD_DriverStrengthTypeA = 1U, /*!< driver strength TYPE A */ - kSD_DriverStrengthTypeC = 2U, /*!< driver strength TYPE C */ - kSD_DriverStrengthTypeD = 3U, /*!< driver strength TYPE D */ -} sd_driver_strength_t; - -/*! @brief SD card current limit */ -typedef enum _sd_max_current -{ - kSD_CurrentLimit200MA = 0U, /*!< default current limit */ - kSD_CurrentLimit400MA = 1U, /*!< current limit to 400MA */ - kSD_CurrentLimit600MA = 2U, /*!< current limit to 600MA */ - kSD_CurrentLimit800MA = 3U, /*!< current limit to 800MA */ -} sd_max_current_t; - -/*! @brief SD/MMC card common commands */ -typedef enum _sdmmc_command -{ - kSDMMC_GoIdleState = 0U, /*!< Go Idle State */ - kSDMMC_AllSendCid = 2U, /*!< All Send CID */ - kSDMMC_SetDsr = 4U, /*!< Set DSR */ - kSDMMC_SelectCard = 7U, /*!< Select Card */ - kSDMMC_SendCsd = 9U, /*!< Send CSD */ - kSDMMC_SendCid = 10U, /*!< Send CID */ - kSDMMC_StopTransmission = 12U, /*!< Stop Transmission */ - kSDMMC_SendStatus = 13U, /*!< Send Status */ - kSDMMC_GoInactiveState = 15U, /*!< Go Inactive State */ - kSDMMC_SetBlockLength = 16U, /*!< Set Block Length */ - kSDMMC_ReadSingleBlock = 17U, /*!< Read Single Block */ - kSDMMC_ReadMultipleBlock = 18U, /*!< Read Multiple Block */ - kSDMMC_SetBlockCount = 23U, /*!< Set Block Count */ - kSDMMC_WriteSingleBlock = 24U, /*!< Write Single Block */ - kSDMMC_WriteMultipleBlock = 25U, /*!< Write Multiple Block */ - kSDMMC_ProgramCsd = 27U, /*!< Program CSD */ - kSDMMC_SetWriteProtect = 28U, /*!< Set Write Protect */ - kSDMMC_ClearWriteProtect = 29U, /*!< Clear Write Protect */ - kSDMMC_SendWriteProtect = 30U, /*!< Send Write Protect */ - kSDMMC_Erase = 38U, /*!< Erase */ - kSDMMC_LockUnlock = 42U, /*!< Lock Unlock */ - kSDMMC_ApplicationCommand = 55U, /*!< Send Application Command */ - kSDMMC_GeneralCommand = 56U, /*!< General Purpose Command */ - kSDMMC_ReadOcr = 58U, /*!< Read OCR */ -} sdmmc_command_t; - -/*! @brief sdio card cccr register addr */ -enum _sdio_cccr_reg -{ - kSDIO_RegCCCRSdioVer = 0x00U, /*!< CCCR & SDIO version*/ - kSDIO_RegSDVersion = 0x01U, /*!< SD version */ - kSDIO_RegIOEnable = 0x02U, /*!< io enable register */ - kSDIO_RegIOReady = 0x03U, /*!< io ready register */ - kSDIO_RegIOIntEnable = 0x04U, /*!< io interrupt enable register */ - kSDIO_RegIOIntPending = 0x05U, /*!< io interrupt pending register */ - kSDIO_RegIOAbort = 0x06U, /*!< io abort register */ - kSDIO_RegBusInterface = 0x07U, /*!< bus interface register */ - kSDIO_RegCardCapability = 0x08U, /*!< card capability register */ - kSDIO_RegCommonCISPointer = 0x09U, /*!< common CIS pointer register */ - kSDIO_RegBusSuspend = 0x0C, /*!< bus suspend register */ - kSDIO_RegFunctionSelect = 0x0DU, /*!< function select register */ - kSDIO_RegExecutionFlag = 0x0EU, /*!< execution flag register */ - kSDIO_RegReadyFlag = 0x0FU, /*!< ready flag register */ - kSDIO_RegFN0BlockSizeLow = 0x10U, /*!< FN0 block size register */ - kSDIO_RegFN0BlockSizeHigh = 0x11U, /*!< FN0 block size register */ - kSDIO_RegPowerControl = 0x12U, /*!< power control register */ - kSDIO_RegHighSpeed = 0x13U, /*!< high speed register */ -}; - -/*! @brief sdio card individual commands */ -typedef enum _sdio_command -{ - kSDIO_SendRelativeAddress = 3U, /*!< send relative address */ - kSDIO_SendOperationCondition = 5U, /*!< send operation condition */ - kSDIO_SendInterfaceCondition = 8U, /*!< send interface condition */ - kSDIO_RWIODirect = 52U, /*!< read/write IO direct command */ - kSDIO_RWIOExtended = 53U, /*!< read/write IO extended command */ -} sdio_command_t; - -/*! @brief sdio card individual commands */ -typedef enum _sdio_func_num -{ - kSDIO_FunctionNum0, /*!< sdio function0*/ - kSDIO_FunctionNum1, /*!< sdio function1*/ - kSDIO_FunctionNum2, /*!< sdio function2*/ - kSDIO_FunctionNum3, /*!< sdio function3*/ - kSDIO_FunctionNum4, /*!< sdio function4*/ - kSDIO_FunctionNum5, /*!< sdio function5*/ - kSDIO_FunctionNum6, /*!< sdio function6*/ - kSDIO_FunctionNum7, /*!< sdio function7*/ - kSDIO_FunctionMemory, /*!< for combo card*/ -} sdio_func_num_t; - -#define SDIO_CMD_ARGUMENT_RW_POS (31U) /*!< read/write flag position */ -#define SDIO_CMD_ARGUMENT_FUNC_NUM_POS (28U) /*!< function number position */ -#define SDIO_DIRECT_CMD_ARGUMENT_RAW_POS (27U) /*!< direct raw flag position */ -#define SDIO_CMD_ARGUMENT_REG_ADDR_POS (9U) /*!< direct reg addr position */ -#define SDIO_CMD_ARGUMENT_REG_ADDR_MASK (0x1FFFFU) /*!< direct reg addr mask */ -#define SDIO_DIRECT_CMD_DATA_MASK (0xFFU) /*!< data mask */ - -#define SDIO_EXTEND_CMD_ARGUMENT_BLOCK_MODE_POS (27U) /*!< extended command argument block mode bit position */ -#define SDIO_EXTEND_CMD_ARGUMENT_OP_CODE_POS (26U) /*!< extended command argument OP Code bit position */ -#define SDIO_EXTEND_CMD_BLOCK_MODE_MASK (0x08000000U) /*!< block mode mask */ -#define SDIO_EXTEND_CMD_OP_CODE_MASK (0x04000000U) /*!< op code mask */ -#define SDIO_EXTEND_CMD_COUNT_MASK (0x1FFU) /*!< byte/block count mask */ -#define SDIO_MAX_BLOCK_SIZE (2048U) /*!< max block size */ -#define SDIO_FBR_BASE(x) (x * 0x100U) /*!< function basic register */ -#define SDIO_TPL_CODE_END (0xFFU) /*!< tuple end */ -#define SDIO_TPL_CODE_MANIFID (0x20U) /*!< manufacturer ID */ -#define SDIO_TPL_CODE_FUNCID (0x21U) /*!< function ID */ -#define SDIO_TPL_CODE_FUNCE (0x22U) /*!< function extension tuple*/ -/*! @brief sdio command response flag */ -enum _sdio_status_flag -{ - kSDIO_StatusCmdCRCError = 0x8000U, /*!< the CRC check of the previous cmd fail*/ - kSDIO_StatusIllegalCmd = 0x4000U, /*!< cmd illegal for the card state */ - kSDIO_StatusR6Error = 0x2000U, /*!< special for R6 error status */ - kSDIO_StatusError = 0x0800U, /*!< A general or an unknown error occurred */ - kSDIO_StatusFunctionNumError = 0x0200U, /*!< invail function error */ - kSDIO_StatusOutofRange = 0x0100U, /*!< cmd argument was out of the allowed range*/ -}; - -/*! @brief sdio operation condition flag */ -enum _sdio_ocr_flag -{ - kSDIO_OcrPowerUpBusyFlag = 31, /*!< Power up busy status */ - kSDIO_OcrIONumber = 28, /*!< number of IO function */ - kSDIO_OcrMemPresent = 27, /*!< memory present flag */ - - kSDIO_OcrVdd20_21Flag = 8, /*!< VDD 2.0-2.1 */ - kSDIO_OcrVdd21_22Flag = 9, /*!< VDD 2.1-2.2 */ - kSDIO_OcrVdd22_23Flag = 10, /*!< VDD 2.2-2.3 */ - kSDIO_OcrVdd23_24Flag = 11, /*!< VDD 2.3-2.4 */ - kSDIO_OcrVdd24_25Flag = 12, /*!< VDD 2.4-2.5 */ - kSDIO_OcrVdd25_26Flag = 13, /*!< VDD 2.5-2.6 */ - kSDIO_OcrVdd26_27Flag = 14, /*!< VDD 2.6-2.7 */ - kSDIO_OcrVdd27_28Flag = 15, /*!< VDD 2.7-2.8 */ - kSDIO_OcrVdd28_29Flag = 16, /*!< VDD 2.8-2.9 */ - kSDIO_OcrVdd29_30Flag = 17, /*!< VDD 2.9-3.0 */ - kSDIO_OcrVdd30_31Flag = 18, /*!< VDD 2.9-3.0 */ - kSDIO_OcrVdd31_32Flag = 19, /*!< VDD 3.0-3.1 */ - kSDIO_OcrVdd32_33Flag = 20, /*!< VDD 3.1-3.2 */ - kSDIO_OcrVdd33_34Flag = 21, /*!< VDD 3.2-3.3 */ - kSDIO_OcrVdd34_35Flag = 22, /*!< VDD 3.3-3.4 */ - kSDIO_OcrVdd35_36Flag = 23, /*!< VDD 3.4-3.5 */ -}; - -/*! @brief sdio capability flag */ -enum _sdio_capability_flag -{ - kSDIO_CCCRSupportDirectCmdDuringDataTrans = (1U << 0U), /*!< support direct cmd during data transfer */ - kSDIO_CCCRSupportMultiBlock = (1U << 1U), /*!< support multi block mode */ - kSDIO_CCCRSupportReadWait = (1U << 2U), /*!< support read wait */ - kSDIO_CCCRSupportSuspendResume = (1U << 3U), /*!< support suspend resume */ - kSDIO_CCCRSupportIntDuring4BitDataTrans = (1U << 4U), /*!< support interrupt during 4-bit data transfer */ - kSDIO_CCCRSupportLowSpeed1Bit = (1U << 6U), /*!< support low speed 1bit mode */ - kSDIO_CCCRSupportLowSpeed4Bit = (1U << 7U), /*!< support low speed 4bit mode */ - kSDIO_CCCRSupportMasterPowerControl = (1U << 8U), /*!< support master power control */ - kSDIO_CCCRSupportHighSpeed = (1U << 9U), /*!< support high speed */ - kSDIO_CCCRSupportContinuousSPIInt = (1U << 10U), /*!< support continuous SPI interrupt */ -}; - -/*! @brief sdio fbr flag */ -enum _sdio_fbr_flag -{ - kSDIO_FBRSupportCSA = (1U << 0U), /*!< function support CSA */ - kSDIO_FBRSupportPowerSelection = (1U << 1U), /*!< function support power selection */ -}; - -/*! @brief sdio bus width */ -typedef enum _sdio_bus_width -{ - kSDIO_DataBus1Bit = 0x00U, /*!< 1bit bus mode */ - kSDIO_DataBus4Bit = 0X02U, /*!< 4 bit bus mode*/ -} sdio_bus_width_t; - -/*! @brief MMC card individual commands */ -typedef enum _mmc_command -{ - kMMC_SendOperationCondition = 1U, /*!< Send Operation Condition */ - kMMC_SetRelativeAddress = 3U, /*!< Set Relative Address */ - kMMC_SleepAwake = 5U, /*!< Sleep Awake */ - kMMC_Switch = 6U, /*!< Switch */ - kMMC_SendExtendedCsd = 8U, /*!< Send EXT_CSD */ - kMMC_ReadDataUntilStop = 11U, /*!< Read Data Until Stop */ - kMMC_BusTestRead = 14U, /*!< Test Read */ - kMMC_SendingBusTest = 19U, /*!< test bus width cmd*/ - kMMC_WriteDataUntilStop = 20U, /*!< Write Data Until Stop */ - kMMC_SendTuningBlock = 21U, /*!< MMC sending tuning block */ - kMMC_ProgramCid = 26U, /*!< Program CID */ - kMMC_EraseGroupStart = 35U, /*!< Erase Group Start */ - kMMC_EraseGroupEnd = 36U, /*!< Erase Group End */ - kMMC_FastInputOutput = 39U, /*!< Fast IO */ - kMMC_GoInterruptState = 40U, /*!< Go interrupt State */ -} mmc_command_t; - -/*! @brief MMC card classified as voltage range */ -typedef enum _mmc_classified_voltage -{ - kMMC_ClassifiedVoltageHigh = 0U, /*!< High-voltage MMC card */ - kMMC_ClassifiedVoltageDual = 1U, /*!< Dual-voltage MMC card */ -} mmc_classified_voltage_t; - -/*! @brief MMC card classified as density level */ -typedef enum _mmc_classified_density -{ - kMMC_ClassifiedDensityWithin2GB = 0U, /*!< Density byte is less than or equal 2GB */ - kMMC_ClassifiedDensityHigher2GB = 1U, /* Density byte is higher than 2GB */ -} mmc_classified_density_t; - -/*! @brief The bit mask for VOLTAGE WINDOW 1.70V to 1.95V field in OCR */ -#define MMC_OCR_V170TO195_SHIFT (7U) -/*! @brief The bit mask for VOLTAGE WINDOW 1.70V to 1.95V field in OCR */ -#define MMC_OCR_V170TO195_MASK (0x00000080U) -/*! @brief The bit shift for VOLTAGE WINDOW 2.00V to 2.60V field in OCR */ -#define MMC_OCR_V200TO260_SHIFT (8U) -/*! @brief The bit mask for VOLTAGE WINDOW 2.00V to 2.60V field in OCR */ -#define MMC_OCR_V200TO260_MASK (0x00007F00U) -/*! @brief The bit shift for VOLTAGE WINDOW 2.70V to 3.60V field in OCR */ -#define MMC_OCR_V270TO360_SHIFT (15U) -/*! @brief The bit mask for VOLTAGE WINDOW 2.70V to 3.60V field in OCR */ -#define MMC_OCR_V270TO360_MASK (0x00FF8000U) -/*! @brief The bit shift for ACCESS MODE field in OCR */ -#define MMC_OCR_ACCESS_MODE_SHIFT (29U) -/*! @brief The bit mask for ACCESS MODE field in OCR */ -#define MMC_OCR_ACCESS_MODE_MASK (0x60000000U) -/*! @brief The bit shift for BUSY field in OCR */ -#define MMC_OCR_BUSY_SHIFT (31U) -/*! @brief The bit mask for BUSY field in OCR */ -#define MMC_OCR_BUSY_MASK (1U << MMC_OCR_BUSY_SHIFT) - -/*! @brief MMC card access mode(Access mode in OCR). */ -typedef enum _mmc_access_mode -{ - kMMC_AccessModeByte = 0U, /*!< The card should be accessed as byte */ - kMMC_AccessModeSector = 2U, /*!< The card should be accessed as sector */ -} mmc_access_mode_t; - -/*! @brief MMC card voltage window(VDD voltage window in OCR). */ -typedef enum _mmc_voltage_window -{ - kMMC_VoltageWindowNone = 0U, /*!< voltage window is not define by user*/ - kMMC_VoltageWindow120 = 0x01U, /*!< Voltage window is 1.20V */ - kMMC_VoltageWindow170to195 = 0x02U, /*!< Voltage window is 1.70V to 1.95V */ - kMMC_VoltageWindows270to360 = 0x1FFU, /*!< Voltage window is 2.70V to 3.60V */ -} mmc_voltage_window_t; - -/*! @brief CSD structure version(CSD_STRUCTURE in CSD). */ -typedef enum _mmc_csd_structure_version -{ - kMMC_CsdStrucureVersion10 = 0U, /*!< CSD version No. 1.0 */ - kMMC_CsdStrucureVersion11 = 1U, /*!< CSD version No. 1.1 */ - kMMC_CsdStrucureVersion12 = 2U, /*!< CSD version No. 1.2 */ - kMMC_CsdStrucureVersionInExtcsd = 3U, /*!< Version coded in Extended CSD */ -} mmc_csd_structure_version_t; - -/*! @brief MMC card specification version(SPEC_VERS in CSD). */ -typedef enum _mmc_specification_version -{ - kMMC_SpecificationVersion0 = 0U, /*!< Allocated by MMCA */ - kMMC_SpecificationVersion1 = 1U, /*!< Allocated by MMCA */ - kMMC_SpecificationVersion2 = 2U, /*!< Allocated by MMCA */ - kMMC_SpecificationVersion3 = 3U, /*!< Allocated by MMCA */ - kMMC_SpecificationVersion4 = 4U, /*!< Version 4.1/4.2/4.3/4.41-4.5-4.51-5.0 */ -} mmc_specification_version_t; - -/*! @brief The bit shift for FREQUENCY UNIT field in TRANSFER SPEED(TRAN-SPEED in Extended CSD) */ -#define MMC_TRANSFER_SPEED_FREQUENCY_UNIT_SHIFT (0U) -/*! @brief The bit mask for FRQEUENCY UNIT in TRANSFER SPEED */ -#define MMC_TRANSFER_SPEED_FREQUENCY_UNIT_MASK (0x07U) -/*! @brief The bit shift for MULTIPLIER field in TRANSFER SPEED */ -#define MMC_TRANSFER_SPEED_MULTIPLIER_SHIFT (3U) -/*! @brief The bit mask for MULTIPLIER field in TRANSFER SPEED */ -#define MMC_TRANSFER_SPEED_MULTIPLIER_MASK (0x78U) - -/*! @brief Read the value of FREQUENCY UNIT in TRANSFER SPEED. */ -#define READ_MMC_TRANSFER_SPEED_FREQUENCY_UNIT(CSD) \ - (((CSD.transferSpeed) & MMC_TRANSFER_SPEED_FREQUENCY_UNIT_MASK) >> MMC_TRANSFER_SPEED_FREQUENCY_UNIT_SHIFT) -/*! @brief Read the value of MULTIPLER filed in TRANSFER SPEED. */ -#define READ_MMC_TRANSFER_SPEED_MULTIPLIER(CSD) \ - (((CSD.transferSpeed) & MMC_TRANSFER_SPEED_MULTIPLIER_MASK) >> MMC_TRANSFER_SPEED_MULTIPLIER_SHIFT) - -/*! @brief MMC card Extended CSD fix version(EXT_CSD_REV in Extended CSD) */ -enum _mmc_extended_csd_revision -{ - kMMC_ExtendedCsdRevision10 = 0U, /*!< Revision 1.0 */ - kMMC_ExtendedCsdRevision11 = 1U, /*!< Revision 1.1 */ - kMMC_ExtendedCsdRevision12 = 2U, /*!< Revision 1.2 */ - kMMC_ExtendedCsdRevision13 = 3U, /*!< Revision 1.3 MMC4.3*/ - kMMC_ExtendedCsdRevision14 = 4U, /*!< Revision 1.4 obsolete*/ - kMMC_ExtendedCsdRevision15 = 5U, /*!< Revision 1.5 MMC4.41*/ - kMMC_ExtendedCsdRevision16 = 6U, /*!< Revision 1.6 MMC4.5*/ - kMMC_ExtendedCsdRevision17 = 7U, /*!< Revision 1.7 MMC5.0 */ -}; - -/*! @brief MMC card command set(COMMAND_SET in Extended CSD) */ -typedef enum _mmc_command_set -{ - kMMC_CommandSetStandard = 0U, /*!< Standard MMC */ - kMMC_CommandSet1 = 1U, /*!< Command set 1 */ - kMMC_CommandSet2 = 2U, /*!< Command set 2 */ - kMMC_CommandSet3 = 3U, /*!< Command set 3 */ - kMMC_CommandSet4 = 4U, /*!< Command set 4 */ -} mmc_command_set_t; - -/*! @brief boot support(BOOT_INFO in Extended CSD) */ -enum _mmc_support_boot_mode -{ - kMMC_SupportAlternateBoot = 1U, /*!< support alternative boot mode*/ - kMMC_SupportDDRBoot = 2U, /*!< support DDR boot mode*/ - kMMC_SupportHighSpeedBoot = 4U, /*!< support high speed boot mode*/ -}; -/*! @brief The power class value bit mask when bus in 4 bit mode */ -#define MMC_POWER_CLASS_4BIT_MASK (0x0FU) -/*! @brief The power class current value bit mask when bus in 8 bit mode */ -#define MMC_POWER_CLASS_8BIT_MASK (0xF0U) - -/*! @brief MMC card high-speed timing(HS_TIMING in Extended CSD) */ -typedef enum _mmc_high_speed_timing -{ - kMMC_HighSpeedTimingNone = 0U, /*!< MMC card using none high-speed timing */ - kMMC_HighSpeedTiming = 1U, /*!< MMC card using high-speed timing */ - kMMC_HighSpeed200Timing = 2U, /*!< MMC card high speed 200 timing*/ - kMMC_HighSpeed400Timing = 3U, /*!< MMC card high speed 400 timing*/ -} mmc_high_speed_timing_t; - -/*! @brief The number of data bus width type */ -#define MMC_DATA_BUS_WIDTH_TYPE_NUMBER (3U) -/*! @brief MMC card data bus width(BUS_WIDTH in Extended CSD) */ -typedef enum _mmc_data_bus_width -{ - kMMC_DataBusWidth1bit = 0U, /*!< MMC data bus width is 1 bit */ - kMMC_DataBusWidth4bit = 1U, /*!< MMC data bus width is 4 bits */ - kMMC_DataBusWidth8bit = 2U, /*!< MMC data bus width is 8 bits */ - kMMC_DataBusWidth4bitDDR = 5U, /*!< MMC data bus width is 4 bits ddr */ - kMMC_DataBusWidth8bitDDR = 6U, /*!< MMC data bus width is 8 bits ddr */ -} mmc_data_bus_width_t; - -/*! @brief MMC card boot partition enabled(BOOT_PARTITION_ENABLE in Extended CSD) */ -typedef enum _mmc_boot_partition_enable -{ - kMMC_BootPartitionEnableNot = 0U, /*!< Device not boot enabled (default) */ - kMMC_BootPartitionEnablePartition1 = 1U, /*!< Boot partition 1 enabled for boot */ - kMMC_BootPartitionEnablePartition2 = 2U, /*!< Boot partition 2 enabled for boot */ - kMMC_BootPartitionEnableUserAera = 7U, /*!< User area enabled for boot */ -} mmc_boot_partition_enable_t; - -/*! @brief boot mode configuration - * Note: HS200 & HS400 is not support during BOOT operation. - */ -typedef enum _mmc_boot_timing_mode -{ - kMMC_BootModeSDRWithDefaultTiming = 0U << 3U, /*!< boot mode single data rate with backward compatiable timings */ - kMMC_BootModeSDRWithHighSpeedTiming = 1U << 3U, /*!< boot mode single data rate with high speed timing */ - kMMC_BootModeDDRTiming = 2U << 3U, /*!< boot mode dual date rate */ -} mmc_boot_timing_mode_t; - -/*! @brief MMC card boot partition write protect configurations - * All the bits in BOOT_WP register, except the two R/W bits B_PERM_WP_DIS - * and B_PERM_WP_EN, shall only be written once per power cycle.The protection - * mdde intended for both boot areas will be set with a single write. - */ -typedef enum _mmc_boot_partition_wp -{ - kMMC_BootPartitionWPDisable = 0x50U, /*!< boot partition write protection disable */ - kMMC_BootPartitionPwrWPToBothPartition = - 0x01U, /*!< power on period write protection apply to both boot partitions */ - kMMC_BootPartitionPermWPToBothPartition = 0x04U, /*!< permanent write protection apply to both boot partitions */ - - kMMC_BootPartitionPwrWPToPartition1 = (1U << 7U) | 1U, /*!< power on period write protection apply to partition1 */ - kMMC_BootPartitionPwrWPToPartition2 = (1U << 7U) | 3U, /*!< power on period write protection apply to partition2 */ - - kMMC_BootPartitionPermWPToPartition1 = - (1U << 7U) | (1U << 2U), /*!< permanent write protection apply to partition1 */ - kMMC_BootPartitionPermWPToPartition2 = - (1U << 7U) | (3U << 2U), /*!< permanent write protection apply to partition2 */ - - kMMC_BootPartitionPermWPToPartition1PwrWPToPartition2 = - (1U << 7U) | (1U << 2U) | - 3U, /*!< permanent write protection apply to partition1, power on period write protection apply to partition2 */ - kMMC_BootPartitionPermWPToPartition2PwrWPToPartition1 = - (1U << 7U) | (3U << 2U) | - 1U, /*!< permanent write protection apply to partition2, power on period write protection apply to partition1 */ -} mmc_boot_partition_wp_t; - -/*! @brief MMC card boot partition write protect status */ -enum _mmc_boot_partition_wp_status -{ - kMMC_BootPartitionNotProtected = 0U, /*!< boot partition not protected */ - kMMC_BootPartitionPwrProtected = 1U, /*!< boot partition is power on period write protected */ - kMMC_BootPartitionPermProtected = 2U, /*!< boot partition is permanently protected */ -}; - -/*! @brief MMC card partition to be accessed(BOOT_PARTITION_ACCESS in Extended CSD) */ -typedef enum _mmc_access_partition -{ - kMMC_AccessPartitionUserAera = 0U, /*!< No access to boot partition (default), normal partition */ - kMMC_AccessPartitionBoot1 = 1U, /*!< Read/Write boot partition 1 */ - kMMC_AccessPartitionBoot2 = 2U, /*!< Read/Write boot partition 2*/ - kMMC_AccessRPMB = 3U, /*!< Replay protected mem block */ - kMMC_AccessGeneralPurposePartition1 = 4U, /*!< access to general purpose partition 1 */ - kMMC_AccessGeneralPurposePartition2 = 5U, /*!< access to general purpose partition 2 */ - kMMC_AccessGeneralPurposePartition3 = 6U, /*!< access to general purpose partition 3 */ - kMMC_AccessGeneralPurposePartition4 = 7U, /*!< access to general purpose partition 4 */ -} mmc_access_partition_t; - -/*! @brief The bit shift for PARTITION ACCESS filed in BOOT CONFIG (BOOT_CONFIG in Extend CSD) */ -#define MMC_PARTITION_CONFIG_PARTITION_ACCESS_SHIFT (0U) -/*! @brief The bit mask for PARTITION ACCESS field in BOOT CONFIG */ -#define MMC_PARTITION_CONFIG_PARTITION_ACCESS_MASK (0x00000007U) -/*! @brief The bit shift for PARTITION ENABLE field in BOOT CONFIG */ -#define MMC_PARTITION_CONFIG_PARTITION_ENABLE_SHIFT (3U) -/*! @brief The bit mask for PARTITION ENABLE field in BOOT CONFIG */ -#define MMC_PARTITION_CONFIG_PARTITION_ENABLE_MASK (0x00000038U) -/*! @brief The bit shift for ACK field in BOOT CONFIG */ -#define MMC_PARTITION_CONFIG_BOOT_ACK_SHIFT (6U) -/*! @brief The bit mask for ACK field in BOOT CONFIG */ -#define MMC_PARTITION_CONFIG_BOOT_ACK_MASK (0x00000040U) -/*! @brief The bit shift for BOOT BUS WIDTH field in BOOT CONFIG */ -#define MMC_BOOT_BUS_CONDITION_BUS_WIDTH_SHIFT (0U) -/*! @brief The bit mask for BOOT BUS WIDTH field in BOOT CONFIG */ -#define MMC_BOOT_BUS_CONDITION_BUS_WIDTH_MASK (3U) -/*! @brief The bit shift for BOOT BUS WIDTH RESET field in BOOT CONFIG */ -#define MMC_BOOT_BUS_CONDITION_RESET_BUS_CONDITION_SHIFT (2U) -/*! @brief The bit mask for BOOT BUS WIDTH RESET field in BOOT CONFIG */ -#define MMC_BOOT_BUS_CONDITION_RESET_BUS_CONDITION_MASK (4U) -/*! @brief The bit mask for BOOT BUS WIDTH RESET field in BOOT CONFIG */ -#define MMC_BOOT_BUS_CONDITION_BOOT_MODE_MASK (0x18U) - -/*! @brief MMC card CSD register flags */ -enum _mmc_csd_flag -{ - kMMC_CsdReadBlockPartialFlag = (1U << 0U), /*!< Partial blocks for read allowed */ - kMMC_CsdWriteBlockMisalignFlag = (1U << 1U), /*!< Write block misalignment */ - kMMC_CsdReadBlockMisalignFlag = (1U << 2U), /*!< Read block misalignment */ - kMMC_CsdDsrImplementedFlag = (1U << 3U), /*!< DSR implemented */ - kMMC_CsdWriteProtectGroupEnabledFlag = (1U << 4U), /*!< Write protect group enabled */ - kMMC_CsdWriteBlockPartialFlag = (1U << 5U), /*!< Partial blocks for write allowed */ - kMMC_ContentProtectApplicationFlag = (1U << 6U), /*!< Content protect application */ - kMMC_CsdFileFormatGroupFlag = (1U << 7U), /*!< File format group */ - kMMC_CsdCopyFlag = (1U << 8U), /*!< Copy flag */ - kMMC_CsdPermanentWriteProtectFlag = (1U << 9U), /*!< Permanent write protection */ - kMMC_CsdTemporaryWriteProtectFlag = (1U << 10U), /*!< Temporary write protection */ -}; - -/*! @brief Extended CSD register access mode(Access mode in CMD6). */ -typedef enum _mmc_extended_csd_access_mode -{ - kMMC_ExtendedCsdAccessModeCommandSet = 0U, /*!< Command set related setting */ - kMMC_ExtendedCsdAccessModeSetBits = 1U, /*!< Set bits in specific byte in Extended CSD */ - kMMC_ExtendedCsdAccessModeClearBits = 2U, /*!< Clear bits in specific byte in Extended CSD */ - kMMC_ExtendedCsdAccessModeWriteBits = 3U, /*!< Write a value to specific byte in Extended CSD */ -} mmc_extended_csd_access_mode_t; - -/*! @brief EXT CSD byte index */ -typedef enum _mmc_extended_csd_index -{ - kMMC_ExtendedCsdIndexBootPartitionWP = 173U, /*!< Boot partition write protect */ - kMMC_ExtendedCsdIndexEraseGroupDefinition = 175U, /*!< Erase Group Def */ - kMMC_ExtendedCsdIndexBootBusConditions = 177U, /*!< Boot Bus conditions */ - kMMC_ExtendedCsdIndexBootConfigWP = 178U, /*!< Boot config write protect */ - kMMC_ExtendedCsdIndexPartitionConfig = 179U, /*!< Partition Config, before BOOT_CONFIG */ - kMMC_ExtendedCsdIndexBusWidth = 183U, /*!< Bus Width */ - kMMC_ExtendedCsdIndexHighSpeedTiming = 185U, /*!< High-speed Timing */ - kMMC_ExtendedCsdIndexPowerClass = 187U, /*!< Power Class */ - kMMC_ExtendedCsdIndexCommandSet = 191U, /*!< Command Set */ -} mmc_extended_csd_index_t; - -/*! @brief mmc driver strength */ -enum _mmc_driver_strength -{ - kMMC_DriverStrength0 = 0U, /*!< Driver type0 ,nominal impedance 50ohm */ - kMMC_DriverStrength1 = 1U, /*!< Driver type1 ,nominal impedance 33ohm */ - kMMC_DriverStrength2 = 2U, /*!< Driver type2 ,nominal impedance 66ohm */ - kMMC_DriverStrength3 = 3U, /*!< Driver type3 ,nominal impedance 100ohm */ - kMMC_DriverStrength4 = 4U, /*!< Driver type4 ,nominal impedance 40ohm */ -}; - -/*! @brief mmc extended csd flags*/ -typedef enum _mmc_extended_csd_flags -{ - kMMC_ExtCsdExtPartitionSupport = (1 << 0U), /*!< partitioning support[160] */ - kMMC_ExtCsdEnhancePartitionSupport = (1 << 1U), /*!< partitioning support[160] */ - kMMC_ExtCsdPartitioningSupport = (1 << 2U), /*!< partitioning support[160] */ - kMMC_ExtCsdPrgCIDCSDInDDRModeSupport = (1 << 3U), /*!< CMD26 and CMD27 are support dual data rate [130]*/ - kMMC_ExtCsdBKOpsSupport = (1 << 4U), /*!< background operation feature support [502]*/ - kMMC_ExtCsdDataTagSupport = (1 << 5U), /*!< data tag support[499]*/ - kMMC_ExtCsdModeOperationCodeSupport = (1 << 6U), /*!< mode operation code support[493]*/ -} mmc_extended_csd_flags_t; - -/*! @brief MMC card boot mode */ -enum _mmc_boot_mode -{ - kMMC_BootModeNormal = 0U, /*!< Normal boot */ - kMMC_BootModeAlternative = 1U, /*!< Alternative boot */ -}; - -/*! @brief The length of Extended CSD register, unit as bytes. */ -#define MMC_EXTENDED_CSD_BYTES (512U) - -/*! @brief MMC card default relative address */ -#define MMC_DEFAULT_RELATIVE_ADDRESS (2U) - -/*! @brief SD card product name length united as bytes. */ -#define SD_PRODUCT_NAME_BYTES (5U) - -/*! @brief sdio card FBR register */ -typedef struct _sdio_fbr -{ - uint8_t flags; /*!< current io flags */ - uint8_t ioStdFunctionCode; /*!< current io standard function code */ - uint8_t ioExtFunctionCode; /*!< current io extended function code*/ - uint32_t ioPointerToCIS; /*!< current io pointer to CIS */ - uint32_t ioPointerToCSA; /*!< current io pointer to CSA*/ - uint16_t ioBlockSize; /*!< current io block size */ -} sdio_fbr_t; - -/*! @brief sdio card common CIS */ -typedef struct _sdio_common_cis -{ - /* manufacturer identification string tuple */ - uint16_t mID; /*!< manufacturer code */ - uint16_t mInfo; /*!< manufacturer information */ - - /*function identification tuple */ - uint8_t funcID; /*!< function ID */ - - /* function extension tuple */ - uint16_t fn0MaxBlkSize; /*!< function 0 max block size */ - uint8_t maxTransSpeed; /*!< max data transfer speed for all function */ - -} sdio_common_cis_t; - -/*! @brief sdio card function CIS */ -typedef struct _sdio_func_cis -{ - /*function identification tuple */ - uint8_t funcID; /*!< function ID */ - - /* function extension tuple */ - uint8_t funcInfo; /*!< function info */ - uint8_t ioVersion; /*!< level of application specification this io support */ - uint32_t cardPSN; /*!< product serial number */ - uint32_t ioCSASize; /*!< avaliable CSA size for io */ - uint8_t ioCSAProperty; /*!< CSA property */ - uint16_t ioMaxBlockSize; /*!< io max transfer data size */ - uint32_t ioOCR; /*!< io ioeration condition */ - uint8_t ioOPMinPwr; /*!< min current in operation mode */ - uint8_t ioOPAvgPwr; /*!< average current in operation mode */ - uint8_t ioOPMaxPwr; /*!< max current in operation mode */ - uint8_t ioSBMinPwr; /*!< min current in standby mode */ - uint8_t ioSBAvgPwr; /*!< average current in standby mode */ - uint8_t ioSBMaxPwr; /*!< max current in standby mode */ - - uint16_t ioMinBandWidth; /*!< io min transfer bandwidth */ - uint16_t ioOptimumBandWidth; /*!< io optimum transfer bandwidth */ - uint16_t ioReadyTimeout; /*!< timeout value from enalbe to ready */ - uint16_t ioHighCurrentAvgCurrent; /*!< the average peak current (mA) - when IO operating in high current mode */ - uint16_t ioHighCurrentMaxCurrent; /*!< the max peak current (mA) - when IO operating in high current mode */ - uint16_t ioLowCurrentAvgCurrent; /*!< the average peak current (mA) - when IO operating in lower current mode */ - uint16_t ioLowCurrentMaxCurrent; /*!< the max peak current (mA) - when IO operating in lower current mode */ -} sdio_func_cis_t; - -/*! @brief SD AU start value */ -#define SD_AU_START_VALUE (1U) -/*! @brief SD UHS AU start value */ -#define SD_UHS_AU_START_VALUE (7U) - -/*! @brief SD card status */ -typedef struct _sd_status -{ - uint8_t busWidth; /*!< current buswidth */ - uint8_t secureMode; /*!< secured mode */ - uint16_t cardType; /*!< sdcard type */ - uint32_t protectedSize; /*!< size of protected area */ - uint8_t speedClass; /*!< speed class of card */ - uint8_t performanceMove; /*!< Performance of move indicated by 1[MB/S]step */ - uint8_t auSize; /*!< size of AU */ - uint16_t eraseSize; /*!< number of AUs to be erased at a time */ - uint8_t eraseTimeout; /*!< timeout value for erasing areas specified by UNIT OF ERASE AU */ - uint8_t eraseOffset; /*!< fixed offset value added to erase time */ - uint8_t uhsSpeedGrade; /*!< speed grade for UHS mode */ - uint8_t uhsAuSize; /*!< size of AU for UHS mode */ -} sd_status_t; - -/*! @brief SD card CID register */ -typedef struct _sd_cid -{ - uint8_t manufacturerID; /*!< Manufacturer ID [127:120] */ - uint16_t applicationID; /*!< OEM/Application ID [119:104] */ - uint8_t productName[SD_PRODUCT_NAME_BYTES]; /*!< Product name [103:64] */ - uint8_t productVersion; /*!< Product revision [63:56] */ - uint32_t productSerialNumber; /*!< Product serial number [55:24] */ - uint16_t manufacturerData; /*!< Manufacturing date [19:8] */ -} sd_cid_t; - -/*! @brief SD card CSD register */ -typedef struct _sd_csd -{ - uint8_t csdStructure; /*!< CSD structure [127:126] */ - uint8_t dataReadAccessTime1; /*!< Data read access-time-1 [119:112] */ - uint8_t dataReadAccessTime2; /*!< Data read access-time-2 in clock cycles (NSAC*100) [111:104] */ - uint8_t transferSpeed; /*!< Maximum data transfer rate [103:96] */ - uint16_t cardCommandClass; /*!< Card command classes [95:84] */ - uint8_t readBlockLength; /*!< Maximum read data block length [83:80] */ - uint16_t flags; /*!< Flags in _sd_csd_flag */ - uint32_t deviceSize; /*!< Device size [73:62] */ - /* Following fields from 'readCurrentVddMin' to 'deviceSizeMultiplier' exist in CSD version 1 */ - uint8_t readCurrentVddMin; /*!< Maximum read current at VDD min [61:59] */ - uint8_t readCurrentVddMax; /*!< Maximum read current at VDD max [58:56] */ - uint8_t writeCurrentVddMin; /*!< Maximum write current at VDD min [55:53] */ - uint8_t writeCurrentVddMax; /*!< Maximum write current at VDD max [52:50] */ - uint8_t deviceSizeMultiplier; /*!< Device size multiplier [49:47] */ - - uint8_t eraseSectorSize; /*!< Erase sector size [45:39] */ - uint8_t writeProtectGroupSize; /*!< Write protect group size [38:32] */ - uint8_t writeSpeedFactor; /*!< Write speed factor [28:26] */ - uint8_t writeBlockLength; /*!< Maximum write data block length [25:22] */ - uint8_t fileFormat; /*!< File format [11:10] */ -} sd_csd_t; - -/*! @brief The bit shift for RATE UNIT field in TRANSFER SPEED */ -#define SD_TRANSFER_SPEED_RATE_UNIT_SHIFT (0U) -/*! @brief The bit mask for RATE UNIT field in TRANSFER SPEED */ -#define SD_TRANSFER_SPEED_RATE_UNIT_MASK (0x07U) -/*! @brief The bit shift for TIME VALUE field in TRANSFER SPEED */ -#define SD_TRANSFER_SPEED_TIME_VALUE_SHIFT (2U) -/*! @brief The bit mask for TIME VALUE field in TRANSFER SPEED */ -#define SD_TRANSFER_SPEED_TIME_VALUE_MASK (0x78U) -/*! @brief Read the value of FREQUENCY UNIT in TRANSFER SPEED field */ -#define SD_RD_TRANSFER_SPEED_RATE_UNIT(x) \ - (((x.transferSpeed) & SD_TRANSFER_SPEED_RATE_UNIT_MASK) >> SD_TRANSFER_SPEED_RATE_UNIT_SHIFT) -/*! @brief Read the value of TIME VALUE in TRANSFER SPEED field */ -#define SD_RD_TRANSFER_SPEED_TIME_VALUE(x) \ - (((x.transferSpeed) & SD_TRANSFER_SPEED_TIME_VALUE_MASK) >> SD_TRANSFER_SPEED_TIME_VALUE_SHIFT) - -/*! @brief SD card SCR register */ -typedef struct _sd_scr -{ - uint8_t scrStructure; /*!< SCR Structure [63:60] */ - uint8_t sdSpecification; /*!< SD memory card specification version [59:56] */ - uint16_t flags; /*!< SCR flags in _sd_scr_flag */ - uint8_t sdSecurity; /*!< Security specification supported [54:52] */ - uint8_t sdBusWidths; /*!< Data bus widths supported [51:48] */ - uint8_t extendedSecurity; /*!< Extended security support [46:43] */ - uint8_t commandSupport; /*!< Command support bits [33:32] 33-support CMD23, 32-support cmd20*/ - uint32_t reservedForManufacturer; /*!< reserved for manufacturer usage [31:0] */ -} sd_scr_t; - -/*! @brief MMC card product name length united as bytes. */ -#define MMC_PRODUCT_NAME_BYTES (6U) -/*! @brief MMC card CID register. */ -typedef struct _mmc_cid -{ - uint8_t manufacturerID; /*!< Manufacturer ID */ - uint16_t applicationID; /*!< OEM/Application ID */ - uint8_t productName[MMC_PRODUCT_NAME_BYTES]; /*!< Product name */ - uint8_t productVersion; /*!< Product revision */ - uint32_t productSerialNumber; /*!< Product serial number */ - uint8_t manufacturerData; /*!< Manufacturing date */ -} mmc_cid_t; - -/*! @brief MMC card CSD register. */ -typedef struct _mmc_csd -{ - uint8_t csdStructureVersion; /*!< CSD structure [127:126] */ - uint8_t systemSpecificationVersion; /*!< System specification version [125:122] */ - uint8_t dataReadAccessTime1; /*!< Data read access-time 1 [119:112] */ - uint8_t dataReadAccessTime2; /*!< Data read access-time 2 in CLOCK cycles (NSAC*100) [111:104] */ - uint8_t transferSpeed; /*!< Max. bus clock frequency [103:96] */ - uint16_t cardCommandClass; /*!< card command classes [95:84] */ - uint8_t readBlockLength; /*!< Max. read data block length [83:80] */ - uint16_t flags; /*!< Contain flags in _mmc_csd_flag */ - uint16_t deviceSize; /*!< Device size [73:62] */ - uint8_t readCurrentVddMin; /*!< Max. read current @ VDD min [61:59] */ - uint8_t readCurrentVddMax; /*!< Max. read current @ VDD max [58:56] */ - uint8_t writeCurrentVddMin; /*!< Max. write current @ VDD min [55:53] */ - uint8_t writeCurrentVddMax; /*!< Max. write current @ VDD max [52:50] */ - uint8_t deviceSizeMultiplier; /*!< Device size multiplier [49:47] */ - uint8_t eraseGroupSize; /*!< Erase group size [46:42] */ - uint8_t eraseGroupSizeMultiplier; /*!< Erase group size multiplier [41:37] */ - uint8_t writeProtectGroupSize; /*!< Write protect group size [36:32] */ - uint8_t defaultEcc; /*!< Manufacturer default ECC [30:29] */ - uint8_t writeSpeedFactor; /*!< Write speed factor [28:26] */ - uint8_t maxWriteBlockLength; /*!< Max. write data block length [25:22] */ - uint8_t fileFormat; /*!< File format [11:10] */ - uint8_t eccCode; /*!< ECC code [9:8] */ -} mmc_csd_t; - -/*! @brief MMC card Extended CSD register (unit: byte). */ -typedef struct _mmc_extended_csd -{ - /*uint8_t SecureRemoveType;*/ /*!< secure removal type[16]*/ - /*uint8_t enProductStateAware;*/ /*!< product state awareness enablement[17]*/ - /*uint32_t maxPreLoadDataSize;*/ /*!< max preload data size[21-18]*/ - /*uint32_t preLoadDataSize;*/ /*!< pre-load data size[25-22]*/ - /*uint8_t ffuStatus;*/ /*!< FFU status [26]*/ - /*uint8_t modeOperationCode;*/ /*!< mode operation code[29]*/ - /*uint8_t modeConfig;*/ /*!< mode config [30]*/ - /*uint8_t cacheCtrl;*/ /*!< control to turn on/off cache[33]*/ - /*uint8_t pwroffNotify;*/ /*!< power off notification[34]*/ - /*uint8_t packedCmdFailIndex;*/ /*!< packed cmd fail index [35]*/ - /*uint8_t packedCmdStatus;*/ /*!< packed cmd status[36]*/ - /*uint32_t contextConfig[4U];*/ /*!< context configuration[51-37]*/ - /*uint16_t extPartitionAttr;*/ /*!< extended partitions attribut[53-52]*/ - /*uint16_t exceptEventStatus;*/ /*!< exception events status[55-54]*/ - /*uint16_t exceptEventControl;*/ /*!< exception events control[57-56]*/ - /*uint8_t toReleaseAddressedGroup;*/ /*!< number of group to be released[58]*/ - /*uint8_t class6CmdCtrl;*/ /*!< class 6 command control[59]*/ - /*uint8_t intTimeoutEmu;*/ /*!< 1st initiallization after disabling sector size emu[60]*/ - /*uint8_t sectorSize;*/ /*!< sector size[61] */ - /*uint8_t sectorSizeEmu;*/ /*!< sector size emulation[62]*/ - /*uint8_t nativeSectorSize;*/ /*!< native sector size[63]*/ - /*uint8_t periodWakeup;*/ /*!< period wakeup [131]*/ - /*uint8_t tCASESupport;*/ /*!< package case temperature is controlled[132]*/ - /*uint8_t productionStateAware;*/ /*!< production state awareness[133]*/ - /*uint32_t enhanceUsrDataStartAddr;*/ /*!< enhanced user data start addr [139-136]*/ - /*uint32_t enhanceUsrDataSize;*/ /*!< enhanced user data area size[142-140]*/ - /*uint32_t generalPartitionSize[3];*/ /*!< general purpose partition size[154-143]*/ - uint8_t partitionAttribute; /*!< partition attribute [156]*/ - /*uint32_t maxEnhanceAreaSize;*/ /*!< max enhance area size [159-157]*/ - /*uint8_t hpiManagementEn;*/ /*!< HPI management [161]*/ - /*uint8_t writeReliabilityParameter;*/ /*!< write reliability parameter register[166] */ - /*uint8_t writeReliabilitySet;*/ /*!< write reliability setting register[167] */ - /*uint8_t rpmbSizeMult;*/ /*!< RPMB size multi [168]*/ - /*uint8_t fwConfig;*/ /*!< FW configuration[169]*/ - uint8_t userWP; /*!< user write protect register[171] */ - uint8_t bootPartitionWP; /*!< boot write protect register[173]*/ - uint8_t bootWPStatus; /*!< boot write protect status register[174]*/ - uint8_t highDensityEraseGroupDefinition; /*!< High-density erase group definition [175] */ - uint8_t bootDataBusConditions; /*!< Boot bus conditions [177] */ - uint8_t bootConfigProtect; /*!< Boot config protection [178]*/ - uint8_t partitionConfig; /*!< Boot configuration [179] */ - uint8_t eraseMemoryContent; /*!< Erased memory content [181] */ - uint8_t dataBusWidth; /*!< Data bus width mode [183] */ - uint8_t highSpeedTiming; /*!< High-speed interface timing [185] */ - uint8_t powerClass; /*!< Power class [187] */ - uint8_t commandSetRevision; /*!< Command set revision [189] */ - uint8_t commandSet; /*!< Command set [191] */ - uint8_t extendecCsdVersion; /*!< Extended CSD revision [192] */ - uint8_t csdStructureVersion; /*!< CSD structure version [194] */ - uint8_t cardType; /*!< Card Type [196] */ - uint8_t ioDriverStrength; /*!< IO driver strength [197] */ - /*uint8_t OutofInterruptBusyTiming;*/ /*!< out of interrupt busy timing [198] */ - /*uint8_t partitionSwitchTiming;*/ /*!< partition switch timing [199] */ - uint8_t powerClass52MHz195V; /*!< Power Class for 52MHz @ 1.95V [200] */ - uint8_t powerClass26MHz195V; /*!< Power Class for 26MHz @ 1.95V [201] */ - uint8_t powerClass52MHz360V; /*!< Power Class for 52MHz @ 3.6V [202] */ - uint8_t powerClass26MHz360V; /*!< Power Class for 26MHz @ 3.6V [203] */ - uint8_t minimumReadPerformance4Bit26MHz; /*!< Minimum Read Performance for 4bit at 26MHz [205] */ - uint8_t minimumWritePerformance4Bit26MHz; /*!< Minimum Write Performance for 4bit at 26MHz [206] */ - uint8_t minimumReadPerformance8Bit26MHz4Bit52MHz; - /*!< Minimum read Performance for 8bit at 26MHz/4bit @52MHz [207] */ - uint8_t minimumWritePerformance8Bit26MHz4Bit52MHz; - /*!< Minimum Write Performance for 8bit at 26MHz/4bit @52MHz [208] */ - uint8_t minimumReadPerformance8Bit52MHz; /*!< Minimum Read Performance for 8bit at 52MHz [209] */ - uint8_t minimumWritePerformance8Bit52MHz; /*!< Minimum Write Performance for 8bit at 52MHz [210] */ - uint32_t sectorCount; /*!< Sector Count [215:212] */ - /*uint8_t sleepNotificationTimeout;*/ /*!< sleep notification timeout [216]*/ - uint8_t sleepAwakeTimeout; /*!< Sleep/awake timeout [217] */ - /*uint8_t productionStateAwareTimeout;*/ /*!< Production state awareness timeout [218]*/ - uint8_t sleepCurrentVCCQ; /*!< Sleep current (VCCQ) [219] */ - uint8_t sleepCurrentVCC; /*!< Sleep current (VCC) [220] */ - uint8_t highCapacityWriteProtectGroupSize; /*!< High-capacity write protect group size [221] */ - uint8_t reliableWriteSectorCount; /*!< Reliable write sector count [222] */ - uint8_t highCapacityEraseTimeout; /*!< High-capacity erase timeout [223] */ - uint8_t highCapacityEraseUnitSize; /*!< High-capacity erase unit size [224] */ - uint8_t accessSize; /*!< Access size [225] */ - /*uint8_t secureTrimMultiplier;*/ /*!< secure trim multiplier[229]*/ - /*uint8_t secureEraseMultiplier;*/ /*!< secure erase multiplier[230]*/ - /*uint8_t secureFeatureSupport;*/ /*!< secure feature support[231]*/ - /*uint32_t trimMultiplier;*/ /*!< trim multiplier[232]*/ - uint8_t minReadPerformance8bitAt52MHZDDR; /*!< Minimum read performance for 8bit at DDR 52MHZ[234]*/ - uint8_t minWritePerformance8bitAt52MHZDDR; /*!< Minimum write performance for 8bit at DDR 52MHZ[235]*/ - uint8_t powerClass200MHZVCCQ130VVCC360V; /*!< power class for 200MHZ, at VCCQ= 1.3V,VCC=3.6V[236]*/ - uint8_t powerClass200MHZVCCQ195VVCC360V; /*!< power class for 200MHZ, at VCCQ= 1.95V,VCC=3.6V[237]*/ - uint8_t powerClass52MHZDDR195V; /*!< power class for 52MHZ,DDR at Vcc 1.95V[238]*/ - uint8_t powerClass52MHZDDR360V; /*!< power class for 52MHZ,DDR at Vcc 3.6V[239]*/ - /*uint8_t iniTimeoutAP;*/ /*!< 1st initialization time after partitioning[241]*/ - /*uint32_t correctPrgSectorNum;*/ /*!< correct prg sectors number[245-242]*/ - /*uint8_t bkOpsStatus;*/ /*!< background operations status[246]*/ - /*uint8_t powerOffNotifyTimeout;*/ /*!< power off notification timeout[247]*/ - /*uint8_t genericCMD6Timeout;*/ /*!< generic CMD6 timeout[248]*/ - uint32_t cacheSize; /*!< cache size[252-249]*/ - uint8_t powerClass200MHZDDR360V; /*!< power class for 200MHZ, DDR at VCC=2.6V[253]*/ - /*uint32_t fwVer[2U];*/ /*!< fw VERSION [261-254]*/ - /*uint16_t deviceVer;*/ /*!< device version[263-262]*/ - /*uint8_t optimalTrimSize;*/ /*!< optimal trim size[264]*/ - /*uint8_t optimalWriteSize;*/ /*!< optimal write size[265]*/ - /*uint8_t optimalReadSize;*/ /*!< optimal read size[266]*/ - /*uint8_t preEolInfo;*/ /*!< pre EOL information[267]*/ - /*uint8_t deviceLifeTimeEstimationA;*/ /*!< device life time estimation typeA[268]*/ - /*uint8_t deviceLifeTimeEstimationB;*/ /*!< device life time estimation typeB[269]*/ - /*uint32_t correctPrgFWSectorNum;*/ /*!< number of FW sectors correctly programmed[305-302]*/ - /*uint32_t ffuArg;*/ /*!< FFU argument[490-487]*/ - /*uint8_t operationCodeTimeout;*/ /*!< operation code timeout[491]*/ - /*uint8_t supportMode;*/ /*!< support mode [493]*/ - uint8_t extPartitionSupport; /*!< extended partition attribute support[494]*/ - /*uint8_t largeUnitSize;*/ /*!< large unit size[495]*/ - /*uint8_t contextManageCap;*/ /*!< context management capability[496]*/ - /*uint8_t tagResourceSize;*/ /*!< tag resource size[497]*/ - /*uint8_t tagUnitSize;*/ /*!< tag unit size[498]*/ - /*uint8_t maxPackedWriteCmd;*/ /*!< max packed write cmd[500]*/ - /*uint8_t maxPackedReadCmd;*/ /*!< max packed read cmd[501]*/ - /*uint8_t hpiFeature;*/ /*!< HPI feature[503]*/ - uint8_t supportedCommandSet; /*!< Supported Command Sets [504] */ - /*uint8_t extSecurityCmdError;*/ /*!< extended security commands error[505]*/ -} mmc_extended_csd_t; - -/*! @brief The bit shift for COMMAND SET field in SWITCH command. */ -#define MMC_SWITCH_COMMAND_SET_SHIFT (0U) -/*! @brief The bit mask for COMMAND set field in SWITCH command. */ -#define MMC_SWITCH_COMMAND_SET_MASK (0x00000007U) -/*! @brief The bit shift for VALUE field in SWITCH command */ -#define MMC_SWITCH_VALUE_SHIFT (8U) -/*! @brief The bit mask for VALUE field in SWITCH command */ -#define MMC_SWITCH_VALUE_MASK (0x0000FF00U) -/*! @brief The bit shift for BYTE INDEX field in SWITCH command */ -#define MMC_SWITCH_BYTE_INDEX_SHIFT (16U) -/*! @brief The bit mask for BYTE INDEX field in SWITCH command */ -#define MMC_SWITCH_BYTE_INDEX_MASK (0x00FF0000U) -/*! @brief The bit shift for ACCESS MODE field in SWITCH command */ -#define MMC_SWITCH_ACCESS_MODE_SHIFT (24U) -/*! @brief The bit mask for ACCESS MODE field in SWITCH command */ -#define MMC_SWTICH_ACCESS_MODE_MASK (0x03000000U) - -/*! @brief MMC Extended CSD configuration. */ -typedef struct _mmc_extended_csd_config -{ - mmc_command_set_t commandSet; /*!< Command set */ - uint8_t ByteValue; /*!< The value to set */ - uint8_t ByteIndex; /*!< The byte index in Extended CSD(mmc_extended_csd_index_t) */ - mmc_extended_csd_access_mode_t accessMode; /*!< Access mode */ -} mmc_extended_csd_config_t; - -/*! @brief MMC card boot configuration definition. */ -typedef struct _mmc_boot_config -{ - bool enableBootAck; /*!< Enable boot ACK */ - mmc_boot_partition_enable_t bootPartition; /*!< Boot partition */ - - mmc_boot_timing_mode_t bootTimingMode; /*!< boot mode */ - mmc_data_bus_width_t bootDataBusWidth; /*!< Boot data bus width */ - bool retainBootbusCondition; /*!< If retain boot bus width and boot mode conditions */ - - bool pwrBootConfigProtection; /*!< Disable the change of boot configuration register bits from at this point - until next power cycle or next H/W reset operation */ - bool premBootConfigProtection; /*!< Disable the change of boot configuration register bits permanently */ - - mmc_boot_partition_wp_t bootPartitionWP; /*!< boot partition write protect configurations */ - -} mmc_boot_config_t; - -/* @} */ - -#endif /* _FSL_SDMMC_SPEC_H_ */ diff --git a/targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_event.c b/targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_event.c deleted file mode 100644 index a3c24ec843..0000000000 --- a/targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_event.c +++ /dev/null @@ -1,151 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2018 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#include -#include -#include "fsl_sdmmc_event.h" -#include "FreeRTOS.h" -#include "semphr.h" -#include "event_groups.h" - -/******************************************************************************* - * Definitons - ******************************************************************************/ -/*! @brief Convert the milliseconds to ticks in FreeRTOS. */ -#define MSEC_TO_TICK(msec) \ - (((uint32_t)(msec) + 500uL / (uint32_t)configTICK_RATE_HZ) * (uint32_t)configTICK_RATE_HZ / 1000uL) - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get event instance. - * @param eventType The event type - * @return The event instance's pointer. - */ -static SemaphoreHandle_t *SDMMCEVENT_GetInstance(sdmmc_event_t eventType); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Transfer complete event. */ -static SemaphoreHandle_t g_eventTransferComplete; -/*! @brief Card detect event. */ -static SemaphoreHandle_t g_eventCardDetect; - -/******************************************************************************* - * Code - ******************************************************************************/ -static SemaphoreHandle_t *SDMMCEVENT_GetInstance(sdmmc_event_t eventType) -{ - SemaphoreHandle_t *event; - - switch (eventType) - { - case kSDMMCEVENT_TransferComplete: - event = &g_eventTransferComplete; - break; - case kSDMMCEVENT_CardDetect: - event = &g_eventCardDetect; - break; - default: - event = NULL; - break; - } - - return event; -} - -bool SDMMCEVENT_Create(sdmmc_event_t eventType) -{ - SemaphoreHandle_t *event = SDMMCEVENT_GetInstance(eventType); - - if (event) - { - *event = xSemaphoreCreateBinary(); - if (*event == NULL) - { - return false; - } - - return true; - } - else - { - return false; - } -} - -bool SDMMCEVENT_Wait(sdmmc_event_t eventType, uint32_t timeoutMilliseconds) -{ - uint32_t timeoutTicks; - SemaphoreHandle_t *event = SDMMCEVENT_GetInstance(eventType); - - if (timeoutMilliseconds && event) - { - if (timeoutMilliseconds == ~0U) - { - timeoutTicks = portMAX_DELAY; - } - else - { - timeoutTicks = MSEC_TO_TICK(timeoutMilliseconds); - } - if (xSemaphoreTake(*event, timeoutTicks) == pdFALSE) - { - return false; /* timeout */ - } - else - { - return true; /* event taken */ - } - } - else - { - return false; - } -} - -bool SDMMCEVENT_Notify(sdmmc_event_t eventType) -{ - SemaphoreHandle_t *event = SDMMCEVENT_GetInstance(eventType); - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - BaseType_t xResult = pdFAIL; - - if (event) - { - xResult = xSemaphoreGiveFromISR(*event, &xHigherPriorityTaskWoken); - if (xResult != pdFAIL) - { - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - return true; - } - else - { - return false; - } - } - else - { - return false; - } -} - -void SDMMCEVENT_Delete(sdmmc_event_t eventType) -{ - SemaphoreHandle_t *event = SDMMCEVENT_GetInstance(eventType); - - if (event) - { - vSemaphoreDelete(*event); - } -} - -void SDMMCEVENT_Delay(uint32_t milliseconds) -{ - vTaskDelay(MSEC_TO_TICK(milliseconds)); -} diff --git a/targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_event.h b/targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_event.h deleted file mode 100644 index b5da963079..0000000000 --- a/targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_event.h +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2018 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#ifndef _FSL_SDMMC_EVENT_H_ -#define _FSL_SDMMC_EVENT_H_ - -#include "fsl_common.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -/*! @brief Event type */ -typedef enum _sdmmc_event -{ - kSDMMCEVENT_TransferComplete = 0U, /*!< Transfer complete event */ - kSDMMCEVENT_CardDetect = 1U, /*!< Card detect event */ -} sdmmc_event_t; - -/******************************************************************************* - * API - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @name Event Function - * @{ - */ - -/*! - * @brief Initialize timer to implement wait event timeout. - */ -void SDMMCEVENT_InitTimer(void); - -/* Callback function for SDHC */ - -/*! - * @brief Create event. - * @param eventType The event type - * @retval true Create event successfully. - * @retval false Create event failed. - */ -bool SDMMCEVENT_Create(sdmmc_event_t eventType); - -/*! - * @brief Wait event. - * - * @param eventType The event type - * @param timeoutMilliseconds Timeout time in milliseconds. - * @retval true Wait event successfully. - * @retval false Wait event failed. - */ -bool SDMMCEVENT_Wait(sdmmc_event_t eventType, uint32_t timeoutMilliseconds); - -/*! - * @brief Notify event. - * @param eventType The event type - * @retval true Notify event successfully. - * @retval false Notify event failed. - */ -bool SDMMCEVENT_Notify(sdmmc_event_t eventType); - -/*! - * @brief Delete event. - * @param eventType The event type - */ -void SDMMCEVENT_Delete(sdmmc_event_t eventType); - -/*! - * @brief sdmmc delay. - * @param milliseconds time to delay - */ -void SDMMCEVENT_Delay(uint32_t milliseconds); - -/* @} */ - -#if defined(__cplusplus) -} -#endif - -#endif /* _FSL_SDMMC_EVENT_H_*/ diff --git a/targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_host.c b/targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_host.c deleted file mode 100644 index 998cb2fab3..0000000000 --- a/targets/FreeRTOS/UAC18/common/sdmmc/port/fsl_sdmmc_host.c +++ /dev/null @@ -1,426 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2018 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#include "fsl_sdmmc_host.h" -#include "fsl_sdmmc_event.h" - -/******************************************************************************* -* Definitions -******************************************************************************/ - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief SDMMCHOST detect card by GPIO. - */ -static void SDMMCHOST_DetectCardByGpio(const sdmmchost_detect_card_t *cd); - -/*! - * @brief SDMMCHOST detect card insert status by host controller. - * @param base host base address. - * @param userData user can register a application card insert callback through userData. - */ -static void SDMMCHOST_DetectCardInsertByHost(SDMMCHOST_TYPE *base, void *userData); - -/*! - * @brief SDMMCHOST detect card remove status by host controller. - * @param base host base address. - * @param userData user can register a application card insert callback through userData. - */ -static void SDMMCHOST_DetectCardRemoveByHost(SDMMCHOST_TYPE *base, void *userData); - -/*! - * @brief SDMMCHOST transfer function. - * @param base host base address. - * @param content transfer configurations. - */ -static status_t SDMMCHOST_TransferFunction(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER *content); - -/*! - * @brief SDMMCHOST transfer complete callback. - * @param base host base address. - * @param handle host handle. - * @param status interrupt status. - * @param userData user data. - */ -static void SDMMCHOST_TransferCompleteCallback(SDMMCHOST_TYPE *base, - usdhc_handle_t *handle, - status_t status, - void *userData); - -/*! - * @brief SDMMCHOST re-tuning callback -* @param base host base address. -* @param userData user can register a application card insert callback through userData. -*/ -static void SDMMCHOST_ReTuningCallback(SDMMCHOST_TYPE *base, void *userData); - -/*! - * @brief card detect deinit function. - */ -static void SDMMCHOST_CardDetectDeinit(void); - -/*! - * @brief card detect deinit function. - * @param host base address. - * @param host detect card configuration. - */ -static status_t SDMMCHOST_CardDetectInit(SDMMCHOST_TYPE *base, const sdmmchost_detect_card_t *cd); -/******************************************************************************* - * Variables - ******************************************************************************/ -/* DMA descriptor should allocate at non-cached memory */ -AT_NONCACHEABLE_SECTION_ALIGN(uint32_t g_usdhcAdma2Table[USDHC_ADMA_TABLE_WORDS], USDHC_ADMA2_ADDR_ALIGN); - -static usdhc_handle_t s_usdhcHandle; -static volatile status_t s_usdhcTransferStatus = kStatus_Success; -static volatile bool s_sdInsertedFlag = false; -static volatile status_t s_reTuningFlag = false; -/******************************************************************************* - * Code - ******************************************************************************/ -static void SDMMCHOST_DetectCardByGpio(const sdmmchost_detect_card_t *cd) -{ - if (SDMMCHOST_CARD_DETECT_GPIO_STATUS() != SDMMCHOST_CARD_INSERT_CD_LEVEL) - { - s_sdInsertedFlag = false; - if (cd && (cd->cardRemoved)) - { - cd->cardRemoved(false, cd->userData); - } - } - else - { - s_sdInsertedFlag = true; - if (cd && (cd->cardInserted)) - { - cd->cardInserted(true, cd->userData); - } - } -} - -static void SDMMCHOST_DetectCardInsertByHost(SDMMCHOST_TYPE *base, void *userData) -{ - (void)base; - - s_sdInsertedFlag = true; - SDMMCEVENT_Notify(kSDMMCEVENT_CardDetect); - /* application callback */ - if (userData && ((sdmmchost_detect_card_t *)userData)->cardInserted) - { - ((sdmmchost_detect_card_t *)userData)->cardInserted(true, ((sdmmchost_detect_card_t *)userData)->userData); - } -} - -static void SDMMCHOST_DetectCardRemoveByHost(SDMMCHOST_TYPE *base, void *userData) -{ - (void)base; - - s_sdInsertedFlag = false; - /* application callback */ - if (userData && ((sdmmchost_detect_card_t *)userData)->cardRemoved) - { - ((sdmmchost_detect_card_t *)userData)->cardRemoved(false, ((sdmmchost_detect_card_t *)userData)->userData); - } -} - -static void SDMMCHOST_TransferCompleteCallback(SDMMCHOST_TYPE *base, - usdhc_handle_t *handle, - status_t status, - void *userData) -{ - (void)base; - (void)userData; - - /* wait the target status and then notify the transfer complete */ - s_usdhcTransferStatus = status; - - if (!((handle->data->rxData) && (status == kStatus_USDHC_SendCommandFailed))) - { - SDMMCEVENT_Notify(kSDMMCEVENT_TransferComplete); - } -} - -static void SDMMCHOST_ReTuningCallback(SDMMCHOST_TYPE *base, void *userData) -{ - (void)base; - (void)userData; - - s_reTuningFlag = true; - SDMMCEVENT_Notify(kSDMMCEVENT_TransferComplete); -} - -static status_t SDMMCHOST_TransferFunction(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER *content) -{ - status_t error = kStatus_Success; - - usdhc_adma_config_t dmaConfig; - - if (content->data != NULL) - { - memset(&dmaConfig, 0, sizeof(usdhc_adma_config_t)); - /* config adma */ - dmaConfig.dmaMode = USDHC_DMA_MODE; - dmaConfig.burstLen = kUSDHC_EnBurstLenForINCR; - dmaConfig.admaTable = g_usdhcAdma2Table; - dmaConfig.admaTableWords = USDHC_ADMA_TABLE_WORDS; - } - - do - { - error = USDHC_TransferNonBlocking(base, &s_usdhcHandle, &dmaConfig, content); - } while (error == kStatus_USDHC_BusyTransferring); - - if ((error != kStatus_Success) || - (false == SDMMCEVENT_Wait(kSDMMCEVENT_TransferComplete, SDMMCHOST_TRANSFER_COMPLETE_TIMEOUT)) || - (s_reTuningFlag) || (s_usdhcTransferStatus != kStatus_Success)) - { - if (s_reTuningFlag || (error == kStatus_USDHC_ReTuningRequest)) - { - if (s_reTuningFlag) - { - s_reTuningFlag = false; - error = kStatus_USDHC_TuningError; - } - } - else - { - error = s_usdhcTransferStatus; - /* host error recovery */ - SDMMCHOST_ErrorRecovery(base); - } - } - - return error; -} - -void SDMMCHOST_ErrorRecovery(SDMMCHOST_TYPE *base) -{ - uint32_t status = 0U; - /* get host present status */ - status = USDHC_GetPresentStatusFlags(base); - /* check command inhibit status flag */ - if ((status & kUSDHC_CommandInhibitFlag) != 0U) - { - /* reset command line */ - USDHC_Reset(base, kUSDHC_ResetCommand, 100U); - } - /* check data inhibit status flag */ - if ((status & kUSDHC_DataInhibitFlag) != 0U) - { - /* reset data line */ - USDHC_Reset(base, kUSDHC_ResetData, 100U); - } -} - -static status_t SDMMCHOST_CardDetectInit(SDMMCHOST_TYPE *base, const sdmmchost_detect_card_t *cd) -{ - sdmmchost_detect_card_type_t cdType = kSDMMCHOST_DetectCardByGpioCD; - - if (cd != NULL) - { - cdType = cd->cdType; - } - - if (!SDMMCEVENT_Create(kSDMMCEVENT_CardDetect)) - { - return kStatus_Fail; - } - - if (cdType == kSDMMCHOST_DetectCardByGpioCD) - { - SDMMCHOST_CARD_DETECT_GPIO_INIT(); - -/* set IRQ priority */ -#if defined(__CORTEX_M) - SDMMCHOST_SET_IRQ_PRIORITY(SDMMCHOST_CARD_DETECT_GPIO_IRQ, 6U); -#else - SDMMCHOST_SET_IRQ_PRIORITY(SDMMCHOST_CARD_DETECT_GPIO_IRQ, 26U); -#endif - /* Open card detection pin NVIC. */ - SDMMCHOST_ENABLE_IRQ(SDMMCHOST_CARD_DETECT_GPIO_IRQ); - /* detect card status */ - SDMMCHOST_DetectCardByGpio(cd); - } - else - { - /* enable card detect through DATA3 */ - if (cdType == kSDMMCHOST_DetectCardByHostDATA3) - { - SDMMCHOST_CARD_DETECT_DATA3_ENABLE(base, true); - } - /* enable card detect interrupt */ - SDMMCHOST_CARD_DETECT_INSERT_ENABLE(base); - SDMMCHOST_CARD_DETECT_REMOVE_ENABLE(base); - SDMMCHOST_CARD_DETECT_INSERT_INTERRUPT_ENABLE(base); - SDMMCHOST_CARD_DETECT_REMOVE_INTERRUPT_ENABLE(base); - /* check if card is inserted */ - if (SDMMCHOST_CARD_DETECT_INSERT_STATUS(base)) - { - s_sdInsertedFlag = true; - } - } - - return kStatus_Success; -} - -static void SDMMCHOST_CardDetectDeinit(void) -{ - SDMMCEVENT_Delete(kSDMMCEVENT_CardDetect); - s_sdInsertedFlag = false; -} - -void SDMMCHOST_Delay(uint32_t milliseconds) -{ - SDMMCEVENT_Delay(milliseconds); -} - -void SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_HANDLER(void) -{ - if (SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_STATUS() & (1U << BOARD_USDHC_CD_GPIO_PIN)) - { - SDMMCHOST_DetectCardByGpio((sdmmchost_detect_card_t *)s_usdhcHandle.userData); - } - /* Clear interrupt flag.*/ - SDMMCHOST_CARD_DETECT_GPIO_INTERRUPT_STATUS_CLEAR(~0U); - SDMMCEVENT_Notify(kSDMMCEVENT_CardDetect); -} - -status_t SDMMCHOST_WaitCardDetectStatus(SDMMCHOST_TYPE *base, const sdmmchost_detect_card_t *cd, bool waitCardStatus) -{ - (void)base; - - uint32_t timeout = SDMMCHOST_CARD_DETECT_TIMEOUT; - - if (cd != NULL) - { - timeout = cd->cdTimeOut_ms; - } - - if (waitCardStatus != s_sdInsertedFlag) - { - /* Wait card inserted. */ - do - { - if (!SDMMCEVENT_Wait(kSDMMCEVENT_CardDetect, timeout)) - { - return kStatus_Fail; - } - } while (waitCardStatus != s_sdInsertedFlag); - } - - return kStatus_Success; -} - -bool SDMMCHOST_IsCardPresent(void) -{ - return s_sdInsertedFlag; -} - -void SDMMCHOST_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr) -{ - (void)base; - - if (pwr != NULL) - { - pwr->powerOff(); - SDMMCHOST_Delay(pwr->powerOffDelay_ms); - } - else - { - /* only SD card need card detect*/ - SDMMCHOST_ENABLE_SD_POWER(false); - /* Delay several milliseconds to make card stable. */ - SDMMCHOST_Delay(500U); - } -} - -void SDMMCHOST_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr) -{ - (void)base; - - /* use user define the power on function */ - if (pwr != NULL) - { - pwr->powerOn(); - SDMMCHOST_Delay(pwr->powerOnDelay_ms); - } - else - { - /* card power on */ - SDMMCHOST_ENABLE_SD_POWER(true); - /* Delay several milliseconds to make card stable. */ - SDMMCHOST_Delay(500U); - } -} - -status_t SDMMCHOST_Init(SDMMCHOST_CONFIG *host, void *userData) -{ - usdhc_host_t *usdhcHost = (usdhc_host_t *)host; - usdhc_transfer_callback_t callback = { - .TransferComplete = SDMMCHOST_TransferCompleteCallback, - .ReTuning = SDMMCHOST_ReTuningCallback, - .CardInserted = SDMMCHOST_DetectCardInsertByHost, - .CardRemoved = SDMMCHOST_DetectCardRemoveByHost, - .SdioInterrupt = NULL, - .BlockGap = NULL, - }; - /* init card power control */ - SDMMCHOST_INIT_SD_POWER(); - SDMMCHOST_INIT_MMC_POWER(); - - /* Initializes USDHC. */ - usdhcHost->config.dataTimeout = USDHC_DATA_TIMEOUT; - usdhcHost->config.endianMode = USDHC_ENDIAN_MODE; - usdhcHost->config.readWatermarkLevel = USDHC_READ_WATERMARK_LEVEL; - usdhcHost->config.writeWatermarkLevel = USDHC_WRITE_WATERMARK_LEVEL; - usdhcHost->config.readBurstLen = USDHC_READ_BURST_LEN; - usdhcHost->config.writeBurstLen = USDHC_WRITE_BURST_LEN; - - USDHC_Init(usdhcHost->base, &(usdhcHost->config)); - - /* disable the card insert/remove interrupt, due to use GPIO interrupt detect card */ - USDHC_DisableInterruptSignal(usdhcHost->base, kUSDHC_CardRemovalFlag | kUSDHC_CardInsertionFlag); - /* create interrupt handler */ - USDHC_TransferCreateHandle(usdhcHost->base, &s_usdhcHandle, &callback, userData); - - if (false == SDMMCEVENT_Create(kSDMMCEVENT_TransferComplete)) - { - return kStatus_Fail; - } - - /* Define transfer function. */ - usdhcHost->transfer = SDMMCHOST_TransferFunction; - /* card detect init */ - SDMMCHOST_CardDetectInit(usdhcHost->base, (sdmmchost_detect_card_t *)userData); - - return kStatus_Success; -} - -void SDMMCHOST_Reset(SDMMCHOST_TYPE *base) -{ - /* voltage switch to normal but not 1.8V */ - SDMMCHOST_SWITCH_VOLTAGE180V(base, false); - /* Disable DDR mode */ - SDMMCHOST_ENABLE_DDR_MODE(base, false, 0U); - /* disable tuning */ - SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, false); - /* Disable HS400 mode */ - SDMMCHOST_ENABLE_HS400_MODE(base, false); - /* Disable DLL */ - SDMMCHOST_ENABLE_STROBE_DLL(base, false); -} - -void SDMMCHOST_Deinit(void *host) -{ - usdhc_host_t *usdhcHost = (usdhc_host_t *)host; - SDMMCHOST_Reset(usdhcHost->base); - USDHC_Deinit(usdhcHost->base); - SDMMCEVENT_Delete(kSDMMCEVENT_TransferComplete); - SDMMCHOST_CardDetectDeinit(); -} diff --git a/targets/FreeRTOS/UAC18/common/sdmmc/src/fsl_sd.c b/targets/FreeRTOS/UAC18/common/sdmmc/src/fsl_sd.c deleted file mode 100644 index d50686c51e..0000000000 --- a/targets/FreeRTOS/UAC18/common/sdmmc/src/fsl_sd.c +++ /dev/null @@ -1,1968 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2018 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// - -#include "fsl_sd.h" - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Wait write process complete. - * - * @param card Card descriptor. - * @retval kStatus_Timeout Send command timeout. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_WaitWriteComplete(sd_card_t *card); - -/*! - * @brief send write success blocks. - * - * @param card Card descriptor. - * @param blocks blocks number wirte successed - * @retval kStatus_SDMMC_TransferFailed Send command failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_SendWriteSuccessBlocks(sd_card_t *card, uint32_t *blocks); - -/*! - * @brief Send SEND_APPLICATION_COMMAND command. - * - * @param card Card descriptor. - * @param relativeaddress - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_SDMMC_CardNotSupport Card doesn't support. - * @retval kStatus_Success Operate successfully. - */ -inline static status_t SD_SendApplicationCmd(sd_card_t *card, uint32_t relativeAddress); - -/*! - * @brief Send GO_IDLE command to set the card to be idle state. - * - * @param card Card descriptor. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -inline static status_t SD_GoIdle(sd_card_t *card); - -/*! - * @brief Send STOP_TRANSMISSION command after multiple blocks read/write. - * - * @param card Card descriptor. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_StopTransmission(sd_card_t *card); - -/*! - * @brief Send SET_BLOCK_SIZE command. - * - * @param card Card descriptor. - * @param blockSize Block size. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -inline static status_t SD_SetBlockSize(sd_card_t *card, uint32_t blockSize); - -/*! - * @brief Send GET_RCA command to get card relative address. - * - * @param card Card descriptor. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_SendRca(sd_card_t *card); - -/*! - * @brief Send SWITCH_FUNCTION command to switch the card function group. - * - * @param card Card descriptor. - * @param mode 0 to check function group. 1 to switch function group - * @param group Function group - * @param number Function number in the function group. - * @param status Switch function status. - * @retval kStatus_SDMMC_SetCardBlockSizeFailed Set card block size failed. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_SwitchFunction(sd_card_t *card, uint32_t mode, uint32_t group, uint32_t number, uint32_t *status); - -/*! - * @brief Decode raw SCR register content in the data blocks. - * - * @param card Card descriptor. - * @param rawScr Raw SCR register content. - */ -static void SD_DecodeScr(sd_card_t *card, uint32_t *rawScr); - -/*! - * @brief Send GET_SCR command. - * - * @param card Card descriptor. - * @retval kStatus_SDMMC_SendApplicationCommandFailed Send application command failed. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_SDMMC_NotSupportYet Not support yet. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_SendScr(sd_card_t *card); - -/*! - * @brief Switch the card to be high speed mode. - * - * @param card Card descriptor. - * @param group Group number. - * @param functio Function number. - * @retval kStatus_SDMMC_CardNotSupport Card not support. - * @retval kStatus_SDMMC_SwitchFailed Switch failed. - * @retval kStatus_SDMMC_NotSupportYet Not support yet. - * @retval kStatus_Fail Switch failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_SelectFunction(sd_card_t *card, uint32_t group, uint32_t function); - -/*! - * @brief Send SET_DATA_WIDTH command to set SD bus width. - * - * @param card Card descriptor. - * @param width Data bus width. - * @retval kStatus_SDMMC_SendApplicationCommandFailed Send application command failed. - * @retval kStatus_InvalidArgument Invalid argument. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_SetDataBusWidth(sd_card_t *card, sd_data_bus_width_t width); - -/*! - * @brief Decode raw CSD register content in the data blocks. - * - * @param card Card descriptor. - * @param rawCsd Raw CSD register content. - */ -static void SD_DecodeCsd(sd_card_t *card, uint32_t *rawCsd); - -/*! - * @brief Send SEND_CSD command to get CSD register content from Card. - * - * @param card Card descriptor. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_SendCsd(sd_card_t *card); - -/*! - * @brief Decode raw CID register content in the data blocks. - * - * @param rawCid raw CID register content. - * @param card Card descriptor. - */ -static void SD_DecodeCid(sd_card_t *card, uint32_t *rawCid); - -/*! - * @brief Send GET_CID command to get CID from card. - * - * @param card Card descriptor. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_AllSendCid(sd_card_t *card); - -/*! - * @brief Send SEND_OPERATION_CONDITION command. - * - * This function sends host capacity support information and asks the accessed card to send its operating condition - * register content. - * - * @param card Card descriptor. - * @param argument The argument of the send operation condition ncomamnd. - * @retval kStatus_SDMMC_SendApplicationCommandFailed Send application command failed. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Timeout Timeout. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_ApplicationSendOperationCondition(sd_card_t *card, uint32_t argument); - -/*! - * @brief Send GET_INTERFACE_CONDITION command to get card interface condition. - * - * This function checks card interface condition, which includes host supply voltage information and asks the card - * whether card supports the specified host voltage. - * - * @param card Card descriptor. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_SDMMC_CardNotSupport Card doesn't support. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_SendInterfaceCondition(sd_card_t *card); - -/*! - * @brief Send switch voltage command - * switch card voltage to 1.8v - * - * @param card Card descriptor. - */ -static status_t SD_SwitchVoltage(sd_card_t *card); - -/*! - * @brief select bus timing - * select card timing - * @param card Card descriptor. - */ -static status_t SD_SelectBusTiming(sd_card_t *card); - -/*! - * @brief Decode sd 512 bit status - * @param card Card descriptor. - * @param 512 bits satus raw data. - */ -static void SD_DecodeStatus(sd_card_t *card, uint32_t *src); - -/*! - * @brief Read data from specific SD card. - * - * @param card Card descriptor. - * @param buffer Buffer to save data blocks read. - * @param startBlock Card start block number to be read. - * @param blockSize Block size. - * @param blockCount Block count. - * @retval kStatus_SDMMC_CardNotSupport Card doesn't support. - * @retval kStatus_SDMMC_WaitWriteCompleteFailed Wait write complete failed. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_SDMMC_StopTransmissionFailed Stop transmission failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_Read(sd_card_t *card, uint8_t *buffer, uint32_t startBlock, uint32_t blockSize, uint32_t blockCount); - -/*! - * @brief Write data to specific card - * - * @param card Card descriptor. - * @param buffer Buffer to be sent. - * @param startBlock Card start block number to be written. - * @param blockSize Block size. - * @param blockCount Block count. - * @param blockWritten successfully write blocks - * @retval kStatus_SDMMC_CardNotSupport Card doesn't support. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_SDMMC_StopTransmissionFailed Stop transmission failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_Write(sd_card_t *card, - const uint8_t *buffer, - uint32_t startBlock, - uint32_t blockSize, - uint32_t blockCount, - uint32_t *blockWritten); - -/*! - * @brief Erase data for the given block range. - * - * @param card Card descriptor. - * @param startBlock Card start block number to be erased. - * @param blockCount The block count to be erased. - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t SD_Erase(sd_card_t *card, uint32_t startBlock, uint32_t blockCount); - -/*! - * @brief card transfer function. - * - * @param card Card descriptor. - * @param content Transfer content. - * @param retry Retry times - * @retval kStatus_SDMMC_TransferFailed Transfer failed. - * @retval kStatus_Success Operate successfully. - * @retval kStatus_SDMMC_TuningFail tuning fail - */ -static status_t SD_Transfer(sd_card_t *card, SDMMCHOST_TRANSFER *content, uint32_t retry); - -/*! - * @brief card execute tuning function. - * - * @param card Card descriptor. - * @retval kStatus_Success Operate successfully. - * @retval kStatus_SDMMC_TuningFail tuning fail. - * @retval kStatus_SDMMC_TransferFailed transfer fail - */ -inline static status_t SD_ExecuteTuning(sd_card_t *card); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* g_sdmmc statement */ -extern uint32_t g_sdmmc[SDK_SIZEALIGN(SDMMC_GLOBAL_BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)]; -static uint32_t s_sdAuSizeMap[] = {0, - 16 * 1024, - 32 * 1024, - 64 * 1024, - 128 * 1024, - 256 * 1024, - 512 * 1024, - 1024 * 1024, - 2 * 1024 * 1024, - 4 * 1024 * 1024, - 8 * 1024 * 1024, - 12 * 1024 * 1024, - 16 * 1024 * 1024, - 24 * 1024 * 1024, - 32 * 1024 * 1024, - 64 * 1024 * 1024}; -/******************************************************************************* - * Code - ******************************************************************************/ -inline static status_t SD_SendApplicationCmd(sd_card_t *card, uint32_t relativeAddress) -{ - assert(card); - - return SDMMC_SendApplicationCommand(card->host.base, card->host.transfer, relativeAddress); -} - -inline static status_t SD_GoIdle(sd_card_t *card) -{ - assert(card); - - return SDMMC_GoIdle(card->host.base, card->host.transfer); -} - -inline static status_t SD_SetBlockSize(sd_card_t *card, uint32_t blockSize) -{ - assert(card); - - return SDMMC_SetBlockSize(card->host.base, card->host.transfer, blockSize); -} - -inline static status_t SD_ExecuteTuning(sd_card_t *card) -{ - assert(card); - - return SDMMC_ExecuteTuning(card->host.base, card->host.transfer, kSD_SendTuningBlock, 64U); -} - -static status_t SD_SwitchVoltage(sd_card_t *card) -{ - assert(card); - - return SDMMC_SwitchVoltage(card->host.base, card->host.transfer); -} - -static status_t SD_StopTransmission(sd_card_t *card) -{ - assert(card); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - status_t error = kStatus_Success; - - command.index = kSDMMC_StopTransmission; - command.argument = 0U; - command.type = kCARD_CommandTypeAbort; - command.responseType = kCARD_ResponseTypeR1b; - command.responseErrorFlags = SDMMC_R1_ALL_ERROR_FLAG; - - content.command = &command; - content.data = 0U; - error = card->host.transfer(card->host.base, &content); - if (kStatus_Success != error) - { - SDMMC_LOG("\r\nError: send CMD12 failed with host error %d, reponse %x\r\n", error, command.response[0U]); - return kStatus_SDMMC_TransferFailed; - } - - return kStatus_Success; -} - -static status_t SD_Transfer(sd_card_t *card, SDMMCHOST_TRANSFER *content, uint32_t retry) -{ - assert(card->host.transfer); - assert(content); - status_t error; - - do - { - error = card->host.transfer(card->host.base, content); -#if SDMMC_ENABLE_SOFTWARE_TUNING - if (((error == SDMMCHOST_RETUNING_REQUEST) || (error == SDMMCHOST_TUNING_ERROR)) && - (card->currentTiming == kSD_TimingSDR104Mode)) - { - /* tuning error need reset tuning circuit */ - if (error == SDMMCHOST_TUNING_ERROR) - { - SDMMCHOST_RESET_TUNING(card->host.base, 100U); - } - - /* execute re-tuning */ - if (SD_ExecuteTuning(card) != kStatus_Success) - { - error = kStatus_SDMMC_TuningFail; - break; - } - else - { - continue; - } - } - else -#endif - if (error != kStatus_Success) - { - /* if transfer data failed, send cmd12 to abort current transfer */ - if (content->data) - { - SD_StopTransmission(card); - } - } - - if (retry != 0U) - { - retry--; - } - else - { - break; - } - - } while (error != kStatus_Success); - - return error; -} - -static status_t SD_WaitWriteComplete(sd_card_t *card) -{ - assert(card); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - status_t error = kStatus_Success; - - command.index = kSDMMC_SendStatus; - command.argument = card->relativeAddress << 16U; - command.responseType = kCARD_ResponseTypeR1; - - do - { - content.command = &command; - content.data = 0U; - error = SD_Transfer(card, &content, 2U); - if (kStatus_Success != error) - { - SDMMC_LOG("\r\nError: send CMD13 failed with host error %d, response %x", error, command.response[0U]); - break; - } - - if ((command.response[0U] & SDMMC_MASK(kSDMMC_R1ReadyForDataFlag)) && - (SDMMC_R1_CURRENT_STATE(command.response[0U]) != kSDMMC_R1StateProgram)) - { - break; - } - } while (true); - - return error; -} - -static status_t SD_SendWriteSuccessBlocks(sd_card_t *card, uint32_t *blocks) -{ - assert(card); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - SDMMCHOST_DATA data = {0}; - status_t error = kStatus_Success; - - memset(g_sdmmc, 0U, sizeof(g_sdmmc)); - - /* Wait for the card write process complete because of that card read process and write process use one buffer. */ - if (kStatus_Success != SD_WaitWriteComplete(card)) - { - return kStatus_SDMMC_WaitWriteCompleteFailed; - } - - if (kStatus_Success != SD_SendApplicationCmd(card, card->relativeAddress)) - { - return kStatus_SDMMC_SendApplicationCommandFailed; - } - - command.index = kSD_ApplicationSendNumberWriteBlocks; - command.responseType = kCARD_ResponseTypeR1; - - data.blockSize = 4U; - data.blockCount = 1U; - data.rxData = &g_sdmmc[0]; - - content.command = &command; - content.data = &data; - error = card->host.transfer(card->host.base, &content); - if ((kStatus_Success != error) || ((command.response[0U]) & SDMMC_R1_ALL_ERROR_FLAG)) - { - SDMMC_LOG("\r\nError: send ACMD13 failed with host error %d, response %x", error, command.response[0U]); - } - else - { - *blocks = SWAP_WORD_BYTE_SEQUENCE(g_sdmmc[0]); - } - - return error; -} - -static status_t SD_SendRca(sd_card_t *card) -{ - assert(card); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - status_t error = kStatus_Success; - - command.index = kSD_SendRelativeAddress; - command.argument = 0U; - command.responseType = kCARD_ResponseTypeR6; - - content.command = &command; - content.data = NULL; - - error = card->host.transfer(card->host.base, &content); - if (kStatus_Success == error) - { - card->relativeAddress = (command.response[0U] >> 16U); - } - else - { - SDMMC_LOG("\r\nError: send CMD3 failed with host error %d, response %x", error, command.response[0U]); - } - - return error; -} - -static status_t SD_SwitchFunction(sd_card_t *card, uint32_t mode, uint32_t group, uint32_t number, uint32_t *status) -{ - assert(card); - assert(status); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - SDMMCHOST_DATA data = {0}; - status_t error = kStatus_Success; - - command.index = kSD_Switch; - command.argument = (mode << 31U | 0x00FFFFFFU); - command.argument &= ~((uint32_t)(0xFU) << (group * 4U)); - command.argument |= (number << (group * 4U)); - command.responseType = kCARD_ResponseTypeR1; - - data.blockSize = 64U; - data.blockCount = 1U; - data.rxData = status; - - content.command = &command; - content.data = &data; - error = card->host.transfer(card->host.base, &content); - if ((kStatus_Success != error) || ((command.response[0U]) & SDMMC_R1_ALL_ERROR_FLAG)) - { - SDMMC_LOG("\r\n\r\nError: send CMD6 failed with host error %d, response %x", error, command.response[0U]); - } - - return error; -} - -static void SD_DecodeScr(sd_card_t *card, uint32_t *rawScr) -{ - assert(card); - assert(rawScr); - - sd_scr_t *scr; - - scr = &(card->scr); - scr->scrStructure = (uint8_t)((rawScr[0U] & 0xF0000000U) >> 28U); - scr->sdSpecification = (uint8_t)((rawScr[0U] & 0xF000000U) >> 24U); - if ((uint8_t)((rawScr[0U] & 0x800000U) >> 23U)) - { - scr->flags |= kSD_ScrDataStatusAfterErase; - } - scr->sdSecurity = (uint8_t)((rawScr[0U] & 0x700000U) >> 20U); - scr->sdBusWidths = (uint8_t)((rawScr[0U] & 0xF0000U) >> 16U); - if ((uint8_t)((rawScr[0U] & 0x8000U) >> 15U)) - { - scr->flags |= kSD_ScrSdSpecification3; - } - scr->extendedSecurity = (uint8_t)((rawScr[0U] & 0x7800U) >> 10U); - scr->commandSupport = (uint8_t)(rawScr[0U] & 0x3U); - scr->reservedForManufacturer = rawScr[1U]; - /* Get specification version. */ - switch (scr->sdSpecification) - { - case 0U: - card->version = kSD_SpecificationVersion1_0; - break; - case 1U: - card->version = kSD_SpecificationVersion1_1; - break; - case 2U: - card->version = kSD_SpecificationVersion2_0; - if (card->scr.flags & kSD_ScrSdSpecification3) - { - card->version = kSD_SpecificationVersion3_0; - } - break; - default: - break; - } - if (card->scr.sdBusWidths & 0x4U) - { - card->flags |= kSD_Support4BitWidthFlag; - } - /* speed class control cmd */ - if (card->scr.commandSupport & 0x01U) - { - card->flags |= kSD_SupportSpeedClassControlCmd; - } - /* set block count cmd */ - if (card->scr.commandSupport & 0x02U) - { - card->flags |= kSD_SupportSetBlockCountCmd; - } -} - -static status_t SD_SendScr(sd_card_t *card) -{ - assert(card); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - SDMMCHOST_DATA data = {0}; - uint32_t *rawScr = g_sdmmc; - status_t error = kStatus_Success; - - /* memset the global buffer */ - memset(g_sdmmc, 0U, sizeof(g_sdmmc)); - - if (kStatus_Success != SD_SendApplicationCmd(card, card->relativeAddress)) - { - return kStatus_SDMMC_SendApplicationCommandFailed; - } - - command.index = kSD_ApplicationSendScr; - command.responseType = kCARD_ResponseTypeR1; - command.argument = 0U; - - data.blockSize = 8U; - data.blockCount = 1U; - data.rxData = rawScr; - - content.data = &data; - content.command = &command; - error = card->host.transfer(card->host.base, &content); - if ((kStatus_Success != error) || ((command.response[0U]) & SDMMC_R1_ALL_ERROR_FLAG)) - { - SDMMC_LOG("\r\nError: send ACMD51 failed with host error %d, response %x", error, command.response[0U]); - } - else - { - /* SCR register data byte sequence from card is big endian(MSB first). */ - switch (card->host.config.endianMode) - { - case kSDMMCHOST_EndianModeLittle: - /* In little endian mode, SD bus byte transferred first is the byte stored in lowest byte position in a - word which will cause 4 byte's sequence in a word is not consistent with their original sequence from - card. So the sequence of 4 bytes received in a word should be converted. */ - rawScr[0U] = SWAP_WORD_BYTE_SEQUENCE(rawScr[0U]); - rawScr[1U] = SWAP_WORD_BYTE_SEQUENCE(rawScr[1U]); - break; - case kSDMMCHOST_EndianModeBig: - break; /* Doesn't need to switch byte sequence when decodes bytes as big endian sequence. */ - case kSDMMCHOST_EndianModeHalfWordBig: - rawScr[0U] = SWAP_HALF_WROD_BYTE_SEQUENCE(rawScr[0U]); - rawScr[1U] = SWAP_HALF_WROD_BYTE_SEQUENCE(rawScr[1U]); - break; - default: - return kStatus_SDMMC_NotSupportYet; - } - memcpy(card->rawScr, rawScr, sizeof(card->rawScr)); - /* decode scr */ - SD_DecodeScr(card, rawScr); - } - - return error; -} - -static status_t SD_SelectFunction(sd_card_t *card, uint32_t group, uint32_t function) -{ - assert(card); - - uint32_t *functionStatus = g_sdmmc; - uint16_t functionGroupInfo[6U] = {0}; - uint32_t currentFunctionStatus = 0U; - - /* memset the global buffer */ - memset(g_sdmmc, 0, sizeof(g_sdmmc)); - - /* check if card support CMD6 */ - if ((card->version <= kSD_SpecificationVersion1_0) || (!(card->csd.cardCommandClass & kSDMMC_CommandClassSwitch))) - { - SDMMC_LOG("\r\nError: current card not support CMD6"); - return kStatus_SDMMC_NotSupportYet; - } - - /* Check if card support high speed mode. */ - if (kStatus_Success != SD_SwitchFunction(card, kSD_SwitchCheck, group, function, functionStatus)) - { - return kStatus_SDMMC_TransferFailed; - } - - /* Switch function status byte sequence from card is big endian(MSB first). */ - switch (card->host.config.endianMode) - { - case kSDMMCHOST_EndianModeLittle: - /* In little endian mode, SD bus byte transferred first is the byte stored in lowest byte position in - a word which will cause 4 byte's sequence in a word is not consistent with their original sequence from - card. So the sequence of 4 bytes received in a word should be converted. */ - functionStatus[0U] = SWAP_WORD_BYTE_SEQUENCE(functionStatus[0U]); - functionStatus[1U] = SWAP_WORD_BYTE_SEQUENCE(functionStatus[1U]); - functionStatus[2U] = SWAP_WORD_BYTE_SEQUENCE(functionStatus[2U]); - functionStatus[3U] = SWAP_WORD_BYTE_SEQUENCE(functionStatus[3U]); - functionStatus[4U] = SWAP_WORD_BYTE_SEQUENCE(functionStatus[4U]); - break; - case kSDMMCHOST_EndianModeBig: - break; /* Doesn't need to switch byte sequence when decodes bytes as big endian sequence. */ - case kSDMMCHOST_EndianModeHalfWordBig: - functionStatus[0U] = SWAP_HALF_WROD_BYTE_SEQUENCE(functionStatus[0U]); - functionStatus[1U] = SWAP_HALF_WROD_BYTE_SEQUENCE(functionStatus[1U]); - functionStatus[2U] = SWAP_HALF_WROD_BYTE_SEQUENCE(functionStatus[2U]); - functionStatus[3U] = SWAP_HALF_WROD_BYTE_SEQUENCE(functionStatus[3U]); - functionStatus[4U] = SWAP_HALF_WROD_BYTE_SEQUENCE(functionStatus[4U]); - break; - default: - return kStatus_SDMMC_NotSupportYet; - } - /* -functionStatus[0U]---bit511~bit480; - -functionStatus[1U]---bit479~bit448; - -functionStatus[2U]---bit447~bit416; - -functionStatus[3U]---bit415~bit384; - -functionStatus[4U]---bit383~bit352; - According to the "switch function status[bits 511~0]" return by switch command in mode "check function": - -Check if function 1(high speed) in function group 1 is supported by checking if bit 401 is set; - -check if function 1 is ready and can be switched by checking if bits 379~376 equal value 1; - */ - functionGroupInfo[5U] = (uint16_t)functionStatus[0U]; - functionGroupInfo[4U] = (uint16_t)(functionStatus[1U] >> 16U); - functionGroupInfo[3U] = (uint16_t)(functionStatus[1U]); - functionGroupInfo[2U] = (uint16_t)(functionStatus[2U] >> 16U); - functionGroupInfo[1U] = (uint16_t)(functionStatus[2U]); - functionGroupInfo[0U] = (uint16_t)(functionStatus[3U] >> 16U); - currentFunctionStatus = ((functionStatus[3U] & 0xFFU) << 8U) | (functionStatus[4U] >> 24U); - - /* check if function is support */ - if (((functionGroupInfo[group] & (1 << function)) == 0U) || - ((currentFunctionStatus >> (group * 4U)) & 0xFU) != function) - { - SDMMC_LOG("\r\nError: current card not support function %d", function); - return kStatus_SDMMC_NotSupportYet; - } - - /* Switch to high speed mode. */ - if (kStatus_Success != SD_SwitchFunction(card, kSD_SwitchSet, group, function, functionStatus)) - { - return kStatus_SDMMC_TransferFailed; - } - - /* Switch function status byte sequence from card is big endian(MSB first). */ - switch (card->host.config.endianMode) - { - case kSDMMCHOST_EndianModeLittle: - /* In little endian mode is little endian, SD bus byte transferred first is the byte stored in lowest byte - position in a word which will cause 4 byte's sequence in a word is not consistent with their original - sequence from card. So the sequence of 4 bytes received in a word should be converted. */ - functionStatus[3U] = SWAP_WORD_BYTE_SEQUENCE(functionStatus[3U]); - functionStatus[4U] = SWAP_WORD_BYTE_SEQUENCE(functionStatus[4U]); - break; - case kSDMMCHOST_EndianModeBig: - break; /* Doesn't need to switch byte sequence when decodes bytes as big endian sequence. */ - case kSDMMCHOST_EndianModeHalfWordBig: - functionStatus[3U] = SWAP_HALF_WROD_BYTE_SEQUENCE(functionStatus[3U]); - functionStatus[4U] = SWAP_HALF_WROD_BYTE_SEQUENCE(functionStatus[4U]); - break; - default: - return kStatus_SDMMC_NotSupportYet; - } - /* According to the "switch function status[bits 511~0]" return by switch command in mode "set function": - -check if group 1 is successfully changed to function 1 by checking if bits 379~376 equal value 1; - */ - currentFunctionStatus = ((functionStatus[3U] & 0xFFU) << 8U) | (functionStatus[4U] >> 24U); - - if (((currentFunctionStatus >> (group * 4U)) & 0xFU) != function) - { - SDMMC_LOG("\r\nError: switch to function %d failed", function); - return kStatus_SDMMC_SwitchFailed; - } - - return kStatus_Success; -} - -static status_t SD_SetDataBusWidth(sd_card_t *card, sd_data_bus_width_t width) -{ - assert(card); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - status_t error = kStatus_Success; - - if (kStatus_Success != SD_SendApplicationCmd(card, card->relativeAddress)) - { - return kStatus_SDMMC_SendApplicationCommandFailed; - } - - command.index = kSD_ApplicationSetBusWdith; - command.responseType = kCARD_ResponseTypeR1; - switch (width) - { - case kSD_DataBusWidth1Bit: - command.argument = 0U; - break; - case kSD_DataBusWidth4Bit: - command.argument = 2U; - break; - default: - return kStatus_InvalidArgument; - } - - content.command = &command; - content.data = NULL; - error = card->host.transfer(card->host.base, &content); - if ((kStatus_Success != error) || ((command.response[0U]) & SDMMC_R1_ALL_ERROR_FLAG)) - { - SDMMC_LOG("\r\nError: send ACMD6 failed with host error %d, response %x", error, command.response[0U]); - } - - return error; -} - -static void SD_DecodeCsd(sd_card_t *card, uint32_t *rawCsd) -{ - assert(card); - assert(rawCsd); - - sd_csd_t *csd; - - csd = &(card->csd); - csd->csdStructure = (uint8_t)((rawCsd[3U] & 0xC0000000U) >> 30U); - csd->dataReadAccessTime1 = (uint8_t)((rawCsd[3U] & 0xFF0000U) >> 16U); - csd->dataReadAccessTime2 = (uint8_t)((rawCsd[3U] & 0xFF00U) >> 8U); - csd->transferSpeed = (uint8_t)(rawCsd[3U] & 0xFFU); - csd->cardCommandClass = (uint16_t)((rawCsd[2U] & 0xFFF00000U) >> 20U); - csd->readBlockLength = (uint8_t)((rawCsd[2U] & 0xF0000U) >> 16U); - if (rawCsd[2U] & 0x8000U) - { - csd->flags |= kSD_CsdReadBlockPartialFlag; - } - if (rawCsd[2U] & 0x4000U) - { - csd->flags |= kSD_CsdReadBlockPartialFlag; - } - if (rawCsd[2U] & 0x2000U) - { - csd->flags |= kSD_CsdReadBlockMisalignFlag; - } - if (rawCsd[2U] & 0x1000U) - { - csd->flags |= kSD_CsdDsrImplementedFlag; - } - switch (csd->csdStructure) - { - case 0: - csd->deviceSize = (uint32_t)((rawCsd[2U] & 0x3FFU) << 2U); - csd->deviceSize |= (uint32_t)((rawCsd[1U] & 0xC0000000U) >> 30U); - csd->readCurrentVddMin = (uint8_t)((rawCsd[1U] & 0x38000000U) >> 27U); - csd->readCurrentVddMax = (uint8_t)((rawCsd[1U] & 0x7000000U) >> 24U); - csd->writeCurrentVddMin = (uint8_t)((rawCsd[1U] & 0xE00000U) >> 20U); - csd->writeCurrentVddMax = (uint8_t)((rawCsd[1U] & 0x1C0000U) >> 18U); - csd->deviceSizeMultiplier = (uint8_t)((rawCsd[1U] & 0x38000U) >> 15U); - - /* Get card total block count and block size. */ - card->blockCount = ((csd->deviceSize + 1U) << (csd->deviceSizeMultiplier + 2U)); - card->blockSize = (1U << (csd->readBlockLength)); - if (card->blockSize != FSL_SDMMC_DEFAULT_BLOCK_SIZE) - { - card->blockCount = (card->blockCount * card->blockSize); - card->blockSize = FSL_SDMMC_DEFAULT_BLOCK_SIZE; - card->blockCount = (card->blockCount / card->blockSize); - } - break; - case 1: - card->blockSize = FSL_SDMMC_DEFAULT_BLOCK_SIZE; - - csd->deviceSize = (uint32_t)((rawCsd[2U] & 0x3FU) << 16U); - csd->deviceSize |= (uint32_t)((rawCsd[1U] & 0xFFFF0000U) >> 16U); - if (csd->deviceSize >= 0xFFFFU) - { - card->flags |= kSD_SupportSdxcFlag; - } - - card->blockCount = ((csd->deviceSize + 1U) * 1024U); - break; - default: - break; - } - if ((uint8_t)((rawCsd[1U] & 0x4000U) >> 14U)) - { - csd->flags |= kSD_CsdEraseBlockEnabledFlag; - } - csd->eraseSectorSize = (uint8_t)((rawCsd[1U] & 0x3F80U) >> 7U); - csd->writeProtectGroupSize = (uint8_t)(rawCsd[1U] & 0x7FU); - if ((uint8_t)(rawCsd[0U] & 0x80000000U)) - { - csd->flags |= kSD_CsdWriteProtectGroupEnabledFlag; - } - csd->writeSpeedFactor = (uint8_t)((rawCsd[0U] & 0x1C000000U) >> 26U); - csd->writeBlockLength = (uint8_t)((rawCsd[0U] & 0x3C00000U) >> 22U); - if ((uint8_t)((rawCsd[0U] & 0x200000U) >> 21U)) - { - csd->flags |= kSD_CsdWriteBlockPartialFlag; - } - if ((uint8_t)((rawCsd[0U] & 0x8000U) >> 15U)) - { - csd->flags |= kSD_CsdFileFormatGroupFlag; - } - if ((uint8_t)((rawCsd[0U] & 0x4000U) >> 14U)) - { - csd->flags |= kSD_CsdCopyFlag; - } - if ((uint8_t)((rawCsd[0U] & 0x2000U) >> 13U)) - { - csd->flags |= kSD_CsdPermanentWriteProtectFlag; - } - if ((uint8_t)((rawCsd[0U] & 0x1000U) >> 12U)) - { - csd->flags |= kSD_CsdTemporaryWriteProtectFlag; - } - csd->fileFormat = (uint8_t)((rawCsd[0U] & 0xC00U) >> 10U); -} - -static status_t SD_SendCsd(sd_card_t *card) -{ - assert(card); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - status_t error = kStatus_Success; - - command.index = kSDMMC_SendCsd; - command.argument = (card->relativeAddress << 16U); - command.responseType = kCARD_ResponseTypeR2; - - content.command = &command; - content.data = NULL; - error = card->host.transfer(card->host.base, &content); - if (kStatus_Success == error) - { - memcpy(card->rawCsd, command.response, sizeof(card->rawCsd)); - /* The response is from bit 127:8 in R2, corrisponding to command.response[3U]:command.response[0U][31U:8]. */ - SD_DecodeCsd(card, command.response); - } - else - { - error = kStatus_SDMMC_TransferFailed; - SDMMC_LOG("\r\nError: send CMD9(get csd) failed with host error %d, response %x", error, command.response[0U]); - } - - return error; -} - -static void SD_DecodeCid(sd_card_t *card, uint32_t *rawCid) -{ - assert(card); - assert(rawCid); - - sd_cid_t *cid; - - cid = &(card->cid); - cid->manufacturerID = (uint8_t)((rawCid[3U] & 0xFF000000U) >> 24U); - cid->applicationID = (uint16_t)((rawCid[3U] & 0xFFFF00U) >> 8U); - - cid->productName[0U] = (uint8_t)((rawCid[3U] & 0xFFU)); - cid->productName[1U] = (uint8_t)((rawCid[2U] & 0xFF000000U) >> 24U); - cid->productName[2U] = (uint8_t)((rawCid[2U] & 0xFF0000U) >> 16U); - cid->productName[3U] = (uint8_t)((rawCid[2U] & 0xFF00U) >> 8U); - cid->productName[4U] = (uint8_t)((rawCid[2U] & 0xFFU)); - - cid->productVersion = (uint8_t)((rawCid[1U] & 0xFF000000U) >> 24U); - - cid->productSerialNumber = (uint32_t)((rawCid[1U] & 0xFFFFFFU) << 8U); - cid->productSerialNumber |= (uint32_t)((rawCid[0U] & 0xFF000000U) >> 24U); - - cid->manufacturerData = (uint16_t)((rawCid[0U] & 0xFFF00U) >> 8U); -} - -static status_t SD_AllSendCid(sd_card_t *card) -{ - assert(card); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - - command.index = kSDMMC_AllSendCid; - command.argument = 0U; - command.responseType = kCARD_ResponseTypeR2; - - content.command = &command; - content.data = NULL; - if (kStatus_Success == card->host.transfer(card->host.base, &content)) - { - memcpy(card->rawCid, command.response, sizeof(card->rawCid)); - SD_DecodeCid(card, command.response); - - return kStatus_Success; - } - - return kStatus_SDMMC_TransferFailed; -} - -static status_t SD_ApplicationSendOperationCondition(sd_card_t *card, uint32_t argument) -{ - assert(card); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - status_t error = kStatus_Fail; - uint32_t i = FSL_SDMMC_MAX_VOLTAGE_RETRIES; - - command.index = kSD_ApplicationSendOperationCondition; - command.argument = argument; - command.responseType = kCARD_ResponseTypeR3; - - while (i--) - { - if (kStatus_Success != SD_SendApplicationCmd(card, 0U)) - { - continue; - } - - content.command = &command; - content.data = NULL; - error = card->host.transfer(card->host.base, &content); - if (kStatus_Success != error) - { - SDMMC_LOG("\r\nError: send ACMD41 failed with host error %d, response %x", error, command.response[0U]); - return kStatus_SDMMC_TransferFailed; - } - - /* Wait until card exit busy state. */ - if (command.response[0U] & SDMMC_MASK(kSD_OcrPowerUpBusyFlag)) - { - /* high capacity check */ - if (command.response[0U] & SDMMC_MASK(kSD_OcrCardCapacitySupportFlag)) - { - card->flags |= kSD_SupportHighCapacityFlag; - } - /* 1.8V support */ - if (command.response[0U] & SDMMC_MASK(kSD_OcrSwitch18AcceptFlag)) - { - card->flags |= kSD_SupportVoltage180v; - } - card->ocr = command.response[0U]; - - return kStatus_Success; - } - } - - SDMMC_LOG("\r\nError: send ACMD41 timeout"); - - return error; -} - -static status_t SD_SendInterfaceCondition(sd_card_t *card) -{ - assert(card); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - uint32_t i = FSL_SDMMC_MAX_CMD_RETRIES; - status_t error = kStatus_Success; - - command.index = kSD_SendInterfaceCondition; - command.argument = 0x1AAU; - command.responseType = kCARD_ResponseTypeR7; - - content.command = &command; - content.data = NULL; - do - { - error = card->host.transfer(card->host.base, &content); - if (kStatus_Success != error) - { - SDMMC_LOG("\r\nError: send CMD8 failed with host error %d, response %x", error, command.response[0U]); - } - else - { - if ((command.response[0U] & 0xFFU) != 0xAAU) - { - error = kStatus_SDMMC_CardNotSupport; - SDMMC_LOG("\r\nError: card not support CMD8"); - } - else - { - error = kStatus_Success; - } - } - } while (--i && (error != kStatus_Success)); - - return error; -} - -static status_t SD_SelectBusTiming(sd_card_t *card) -{ - assert(card); - - status_t error = kStatus_SDMMC_SwitchBusTimingFailed; - - if (card->operationVoltage != kCARD_OperationVoltage180V) - { - /* Switch the card to high speed mode */ - if (card->host.capability.flags & kSDMMCHOST_SupportHighSpeed) - { - /* group 1, function 1 ->high speed mode*/ - error = SD_SelectFunction(card, kSD_GroupTimingMode, kSD_FunctionSDR25HighSpeed); - /* If the result isn't "switching to high speed mode(50MHZ) successfully or card doesn't support high speed - * mode". Return failed status. */ - if (error == kStatus_Success) - { - card->currentTiming = kSD_TimingSDR25HighSpeedMode; - card->busClock_Hz = - SDMMCHOST_SET_CARD_CLOCK(card->host.base, card->host.sourceClock_Hz, SD_CLOCK_50MHZ); - } - else if (error == kStatus_SDMMC_NotSupportYet) - { - /* if not support high speed, keep the card work at default mode */ - SDMMC_LOG("\r\nNote: High speed mode is not supported by card"); - return kStatus_Success; - } - } - else - { - /* if not support high speed, keep the card work at default mode */ - return kStatus_Success; - } - } - /* card is in UHS_I mode */ - else if ((kSDMMCHOST_SupportSDR104 != SDMMCHOST_NOT_SUPPORT) || - (kSDMMCHOST_SupportSDR50 != SDMMCHOST_NOT_SUPPORT) || (kSDMMCHOST_SupportDDR50 != SDMMCHOST_NOT_SUPPORT)) - { - switch (card->currentTiming) - { - /* if not select timing mode, sdmmc will handle it automatically*/ - case kSD_TimingSDR12DefaultMode: - case kSD_TimingSDR104Mode: - error = SD_SelectFunction(card, kSD_GroupTimingMode, kSD_FunctionSDR104); - if (error == kStatus_Success) - { - card->currentTiming = kSD_TimingSDR104Mode; - card->busClock_Hz = SDMMCHOST_SET_CARD_CLOCK(card->host.base, card->host.sourceClock_Hz, - SDMMCHOST_SUPPORT_SDR104_FREQ); - break; - } - SDMMC_LOG("\r\nNote: SDR104 mode is not supported by card"); - break; - case kSD_TimingDDR50Mode: - error = SD_SelectFunction(card, kSD_GroupTimingMode, kSD_FunctionDDR50); - if (error == kStatus_Success) - { - card->currentTiming = kSD_TimingDDR50Mode; - card->busClock_Hz = - SDMMCHOST_SET_CARD_CLOCK(card->host.base, card->host.sourceClock_Hz, SD_CLOCK_50MHZ); - SDMMCHOST_ENABLE_DDR_MODE(card->host.base, true, 0U); - break; - } - SDMMC_LOG("\r\nNote: DDR50 mode is not supported by card"); - break; - case kSD_TimingSDR50Mode: - error = SD_SelectFunction(card, kSD_GroupTimingMode, kSD_FunctionSDR50); - if (error == kStatus_Success) - { - card->currentTiming = kSD_TimingSDR50Mode; - card->busClock_Hz = - SDMMCHOST_SET_CARD_CLOCK(card->host.base, card->host.sourceClock_Hz, SD_CLOCK_100MHZ); - break; - } - SDMMC_LOG("\r\nNote: SDR50 mode is not supported by card"); - break; - case kSD_TimingSDR25HighSpeedMode: - error = SD_SelectFunction(card, kSD_GroupTimingMode, kSD_FunctionSDR25HighSpeed); - if (error == kStatus_Success) - { - card->currentTiming = kSD_TimingSDR25HighSpeedMode; - card->busClock_Hz = - SDMMCHOST_SET_CARD_CLOCK(card->host.base, card->host.sourceClock_Hz, SD_CLOCK_50MHZ); - } - break; - - default: - SDMMC_LOG("\r\nWarning: unknown timing mode"); - break; - } - } - else - { - } - - if (error == kStatus_Success) - { - /* SDR50 and SDR104 mode need tuning */ - if ((card->currentTiming == kSD_TimingSDR50Mode) || (card->currentTiming == kSD_TimingSDR104Mode)) - { - /* config IO strength in IOMUX*/ - if (card->currentTiming == kSD_TimingSDR50Mode) - { - SDMMCHOST_CONFIG_SD_IO(CARD_BUS_FREQ_100MHZ1, CARD_BUS_STRENGTH_7); - } - else - { - SDMMCHOST_CONFIG_SD_IO(CARD_BUS_FREQ_200MHZ, CARD_BUS_STRENGTH_7); - } - /* execute tuning */ - if (SD_ExecuteTuning(card) != kStatus_Success) - { - SDMMC_LOG("\r\nError: tuning failed for mode %d", card->currentTiming); - return kStatus_SDMMC_TuningFail; - } - } - else - { - /* set default IO strength to 4 to cover card adapter driver strength difference */ - SDMMCHOST_CONFIG_SD_IO(CARD_BUS_FREQ_100MHZ1, CARD_BUS_STRENGTH_4); - } - } - - return error; -} - -static void SD_DecodeStatus(sd_card_t *card, uint32_t *src) -{ - assert(card); - assert(src); - - card->stat.busWidth = (uint8_t)((src[0U] & 0xC0000000U) >> 30U); /* 511-510 */ - card->stat.secureMode = (uint8_t)((src[0U] & 0x20000000U) >> 29U); /* 509 */ - card->stat.cardType = (uint16_t)((src[0U] & 0x0000FFFFU)); /* 495-480 */ - card->stat.protectedSize = src[1U]; /* 479-448 */ - card->stat.speedClass = (uint8_t)((src[2U] & 0xFF000000U) >> 24U); /* 447-440 */ - card->stat.performanceMove = (uint8_t)((src[2U] & 0x00FF0000U) >> 16U); /* 439-432 */ - card->stat.auSize = (uint8_t)((src[2U] & 0x0000F000U) >> 12U); /* 431-428 */ - card->stat.eraseSize = (uint16_t)(((src[2U] & 0x000000FFU) << 8U) | ((src[3U] & 0xFF000000U) >> 24U)); /* 423-408 */ - card->stat.eraseTimeout = (((uint8_t)((src[3U] & 0x00FF0000U) >> 16U)) & 0xFCU) >> 2U; /* 407-402 */ - card->stat.eraseOffset = ((uint8_t)((src[3U] & 0x00FF0000U) >> 16U)) & 0x3U; /* 401-400 */ - card->stat.uhsSpeedGrade = (((uint8_t)((src[3U] & 0x0000FF00U) >> 8U)) & 0xF0U) >> 4U; /* 399-396 */ - card->stat.uhsAuSize = ((uint8_t)((src[3U] & 0x0000FF00U) >> 8U)) & 0xFU; /* 395-392 */ -} - -status_t SD_ReadStatus(sd_card_t *card) -{ - assert(card); - - uint32_t i = 0U; - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - SDMMCHOST_DATA data = {0}; - status_t error = kStatus_Success; - - memset(g_sdmmc, 0U, sizeof(g_sdmmc)); - - /* wait card status ready. */ - if (kStatus_Success != SD_WaitWriteComplete(card)) - { - return kStatus_SDMMC_WaitWriteCompleteFailed; - } - - if (kStatus_Success != SD_SendApplicationCmd(card, card->relativeAddress)) - { - return kStatus_SDMMC_SendApplicationCommandFailed; - } - - command.index = kSDMMC_SendStatus; - command.responseType = kCARD_ResponseTypeR1; - - data.blockSize = 64U; - data.blockCount = 1U; - data.rxData = &g_sdmmc[0]; - - content.command = &command; - content.data = &data; - error = card->host.transfer(card->host.base, &content); - if ((kStatus_Success != error) || ((command.response[0U]) & SDMMC_R1_ALL_ERROR_FLAG)) - { - SDMMC_LOG("\r\nError: send ACMD13 failed with host error %d, response %x", error, command.response[0U]); - - return kStatus_SDMMC_TransferFailed; - } - - switch (card->host.config.endianMode) - { - case kSDMMCHOST_EndianModeLittle: - /* In little endian mode, SD bus byte transferred first is the byte stored in lowest byte position in - a word which will cause 4 byte's sequence in a word is not consistent with their original sequence from - card. So the sequence of 4 bytes received in a word should be converted. */ - for (i = 0U; i < 16; i++) - { - g_sdmmc[i] = SWAP_WORD_BYTE_SEQUENCE(g_sdmmc[i]); - } - break; - case kSDMMCHOST_EndianModeBig: - break; /* Doesn't need to switch byte sequence when decodes bytes as big endian sequence. */ - case kSDMMCHOST_EndianModeHalfWordBig: - for (i = 0U; i < 16; i++) - { - g_sdmmc[i] = SWAP_HALF_WROD_BYTE_SEQUENCE(g_sdmmc[i]); - } - break; - default: - return kStatus_SDMMC_NotSupportYet; - } - - SD_DecodeStatus(card, g_sdmmc); - - return kStatus_Success; -} - -status_t SD_SelectCard(sd_card_t *card, bool isSelected) -{ - assert(card); - - return SDMMC_SelectCard(card->host.base, card->host.transfer, card->relativeAddress, isSelected); -} - -status_t SD_SetDriverStrength(sd_card_t *card, sd_driver_strength_t driverStrength) -{ - assert(card); - - status_t error; - uint32_t strength = driverStrength; - - error = SD_SelectFunction(card, kSD_GroupDriverStrength, strength); - - return error; -} - -status_t SD_SetMaxCurrent(sd_card_t *card, sd_max_current_t maxCurrent) -{ - assert(card); - - status_t error; - uint32_t current = maxCurrent; - - error = SD_SelectFunction(card, kSD_GroupCurrentLimit, current); - - return error; -} - -static status_t SD_Read(sd_card_t *card, uint8_t *buffer, uint32_t startBlock, uint32_t blockSize, uint32_t blockCount) -{ - assert(card); - assert(buffer); - assert(blockCount); - assert(blockSize == FSL_SDMMC_DEFAULT_BLOCK_SIZE); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - SDMMCHOST_DATA data = {0}; - - if (((card->flags & kSD_SupportHighCapacityFlag) && (blockSize != 512U)) || (blockSize > card->blockSize) || - (blockSize > card->host.capability.maxBlockLength) || (blockSize % 4)) - { - SDMMC_LOG("\r\nError: read with parameter, block size %d is not support", blockSize); - return kStatus_SDMMC_CardNotSupport; - } - - /* Wait for the card write process complete because of that card read process and write process use one buffer. */ - if (kStatus_Success != SD_WaitWriteComplete(card)) - { - return kStatus_SDMMC_WaitWriteCompleteFailed; - } - - data.blockSize = blockSize; - data.blockCount = blockCount; - data.rxData = (uint32_t *)buffer; - data.enableAutoCommand12 = true; - - command.index = (blockCount == 1U) ? kSDMMC_ReadSingleBlock : kSDMMC_ReadMultipleBlock; - command.argument = startBlock; - if (!(card->flags & kSD_SupportHighCapacityFlag)) - { - command.argument *= data.blockSize; - } - command.responseType = kCARD_ResponseTypeR1; - command.responseErrorFlags = SDMMC_R1_ALL_ERROR_FLAG; - - content.command = &command; - content.data = &data; - - return SD_Transfer(card, &content, 1U); -} - -static status_t SD_Write(sd_card_t *card, - const uint8_t *buffer, - uint32_t startBlock, - uint32_t blockSize, - uint32_t blockCount, - uint32_t *writtenBlocks) -{ - assert(card); - assert(buffer); - assert(blockCount); - assert(blockSize == FSL_SDMMC_DEFAULT_BLOCK_SIZE); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - SDMMCHOST_DATA data = {0}; - status_t error; - - if (((card->flags & kSD_SupportHighCapacityFlag) && (blockSize != 512U)) || (blockSize > card->blockSize) || - (blockSize > card->host.capability.maxBlockLength) || (blockSize % 4U)) - { - SDMMC_LOG("\r\nError: write with parameter, block size %d is not support", blockSize); - return kStatus_SDMMC_CardNotSupport; - } - - /* Wait for the card write process complete because of that card read process and write process use one buffer.*/ - if (kStatus_Success != SD_WaitWriteComplete(card)) - { - return kStatus_SDMMC_WaitWriteCompleteFailed; - } - - /* Wait for the card's buffer to be not full to write to improve the write performance. */ - while ((GET_SDMMCHOST_STATUS(card->host.base) & CARD_DATA0_STATUS_MASK) != CARD_DATA0_NOT_BUSY) - { - } - - data.enableAutoCommand12 = true; - data.blockSize = blockSize; - command.responseType = kCARD_ResponseTypeR1; - command.responseErrorFlags = SDMMC_R1_ALL_ERROR_FLAG; - - command.index = (blockCount == 1U) ? kSDMMC_WriteSingleBlock : kSDMMC_WriteMultipleBlock; - command.argument = startBlock; - if (!(card->flags & kSD_SupportHighCapacityFlag)) - { - command.argument *= data.blockSize; - } - - *writtenBlocks = blockCount; - data.blockCount = blockCount; - data.txData = (const uint32_t *)(buffer); - - content.command = &command; - content.data = &data; - - error = SD_Transfer(card, &content, 0U); - if (error != kStatus_Success) - { - /* check the successfully written block */ - if ((SD_SendWriteSuccessBlocks(card, writtenBlocks) == kStatus_Success)) - { - if (*writtenBlocks) - { - /* written success, but not all the blocks are written */ - error = kStatus_Success; - } - } - SDMMC_LOG("\r\nWarning: write failed with block count %d, successed %d", blockCount, *writtenBlocks); - } - - return error; -} - -static status_t SD_Erase(sd_card_t *card, uint32_t startBlock, uint32_t blockCount) -{ - assert(card); - assert(blockCount); - - uint32_t eraseBlockStart; - uint32_t eraseBlockEnd; - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - status_t error = kStatus_Success; - - /* Wait for the card write process complete because of that card read process and write process use one buffer.*/ - if (kStatus_Success != SD_WaitWriteComplete(card)) - { - return kStatus_SDMMC_WaitWriteCompleteFailed; - } - /* Wait for the card's buffer to be not full to write to improve the write performance. */ - while ((GET_SDMMCHOST_STATUS(card->host.base) & CARD_DATA0_STATUS_MASK) != CARD_DATA0_NOT_BUSY) - { - } - - eraseBlockStart = startBlock; - eraseBlockEnd = eraseBlockStart + blockCount - 1U; - if (!(card->flags & kSD_SupportHighCapacityFlag)) - { - eraseBlockStart = eraseBlockStart * FSL_SDMMC_DEFAULT_BLOCK_SIZE; - eraseBlockEnd = eraseBlockEnd * FSL_SDMMC_DEFAULT_BLOCK_SIZE; - } - - /* Send ERASE_WRITE_BLOCK_START command to set the start block number to erase. */ - command.index = kSD_EraseWriteBlockStart; - command.argument = eraseBlockStart; - command.responseType = kCARD_ResponseTypeR1; - command.responseErrorFlags = SDMMC_R1_ALL_ERROR_FLAG; - - content.command = &command; - content.data = NULL; - error = SD_Transfer(card, &content, 1U); - if (kStatus_Success != error) - { - SDMMC_LOG("\r\nError: send CMD32(erase start) failed with host error %d, response %x", error, - command.response[0U]); - return kStatus_SDMMC_TransferFailed; - } - - /* Send ERASE_WRITE_BLOCK_END command to set the end block number to erase. */ - command.index = kSD_EraseWriteBlockEnd; - command.argument = eraseBlockEnd; - - content.command = &command; - content.data = NULL; - error = SD_Transfer(card, &content, 0U); - if (kStatus_Success != error) - { - SDMMC_LOG("\r\nError: send CMD33(erase end) failed with host error %d, response %x", error, - command.response[0U]); - return kStatus_SDMMC_TransferFailed; - } - - /* Send ERASE command to start erase process. */ - command.index = kSDMMC_Erase; - command.argument = 0U; - command.responseType = kCARD_ResponseTypeR1b; - command.responseErrorFlags = SDMMC_R1_ALL_ERROR_FLAG; - - content.command = &command; - content.data = NULL; - error = SD_Transfer(card, &content, 0U); - if (kStatus_Success != error) - { - SDMMC_LOG("\r\nError: send CMD38(erase) failed with host error %d, response %x", error, command.response[0U]); - return kStatus_SDMMC_TransferFailed; - } - - return kStatus_Success; -} - -bool SD_CheckReadOnly(sd_card_t *card) -{ - assert(card); - - return ((card->csd.flags & kSD_CsdPermanentWriteProtectFlag) || - (card->csd.flags & kSD_CsdTemporaryWriteProtectFlag)); -} - -status_t SD_ReadBlocks(sd_card_t *card, uint8_t *buffer, uint32_t startBlock, uint32_t blockCount) -{ - assert(card); - assert(buffer); - assert(blockCount); - assert((blockCount + startBlock) <= card->blockCount); - - uint32_t blockCountOneTime; - uint32_t blockLeft; - uint32_t blockDone = 0U; - uint8_t *nextBuffer = buffer; - bool dataAddrAlign = true; - - blockLeft = blockCount; - - while (blockLeft) - { - nextBuffer = (buffer + blockDone * FSL_SDMMC_DEFAULT_BLOCK_SIZE); - if (!card->noInteralAlign && (!dataAddrAlign || (((uint32_t)nextBuffer) & (sizeof(uint32_t) - 1U)))) - { - blockLeft--; - blockCountOneTime = 1U; - memset(g_sdmmc, 0U, FSL_SDMMC_DEFAULT_BLOCK_SIZE); - dataAddrAlign = false; - } - else - { - if (blockLeft > card->host.capability.maxBlockCount) - { - blockLeft = (blockLeft - card->host.capability.maxBlockCount); - blockCountOneTime = card->host.capability.maxBlockCount; - } - else - { - blockCountOneTime = blockLeft; - blockLeft = 0U; - } - } - - if (kStatus_Success != SD_Read(card, dataAddrAlign ? nextBuffer : (uint8_t *)g_sdmmc, (startBlock + blockDone), - FSL_SDMMC_DEFAULT_BLOCK_SIZE, blockCountOneTime)) - { - return kStatus_SDMMC_TransferFailed; - } - - blockDone += blockCountOneTime; - - if (!card->noInteralAlign && (!dataAddrAlign)) - { - memcpy(nextBuffer, (uint8_t *)&g_sdmmc, FSL_SDMMC_DEFAULT_BLOCK_SIZE); - } - } - - return kStatus_Success; -} - -status_t SD_WriteBlocks(sd_card_t *card, const uint8_t *buffer, uint32_t startBlock, uint32_t blockCount) -{ - assert(card); - assert(buffer); - assert(blockCount); - assert((blockCount + startBlock) <= card->blockCount); - - uint32_t blockCountOneTime = 0U; /* The block count can be wrote in one time sending WRITE_BLOCKS command. */ - uint32_t blockWrittenOneTime = 0U; - uint32_t blockLeft = 0U; /* Left block count to be wrote. */ - const uint8_t *nextBuffer; - bool dataAddrAlign = true; - - blockLeft = blockCount; - while (blockLeft) - { - nextBuffer = (buffer + (blockCount - blockLeft) * FSL_SDMMC_DEFAULT_BLOCK_SIZE); - if (!card->noInteralAlign && (!dataAddrAlign || (((uint32_t)nextBuffer) & (sizeof(uint32_t) - 1U)))) - { - blockCountOneTime = 1U; - memcpy((uint8_t *)&g_sdmmc, nextBuffer, FSL_SDMMC_DEFAULT_BLOCK_SIZE); - dataAddrAlign = false; - } - else - { - if (blockLeft > card->host.capability.maxBlockCount) - { - blockCountOneTime = card->host.capability.maxBlockCount; - } - else - { - blockCountOneTime = blockLeft; - } - } - - if (kStatus_Success != SD_Write(card, dataAddrAlign ? nextBuffer : (uint8_t *)g_sdmmc, - (startBlock + blockCount - blockLeft), FSL_SDMMC_DEFAULT_BLOCK_SIZE, - blockCountOneTime, &blockWrittenOneTime)) - { - return kStatus_SDMMC_TransferFailed; - } - - blockLeft -= blockWrittenOneTime; - - if ((!card->noInteralAlign) && !dataAddrAlign) - { - memset(g_sdmmc, 0U, FSL_SDMMC_DEFAULT_BLOCK_SIZE); - } - } - - return kStatus_Success; -} - -status_t SD_EraseBlocks(sd_card_t *card, uint32_t startBlock, uint32_t blockCount) -{ - assert(card); - assert(blockCount); - assert((blockCount + startBlock) <= card->blockCount); - - uint32_t blockCountOneTime; /* The block count can be erased in one time sending ERASE_BLOCKS command. */ - uint32_t blockDone = 0U; /* The block count has been erased. */ - uint32_t blockLeft; /* Left block count to be erase. */ - status_t error; - uint32_t onetimeMaxEraseBlocks = 0U; - - /* sdsc card erasable sector is determined by CSD register */ - if (card->csd.csdStructure == 0U) - { - onetimeMaxEraseBlocks = card->csd.eraseSectorSize + 1U; - } - else - { - /* limit one time maximum erase size to 1 AU */ - if (card->stat.auSize >= SD_AU_START_VALUE) - { - onetimeMaxEraseBlocks = s_sdAuSizeMap[card->stat.auSize] / FSL_SDMMC_DEFAULT_BLOCK_SIZE; - } - } - - if (onetimeMaxEraseBlocks == 0U) - { - SDMMC_LOG( - "Warning: AU size in sd descriptor is not set properly, please check if SD_ReadStatus is called before\ - SD_EraseBlocks"); - return kStatus_SDMMC_AuSizeNotSetProperly; - } - - blockLeft = blockCount; - while (blockLeft) - { - if (blockLeft > onetimeMaxEraseBlocks) - { - blockCountOneTime = onetimeMaxEraseBlocks; - blockLeft = blockLeft - blockCountOneTime; - } - else - { - blockCountOneTime = blockLeft; - blockLeft = 0U; - } - - error = SD_Erase(card, (startBlock + blockDone), blockCountOneTime); - if (error != kStatus_Success) - { - return error; - } - - blockDone += blockCountOneTime; - } - - return kStatus_Success; -} - -status_t SD_ProbeBusVoltage(sd_card_t *card) -{ - assert(card); - - uint32_t applicationCommand41Argument = 0U; - status_t error = kStatus_Success; - - /* 3.3V voltage should be supported as default */ - applicationCommand41Argument |= - SDMMC_MASK(kSD_OcrVdd29_30Flag) | SDMMC_MASK(kSD_OcrVdd32_33Flag) | SDMMC_MASK(kSD_OcrVdd33_34Flag); - card->operationVoltage = kCARD_OperationVoltage330V; - - /* allow user select the work voltage, if not select, sdmmc will handle it automatically */ - if (kSDMMCHOST_SupportV180 != SDMMCHOST_NOT_SUPPORT) - { - applicationCommand41Argument |= SDMMC_MASK(kSD_OcrSwitch18RequestFlag); - } - - do - { - /* card go idle */ - if (kStatus_Success != SD_GoIdle(card)) - { - error = kStatus_SDMMC_GoIdleFailed; - break; - } - - /* Check card's supported interface condition. */ - if (kStatus_Success == SD_SendInterfaceCondition(card)) - { - /* SDHC or SDXC card */ - applicationCommand41Argument |= SDMMC_MASK(kSD_OcrHostCapacitySupportFlag); - card->flags |= kSD_SupportSdhcFlag; - } - else - { - /* SDSC card */ - if (kStatus_Success != SD_GoIdle(card)) - { - error = kStatus_SDMMC_GoIdleFailed; - break; - } - } - /* Set card interface condition according to SDHC capability and card's supported interface condition. */ - if (kStatus_Success != SD_ApplicationSendOperationCondition(card, applicationCommand41Argument)) - { - error = kStatus_SDMMC_HandShakeOperationConditionFailed; - break; - } - - /* check if card support 1.8V */ - if ((card->flags & kSD_SupportVoltage180v)) - { - error = SD_SwitchVoltage(card); - if (kStatus_SDMMC_SwitchVoltageFail == error) - { - break; - } - - if (error == kStatus_SDMMC_SwitchVoltage18VFail33VSuccess) - { - applicationCommand41Argument &= ~SDMMC_MASK(kSD_OcrSwitch18RequestFlag); - card->flags &= ~kSD_SupportVoltage180v; - continue; - } - else - { - card->operationVoltage = kCARD_OperationVoltage180V; - break; - } - } - - break; - } while (1U); - - return error; -} - -status_t SD_CardInit(sd_card_t *card) -{ - assert(card); - assert(card->isHostReady == true); - - /* reset variables */ - card->flags = 0U; - /* set DATA bus width */ - SDMMCHOST_SET_CARD_BUS_WIDTH(card->host.base, kSDMMCHOST_DATABUSWIDTH1BIT); - /*set card freq to 400KHZ*/ - card->busClock_Hz = SDMMCHOST_SET_CARD_CLOCK(card->host.base, card->host.sourceClock_Hz, SDMMC_CLOCK_400KHZ); - /* send card active */ - SDMMCHOST_SEND_CARD_ACTIVE(card->host.base, 100U); - /* Get host capability. */ - GET_SDMMCHOST_CAPABILITY(card->host.base, &(card->host.capability)); - - /* probe bus voltage*/ - if (SD_ProbeBusVoltage(card) == kStatus_SDMMC_SwitchVoltageFail) - { - return kStatus_SDMMC_SwitchVoltageFail; - } - - /* Initialize card if the card is SD card. */ - if (kStatus_Success != SD_AllSendCid(card)) - { - return kStatus_SDMMC_AllSendCidFailed; - } - if (kStatus_Success != SD_SendRca(card)) - { - return kStatus_SDMMC_SendRelativeAddressFailed; - } - if (kStatus_Success != SD_SendCsd(card)) - { - return kStatus_SDMMC_SendCsdFailed; - } - if (kStatus_Success != SD_SelectCard(card, true)) - { - return kStatus_SDMMC_SelectCardFailed; - } - - /* Set to max frequency in non-high speed mode. */ - card->busClock_Hz = SDMMCHOST_SET_CARD_CLOCK(card->host.base, card->host.sourceClock_Hz, SD_CLOCK_25MHZ); - - if (kStatus_Success != SD_SendScr(card)) - { - return kStatus_SDMMC_SendScrFailed; - } - /* Set to 4-bit data bus mode. */ - if (((card->host.capability.flags) & kSDMMCHOST_Support4BitBusWidth) && (card->flags & kSD_Support4BitWidthFlag)) - { - if (kStatus_Success != SD_SetDataBusWidth(card, kSD_DataBusWidth4Bit)) - { - return kStatus_SDMMC_SetDataBusWidthFailed; - } - SDMMCHOST_SET_CARD_BUS_WIDTH(card->host.base, kSDMMCHOST_DATABUSWIDTH4BIT); - } - - /* set block size */ - if (SD_SetBlockSize(card, FSL_SDMMC_DEFAULT_BLOCK_SIZE)) - { - return kStatus_SDMMC_SetCardBlockSizeFailed; - } - - /* select bus timing */ - if (kStatus_Success != SD_SelectBusTiming(card)) - { - return kStatus_SDMMC_SwitchBusTimingFailed; - } - - /* try to get card current status */ - SD_ReadStatus(card); - - return kStatus_Success; -} - -void SD_CardDeinit(sd_card_t *card) -{ - assert(card); - - SD_SelectCard(card, false); -} - -status_t SD_HostInit(sd_card_t *card) -{ - assert(card); - - if ((!card->isHostReady) && SDMMCHOST_Init(&(card->host), (void *)(card->usrParam.cd)) != kStatus_Success) - { - return kStatus_Fail; - } - - /* set the host status flag, after the card re-plug in, don't need init host again */ - card->isHostReady = true; - - return kStatus_Success; -} - -void SD_HostDeinit(sd_card_t *card) -{ - assert(card); - - SDMMCHOST_Deinit(&(card->host)); - /* should re-init host */ - card->isHostReady = false; -} - -void SD_HostReset(SDMMCHOST_CONFIG *host) -{ - SDMMCHOST_Reset(host->base); -} - -void SD_PowerOnCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr) -{ - SDMMCHOST_PowerOnCard(base, pwr); -} - -void SD_PowerOffCard(SDMMCHOST_TYPE *base, const sdmmchost_pwr_card_t *pwr) -{ - SDMMCHOST_PowerOffCard(base, pwr); -} - -status_t SD_WaitCardDetectStatus(SDMMCHOST_TYPE *hostBase, const sdmmchost_detect_card_t *cd, bool waitCardStatus) -{ - return SDMMCHOST_WaitCardDetectStatus(hostBase, cd, waitCardStatus); -} - -bool SD_IsCardPresent(sd_card_t *card) -{ - (void) card; - return SDMMCHOST_IsCardPresent(); -} - -status_t SD_Init(sd_card_t *card) -{ - assert(card); - - if (!card->isHostReady) - { - if (SD_HostInit(card) != kStatus_Success) - { - return kStatus_SDMMC_HostNotReady; - } - } - else - { - SD_HostReset(&(card->host)); - } - SD_PowerOffCard(card->host.base, card->usrParam.pwr); - - if (SD_WaitCardDetectStatus(card->host.base, card->usrParam.cd, true) != kStatus_Success) - { - return kStatus_SDMMC_CardDetectFailed; - } - SD_PowerOnCard(card->host.base, card->usrParam.pwr); - - return SD_CardInit(card); -} - -void SD_Deinit(sd_card_t *card) -{ - /* card deinitialize */ - SD_CardDeinit(card); - /* host deinitialize */ - SD_HostDeinit(card); -} diff --git a/targets/FreeRTOS/UAC18/common/sdmmc/src/fsl_sdmmc_common.c b/targets/FreeRTOS/UAC18/common/sdmmc/src/fsl_sdmmc_common.c deleted file mode 100644 index 291272603e..0000000000 --- a/targets/FreeRTOS/UAC18/common/sdmmc/src/fsl_sdmmc_common.c +++ /dev/null @@ -1,298 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. All rights reserved. -// Portions Copyright 2016-2018 NXP All rights reserved. -// See LICENSE file in the project root for full license information. -// - - -#include "fsl_sdmmc_common.h" -/******************************************************************************* - * Variables - ******************************************************************************/ -SDK_ALIGN(uint32_t g_sdmmc[SDK_SIZEALIGN(SDMMC_GLOBAL_BUFFER_SIZE, SDMMC_DATA_BUFFER_ALIGN_CACHE)], - MAX(SDMMC_DATA_BUFFER_ALIGN_CACHE, SDMMCHOST_DMA_BUFFER_ADDR_ALIGN)); -/******************************************************************************* - * Code - ******************************************************************************/ -status_t SDMMC_SelectCard(SDMMCHOST_TYPE *base, - SDMMCHOST_TRANSFER_FUNCTION transfer, - uint32_t relativeAddress, - bool isSelected) -{ - assert(transfer); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - - command.index = kSDMMC_SelectCard; - if (isSelected) - { - command.argument = relativeAddress << 16U; - command.responseType = kCARD_ResponseTypeR1; - } - else - { - command.argument = 0U; - command.responseType = kCARD_ResponseTypeNone; - } - - content.command = &command; - content.data = NULL; - if ((kStatus_Success != transfer(base, &content)) || (command.response[0U] & SDMMC_R1_ALL_ERROR_FLAG)) - { - return kStatus_SDMMC_TransferFailed; - } - - /* Wait until card to transfer state */ - return kStatus_Success; -} - -status_t SDMMC_SendApplicationCommand(SDMMCHOST_TYPE *base, - SDMMCHOST_TRANSFER_FUNCTION transfer, - uint32_t relativeAddress) -{ - assert(transfer); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - - command.index = kSDMMC_ApplicationCommand; - command.argument = (relativeAddress << 16U); - command.responseType = kCARD_ResponseTypeR1; - - content.command = &command; - content.data = 0U; - if ((kStatus_Success != transfer(base, &content)) || (command.response[0U] & SDMMC_R1_ALL_ERROR_FLAG)) - { - return kStatus_SDMMC_TransferFailed; - } - - if (!(command.response[0U] & SDMMC_MASK(kSDMMC_R1ApplicationCommandFlag))) - { - return kStatus_SDMMC_CardNotSupport; - } - - return kStatus_Success; -} - -status_t SDMMC_SetBlockCount(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer, uint32_t blockCount) -{ - assert(transfer); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - - command.index = kSDMMC_SetBlockCount; - command.argument = blockCount; - command.responseType = kCARD_ResponseTypeR1; - - content.command = &command; - content.data = 0U; - if ((kStatus_Success != transfer(base, &content)) || (command.response[0U] & SDMMC_R1_ALL_ERROR_FLAG)) - { - return kStatus_SDMMC_TransferFailed; - } - - return kStatus_Success; -} - -status_t SDMMC_GoIdle(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer) -{ - assert(transfer); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - - command.index = kSDMMC_GoIdleState; - - content.command = &command; - content.data = 0U; - if (kStatus_Success != transfer(base, &content)) - { - return kStatus_SDMMC_TransferFailed; - } - - return kStatus_Success; -} - -status_t SDMMC_SetBlockSize(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer, uint32_t blockSize) -{ - assert(transfer); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - - command.index = kSDMMC_SetBlockLength; - command.argument = blockSize; - command.responseType = kCARD_ResponseTypeR1; - - content.command = &command; - content.data = 0U; - if ((kStatus_Success != transfer(base, &content)) || (command.response[0U] & SDMMC_R1_ALL_ERROR_FLAG)) - { - return kStatus_SDMMC_TransferFailed; - } - - return kStatus_Success; -} - -status_t SDMMC_SetCardInactive(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer) -{ - assert(transfer); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - - command.index = kSDMMC_GoInactiveState; - command.argument = 0U; - command.responseType = kCARD_ResponseTypeNone; - - content.command = &command; - content.data = 0U; - if ((kStatus_Success != transfer(base, &content))) - { - return kStatus_SDMMC_TransferFailed; - } - - return kStatus_Success; -} - -status_t SDMMC_SwitchVoltage(SDMMCHOST_TYPE *base, SDMMCHOST_TRANSFER_FUNCTION transfer) -{ - assert(transfer); - - SDMMCHOST_TRANSFER content = {0}; - SDMMCHOST_COMMAND command = {0}; - status_t error = kStatus_Success; - - command.index = kSD_VoltageSwitch; - command.argument = 0U; - command.responseType = kCARD_ResponseTypeR1; - - content.command = &command; - content.data = NULL; - if (kStatus_Success != transfer(base, &content)) - { - return kStatus_SDMMC_TransferFailed; - } - /* disable card clock */ - SDMMCHOST_ENABLE_CARD_CLOCK(base, false); - - /* check data line and cmd line status */ - if ((GET_SDMMCHOST_STATUS(base) & - (CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK | CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY)) != 0U) - { - return kStatus_SDMMC_SwitchVoltageFail; - } - - /* host switch to 1.8V */ - SDMMCHOST_SWITCH_VOLTAGE180V(base, true); - - SDMMCHOST_Delay(100U); - - /*enable sd clock*/ - SDMMCHOST_ENABLE_CARD_CLOCK(base, true); - /*enable force clock on*/ - SDMMCHOST_FORCE_SDCLOCK_ON(base, true); - /* dealy 1ms,not exactly correct when use while */ - SDMMCHOST_Delay(10U); - /*disable force clock on*/ - SDMMCHOST_FORCE_SDCLOCK_ON(base, false); - - /* check data line and cmd line status */ - if ((GET_SDMMCHOST_STATUS(base) & - (CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK | CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY)) == 0U) - { - error = kStatus_SDMMC_SwitchVoltageFail; - /* power reset the card */ - SDMMCHOST_ENABLE_SD_POWER(false); - SDMMCHOST_Delay(10U); - SDMMCHOST_ENABLE_SD_POWER(true); - SDMMCHOST_Delay(10U); - /* re-check the data line status */ - if ((GET_SDMMCHOST_STATUS(base) & - (CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK | CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY))) - { - error = kStatus_SDMMC_SwitchVoltage18VFail33VSuccess; - SDMMC_LOG("\r\nNote: Current card support 1.8V, but board don't support, so sdmmc switch back to 3.3V."); - } - else - { - SDMMC_LOG( - "\r\nError: Current card support 1.8V, but board don't support, sdmmc tried to switch back\ - to 3.3V, but failed, please check board setting."); - } - } - - return error; -} - -status_t SDMMC_ExecuteTuning(SDMMCHOST_TYPE *base, - SDMMCHOST_TRANSFER_FUNCTION transfer, - uint32_t tuningCmd, - uint32_t blockSize) -{ - SDMMCHOST_TRANSFER content = {0U}; - SDMMCHOST_COMMAND command = {0U}; - SDMMCHOST_DATA data = {0U}; - uint32_t buffer[32U] = {0U}; - bool tuningError = true; - - command.index = tuningCmd; - command.argument = 0U; - command.responseType = kCARD_ResponseTypeR1; - - data.blockSize = blockSize; - data.blockCount = 1U; - data.rxData = buffer; - /* add this macro for adpter to different driver */ - SDMMCHOST_ENABLE_TUNING_FLAG(data); - - content.command = &command; - content.data = &data; - - /* enable the standard tuning */ - SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, true); - - while (true) - { - /* send tuning block */ - if ((kStatus_Success != transfer(base, &content))) - { - return kStatus_SDMMC_TransferFailed; - } - SDMMCHOST_Delay(1U); - - /*wait excute tuning bit clear*/ - if ((SDMMCHOST_EXECUTE_STANDARD_TUNING_STATUS(base) != 0U)) - { - continue; - } - - /* if tuning error , re-tuning again */ - if ((SDMMCHOST_CHECK_TUNING_ERROR(base) != 0U) && tuningError) - { - tuningError = false; - /* enable the standard tuning */ - SDMMCHOST_EXECUTE_STANDARD_TUNING_ENABLE(base, true); - SDMMCHOST_ADJUST_TUNING_DELAY(base, SDMMCHOST_STANDARD_TUNING_START); - } - else - { - break; - } - } - - /* check tuning result*/ - if (SDMMCHOST_EXECUTE_STANDARD_TUNING_RESULT(base) == 0U) - { - return kStatus_SDMMC_TuningFail; - } - -#if !SDMMC_ENABLE_SOFTWARE_TUNING - SDMMCHOST_AUTO_TUNING_ENABLE(base, true); -#endif - - return kStatus_Success; -} diff --git a/targets/FreeRTOS/UAC18/nanoCLR/CMakeLists.txt b/targets/FreeRTOS/UAC18/nanoCLR/CMakeLists.txt deleted file mode 100644 index 7b745650be..0000000000 --- a/targets/FreeRTOS/UAC18/nanoCLR/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -# -# Copyright (c) 2019 The nanoFramework project contributors -# See LICENSE file in the project root for full license information. -# - -include(NF_NativeAssemblies) - -# append nanoCLR source files -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/main.c") -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/Memory.cpp") -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/nanoHAL.cpp") -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/CLR_Startup_Thread.c") -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/WireProtocol_App_Interface.c") - -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/TargetHAL.cpp") - -# append target HAL source files -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/TargetHAL_Time.cpp") -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/TargetHAL_Power.c") - -# append nanoCRT -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/nanoCRT.cpp") - -# append target PAL source files -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetPAL_Events.cpp") -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetPAL_Time.cpp") - -# append Random number generator files -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetRandom.cpp") - -# append FatFS files -if(USE_FILESYSTEM_OPTION) - list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/fatfs/diskio.c") - list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/fatfs/fsl_sd_disk.c") - list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/fatfs/ffsystem.c") -endif() - -# append networking files, if enabled -if(USE_NETWORKING_OPTION) - list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/targetHAL_Network.cpp") - list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/target_Network.cpp") - list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/LwIP/ethernetif.c") - - # append mbed TLS entropy generator, if hardware has it - # if(NF_SECURITY_MBEDTLS AND USE_RNG) - # list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/mbedtls_entropy_hardware_pool.c") - # endif() - -endif() - -# append files from Runtime.Native -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/nanoFramework.Runtime.Native/nf_rt_native_nanoFramework_Runtime_Native_Rtc.cpp") - -# add native assemblies -ParseNativeAssemblies() - -# configure code file with Interop Assemblies table and... -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CLR_RT_InteropAssembliesTable.cpp.in" - "${CMAKE_CURRENT_BINARY_DIR}/CLR_RT_InteropAssembliesTable.cpp" @ONLY) -# ... now add Interop Assemblies table to nanoCLR sources list -list(APPEND NANOCLR_PROJECT_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/CLR_RT_InteropAssembliesTable.cpp") - -# make vars global -set(NANOCLR_PROJECT_SOURCES ${NANOCLR_PROJECT_SOURCES} CACHE INTERNAL "make global") -set(NANOCLR_PROJECT_INCLUDE_DIRS ${NANOCLR_PROJECT_INCLUDE_DIRS} CACHE INTERNAL "make global") diff --git a/targets/FreeRTOS/UAC18/nanoCLR/fatfs/diskio.c b/targets/FreeRTOS/UAC18/nanoCLR/fatfs/diskio.c deleted file mode 100644 index e6882fc6e4..0000000000 --- a/targets/FreeRTOS/UAC18/nanoCLR/fatfs/diskio.c +++ /dev/null @@ -1,111 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. -// Portions Copyright 2016-2018 NXP -// See LICENSE file in the project root for full license information. -// - -/*-----------------------------------------------------------------------*/ -/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */ -/*-----------------------------------------------------------------------*/ -/* If a working storage control module is available, it should be */ -/* attached to the FatFs via a glue function rather than modifying it. */ -/* This is an example of glue functions to attach various exsisting */ -/* storage control modules to the FatFs module with a defined API. */ -/*-----------------------------------------------------------------------*/ - -#include "ff.h" /* FatFs configuration options */ -#include "diskio.h" /* FatFs lower layer API */ -#include "fsl_sd_disk.h" - - -/*-----------------------------------------------------------------------*/ -/* Get Drive Status */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_status ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) -{ - DSTATUS stat; - - stat = sd_disk_status(pdrv); - - return stat; -} - - - -/*-----------------------------------------------------------------------*/ -/* Inidialize a Drive */ -/*-----------------------------------------------------------------------*/ - -DSTATUS disk_initialize ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) -{ - DSTATUS stat; - stat = sd_disk_initialize(pdrv); - - return stat; -} - - - -/*-----------------------------------------------------------------------*/ -/* Read Sector(s) */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_read ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to read */ -) -{ - DRESULT res; - res = sd_disk_read(pdrv, buff, sector, count); - - return res; -} - - - -/*-----------------------------------------------------------------------*/ -/* Write Sector(s) */ -/*-----------------------------------------------------------------------*/ - -#if FF_FS_READONLY == 0 - -DRESULT disk_write ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - const BYTE *buff, /* Data to be written */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to write */ -) -{ - DRESULT res; - res = sd_disk_write(pdrv, buff, sector, count); - - return res; -} - -#endif - - -/*-----------------------------------------------------------------------*/ -/* Miscellaneous Functions */ -/*-----------------------------------------------------------------------*/ - -DRESULT disk_ioctl ( - BYTE pdrv, /* Physical drive nmuber (0..) */ - BYTE cmd, /* Control code */ - void *buff /* Buffer to send/receive control data */ -) -{ - DRESULT res; - res = sd_disk_ioctl(pdrv, cmd, buff); - - return res; -} - diff --git a/targets/FreeRTOS/UAC18/nanoCLR/fatfs/ffsystem.c b/targets/FreeRTOS/UAC18/nanoCLR/fatfs/ffsystem.c deleted file mode 100644 index 54a4f03c31..0000000000 --- a/targets/FreeRTOS/UAC18/nanoCLR/fatfs/ffsystem.c +++ /dev/null @@ -1,170 +0,0 @@ -/*------------------------------------------------------------------------*/ -/* Sample Code of OS Dependent Functions for FatFs */ -/* (C)ChaN, 2018 */ -/*------------------------------------------------------------------------*/ - - -#include "ff.h" -#include "nanoHAL_v2.h" - -#if FF_USE_LFN == 3 /* Dynamic memory allocation */ - -/*------------------------------------------------------------------------*/ -/* Allocate a memory block */ -/*------------------------------------------------------------------------*/ - -void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */ - UINT msize /* Number of bytes to allocate */ -) -{ - return platform_malloc(msize); /* Allocate a new memory block with POSIX API */ -} - - -/*------------------------------------------------------------------------*/ -/* Free a memory block */ -/*------------------------------------------------------------------------*/ - -void ff_memfree ( - void* mblock /* Pointer to the memory block to free (nothing to do if null) */ -) -{ - platform_free(mblock); /* Free the memory block with POSIX API */ -} - -#endif - - - -#if FF_FS_REENTRANT /* Mutal exclusion */ - -/*------------------------------------------------------------------------*/ -/* Create a Synchronization Object */ -/*------------------------------------------------------------------------*/ -/* This function is called in f_mount() function to create a new -/ synchronization object for the volume, such as semaphore and mutex. -/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR. -*/ - -//const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */ - - -int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */ - BYTE vol, /* Corresponding volume (logical drive number) */ - FF_SYNC_t* sobj /* Pointer to return the created sync object */ -) -{ - /* Win32 */ - *sobj = CreateMutex(NULL, FALSE, NULL); - return (int)(*sobj != INVALID_HANDLE_VALUE); - - /* uITRON */ -// T_CSEM csem = {TA_TPRI,1,1}; -// *sobj = acre_sem(&csem); -// return (int)(*sobj > 0); - - /* uC/OS-II */ -// OS_ERR err; -// *sobj = OSMutexCreate(0, &err); -// return (int)(err == OS_NO_ERR); - - /* FreeRTOS */ -// *sobj = xSemaphoreCreateMutex(); -// return (int)(*sobj != NULL); - - /* CMSIS-RTOS */ -// *sobj = osMutexCreate(&Mutex[vol]); -// return (int)(*sobj != NULL); -} - - -/*------------------------------------------------------------------------*/ -/* Delete a Synchronization Object */ -/*------------------------------------------------------------------------*/ -/* This function is called in f_mount() function to delete a synchronization -/ object that created with ff_cre_syncobj() function. When a 0 is returned, -/ the f_mount() function fails with FR_INT_ERR. -*/ - -int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */ - FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ -) -{ - /* Win32 */ - return (int)CloseHandle(sobj); - - /* uITRON */ -// return (int)(del_sem(sobj) == E_OK); - - /* uC/OS-II */ -// OS_ERR err; -// OSMutexDel(sobj, OS_DEL_ALWAYS, &err); -// return (int)(err == OS_NO_ERR); - - /* FreeRTOS */ -// vSemaphoreDelete(sobj); -// return 1; - - /* CMSIS-RTOS */ -// return (int)(osMutexDelete(sobj) == osOK); -} - - -/*------------------------------------------------------------------------*/ -/* Request Grant to Access the Volume */ -/*------------------------------------------------------------------------*/ -/* This function is called on entering file functions to lock the volume. -/ When a 0 is returned, the file function fails with FR_TIMEOUT. -*/ - -int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */ - FF_SYNC_t sobj /* Sync object to wait */ -) -{ - /* Win32 */ - return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0); - - /* uITRON */ -// return (int)(wai_sem(sobj) == E_OK); - - /* uC/OS-II */ -// OS_ERR err; -// OSMutexPend(sobj, FF_FS_TIMEOUT, &err)); -// return (int)(err == OS_NO_ERR); - - /* FreeRTOS */ -// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE); - - /* CMSIS-RTOS */ -// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK); -} - - -/*------------------------------------------------------------------------*/ -/* Release Grant to Access the Volume */ -/*------------------------------------------------------------------------*/ -/* This function is called on leaving file functions to unlock the volume. -*/ - -void ff_rel_grant ( - FF_SYNC_t sobj /* Sync object to be signaled */ -) -{ - /* Win32 */ - ReleaseMutex(sobj); - - /* uITRON */ -// sig_sem(sobj); - - /* uC/OS-II */ -// OSMutexPost(sobj); - - /* FreeRTOS */ -// xSemaphoreGive(sobj); - - /* CMSIS-RTOS */ -// osMutexRelease(sobj); -} - -#endif - diff --git a/targets/FreeRTOS/UAC18/nanoCLR/fatfs/fsl_sd_disk.c b/targets/FreeRTOS/UAC18/nanoCLR/fatfs/fsl_sd_disk.c deleted file mode 100644 index 602d9af28a..0000000000 --- a/targets/FreeRTOS/UAC18/nanoCLR/fatfs/fsl_sd_disk.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - - -#include "ff.h" -/* This fatfs subcomponent is disabled by default - * To enable it, define following macro in ffconf.h */ -#ifdef SD_DISK_ENABLE - -#include -#include -#include -#include "fsl_sd_disk.h" - - -/******************************************************************************* - * Code - ******************************************************************************/ -DRESULT sd_disk_write(uint8_t physicalDrive, const uint8_t *buffer, uint32_t sector, uint8_t count) -{ - if (physicalDrive != SDDISK) - { - return RES_PARERR; - } - - if (kStatus_Success != SD_WriteBlocks(&g_sd, buffer, sector, count)) - { - return RES_ERROR; - } - - return RES_OK; -} - -DRESULT sd_disk_read(uint8_t physicalDrive, uint8_t *buffer, uint32_t sector, uint8_t count) -{ - if (physicalDrive != SDDISK) - { - return RES_PARERR; - } - - if (kStatus_Success != SD_ReadBlocks(&g_sd, buffer, sector, count)) - { - return RES_ERROR; - } - - return RES_OK; -} - -DRESULT sd_disk_ioctl(uint8_t physicalDrive, uint8_t command, void *buffer) -{ - DRESULT result = RES_OK; - - if (physicalDrive != SDDISK) - { - return RES_PARERR; - } - - switch (command) - { - case GET_SECTOR_COUNT: - if (buffer) - { - *(uint32_t *)buffer = g_sd.blockCount; - } - else - { - result = RES_PARERR; - } - break; - case GET_SECTOR_SIZE: - if (buffer) - { - *(uint32_t *)buffer = g_sd.blockSize; - } - else - { - result = RES_PARERR; - } - break; - case GET_BLOCK_SIZE: - if (buffer) - { - *(uint32_t *)buffer = g_sd.csd.eraseSectorSize; - } - else - { - result = RES_PARERR; - } - break; - case CTRL_SYNC: - result = RES_OK; - break; - default: - result = RES_PARERR; - break; - } - - return result; -} - -DSTATUS sd_disk_status(uint8_t physicalDrive) -{ - if (physicalDrive != SDDISK) - { - return STA_NOINIT; - } - - return 0; -} - -DSTATUS sd_disk_initialize(uint8_t physicalDrive) -{ - if (physicalDrive != SDDISK) - { - return STA_NOINIT; - } - - return 0; -} -#endif /* SD_DISK_ENABLE */ diff --git a/targets/FreeRTOS/UAC18/nanoCLR/fatfs/fsl_sd_disk.h b/targets/FreeRTOS/UAC18/nanoCLR/fatfs/fsl_sd_disk.h deleted file mode 100644 index c4efcc200b..0000000000 --- a/targets/FreeRTOS/UAC18/nanoCLR/fatfs/fsl_sd_disk.h +++ /dev/null @@ -1,103 +0,0 @@ -// -// Copyright (c) 2019 The nanoFramework project contributors -// Portions Copyright (c) 2015, Freescale Semiconductor, Inc. -// Portions Copyright 2016 NXP -// See LICENSE file in the project root for full license information. -// - - -#ifndef _FSL_SD_DISK_H_ -#define _FSL_SD_DISK_H_ - -#include -#include "diskio.h" -#include "fsl_sd.h" - -/*! - * @addtogroup SD Disk - * @{ - */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -#define CD_USING_GPIO - -/******************************************************************************* - * Variables - ******************************************************************************/ -extern sd_card_t g_sd; /* sd card descriptor */ - -/************************************************************************************************* - * API - ************************************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - * @name SD Disk Function - * @{ - */ - -/*! - * @brief Initializes SD disk. - * - * @param physicalDrive Physical drive number. - * @retval STA_NOINIT Failed. - * @retval RES_OK Success. - */ -DSTATUS sd_disk_initialize(uint8_t physicalDrive); - -/*! - * Gets SD disk status - * - * @param physicalDrive Physical drive number. - * @retval STA_NOINIT Failed. - * @retval RES_OK Success. - */ -DSTATUS sd_disk_status(uint8_t physicalDrive); - -/*! - * @brief Reads SD disk. - * - * @param physicalDrive Physical drive number. - * @param buffer The data buffer pointer to store read content. - * @param sector The start sector number to be read. - * @param count The sector count to be read. - * @retval RES_PARERR Failed. - * @retval RES_OK Success. - */ -DRESULT sd_disk_read(uint8_t physicalDrive, uint8_t *buffer, uint32_t sector, uint8_t count); - -/*! - * @brief Writes SD disk. - * - * @param physicalDrive Physical drive number. - * @param buffer The data buffer pointer to store write content. - * @param sector The start sector number to be written. - * @param count The sector count to be written. - * @retval RES_PARERR Failed. - * @retval RES_OK Success. - */ -DRESULT sd_disk_write(uint8_t physicalDrive, const uint8_t *buffer, uint32_t sector, uint8_t count); - -/*! - * @brief SD disk IO operation. - * - * @param physicalDrive Physical drive number. - * @param command The command to be set. - * @param buffer The buffer to store command result. - * @retval RES_PARERR Failed. - * @retval RES_OK Success. - */ -DRESULT sd_disk_ioctl(uint8_t physicalDrive, uint8_t command, void *buffer); - -/* @} */ -#if defined(__cplusplus) -} -#endif - -#endif /* _FSL_SD_DISK_H_ */