summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/action.yml467
-rw-r--r--.travis.yml145
-rw-r--r--bsp/allwinner_tina/drivers/drv_uart.c4
-rw-r--r--bsp/nrf5x/libraries/drivers/drv_adc.c2
-rw-r--r--bsp/nrf5x/libraries/drivers/drv_adc.h2
-rw-r--r--bsp/raspberry-pi/raspi4-32/.config79
-rw-r--r--bsp/raspberry-pi/raspi4-32/README.md6
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/Kconfig65
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/SConscript12
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/board.c20
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_bluetooth.c885
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_bluetooth.h28
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_dma.c113
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_dma.h172
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_eth.c314
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_eth.h11
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_i2c.c368
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_i2c.h59
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_sdio.c18
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_spi.c85
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/drv_uart.c27
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/lcd/Sconscript18
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/lcd/drv_hdmi.c (renamed from bsp/raspberry-pi/raspi4-32/driver/drv_hdmi.c)22
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/lcd/drv_hdmi.h (renamed from bsp/raspberry-pi/raspi4-32/driver/drv_hdmi.h)0
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/lcd/drv_ili9486.c381
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/lcd/drv_ili9486.h13
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_console.c258
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_console.h59
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_font_20.h2299
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/mbox.c18
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/mbox.h18
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/raspi4.h21
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/touch/Sconscript16
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/touch/drv_dsi_touch.c132
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/touch/drv_dsi_touch.h13
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/touch/drv_xpt2046.c252
-rw-r--r--bsp/raspberry-pi/raspi4-32/driver/touch/drv_xpt2046.h13
-rw-r--r--bsp/raspberry-pi/raspi4-32/link.lds8
-rw-r--r--bsp/raspberry-pi/raspi4-32/rtconfig.h37
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/Kconfig16
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/config/l4/dac_config.h42
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/config/mp1/dma_config.h112
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/config/mp1/qspi_config.h56
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/config/mp1/spi_config.h4
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/drv_config.h2
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/drv_crypto.c415
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/drv_dac.c8
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/drv_qspi.c6
-rw-r--r--bsp/stm32/libraries/HAL_Drivers/drv_sdio.c8
-rw-r--r--bsp/stm32/libraries/STM32F0xx_HAL/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h1
-rw-r--r--bsp/stm32/libraries/STM32F1xx_HAL/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h1
-rw-r--r--bsp/stm32/libraries/STM32F2xx_HAL/STM32F2xx_HAL_Driver/Inc/stm32f2xx_hal.h1
-rw-r--r--bsp/stm32/libraries/STM32F4xx_HAL/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h1
-rw-r--r--bsp/stm32/libraries/STM32F7xx_HAL/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal.h1
-rw-r--r--bsp/stm32/libraries/STM32G0xx_HAL/STM32G0xx_HAL_Driver/Inc/stm32g0xx_hal.h1
-rw-r--r--bsp/stm32/libraries/STM32G4xx_HAL/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal.h1
-rw-r--r--bsp/stm32/libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h1
-rw-r--r--bsp/stm32/libraries/STM32L0xx_HAL/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal.h1
-rw-r--r--bsp/stm32/libraries/STM32L4xx_HAL/SConscript4
-rw-r--r--bsp/stm32/libraries/STM32L4xx_HAL/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h1
-rw-r--r--bsp/stm32/libraries/STM32MPxx_HAL/SConscript51
-rw-r--r--bsp/stm32/libraries/STM32MPxx_HAL/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c4
-rw-r--r--bsp/stm32/stm32h743-atk-apollo/board/Kconfig68
-rw-r--r--bsp/stm32/stm32h743-atk-apollo/board/SConscript4
-rw-r--r--bsp/stm32/stm32h743-atk-apollo/board/ports/drv_dcmi.c223
-rw-r--r--bsp/stm32/stm32h743-atk-apollo/board/ports/drv_dcmi.h34
-rw-r--r--bsp/stm32/stm32h743-atk-apollo/board/ports/drv_ov2640.c751
-rw-r--r--bsp/stm32/stm32h743-atk-apollo/board/ports/drv_ov2640.h778
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject14
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h229
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_it.h2
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc660
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c78
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c221
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_it.c2
-rw-r--r--bsp/stm32/stm32l475-atk-pandora/board/Kconfig10
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/.config58
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h12
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c352
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/Kconfig47
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/SConscript18
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/board.h4
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/linker_scripts/link.icf7
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/audio_play.c258
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_cs42l51.c531
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_cs42l51.h198
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_mic.c390
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_sound.c603
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/crypto/crypto_sample.c449
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_eth.c882
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_eth.h404
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_pmic.c71
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_sdio.c555
-rw-r--r--bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_sdio.h117
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h24
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c1133
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/Kconfig148
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/SConscript60
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/board.h9
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/linker_scripts/link.icf7
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/OpenAMP/drv_openamp.c38
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/crypto_sample.c365
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.c203
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.h22
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.c385
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.h26
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.c593
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.h104
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_exti.c36
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_fdcan.c290
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_fdcan.h22
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_lptim.c163
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.c297
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.h45
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.c666
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.h653
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c66
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pwr.c202
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_qspi_flash.c180
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_rs485.c111
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_rs485.h25
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sdcard.c413
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sound.c572
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_spdifrx.c303
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_spdifrx.h0
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wm8994.c782
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wm8994.h80
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wwdg.c115
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/eth/drv_eth.c870
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/eth/drv_eth.h381
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.c1602
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.h853
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/spi_sample.c85
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/board/ports/timer_sample.c160
-rw-r--r--bsp/stm32/stm32mp157a-st-ev1/rtconfig.py2
-rw-r--r--bsp/thead-smart/README.md13
-rw-r--r--components/dfs/filesystems/devfs/devfs.c2
-rw-r--r--components/dfs/filesystems/romfs/dfs_romfs.c2
-rw-r--r--components/drivers/audio/audio.c2
-rw-r--r--components/drivers/audio/audio_pipe.c3
-rw-r--r--components/drivers/audio/audio_pipe.h5
-rw-r--r--components/drivers/include/drivers/alarm.h2
-rw-r--r--components/drivers/include/ipc/ringbuffer.h1
-rw-r--r--components/drivers/rtc/alarm.c94
-rw-r--r--components/drivers/rtc/soft_rtc.c63
-rw-r--r--components/drivers/serial/serial.c5
-rw-r--r--components/drivers/src/ringbuffer.c34
-rw-r--r--components/drivers/src/workqueue.c2
-rw-r--r--components/drivers/usb/usbdevice/class/audio_mic.c3
-rw-r--r--components/drivers/usb/usbdevice/class/audio_speaker.c3
-rw-r--r--components/drivers/usb/usbdevice/class/cdc_vcom.c2
-rw-r--r--components/drivers/usb/usbdevice/class/hid.c4
-rw-r--r--components/drivers/usb/usbdevice/class/mstorage.c1
-rw-r--r--components/drivers/usb/usbdevice/class/winusb.c2
-rw-r--r--components/libc/compilers/common/termios.h2
-rw-r--r--components/net/lwip-1.4.1/src/netif/ethernetif.c10
-rw-r--r--components/net/lwip-2.1.2/src/netif/ethernetif.c10
-rw-r--r--libcpu/risc-v/common/context_gcc.S4
-rw-r--r--libcpu/risc-v/k210/interrupt_gcc.S4
-rw-r--r--libcpu/risc-v/k210/startup_gcc.S7
-rw-r--r--src/timer.c4
161 files changed, 26367 insertions, 1236 deletions
diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml
new file mode 100644
index 0000000000..96e94ebe50
--- /dev/null
+++ b/.github/workflows/action.yml
@@ -0,0 +1,467 @@
+name: RT-Thread
+
+# Controls when the action will run. Triggers the workflow on push or pull request
+# events but only for the master branch
+on:
+ # Runs at 16:00 UTC (BeiJing 00:00) on the 1st of every month
+ schedule:
+ - cron: '0 16 1 * *'
+ push:
+ branches:
+ - master
+ paths-ignore:
+ - documentation/**
+ - '**/README.md'
+ pull_request:
+ branches:
+ - master
+ paths-ignore:
+ - documentation/**
+ - '**/README.md'
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - action-version: "1.0"
+ RTT_BSP: "CME_M7"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "apollo2"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "asm9260t"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "at91sam9260"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "allwinner_tina"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "efm32"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "gd32e230k-start"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "gd32303e-eval"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "gd32450z-eval"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "gkipc"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "imx6sx/cortex-a9"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "imxrt/imxrt1052-atk-commander"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "imxrt/imxrt1052-fire-pro"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "imxrt/imxrt1052-nxp-evk"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lm3s8962"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lm3s9b9x"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lm4f232"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "tm4c123bsp"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "tm4c129x"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lpc43xx/M4"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lpc176x"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lpc178x"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lpc408x"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lpc1114"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lpc2148"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lpc2478"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lpc5410x"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "lpc54114-lite"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "ls1bdev"
+ RTT_TOOL_CHAIN: "sourcery-mips"
+
+ - action-version: "1.0"
+ RTT_BSP: "ls1cdev"
+ RTT_TOOL_CHAIN: "sourcery-mips"
+
+ - action-version: "1.0"
+ RTT_BSP: "mb9bf500r"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "mb9bf506r"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "mb9bf618s"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "mb9bf568r"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "mini2440"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "qemu-vexpress-a9"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "qemu-vexpress-gemini"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "sam7x"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f072-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f091-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f103-atk-nano"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f103-atk-warshipv3"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f103-dofly-lyc8"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f103-dofly-M3S"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f103-fire-arbitrary"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f103-hw100k-ibox"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f103-mini-system"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f103-onenet-nbiot"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f103-yf-ufun"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f107-uc-eval"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f401-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f405-smdz-breadfruit"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f407-atk-explorer"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f407-st-discovery"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f410-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f411-atk-nano"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f411-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f411-weact-MiniF4"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f413-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f427-robomaster-a"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f429-armfly-v6"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f429-atk-apollo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f429-fire-challenger"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f429-st-disco"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f446-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f469-st-disco"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f746-st-disco"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f767-atk-apollo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f767-fire-challenger"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32f767-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32g070-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32g071-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32g431-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32h743-atk-apollo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32h743-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32h747-st-discovery"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l4r9-st-eval"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l010-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l053-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l412-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l432-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l433-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l475-atk-pandora"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l475-st-discovery"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l476-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l496-ali-developer"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32l496-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32mp157a-st-discovery"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32mp157a-st-ev1"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32/stm32wb55-st-nucleo"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "stm32f20x"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "swm320-lq100"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "beaglebone"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "zynq7000"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "frdm-k64f"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "fh8620"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "xplorer4330/M4"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "at32/at32f403a-start"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "at32/at32f407-start"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ - action-version: "1.0"
+ RTT_BSP: "smartfusion2"
+ RTT_TOOL_CHAIN: "sourcery-arm"
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up Python
+ uses: actions/setup-python@master
+ with:
+ python-version: 3.8
+
+ - name: Install Tools
+ run: |
+ sudo apt-get -qq install gcc-multilib libsdl-dev scons
+ wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/arm-2017q2-v6/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2
+ sudo tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 -C /opt
+ /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc --version
+
+ wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/v1.1/mips-2016.05-7-mips-sde-elf-i686-pc-linux-gnu.tar.bz2
+ sudo tar xjf mips-2016.05-7-mips-sde-elf-i686-pc-linux-gnu.tar.bz2 -C /opt
+ /opt/mips-2016.05/bin/mips-sde-elf-gcc --version
+
+ echo "RTT_ROOT=${{ github.workspace }}" >> $GITHUB_ENV
+ echo "RTT_CC=gcc" >> $GITHUB_ENV
+
+ - name: ARM Scons Compile
+ if: ${{ matrix.RTT_TOOL_CHAIN == 'sourcery-arm' }}
+ env:
+ RTT_BSP: ${{ matrix.RTT_BSP }}
+ RTT_TOOL_CHAIN: ${{ matrix.RTT_TOOL_CHAIN }}
+ run: |
+ export RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-6-2017-q2-update/bin
+ scons -C bsp/$RTT_BSP
+
+ - name: MIPS Scons Compile
+ if: ${{ matrix.RTT_TOOL_CHAIN == 'sourcery-mips' }}
+ env:
+ RTT_BSP: ${{ matrix.RTT_BSP }}
+ RTT_TOOL_CHAIN: ${{ matrix.RTT_TOOL_CHAIN }}
+ run: |
+ export RTT_EXEC_PATH=/opt/mips-2016.05/bin
+ scons -C bsp/$RTT_BSP
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index f7ecc85ca7..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,145 +0,0 @@
-language: c
-
-notifications:
- email: false
-
-before_script:
-# travis has changed to 64-bit and we require 32-bit compatibility libraries
- - sudo apt-get update
- # clang
- - "sudo apt-get -qq install gcc-multilib libc6:i386 libgcc1:i386 libstdc++5:i386 libstdc++6:i386 libsdl-dev scons || true"
- # - sudo apt-get -qq install gcc-arm-none-eabi
- # - "[ $RTT_TOOL_CHAIN = 'sourcery-arm' ] && export RTT_EXEC_PATH=/usr/bin && arm-none-eabi-gcc --version || true"
- # - "[ $RTT_TOOL_CHAIN = 'sourcery-arm' ] && curl -s https://sourcery.mentor.com/public/gnu_toolchain/arm-none-eabi/arm-2014.05-28-arm-none-eabi-i686-pc-linux-gnu.tar.bz2 | sudo tar xjf - -C /opt && export RTT_EXEC_PATH=/opt/arm-2014.05/bin && /opt/arm-2014.05/bin/arm-none-eabi-gcc --version || true"
- - "[ $RTT_TOOL_CHAIN = 'sourcery-arm' ] && wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/arm-2017q2-v6/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 && sudo tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 -C /opt && export RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-6-2017-q2-update/bin && /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc --version || true"
- - "[ $RTT_TOOL_CHAIN = 'sourcery-mips' ] && wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/v1.1/mips-2016.05-7-mips-sde-elf-i686-pc-linux-gnu.tar.bz2 && sudo tar xjf mips-2016.05-7-mips-sde-elf-i686-pc-linux-gnu.tar.bz2 -C /opt && export RTT_EXEC_PATH=/opt/mips-2016.05/bin && /opt/mips-2016.05/bin/mips-sde-elf-gcc --version || true"
- # - "[ $RTT_TOOL_CHAIN = 'sourcery-ppc' ] && curl -s https://sourcery.mentor.com/public/gnu_toolchain/powerpc-eabi/freescale-2011.03-39-powerpc-eabi-i686-pc-linux-gnu.tar.bz2 | sudo tar xjf - -C /opt && export RTT_EXEC_PATH=/opt/freescale-2011.03/bin && /opt/freescale-2011.03/bin/powerpc-eabi-gcc --version || true"
- # - "[ $RTT_TOOL_CHAIN = 'atmel-avr32' ] && curl -s http://www.atmel.com/images/avr32-gnu-toolchain-3.4.1.348-linux.any.x86.tar.gz | sudo tar xzf - -C /opt && export RTT_EXEC_PATH=/opt/avr32-gnu-toolchain-linux_x86/bin && /opt/avr32-gnu-toolchain-linux_x86/bin/avr32-gcc --version && curl -sO http://www.atmel.com/images/avr-headers-3.2.3.970.zip && unzip -qq avr-headers-3.2.3.970.zip -d bsp/$RTT_BSP || true"
- - export RTT_ROOT=`pwd`
- - "[ x$RTT_CC == x ] && export RTT_CC='gcc' || true"
-
-env:
-# - RTT_BSP='simulator' RTT_CC='clang-analyze' RTT_EXEC_PATH=/usr/share/clang/scan-build
- - RTT_BSP='CME_M7' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='apollo2' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='asm9260t' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='at91sam9260' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='allwinner_tina' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='avr32uc3b0' RTT_TOOL_CHAIN='atmel-avr32'
-# - RTT_BSP='bf533' # no scons
- - RTT_BSP='efm32' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='es32f0334' RTT_TOOL_CHAIN='sourcery-arm' # not support gcc
-# - RTT_BSP='es32f0654' RTT_TOOL_CHAIN='sourcery-arm' # not support gcc
- - RTT_BSP='gd32e230k-start' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='gd32303e-eval' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='gd32450z-eval' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='gkipc' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='imx6sx/cortex-a9' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='imxrt/imxrt1052-atk-commander' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='imxrt/imxrt1052-fire-pro' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='imxrt/imxrt1052-nxp-evk' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lm3s8962' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lm3s9b9x' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lm4f232' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='tm4c123bsp' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='tm4c129x' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lpc43xx/M4' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lpc176x' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lpc178x' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lpc408x' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lpc1114' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='lpc824' RTT_TOOL_CHAIN='sourcery-arm' # not support gcc
- - RTT_BSP='lpc2148' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lpc2478' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lpc5410x' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='lpc54114-lite' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='lpc54608-LPCXpresso' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='ls1bdev' RTT_TOOL_CHAIN='sourcery-mips'
- - RTT_BSP='ls1cdev' RTT_TOOL_CHAIN='sourcery-mips'
-# - RTT_BSP='m16c62p' # m32c
- - RTT_BSP='mb9bf500r' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='mb9bf506r' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='mb9bf618s' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='mb9bf568r' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='microblaze' # no scons
- - RTT_BSP='mini2440' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='mini4020' # no scons
-# - RTT_BSP='mm32l07x' # not support gcc
-# - RTT_BSP='nios_ii' # no scons
-# - RTT_BSP='nuvoton_nuc472' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='nuvoton_m05x' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='pic32ethernet' # no scons
- - RTT_BSP='qemu-vexpress-a9' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='qemu-vexpress-gemini' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='sam7x' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='simulator' # x86
- - RTT_BSP='stm32/stm32f072-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f091-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f103-atk-nano' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f103-atk-warshipv3' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f103-dofly-lyc8' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f103-dofly-M3S' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f103-fire-arbitrary' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f103-hw100k-ibox' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f103-mini-system' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f103-onenet-nbiot' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f103-yf-ufun' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f107-uc-eval' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f401-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f405-smdz-breadfruit' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f407-atk-explorer' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f407-st-discovery' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f410-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f411-atk-nano' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f411-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f411-weact-MiniF4' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f413-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f427-robomaster-a' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f429-armfly-v6' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f429-atk-apollo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f429-fire-challenger' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f429-st-disco' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f446-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f469-st-disco' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f746-st-disco' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f767-atk-apollo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f767-fire-challenger' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32f767-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32g070-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32g071-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32g431-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32h743-atk-apollo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32h743-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32h747-st-discovery' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l4r9-st-eval' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l010-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l053-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l412-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l432-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l433-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l475-atk-pandora' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l475-st-discovery' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l476-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l496-ali-developer' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32l496-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32mp157a-st-discovery' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32mp157a-st-ev1' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32f20x' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='swm320-lq100' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='stm32/stm32wb55-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='taihu' RTT_TOOL_CHAIN='sourcery-ppc'
-# - RTT_BSP='upd70f3454' # iar
-# - RTT_BSP='x86' # x86
- - RTT_BSP='beaglebone' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='zynq7000' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='frdm-k64f' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='fh8620' RTT_TOOL_CHAIN='sourcery-arm'
-# - RTT_BSP='x1000' RTT_TOOL_CHAIN='sourcery-mips'
- - RTT_BSP='xplorer4330/M4' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='at32/at32f403a-start' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='at32/at32f407-start' RTT_TOOL_CHAIN='sourcery-arm'
- - RTT_BSP='smartfusion2' RTT_TOOL_CHAIN='sourcery-arm'
-
-stage: compile
-script:
- - scons -C bsp/$RTT_BSP
diff --git a/bsp/allwinner_tina/drivers/drv_uart.c b/bsp/allwinner_tina/drivers/drv_uart.c
index 9113dcdb66..ede0eee4e4 100644
--- a/bsp/allwinner_tina/drivers/drv_uart.c
+++ b/bsp/allwinner_tina/drivers/drv_uart.c
@@ -120,8 +120,8 @@ int rt_hw_uart_init(void)
uart->irqno = UART1_INTERRUPT; // IRQ_UART1;
uart->gpio_rx_port = GPIO_PORT_A;
uart->gpio_tx_port = GPIO_PORT_A;
- uart->gpio_rx_pin = GPIO_PIN_3;
- uart->gpio_tx_pin = GPIO_PIN_2;
+ uart->gpio_rx_pin = GPIO_PIN_2;
+ uart->gpio_tx_pin = GPIO_PIN_3;
uart->gpio_rx_fun = IO_FUN_4;
uart->gpio_tx_fun = IO_FUN_4;
diff --git a/bsp/nrf5x/libraries/drivers/drv_adc.c b/bsp/nrf5x/libraries/drivers/drv_adc.c
index 1f02fdddd6..8b136a3598 100644
--- a/bsp/nrf5x/libraries/drivers/drv_adc.c
+++ b/bsp/nrf5x/libraries/drivers/drv_adc.c
@@ -12,8 +12,6 @@
#ifdef RT_USING_ADC
-#define ADC_NAME "adc"
-
struct rt_adc_device nrf5x_adc_device;
drv_nrfx_saadc_result_t results;
diff --git a/bsp/nrf5x/libraries/drivers/drv_adc.h b/bsp/nrf5x/libraries/drivers/drv_adc.h
index 908ac87489..b65a981982 100644
--- a/bsp/nrf5x/libraries/drivers/drv_adc.h
+++ b/bsp/nrf5x/libraries/drivers/drv_adc.h
@@ -16,6 +16,8 @@
#include <hal/nrf_saadc.h>
#include <drivers/include/nrfx_saadc.h>
+#define ADC_NAME "adc"
+
/*
previous definition in application
diff --git a/bsp/raspberry-pi/raspi4-32/.config b/bsp/raspberry-pi/raspi4-32/.config
index 60727061a2..813f9417f1 100644
--- a/bsp/raspberry-pi/raspi4-32/.config
+++ b/bsp/raspberry-pi/raspi4-32/.config
@@ -14,7 +14,7 @@ CONFIG_RT_ALIGN_SIZE=4
CONFIG_RT_THREAD_PRIORITY_32=y
# CONFIG_RT_THREAD_PRIORITY_256 is not set
CONFIG_RT_THREAD_PRIORITY_MAX=32
-CONFIG_RT_TICK_PER_SECOND=100
+CONFIG_RT_TICK_PER_SECOND=1000
CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_USING_HOOK=y
CONFIG_RT_USING_IDLE_HOOK=y
@@ -54,6 +54,7 @@ CONFIG_RT_USING_MEMPOOL=y
# CONFIG_RT_USING_NOHEAP is not set
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
+# CONFIG_RT_USING_USERHEAP is not set
# CONFIG_RT_USING_MEMTRACE is not set
CONFIG_RT_USING_HEAP=y
@@ -65,7 +66,7 @@ CONFIG_RT_USING_DEVICE=y
# CONFIG_RT_USING_INTERRUPT_INFO is not set
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
-CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
CONFIG_RT_VER_NUM=0x40003
# CONFIG_RT_USING_CPU_FFS is not set
CONFIG_ARCH_ARMV8=y
@@ -141,14 +142,20 @@ CONFIG_RT_USING_DFS_DEVFS=y
#
CONFIG_RT_USING_DEVICE_IPC=y
CONFIG_RT_PIPE_BUFSZ=512
-# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
+CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
+CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048
+CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
CONFIG_RT_USING_SERIAL=y
CONFIG_RT_SERIAL_USING_DMA=y
-CONFIG_RT_SERIAL_RB_BUFSZ=64
+CONFIG_RT_SERIAL_RB_BUFSZ=512
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
# CONFIG_RT_USING_CPUTIME is not set
-# CONFIG_RT_USING_I2C is not set
+CONFIG_RT_USING_I2C=y
+# CONFIG_RT_I2C_DEBUG is not set
+CONFIG_RT_USING_I2C_BITOPS=y
+# CONFIG_RT_I2C_BITOPS_DEBUG is not set
+# CONFIG_RT_USING_PHY is not set
CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_ADC is not set
# CONFIG_RT_USING_DAC is not set
@@ -173,7 +180,7 @@ CONFIG_RT_USING_SPI=y
CONFIG_RT_USING_WDT=y
# CONFIG_RT_USING_AUDIO is not set
# CONFIG_RT_USING_SENSOR is not set
-# CONFIG_RT_USING_TOUCH is not set
+CONFIG_RT_USING_TOUCH=y
# CONFIG_RT_USING_HWCRYPTO is not set
# CONFIG_RT_USING_PULSE_ENCODER is not set
# CONFIG_RT_USING_INPUT_CAPTURE is not set
@@ -204,7 +211,13 @@ CONFIG_RT_USING_POSIX=y
#
# Socket abstraction layer
#
-# CONFIG_RT_USING_SAL is not set
+CONFIG_RT_USING_SAL=y
+
+#
+# protocol stack implement
+#
+CONFIG_SAL_USING_LWIP=y
+CONFIG_SAL_USING_POSIX=y
#
# Network interface device
@@ -376,6 +389,7 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_AGILE_JSMN is not set
# CONFIG_PKG_USING_PDULIB is not set
# CONFIG_PKG_USING_BTSTACK is not set
+# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
#
# security packages
@@ -402,6 +416,8 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_WAVPLAYER is not set
# CONFIG_PKG_USING_TJPGD is not set
# CONFIG_PKG_USING_HELIX is not set
+# CONFIG_PKG_USING_AZUREGUIX is not set
+# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
#
# tools packages
@@ -416,6 +432,7 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_ADBD is not set
# CONFIG_PKG_USING_COREMARK is not set
# CONFIG_PKG_USING_DHRYSTONE is not set
+# CONFIG_PKG_USING_MEMORYPERF is not set
# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
@@ -423,6 +440,7 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_GPS_RMC is not set
# CONFIG_PKG_USING_URLENCODE is not set
# CONFIG_PKG_USING_UMCN is not set
+# CONFIG_PKG_USING_LWRB2RTT is not set
#
# system packages
@@ -449,7 +467,16 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_RAMDISK is not set
# CONFIG_PKG_USING_MININI is not set
# CONFIG_PKG_USING_QBOOT is not set
+
+#
+# Micrium: Micrium software products porting for RT-Thread
+#
# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
+# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
+# CONFIG_PKG_USING_UC_CRC is not set
+# CONFIG_PKG_USING_UC_CLK is not set
+# CONFIG_PKG_USING_UC_COMMON is not set
+# CONFIG_PKG_USING_UC_MODBUS is not set
# CONFIG_PKG_USING_PPOOL is not set
#
@@ -505,6 +532,8 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_WK2124 is not set
# CONFIG_PKG_USING_LY68L6400 is not set
# CONFIG_PKG_USING_DM9051 is not set
+# CONFIG_PKG_USING_SSD1306 is not set
+# CONFIG_PKG_USING_QKEY is not set
#
# miscellaneous packages
@@ -534,6 +563,7 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
# CONFIG_PKG_USING_HELLO is not set
# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_KI is not set
# CONFIG_PKG_USING_NNOM is not set
# CONFIG_PKG_USING_LIBANN is not set
# CONFIG_PKG_USING_ELAPACK is not set
@@ -542,8 +572,13 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_ULAPACK is not set
# CONFIG_PKG_USING_UKAL is not set
# CONFIG_PKG_USING_CRCLIB is not set
+
+#
+# games: games run on RT-Thread console
+#
# CONFIG_PKG_USING_THREES is not set
# CONFIG_PKG_USING_2048 is not set
+# CONFIG_PKG_USING_TETRIS is not set
# CONFIG_PKG_USING_LWGPS is not set
# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
@@ -584,6 +619,9 @@ CONFIG_RT_LWIP_USING_PING=y
# CONFIG_PKG_USING_DCM is not set
# CONFIG_PKG_USING_EMQ is not set
# CONFIG_PKG_USING_CFGM is not set
+# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
+# CONFIG_PKG_USING_VIRTUAL_DEVICE is not set
+# CONFIG_PKG_USING_SMODULE is not set
CONFIG_BCM2711_SOC=y
# CONFIG_BSP_SUPPORT_FPU is not set
@@ -596,10 +634,10 @@ CONFIG_BCM2711_SOC=y
#
CONFIG_BSP_USING_UART=y
CONFIG_RT_USING_UART0=y
-# CONFIG_RT_USING_UART1 is not set
+CONFIG_RT_USING_UART1=y
CONFIG_RT_USING_UART3=y
-CONFIG_RT_USING_UART4=y
-# CONFIG_RT_USING_UART5 is not set
+# CONFIG_RT_USING_UART4 is not set
+CONFIG_RT_USING_UART5=y
CONFIG_BSP_USING_GIC=y
CONFIG_BSP_USING_GIC400=y
# CONFIG_BSP_USING_GIC500 is not set
@@ -607,10 +645,19 @@ CONFIG_BSP_USING_PIN=y
CONFIG_BSP_USING_SPI=y
CONFIG_BSP_USING_SPI0_BUS=y
CONFIG_BSP_USING_SPI0_DEVICE0=y
-# CONFIG_BSP_USING_SPI0_DEVICE1 is not set
+CONFIG_BSP_USING_SPI0_DEVICE1=y
+CONFIG_BSP_USING_I2C=y
+# CONFIG_BSP_USING_I2C0 is not set
+# CONFIG_BSP_USING_I2C1 is not set
+CONFIG_BSP_USING_I2C3=y
+# CONFIG_BSP_USING_I2C4 is not set
+# CONFIG_BSP_USING_I2C5 is not set
+# CONFIG_BSP_USING_I2C6 is not set
CONFIG_BSP_USING_CORETIMER=y
# CONFIG_BSP_USING_SYSTIMER is not set
CONFIG_BSP_USING_WDT=y
+CONFIG_BSP_USING_ETH=y
+# CONFIG_BSP_USING_BULETOOTH is not set
# CONFIG_BSP_USING_RTC is not set
CONFIG_BSP_USING_SDIO=y
CONFIG_BSP_USING_SDIO0=y
@@ -618,5 +665,11 @@ CONFIG_BSP_USING_SDIO0=y
#
# Board Peripheral Drivers
#
-CONFIG_BSP_USING_HDMI=y
-CONFIG_BSP_USING_HDMI_DISPLAY=y
+CONFIG_BSP_USING_LCD=y
+# CONFIG_BSP_USING_HDMI_DISPLAY is not set
+CONFIG_BSP_USING_DSI_DISPLAY=y
+# CONFIG_BSP_USING_ILI9486 is not set
+CONFIG_BSP_USING_TOUCH=y
+CONFIG_BSP_USING_DSI_TOUCH_DEV=y
+# CONFIG_BSP_USING_XPT_TOUCH_DEV is not set
+# CONFIG_USING_LCD_CONSOLE is not set
diff --git a/bsp/raspberry-pi/raspi4-32/README.md b/bsp/raspberry-pi/raspi4-32/README.md
index 94eac22e67..64208c12a6 100644
--- a/bsp/raspberry-pi/raspi4-32/README.md
+++ b/bsp/raspberry-pi/raspi4-32/README.md
@@ -129,6 +129,12 @@ msh />
| HDMI | 支持 | - |
| SDIO | 支持 | - |
| ETH | 支持 | - |
+| BSC | 支持 | - |
+| DMA | 支持 | - |
+| DSI LCD/TOUCH | 支持 | DSI接口的LCD和TOUCH |
+| ILI9486 SPI LCD | 支持 | - |
+| XPT2046 TOUCH | 支持 | - |
+| BULETOOTH | 正在完善 | 支持reset,loadfirmware |
## 5. 注意事项
diff --git a/bsp/raspberry-pi/raspi4-32/driver/Kconfig b/bsp/raspberry-pi/raspi4-32/driver/Kconfig
index 5dca313513..28c08547f2 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/Kconfig
+++ b/bsp/raspberry-pi/raspi4-32/driver/Kconfig
@@ -50,7 +50,7 @@ menu "Hardware Drivers Config"
select RT_USING_PIN
default y
- menuconfig BSP_USING_SPI
+ menuconfig BSP_USING_SPI
bool "Enable SPI"
select RT_USING_SPI
default n
@@ -69,6 +69,32 @@ menu "Hardware Drivers Config"
default n
endif
+ menuconfig BSP_USING_I2C
+ bool "Enable I2C"
+ select RT_USING_I2C
+ default n
+
+ if BSP_USING_I2C
+ config BSP_USING_I2C0
+ bool "Enable I2C0 BUS"
+ default n
+ config BSP_USING_I2C1
+ bool "Enable I2C1 BUS"
+ default n
+ config BSP_USING_I2C3
+ bool "Enable I2C3 BUS"
+ default n
+ config BSP_USING_I2C4
+ bool "Enable I2C4 BUS"
+ default n
+ config BSP_USING_I2C5
+ bool "Enable I2C5 BUS"
+ default n
+ config BSP_USING_I2C6
+ bool "Enable I2C6 BUS"
+ default n
+ endif
+
config BSP_USING_CORETIMER
bool "Using core timer"
select RT_USING_CORETIMER
@@ -93,6 +119,14 @@ menu "Hardware Drivers Config"
select RT_USING_WDT
default n
+ config BSP_USING_ETH
+ bool "Enable ETH"
+ default n
+
+ config BSP_USING_BULETOOTH
+ bool "Enable BULETOOTH"
+ default n
+
menuconfig BSP_USING_RTC
bool "Enable RTC"
select RT_USING_RTC
@@ -119,14 +153,37 @@ menu "Hardware Drivers Config"
endmenu
menu "Board Peripheral Drivers"
- menuconfig BSP_USING_HDMI
- bool "Enable HDMI"
+ menuconfig BSP_USING_LCD
+ bool "Enable LCD"
default n
- if BSP_USING_HDMI
+ if BSP_USING_LCD
config BSP_USING_HDMI_DISPLAY
bool "HDMI DISPLAY"
default n
+ config BSP_USING_DSI_DISPLAY
+ bool "DSI DISPLAY"
+ default n
+ config BSP_USING_ILI9486
+ bool "ILI9486 DISPLAY"
+ default n
+ endif
+
+ menuconfig BSP_USING_TOUCH
+ bool "Enable Touch"
+ default n
+
+ if BSP_USING_TOUCH
+ config BSP_USING_DSI_TOUCH_DEV
+ bool "DSI TOUCH"
+ default n
+ config BSP_USING_XPT_TOUCH_DEV
+ bool "XPT TOUCH"
+ default n
endif
+
+ config USING_LCD_CONSOLE
+ bool "LCD CONSOLE"
+ default n
endmenu
endmenu
diff --git a/bsp/raspberry-pi/raspi4-32/driver/SConscript b/bsp/raspberry-pi/raspi4-32/driver/SConscript
index 64c764c1b3..446c86a654 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/SConscript
+++ b/bsp/raspberry-pi/raspi4-32/driver/SConscript
@@ -1,9 +1,19 @@
+# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
-src = Glob('*.c') + Glob('*.cpp')
+src = Glob('*.c') + Glob('*.cpp') + Glob('*.a')
CPPPATH = [cwd, str(Dir('#'))]
+if not GetDepend('BSP_USING_ETH'):
+ SrcRemove(src, ['drv_eth.c'])
+if not GetDepend('BSP_USING_SPI'):
+ SrcRemove(src, ['drv_spi.c'])
+if not GetDepend('BSP_USING_WDT'):
+ SrcRemove(src, ['drv_wdt.c'])
+if not GetDepend('BSP_USING_BULETOOTH'):
+ SrcRemove(src, ['drv_bluetooth.c'])
+
group = DefineGroup('driver', src, depend = [''], CPPPATH = CPPPATH)
# build for sub-directory
diff --git a/bsp/raspberry-pi/raspi4-32/driver/board.c b/bsp/raspberry-pi/raspi4-32/driver/board.c
index ed25fa4176..455bd28ee2 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/board.c
+++ b/bsp/raspberry-pi/raspi4-32/driver/board.c
@@ -16,13 +16,15 @@
#include "cp15.h"
#include "mmu.h"
+#include "mbox.h"
struct mem_desc platform_mem_desc[] = {
{0x0, 0x6400000, 0x0, NORMAL_MEM},
{0x8000000, 0x8800000, 0x8000000, DEVICE_MEM}, //mbox msg
- {0x0EA00000, 0x0EE00000, 0x0EA00000, DEVICE_MEM}, //framebuffer
+ {0x0E000000, 0x0EE00000, 0x0E000000, DEVICE_MEM}, //framebuffer
+ {0x0F400000, 0x0FA00000, 0x0F400000, DEVICE_MEM}, //dsi_touch
{0xFD500000, 0xFDA00000, 0xFD500000, DEVICE_MEM}, //gmac
- {0xFE000000, 0xFE400000, 0xFE000000, DEVICE_MEM}, //peripheral
+ {0xFE000000, 0xFF000000, 0xFE000000, DEVICE_MEM}, //peripheral
{0xFF800000, 0xFFA00000, 0xFF800000, DEVICE_MEM} //gic
};
@@ -36,21 +38,25 @@ void rt_hw_timer_isr(int vector, void *parameter)
void rt_hw_timer_init(void)
{
- rt_hw_interrupt_install(ARM_TIMER_IRQ, rt_hw_timer_isr, RT_NULL, "tick");
- rt_hw_interrupt_umask(ARM_TIMER_IRQ);
+ rt_uint32_t apb_clock = 0;
+ rt_uint32_t timer_clock = 1000000;
/* timer_clock = apb_clock/(pre_divider + 1) */
- ARM_TIMER_PREDIV = (250 - 1);
+ apb_clock = bcm271x_mbox_clock_get_rate(CORE_CLK_ID);
+ ARM_TIMER_PREDIV = (apb_clock/timer_clock - 1);
ARM_TIMER_RELOAD = 0;
ARM_TIMER_LOAD = 0;
ARM_TIMER_IRQCLR = 0;
ARM_TIMER_CTRL = 0;
- ARM_TIMER_RELOAD = 10000;
- ARM_TIMER_LOAD = 10000;
+ ARM_TIMER_RELOAD = 1000000/RT_TICK_PER_SECOND;
+ ARM_TIMER_LOAD = 1000000/RT_TICK_PER_SECOND;
/* 23-bit counter, enable interrupt, enable timer */
ARM_TIMER_CTRL = (1 << 1) | (1 << 5) | (1 << 7);
+
+ rt_hw_interrupt_install(ARM_TIMER_IRQ, rt_hw_timer_isr, RT_NULL, "tick");
+ rt_hw_interrupt_umask(ARM_TIMER_IRQ);
}
void idle_wfi(void)
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_bluetooth.c b/bsp/raspberry-pi/raspi4-32/driver/drv_bluetooth.c
new file mode 100644
index 0000000000..6b839f5e23
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_bluetooth.c
@@ -0,0 +1,885 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-29 bigmagic first version
+ */
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "drv_bluetooth.h"
+#include "drv_uart.h"
+#include "raspi4.h"
+
+//https://github.com/RPi-Distro/bluez-firmware/tree/master/broadcom
+//arm-none-eabi-objcopy.exe -I binary -O elf32-littlearm -B arm driver\BCM4345C0.hcd driver\BCM4345C0.a
+
+#define BT_UART_NAME "uart0"
+#define BT_TX_MAX (256)
+#define BT_RX_MAX (256)
+#define BT_HEAD_NUM (4)
+#define BT_TRY_NUM_MAX (3)
+#define BT_SEND_MIN_PACK (8)
+
+unsigned char lo(unsigned int val) { return (unsigned char)(val & 0xff); }
+unsigned char hi(unsigned int val) { return (unsigned char)((val & 0xff00) >> 8); }
+
+#define BT_THREAD_STACK_SIZE (2048)
+#define BT_THREAD_PRIORITY (15)
+#define BT_THREAD_TICK (10)
+
+enum
+{
+ LE_EVENT_CODE = 0x3e,
+ LE_CONNECT_CODE = 0x01,
+ LE_ADREPORT_CODE = 0x02,
+ HCI_ACL_PKT = 0x02,
+ HCI_EVENT_PKT = 0x04
+};
+
+static char ch;
+static rt_sem_t bt_rx_sem = RT_NULL;
+static rt_device_t bt_device;
+
+static rt_uint8_t tx_buff[BT_TX_MAX];
+static rt_uint8_t rx_buff[BT_RX_MAX];
+
+static rt_err_t bt_rx_ind(rt_device_t dev, rt_size_t size)
+{
+ rt_sem_release(bt_rx_sem);
+ return RT_EOK;
+}
+
+int bt_uart_send_data(rt_device_t dev, rt_uint32_t *buf, int len)
+{
+ return rt_device_write(dev, 0, buf, len);
+}
+
+
+void bt_uart_receive_flush(rt_device_t dev)
+{
+ rt_device_read(dev, RT_NULL, rx_buff, BT_RX_MAX);
+}
+
+int bt_uart_receive_data(rt_device_t dev, rt_uint8_t *buf, rt_uint32_t *len, rt_int32_t time)
+{
+ rt_uint16_t ii = 0;
+
+ ii = rt_device_read(dev, 0, buf, BT_RX_MAX);
+ *len = ii;
+ return ii;
+}
+
+void bt_data_pack(rt_uint8_t *tx_buff, rt_uint8_t ogf, rt_uint8_t ocf, rt_uint32_t data_len)
+{
+ tx_buff[0] = BT_HCI_COMMAND_PKT;
+ tx_buff[1] = ogf; //hi(ogf << 10 | ocf);//opcode hi
+ tx_buff[2] = ocf; //lo(ogf << 10 | ocf);//opcode lo
+ tx_buff[3] = data_len;
+}
+
+rt_uint32_t bt_reply_check(const rt_uint8_t *buff, rt_uint16_t ogf, rt_uint16_t ocf, int pack_len)
+{
+ //step 1
+ if (buff[0] != BT_HCI_EVENT_PKT)
+ {
+ return 1;
+ }
+
+ //step2
+ if (buff[1] == BT_CONNECT_COMPLETE_CODE)
+ {
+ if (buff[2] != 4)
+ {
+ return 2;
+ }
+
+ //err code
+ if (buff[3] != 0)
+ {
+ rt_kprintf("Saw HCI COMMAND STATUS error:%d", buff[3]);
+ return 12;
+ }
+
+ if (buff[4] == 0)
+ {
+ return 3;
+ }
+
+ if (buff[5] != ogf)
+ {
+ return 4;
+ }
+
+ if (buff[6] != ocf)
+ {
+ return 5;
+ }
+ }
+ else if (buff[1] == BT_COMMAND_COMPLETE_CODE)
+ {
+ if (buff[2] != 4)
+ {
+ return 6;
+ }
+
+ if (buff[3] == 0)
+ {
+ return 7;
+ }
+
+ if (buff[4] != ogf)
+ {
+ return 8;
+ }
+
+ if (buff[5] != ocf)
+ {
+ return 9;
+ }
+
+ if (buff[6] == 0)
+ {
+ return 10;
+ }
+ }
+ else
+ {
+ return 11;
+ }
+
+ return 0;
+}
+
+rt_err_t bt_loadfirmware(void)
+{
+
+ int ii = 0;
+ int ret = 0;
+ int recv_len = BT_RX_MAX;
+ int step = 0;
+ rt_uint8_t ogf, ocf;
+
+ rt_memset(tx_buff, 0, BT_TX_MAX);
+
+ ogf = hi(BT_OGF_VENDOR << 10 | BT_COMMAND_LOAD_FIRMWARE);
+ ocf = lo(BT_OGF_VENDOR << 10 | BT_COMMAND_LOAD_FIRMWARE);
+
+ bt_data_pack(tx_buff, ogf, ocf, 0);
+ int kk = 0;
+ for (ii = 0; ii < BT_TRY_NUM_MAX; ii++)
+ {
+ recv_len = BT_RX_MAX;
+ bt_uart_receive_flush(bt_device);
+ bt_uart_send_data(bt_device, tx_buff, BT_SEND_MIN_PACK);
+ rt_thread_mdelay(5);
+
+ ret = bt_uart_receive_data(bt_device, rx_buff, &recv_len, 2000);
+
+ if (ret > 0)
+ {
+ ret = bt_reply_check(rx_buff, ogf, ocf, RT_NULL);
+ if (ret == 0)
+ {
+ step = 1;
+ break;
+ }
+ else
+ {
+ rt_kprintf("err code is %d\n", ret);
+ }
+ }
+ }
+
+ if (step == 1)
+ {
+ extern unsigned char _binary_driver_BCM4345C0_hcd_size[];
+ extern unsigned char _binary_driver_BCM4345C0_hcd_start[];
+ unsigned int c = 0;
+ unsigned int size = (long)&_binary_driver_BCM4345C0_hcd_size;
+ while (c < size)
+ {
+ //unsigned char opcodebytes[] = {_binary_BCM4345C0_hcd_start[c], _binary_BCM4345C0_hcd_start[c + 1]};
+ unsigned char length = _binary_driver_BCM4345C0_hcd_start[c + 2];
+ unsigned char *data = &(_binary_driver_BCM4345C0_hcd_start[c + 3]);
+ rt_memset(tx_buff, 0, BT_TX_MAX);
+
+ ogf = _binary_driver_BCM4345C0_hcd_start[c + 1];
+ ocf = _binary_driver_BCM4345C0_hcd_start[c];
+ bt_data_pack(tx_buff, ogf, ocf, length);
+
+ rt_memcpy(&tx_buff[BT_HEAD_NUM], data, length);
+ int kk = 0;
+ for (ii = 0; ii < BT_TRY_NUM_MAX; ii++)
+ {
+ recv_len = BT_RX_MAX;
+ rt_memset(rx_buff, 0, BT_TX_MAX);
+ bt_uart_receive_flush(bt_device);
+ bt_uart_send_data(bt_device, tx_buff, length + BT_HEAD_NUM);
+ bt_uart_receive_flush(bt_device);
+ rt_thread_mdelay(5);
+ ret = bt_uart_receive_data(bt_device, rx_buff, &recv_len, 1000);
+
+ if (ret > 0)
+ {
+ ret = bt_reply_check(rx_buff, ogf, ocf, RT_NULL);
+ if (ret == 0)
+ {
+ step = 2;
+ break;
+ }
+ else
+ {
+ rt_kprintf("err code is %d\n", ret);
+ }
+ }
+ }
+
+ if (ii >= 3)
+ {
+ step = 3;
+ break;
+ }
+ c += 3 + length;
+ }
+
+ if (step != 3)
+ {
+ return RT_EOK;
+ }
+ }
+ else
+ {
+ return RT_ERROR;
+ }
+
+ return RT_ERROR;
+}
+
+rt_err_t bt_setbaud(void)
+{
+ static unsigned char params[] = {0, 0, 0x00, 0xc2, 0x01, 0x00}; // little endian, 115200
+ int params_len = 6;
+ int ii = 0;
+ int ret = 0;
+
+ int recv_len = BT_RX_MAX;
+ rt_uint16_t ogf, ocf;
+
+ rt_memset(tx_buff, 0, BT_TX_MAX);
+
+ ogf = hi(BT_OGF_VENDOR << 10 | BT_COMMAND_SET_BAUD);
+ ocf = lo(BT_OGF_VENDOR << 10 | BT_COMMAND_SET_BAUD);
+
+ bt_data_pack(tx_buff, ogf, ocf, params_len);
+
+ //rt_memcpy(&tx_buff[BT_HEAD_NUM], params, params_len);
+ tx_buff[4] = 0x00;
+ tx_buff[5] = 0x01;
+ tx_buff[6] = 0xc2;
+ tx_buff[7] = 0x00;
+ tx_buff[8] = 0x00;
+ tx_buff[9] = 0x00;
+
+ for (ii = 0; ii < BT_TRY_NUM_MAX; ii++)
+ {
+ recv_len = BT_RX_MAX;
+ bt_uart_receive_flush(bt_device);
+ bt_uart_send_data(bt_device, tx_buff, params_len + BT_HEAD_NUM);
+ rt_thread_mdelay(5);
+ ret = bt_uart_receive_data(bt_device, rx_buff, &recv_len, 1000);
+ if (ret > 0)
+ {
+ ret = bt_reply_check(rx_buff, ogf, ocf, RT_NULL);
+ if (ret == 0)
+ {
+ return RT_EOK;
+ }
+ else
+ {
+ rt_kprintf("err code is %d\n", ret);
+ }
+ }
+ }
+ return RT_ERROR;
+}
+
+rt_err_t setLEeventmask(unsigned char mask)
+{
+ unsigned char params[] = {mask, 0, 0, 0, 0, 0, 0, 0};
+
+ //static unsigned char params[] = { 0xee, 0xff, 0xc0, 0xee, 0xff, 0xc0 }; // reversed
+ int params_len = 8;
+ int ii = 0;
+ int ret = 0;
+
+ int recv_len = BT_RX_MAX;
+ rt_uint16_t ogf, ocf;
+
+ rt_memset(tx_buff, 0, BT_TX_MAX);
+
+ ogf = hi(BT_OGF_LE_CONTROL << 10 | 0x01);
+ ocf = lo(BT_OGF_LE_CONTROL << 10 | 0x01);
+
+ bt_data_pack(tx_buff, ogf, ocf, params_len);
+
+ //rt_memcpy(&tx_buff[BT_HEAD_NUM], params, params_len);
+ tx_buff[4] = params[0];
+ tx_buff[5] = params[1];
+ tx_buff[6] = params[2];
+ tx_buff[7] = params[3];
+ tx_buff[8] = params[4];
+ tx_buff[9] = params[5];
+ tx_buff[10] = params[6];
+ tx_buff[11] = params[7];
+
+
+ for (ii = 0; ii < BT_TRY_NUM_MAX; ii++)
+ {
+ recv_len = BT_RX_MAX;
+ bt_uart_receive_flush(bt_device);
+ bt_uart_send_data(bt_device, tx_buff, params_len + BT_HEAD_NUM);
+ rt_thread_mdelay(5);
+ ret = bt_uart_receive_data(bt_device, rx_buff, &recv_len, 1000);
+ if (ret > 0)
+ {
+ ret = bt_reply_check(rx_buff, ogf, ocf, RT_NULL);
+ if (ret == 0)
+ {
+ return RT_EOK;
+ }
+ else
+ {
+ rt_kprintf("err code is %d\n", ret);
+ }
+ }
+ }
+ return RT_ERROR;
+
+ //if (hciCommand(OGF_LE_CONTROL, 0x01, params, 8)) uart_writeText("setLEeventmask failed\n");
+}
+
+rt_err_t bt_getbdaddr(unsigned char *bdaddr)
+{
+ static unsigned char params[] = {0x00, 0x10, 0x09, BT_HCI_COMMAND_PKT}; //get bdaddr
+ int params_len = 4;
+ int recv_len = BT_RX_MAX;
+
+ // rt_memcpy(tx_buff, params, 4);
+ tx_buff[0] = BT_HCI_COMMAND_PKT;
+ tx_buff[1] = 0x09;
+ tx_buff[2] = 0x10;
+ tx_buff[3] = 0x00;
+
+ bt_uart_receive_flush(bt_device);
+ bt_uart_send_data(bt_device, tx_buff, 4);
+ rt_thread_mdelay(100);
+ bt_uart_receive_data(bt_device, rx_buff, &recv_len, 1000);
+ if (recv_len > 0)
+ {
+ if ((rx_buff[0] != BT_HCI_EVENT_PKT) || (rx_buff[1] != BT_COMMAND_COMPLETE_CODE))
+ {
+ return RT_ERROR;
+ }
+
+ if ((rx_buff[2] != 0x0a) || (rx_buff[3] != 0x01))
+ {
+ return RT_ERROR;
+ }
+
+ if ((rx_buff[4] != 0x09) || (rx_buff[5] != 0x10))
+ {
+ return RT_ERROR;
+ }
+ bdaddr[0] = rx_buff[7];
+ bdaddr[1] = rx_buff[8];
+ bdaddr[2] = rx_buff[9];
+
+ bdaddr[3] = rx_buff[10];
+ bdaddr[4] = rx_buff[11];
+ bdaddr[5] = rx_buff[12];
+
+ }
+ else
+ {
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+rt_err_t setLEscanenable(unsigned char state, unsigned char duplicates)
+{
+ unsigned char params[] = {state, duplicates};
+
+ //static unsigned char params[] = { 0xee, 0xff, 0xc0, 0xee, 0xff, 0xc0 }; // reversed
+ int params_len = 2;
+ int ii = 0;
+ int ret = 0;
+
+ int recv_len = BT_RX_MAX;
+ rt_uint16_t ogf, ocf;
+
+ rt_memset(tx_buff, 0, BT_TX_MAX);
+
+ ogf = hi(BT_OGF_LE_CONTROL << 10 | 0x0c);
+ ocf = lo(BT_OGF_LE_CONTROL << 10 | 0x0c);
+
+ bt_data_pack(tx_buff, ogf, ocf, params_len);
+ tx_buff[4] = params[0];
+ tx_buff[5] = params[1];
+
+ //rt_memcpy(&tx_buff[BT_HEAD_NUM], params, params_len);
+
+ for (ii = 0; ii < BT_TRY_NUM_MAX; ii++)
+ {
+ recv_len = BT_RX_MAX;
+ bt_uart_receive_flush(bt_device);
+ bt_uart_send_data(bt_device, tx_buff, params_len + BT_HEAD_NUM);
+ rt_thread_mdelay(5);
+ ret = bt_uart_receive_data(bt_device, rx_buff, &recv_len, 1000);
+ if (ret > 0)
+ {
+ ret = bt_reply_check(rx_buff, ogf, ocf, RT_NULL);
+ if (ret == 0)
+ {
+ return RT_EOK;
+ }
+ else
+ {
+ rt_kprintf("err code is %d\n", ret);
+ }
+ }
+ }
+ return RT_ERROR;
+}
+
+rt_err_t setLEscanparameters(unsigned char type, unsigned char linterval, unsigned char hinterval, unsigned char lwindow, unsigned char hwindow, unsigned char own_address_type, unsigned char filter_policy)
+{
+ unsigned char params[] = {type, linterval, hinterval, lwindow, hwindow, own_address_type, filter_policy};
+
+ int params_len = 7;
+ int ii = 0;
+ int ret = 0;
+
+ int recv_len = BT_RX_MAX;
+ rt_uint16_t ogf, ocf;
+
+ rt_memset(tx_buff, 0, BT_TX_MAX);
+
+ ogf = hi(BT_OGF_LE_CONTROL << 10 | 0x0b);
+ ocf = lo(BT_OGF_LE_CONTROL << 10 | 0x0b);
+
+ bt_data_pack(tx_buff, ogf, ocf, params_len);
+ tx_buff[4] = params[0];
+ tx_buff[5] = params[1];
+ tx_buff[6] = params[2];
+ tx_buff[7] = params[3];
+ tx_buff[8] = params[4];
+ tx_buff[9] = params[5];
+ tx_buff[10] = params[6];
+ //rt_memcpy(&tx_buff[BT_HEAD_NUM], params, params_len);
+
+ for (ii = 0; ii < BT_TRY_NUM_MAX; ii++)
+ {
+ recv_len = BT_RX_MAX;
+ bt_uart_receive_flush(bt_device);
+ bt_uart_send_data(bt_device, tx_buff, params_len + BT_HEAD_NUM);
+ rt_thread_mdelay(5);
+ ret = bt_uart_receive_data(bt_device, rx_buff, &recv_len, 1000);
+ if (ret > 0)
+ {
+ ret = bt_reply_check(rx_buff, ogf, ocf, RT_NULL);
+ if (ret == 0)
+ {
+ return RT_EOK;
+ }
+ else
+ {
+ rt_kprintf("err code is %d\n", ret);
+ }
+ }
+ }
+ return RT_ERROR;
+}
+
+rt_err_t startActiveScanning()
+{
+ float BleScanInterval = 60; // every 60ms
+ float BleScanWindow = 60;
+ float BleScanDivisor = 0.625;
+
+ unsigned int p = BleScanInterval / BleScanDivisor;
+ unsigned int q = BleScanWindow / BleScanDivisor;
+
+ if (setLEscanparameters(BT_LL_SCAN_ACTIVE, lo(p), hi(p), lo(q), hi(q), 0, 0) == RT_EOK)
+ {
+ rt_kprintf("setLEscanparameters ok!\n");
+ }
+ if (setLEscanenable(1, 0) == RT_EOK)
+ {
+ rt_kprintf("setLEscanenable ok!\n");
+ }
+}
+
+rt_err_t bt_setbdaddr(void)
+{
+ static unsigned char params[] = {0xee, 0xff, 0xc0, 0xee, 0xff, 0xc0}; // reversed
+ int params_len = 6;
+ int ii = 0;
+ int ret = 0;
+
+ int recv_len = BT_RX_MAX;
+ rt_uint16_t ogf, ocf;
+
+ rt_memset(tx_buff, 0, BT_TX_MAX);
+
+ ogf = hi(BT_OGF_VENDOR << 10 | BT_COMMAND_SET_BDADDR);
+ ocf = lo(BT_OGF_VENDOR << 10 | BT_COMMAND_SET_BDADDR);
+
+ bt_data_pack(tx_buff, ogf, ocf, params_len);
+
+ tx_buff[4] = 0xc0;
+ tx_buff[5] = 0xff;
+ tx_buff[6] = 0xee;
+ tx_buff[7] = 0xc0;
+ tx_buff[8] = 0xff;
+ tx_buff[9] = 0xee;
+
+ //rt_memcpy(&tx_buff[BT_HEAD_NUM], params, params_len);
+
+ for (ii = 0; ii < BT_TRY_NUM_MAX; ii++)
+ {
+ recv_len = BT_RX_MAX;
+ bt_uart_receive_flush(bt_device);
+ bt_uart_send_data(bt_device, tx_buff, params_len + BT_HEAD_NUM);
+ rt_thread_mdelay(5);
+ ret = bt_uart_receive_data(bt_device, rx_buff, &recv_len, 1000);
+ if (ret > 0)
+ {
+ ret = bt_reply_check(rx_buff, ogf, ocf, RT_NULL);
+ if (ret == 0)
+ {
+ return RT_EOK;
+ }
+ else
+ {
+ rt_kprintf("err code is %d\n", ret);
+ }
+ }
+ }
+ return RT_ERROR;
+}
+rt_err_t bt_reset(void)
+{
+ int ii = 0;
+ int ret = 0;
+ int recv_len = BT_RX_MAX;
+ rt_uint16_t ogf, ocf;
+
+ rt_memset(tx_buff, 0, BT_TX_MAX);
+
+ ogf = hi(BT_OGF_HOST_CONTROL << 10 | BT_COMMAND_RESET_CHIP);
+ ocf = lo(BT_OGF_HOST_CONTROL << 10 | BT_COMMAND_RESET_CHIP);
+
+ bt_data_pack(tx_buff, ogf, ocf, 0);
+ for (ii = 0; ii < BT_TRY_NUM_MAX; ii++)
+ {
+ recv_len = BT_RX_MAX;
+ bt_uart_receive_flush(bt_device);
+ bt_uart_send_data(bt_device, tx_buff, 8);
+ rt_thread_mdelay(5);
+ ret = bt_uart_receive_data(bt_device, rx_buff, &recv_len, 1000);
+ //rt_kprintf("recv_len is %d\n", recv_len);
+ if (ret > 0)
+ {
+ ret = bt_reply_check(rx_buff, ogf, ocf, RT_NULL);
+ if (ret == 0)
+ {
+ return RT_EOK;
+ }
+ else
+ {
+ rt_kprintf("err code is %d\n", ret);
+ }
+ }
+ }
+ return RT_ERROR;
+}
+
+rt_device_t bt_uart_init(const char *uartname)
+{
+ rt_device_t dev = RT_NULL;
+ if (strcmp(uartname, BT_UART_NAME) == 0)
+ {
+ bt_rx_sem = rt_sem_create("btbuf", 0, RT_IPC_FLAG_FIFO);
+ dev = rt_device_find(uartname);
+ if (dev == RT_NULL)
+ {
+ rt_kprintf("can no find dev %s\n", uartname);
+ return dev;
+ }
+
+ if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR) == RT_EOK)
+ {
+ rt_device_set_rx_indicate(dev, bt_rx_ind);
+ }
+ return dev;
+ }
+ return dev;
+}
+
+static void bt_task_entry(void *param)
+{
+ while (1)
+ {
+ rt_thread_delay(1000);
+ }
+}
+
+#define MAX_MSG_LEN 50
+#define MAX_READ_RUN 100
+
+unsigned char data_buf[MAX_MSG_LEN];
+unsigned int data_len;
+unsigned int messages_received = 0;
+unsigned int poll_state = 0;
+
+unsigned int got_echo_sid = 0;
+unsigned int got_echo_name = 0;
+unsigned char echo_addr[6];
+
+void hci_poll2(unsigned char byte)
+{
+ switch (poll_state)
+ {
+ case 0:
+ if (byte != HCI_EVENT_PKT)
+ poll_state = 0;
+ else
+ poll_state = 1;
+ break;
+ case 1:
+ if (byte != LE_EVENT_CODE)
+ poll_state = 0;
+ else
+ poll_state = 2;
+ break;
+ case 2:
+ if (byte > MAX_MSG_LEN)
+ poll_state = 0;
+ else
+ {
+ poll_state = 3;
+ data_len = byte;
+ }
+ break;
+ default:
+ data_buf[poll_state - 3] = byte;
+ if (poll_state == data_len + 3 - 1)
+ {
+ messages_received++;
+ poll_state = 0;
+ }
+ else
+ poll_state++;
+ }
+}
+
+unsigned char *hci_poll()
+{
+ int recv_len = 256;
+ unsigned int goal = messages_received + 1;
+ bt_uart_receive_data(bt_device, rx_buff, &recv_len, 1000);
+ rt_thread_mdelay(10);
+ if (recv_len > 0)
+ {
+ unsigned int run = 0;
+ while (run < MAX_READ_RUN && messages_received < goal)
+ {
+
+ recv_len = recv_len - 1;
+ hci_poll2(rx_buff[recv_len]);
+ run++;
+
+ if (recv_len == 0)
+ {
+ break;
+ }
+ }
+ if (run == MAX_READ_RUN)
+ return 0;
+ else
+ return data_buf;
+ }
+ return 0;
+}
+
+void bt_search()
+{
+ unsigned char *buf;
+
+ while ((buf = hci_poll()))
+ {
+ if (data_len >= 2)
+ {
+ if (buf[0] == LE_ADREPORT_CODE)
+ {
+ unsigned char numreports = buf[1];
+
+ if (numreports == 1)
+ {
+ unsigned char event_type = buf[2];
+
+ if (event_type == 0x00)
+ {
+ unsigned char buf_len = buf[10];
+ unsigned char ad_len = buf[11];
+
+ if (ad_len < data_len && buf_len + 11 == data_len - 1)
+ {
+ for (int c = 9; c >= 4; c--)
+ echo_addr[9 - c] = buf[c];
+ buf += 11;
+
+ got_echo_sid = 0;
+ got_echo_name = 0; // Reset the search state machine
+ do
+ {
+ ad_len = buf[0];
+ unsigned char ad_type = buf[1];
+ buf += 2;
+
+ if (ad_len >= 2)
+ {
+ if (ad_type == 0x03)
+ {
+ unsigned int sid = 0;
+
+ for (int d = 0; d < ad_len - 1; d += 2)
+ {
+ sid = buf[d] | (buf[d + 1] << 8);
+ if (sid == 0xEC00)
+ {
+ rt_kprintf("sid is %d\n", sid);
+ //uart_hex(sid); uart_writeText(" ");
+ got_echo_sid = 1;
+ }
+ }
+ }
+ else if (ad_type == 0x09)
+ {
+ char remote_name[ad_len - 1];
+ unsigned int d = 0;
+
+ while (d < ad_len - 1)
+ {
+ remote_name[d] = buf[d];
+ d++;
+ }
+ if (!memcmp(remote_name, "echo", 4))
+ {
+ rt_kprintf("remote_name is %s\n", remote_name);
+ got_echo_name = 1;
+ }
+ }
+ }
+
+ buf += ad_len - 1;
+ } while (buf[1]);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void bt_uart_protocol_init()
+{
+ rt_thread_t bt_tid = RT_NULL;
+ bt_device = bt_uart_init(BT_UART_NAME);
+ bt_tid = rt_thread_create("bt_task", bt_task_entry, RT_NULL, BT_THREAD_STACK_SIZE, BT_THREAD_PRIORITY, BT_THREAD_TICK);
+ if (bt_tid == RT_NULL)
+ {
+ rt_kprintf("bt_task create err!\n");
+ return 0;
+ }
+ rt_thread_startup(bt_tid);
+}
+
+int rt_hw_bluetooth_init(void)
+{
+ bt_uart_protocol_init();
+ if (bt_reset() == RT_EOK)
+ {
+ rt_kprintf("bluetooth reset ok!\n");
+ }
+ else
+ {
+ rt_kprintf("bluetooth reset err!\n");
+ }
+
+ rt_thread_delay(10);
+ if (bt_loadfirmware() == RT_EOK)
+ {
+ rt_kprintf("loadfirmware ok!\n");
+ }
+ else
+ {
+ rt_kprintf("loadfirmware err!\n");
+ }
+ rt_thread_delay(10);
+ if (bt_setbaud() == RT_EOK)
+ {
+ rt_kprintf("setbaud ok!\n");
+ }
+ else
+ {
+ rt_kprintf("setbaud err!\n");
+ }
+
+ rt_thread_delay(10);
+ if (bt_setbdaddr() == RT_EOK)
+ {
+ rt_kprintf("setbdaddr ok!\n");
+ }
+ else
+ {
+ rt_kprintf("setbdaddr err!\n");
+ }
+ rt_thread_delay(100);
+ rt_uint8_t bdaddr[6];
+ if (bt_getbdaddr(bdaddr) == RT_EOK)
+ {
+ rt_kprintf("bdaddr :%02x:%02x:%02x:%02x:%02x:%02x\n", bdaddr[0], bdaddr[1], bdaddr[2], bdaddr[3], bdaddr[4], bdaddr[5]);
+ }
+ else
+ {
+ rt_kprintf("getbdaddr err!\n");
+ }
+
+ rt_thread_delay(100);
+
+ if (setLEeventmask(0xff) == RT_EOK)
+ {
+ rt_kprintf("setLEeventmask ok!\n");
+ }
+ rt_thread_delay(100);
+ startActiveScanning();
+ rt_thread_delay(500);
+ rt_kprintf("start!\n");
+ while (1)
+ {
+ bt_search();
+ if (got_echo_sid && got_echo_name)
+ {
+ break;
+ }
+ rt_thread_mdelay(10);
+ }
+ rt_kprintf("stop scan!\n");
+}
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_bluetooth.h b/bsp/raspberry-pi/raspi4-32/driver/drv_bluetooth.h
new file mode 100644
index 0000000000..9de47bf191
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_bluetooth.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-29 bigmagic first version
+ */
+#ifndef __DRV_BT_H__
+#define __DRV_BT_H__
+
+#define BT_HCI_COMMAND_PKT (0x01)
+#define BT_OGF_HOST_CONTROL (0x03)
+#define BT_OGF_LE_CONTROL (0x08)
+#define BT_OGF_VENDOR (0x3f)
+#define BT_COMMAND_SET_BDADDR (0x01)
+#define BT_COMMAND_RESET_CHIP (0x03)
+#define BT_COMMAND_SET_BAUD (0x18)
+#define BT_COMMAND_LOAD_FIRMWARE (0x2e)
+#define BT_HCI_ACL_PKT (0x02)
+#define BT_HCI_EVENT_PKT (0x04)
+#define BT_COMMAND_COMPLETE_CODE (0x0e)
+#define BT_CONNECT_COMPLETE_CODE (0x0f)
+#define BT_LL_SCAN_ACTIVE (0x01)
+#define BT_LL_ADV_NONCONN_IND (0x03)
+
+#endif
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_dma.c b/bsp/raspberry-pi/raspi4-32/driver/drv_dma.c
new file mode 100644
index 0000000000..4ec94896c1
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_dma.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-12-02 bigmagic first version
+ */
+#include "drv_dma.h"
+#include "raspi4.h"
+
+volatile unsigned int __attribute__((aligned(256))) dma_disc[32];
+//https://www.raspberrypi.org/forums/viewtopic.php?f=72&t=10276
+static struct rt_semaphore dma_sem;
+
+//DMA 0 1 2 3 4 5 6
+typedef struct _dma_ctrl_block
+{
+ unsigned int TI; // Transfer information
+ unsigned int SOURCE_AD; // source address
+ unsigned int DEST_AD; // destination address
+ unsigned int TXFR_LEN; // transfer length
+ unsigned int STRIDE; // 2D mode stride
+ struct _dma_ctrl_block *NEXTCONBK; // Next control block address
+ unsigned int DEBUG;
+ unsigned int reserved1;
+
+} dma_ctrl_block_t;
+
+//DMA 7 8 9 10
+typedef struct _dma_lite_ctrl_block
+{
+ unsigned int TI; // Transfer information
+ unsigned int SOURCE_AD; // source address
+ unsigned int DEST_AD; // destination address
+ unsigned int TXFR_LEN; // transfer length
+ struct _dma_lite_ctrl_block *NEXTCONBK; // Next control block address
+ unsigned int DEBUG;
+ unsigned int reserved1;
+ unsigned int reserved2;
+
+} dma_lite_ctrl_block_t;
+
+//DMA 11 12 13 14 15
+typedef struct _dma4_ctrl_block
+{
+ unsigned int TI; // Transfer information
+ unsigned int SOURCE_AD0; // source address0
+ unsigned int SOURCE_AD1; // source address1
+ unsigned int DEST_AD0; // destination address0
+ unsigned int DEST_AD1; // destination address1
+ unsigned int TXFR_LEN; // transfer length
+ unsigned int STRIDE; // 2D mode stride
+ struct _dma4_ctrl_block *NEXTCONBK; // Next control block address
+} dma4_ctrl_block_t;
+
+static dma_lite_ctrl_block_t *ctr_blocks;
+
+static void dma_irq(int irq, void *param)
+{
+ if (DMA_INT_STATUS_REG & DMA_INT7)
+ {
+ DMA_CS(7) = DMA_CS_INT;
+ rt_sem_release(&dma_sem);
+ }
+}
+
+//dma 7 8 9 10:XLENGTH
+rt_err_t dma_memcpy(void *src, void *dst, unsigned int size, unsigned int dch, unsigned int timeout)
+{
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, dst, size);
+
+ /* Stop DMA, if it was already started */
+ DMA_CS(dch) = DMA_CS_RESET;
+
+ /* Clear DMA status flags */
+ DMA_CS(dch) = DMA_CS_INT | DMA_CS_END; /* Interrupted flag & Transmission ended flag*/
+ //cb info
+ ctr_blocks->TI = DMA_TI_SRC_INC | DMA_TI_DEST_INC | DMA_TI_INTEN;
+ ctr_blocks->SOURCE_AD = (unsigned int)src;
+ ctr_blocks->DEST_AD = (unsigned int)dst;
+ ctr_blocks->TXFR_LEN = size;
+ ctr_blocks->NEXTCONBK = 0;
+ ctr_blocks->reserved1 = 0;
+ ctr_blocks->reserved2 = 0;
+
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, ctr_blocks, sizeof(dma_lite_ctrl_block_t) * 8);
+
+ DMA_CONBLK_AD(dch) = (rt_uint32_t)ctr_blocks;
+ DMA_CS(dch) = DMA_CS_INT | DMA_CS_END | DMA_CS_ACTIVE;
+
+ if(rt_sem_take(&dma_sem, timeout) != RT_EOK)
+ {
+ rt_kprintf("dma transfer timeout!\n");
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+void dma_init(unsigned char dch)
+{
+ rt_sem_init(&dma_sem, "dma_sem", 0, RT_IPC_FLAG_FIFO);
+
+ ctr_blocks = (dma_lite_ctrl_block_t *)&dma_disc[0]; //rt_malloc(sizeof(DMA_Lite_Control_Block));
+ //Make sure DMA channel is enabled by
+ //writing the corresponding bit in DMA_ENABLE in the DMA register to 1
+ DMA_ENABLE_REG = (1 << dch);
+
+ rt_hw_interrupt_install(IRQ_DMA7_DMA8, dma_irq, RT_NULL, "dma_irq");
+ rt_hw_interrupt_umask(IRQ_DMA7_DMA8);
+}
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_dma.h b/bsp/raspberry-pi/raspi4-32/driver/drv_dma.h
new file mode 100644
index 0000000000..1b79eb1c95
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_dma.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-12-02 bigmagic first version
+ */
+#ifndef __DRV_DMA_H__
+#define __DRV_DMA_H__
+
+#include <rthw.h>
+
+#define DMA_PER_BASE (0xFE000000)
+
+//DMA
+#define DMA_BASE (DMA_PER_BASE+0x7000)
+#define DMA_INT_STATUS (DMA_BASE + 0xFE0) //Interrupt Status of each DMA Channel
+#define DMA_ENABLE (DMA_BASE + 0xFF0) //Global Enable bits for each DMA Channel */
+#define DMA15_BASE (DMA_PER_BASE+0xE05000) //DMA Channel 15 Register Set */
+
+
+#define DMA_INT_STATUS_REG __REG32(DMA_INT_STATUS)
+#define DMA_ENABLE_REG __REG32(DMA_ENABLE)
+//DMA dch 1~14
+#define DMA_CS(dch) __REG32(DMA_BASE + dch*0x100 + 0x000) /* Control and Status */
+#define DMA_CONBLK_AD(dch) __REG32(DMA_BASE + dch*0x100 + 0x004) /* Control Block Address */
+#define DMA_TI(dch) __REG32(DMA_BASE + dch*0x100 + 0x008) /* CB Word 0(Transfer Information) */
+#define DMA_SOURCE_AD(dch) __REG32(DMA_BASE + dch*0x100 + 0x00c) /* CB Word 1(Source Address) */
+#define DMA_DEST_AD(dch) __REG32(DMA_BASE + dch*0x100 + 0x010) /* CB Word 2(Destination Address) */
+#define DMA_TXFR_LEN(dch) __REG32(DMA_BASE + dch*0x100 + 0x014) /* CB Word 3(Transfer Length) */
+#define DMA_STRIDE(dch) __REG32(DMA_BASE + dch*0x100 + 0x018) /* CB Word 4(2D Stride) */
+#define DMA_NEXTCONBK(dch) __REG32(DMA_BASE + dch*0x100 + 0x01c) /* CB Word 5(Next CB Address) */
+#define DMA_DEBUG(dch) __REG32(DMA_BASE + dch*0x100 + 0x01c) /* Debug */
+
+//DMA dch 15
+#define DMA15_CS __REG32(DMA15_BASE + 0x000) /* Control and Status */
+#define DMA15_CONBLK_AD __REG32(DMA15_BASE + 0x004) /* Control Block Address */
+#define DMA15_TI __REG32(DMA15_BASE + 0x008) /* CB Word 0(Transfer Information) */
+#define DMA15_SOURCE_AD __REG32(DMA15_BASE + 0x00c) /* CB Word 1(Source Address) */
+#define DMA15_DEST_AD __REG32(DMA15_BASE + 0x010) /* CB Word 2(Destination Address) */
+#define DMA15_TXFR_LEN __REG32(DMA15_BASE + 0x014) /* CB Word 3(Transfer Length) */
+#define DMA15_STRIDE __REG32(DMA15_BASE + 0x018) /* CB Word 4(2D Stride) */
+#define DMA15_NEXTCONBK __REG32(DMA15_BASE + 0x01c) /* CB Word 5(Next CB Address) */
+#define DMA15_DEBUG __REG32(DMA15_BASE + 0x01c) /* Debug */
+
+#define DMA15_ENABLE (1 << 15)
+#define DMA14_ENABLE (1 << 14)
+#define DMA13_ENABLE (1 << 13)
+#define DMA12_ENABLE (1 << 12)
+#define DMA11_ENABLE (1 << 11)
+#define DMA10_ENABLE (1 << 10)
+#define DMA9_ENABLE (1 << 9)
+#define DMA8_ENABLE (1 << 8)
+#define DMA7_ENABLE (1 << 7)
+#define DMA6_ENABLE (1 << 6)
+#define DMA5_ENABLE (1 << 5)
+#define DMA4_ENABLE (1 << 4)
+#define DMA3_ENABLE (1 << 3)
+#define DMA2_ENABLE (1 << 2)
+#define DMA1_ENABLE (1 << 1)
+#define DMA0_ENABLE (1 << 0)
+
+//Peripheral DREQ Signals
+#define DREQ_DSI0_PWM1 (1)
+#define DREQ_PCM_TX (2)
+#define DREQ_PCM_RX (3)
+#define DREQ_SMI (4)
+#define DREQ_PWM0 (5)
+#define DREQ_SPI0_TX (6)
+#define DREQ_SPI0_RX (7)
+#define DREQ_BSC_SPI_SLAVE_TX (8)
+#define DREQ_BSC_SPI_SLAVE_RX (9)
+#define DREQ_HSMI0 (10)
+#define DREQ_EMMC (11)
+#define DREQ_UART0_TX (12)
+#define DREQ_SD_HOST (13)
+#define DREQ_UART0_RX (14)
+#define DREQ_DSI1 (15)
+#define DREQ_SPI1_TX (16)
+#define DREQ_HDMI1 (17)
+#define DREQ_SPI1_RX (18)
+#define DREQ_UART3_TX_SPI4_TX (19)
+#define DREQ_UART3_RX_SPI4_RX (20)
+#define DREQ_UART5_TX_SPI5_TX (21)
+#define DREQ_UART5_RX_SPI5_RX (22)
+#define DREQ_SPI6_TX (23)
+#define DREQ_SCALER_FIFO0_SMI (24)
+#define DREQ_SCALER_FIFO1_SMI (25)
+#define DREQ_SCALER_FIFO2_SMI (26)
+#define DREQ_SPI6_RX (27)
+#define DREQ_UART2_TX (28)
+#define DREQ_UART2_RX (29)
+#define DREQ_UART4_TX (30)
+#define DREQ_UART4_RX (31)
+
+//IRQ
+#define DMA_INT15 (1 << 15)
+#define DMA_INT14 (1 << 14)
+#define DMA_INT13 (1 << 13)
+#define DMA_INT12 (1 << 12)
+#define DMA_INT11 (1 << 11)
+#define DMA_INT10 (1 << 10)
+#define DMA_INT9 (1 << 9)
+#define DMA_INT8 (1 << 8)
+#define DMA_INT7 (1 << 7)
+#define DMA_INT6 (1 << 6)
+#define DMA_INT5 (1 << 5)
+#define DMA_INT4 (1 << 4)
+#define DMA_INT3 (1 << 3)
+#define DMA_INT2 (1 << 2)
+#define DMA_INT1 (1 << 1)
+#define DMA_INT0 (1 << 0)
+
+//IRQ_NUMBER
+#define IRQ_DMA0 (96 + 16)
+#define IRQ_DMA1 (96 + 17)
+#define IRQ_DMA2 (96 + 18)
+#define IRQ_DMA3 (96 + 19)
+#define IRQ_DMA4 (96 + 20)
+#define IRQ_DMA5 (96 + 21)
+#define IRQ_DMA6 (96 + 22)
+#define IRQ_DMA7_DMA8 (96 + 23)
+#define IRQ_DMA9_DMA10 (96 + 24)
+#define IRQ_DMA11 (96 + 25)
+#define IRQ_DMA12 (96 + 26)
+#define IRQ_DMA13 (96 + 27)
+#define IRQ_DMA14 (96 + 28)
+#define IRQ_DMA15 (96 + 31)
+
+//CS
+#define DMA_CS_RESET (1 << 31)
+#define DMA_CS_ABORT (1 << 30)
+#define DMA_CS_DISDEBUG (1 << 29)
+#define DMA_CS_DREQ_STOPS_DMA (1 << 5)
+#define DMA_CS_PAUSED (1 << 4)
+#define DMA_CS_DREQ (1 << 3)
+#define DMA_CS_INT (1 << 2)
+#define DMA_CS_END (1 << 1)
+#define DMA_CS_ACTIVE (1 << 0)
+
+//CONBLK_AD
+//The address must be256-bit aligned, so the bottom 5 bits of the address mustbe zero.
+
+//TI
+//DMA Transfer Information.
+#define DMA_TI_SRC_IGNORE (1 << 11)
+#define DMA_TI_SRC_DREQ (1 << 10)
+#define DMA_TI_SRC_WIDTH (1 << 9)
+#define DMA_TI_SRC_INC (1 << 8)
+#define DMA_TI_DEST_IGNORE (1 << 7)
+#define DMA_TI_DEST_DREQ (1 << 6)
+#define DMA_TI_DEST_WIDTH (1 << 5)
+#define DMA_TI_DEST_INC (1 << 4)
+#define DMA_TI_WAIT_RESP (1 << 3)
+#define DMA_TI_TDMODE (1 << 1)
+#define DMA_TI_INTEN (1 << 0)
+
+//SOURCE_AD
+//DMA Source Address
+
+//DEST_AD
+//DMA Destination Address
+
+//TXFR_LEN
+//DMA Transfer Length
+
+void dma_init(unsigned char dch);
+rt_err_t dma_memcpy(void *src, void *dst, unsigned int size, unsigned int dch, unsigned int timeout);
+
+#endif
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_eth.c b/bsp/raspberry-pi/raspi4-32/driver/drv_eth.c
index a26c3c8519..a2f78ffd61 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/drv_eth.c
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_eth.c
@@ -19,6 +19,15 @@
#include "raspi4.h"
#include "drv_eth.h"
+//#define ETH_RX_POLL
+
+#define DBG_LEVEL DBG_LOG
+#include <rtdbg.h>
+#define LOG_TAG "drv.eth"
+
+static int link_speed = 0;
+static int link_flag = 0;
+
#define RECV_CACHE_BUF (1024)
#define SEND_DATA_NO_CACHE (0x08200000)
#define RECV_DATA_NO_CACHE (0x08400000)
@@ -34,6 +43,11 @@
#define BIT(nr) (1UL << (nr))
+static rt_thread_t link_thread_tid = RT_NULL;
+#define LINK_THREAD_STACK_SIZE (1024)
+#define LINK_THREAD_PRIORITY (20)
+#define LINK_THREAD_TIMESLICE (10)
+
static rt_uint32_t tx_index = 0;
static rt_uint32_t rx_index = 0;
static rt_uint32_t index_flag = 0;
@@ -54,6 +68,7 @@ struct rt_eth_dev
};
static struct rt_eth_dev eth_dev;
static struct rt_semaphore sem_lock;
+static struct rt_semaphore link_ack;
static inline rt_uint32_t read32(void *addr)
{
@@ -65,19 +80,36 @@ static inline void write32(void *addr, rt_uint32_t value)
(*((volatile unsigned int*)(addr))) = value;
}
-void eth_rx_irq(void *param)
+static void eth_rx_irq(int irq, void *param)
{
+#ifndef ETH_RX_POLL
+ rt_uint32_t val = 0;
+ val = read32(MAC_REG + GENET_INTRL2_CPU_STAT);
+ val &= ~read32(MAC_REG + GENET_INTRL2_CPU_STAT_MASK);
+ write32(MAC_REG + GENET_INTRL2_CPU_CLEAR, val);
+ if (val & GENET_IRQ_RXDMA_DONE)
+ {
+ eth_device_ready(&eth_dev.parent);
+ }
+
+ if (val & GENET_IRQ_TXDMA_DONE)
+ {
+ //todo
+ }
+#else
eth_device_ready(&eth_dev.parent);
+#endif
}
/* We only support RGMII (as used on the RPi4). */
static int bcmgenet_interface_set(void)
{
int phy_mode = PHY_INTERFACE_MODE_RGMII;
- switch (phy_mode) {
+ switch (phy_mode)
+ {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_RXID:
- write32(MAC_REG + SYS_PORT_CTRL,PORT_MODE_EXT_GPHY);
+ write32(MAC_REG + SYS_PORT_CTRL, PORT_MODE_EXT_GPHY);
break;
default:
rt_kprintf("unknown phy mode: %d\n", MAC_REG);
@@ -94,10 +126,10 @@ static void bcmgenet_umac_reset(void)
write32((MAC_REG + SYS_RBUF_FLUSH_CTRL), reg);
reg &= ~BIT(1);
- write32((MAC_REG + SYS_RBUF_FLUSH_CTRL),reg);
+ write32((MAC_REG + SYS_RBUF_FLUSH_CTRL), reg);
DELAY_MICROS(10);
- write32((MAC_REG + SYS_RBUF_FLUSH_CTRL),0);
+ write32((MAC_REG + SYS_RBUF_FLUSH_CTRL), 0);
DELAY_MICROS(10);
write32(MAC_REG + UMAC_CMD, 0);
write32(MAC_REG + UMAC_CMD, (CMD_SW_RESET | CMD_LCL_LOOP_EN));
@@ -145,7 +177,7 @@ static int bcmgenet_mdio_write(rt_uint32_t addr, rt_uint32_t reg, rt_uint32_t va
{
int count = 10000;
rt_uint32_t val;
- val = MDIO_WR | (addr << MDIO_PMD_SHIFT) |(reg << MDIO_REG_SHIFT) | (0xffff & value);
+ val = MDIO_WR | (addr << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT) | (0xffff & value);
write32(MAC_REG + MDIO_CMD, val);
rt_uint32_t reg_val = read32(MAC_REG + MDIO_CMD);
@@ -158,7 +190,6 @@ static int bcmgenet_mdio_write(rt_uint32_t addr, rt_uint32_t reg, rt_uint32_t va
reg_val = read32(MAC_REG + MDIO_CMD);
return reg_val & 0xffff;
-
}
static int bcmgenet_mdio_read(rt_uint32_t addr, rt_uint32_t reg)
@@ -179,7 +210,7 @@ static int bcmgenet_mdio_read(rt_uint32_t addr, rt_uint32_t reg)
reg_val = read32(MAC_REG + MDIO_CMD);
- return reg_val & 0xffff;
+ return reg_val & 0xffff;
}
static int bcmgenet_gmac_write_hwaddr(void)
@@ -207,9 +238,9 @@ static int get_ethernet_uid(void)
uid_low = bcmgenet_mdio_read(1, BCM54213PE_PHY_IDENTIFIER_LOW);
uid = (uid_high << 16 | uid_low);
- if(BCM54213PE_VERSION_B1 == uid)
+ if (BCM54213PE_VERSION_B1 == uid)
{
- rt_kprintf("version is B1\n");
+ LOG_I("version is B1\n");
}
return uid;
}
@@ -219,7 +250,7 @@ static void bcmgenet_mdio_init(void)
rt_uint32_t ret = 0;
/*get ethernet uid*/
ret = get_ethernet_uid();
- if(ret == 0)
+ if (ret == 0)
{
return;
}
@@ -236,19 +267,21 @@ static void bcmgenet_mdio_init(void)
/* read status reg */
bcmgenet_mdio_read(1, BCM54213PE_IEEE_EXTENDED_STATUS);
bcmgenet_mdio_read(1, BCM54213PE_AUTO_NEGOTIATION_ADV);
+
bcmgenet_mdio_read(1, BCM54213PE_MII_STATUS);
bcmgenet_mdio_read(1, BCM54213PE_CONTROL);
/* half full duplex capability */
bcmgenet_mdio_write(1, BCM54213PE_CONTROL, (CONTROL_HALF_DUPLEX_CAPABILITY | CONTROL_FULL_DUPLEX_CAPABILITY));
bcmgenet_mdio_read(1, BCM54213PE_MII_CONTROL);
+
/* set mii control */
- bcmgenet_mdio_write(1,BCM54213PE_MII_CONTROL,(MII_CONTROL_AUTO_NEGOTIATION_ENABLED | MII_CONTROL_AUTO_NEGOTIATION_RESTART| MII_CONTROL_PHY_FULL_DUPLEX| MII_CONTROL_SPEED_SELECTION));
+ bcmgenet_mdio_write(1, BCM54213PE_MII_CONTROL, (MII_CONTROL_AUTO_NEGOTIATION_ENABLED | MII_CONTROL_AUTO_NEGOTIATION_RESTART | MII_CONTROL_PHY_FULL_DUPLEX | MII_CONTROL_SPEED_SELECTION));
}
static void rx_ring_init(void)
{
write32(MAC_REG + RDMA_REG_BASE + DMA_SCB_BURST_SIZE, DMA_MAX_BURST_LENGTH);
- write32(MAC_REG + RDMA_RING_REG_BASE + DMA_START_ADDR,0x0 );
+ write32(MAC_REG + RDMA_RING_REG_BASE + DMA_START_ADDR, 0x0);
write32(MAC_REG + RDMA_READ_PTR, 0x0);
write32(MAC_REG + RDMA_WRITE_PTR, 0x0);
write32(MAC_REG + RDMA_RING_REG_BASE + DMA_END_ADDR, RX_DESCS * DMA_DESC_SIZE / 4 - 1);
@@ -257,7 +290,7 @@ static void rx_ring_init(void)
write32(MAC_REG + RDMA_CONS_INDEX, 0x0);
write32(MAC_REG + RDMA_RING_REG_BASE + DMA_RING_BUF_SIZE, (RX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH);
write32(MAC_REG + RDMA_XON_XOFF_THRESH, DMA_FC_THRESH_VALUE);
- write32(MAC_REG + RDMA_REG_BASE + DMA_RING_CFG,1 << DEFAULT_Q);
+ write32(MAC_REG + RDMA_REG_BASE + DMA_RING_CFG, 1 << DEFAULT_Q);
}
static void tx_ring_init(void)
@@ -268,13 +301,13 @@ static void tx_ring_init(void)
write32(MAC_REG + TDMA_READ_PTR, 0x0);
write32(MAC_REG + TDMA_READ_PTR, 0x0);
write32(MAC_REG + TDMA_WRITE_PTR, 0x0);
- write32(MAC_REG + TDMA_RING_REG_BASE + DMA_END_ADDR,TX_DESCS * DMA_DESC_SIZE / 4 - 1);
+ write32(MAC_REG + TDMA_RING_REG_BASE + DMA_END_ADDR, TX_DESCS * DMA_DESC_SIZE / 4 - 1);
write32(MAC_REG + TDMA_PROD_INDEX, 0x0);
write32(MAC_REG + TDMA_CONS_INDEX, 0x0);
- write32(MAC_REG + TDMA_RING_REG_BASE + DMA_MBUF_DONE_THRESH,0x1);
- write32(MAC_REG + TDMA_FLOW_PERIOD,0x0);
+ write32(MAC_REG + TDMA_RING_REG_BASE + DMA_MBUF_DONE_THRESH, 0x1);
+ write32(MAC_REG + TDMA_FLOW_PERIOD, 0x0);
write32(MAC_REG + TDMA_RING_REG_BASE + DMA_RING_BUF_SIZE, (TX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH);
- write32(MAC_REG + TDMA_REG_BASE + DMA_RING_CFG,1 << DEFAULT_Q);
+ write32(MAC_REG + TDMA_REG_BASE + DMA_RING_CFG, 1 << DEFAULT_Q);
}
static void rx_descs_init(void)
@@ -284,55 +317,21 @@ static void rx_descs_init(void)
void *desc_base = (void *)RX_DESC_BASE;
len_stat = (RX_BUF_LENGTH << DMA_BUFLENGTH_SHIFT) | DMA_OWN;
- for (i = 0; i < RX_DESCS; i++) {
- write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_LO), lower_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]));
- write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_HI),upper_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]));
- write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_LENGTH_STATUS),len_stat);
- }
-}
-
-static int phy_startup(void)
-{
- int count = 1000000;
- while ((bcmgenet_mdio_read(1, BCM54213PE_MII_STATUS) & MII_STATUS_LINK_UP) && (--count))
- DELAY_MICROS(1);
- if(count > 0)
- {
- rt_kprintf("bcmgenet: PHY startup ok!\n");
- }
- else
+ for (i = 0; i < RX_DESCS; i++)
{
- rt_kprintf("bcmgenet: PHY startup err!\n");
- return 1;
- }
-
- if(bcmgenet_mdio_read(1, BCM54213PE_STATUS) == 0)
- {
- //todo
- }
- else
- {
- rt_kprintf("bcmgenet: BCM54213PE_STATUS err!\n");
- }
-
- if(bcmgenet_mdio_read(1, BCM54213PE_CONTROL) == (CONTROL_FULL_DUPLEX_CAPABILITY| CONTROL_HALF_DUPLEX_CAPABILITY))
- {
- //todo
- }
- else
- {
- rt_kprintf("bcmgenet: BCM54213PE_CONTROL err!\n");
+ write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_LO), lower_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]));
+ write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_ADDRESS_HI), upper_32_bits((uintptr_t)&rxbuffs[i * RX_BUF_LENGTH]));
+ write32((desc_base + i * DMA_DESC_SIZE + DMA_DESC_LENGTH_STATUS), len_stat);
}
-
- return 0;
}
static int bcmgenet_adjust_link(void)
{
rt_uint32_t speed;
- rt_uint32_t phy_dev_speed = SPEED_100;
-
- switch (phy_dev_speed) {
+ rt_uint32_t phy_dev_speed = link_speed;
+
+ switch (phy_dev_speed)
+ {
case SPEED_1000:
speed = UMAC_SPEED_1000;
break;
@@ -358,6 +357,14 @@ static int bcmgenet_adjust_link(void)
return 0;
}
+void link_irq(void *param)
+{
+ if ((bcmgenet_mdio_read(1, BCM54213PE_MII_STATUS) & MII_STATUS_LINK_UP) != 0)
+ {
+ rt_sem_release(&link_ack);
+ }
+}
+
static int bcmgenet_gmac_eth_start(void)
{
rt_uint32_t ret;
@@ -375,23 +382,17 @@ static int bcmgenet_gmac_eth_start(void)
/* Enable RX/TX DMA */
bcmgenet_enable_dma();
- /* read PHY properties over the wire from generic PHY set-up */
- ret = phy_startup();
- if (ret) {
- rt_kprintf("bcmgenet: PHY startup failed: %d\n", ret);
- return ret;
- }
-
/* Update MAC registers based on PHY property */
ret = bcmgenet_adjust_link();
- if (ret) {
+ if(ret)
+ {
rt_kprintf("bcmgenet: adjust PHY link failed: %d\n", ret);
return ret;
}
/* wait tx index clear */
while ((read32(MAC_REG + TDMA_CONS_INDEX) != 0) && (--count))
- DELAY_MICROS(1);
+ DELAY_MICROS(1);
tx_index = read32(MAC_REG + TDMA_CONS_INDEX);
write32(MAC_REG + TDMA_PROD_INDEX, tx_index);
@@ -410,6 +411,8 @@ static int bcmgenet_gmac_eth_start(void)
rx_tx_en |= (CMD_TX_EN | CMD_RX_EN);
write32(MAC_REG + UMAC_CMD, rx_tx_en);
+ //IRQ
+ write32(MAC_REG + GENET_INTRL2_CPU_CLEAR_MASK, GENET_IRQ_TXDMA_DONE | GENET_IRQ_RXDMA_DONE);
return 0;
}
@@ -424,6 +427,7 @@ static rt_uint32_t bcmgenet_gmac_eth_recv(rt_uint8_t **packetp)
if(prod_index == index_flag)
{
cur_recv_cnt = index_flag;
+ index_flag = 0x7fffffff;
//no buff
return 0;
}
@@ -433,7 +437,7 @@ static rt_uint32_t bcmgenet_gmac_eth_recv(rt_uint8_t **packetp)
{
return 0;
}
-
+
desc_base = RX_DESC_BASE + rx_index * DMA_DESC_SIZE;
length = read32(desc_base + DMA_DESC_LENGTH_STATUS);
length = (length >> DMA_BUFLENGTH_SHIFT) & DMA_BUFLENGTH_MASK;
@@ -452,6 +456,11 @@ static rt_uint32_t bcmgenet_gmac_eth_recv(rt_uint8_t **packetp)
write32(MAC_REG + RDMA_CONS_INDEX, cur_recv_cnt);
cur_recv_cnt = cur_recv_cnt + 1;
+
+ if(cur_recv_cnt > 0xffff)
+ {
+ cur_recv_cnt = 0;
+ }
prev_recv_cnt = cur_recv_cnt;
return length;
@@ -460,52 +469,120 @@ static rt_uint32_t bcmgenet_gmac_eth_recv(rt_uint8_t **packetp)
static int bcmgenet_gmac_eth_send(void *packet, int length)
{
- void* desc_base = (TX_DESC_BASE + tx_index * DMA_DESC_SIZE);
+ void *desc_base = (TX_DESC_BASE + tx_index * DMA_DESC_SIZE);
rt_uint32_t len_stat = length << DMA_BUFLENGTH_SHIFT;
rt_uint32_t prod_index, cons;
rt_uint32_t tries = 100;
-
+
prod_index = read32(MAC_REG + TDMA_PROD_INDEX);
len_stat |= 0x3F << DMA_TX_QTAG_SHIFT;
len_stat |= DMA_TX_APPEND_CRC | DMA_SOP | DMA_EOP;
- write32((desc_base + DMA_DESC_ADDRESS_LO),SEND_DATA_NO_CACHE);
- write32((desc_base + DMA_DESC_ADDRESS_HI),0);
- write32((desc_base + DMA_DESC_LENGTH_STATUS),len_stat);
+ write32((desc_base + DMA_DESC_ADDRESS_LO), SEND_DATA_NO_CACHE);
+ write32((desc_base + DMA_DESC_ADDRESS_HI), 0);
+ write32((desc_base + DMA_DESC_LENGTH_STATUS), len_stat);
+
+ tx_index = tx_index + 1;
+ prod_index = prod_index + 1;
+
+ if (prod_index == 0xe000)
+ {
+ write32(MAC_REG + TDMA_PROD_INDEX, 0);
+ prod_index = 0;
+ }
- if(++tx_index>= TX_DESCS)
+ if (tx_index == 256)
{
tx_index = 0;
}
- prod_index++;
+
/* Start Transmisson */
- write32(MAC_REG + TDMA_PROD_INDEX,prod_index);
+ write32(MAC_REG + TDMA_PROD_INDEX, prod_index);
- do {
+ do
+ {
cons = read32(MAC_REG + TDMA_CONS_INDEX);
} while ((cons & 0xffff) < prod_index && --tries);
+
if (!tries)
{
+ rt_kprintf("send err! tries is %d\n", tries);
return -1;
}
return 0;
}
-static rt_err_t bcmgenet_eth_init(rt_device_t device)
+static void link_task_entry(void *param)
{
- struct eth_device *eth_device = (struct eth_device *)device;
+ struct eth_device *eth_device = (struct eth_device *)param;
RT_ASSERT(eth_device != RT_NULL);
+ struct rt_eth_dev *dev = &eth_dev;
+ //start mdio
+ bcmgenet_mdio_init();
+ //start timer link
+ rt_timer_init(&dev->link_timer, "link_timer",
+ link_irq,
+ NULL,
+ 100,
+ RT_TIMER_FLAG_PERIODIC);
+ rt_timer_start(&dev->link_timer);
+
+ //link wait forever
+ rt_sem_take(&link_ack, RT_WAITING_FOREVER);
+ eth_device_linkchange(&eth_dev.parent, RT_TRUE); //link up
+ rt_timer_stop(&dev->link_timer);
+
+ //set mac
+ bcmgenet_gmac_write_hwaddr();
+ bcmgenet_gmac_write_hwaddr();
+
+ //check link speed
+ if ((bcmgenet_mdio_read(1, BCM54213PE_STATUS) & (1 << 10)) || (bcmgenet_mdio_read(1, BCM54213PE_STATUS) & (1 << 11)))
+ {
+ link_speed = 1000;
+ rt_kprintf("Support link mode Speed 1000M\n");
+ }
+ else if ((bcmgenet_mdio_read(1, 0x05) & (1 << 7)) || (bcmgenet_mdio_read(1, 0x05) & (1 << 8)) || (bcmgenet_mdio_read(1, 0x05) & (1 << 9)))
+ {
+ link_speed = 100;
+ rt_kprintf("Support link mode Speed 100M\n");
+ }
+ else
+ {
+ link_speed = 10;
+ rt_kprintf("Support link mode Speed 10M\n");
+ }
+
+ bcmgenet_gmac_eth_start();
+ //irq or poll
+#ifdef ETH_RX_POLL
+ rt_timer_init(&dev->rx_poll_timer, "rx_poll_timer",
+ eth_rx_irq,
+ NULL,
+ 1,
+ RT_TIMER_FLAG_PERIODIC);
+
+ rt_timer_start(&dev->rx_poll_timer);
+#else
+ rt_hw_interrupt_install(ETH_IRQ, eth_rx_irq, NULL, "eth_irq");
+ rt_hw_interrupt_umask(ETH_IRQ);
+#endif
+ link_flag = 1;
+}
+
+static rt_err_t bcmgenet_eth_init(rt_device_t device)
+{
rt_uint32_t ret = 0;
rt_uint32_t hw_reg = 0;
- struct rt_eth_dev *dev = &eth_dev;
-
+
/* Read GENET HW version */
rt_uint8_t major = 0;
hw_reg = read32(MAC_REG + SYS_REV_CTRL);
major = (hw_reg >> 24) & 0x0f;
- if (major != 6) {
+ if (major != 6)
+ {
if (major == 5)
major = 4;
else if (major == 0)
@@ -514,13 +591,12 @@ static rt_err_t bcmgenet_eth_init(rt_device_t device)
rt_kprintf("Uns upported GENETv%d.%d\n", major, (hw_reg >> 16) & 0x0f);
return RT_ERROR;
}
-
/* set interface */
ret = bcmgenet_interface_set();
if (ret)
{
return ret;
- }
+ }
/* rbuf clear */
write32(MAC_REG + SYS_RBUF_FLUSH_CTRL, 0);
@@ -530,21 +606,11 @@ static rt_err_t bcmgenet_eth_init(rt_device_t device)
/* issue soft reset with (rg)mii loopback to ensure a stable rxclk */
write32(MAC_REG + UMAC_CMD, CMD_SW_RESET | CMD_LCL_LOOP_EN);
- bcmgenet_mdio_init();
-
- bcmgenet_gmac_write_hwaddr();
- bcmgenet_gmac_write_hwaddr();
-
- bcmgenet_gmac_eth_start();
-
- //irq or poll
- rt_timer_init(&dev->rx_poll_timer, "rx_poll_timer",
- eth_rx_irq,
- NULL,
- 1,
- RT_TIMER_FLAG_PERIODIC);
-
- rt_timer_start(&dev->rx_poll_timer);
+ link_thread_tid = rt_thread_create("link", link_task_entry, (void *)device,
+ LINK_THREAD_STACK_SIZE,
+ LINK_THREAD_PRIORITY, LINK_THREAD_TIMESLICE);
+ if (link_thread_tid != RT_NULL)
+ rt_thread_startup(link_thread_tid);
return RT_EOK;
}
@@ -554,10 +620,12 @@ static rt_err_t bcmgenet_eth_control(rt_device_t dev, int cmd, void *args)
switch (cmd)
{
case NIOCTL_GADDR:
- if (args) rt_memcpy(args, eth_dev.dev_addr, 6);
- else return -RT_ERROR;
+ if (args)
+ rt_memcpy(args, eth_dev.dev_addr, 6);
+ else
+ return -RT_ERROR;
break;
- default :
+ default:
break;
}
return RT_EOK;
@@ -565,15 +633,17 @@ static rt_err_t bcmgenet_eth_control(rt_device_t dev, int cmd, void *args)
rt_err_t rt_eth_tx(rt_device_t device, struct pbuf *p)
{
- rt_uint32_t sendbuf = SEND_DATA_NO_CACHE;
+ rt_uint32_t sendbuf = (rt_uint32_t)SEND_DATA_NO_CACHE;
/* lock eth device */
- rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
- //struct rt_eth_dev *dev = (struct rt_eth_dev *) device;
- pbuf_copy_partial(p, (void *)&send_cache_pbuf[0], p->tot_len, 0);
- rt_memcpy((void *)sendbuf, send_cache_pbuf, p->tot_len);
+ if (link_flag == 1)
+ {
+ rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+ pbuf_copy_partial(p, (void *)&send_cache_pbuf[0], p->tot_len, 0);
+ rt_memcpy((void *)sendbuf, send_cache_pbuf, p->tot_len);
- bcmgenet_gmac_eth_send((void *)sendbuf, p->tot_len);
- rt_sem_release(&sem_lock);
+ bcmgenet_gmac_eth_send((void *)sendbuf, p->tot_len);
+ rt_sem_release(&sem_lock);
+ }
return RT_EOK;
}
@@ -583,16 +653,17 @@ struct pbuf *rt_eth_rx(rt_device_t device)
int recv_len = 0;
rt_uint32_t addr_point[8];
struct pbuf *pbuf = RT_NULL;
- rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
-
- recv_len = bcmgenet_gmac_eth_recv((rt_uint8_t **)&addr_point[0]);
-
- if(recv_len > 0)
+ if (link_flag == 1)
{
- pbuf = pbuf_alloc(PBUF_LINK, recv_len, PBUF_RAM);
- rt_memcpy(pbuf->payload, (char *)addr_point[0], recv_len);
+ rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
+ recv_len = bcmgenet_gmac_eth_recv((rt_uint8_t **)&addr_point[0]);
+ if (recv_len > 0)
+ {
+ pbuf = pbuf_alloc(PBUF_LINK, recv_len, PBUF_RAM);
+ rt_memcpy(pbuf->payload, (char *)addr_point[0], recv_len);
+ }
+ rt_sem_release(&sem_lock);
}
- rt_sem_release(&sem_lock);
return pbuf;
}
@@ -601,11 +672,11 @@ int rt_hw_eth_init(void)
rt_uint8_t mac_addr[6];
rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
+ rt_sem_init(&link_ack, "link_ack", 0, RT_IPC_FLAG_FIFO);
memset(&eth_dev, 0, sizeof(eth_dev));
memset((void *)SEND_DATA_NO_CACHE, 0, sizeof(DMA_DISC_ADDR_SIZE));
memset((void *)RECV_DATA_NO_CACHE, 0, sizeof(DMA_DISC_ADDR_SIZE));
-
bcm271x_mbox_hardware_get_mac_address(&mac_addr[0]);
eth_dev.iobase = MAC_REG;
@@ -629,9 +700,8 @@ int rt_hw_eth_init(void)
eth_dev.parent.eth_tx = rt_eth_tx;
eth_dev.parent.eth_rx = rt_eth_rx;
-
eth_device_init(&(eth_dev.parent), "e0");
- eth_device_linkchange(&eth_dev.parent, RT_TRUE); //linkup the e0 for lwip to check
+ eth_device_linkchange(&eth_dev.parent, RT_FALSE); //link down
return 0;
}
INIT_COMPONENT_EXPORT(rt_hw_eth_init);
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_eth.h b/bsp/raspberry-pi/raspi4-32/driver/drv_eth.h
index 708e626975..f7916ee5e1 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/drv_eth.h
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_eth.h
@@ -53,6 +53,17 @@
#define MDIO_REG_SHIFT (16)
#define MDIO_REG_MASK (0x1f)
+#define GENET_INTRL2_OFF (0x0200)
+#define GENET_INTRL2_CPU_STAT (GENET_INTRL2_OFF + 0x00)
+#define GENET_INTRL2_CPU_CLEAR (GENET_INTRL2_OFF + 0x08)
+#define GENET_INTRL2_CPU_STAT_MASK (GENET_INTRL2_OFF + 0x0c)
+#define GENET_INTRL2_CPU_SET_MASK (GENET_INTRL2_OFF + 0x10)
+#define GENET_INTRL2_CPU_CLEAR_MASK (GENET_INTRL2_OFF + 0x14)
+#define GENET_IRQ_MDIO_ERROR BIT(24)
+#define GENET_IRQ_MDIO_DONE BIT(23)
+#define GENET_IRQ_TXDMA_DONE BIT(16)
+#define GENET_IRQ_RXDMA_DONE BIT(13)
+
#define CMD_TX_EN BIT(0)
#define CMD_RX_EN BIT(1)
#define UMAC_SPEED_10 (0)
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_i2c.c b/bsp/raspberry-pi/raspi4-32/driver/drv_i2c.c
new file mode 100644
index 0000000000..f596eccc89
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_i2c.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-28 bigmagic first version
+ */
+
+#include "drv_i2c.h"
+#include "drv_gpio.h"
+#include "raspi4.h"
+#include "mbox.h"
+
+/*
+* (3.3v) -1 2-
+* (SDA1/SDA3) -3 4-
+* (SCL1/SCL3) -5 6-
+* (SDA3) -7 8-
+* -9 10-
+* -11 12-
+* -13 14-
+* -15 16-
+* -17 18-
+* -19 20-
+* (SCL4) -21 22-
+* -23 24- (SDA4)
+* -25 26- (SCL4)
+* -27 28-
+* (SCL3) -29 30-
+* (SDA4) -31 32-
+*/
+
+#define DBG_TAG "drv.i2c"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+struct raspi_i2c_hw_config
+{
+ rt_uint32_t bsc_num;
+ rt_uint32_t bsc_rate;
+ rt_uint32_t bsc_address;
+ rt_uint32_t sda_pin;
+ rt_uint32_t scl_pin;
+ rt_uint32_t sda_mode;
+ rt_uint32_t scl_mode;
+};
+
+rt_uint8_t i2c_read_or_write(volatile rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len, rt_uint8_t flag)
+{
+ rt_uint32_t status;
+ rt_uint32_t remaining = len;
+ rt_uint32_t i = 0;
+ rt_uint8_t reason = I2C_REASON_OK;
+
+ /* Clear FIFO */
+ BSC_C(base) |= (BSC_C_CLEAR_1 & BSC_C_CLEAR_1);
+ /* Clear Status */
+ BSC_S(base) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE;
+ /* Set Data Length */
+ BSC_DLEN(base) = len;
+ if (flag)
+ {
+ /* Start read */
+ BSC_C(base) = BSC_C_I2CEN | BSC_C_ST | BSC_C_READ;
+ /* wait for transfer to complete */
+ while (!(BSC_S(base) & BSC_S_DONE))
+ {
+ /* we must empty the FIFO as it is populated and not use any delay */
+ while (remaining && (BSC_S(base) & BSC_S_RXD))
+ {
+ /* Read from FIFO, no barrier */
+ buf[i] = BSC_FIFO(base);
+ i++;
+ remaining--;
+ }
+ }
+ /* transfer has finished - grab any remaining stuff in FIFO */
+ while (remaining && (BSC_S(base) & BSC_S_RXD))
+ {
+ /* Read from FIFO, no barrier */
+ buf[i] = BSC_FIFO(base);
+ i++;
+ remaining--;
+ }
+ }
+ else
+ {
+ LOG_D("i2c%d write start", flag);
+ /* pre populate FIFO with max buffer */
+ while (remaining && (i < BSC_FIFO_SIZE))
+ {
+ BSC_FIFO(base) = buf[i];
+ i++;
+ remaining--;
+ }
+
+ /* Enable device and start transfer */
+ BSC_C(base) = BSC_C_I2CEN | BSC_C_ST;
+
+ /* Transfer is over when BCM2835_BSC_S_DONE */
+ while (!(BSC_S(base) & BSC_S_DONE))
+ {
+ while (remaining && (BSC_S(base) & BSC_S_TXD))
+ {
+ /* Write to FIFO */
+ BSC_FIFO(base) = buf[i];
+ i++;
+ remaining--;
+ }
+ }
+ LOG_D("i2c%d write end", flag);
+ }
+
+ status = BSC_S(base);
+ if (status & BSC_S_ERR)
+ {
+ reason = I2C_REASON_ERROR_NACK;
+ }
+ else if (status & BSC_S_CLKT)
+ {
+ reason = I2C_REASON_ERROR_CLKT;
+ }
+ else if (remaining)
+ {
+ reason = I2C_REASON_ERROR_DATA;
+ }
+ BSC_C(base) |= (BSC_S_DONE & BSC_S_DONE);
+
+ return reason;
+}
+
+static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
+ struct rt_i2c_msg msgs[],
+ rt_uint32_t num)
+{
+ rt_size_t i;
+ rt_uint8_t reason;
+ RT_ASSERT(bus != RT_NULL);
+
+ struct raspi_i2c_hw_config *i2c_hw_config = (struct raspi_i2c_hw_config*)(bus->priv);
+
+ //Slave Address
+ BSC_A(i2c_hw_config->bsc_address) = msgs->addr;
+
+ for (i = 0; i < num; i++)
+ {
+ if (msgs[i].flags & RT_I2C_RD)
+ reason = i2c_read_or_write(i2c_hw_config->bsc_address, msgs->buf, msgs->len, 1);
+ else
+ reason = i2c_read_or_write(i2c_hw_config->bsc_address, msgs->buf, msgs->len, 0);
+ }
+ return (reason == 0)? i : 0;
+}
+
+static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
+ struct rt_i2c_msg msgs[],
+ rt_uint32_t num)
+{
+ return 0;
+}
+
+static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus,
+ rt_uint32_t cmd,
+ rt_uint32_t arg)
+{
+ return RT_EOK;
+}
+
+
+static rt_err_t raspi_i2c_configure(struct raspi_i2c_hw_config *cfg)
+{
+ RT_ASSERT(cfg != RT_NULL);
+ rt_uint32_t apb_clock = 0;
+ prev_raspi_pin_mode(cfg->sda_pin, cfg->sda_mode);//sda
+ prev_raspi_pin_mode(cfg->scl_pin, cfg->scl_mode);//scl
+ /* use 0xFFFE mask to limit a max value and round down any odd number */
+ apb_clock = bcm271x_mbox_clock_get_rate(CORE_CLK_ID);
+ rt_uint32_t divider = (apb_clock / cfg->bsc_rate) & 0xFFFE;
+
+ BSC_DIV(cfg->bsc_address) = (rt_uint16_t)divider;
+
+ return RT_EOK;
+}
+
+static const struct rt_i2c_bus_device_ops raspi_i2c_ops =
+{
+ .master_xfer = raspi_i2c_mst_xfer,
+ .slave_xfer = raspi_i2c_slv_xfer,
+ .i2c_bus_control = raspi_i2c_bus_control,
+};
+
+#if defined (BSP_USING_I2C0)
+#define I2C0_BUS_NAME "i2c0"
+static struct raspi_i2c_hw_config hw_device0 =
+{
+ .bsc_num = 0,
+ .bsc_rate = 100000,//100k
+ .bsc_address = BSC0_BASE,
+ .sda_pin = GPIO_PIN_0,
+ .scl_pin = GPIO_PIN_1,
+ .sda_mode = ALT0,
+ .scl_mode = ALT0,
+};
+
+struct rt_i2c_bus_device device0 =
+{
+ .ops = &raspi_i2c_ops,
+ .priv = (void *)&hw_device0,
+};
+#endif
+
+#if defined (BSP_USING_I2C1)
+#define I2C1_BUS_NAME "i2c1"
+static struct raspi_i2c_hw_config hw_device1 =
+{
+ .bsc_num = 1,
+ .bsc_rate = 100000,//100k
+ .bsc_address = BSC1_BASE,
+ .sda_pin = GPIO_PIN_2,
+ .scl_pin = GPIO_PIN_3,
+ .sda_mode = ALT0,
+ .scl_mode = ALT0,
+};
+
+struct rt_i2c_bus_device device1 =
+{
+ .ops = &raspi_i2c_ops,
+ .priv = (void *)&hw_device1,
+};
+#endif
+
+#if defined (BSP_USING_I2C3)
+#define I2C3_BUS_NAME "i2c3"
+static struct raspi_i2c_hw_config hw_device3 =
+{
+ .bsc_num = 3,
+ .bsc_rate = 100000,//100k
+ .bsc_address = BSC3_BASE,
+#ifndef BSP_USING_I2C3_0
+ .sda_pin = GPIO_PIN_2,
+ .scl_pin = GPIO_PIN_3,
+#else
+ .sda_pin = GPIO_PIN_4,
+ .scl_pin = GPIO_PIN_5,
+#endif
+ .sda_mode = ALT5,
+ .scl_mode = ALT5,
+};
+
+struct rt_i2c_bus_device device3 =
+{
+ .ops = &raspi_i2c_ops,
+ .priv = (void *)&hw_device3,
+};
+#endif
+
+#if defined (BSP_USING_I2C4)
+#define I2C4_BUS_NAME "i2c4"
+static struct raspi_i2c_hw_config hw_device4 =
+{
+ .bsc_num = 4,
+ .bsc_rate = 100000,//100k
+ .bsc_address = BSC4_BASE,
+#ifdef BSP_USING_I2C4_0
+ .sda_pin = GPIO_PIN_6,
+ .scl_pin = GPIO_PIN_7,
+#else
+ .sda_pin = GPIO_PIN_8,
+ .scl_pin = GPIO_PIN_9,
+#endif
+ .sda_mode = ALT5,
+ .scl_mode = ALT5,
+};
+
+struct rt_i2c_bus_device device4 =
+{
+ .ops = &raspi_i2c_ops,
+ .priv = (void *)&hw_device4,
+};
+#endif
+
+#if defined (BSP_USING_I2C5)
+#define I2C5_BUS_NAME "i2c5"
+static struct raspi_i2c_hw_config hw_device5 =
+{
+ .bsc_num = 5,
+ .bsc_rate = 100000,//100k
+ .bsc_address = BSC5_BASE,
+#ifdef BSP_USING_I2C5_0
+ .sda_pin = GPIO_PIN_10,
+ .scl_pin = GPIO_PIN_11,
+#else
+ .sda_pin = GPIO_PIN_12,
+ .scl_pin = GPIO_PIN_13,
+#endif
+ .sda_mode = ALT5,
+ .scl_mode = ALT5,
+};
+
+struct rt_i2c_bus_device device5 =
+{
+ .ops = &raspi_i2c_ops,
+ .priv = (void *)&hw_device5,
+};
+#endif
+
+#if defined (BSP_USING_I2C6)
+#define I2C6_BUS_NAME "i2c6"
+static struct raspi_i2c_hw_config hw_device6 =
+{
+ .bsc_num = 6,
+ .bsc_rate = 100000,//100k
+ .bsc_address = BSC6_BASE,
+#ifdef BSP_USING_I2C5_0
+ .sda_pin = GPIO_PIN_0,
+ .scl_pin = GPIO_PIN_1,
+#else
+ .sda_pin = GPIO_PIN_22,
+ .scl_pin = GPIO_PIN_23,
+#endif
+ .sda_mode = ALT5,
+ .scl_mode = ALT5,
+};
+
+struct rt_i2c_bus_device device6 =
+{
+ .ops = &raspi_i2c_ops,
+ .priv = (void *)&hw_device6,
+};
+#endif
+
+int rt_hw_i2c_init(void)
+{
+#if defined(BSP_USING_I2C0)
+ raspi_i2c_configure(&hw_device0);
+ rt_i2c_bus_device_register(&device0, I2C0_BUS_NAME);
+#endif
+
+#if defined(BSP_USING_I2C1)
+ raspi_i2c_configure(&hw_device1);
+ rt_i2c_bus_device_register(&device1, I2C1_BUS_NAME);
+#endif
+
+#if defined(BSP_USING_I2C3)
+ raspi_i2c_configure(&hw_device3);
+ rt_i2c_bus_device_register(&device3, I2C3_BUS_NAME);
+#endif
+
+#if defined(BSP_USING_I2C4)
+ raspi_i2c_configure(&hw_device4);
+ rt_i2c_bus_device_register(&device4, I2C4_BUS_NAME);
+#endif
+
+#if defined(BSP_USING_I2C5)
+ raspi_i2c_configure(&hw_device5);
+ rt_i2c_bus_device_register(&device5, I2C5_BUS_NAME);
+#endif
+
+#if defined(BSP_USING_I2C6)
+ raspi_i2c_configure(&hw_device6);
+ rt_i2c_bus_device_register(&device6, I2C6_BUS_NAME);
+#endif
+ return 0;
+}
+
+INIT_DEVICE_EXPORT(rt_hw_i2c_init);
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_i2c.h b/bsp/raspberry-pi/raspi4-32/driver/drv_i2c.h
new file mode 100644
index 0000000000..e02c8887f0
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_i2c.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-28 bigmagic first version
+ */
+
+#ifndef __DRV_I2C_H__
+#define __DRV_I2C_H__
+
+#include <rthw.h>
+
+#define BSC_C(BASE) __REG32(BASE + 0x0000) /* BSC Master Control */
+#define BSC_S(BASE) __REG32(BASE + 0x0004) /* BSC Master Status */
+#define BSC_DLEN(BASE) __REG32(BASE + 0x0008) /* BSC Master Data Length */
+#define BSC_A(BASE) __REG32(BASE + 0x000c) /* BSC Master Slave Address */
+#define BSC_FIFO(BASE) __REG32(BASE + 0x0010) /* BSC Master Data FIFO */
+#define BSC_DIV(BASE) __REG32(BASE + 0x0014) /* BSC Master Clock Divider */
+#define BSC_DEL(BASE) __REG32(BASE + 0x0018) /* BSC Master Data Delay */
+#define BSC_CLKT(BASE) __REG32(BASE + 0x001c) /* BSC Master Clock Stretch Timeout */
+
+/* Register masks for C Register */
+#define BSC_C_I2CEN (0x00008000) /* I2C Enable, 0 = disabled, 1 = enabled */
+#define BSC_C_INTR (0x00000400) /* Interrupt on RX */
+#define BSC_C_INTT (0x00000200) /* Interrupt on TX */
+#define BSC_C_INTD (0x00000100) /* Interrupt on DONE */
+#define BSC_C_ST (0x00000080) /* Start transfer, 1 = Start a new transfer */
+#define BSC_C_CLEAR_1 (0x00000020) /* Clear FIFO Clear */
+#define BSC_C_CLEAR_2 (0x00000010) /* Clear FIFO Clear */
+#define BSC_C_READ (0x00000001) /* Read transfer */
+
+/* Register masks for S Register */
+#define BSC_S_CLKT (0x00000200) /* Clock stretch timeout */
+#define BSC_S_ERR (0x00000100) /* ACK error */
+#define BSC_S_RXF (0x00000080) /* RXF FIFO full, 0 = FIFO is not full, 1 = FIFO is full */
+#define BSC_S_TXE (0x00000040) /* TXE FIFO full, 0 = FIFO is not full, 1 = FIFO is full */
+#define BSC_S_RXD (0x00000020) /* RXD FIFO contains data */
+#define BSC_S_TXD (0x00000010) /* TXD FIFO can accept data */
+#define BSC_S_RXR (0x00000008) /* RXR FIFO needs reading (full) */
+#define BSC_S_TXW (0x00000004) /* TXW FIFO needs writing (full) */
+#define BSC_S_DONE (0x00000002) /* Transfer DONE */
+#define BSC_S_TA (0x00000001) /* Transfer Active */
+
+#define BSC_FIFO_SIZE (16) /* BSC FIFO size */
+
+typedef enum
+{
+ I2C_REASON_OK = 0x00, /* Success */
+ I2C_REASON_ERROR_NACK = 0x01, /* Received a NACK */
+ I2C_REASON_ERROR_CLKT = 0x02, /* Received Clock Stretch Timeout */
+ I2C_REASON_ERROR_DATA = 0x04 /* Not all data is sent / received */
+} i2c_reason_codes;
+
+int rt_hw_i2c_init(void);
+
+#endif
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_sdio.c b/bsp/raspberry-pi/raspi4-32/driver/drv_sdio.c
index 8d34f3ab73..4d88668eee 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/drv_sdio.c
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_sdio.c
@@ -103,8 +103,8 @@ rt_err_t sd_int(struct sdhci_pdata_t * pdat, rt_uint32_t mask)
{
write32(pdat->virt + EMMC_INTERRUPT, r);
//qemu maybe can not use sdcard
- //rt_kprintf("send cmd/data timeout wait for %x int: %x, status: %x\n",mask, r, read32(pdat->virt + EMMC_STATUS));
- //return -RT_ETIMEOUT;
+ rt_kprintf("send cmd/data timeout wait for %x int: %x, status: %x\n",mask, r, read32(pdat->virt + EMMC_STATUS));
+ return -RT_ETIMEOUT;
}
else if (r & INT_ERROR_MASK)
{
@@ -552,9 +552,8 @@ static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat)
// Clear control2
write32(pdat->virt + EMMC_CONTROL2, 0);
-
- // Get the base clock rate
- mmc_base_clock = bcm271x_mbox_clock_get_rate(12);
+ // Get the base clock rate //12
+ mmc_base_clock = bcm271x_mbox_clock_get_rate(EMMC_CLK_ID);
if(mmc_base_clock == 0)
{
rt_kprintf("EMMC: assuming clock rate to be 100MHz\n");
@@ -590,7 +589,6 @@ int raspi_sdmmc_init(void)
struct rt_mmcsd_host * host = RT_NULL;
struct sdhci_pdata_t * pdat = RT_NULL;
struct sdhci_t * sdhci = RT_NULL;
-
#ifdef BSP_USING_SDIO0
host = mmcsd_alloc_host();
if (!host)
@@ -598,7 +596,6 @@ int raspi_sdmmc_init(void)
rt_kprintf("alloc host failed");
goto err;
}
-
sdhci = rt_malloc(sizeof(struct sdhci_t));
if (!sdhci)
{
@@ -608,17 +605,15 @@ int raspi_sdmmc_init(void)
rt_memset(sdhci, 0, sizeof(struct sdhci_t));
virt = MMC2_BASE_ADDR;
-
pdat = (struct sdhci_pdata_t *)rt_malloc(sizeof(struct sdhci_pdata_t));
RT_ASSERT(pdat != RT_NULL);
pdat->virt = (rt_uint32_t)virt;
reset_emmc(pdat);
-
sdhci->name = "sd0";
sdhci->voltages = VDD_33_34;
sdhci->width = MMCSD_BUSWIDTH_4;
- sdhci->clock = 250 * 1000 * 1000;
+ sdhci->clock = 1000 * 1000 * 1000;
sdhci->removeable = RT_TRUE;
sdhci->detect = sdhci_detect;
@@ -634,10 +629,9 @@ int raspi_sdmmc_init(void)
host->max_seg_size = 2048;
host->max_dma_segs = 10;
host->max_blk_size = 512;
- host->max_blk_count = 4096;
+ host->max_blk_count = 1;
host->private_data = sdhci;
-
write32((pdat->virt + EMMC_IRPT_EN),0xffffffff);
write32((pdat->virt + EMMC_IRPT_MASK),0xffffffff);
#ifdef RT_MMCSD_DBG
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_spi.c b/bsp/raspberry-pi/raspi4-32/driver/drv_spi.c
index 90ea26f7ab..f0c6351d7f 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/drv_spi.c
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_spi.c
@@ -16,8 +16,7 @@
#ifdef RT_USING_SPI
-#define RPI_CORE_CLK_HZ (250000000)
-#define BSP_SPI_MAX_HZ (30* 1000 *1000)
+#define RPI_CORE_CLK_HZ (500 * 1000 * 1000)
#define SPITIMEOUT 0x0FFF
static rt_uint8_t raspi_byte_reverse_table[] =
@@ -76,35 +75,35 @@ static rt_err_t raspi_spi_configure(struct rt_spi_device *device, struct rt_spi_
{
RT_ASSERT(cfg != RT_NULL);
RT_ASSERT(device != RT_NULL);
- rt_uint16_t divider;
struct raspi_spi_device* hw_config = (struct raspi_spi_device *)(device->parent.user_data);
struct raspi_spi_hw_config *hwcfg = (struct raspi_spi_hw_config *)hw_config->spi_hw_config;
// spi clear fifo
- SPI_REG_CS(hwcfg->hw_base) = (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX);
+ SPI_REG_CS(hwcfg->hw_base) |= (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX);
if(cfg->mode & RT_SPI_CPOL)
{
SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CPOL;
}
+ else
+ {
+ SPI_REG_CS(hwcfg->hw_base) &= ~SPI_CS_CPOL;
+ }
if(cfg->mode & RT_SPI_CPHA)
{
SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CPHA;
+ }else
+ {
+ SPI_REG_CS(hwcfg->hw_base) &= ~SPI_CS_CPHA;
}
if(cfg->mode & RT_SPI_CS_HIGH)
{
SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CSPOL_HIGH;
}
-
- //set clk
- if (cfg->max_hz > BSP_SPI_MAX_HZ)
- cfg->max_hz = BSP_SPI_MAX_HZ;
-
- divider = (rt_uint16_t) ((rt_uint32_t) RPI_CORE_CLK_HZ / cfg->max_hz);
- divider &= 0xFFFE;
-
- SPI_REG_CLK(hwcfg->hw_base) = divider;
-
+ else
+ {
+ SPI_REG_CS(hwcfg->hw_base) &= ~SPI_CS_CSPOL_HIGH;
+ }
return RT_EOK;
}
@@ -120,13 +119,6 @@ static rt_err_t spi_transfernb(struct raspi_spi_hw_config *hwcfg, rt_uint8_t* tb
{
rt_uint32_t TXCnt=0;
rt_uint32_t RXCnt=0;
-
- /* Clear TX and RX fifos */
- SPI_REG_CS(hwcfg->hw_base) |= (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX);
-
- /* Set TA = 1 */
- SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_TA;
-
/* Use the FIFO's to reduce the interbyte times */
while ((TXCnt < len) || (RXCnt < len))
{
@@ -145,9 +137,6 @@ static rt_err_t spi_transfernb(struct raspi_spi_hw_config *hwcfg, rt_uint8_t* tb
}
/* Wait for DONE to be set */
while (!(SPI_REG_CS(hwcfg->hw_base) & SPI_CS_DONE));
- /* Set TA = 0, and also set the barrier */
- SPI_REG_CS(hwcfg->hw_base) |= (0 & SPI_CS_TA);
-
return RT_EOK;
}
@@ -159,31 +148,54 @@ static rt_uint32_t raspi_spi_xfer(struct rt_spi_device *device, struct rt_spi_me
RT_ASSERT(device->bus != RT_NULL);
RT_ASSERT(device->parent.user_data != RT_NULL);
RT_ASSERT(message->send_buf != RT_NULL || message->recv_buf != RT_NULL);
-
struct rt_spi_configuration config = device->config;
struct raspi_spi_device * hw_config = (struct raspi_spi_device *)device->parent.user_data;
GPIO_PIN cs_pin = (GPIO_PIN)hw_config->cs_pin;
struct raspi_spi_hw_config *hwcfg = (struct raspi_spi_hw_config *)hw_config->spi_hw_config;
+ //mode MSB
if (config.mode & RT_SPI_MSB)
{
- flag = 0;
+ flag = 1;
}
else
{
- flag = 1;
+ flag = 0;
}
- if (message->cs_take)
+ //max_hz
+ if(config.max_hz == 0)
+ {
+ SPI_REG_CLK(hwcfg->hw_base) = 0;
+ }
+ else
{
- (config.mode & RT_SPI_CS_HIGH)?prev_raspi_pin_write(cs_pin, 1):prev_raspi_pin_write(cs_pin, 0);
+ SPI_REG_CLK(hwcfg->hw_base) = (RPI_CORE_CLK_HZ / (config.max_hz));
+ }
+
+ //cs_pin spi0.0
+ if(cs_pin == GPIO_PIN_8)
+ {
+ SPI_REG_CS(hwcfg->hw_base) &= (~(3 << 0));
+ }
+ else if(cs_pin == GPIO_PIN_7)//spi0.1
+ {
+ SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CHIP_SELECT_1;
}
+ //Clear TX and RX fifos
+ SPI_REG_CS(hwcfg->hw_base) |= (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX);
+ if (message->cs_take)
+ {
+ SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_TA;
+ }
res = spi_transfernb(hwcfg, (rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf, (rt_int32_t)message->length, flag);
if (message->cs_release)
{
- (config.mode & RT_SPI_CS_HIGH)?prev_raspi_pin_write(cs_pin, 0):prev_raspi_pin_write(cs_pin, 1);
+ //Set TA = 0, and also set the barrier
+ SPI_REG_CS(hwcfg->hw_base) &= (~SPI_CS_TA);
}
+
if (res != RT_EOK)
return RT_ERROR;
@@ -212,18 +224,6 @@ rt_err_t raspi_spi_hw_init(struct raspi_spi_hw_config *hwcfg)
#endif
//clear rx and tx
SPI_REG_CS(hwcfg->hw_base) = (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX);
- //enable chip select
-#if defined (BSP_USING_SPI0_DEVICE0)
- SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CHIP_SELECT_0;
-#endif
-
-#if defined (BSP_USING_SPI0_DEVICE1)
- SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CHIP_SELECT_1;
-#endif
-
-#if defined (BSP_USING_SPI0_DEVICE0) && defined (BSP_USING_SPI0_DEVICE1)
- HWREG32(SPI_REG_CS(hwcfg->hw_base)) |= (SPI_CS_CHIP_SELECT_0 | SPI_CS_CHIP_SELECT_1);
-#endif
return RT_EOK;
}
@@ -273,6 +273,7 @@ struct raspi_spi_device raspi_spi0_device1 =
.device_name = SPI0_DEVICE1_NAME,
.spi_bus = &spi0_bus,
.spi_device = &spi0_device1,
+ .spi_hw_config = &raspi_spi0_hw,
.cs_pin = GPIO_PIN_7,
};
#endif
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_uart.c b/bsp/raspberry-pi/raspi4-32/driver/drv_uart.c
index ae61d84224..34b9e1d945 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/drv_uart.c
+++ b/bsp/raspberry-pi/raspi4-32/driver/drv_uart.c
@@ -63,15 +63,22 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co
AUX_MU_LCR_REG(uart->hw_base) = 3; /* Works in 8-bit mode */
AUX_MU_MCR_REG(uart->hw_base) = 0; /* Disable RTS */
AUX_MU_IIR_REG(uart->hw_base) = 0xC6; /* Enable FIFO, Clear FIFO */
- AUX_MU_BAUD_REG(uart->hw_base) = 270; /* 115200 = system clock 250MHz / (8 * (baud + 1)), baud = 270 */
+ AUX_MU_BAUD_REG(uart->hw_base) = 541; /* 115200 = system clock 500MHz / (8 * (baud + 1)), baud = 541 */
AUX_MU_CNTL_REG(uart->hw_base) = 3; /* Enable Transmitter and Receiver */
return RT_EOK;
}
if(uart->hw_base == UART0_BASE)
{
+#ifndef BSP_USING_BULETOOTH
prev_raspi_pin_mode(GPIO_PIN_14, ALT0);
prev_raspi_pin_mode(GPIO_PIN_15, ALT0);
+#else
+ prev_raspi_pin_mode(GPIO_PIN_30, ALT3);
+ prev_raspi_pin_mode(GPIO_PIN_31, ALT3);
+ prev_raspi_pin_mode(GPIO_PIN_32, ALT3);
+ prev_raspi_pin_mode(GPIO_PIN_33, ALT3);
+#endif
}
if(uart->hw_base == UART3_BASE)
@@ -92,13 +99,21 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co
prev_raspi_pin_mode(GPIO_PIN_13, ALT4);
}
- PL011_REG_CR(uart->hw_base) = 0;/*Clear UART setting*/
- PL011_REG_LCRH(uart->hw_base) = 0;/*disable FIFO*/
+ PL011_REG_IMSC(uart->hw_base) = 0; /* mask all interrupt */
+ PL011_REG_ICR(uart->hw_base) = 0x7ff; /* clear all interrupt */
+ //PL011 clock 480MHz 480x10^6/baudrate/16
PL011_REG_IBRD(uart->hw_base) = ibrd;
PL011_REG_FBRD(uart->hw_base) = (((bauddiv - ibrd * 1000) * 64 + 500) / 1000);
- PL011_REG_LCRH(uart->hw_base) = PL011_LCRH_WLEN_8;/*FIFO*/
- PL011_REG_CR(uart->hw_base) = PL011_CR_UARTEN | PL011_CR_TXE | PL011_CR_RXE;/*art enable, TX/RX enable*/
-
+#ifdef BSP_USING_BULETOOTH
+ PL011_REG_IFLS(uart->hw_base) = 0x08;
+ PL011_REG_LCRH(uart->hw_base) = 0x70;
+ PL011_REG_CR(uart->hw_base) = PL011_CR_UARTEN | PL011_CR_TXE | PL011_CR_RXE | PL011_CR_RTS;
+#else
+ PL011_REG_IFLS(uart->hw_base) = 0x0;
+ PL011_REG_LCRH(uart->hw_base) = PL011_LCRH_WLEN_8;
+ PL011_REG_CR(uart->hw_base) = PL011_CR_UARTEN | PL011_CR_TXE | PL011_CR_RXE;
+#endif
+ PL011_REG_IMSC(uart->hw_base) = 0;
return RT_EOK;
}
diff --git a/bsp/raspberry-pi/raspi4-32/driver/lcd/Sconscript b/bsp/raspberry-pi/raspi4-32/driver/lcd/Sconscript
new file mode 100644
index 0000000000..ad749bcb9b
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/lcd/Sconscript
@@ -0,0 +1,18 @@
+# RT-Thread building script for component
+
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if not (GetDepend('BSP_USING_HDMI_DISPLAY') or GetDepend('BSP_USING_DSI_DISPLAY')):
+ SrcRemove(src, ['drv_hdmi.c'])
+if not GetDepend('BSP_USING_ILI9486'):
+ SrcRemove(src, ['drv_ili9486.c'])
+if not GetDepend('USING_LCD_CONSOLE'):
+ SrcRemove(src, ['lcd_console.c'])
+
+group = DefineGroup('drv_lcd', src, depend = ['BSP_USING_LCD'], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_hdmi.c b/bsp/raspberry-pi/raspi4-32/driver/lcd/drv_hdmi.c
index a8d68fd9cf..955e55bcf5 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/drv_hdmi.c
+++ b/bsp/raspberry-pi/raspi4-32/driver/lcd/drv_hdmi.c
@@ -13,10 +13,14 @@
#include "mbox.h"
#include "drv_hdmi.h"
-#ifdef BSP_USING_HDMI
+#ifdef USING_LCD_CONSOLE
+#include "lcd_console.h"
+#endif
+
+#if defined(BSP_USING_HDMI_DISPLAY) || defined(BSP_USING_DSI_DISPLAY)
#define LCD_WIDTH (800)
#define LCD_HEIGHT (480)
-#define LCD_DEPTH (32)
+#define LCD_DEPTH (4)
#define LCD_BPP (32)
#define TAG_ALLOCATE_BUFFER 0x00040001
@@ -84,6 +88,9 @@ rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
+#ifdef USING_LCD_CONSOLE
+ fb_print((char*)buffer);
+#endif
return size;
}
@@ -105,7 +112,7 @@ rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args)
RT_ASSERT(info != RT_NULL);
info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
- info->bits_per_pixel= LCD_DEPTH;
+ info->bits_per_pixel= 32;
info->width = lcd->width;
info->height = lcd->height;
info->framebuffer = lcd->fb;
@@ -285,12 +292,18 @@ void *bcm271x_mbox_fb_alloc(int width, int height, int bpp, int nrender)
mbox[34] = TAG_END;
mbox_call(8, MMU_DISABLE);
+
return (void *)((rt_uint32_t)(mbox[5] & 0x3fffffff));
}
int hdmi_fb_init(void)
{
_hdmi.fb = (rt_uint8_t *)bcm271x_mbox_fb_alloc(LCD_WIDTH, LCD_HEIGHT, LCD_BPP, 1);
+ if(_hdmi.fb == RT_NULL)
+ {
+ rt_kprintf("init dsi or hdmi err!\n");
+ return 0;
+ }
bcm271x_mbox_fb_setoffset(0, 0);
bcm271x_mbox_fb_set_porder(0);
_hdmi.width = LCD_WIDTH;
@@ -299,8 +312,9 @@ int hdmi_fb_init(void)
_hdmi.pitch = 0;
_hdmi.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
+ rt_memset(_hdmi.fb, 0, LCD_WIDTH*LCD_HEIGHT*(LCD_BPP/8));
//rt_kprintf("_hdmi.fb is %p\n", _hdmi.fb);
- rt_hdmi_fb_device_init(&_hdmi, "lcd");
+ rt_hdmi_fb_device_init(&_hdmi, "hdmi");
return 0;
}
diff --git a/bsp/raspberry-pi/raspi4-32/driver/drv_hdmi.h b/bsp/raspberry-pi/raspi4-32/driver/lcd/drv_hdmi.h
index c9a06358d0..c9a06358d0 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/drv_hdmi.h
+++ b/bsp/raspberry-pi/raspi4-32/driver/lcd/drv_hdmi.h
diff --git a/bsp/raspberry-pi/raspi4-32/driver/lcd/drv_ili9486.c b/bsp/raspberry-pi/raspi4-32/driver/lcd/drv_ili9486.c
new file mode 100644
index 0000000000..c2317bd112
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/lcd/drv_ili9486.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-08 bigmagic first version
+ */
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include <raspi4.h>
+#include <drv_spi.h>
+#include "drv_ili9486.h"
+
+#ifdef USING_LCD_CONSOLE
+#include "lcd_console.h"
+#endif
+
+//http://www.lcdwiki.com/MHS-3.5inch_RPi_Display
+#define LCD_DEVICE_NAME ("spi0.0")
+
+#define LCD_SPI_SEND_FAST
+//waveshare
+#define LCD_SCREEN_WIDTH (320)
+#define LCD_SCREEN_HEIGHT (480)
+
+#define LCD_RESET_PIN (25)
+#define LCD_RS_PIN (24)
+
+#define LCD_SPI_FREQ_MAX (125*1000*1000)
+
+uint16_t LCD_HEIGHT = LCD_SCREEN_HEIGHT;
+uint16_t LCD_WIDTH = LCD_SCREEN_WIDTH;
+
+#define SCREEN_VERTICAL_1 (0)
+#define SCREEN_HORIZONTAL_1 (1)
+#define SCREEN_VERTICAL_2 (2)
+#define SCREEN_HORIZONTAL_2 (3)
+
+struct rt_semaphore lcd_spi_lock;
+struct rt_semaphore lcd_lock;
+
+//rgb565 lcd buffer
+uint16_t _lcd_buffer[LCD_SCREEN_WIDTH * LCD_SCREEN_HEIGHT];
+uint16_t send_buffer[LCD_SCREEN_WIDTH * LCD_SCREEN_HEIGHT];
+
+static struct rt_spi_device *lcd_dev;
+
+static inline void send_cmd(void)
+{
+ rt_pin_write(LCD_RS_PIN, PIN_LOW);
+}
+
+static inline void send_data(void)
+{
+ rt_pin_write(LCD_RS_PIN, PIN_HIGH);
+}
+
+void writeData16(rt_uint16_t data)
+{
+ rt_uint8_t send_data[2];
+ send_data[1] = data & 0x00FF;
+ send_data[0] = ((data >> 8) & 0x00FF);
+ rt_spi_transfer(lcd_dev, &send_data[0], RT_NULL, 2);
+}
+
+void writeData(void* dev,rt_uint8_t data)
+{
+ writeData16((rt_uint16_t)(data));
+}
+
+void writeCommand(void* dev, rt_uint8_t cmd)
+{
+ send_cmd();
+ writeData16((rt_uint16_t)(cmd));
+ send_data();
+}
+
+void lcd_write_commmand(rt_uint8_t cmd)
+{
+ writeCommand(lcd_dev, cmd);
+}
+
+void lcd_write_data(rt_uint8_t data)
+{
+ writeData(lcd_dev, data);
+}
+
+/*Ser rotation of the screen - changes x0 and y0*/
+static inline void lcd_set_rotation(uint8_t rotation)
+{
+ writeCommand(lcd_dev, 0x36);
+ rt_thread_mdelay(100);
+
+ switch(rotation) {
+ case SCREEN_VERTICAL_1:
+ writeData(lcd_dev, 0x48);
+ LCD_WIDTH = 320;
+ LCD_HEIGHT = 480;
+ break;
+ case SCREEN_HORIZONTAL_1:
+ writeData(lcd_dev, 0x28);
+ LCD_WIDTH = 480;
+ LCD_HEIGHT = 320;
+ break;
+ case SCREEN_VERTICAL_2:
+ writeData(lcd_dev, 0x98);
+ LCD_WIDTH = 320;
+ LCD_HEIGHT = 480;
+ break;
+ case SCREEN_HORIZONTAL_2:
+ writeData(lcd_dev, 0xF8);
+ LCD_WIDTH = 480;
+ LCD_HEIGHT = 320;
+ break;
+ default:
+ //EXIT IF SCREEN ROTATION NOT VALID!
+ break;
+ }
+
+ if((rotation == SCREEN_VERTICAL_1) || (rotation == SCREEN_VERTICAL_2))
+ {
+ lcd_write_commmand(0x2A);
+ lcd_write_data(0x00);
+ lcd_write_data(0x00);
+ lcd_write_data(0x01);
+ lcd_write_data(0x3F);
+
+ lcd_write_commmand(0x2B);
+ lcd_write_data(0x00);
+ lcd_write_data(0x00);
+ lcd_write_data(0x01);
+ lcd_write_data(0xE0);
+ }
+
+ if((rotation == SCREEN_HORIZONTAL_1) || (rotation == SCREEN_HORIZONTAL_2))
+ {
+ lcd_write_commmand(0x2B);
+ lcd_write_data(0x00);
+ lcd_write_data(0x00);
+ lcd_write_data(0x01);
+ lcd_write_data(0x3F);
+
+ lcd_write_commmand(0x2A);
+ lcd_write_data(0x00);
+ lcd_write_data(0x00);
+ lcd_write_data(0x01);
+ lcd_write_data(0xE0);
+ }
+}
+
+static inline void fast_send_data(void)
+{
+ rt_uint32_t ii = 0;
+ rt_uint32_t tx_index = 0;
+ char *tx_data = (char *)send_buffer;
+ rt_sem_take(&lcd_spi_lock, RT_WAITING_FOREVER);
+
+ SPI_REG_CS(SPI_0_BASE) &= (~(3 << 0));
+ SPI_REG_CLK(SPI_0_BASE) = 4;
+ SPI_REG_CS(SPI_0_BASE) |= SPI_CS_TA;
+ for(tx_index=0;tx_index<(LCD_SCREEN_WIDTH * LCD_SCREEN_HEIGHT) * 2;tx_index++)
+ {
+ for(ii = 0; ii < 32; ii = ii + 2)
+ {
+ SPI_REG_FIFO(SPI_0_BASE) = tx_data[tx_index + ii + 1];
+ SPI_REG_FIFO(SPI_0_BASE) = tx_data[tx_index + ii];
+ }
+ while (!(SPI_REG_CS(SPI_0_BASE) & SPI_CS_DONE));
+ SPI_REG_CS(SPI_0_BASE) |= (SPI_CS_CLEAR_TX) | (SPI_CS_CLEAR_RX);
+ tx_index = tx_index + 31;
+ }
+ SPI_REG_CS(SPI_0_BASE) |= (SPI_CS_CLEAR_TX) | (SPI_CS_CLEAR_RX);
+ SPI_REG_CS(SPI_0_BASE) &= (~SPI_CS_TA);
+ rt_sem_release(&lcd_spi_lock);
+}
+
+static inline void lcd_show(void)
+{
+
+ lcd_write_commmand(0x2C); // Memory write?
+
+ //rt_thread_mdelay(150);
+
+#ifdef LCD_SPI_SEND_FAST
+ fast_send_data();
+#else
+ int i, j;
+ for (i = 0 ; i < 30 ; i ++)
+ {
+ uint16_t *tx_data = (uint16_t*)&send_buffer[5120* i];
+ int32_t data_sz = 5120;
+ for( j=0; j<data_sz; j++)
+ {
+ writeData16(tx_data[j]);
+ }
+ }
+#endif
+
+}
+
+static void lcd_init(void)
+{
+ writeCommand(lcd_dev, 0x28);
+ rt_thread_mdelay(150);
+
+ writeCommand(lcd_dev, 0x3A); // Interface Pixel Format
+ writeData(lcd_dev, 0x55); // 16 bit/pixe
+
+ writeCommand(lcd_dev, 0xC2); // Interface Pixel Format
+ writeData(lcd_dev, 0x44);
+
+ writeCommand(lcd_dev, 0xC5); // VCOM Control
+ writeData(lcd_dev, 0x00);
+ writeData(lcd_dev, 0x00);
+ writeData(lcd_dev, 0x00);
+ writeData(lcd_dev, 0x00);
+
+ writeCommand(lcd_dev, 0xE0); // PGAMCTRL(Positive Gamma Control)
+ writeData(lcd_dev, 0x0F);
+ writeData(lcd_dev, 0x1F);
+ writeData(lcd_dev, 0x1C);
+ writeData(lcd_dev, 0x0C);
+ writeData(lcd_dev, 0x0F);
+ writeData(lcd_dev, 0x08);
+ writeData(lcd_dev, 0x48);
+ writeData(lcd_dev, 0x98);
+ writeData(lcd_dev, 0x37);
+ writeData(lcd_dev, 0x0A);
+ writeData(lcd_dev, 0x13);
+ writeData(lcd_dev, 0x04);
+ writeData(lcd_dev, 0x11);
+ writeData(lcd_dev, 0x0D);
+ writeData(lcd_dev, 0x00);
+
+ writeCommand(lcd_dev, 0xE1); // NGAMCTRL (Negative Gamma Correction)
+ writeData(lcd_dev, 0x0F);
+ writeData(lcd_dev, 0x32);
+ writeData(lcd_dev, 0x2E);
+ writeData(lcd_dev, 0x0B);
+ writeData(lcd_dev, 0x0D);
+ writeData(lcd_dev, 0x05);
+ writeData(lcd_dev, 0x47);
+ writeData(lcd_dev, 0x75);
+ writeData(lcd_dev, 0x37);
+ writeData(lcd_dev, 0x06);
+ writeData(lcd_dev, 0x10);
+ writeData(lcd_dev, 0x03);
+ writeData(lcd_dev, 0x24);
+ writeData(lcd_dev, 0x20);
+ writeData(lcd_dev, 0x00);
+
+ writeCommand(lcd_dev, 0x11); // Sleep out, also SW reset
+ rt_thread_mdelay(150);
+
+ writeCommand(lcd_dev, 0x20); // Display Inversion OFF RPi LCD (A)
+ //writeCommand(lcd_dev, 0x21); // Display Inversion ON RPi LCD (B)
+
+ lcd_set_rotation(SCREEN_VERTICAL_2);
+ writeCommand(lcd_dev, 0x29); // Display ON
+ rt_thread_mdelay(150);
+}
+
+static inline void lcd_reset(void)
+{
+ //Reset signal, low reset (pin22)
+ rt_pin_mode(LCD_RESET_PIN,PIN_MODE_OUTPUT);
+
+ rt_pin_write(LCD_RESET_PIN, PIN_HIGH);
+ rt_thread_mdelay(100);
+ rt_pin_write(LCD_RESET_PIN, PIN_LOW);
+ rt_thread_mdelay(100);
+ rt_pin_write(LCD_RESET_PIN, PIN_HIGH);
+}
+
+
+rt_err_t ili9486_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ return RT_EOK;
+}
+
+rt_err_t ili9486_close(rt_device_t dev)
+{
+ return RT_EOK;
+}
+
+rt_size_t ili9486_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
+{
+ return 0;
+}
+
+rt_size_t ili9486_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+#ifdef USING_LCD_CONSOLE
+ fb_print((char*)buffer);
+#endif
+ return size;
+}
+
+rt_err_t ili9486_control(rt_device_t dev, int cmd, void *args)
+{
+ rt_sem_take(&lcd_lock, RT_WAITING_FOREVER);
+ switch (cmd)
+ {
+ case RTGRAPHIC_CTRL_RECT_UPDATE:
+ {
+ struct rt_device_rect_info *info = (struct rt_device_rect_info*)args;
+ info = info;
+ rt_memcpy(send_buffer, _lcd_buffer, LCD_SCREEN_WIDTH * LCD_SCREEN_HEIGHT * 2);
+ lcd_show();
+ }
+ break;
+
+ case RTGRAPHIC_CTRL_GET_INFO:
+ {
+ struct rt_device_graphic_info* info = (struct rt_device_graphic_info*)args;
+
+ RT_ASSERT(info != RT_NULL);
+ info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
+ info->bits_per_pixel= 16;
+ info->width = LCD_WIDTH;
+ info->height = LCD_HEIGHT;
+ info->framebuffer = (void *)_lcd_buffer;//lcd->fb;
+ }
+ break;
+ }
+ rt_sem_release(&lcd_lock);
+ return RT_EOK;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops ili9486_ops =
+{
+ RT_NULL,
+ ili9486_open,
+ ili9486_close,
+ ili9486_read,
+ ili9486_write,
+ ili9486_control,
+};
+#endif
+
+static int hw_ili9486_lcd_init(void)
+{
+ struct rt_device *device;
+ device = rt_malloc(sizeof(struct rt_device));
+ rt_memset(device, 0, sizeof(struct rt_device));
+
+ lcd_reset();
+ rt_pin_mode(LCD_RS_PIN, PIN_MODE_OUTPUT);
+ lcd_dev = (struct rt_spi_device *)rt_device_find(LCD_DEVICE_NAME);
+ if (!lcd_dev)
+ {
+ rt_kprintf("no %s!\n", LCD_DEVICE_NAME);
+ }
+ lcd_dev->config.max_hz = LCD_SPI_FREQ_MAX;//125M
+ lcd_init();
+
+ rt_sem_init(&lcd_spi_lock, "lcd_spi_lock", 1, RT_IPC_FLAG_FIFO);
+ rt_sem_init(&lcd_lock, "lcd_spi_lock", 1, RT_IPC_FLAG_FIFO);
+ /* set device type */
+ device->type = RT_Device_Class_Graphic;
+ /* initialize device interface */
+#ifdef RT_USING_DEVICE_OPS
+ device->ops = &ili9486_ops;
+#else
+ device->init = RT_NULL;
+ device->open = ili9486_open;
+ device->close = ili9486_close;
+ device->read = ili9486_read;
+ device->write = ili9486_write;
+ device->control = ili9486_control;
+#endif
+ /* register to device manager */
+ rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR);
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(hw_ili9486_lcd_init);
diff --git a/bsp/raspberry-pi/raspi4-32/driver/lcd/drv_ili9486.h b/bsp/raspberry-pi/raspi4-32/driver/lcd/drv_ili9486.h
new file mode 100644
index 0000000000..b9f2658d0f
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/lcd/drv_ili9486.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-08 bigmagic first version
+ */
+#ifndef __DRV_ILI9486_H__
+#define __DRV_ILI9486_H__
+
+#endif//ILI9486
diff --git a/bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_console.c b/bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_console.c
new file mode 100644
index 0000000000..b362f80c05
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_console.c
@@ -0,0 +1,258 @@
+
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-09 bigmagic first version
+ */
+
+#include "lcd_console.h"
+#include "lcd_font_20.h"
+
+#define LCD_CONSOLE_FLUSH_NOW 1
+
+#define CONSOLE_NAME "hdmi"
+#define COLOR_DELTA 0.05
+
+#ifndef LCD_CONSOLE_FLUSH_NOW
+static rt_thread_t console_flush_thread_tid = RT_NULL;
+#define CONSOLE_FLUSH_THREAD_STACK_SIZE (1024)
+#define CONSOLE_FLUSH_THREAD_PRIORITY (20)
+#define CONSOLE_FLUSH_THREAD_TIMESLICE (10)
+#define LCD_CONSOLE_DELAY (100) //100ms
+#endif
+
+static rt_device_t console_dev = RT_NULL;
+
+static fb_t console_fb;
+static rt_uint8_t* virt_buffer;
+
+static rt_uint32_t CHAR_W = 8;
+static rt_uint32_t CHAR_H = 20;
+
+static int prev_x_offset = 0;
+
+static void newline(fb_t* fb)
+{
+ uint8_t* to;
+ uint8_t* from;
+ int i;
+ fb->y++;
+ fb->x = 5 * fb->depth;
+
+ if (fb->y == (fb->height / CHAR_H))
+ {
+ to = (uint8_t*) fb->vaddr;
+ from = to + (CHAR_H * fb->pitch);
+
+ for (i = 0; i < ((fb->height - CHAR_H) * fb->pitch); i++)
+ {
+ *to++ = *from++;
+ }
+
+ if(fb->depth >= 3)
+ {
+ uint32_t *addr_32bit = (uint32_t*) (fb->vaddr) + (fb->height - CHAR_H) * fb->width;
+
+ for (i = 0; i < (CHAR_H * fb->width); i++)
+ {
+ *addr_32bit++ = fb->back;
+ }
+ }
+ else
+ {
+ uint16_t *addr_16bit = (uint16_t*) (fb->vaddr) + (fb->height - CHAR_H) * fb->width;
+
+ for (i = 0; i < (CHAR_H * fb->width); i++)
+ {
+ *addr_16bit++ = fb->back;
+ }
+ }
+ fb->y = fb->y - 1;
+ }
+}
+
+
+static void fb_draw_char(fb_t *fb, char s)
+{
+ unsigned char* addr = (unsigned char*) fb->vaddr;
+ unsigned char *glyph = (unsigned char *)lcd_console_font_dejavu_20_glyph_bitmap + lcd_console_font_dejavu_20_glyph_dsc[s - 32].glyph_index;
+ CHAR_W = lcd_console_font_dejavu_20_glyph_dsc[s - 32].w_px;
+
+ fb->x = fb->x + prev_x_offset * fb->depth;
+
+ int i, j, line, mask, bytesperline = (CHAR_W + 7) / 8;
+ int kk = (bytesperline) * 8;
+ prev_x_offset = CHAR_W + 2;
+ // calculate the offset on screen
+ int offs = (fb->y * CHAR_H * fb->pitch) + fb->x;
+
+ // display a character
+ for (j = 0; j < CHAR_H; j++)
+ {
+ // display one row
+ line = offs;
+ mask = 1;
+ mask = 0x80;
+ for (i = 0; i < kk; i++)
+ {
+ if(fb->depth >= 3)
+ {
+ *((unsigned int*) (addr + line)) = ((int) *(glyph + ((i)/8)) * 1) & mask ? fb->fore : fb->back;
+ }
+ else
+ {
+ *((unsigned short*) (addr + line)) = ((int) *(glyph + ((i)/8)) * 1) & mask ? fb->fore : fb->back;
+ }
+
+ mask >>= 1;
+ if(mask == 0)
+ {
+ mask = 0x80;
+ }
+ line += fb->depth;
+ }
+ // adjust to next line
+ glyph += bytesperline;
+ offs += fb->pitch;
+ }
+}
+
+void fb_print(char *s)
+{
+ fb_t *fb = &console_fb;
+ // draw next character if it's not zero
+ while (*s)
+ {
+ // handle carrige return
+ if (*s == '\r')
+ {
+ fb->x = 5 * fb->depth;
+ }
+ else if (*s == '\n')
+ {
+ newline(fb);
+ }
+ else if (*s == '\t')
+ {
+ //tab is 8 spaces
+ if((fb->x + 8 * fb->depth) < (fb->width) * fb->depth)
+ {
+ fb->x = fb->x + 8 * fb->depth;
+ }
+ }
+ else if (*s == '\b')
+ {
+ if (fb->x > 5 * fb->depth)
+ {
+ fb->x = fb->x - prev_x_offset * fb->depth;
+ fb_draw_char(fb, ' ');
+ }
+ }
+ else if((fb->x + prev_x_offset * fb->depth + 5 * fb->depth) >= (fb->width * fb->depth))
+ {
+ newline(fb);
+ fb_draw_char(fb, *s);
+ }
+ else
+ {
+ fb_draw_char(fb, *s);
+ }
+ s++;
+ }
+
+#ifdef LCD_CONSOLE_FLUSH_NOW
+ rt_memcpy((void *)fb->paddr, (void *)fb->vaddr, fb->size);
+ if(console_dev != RT_NULL)
+ {
+ rt_device_control(console_dev,RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
+ }
+#endif
+}
+
+#ifndef LCD_CONSOLE_FLUSH_NOW
+void lcd_console_task_entry(void *param)
+{
+ fb_t *fb = (fb_t *)param;
+ while (1)
+ {
+ rt_memcpy((void *)fb->paddr, (void *)fb->vaddr, fb->size);
+ if(console_dev != RT_NULL)
+ {
+ rt_device_control(console_dev,RTGRAPHIC_CTRL_RECT_UPDATE, RT_NULL);
+ }
+ rt_thread_mdelay(LCD_CONSOLE_DELAY);
+ }
+
+}
+#endif
+
+int lcd_console_init(void)
+{
+ struct rt_device_graphic_info info;
+ console_dev = rt_device_find(CONSOLE_NAME);
+ if(console_dev == RT_NULL)
+ {
+ rt_kprintf("no console dev!\n");
+ return 0;
+ }
+
+ if(console_dev->ref_count >= 1)
+ {
+ rt_kprintf("lcd console has open!\n");
+ return 0;
+ }
+
+ rt_device_open(console_dev,RT_DEVICE_OFLAG_RDWR);
+
+ rt_device_control(console_dev, RTGRAPHIC_CTRL_GET_INFO, &info);
+
+ virt_buffer = (rt_uint8_t* )rt_malloc(info.width * info.height * (info.bits_per_pixel/8));
+ rt_memset(virt_buffer, 0 , info.width * info.height * (info.bits_per_pixel/8));
+ console_fb.width = info.width;
+ console_fb.height = info.height;
+ console_fb.pitch = info.width * (info.bits_per_pixel/8);
+ console_fb.vaddr = (rt_uint32_t)virt_buffer;
+ console_fb.paddr = (rt_uint32_t)info.framebuffer;
+ console_fb.size = info.width * info.height * (info.bits_per_pixel/8);
+ console_fb.depth = info.bits_per_pixel/8;
+ console_fb.x = 0;
+ console_fb.y = 0;
+ if(console_fb.depth >= 3)
+ {
+ console_fb.fore = CONSOLE_WHITE_32;
+ console_fb.back = CONSOLE_BLACK_32;
+ }
+ else
+ {
+ console_fb.fore = CONSOLE_WHITE_16;
+ console_fb.back = CONSOLE_BLACK_16;
+ }
+
+#ifndef LCD_CONSOLE_FLUSH_NOW
+ console_flush_thread_tid = rt_thread_create("lcd_console", lcd_console_task_entry, (void *)&console_fb,
+ CONSOLE_FLUSH_THREAD_STACK_SIZE,
+ CONSOLE_FLUSH_THREAD_PRIORITY, CONSOLE_FLUSH_THREAD_TIMESLICE);
+ if (console_flush_thread_tid != RT_NULL)
+ rt_thread_startup(console_flush_thread_tid);
+#endif
+ /*
+ * note:
+ * if serial console and lcd console together
+ * you can add /src/kservice.c:rt_kprintf
+ * #ifdef USING_LCD_CONSOLE
+ * fb_print((char*)rt_log_buf);
+ * #endif
+ *
+ * remove rt_console_set_device(CONSOLE_NAME);
+ */
+ rt_console_set_device(CONSOLE_NAME);
+
+ rt_show_version();//show rt-thread logo
+
+ return 0;
+}
+INIT_APP_EXPORT(lcd_console_init);
diff --git a/bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_console.h b/bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_console.h
new file mode 100644
index 0000000000..ebe6afa068
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_console.h
@@ -0,0 +1,59 @@
+
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-09 bigmagic first version
+ */
+#ifndef __LCD_CONSOLE_H__
+#define __LCD_CONSOLE_H__
+
+#include <rtthread.h>
+
+#define RGB(r, g, b) ((((r))<<16) | (((g))<<8) | ((b)))
+#define COLOR_BLACK RGB(0, 0, 0)
+#define COLOR_GREEN RGB(0, 255, 0)
+#define COLOR_CYAN RGB(0, 255, 255)
+#define COLOR_RED RGB(255, 0, 0)
+#define COLOR_YELLOW RGB(255, 255, 0)
+#define COLOR_WHITE RGB(255, 255, 255)
+
+#define CONSOLE_WHITE_32 COLOR_WHITE
+#define CONSOLE_BLACK_32 COLOR_BLACK
+#define CONSOLE_GREEN_32 COLOR_GREEN
+#define CONSOLE_CYAN_32 COLOR_CYAN
+#define CONSOLE_RED_32 COLOR_RED
+
+
+#define RGB16(r, g, b) ((((r))<<11) | (((g))<<5) | ((b)))
+#define CONSOLE_YELLOW_16 RGB16(0x1f,0x3f,0)
+#define CONSOLE_WHITE_16 RGB16(0x1f,0x3f,0x1f)
+#define CONSOLE_BLACK_16 RGB16(0,0,0)
+#define CONSOLE_GREEN_16 RGB16(0,0x3f,0)
+#define CONSOLE_CYAN_16 RGB16(0,0x3f,0x1f)
+#define CONSOLE_RED_16 RGB16(0x1f,0,0)
+
+typedef struct
+{
+ rt_uint32_t width;
+ rt_uint32_t height;
+ rt_uint32_t vwidth;
+ rt_uint32_t vheight;
+ rt_uint32_t pitch;
+ rt_uint32_t depth;
+ rt_uint32_t fore;
+ rt_uint32_t back;
+ rt_uint32_t x;
+ rt_uint32_t y;
+ rt_uint32_t vaddr;
+ rt_uint32_t paddr;
+ rt_uint32_t size;
+} fb_t;
+
+void fb_print(char *s);
+int lcd_console_init(void);
+
+#endif//CONSOLE
diff --git a/bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_font_20.h b/bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_font_20.h
new file mode 100644
index 0000000000..7ef56d7e3c
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/lcd/lcd_font_20.h
@@ -0,0 +1,2299 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-26 bigmagic first version
+ */
+static const uint8_t lcd_console_font_dejavu_20_glyph_bitmap[] = {
+ /*Unicode: U+0020 ( ) , Width: 6 */
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+
+
+ /*Unicode: U+0021 (!) , Width: 2 */
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+
+
+ /*Unicode: U+0022 (") , Width: 6 */
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0xcc, //@@..@@
+ 0xcc, //@@..@@
+ 0xcc, //@@..@@
+ 0xcc, //@@..@@
+ 0xcc, //@@..@@
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+
+
+ /*Unicode: U+0023 (#) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x04, 0x40, //.....@..+@..
+ 0x04, 0x40, //....+@..+@..
+ 0x0c, 0xc0, //....%@..%%..
+ 0x0c, 0x80, //....@%..@+..
+ 0x7f, 0xf0, //.@@@@@@@@@@@
+ 0x7f, 0xf0, //.@@@@@@@@@@@
+ 0x09, 0x80, //...+@..%@...
+ 0x19, 0x00, //...@%..@+...
+ 0xff, 0xe0, //@@@@@@@@@@@.
+ 0xff, 0xe0, //@@@@@@@@@@@.
+ 0x13, 0x00, //..+@..%@....
+ 0x33, 0x00, //..%%..%%....
+ 0x32, 0x00, //..@%..@+....
+ 0x22, 0x00, //..@+..@.....
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+0024 ($) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x08, 0x00, //....@....
+ 0x08, 0x00, //....@....
+ 0x3e, 0x00, //.+%@@@%..
+ 0x7f, 0x00, //+@@@@@@@.
+ 0xe9, 0x00, //@@%.@.+@.
+ 0xc8, 0x00, //@@..@....
+ 0xf8, 0x00, //%@@%@....
+ 0x7e, 0x00, //.@@@@@@+.
+ 0x0f, 0x00, //...+@@@@+
+ 0x09, 0x80, //....@.+@@
+ 0x09, 0x80, //....@..@@
+ 0x8b, 0x80, //@+..@.%@@
+ 0xff, 0x00, //@@@@@@@@+
+ 0x7e, 0x00, //.%@@@@%+.
+ 0x08, 0x00, //....@....
+ 0x08, 0x00, //....@....
+ 0x08, 0x00, //....@....
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+0025 (%) , Width: 15 */
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x78, 0x10, //.%@@%.....+@...
+ 0x48, 0x20, //+@++@+....@....
+ 0xcc, 0x60, //@@..@@...%%....
+ 0xcc, 0x40, //@@..@@...@.....
+ 0xcc, 0x80, //@@..@@..@+.....
+ 0xc8, 0x80, //+@++@+.+%......
+ 0x79, 0x3c, //.%@@%..@..%@@%.
+ 0x02, 0x24, //......%+.+@++@+
+ 0x02, 0x66, //.....+@..@@..@@
+ 0x04, 0x66, //.....@...@@..@@
+ 0x0c, 0x66, //....%%...@@..@@
+ 0x08, 0x24, //....@....+@++@+
+ 0x10, 0x3c, //...@+.....%@@%.
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+
+
+ /*Unicode: U+0026 (&) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x0f, 0x00, //...+@@@%+...
+ 0x1f, 0x80, //..+@@@@@@...
+ 0x30, 0x80, //..@@+..+%...
+ 0x30, 0x00, //..@@........
+ 0x38, 0x00, //..%@%.......
+ 0x3c, 0x00, //..%@@%......
+ 0x7e, 0x60, //.%@%@@%..@@.
+ 0xc7, 0x60, //%@+.+@@%+@%.
+ 0xc3, 0xc0, //@@...+@@@@..
+ 0xc1, 0x80, //@@+...+@@+..
+ 0xe1, 0xc0, //%@@+..+@@%..
+ 0x7f, 0xe0, //.@@@@@@@@@%.
+ 0x3e, 0x70, //..%@@@%.+@@%
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+0027 (') , Width: 2 */
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+
+
+ /*Unicode: U+0028 (() , Width: 4 */
+ 0x00, //....
+ 0x00, //....
+ 0x30, //..%@
+ 0x20, //..@+
+ 0x60, //.%@.
+ 0x60, //.@%.
+ 0x40, //+@+.
+ 0xc0, //%@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //%@..
+ 0x40, //+@+.
+ 0x60, //.@%.
+ 0x60, //.%@.
+ 0x20, //..@+
+ 0x30, //..%@
+ 0x00, //....
+ 0x00, //....
+
+
+ /*Unicode: U+0029 ()) , Width: 4 */
+ 0x00, //....
+ 0x00, //....
+ 0xc0, //@%..
+ 0x40, //+@..
+ 0x60, //.@%.
+ 0x60, //.%@.
+ 0x20, //.+@+
+ 0x30, //..@%
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@%
+ 0x20, //.+@+
+ 0x60, //.%@.
+ 0x60, //.@%.
+ 0x40, //+@..
+ 0xc0, //@%..
+ 0x00, //....
+ 0x00, //....
+
+
+ /*Unicode: U+002a (*) , Width: 7 */
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x10, //...@...
+ 0x92, //%..@..%
+ 0x54, //+@+@+@+
+ 0x38, //..@@@..
+ 0x38, //..@@@..
+ 0x54, //+@+@+@+
+ 0x92, //%..@..%
+ 0x10, //...@...
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+
+
+ /*Unicode: U+002b (+) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0xff, 0xf0, //@@@@@@@@@@@@
+ 0xff, 0xf0, //@@@@@@@@@@@@
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+002c (,) , Width: 3 */
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x60, //.@@
+ 0x60, //.@@
+ 0x40, //+@.
+ 0x80, //@+.
+ 0x00, //...
+ 0x00, //...
+
+
+ /*Unicode: U+002d (-) , Width: 5 */
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0xf8, //@@@@@
+ 0xf8, //@@@@@
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+ 0x00, //.....
+
+
+ /*Unicode: U+002e (.) , Width: 2 */
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+
+
+ /*Unicode: U+002f (/) , Width: 6 */
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x0c, //....@@
+ 0x0c, //...+@%
+ 0x18, //...%@+
+ 0x18, //...@@.
+ 0x18, //...@@.
+ 0x38, //..+@%.
+ 0x30, //..@@+.
+ 0x30, //..@@..
+ 0x30, //.+@@..
+ 0x70, //.%@%..
+ 0x60, //.@@+..
+ 0x60, //.@@...
+ 0x60, //+@%...
+ 0xc0, //%@+...
+ 0xc0, //@@....
+ 0x00, //......
+ 0x00, //......
+
+
+ /*Unicode: U+0030 (0) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x1c, 0x00, //..+@@@+..
+ 0x7f, 0x00, //.%@@@@@%.
+ 0x63, 0x00, //+@@+.+@@+
+ 0xc1, 0x80, //%@+...+@%
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //%@+...+@%
+ 0x63, 0x00, //+@@+.+@@+
+ 0x7f, 0x00, //.%@@@@@%.
+ 0x3e, 0x00, //..+@@@+..
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+0031 (1) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x38, //.+@@@...
+ 0xf8, //@@@@@...
+ 0x98, //@+.@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0xff, //@@@@@@@@
+ 0xff, //@@@@@@@@
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+0032 (2) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x7c, 0x00, //.%@@@%...
+ 0xfe, 0x00, //@@@@@@@+.
+ 0x87, 0x00, //@+...@@@.
+ 0x03, 0x00, //......@@.
+ 0x03, 0x00, //......@@.
+ 0x06, 0x00, //.....%@+.
+ 0x06, 0x00, //....+@@..
+ 0x0c, 0x00, //...+@@...
+ 0x18, 0x00, //..+@@+...
+ 0x30, 0x00, //.+@@+....
+ 0x60, 0x00, //+@@+.....
+ 0xff, 0x00, //@@@@@@@@.
+ 0xff, 0x00, //@@@@@@@@.
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+0033 (3) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x7e, 0x00, //.%@@@@%..
+ 0xff, 0x00, //@@@@@@@@+
+ 0x83, 0x80, //@+....%@@
+ 0x01, 0x80, //.......@@
+ 0x03, 0x80, //......%@%
+ 0x3e, 0x00, //..@@@@@+.
+ 0x3f, 0x00, //..@@@@@%.
+ 0x03, 0x80, //.....+@@%
+ 0x01, 0x80, //.......@@
+ 0x01, 0x80, //.......@@
+ 0x83, 0x80, //%+...+@@%
+ 0xff, 0x00, //@@@@@@@@.
+ 0x7e, 0x00, //.%@@@@%..
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+0034 (4) , Width: 10 */
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x07, 0x00, //.....%@@..
+ 0x07, 0x00, //....+@@@..
+ 0x0b, 0x00, //....@+@@..
+ 0x1b, 0x00, //...%@.@@..
+ 0x13, 0x00, //..+@..@@..
+ 0x23, 0x00, //..@+..@@..
+ 0x63, 0x00, //.@@...@@..
+ 0x43, 0x00, //+@....@@..
+ 0xff, 0xc0, //@@@@@@@@@@
+ 0xff, 0xc0, //@@@@@@@@@@
+ 0x03, 0x00, //......@@..
+ 0x03, 0x00, //......@@..
+ 0x03, 0x00, //......@@..
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+
+
+ /*Unicode: U+0035 (5) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x7e, //.@@@@@@.
+ 0x7e, //.@@@@@@.
+ 0x60, //.@@.....
+ 0x60, //.@@.....
+ 0x7c, //.@@@@@..
+ 0x7e, //.@@@@@@.
+ 0x47, //.%...@@%
+ 0x03, //......@@
+ 0x03, //......@@
+ 0x03, //......@@
+ 0x87, //%...+@@%
+ 0xfe, //@@@@@@@.
+ 0x7c, //.%@@@%..
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+0036 (6) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x1e, 0x00, //...%@@@+.
+ 0x3f, 0x00, //.+@@@@@@.
+ 0x71, 0x00, //.@@%...%.
+ 0xe0, 0x00, //+@@......
+ 0xc0, 0x00, //@@+......
+ 0xde, 0x00, //@@.%@@%..
+ 0xff, 0x00, //@@%@@@@@.
+ 0xe3, 0x80, //@@%...%@%
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //%@.....@@
+ 0x63, 0x80, //+@%...%@%
+ 0x7f, 0x00, //.%@@@@@@.
+ 0x1e, 0x00, //..+@@@%..
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+0037 (7) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0xff, //@@@@@@@@
+ 0xff, //@@@@@@@@
+ 0x06, //.....%@+
+ 0x06, //.....@@.
+ 0x06, //....+@@.
+ 0x0c, //....%@+.
+ 0x0c, //....@@..
+ 0x0c, //....@@..
+ 0x1c, //...%@%..
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x38, //..%@%...
+ 0x30, //..@@+...
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+0038 (8) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x3e, 0x00, //.+%@@@%+.
+ 0x7f, 0x00, //+@@@@@@@+
+ 0xe3, 0x80, //@@%...%@@
+ 0xc1, 0x80, //@@.....@@
+ 0xe3, 0x80, //%@%...%@%
+ 0x3e, 0x00, //.+@@@@@+.
+ 0x7f, 0x00, //.%@@@@@%.
+ 0xe3, 0x80, //%@%...%@%
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xe3, 0x80, //@@%...%@@
+ 0x7f, 0x00, //+@@@@@@@+
+ 0x3e, 0x00, //..%@@@%..
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+0039 (9) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x3c, 0x00, //..%@@@+..
+ 0x7f, 0x00, //.@@@@@@%.
+ 0xe3, 0x00, //%@%...%@.
+ 0xc1, 0x80, //@@.....@%
+ 0xc1, 0x80, //@@.....@@
+ 0xe3, 0x80, //%@%...%@@
+ 0x7f, 0x80, //.@@@@@%@@
+ 0x3d, 0x80, //..%@@%.@@
+ 0x01, 0x80, //......+@@
+ 0x03, 0x00, //......@@+
+ 0x47, 0x00, //.%...%@@.
+ 0x7e, 0x00, //.@@@@@@+.
+ 0x3c, 0x00, //.+@@@%...
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+003a (:) , Width: 2 */
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+
+
+ /*Unicode: U+003b (;) , Width: 3 */
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x60, //.@@
+ 0x60, //.@@
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x00, //...
+ 0x60, //.@@
+ 0x60, //.@@
+ 0x40, //+@.
+ 0x80, //@+.
+ 0x00, //...
+ 0x00, //...
+
+
+ /*Unicode: U+003c (<) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x20, //.........+@
+ 0x01, 0xe0, //.......%@@@
+ 0x07, 0xc0, //....+@@@@%+
+ 0x3e, 0x00, //.+%@@@@+...
+ 0xf8, 0x00, //@@@@%+.....
+ 0xf8, 0x00, //@@@@%+.....
+ 0x3e, 0x00, //.+%@@@@+...
+ 0x07, 0xc0, //....+@@@@%+
+ 0x01, 0xe0, //......+%@@@
+ 0x00, 0x20, //.........+@
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+
+
+ /*Unicode: U+003d (=) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0xff, 0xe0, //@@@@@@@@@@@
+ 0xff, 0xe0, //@@@@@@@@@@@
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0xff, 0xe0, //@@@@@@@@@@@
+ 0xff, 0xe0, //@@@@@@@@@@@
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+
+
+ /*Unicode: U+003e (>) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x80, 0x00, //@+.........
+ 0xf0, 0x00, //@@@%.......
+ 0x7c, 0x00, //+%@@@@+....
+ 0x0f, 0x80, //...+@@@@%+.
+ 0x03, 0xe0, //.....+%@@@@
+ 0x03, 0xe0, //.....+%@@@@
+ 0x0f, 0x80, //...+@@@@%+.
+ 0x7c, 0x00, //+%@@@@+....
+ 0xf0, 0x00, //@@@%+......
+ 0x80, 0x00, //@+.........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+
+
+ /*Unicode: U+003f (?) , Width: 7 */
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x78, //.%@@@+.
+ 0xfc, //@@@@@@+
+ 0x8e, //@+..%@@
+ 0x06, //.....@@
+ 0x06, //....+@%
+ 0x0c, //....@@.
+ 0x18, //...@@..
+ 0x30, //..@@...
+ 0x30, //..@@...
+ 0x30, //..@@...
+ 0x00, //.......
+ 0x30, //..@@...
+ 0x30, //..@@...
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+
+
+ /*Unicode: U+0040 (@) , Width: 16 */
+ 0x00, 0x00, //................
+ 0x00, 0x00, //................
+ 0x00, 0x00, //................
+ 0x07, 0xe0, //.....%@@@@%+....
+ 0x1f, 0xf8, //...%@@@@@@@@@+..
+ 0x3c, 0x1c, //..%@@%....+%@@+.
+ 0x70, 0x06, //.%@@........+@@.
+ 0x60, 0x03, //.@@..........+@%
+ 0xe3, 0x63, //%@%...@@.@@...@@
+ 0xc7, 0xe3, //@@...%@@@@@...@@
+ 0xc6, 0x63, //@@...@@..@@..+@@
+ 0xc6, 0x66, //@@...@@..@@.+@@+
+ 0xc7, 0xfc, //@@...%@@@@@@@@+.
+ 0xe3, 0x70, //%@%...@@.@@%+...
+ 0x60, 0x00, //.@@.............
+ 0x70, 0x00, //.%@@............
+ 0x3c, 0x30, //..@@@+....+@....
+ 0x1f, 0xf0, //...%@@@@@@@@....
+ 0x07, 0xc0, //....+%@@@%+.....
+ 0x00, 0x00, //................
+
+
+ /*Unicode: U+0041 (A) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //....+@@+....
+ 0x0f, 0x00, //....@@@@....
+ 0x0f, 0x00, //....@@@@....
+ 0x19, 0x80, //...%@++@%...
+ 0x19, 0x80, //...@@..@@...
+ 0x19, 0x80, //..+@%..%@+..
+ 0x30, 0xc0, //..@@....@@..
+ 0x3f, 0xc0, //..@@@@@@@@..
+ 0x7f, 0xe0, //.%@@@@@@@@%.
+ 0x60, 0x60, //.@@......@@.
+ 0x60, 0x60, //+@%......%@+
+ 0xc0, 0x30, //@@+......+@@
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+0042 (B) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0xfc, 0x00, //@@@@@@+..
+ 0xff, 0x00, //@@@@@@@%.
+ 0xc3, 0x00, //@@...+@@.
+ 0xc3, 0x00, //@@....@@.
+ 0xc3, 0x00, //@@...+@%.
+ 0xfe, 0x00, //@@@@@@%..
+ 0xfe, 0x00, //@@@@@@@+.
+ 0xc3, 0x00, //@@....%@+
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc3, 0x80, //@@....%@@
+ 0xff, 0x00, //@@@@@@@@+
+ 0xfe, 0x00, //@@@@@@%..
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+0043 (C) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x0f, 0xc0, //...+%@@@@%.
+ 0x3f, 0xe0, //..@@@@@@@@@
+ 0x70, 0x20, //.@@@+....+@
+ 0x60, 0x00, //+@@........
+ 0xc0, 0x00, //%@+........
+ 0xc0, 0x00, //@@.........
+ 0xc0, 0x00, //@@.........
+ 0xc0, 0x00, //@@.........
+ 0xc0, 0x00, //%@+........
+ 0x60, 0x00, //+@@........
+ 0x70, 0x20, //.@@@+....+@
+ 0x3f, 0xe0, //..@@@@@@@@@
+ 0x0f, 0xc0, //...+%@@@@%.
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+
+
+ /*Unicode: U+0044 (D) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0xfe, 0x00, //@@@@@@%+...
+ 0xff, 0x80, //@@@@@@@@@..
+ 0xc1, 0xc0, //@@....+@@@.
+ 0xc0, 0xc0, //@@......@@+
+ 0xc0, 0x60, //@@......+@@
+ 0xc0, 0x60, //@@.......@@
+ 0xc0, 0x60, //@@.......@@
+ 0xc0, 0x60, //@@.......@@
+ 0xc0, 0x60, //@@......+@@
+ 0xc0, 0xc0, //@@......@@+
+ 0xc1, 0xc0, //@@....+@@@.
+ 0xff, 0x80, //@@@@@@@@@..
+ 0xfe, 0x00, //@@@@@@%+...
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+
+
+ /*Unicode: U+0045 (E) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0xff, //@@@@@@@@
+ 0xff, //@@@@@@@@
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xff, //@@@@@@@@
+ 0xff, //@@@@@@@@
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xff, //@@@@@@@@
+ 0xff, //@@@@@@@@
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+0046 (F) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0xff, //@@@@@@@@
+ 0xff, //@@@@@@@@
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xfe, //@@@@@@@.
+ 0xfe, //@@@@@@@.
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+0047 (G) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x0f, 0xc0, //...+%@@@@%.
+ 0x3f, 0xe0, //..@@@@@@@@@
+ 0x70, 0x20, //.@@@+....+@
+ 0x60, 0x00, //+@@........
+ 0xc0, 0x00, //%@+........
+ 0xc3, 0xe0, //@@....@@@@@
+ 0xc3, 0xe0, //@@....@@@@@
+ 0xc0, 0x60, //@@.......@@
+ 0xc0, 0x60, //@@+......@@
+ 0x60, 0x60, //+@@......@@
+ 0x70, 0x60, //.@@@+...+@@
+ 0x3f, 0xc0, //..@@@@@@@@+
+ 0x0f, 0x80, //...+@@@@%..
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+
+
+ /*Unicode: U+0048 (H) , Width: 10 */
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xff, 0xc0, //@@@@@@@@@@
+ 0xff, 0xc0, //@@@@@@@@@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+
+
+ /*Unicode: U+0049 (I) , Width: 2 */
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+
+
+ /*Unicode: U+004a (J) , Width: 4 */
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x70, //.%@%
+ 0xe0, //@@@.
+ 0xc0, //@%..
+
+
+ /*Unicode: U+004b (K) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0xc1, 0x80, //@@.....@@+.
+ 0xc3, 0x00, //@@....@@+..
+ 0xc6, 0x00, //@@...@@+...
+ 0xcc, 0x00, //@@..@@+....
+ 0xd8, 0x00, //@@.@@+.....
+ 0xf0, 0x00, //@@@@+......
+ 0xf0, 0x00, //@@@@.......
+ 0xd8, 0x00, //@@+@@......
+ 0xcc, 0x00, //@@.+@@.....
+ 0xc6, 0x00, //@@..+@@....
+ 0xc3, 0x00, //@@...+@@...
+ 0xc1, 0x80, //@@....+@@..
+ 0xc0, 0xc0, //@@.....+@@+
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+
+
+ /*Unicode: U+004c (L) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xff, //@@@@@@@@
+ 0xff, //@@@@@@@@
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+004d (M) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0xe0, 0x70, //@@@+....+@@@
+ 0xf0, 0xf0, //@@@%....%@@@
+ 0xf0, 0xf0, //@@%@....@%@@
+ 0xd8, 0xb0, //@@.@+..+@.@@
+ 0xd9, 0xb0, //@@.@@..@@.@@
+ 0xd9, 0xb0, //@@.%@..@+.@@
+ 0xcf, 0x30, //@@..@%%@..@@
+ 0xcf, 0x30, //@@..@@@@..@@
+ 0xc6, 0x30, //@@..+@@+..@@
+ 0xc6, 0x30, //@@...@@...@@
+ 0xc0, 0x30, //@@........@@
+ 0xc0, 0x30, //@@........@@
+ 0xc0, 0x30, //@@........@@
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+004e (N) , Width: 10 */
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0xe0, 0xc0, //@@%.....@@
+ 0xe0, 0xc0, //@@@.....@@
+ 0xf0, 0xc0, //@@@%....@@
+ 0xf0, 0xc0, //@@%@+...@@
+ 0xd8, 0xc0, //@@.@@...@@
+ 0xd8, 0xc0, //@@.%@+..@@
+ 0xcc, 0xc0, //@@..@@..@@
+ 0xc6, 0xc0, //@@..+@%.@@
+ 0xc6, 0xc0, //@@...@@.@@
+ 0xc3, 0xc0, //@@...+@@@@
+ 0xc3, 0xc0, //@@....%@@@
+ 0xc1, 0xc0, //@@.....@@@
+ 0xc1, 0xc0, //@@.....%@@
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+
+
+ /*Unicode: U+004f (O) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x0f, 0x80, //...+@@@@+...
+ 0x3f, 0xc0, //..@@@@@@@@..
+ 0x70, 0xe0, //.@@@+..+@@@.
+ 0x60, 0x60, //+@@......@@+
+ 0xc0, 0x30, //%@+......+@%
+ 0xc0, 0x30, //@@........@@
+ 0xc0, 0x30, //@@........@@
+ 0xc0, 0x30, //@@........@@
+ 0xc0, 0x30, //%@+......+@%
+ 0x60, 0x60, //+@@......@@+
+ 0x70, 0xe0, //.@@@+..+@@@.
+ 0x3f, 0xc0, //..@@@@@@@@..
+ 0x1f, 0x80, //...+@@@@+...
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+0050 (P) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0xfc, //@@@@@%+.
+ 0xfe, //@@@@@@@+
+ 0xc7, //@@...%@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc7, //@@...%@@
+ 0xfe, //@@@@@@@+
+ 0xfc, //@@@@@@+.
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+0051 (Q) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x0f, 0x80, //...+@@@@%...
+ 0x3f, 0xc0, //..@@@@@@@@..
+ 0x70, 0xe0, //.@@@+..+@@@.
+ 0x60, 0x60, //+@@......@@+
+ 0xc0, 0x30, //%@+......+@@
+ 0xc0, 0x30, //@@........@@
+ 0xc0, 0x30, //@@........@@
+ 0xc0, 0x30, //@@........@@
+ 0xc0, 0x30, //%@+......+@%
+ 0x60, 0x60, //+@@......@@+
+ 0x70, 0xe0, //.@@@+..+@@%.
+ 0x3f, 0xc0, //..@@@@@@@%..
+ 0x1f, 0x80, //...%@@@@%...
+ 0x01, 0x80, //......+@@+..
+ 0x00, 0xc0, //.......+@@+.
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+0052 (R) , Width: 10 */
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0xfc, 0x00, //@@@@@@+...
+ 0xfe, 0x00, //@@@@@@@+..
+ 0xc7, 0x00, //@@...%@@..
+ 0xc3, 0x00, //@@....@@..
+ 0xc3, 0x00, //@@....@@..
+ 0xc7, 0x00, //@@...%@%..
+ 0xfe, 0x00, //@@@@@@@...
+ 0xfc, 0x00, //@@@@@@+...
+ 0xc6, 0x00, //@@..+@@...
+ 0xc3, 0x00, //@@...+@@..
+ 0xc3, 0x00, //@@....@@+.
+ 0xc1, 0x80, //@@....+@@.
+ 0xc1, 0xc0, //@@.....%@%
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+
+
+ /*Unicode: U+0053 (S) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x3e, 0x00, //..%@@@%..
+ 0x7f, 0x00, //+@@@@@@@.
+ 0xe1, 0x00, //@@%...+%.
+ 0xc0, 0x00, //@@.......
+ 0xc0, 0x00, //@@+......
+ 0x7c, 0x00, //+@@@@%+..
+ 0x3f, 0x00, //..%@@@@@.
+ 0x03, 0x80, //.....+@@%
+ 0x01, 0x80, //.......@@
+ 0x01, 0x80, //.......@@
+ 0x83, 0x80, //@+....%@@
+ 0xff, 0x00, //@@@@@@@@+
+ 0x7e, 0x00, //.%@@@@%..
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+0054 (T) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0xff, 0xf0, //@@@@@@@@@@@@
+ 0xff, 0xf0, //@@@@@@@@@@@@
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+0055 (U) , Width: 10 */
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@+....+@@
+ 0x61, 0x80, //+@@+..+@@+
+ 0x7f, 0x80, //.@@@@@@@@.
+ 0x1e, 0x00, //..+@@@@+..
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+
+
+ /*Unicode: U+0056 (V) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0xc0, 0x30, //@@+......+@@
+ 0x60, 0x60, //+@%......%@+
+ 0x60, 0x60, //.@@......@@.
+ 0x60, 0x60, //.%@+....+@%.
+ 0x30, 0xc0, //..@@....@@..
+ 0x30, 0xc0, //..@@....@@..
+ 0x19, 0x80, //..+@%..%@+..
+ 0x19, 0x80, //...@@..@@...
+ 0x19, 0x80, //...%@++@%...
+ 0x0f, 0x00, //....@@@@+...
+ 0x0f, 0x00, //....@@@@....
+ 0x06, 0x00, //....+@@+....
+ 0x06, 0x00, //.....@@.....
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+0057 (W) , Width: 17 */
+ 0x00, 0x00, 0x00, //.................
+ 0x00, 0x00, 0x00, //.................
+ 0x00, 0x00, 0x00, //.................
+ 0xc1, 0xc1, 0x80, //@@.....@@@.....@@
+ 0xc1, 0xc1, 0x80, //%@+...+@@@+...+@%
+ 0x63, 0xe3, 0x00, //+@%...%@%@%...%@+
+ 0x63, 0x63, 0x00, //.@@...@@.@@...@@.
+ 0x63, 0x63, 0x00, //.@@...@@.@@...@@.
+ 0x63, 0x63, 0x00, //.%@+.+@%.%@+.+@%.
+ 0x36, 0x36, 0x00, //.+@%.%@+.+@%.%@+.
+ 0x36, 0x36, 0x00, //..@@.@@...@@.@@..
+ 0x36, 0x36, 0x00, //..@@+@@...@@+@@..
+ 0x3e, 0x3e, 0x00, //..%@@@%...%@@@%..
+ 0x1c, 0x1c, 0x00, //..+@@@+...+@@@+..
+ 0x1c, 0x1c, 0x00, //...@@@.....@@@...
+ 0x1c, 0x1c, 0x00, //...@@@.....@@%...
+ 0x00, 0x00, 0x00, //.................
+ 0x00, 0x00, 0x00, //.................
+ 0x00, 0x00, 0x00, //.................
+ 0x00, 0x00, 0x00, //.................
+
+
+ /*Unicode: U+0058 (X) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x70, 0xe0, //.%@%....%@%
+ 0x30, 0xc0, //..@@+..+@@.
+ 0x39, 0x80, //..%@@..@@+.
+ 0x1b, 0x80, //...@@+%@%..
+ 0x0f, 0x00, //...+@@@@...
+ 0x0e, 0x00, //....%@@+...
+ 0x0e, 0x00, //....%@@....
+ 0x0f, 0x00, //...+@@@@...
+ 0x1b, 0x00, //...@@+@@+..
+ 0x39, 0x80, //..%@%.+@@..
+ 0x31, 0xc0, //.+@@...@@%.
+ 0x60, 0xc0, //.@@+....@@.
+ 0xe0, 0xe0, //%@@.....%@%
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+
+
+ /*Unicode: U+0059 (Y) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0xe0, 0x70, //%@@......@@%
+ 0x60, 0x60, //.@@+....+@@.
+ 0x30, 0xc0, //..@@....@@..
+ 0x19, 0x80, //..+@%..%@+..
+ 0x19, 0x80, //...%@++@%...
+ 0x0f, 0x00, //....@@@@....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //.....@@.....
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+005a (Z) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0xff, 0xe0, //@@@@@@@@@@@
+ 0xff, 0xe0, //@@@@@@@@@@@
+ 0x01, 0xc0, //.......%@@.
+ 0x03, 0x80, //......%@@..
+ 0x03, 0x00, //.....+@@+..
+ 0x07, 0x00, //.....@@%...
+ 0x0e, 0x00, //....@@%....
+ 0x1c, 0x00, //...%@@.....
+ 0x18, 0x00, //..+@@......
+ 0x30, 0x00, //.+@@+......
+ 0x70, 0x00, //.@@%.......
+ 0xff, 0xe0, //@@@@@@@@@@@
+ 0xff, 0xe0, //@@@@@@@@@@@
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+
+
+ /*Unicode: U+005b ([) , Width: 4 */
+ 0x00, //....
+ 0x00, //....
+ 0xf0, //@@@@
+ 0xf0, //@@@@
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xc0, //@@..
+ 0xf0, //@@@@
+ 0xf0, //@@@@
+ 0x00, //....
+ 0x00, //....
+
+
+ /*Unicode: U+005c (\) , Width: 6 */
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0xc0, //@@....
+ 0xc0, //%@+...
+ 0x60, //+@%...
+ 0x60, //.@@...
+ 0x60, //.@@+..
+ 0x70, //.%@%..
+ 0x30, //.+@@..
+ 0x30, //..@@..
+ 0x30, //..@@+.
+ 0x38, //..+@%.
+ 0x18, //...@@.
+ 0x18, //...@@.
+ 0x18, //...%@+
+ 0x0c, //...+@%
+ 0x0c, //....@@
+ 0x00, //......
+ 0x00, //......
+
+
+ /*Unicode: U+005d (]) , Width: 4 */
+ 0x00, //....
+ 0x00, //....
+ 0xf0, //@@@@
+ 0xf0, //@@@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0xf0, //@@@@
+ 0xf0, //@@@@
+ 0x00, //....
+ 0x00, //....
+
+
+ /*Unicode: U+005e (^) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x0e, 0x00, //....@@@....
+ 0x1f, 0x00, //...%@%@%...
+ 0x31, 0x80, //..%@+.+@%..
+ 0x60, 0xc0, //.%@+...+@%.
+ 0xc0, 0x60, //%@+.....+@%
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+
+
+ /*Unicode: U+005f (_) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0xff, 0x80, //@@@@@@@@@
+ 0xff, 0x80, //@@@@@@@@@
+
+
+ /*Unicode: U+0060 (`) , Width: 4 */
+ 0x00, //....
+ 0x00, //....
+ 0xc0, //%@..
+ 0x60, //.%@.
+ 0x30, //..%%
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+ 0x00, //....
+
+
+ /*Unicode: U+0061 (a) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x3c, //.+%@@@+.
+ 0x7e, //.@@@@@@.
+ 0x47, //.%...%@%
+ 0x03, //......@@
+ 0x3f, //.+@@@@@@
+ 0xff, //%@@@@@@@
+ 0xc3, //@@+...@@
+ 0xc7, //@@+..%@@
+ 0xff, //%@@@@%@@
+ 0x7b, //.%@@%.@@
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+0062 (b) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0xc0, 0x00, //@@.......
+ 0xc0, 0x00, //@@.......
+ 0xc0, 0x00, //@@.......
+ 0xc0, 0x00, //@@.......
+ 0xde, 0x00, //@@.%@@%..
+ 0xff, 0x00, //@@%@@@@@.
+ 0xe3, 0x80, //@@@...@@%
+ 0xc1, 0x80, //@@+...+@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@+...+@@
+ 0xe3, 0x80, //@@@...@@%
+ 0xff, 0x00, //@@%@@@@@.
+ 0xde, 0x00, //@@.%@@%..
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+0063 (c) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x1e, //..+@@@%+
+ 0x7f, //.%@@@@@@
+ 0x61, //+@@+...%
+ 0xc0, //@@+.....
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@+.....
+ 0x61, //+@@+...%
+ 0x7f, //.%@@@@@@
+ 0x1e, //..+@@@%+
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+0064 (d) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x01, 0x80, //.......@@
+ 0x01, 0x80, //.......@@
+ 0x01, 0x80, //.......@@
+ 0x01, 0x80, //.......@@
+ 0x3d, 0x80, //..%@@%.@@
+ 0x7f, 0x80, //.@@@@@%@@
+ 0xe3, 0x80, //%@@...@@@
+ 0xc1, 0x80, //@@+...+@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@+...+@@
+ 0xe3, 0x80, //%@@...@@@
+ 0x7f, 0x80, //.@@@@@%@@
+ 0x3d, 0x80, //..%@@%.@@
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+0065 (e) , Width: 10 */
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x1f, 0x00, //..+%@@@%..
+ 0x7f, 0x80, //.%@@@@@@@.
+ 0x61, 0xc0, //+@@+...@@%
+ 0xc0, 0xc0, //@@......@@
+ 0xff, 0xc0, //@@@@@@@@@@
+ 0xff, 0xc0, //@@@@@@@@@@
+ 0xc0, 0x00, //@@........
+ 0x60, 0x40, //+@@+....+@
+ 0x7f, 0xc0, //.%@@@@@@@@
+ 0x1f, 0x80, //..+%@@@@%.
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+
+
+ /*Unicode: U+0066 (f) , Width: 7 */
+ 0x00, //.......
+ 0x00, //.......
+ 0x1e, //...%@@@
+ 0x3e, //..%@@@@
+ 0x30, //..@@+..
+ 0x30, //..@@...
+ 0xfe, //@@@@@@@
+ 0xfe, //@@@@@@@
+ 0x30, //..@@...
+ 0x30, //..@@...
+ 0x30, //..@@...
+ 0x30, //..@@...
+ 0x30, //..@@...
+ 0x30, //..@@...
+ 0x30, //..@@...
+ 0x30, //..@@...
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+
+
+ /*Unicode: U+0067 (g) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x3d, 0x80, //..%@@%.@@
+ 0x7f, 0x80, //.@@@@@%@@
+ 0xe3, 0x80, //%@@...@@@
+ 0xc1, 0x80, //@@+...+@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@+...+@@
+ 0xe3, 0x80, //%@@...@@@
+ 0x7f, 0x80, //.@@@@@%@@
+ 0x3d, 0x80, //..%@@%.@@
+ 0x01, 0x80, //......+@%
+ 0x43, 0x00, //.%...+@@+
+ 0x7f, 0x00, //.@@@@@@@.
+ 0x3e, 0x00, //.+%@@@%..
+
+
+ /*Unicode: U+0068 (h) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xc0, //@@......
+ 0xde, //@@.%@@%.
+ 0xfe, //@@%@@@@+
+ 0xe7, //@@@..%@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+0069 (i) , Width: 2 */
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+
+
+ /*Unicode: U+006a (j) , Width: 4 */
+ 0x00, //....
+ 0x00, //....
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x00, //....
+ 0x00, //....
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //..@@
+ 0x30, //.+@@
+ 0xe0, //@@@+
+ 0xc0, //@@+.
+
+
+ /*Unicode: U+006b (k) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0xc0, 0x00, //@@.......
+ 0xc0, 0x00, //@@.......
+ 0xc0, 0x00, //@@.......
+ 0xc0, 0x00, //@@.......
+ 0xc3, 0x00, //@@....@@+
+ 0xc6, 0x00, //@@..+@@+.
+ 0xcc, 0x00, //@@.+@@+..
+ 0xd8, 0x00, //@@+@@+...
+ 0xf0, 0x00, //@@@@.....
+ 0xf0, 0x00, //@@@@+....
+ 0xd8, 0x00, //@@+@@+...
+ 0xcc, 0x00, //@@.+@@+..
+ 0xc6, 0x00, //@@..+@@+.
+ 0xc3, 0x00, //@@...+@@+
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+
+
+ /*Unicode: U+006c (l) , Width: 2 */
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+ 0x00, //..
+
+
+ /*Unicode: U+006d (m) , Width: 14 */
+ 0x00, 0x00, //..............
+ 0x00, 0x00, //..............
+ 0x00, 0x00, //..............
+ 0x00, 0x00, //..............
+ 0x00, 0x00, //..............
+ 0x00, 0x00, //..............
+ 0xdc, 0x78, //@@.%@@+..%@@%.
+ 0xfe, 0xf8, //@@%@@@@+@@@@@+
+ 0xe7, 0x9c, //@@@..%@@@..%@@
+ 0xc3, 0x0c, //@@....@@....@@
+ 0xc3, 0x0c, //@@....@@....@@
+ 0xc3, 0x0c, //@@....@@....@@
+ 0xc3, 0x0c, //@@....@@....@@
+ 0xc3, 0x0c, //@@....@@....@@
+ 0xc3, 0x0c, //@@....@@....@@
+ 0xc3, 0x0c, //@@....@@....@@
+ 0x00, 0x00, //..............
+ 0x00, 0x00, //..............
+ 0x00, 0x00, //..............
+ 0x00, 0x00, //..............
+
+
+ /*Unicode: U+006e (n) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0xde, //@@.%@@%.
+ 0xfe, //@@%@@@@+
+ 0xe7, //@@@..%@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+006f (o) , Width: 10 */
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x1e, 0x00, //..+@@@@+..
+ 0x7f, 0x80, //.%@@@@@@%.
+ 0x61, 0x80, //+@@+..+@@+
+ 0xc0, 0xc0, //@@+....+@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@......@@
+ 0xc0, 0xc0, //@@+....+@@
+ 0x61, 0x80, //+@@+..+@@+
+ 0x7f, 0x80, //.%@@@@@@%.
+ 0x1e, 0x00, //..+@@@@+..
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+
+
+ /*Unicode: U+0070 (p) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0xde, 0x00, //@@.%@@%..
+ 0xff, 0x00, //@@%@@@@@.
+ 0xe3, 0x80, //@@@...@@%
+ 0xc1, 0x80, //@@+...+@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@+...+@@
+ 0xe3, 0x80, //@@@...@@%
+ 0xff, 0x00, //@@%@@@@@.
+ 0xde, 0x00, //@@.%@@%..
+ 0xc0, 0x00, //@@.......
+ 0xc0, 0x00, //@@.......
+ 0xc0, 0x00, //@@.......
+ 0xc0, 0x00, //@@.......
+
+
+ /*Unicode: U+0071 (q) , Width: 9 */
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x00, 0x00, //.........
+ 0x3d, 0x80, //..%@@%.@@
+ 0x7f, 0x80, //.@@@@@%@@
+ 0xe3, 0x80, //%@@...@@@
+ 0xc1, 0x80, //@@+...+@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@.....@@
+ 0xc1, 0x80, //@@+...+@@
+ 0xe3, 0x80, //%@@...@@@
+ 0x7f, 0x80, //.@@@@@%@@
+ 0x3d, 0x80, //..%@@%.@@
+ 0x01, 0x80, //.......@@
+ 0x01, 0x80, //.......@@
+ 0x01, 0x80, //.......@@
+ 0x01, 0x80, //.......@@
+
+
+ /*Unicode: U+0072 (r) , Width: 6 */
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0xdc, //@@.%@@
+ 0xfc, //@@%@@@
+ 0xe0, //@@@+..
+ 0xc0, //@@+...
+ 0xc0, //@@....
+ 0xc0, //@@....
+ 0xc0, //@@....
+ 0xc0, //@@....
+ 0xc0, //@@....
+ 0xc0, //@@....
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+
+
+ /*Unicode: U+0073 (s) , Width: 7 */
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x7c, //.+@@@%+
+ 0xfe, //%@@@@@@
+ 0xc2, //@@+...%
+ 0xe0, //@@%+...
+ 0x7c, //+@@@@@.
+ 0x1e, //..+%@@%
+ 0x06, //.....@@
+ 0x86, //%+..+@@
+ 0xfe, //@@@@@@%
+ 0x78, //.%@@@+.
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+ 0x00, //.......
+
+
+ /*Unicode: U+0074 (t) , Width: 6 */
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x60, //.@@...
+ 0x60, //.@@...
+ 0x60, //.@@...
+ 0xfc, //@@@@@@
+ 0xfc, //@@@@@@
+ 0x60, //.@@...
+ 0x60, //.@@...
+ 0x60, //.@@...
+ 0x60, //.@@...
+ 0x60, //.@@...
+ 0x60, //.@@+..
+ 0x7c, //.%@@@@
+ 0x3c, //..%@@@
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+ 0x00, //......
+
+
+ /*Unicode: U+0075 (u) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xc3, //@@....@@
+ 0xe7, //@@%..@@@
+ 0x7f, //+@@@@%@@
+ 0x7b, //.%@@%.@@
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+0076 (v) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x60, 0x60, //.@@......@@.
+ 0x60, 0x60, //.%@+....+@%.
+ 0x30, 0xc0, //..@@....@@..
+ 0x30, 0xc0, //..@@....@@..
+ 0x19, 0x80, //..+@%..%@+..
+ 0x19, 0x80, //...@@..@@...
+ 0x19, 0x80, //...%@.+@%...
+ 0x0f, 0x00, //...+@%@@....
+ 0x0f, 0x00, //....@@@@....
+ 0x06, 0x00, //....+@@+....
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+
+
+ /*Unicode: U+0077 (w) , Width: 15 */
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x63, 0x8c, //.@@...@@@...@@.
+ 0x63, 0x8c, //.@@...@@@...@@.
+ 0x63, 0x8c, //.%@+.+@@@+.+@%.
+ 0x36, 0xd8, //.+@%.%@+@%.%@+.
+ 0x36, 0xd8, //..@@.@@.@@.@@..
+ 0x36, 0xd8, //..@@.@%.%@.@@..
+ 0x3c, 0x78, //..%@%@+.+@%@%..
+ 0x1c, 0x70, //..+@@@...@@@+..
+ 0x1c, 0x70, //...@@@...@@@...
+ 0x1c, 0x70, //...@@%...%@@...
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+ 0x00, 0x00, //...............
+
+
+ /*Unicode: U+0078 (x) , Width: 10 */
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0xe1, 0xc0, //%@@....@@%
+ 0x61, 0x80, //.@@+..+@@.
+ 0x33, 0x00, //.+@@..@@..
+ 0x33, 0x00, //..%@++@%..
+ 0x1e, 0x00, //...@@@@...
+ 0x1e, 0x00, //...@@@@...
+ 0x33, 0x00, //..%@++@%..
+ 0x33, 0x00, //.+@@..@@+.
+ 0x61, 0x80, //.@@+..+@@.
+ 0xe1, 0xc0, //%@@....@@%
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+ 0x00, 0x00, //..........
+
+
+ /*Unicode: U+0079 (y) , Width: 12 */
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x00, 0x00, //............
+ 0x60, 0x60, //.@@......@@.
+ 0x60, 0x60, //.%@+....+@%.
+ 0x30, 0xc0, //..@@....@@..
+ 0x30, 0xc0, //..%@+..+@@..
+ 0x19, 0x80, //...@@..@@+..
+ 0x19, 0x80, //...@@+.@@...
+ 0x0f, 0x00, //...+@%%@+...
+ 0x0f, 0x00, //....@@@@....
+ 0x06, 0x00, //....+@@+....
+ 0x06, 0x00, //.....@@.....
+ 0x06, 0x00, //....+@%.....
+ 0x0c, 0x00, //....%@......
+ 0x3c, 0x00, //..@@@%......
+ 0x38, 0x00, //..@@%.......
+
+
+ /*Unicode: U+007a (z) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0xff, //@@@@@@@@
+ 0xff, //@@@@@@@@
+ 0x06, //....+@@.
+ 0x0c, //....@@+.
+ 0x1c, //...@@@..
+ 0x38, //..%@@...
+ 0x30, //.+@@+...
+ 0x70, //.@@%....
+ 0xff, //@@@@@@@@
+ 0xff, //@@@@@@@@
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+ 0x00, //........
+
+
+ /*Unicode: U+007b ({) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0x0f, //....%@@@
+ 0x1f, //...%@@@@
+ 0x18, //...@@+..
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x38, //..%@@...
+ 0xf0, //@@@@....
+ 0xf0, //@@@@....
+ 0x38, //..%@%...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@+..
+ 0x1f, //...%@@@@
+ 0x0f, //....%@@@
+ 0x00, //........
+
+
+ /*Unicode: U+007c (|) , Width: 2 */
+ 0x00, //..
+ 0x00, //..
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+ 0xc0, //@@
+
+
+ /*Unicode: U+007d (}) , Width: 8 */
+ 0x00, //........
+ 0x00, //........
+ 0xf0, //@@@%....
+ 0xf8, //@@@@%...
+ 0x18, //..+@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x1c, //...@@%..
+ 0x0f, //....@@@@
+ 0x0f, //....@@@@
+ 0x1c, //...%@%..
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //...@@...
+ 0x18, //..+@@...
+ 0xf8, //@@@@%...
+ 0xf0, //@@@%....
+ 0x00, //........
+
+
+ /*Unicode: U+007e (~) , Width: 11 */
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x7c, 0x20, //.%@@@%...+@
+ 0xff, 0xe0, //@@@@@@@@@@@
+ 0x87, 0xc0, //@+...%@@@%.
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+ 0x00, 0x00, //...........
+};
+
+typedef struct
+{
+ uint32_t w_px :8;
+ uint32_t glyph_index :24;
+} lcd_console_font_glyph_dsc_t;
+
+/*Store the glyph descriptions*/
+static const lcd_console_font_glyph_dsc_t lcd_console_font_dejavu_20_glyph_dsc[] = {
+ {.w_px = 6, .glyph_index = 0}, /*Unicode: U+0020 ( )*/
+ {.w_px = 2, .glyph_index = 20}, /*Unicode: U+0021 (!)*/
+ {.w_px = 6, .glyph_index = 40}, /*Unicode: U+0022 (")*/
+ {.w_px = 12, .glyph_index = 60}, /*Unicode: U+0023 (#)*/
+ {.w_px = 9, .glyph_index = 100}, /*Unicode: U+0024 ($)*/
+ {.w_px = 15, .glyph_index = 140}, /*Unicode: U+0025 (%)*/
+ {.w_px = 12, .glyph_index = 180}, /*Unicode: U+0026 (&)*/
+ {.w_px = 2, .glyph_index = 220}, /*Unicode: U+0027 (')*/
+ {.w_px = 4, .glyph_index = 240}, /*Unicode: U+0028 (()*/
+ {.w_px = 4, .glyph_index = 260}, /*Unicode: U+0029 ())*/
+ {.w_px = 7, .glyph_index = 280}, /*Unicode: U+002a (*)*/
+ {.w_px = 12, .glyph_index = 300}, /*Unicode: U+002b (+)*/
+ {.w_px = 3, .glyph_index = 340}, /*Unicode: U+002c (,)*/
+ {.w_px = 5, .glyph_index = 360}, /*Unicode: U+002d (-)*/
+ {.w_px = 2, .glyph_index = 380}, /*Unicode: U+002e (.)*/
+ {.w_px = 6, .glyph_index = 400}, /*Unicode: U+002f (/)*/
+ {.w_px = 9, .glyph_index = 420}, /*Unicode: U+0030 (0)*/
+ {.w_px = 8, .glyph_index = 460}, /*Unicode: U+0031 (1)*/
+ {.w_px = 9, .glyph_index = 480}, /*Unicode: U+0032 (2)*/
+ {.w_px = 9, .glyph_index = 520}, /*Unicode: U+0033 (3)*/
+ {.w_px = 10, .glyph_index = 560}, /*Unicode: U+0034 (4)*/
+ {.w_px = 8, .glyph_index = 600}, /*Unicode: U+0035 (5)*/
+ {.w_px = 9, .glyph_index = 620}, /*Unicode: U+0036 (6)*/
+ {.w_px = 8, .glyph_index = 660}, /*Unicode: U+0037 (7)*/
+ {.w_px = 9, .glyph_index = 680}, /*Unicode: U+0038 (8)*/
+ {.w_px = 9, .glyph_index = 720}, /*Unicode: U+0039 (9)*/
+ {.w_px = 2, .glyph_index = 760}, /*Unicode: U+003a (:)*/
+ {.w_px = 3, .glyph_index = 780}, /*Unicode: U+003b (;)*/
+ {.w_px = 11, .glyph_index = 800}, /*Unicode: U+003c (<)*/
+ {.w_px = 11, .glyph_index = 840}, /*Unicode: U+003d (=)*/
+ {.w_px = 11, .glyph_index = 880}, /*Unicode: U+003e (>)*/
+ {.w_px = 7, .glyph_index = 920}, /*Unicode: U+003f (?)*/
+ {.w_px = 16, .glyph_index = 940}, /*Unicode: U+0040 (@)*/
+ {.w_px = 12, .glyph_index = 980}, /*Unicode: U+0041 (A)*/
+ {.w_px = 9, .glyph_index = 1020}, /*Unicode: U+0042 (B)*/
+ {.w_px = 11, .glyph_index = 1060}, /*Unicode: U+0043 (C)*/
+ {.w_px = 11, .glyph_index = 1100}, /*Unicode: U+0044 (D)*/
+ {.w_px = 8, .glyph_index = 1140}, /*Unicode: U+0045 (E)*/
+ {.w_px = 8, .glyph_index = 1160}, /*Unicode: U+0046 (F)*/
+ {.w_px = 11, .glyph_index = 1180}, /*Unicode: U+0047 (G)*/
+ {.w_px = 10, .glyph_index = 1220}, /*Unicode: U+0048 (H)*/
+ {.w_px = 2, .glyph_index = 1260}, /*Unicode: U+0049 (I)*/
+ {.w_px = 4, .glyph_index = 1280}, /*Unicode: U+004a (J)*/
+ {.w_px = 11, .glyph_index = 1300}, /*Unicode: U+004b (K)*/
+ {.w_px = 8, .glyph_index = 1340}, /*Unicode: U+004c (L)*/
+ {.w_px = 12, .glyph_index = 1360}, /*Unicode: U+004d (M)*/
+ {.w_px = 10, .glyph_index = 1400}, /*Unicode: U+004e (N)*/
+ {.w_px = 12, .glyph_index = 1440}, /*Unicode: U+004f (O)*/
+ {.w_px = 8, .glyph_index = 1480}, /*Unicode: U+0050 (P)*/
+ {.w_px = 12, .glyph_index = 1500}, /*Unicode: U+0051 (Q)*/
+ {.w_px = 10, .glyph_index = 1540}, /*Unicode: U+0052 (R)*/
+ {.w_px = 9, .glyph_index = 1580}, /*Unicode: U+0053 (S)*/
+ {.w_px = 12, .glyph_index = 1620}, /*Unicode: U+0054 (T)*/
+ {.w_px = 10, .glyph_index = 1660}, /*Unicode: U+0055 (U)*/
+ {.w_px = 12, .glyph_index = 1700}, /*Unicode: U+0056 (V)*/
+ {.w_px = 17, .glyph_index = 1740}, /*Unicode: U+0057 (W)*/
+ {.w_px = 11, .glyph_index = 1800}, /*Unicode: U+0058 (X)*/
+ {.w_px = 12, .glyph_index = 1840}, /*Unicode: U+0059 (Y)*/
+ {.w_px = 11, .glyph_index = 1880}, /*Unicode: U+005a (Z)*/
+ {.w_px = 4, .glyph_index = 1920}, /*Unicode: U+005b ([)*/
+ {.w_px = 6, .glyph_index = 1940}, /*Unicode: U+005c (\)*/
+ {.w_px = 4, .glyph_index = 1960}, /*Unicode: U+005d (])*/
+ {.w_px = 11, .glyph_index = 1980}, /*Unicode: U+005e (^)*/
+ {.w_px = 9, .glyph_index = 2020}, /*Unicode: U+005f (_)*/
+ {.w_px = 4, .glyph_index = 2060}, /*Unicode: U+0060 (`)*/
+ {.w_px = 8, .glyph_index = 2080}, /*Unicode: U+0061 (a)*/
+ {.w_px = 9, .glyph_index = 2100}, /*Unicode: U+0062 (b)*/
+ {.w_px = 8, .glyph_index = 2140}, /*Unicode: U+0063 (c)*/
+ {.w_px = 9, .glyph_index = 2160}, /*Unicode: U+0064 (d)*/
+ {.w_px = 10, .glyph_index = 2200}, /*Unicode: U+0065 (e)*/
+ {.w_px = 7, .glyph_index = 2240}, /*Unicode: U+0066 (f)*/
+ {.w_px = 9, .glyph_index = 2260}, /*Unicode: U+0067 (g)*/
+ {.w_px = 8, .glyph_index = 2300}, /*Unicode: U+0068 (h)*/
+ {.w_px = 2, .glyph_index = 2320}, /*Unicode: U+0069 (i)*/
+ {.w_px = 4, .glyph_index = 2340}, /*Unicode: U+006a (j)*/
+ {.w_px = 9, .glyph_index = 2360}, /*Unicode: U+006b (k)*/
+ {.w_px = 2, .glyph_index = 2400}, /*Unicode: U+006c (l)*/
+ {.w_px = 14, .glyph_index = 2420}, /*Unicode: U+006d (m)*/
+ {.w_px = 8, .glyph_index = 2460}, /*Unicode: U+006e (n)*/
+ {.w_px = 10, .glyph_index = 2480}, /*Unicode: U+006f (o)*/
+ {.w_px = 9, .glyph_index = 2520}, /*Unicode: U+0070 (p)*/
+ {.w_px = 9, .glyph_index = 2560}, /*Unicode: U+0071 (q)*/
+ {.w_px = 6, .glyph_index = 2600}, /*Unicode: U+0072 (r)*/
+ {.w_px = 7, .glyph_index = 2620}, /*Unicode: U+0073 (s)*/
+ {.w_px = 6, .glyph_index = 2640}, /*Unicode: U+0074 (t)*/
+ {.w_px = 8, .glyph_index = 2660}, /*Unicode: U+0075 (u)*/
+ {.w_px = 12, .glyph_index = 2680}, /*Unicode: U+0076 (v)*/
+ {.w_px = 15, .glyph_index = 2720}, /*Unicode: U+0077 (w)*/
+ {.w_px = 10, .glyph_index = 2760}, /*Unicode: U+0078 (x)*/
+ {.w_px = 12, .glyph_index = 2800}, /*Unicode: U+0079 (y)*/
+ {.w_px = 8, .glyph_index = 2840}, /*Unicode: U+007a (z)*/
+ {.w_px = 8, .glyph_index = 2860}, /*Unicode: U+007b ({)*/
+ {.w_px = 2, .glyph_index = 2880}, /*Unicode: U+007c (|)*/
+ {.w_px = 8, .glyph_index = 2900}, /*Unicode: U+007d (})*/
+ {.w_px = 11, .glyph_index = 2920}, /*Unicode: U+007e (~)*/
+};
diff --git a/bsp/raspberry-pi/raspi4-32/driver/mbox.c b/bsp/raspberry-pi/raspi4-32/driver/mbox.c
index b0c79e09bd..0f993f945a 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/mbox.c
+++ b/bsp/raspberry-pi/raspi4-32/driver/mbox.c
@@ -49,6 +49,24 @@ int mbox_call(unsigned char ch, int mmu_enable)
return 0;
}
+int bcm271x_mbox_get_touch(void)
+{
+ mbox[0] = 8*4; // length of the message
+ mbox[1] = MBOX_REQUEST; // this is a request message
+
+ mbox[2] = MBOX_TAG_GET_TOUCHBUF;
+ mbox[3] = 4; // buffer size
+ mbox[4] = 0; // len
+
+ mbox[5] = 0; // id
+ mbox[6] = 0;
+
+ mbox[7] = MBOX_TAG_LAST;
+ mbox_call(8, MMU_DISABLE);
+
+ return (int)(mbox[5] & ~0xC0000000);
+}
+
int bcm271x_notify_reboot(void)
{
mbox[0] = 7*4; // length of the message
diff --git a/bsp/raspberry-pi/raspi4-32/driver/mbox.h b/bsp/raspberry-pi/raspi4-32/driver/mbox.h
index ec31370f6b..7a05597de4 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/mbox.h
+++ b/bsp/raspberry-pi/raspi4-32/driver/mbox.h
@@ -132,9 +132,27 @@ enum {
#define MBOX_TAG_NOTIFY_REBOOT 0x00030048
#define MBOX_TAG_NOTIFY_XHCI_RESET 0x00030058
+/*
+* touch
+*/
+#define MBOX_TAG_GET_TOUCHBUF (0x0004000F)
+
#define MBOX_ADDR 0x08000000
+#define RES_CLK_ID (0x000000000)
+#define EMMC_CLK_ID (0x000000001)
+#define UART_CLK_ID (0x000000002)
+#define ARM_CLK_ID (0x000000003)
+#define CORE_CLK_ID (0x000000004)
+#define V3D_CLK_ID (0x000000005)
+#define H264_CLK_ID (0x000000006)
+#define ISP_CLK_ID (0x000000007)
+#define SDRAM_CLK_ID (0x000000008)
+#define PIXEL_CLK_ID (0x000000009)
+#define PWM_CLK_ID (0x00000000a)
+
int mbox_call(unsigned char ch, int mmu_enable);
+int bcm271x_mbox_get_touch(void);
int bcm271x_notify_reboot(void);
int bcm271x_notify_xhci_reset(void);
int bcm271x_gpu_enable(void);
diff --git a/bsp/raspberry-pi/raspi4-32/driver/raspi4.h b/bsp/raspberry-pi/raspi4-32/driver/raspi4.h
index 5a91796d40..72e212ff85 100644
--- a/bsp/raspberry-pi/raspi4-32/driver/raspi4.h
+++ b/bsp/raspberry-pi/raspi4-32/driver/raspi4.h
@@ -150,7 +150,26 @@ typedef enum {
//External Mass Media Controller (SD Card)
#define MMC0_BASE_ADDR (PER_BASE+0x300000)
-#define MMC2_BASE_ADDR (PER_BASE+0x340000)
+#define MMC2_BASE_ADDR (PER_BASE+0x340000)
+
+#define ETH_IRQ (160+29)
+
+//I2C
+#define BSC0_BASE_OFFSET (0x205000)
+#define BSC1_BASE_OFFSET (0x804000)
+#define BSC3_BASE_OFFSET (0x205600)
+#define BSC4_BASE_OFFSET (0x205800)
+#define BSC5_BASE_OFFSET (0x205A80)
+#define BSC6_BASE_OFFSET (0x205C00)
+
+//BSC2 and BSC7 masters are dedicated for use by the
+//HDMI interfaces and should not be accessed byuser programs.
+#define BSC0_BASE (PER_BASE + BSC0_BASE_OFFSET)
+#define BSC1_BASE (PER_BASE + BSC1_BASE_OFFSET)
+#define BSC3_BASE (PER_BASE + BSC3_BASE_OFFSET)
+#define BSC4_BASE (PER_BASE + BSC4_BASE_OFFSET)
+#define BSC5_BASE (PER_BASE + BSC5_BASE_OFFSET)
+#define BSC6_BASE (PER_BASE + BSC6_BASE_OFFSET)
/* the basic constants and interfaces needed by gic */
rt_inline rt_uint32_t platform_get_gic_dist_base(void)
diff --git a/bsp/raspberry-pi/raspi4-32/driver/touch/Sconscript b/bsp/raspberry-pi/raspi4-32/driver/touch/Sconscript
new file mode 100644
index 0000000000..40b20024db
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/touch/Sconscript
@@ -0,0 +1,16 @@
+# RT-Thread building script for component
+
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+if not GetDepend('BSP_USING_XPT_TOUCH_DEV'):
+ SrcRemove(src, ['drv_xpt2046.c'])
+if not GetDepend('BSP_USING_DSI_TOUCH_DEV'):
+ SrcRemove(src, ['drv_dsi_touch.c'])
+
+group = DefineGroup('drv_touch', src, depend = ['BSP_USING_TOUCH'], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/bsp/raspberry-pi/raspi4-32/driver/touch/drv_dsi_touch.c b/bsp/raspberry-pi/raspi4-32/driver/touch/drv_dsi_touch.c
new file mode 100644
index 0000000000..894ef1f25c
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/touch/drv_dsi_touch.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-26 bigmagic first version
+ */
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <touch.h>
+
+#include "mbox.h"
+#include "drv_dsi_touch.h"
+
+#define DBG_TAG "dsi_touch"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+static rt_touch_t touch_device = RT_NULL;
+static struct rt_semaphore dsi_touch_ack;
+
+static rt_uint32_t touch_x;
+static rt_uint32_t touch_y;
+static rt_uint32_t touch_state;
+
+static rt_thread_t dsi_touch_tid = RT_NULL;
+#define DSI_TOUCH_THREAD_STACK_SIZE (4096)
+#define DSI_TOUCH_THREAD_PRIORITY (25)
+#define DSI_TOUCH_THREAD_TIMESLICE (10)
+
+#define MAXIMUM_SUPPORTED_POINTS (10)
+
+struct touch_regs
+{
+ uint8_t device_mode;
+ uint8_t gesture_id;
+ uint8_t num_points;
+ struct touch
+ {
+ uint8_t xh;
+ uint8_t xl;
+ uint8_t yh;
+ uint8_t yl;
+ uint8_t res1;
+ uint8_t res2;
+ } point[MAXIMUM_SUPPORTED_POINTS];
+};
+
+static void dsi_touch_thread_entry(void *param)
+{
+ static volatile uint32_t touchbuf;
+ touchbuf = bcm271x_mbox_get_touch(); //0x0f436000
+
+ if(touchbuf == RT_NULL)
+ {
+ rt_kprintf("init dsi touch err!\n");
+ return;
+ }
+
+ while (1)
+ {
+ struct touch_regs *regs = (struct touch_regs *)touchbuf;
+ if ((regs->num_points > 0) && (regs->num_points < MAXIMUM_SUPPORTED_POINTS))
+ {
+ //only one touch point
+ touch_x = (((int)regs->point[0].xh & 0xf) << 8) + regs->point[0].xl;
+ touch_y = (((int)regs->point[0].yh & 0xf) << 8) + regs->point[0].yl;
+ touch_state = 1;
+ }
+ else
+ {
+ touch_state = 0;
+ }
+ rt_thread_mdelay(50);
+ }
+}
+
+static rt_size_t dsi_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
+{
+ rt_uint16_t* touchxy = (rt_uint16_t *)buf;
+ if((read_num != 0) && (touch_state == 1))
+ {
+ touchxy[0] = touch_x;
+ touchxy[1] = touch_y;
+ touch_state = 0;
+ return read_num;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static rt_err_t dsi_control(struct rt_touch_device *device, int cmd, void *data)
+{
+ return RT_EOK;
+}
+
+static struct rt_touch_ops dsi_touch_ops =
+{
+ .touch_readpoint = dsi_read_point,
+ .touch_control = dsi_control,
+};
+
+static int hw_dsi_touch_init(void)
+{
+ //touch sem
+ rt_sem_init(&dsi_touch_ack, "dsi_touch_ack", 0, RT_IPC_FLAG_FIFO);
+
+ dsi_touch_tid = rt_thread_create("dsi_touch",
+ dsi_touch_thread_entry, RT_NULL,
+ DSI_TOUCH_THREAD_STACK_SIZE,
+ DSI_TOUCH_THREAD_PRIORITY, DSI_TOUCH_THREAD_TIMESLICE);
+ if (dsi_touch_tid != RT_NULL)
+ rt_thread_startup(dsi_touch_tid);
+
+ touch_device = (rt_touch_t)rt_calloc(1, sizeof(struct rt_touch_device));
+
+ if (touch_device == RT_NULL)
+ return -RT_ERROR;
+
+ /* register touch device */
+ touch_device->info.type = RT_TOUCH_TYPE_RESISTANCE;
+ touch_device->info.vendor = RT_TOUCH_VENDOR_UNKNOWN;
+ //rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config));
+ touch_device->ops = &dsi_touch_ops;
+ rt_hw_touch_register(touch_device, "dsi_touch", RT_DEVICE_FLAG_INT_RX, RT_NULL);
+ return 0;
+}
+INIT_DEVICE_EXPORT(hw_dsi_touch_init);
diff --git a/bsp/raspberry-pi/raspi4-32/driver/touch/drv_dsi_touch.h b/bsp/raspberry-pi/raspi4-32/driver/touch/drv_dsi_touch.h
new file mode 100644
index 0000000000..6d6439f199
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/touch/drv_dsi_touch.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-26 bigmagic first version
+ */
+#ifndef __DRV_DSI_TOUCH_H__
+#define __DRV_DSI_TOUCH_H__
+
+#endif//DSI TOUCH
diff --git a/bsp/raspberry-pi/raspi4-32/driver/touch/drv_xpt2046.c b/bsp/raspberry-pi/raspi4-32/driver/touch/drv_xpt2046.c
new file mode 100644
index 0000000000..5c3fcf749c
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/touch/drv_xpt2046.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-08 bigmagic first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <touch.h>
+
+#include "drv_xpt2046.h"
+//http://www.lcdwiki.com/MHS-3.5inch_RPi_Display
+
+#define DBG_TAG "xpt2046"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+//XPT2049
+#define READ_X (0xD0)
+#define READ_Y (0x90)
+
+#define TFT_WIDTH (320)
+#define TFT_HEIGHT (480)
+//freq
+#define TOUCH_SPI_MAX_FREQ (10*1000)
+
+#define TP_IRQ_PIN (17)
+#define TOUCH_DEVICE_NAME ("spi0.1")
+
+static struct rt_semaphore touch_ack;
+static rt_touch_t touch_device = RT_NULL;
+
+static rt_thread_t touch_tid = RT_NULL;
+#define TOUCH_THREAD_STACK_SIZE (1024)
+#define TOUCH_THREAD_PRIORITY (30)
+#define TOUCH_THREAD_TIMESLICE (10)
+
+rt_uint8_t touch_flag = 0;
+rt_uint16_t touch_x_val = 0;
+rt_uint16_t touch_y_val = 0;
+
+extern struct rt_semaphore lcd_spi_lock;
+static void touch_read_x_y(void *dev, rt_uint16_t *x, rt_uint16_t *y)
+{
+ struct rt_spi_device *touch_dev = (struct rt_spi_device *)dev;
+ struct rt_spi_message msg1,msg2,msg3,msg4;
+ rt_uint16_t readx_val = 0,ready_val = 0;
+ rt_uint8_t readx[2];
+ rt_uint8_t ready[2];
+ rt_sem_take(&lcd_spi_lock, RT_WAITING_FOREVER);
+
+ int read_x_id = READ_X;
+ int read_y_id = READ_Y;
+
+ msg1.send_buf = &read_x_id;
+ msg1.recv_buf = RT_NULL;
+ msg1.length = 1;
+ msg1.cs_take = 1;
+ msg1.cs_release = 0;
+ msg1.next = &msg2;
+
+ msg2.send_buf = RT_NULL;
+ msg2.recv_buf = &readx[0];
+ msg2.length = 2;
+ msg2.cs_take = 0;
+ msg2.cs_release = 0;
+ msg2.next = &msg3;
+
+ msg3.send_buf = &read_y_id;
+ msg3.recv_buf = RT_NULL;
+ msg3.length = 1;
+ msg3.cs_take = 0;
+ msg3.cs_release = 0;
+ msg3.next = &msg4;
+
+ msg4.send_buf = RT_NULL;
+ msg4.recv_buf = &ready[0];
+ msg4.length = 2;
+ msg4.cs_take = 0;
+ msg4.cs_release = 1;
+ msg4.next = RT_NULL;
+
+ rt_spi_transfer_message(touch_dev, &msg1);
+
+ readx_val = ((readx[0] << 8) | readx[1]) >> 4;
+ ready_val = ((ready[0] << 8) | ready[1]) >> 4;
+
+ rt_sem_release(&lcd_spi_lock);
+ *x = readx_val;
+ *y = ready_val;
+}
+
+/*
+XPT2046:Width:320 High:480
+no pressed:(0x800,0xfff)
+---ETH----USB-----------------------
+| (0x800,0x800) (0xfff,0x800) |
+| |
+| (0x800,0xFFF) (0xfff,0xfff) |
+------------------------------------
+*/
+#define XMIN 0x800
+#define YMAX 0xfff
+void read_tp(void *dev, rt_uint16_t *x, rt_uint16_t *y)
+{
+ struct rt_spi_device *touch_dev = (struct rt_spi_device *)dev;
+ rt_uint8_t try = 0;
+ uint16_t _y[5] = {0,0,0,0,0};
+ uint16_t _x[5] = {0,0,0,0,0};
+ uint16_t x_val = 0;
+ uint16_t y_val = 0;
+ uint16_t cur_x = 0;
+ uint16_t cur_y = 0;
+ int index = 0;
+
+ while(1)
+ {
+ try = try + 1;
+ touch_read_x_y(touch_dev, x, y);
+ if((*x > XMIN) && (*y < YMAX))
+ {
+ _x[index] = *x;
+ _y[index] = *y;
+ index = index + 1;
+ }
+ if(index == 5)
+ {
+ break;
+ }
+
+ if(try > 10)
+ {
+ break;
+ }
+ }
+
+ x_val = (_x[0] + _x[1] + _x[2] + _x[3]+ _x[4]) / index;
+ y_val = (_y[0] + _y[1] + _y[2] + _y[3]+ _y[4]) / index;
+
+ cur_x = (x_val - 0x800) * TFT_WIDTH / 0x800;
+ cur_y = (y_val - 0x800) * TFT_HEIGHT / 0x800;
+
+ if((cur_x < TFT_WIDTH) && (cur_y < TFT_HEIGHT))
+ {
+ *x = TFT_WIDTH - cur_x;
+ *y = TFT_HEIGHT - cur_y;
+ }
+ else
+ {
+ *x = 0;
+ *y = 0;
+ }
+}
+
+static void touch_thread_entry(void *param)
+{
+ rt_uint16_t x,y;
+ struct rt_spi_device *touch_dev;
+ touch_dev = (struct rt_spi_device *)rt_device_find(TOUCH_DEVICE_NAME);
+ touch_dev->config.max_hz = TOUCH_SPI_MAX_FREQ;
+ if (!touch_dev)
+ {
+ rt_kprintf("no %s!\n", TOUCH_DEVICE_NAME);
+ }
+
+ while (1)
+ {
+ rt_sem_take(&touch_ack, RT_WAITING_FOREVER);
+ read_tp(touch_dev, &x, &y);
+ if((x!= 0) && (y !=0))
+ {
+ touch_x_val = x;
+ touch_y_val = y;
+ touch_flag = 1;
+ }
+ rt_pin_mode(TP_IRQ_PIN, PIN_MODE_INPUT_PULLUP);
+ }
+}
+
+static void touch_readly(void *args)
+{
+ if(rt_pin_read(TP_IRQ_PIN) == PIN_LOW)
+ {
+ rt_pin_mode(TP_IRQ_PIN, PIN_MODE_OUTPUT);
+ rt_pin_write(TP_IRQ_PIN,PIN_HIGH);
+ rt_sem_release(&touch_ack);
+ }
+}
+
+static rt_size_t xpt2046_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
+{
+ rt_uint16_t* touchxy = (rt_uint16_t *)buf;
+ if((read_num != 0) && (touch_flag == 1))
+ {
+ touchxy[0] = touch_x_val;
+ touchxy[1] = touch_y_val;
+ touch_flag = 0;
+ return read_num;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static rt_err_t xpt2046_control(struct rt_touch_device *device, int cmd, void *data)
+{
+ return RT_EOK;
+}
+
+static struct rt_touch_ops touch_ops =
+{
+ .touch_readpoint = xpt2046_read_point,
+ .touch_control = xpt2046_control,
+};
+
+static int hw_xpt2049_touch_init(void)
+{
+ //touch sem
+ rt_sem_init(&touch_ack, "touch_ack", 0, RT_IPC_FLAG_FIFO);
+
+ touch_tid = rt_thread_create("touch",
+ touch_thread_entry, RT_NULL,
+ TOUCH_THREAD_STACK_SIZE,
+ TOUCH_THREAD_PRIORITY, TOUCH_THREAD_TIMESLICE);
+ if (touch_tid != RT_NULL)
+ rt_thread_startup(touch_tid);
+
+ rt_pin_mode(TP_IRQ_PIN, PIN_MODE_INPUT_PULLUP);
+ rt_pin_attach_irq(TP_IRQ_PIN, PIN_IRQ_MODE_LOW_LEVEL, touch_readly, RT_NULL);
+ rt_pin_irq_enable(TP_IRQ_PIN, PIN_IRQ_ENABLE);
+
+ touch_device = (rt_touch_t)rt_calloc(1, sizeof(struct rt_touch_device));
+
+ if (touch_device == RT_NULL)
+ return -RT_ERROR;
+
+ /* register touch device */
+ touch_device->info.type = RT_TOUCH_TYPE_RESISTANCE;
+ touch_device->info.vendor = RT_TOUCH_VENDOR_UNKNOWN;
+ //rt_memcpy(&touch_device->config, cfg, sizeof(struct rt_touch_config));
+ touch_device->ops = &touch_ops;
+
+ rt_hw_touch_register(touch_device, "xpt2046", RT_DEVICE_FLAG_INT_RX, RT_NULL);
+
+ return 0;
+}
+INIT_DEVICE_EXPORT(hw_xpt2049_touch_init);
diff --git a/bsp/raspberry-pi/raspi4-32/driver/touch/drv_xpt2046.h b/bsp/raspberry-pi/raspi4-32/driver/touch/drv_xpt2046.h
new file mode 100644
index 0000000000..5b28c0a7dd
--- /dev/null
+++ b/bsp/raspberry-pi/raspi4-32/driver/touch/drv_xpt2046.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-08 bigmagic first version
+ */
+#ifndef __DRV_XPT2046_H__
+#define __DRV_XPT2046_H__
+
+#endif//XPT2046
diff --git a/bsp/raspberry-pi/raspi4-32/link.lds b/bsp/raspberry-pi/raspi4-32/link.lds
index 3f2f8ca413..92ec03c8f4 100644
--- a/bsp/raspberry-pi/raspi4-32/link.lds
+++ b/bsp/raspberry-pi/raspi4-32/link.lds
@@ -63,6 +63,14 @@ SECTIONS
_etext = .;
}
+ __exidx_start = .;
+ .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+ __exidx_end = .;
+
+ __rodata_start = .;
+ .rodata : { *(.rodata) *(.rodata.*) }
+ __rodata_end = .;
+
.eh_frame_hdr :
{
*(.eh_frame_hdr)
diff --git a/bsp/raspberry-pi/raspi4-32/rtconfig.h b/bsp/raspberry-pi/raspi4-32/rtconfig.h
index 1edd99a549..c31d300cb2 100644
--- a/bsp/raspberry-pi/raspi4-32/rtconfig.h
+++ b/bsp/raspberry-pi/raspi4-32/rtconfig.h
@@ -10,7 +10,7 @@
#define RT_ALIGN_SIZE 4
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
-#define RT_TICK_PER_SECOND 100
+#define RT_TICK_PER_SECOND 1000
#define RT_USING_OVERFLOW_CHECK
#define RT_USING_HOOK
#define RT_USING_IDLE_HOOK
@@ -40,7 +40,7 @@
#define RT_USING_DEVICE
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
-#define RT_CONSOLE_DEVICE_NAME "uart0"
+#define RT_CONSOLE_DEVICE_NAME "uart1"
#define RT_VER_NUM 0x40003
#define ARCH_ARMV8
@@ -94,9 +94,14 @@
#define RT_USING_DEVICE_IPC
#define RT_PIPE_BUFSZ 512
+#define RT_USING_SYSTEM_WORKQUEUE
+#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048
+#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
#define RT_USING_SERIAL
#define RT_SERIAL_USING_DMA
-#define RT_SERIAL_RB_BUFSZ 64
+#define RT_SERIAL_RB_BUFSZ 512
+#define RT_USING_I2C
+#define RT_USING_I2C_BITOPS
#define RT_USING_PIN
#define RT_USING_SDIO
#define RT_SDIO_STACK_SIZE 512
@@ -106,6 +111,7 @@
#define RT_MMCSD_MAX_PARTITION 16
#define RT_USING_SPI
#define RT_USING_WDT
+#define RT_USING_TOUCH
/* Using USB */
@@ -119,6 +125,12 @@
/* Socket abstraction layer */
+#define RT_USING_SAL
+
+/* protocol stack implement */
+
+#define SAL_USING_LWIP
+#define SAL_USING_POSIX
/* Network interface device */
@@ -214,6 +226,9 @@
/* system packages */
+/* Micrium: Micrium software products porting for RT-Thread */
+
+
/* peripheral libraries and drivers */
@@ -223,6 +238,9 @@
/* samples: kernel and components samples */
+/* games: games run on RT-Thread console */
+
+
/* Privated Packages of RealThread */
@@ -236,22 +254,29 @@
#define BSP_USING_UART
#define RT_USING_UART0
+#define RT_USING_UART1
#define RT_USING_UART3
-#define RT_USING_UART4
+#define RT_USING_UART5
#define BSP_USING_GIC
#define BSP_USING_GIC400
#define BSP_USING_PIN
#define BSP_USING_SPI
#define BSP_USING_SPI0_BUS
#define BSP_USING_SPI0_DEVICE0
+#define BSP_USING_SPI0_DEVICE1
+#define BSP_USING_I2C
+#define BSP_USING_I2C3
#define BSP_USING_CORETIMER
#define BSP_USING_WDT
+#define BSP_USING_ETH
#define BSP_USING_SDIO
#define BSP_USING_SDIO0
/* Board Peripheral Drivers */
-#define BSP_USING_HDMI
-#define BSP_USING_HDMI_DISPLAY
+#define BSP_USING_LCD
+#define BSP_USING_DSI_DISPLAY
+#define BSP_USING_TOUCH
+#define BSP_USING_DSI_TOUCH_DEV
#endif
diff --git a/bsp/stm32/libraries/HAL_Drivers/Kconfig b/bsp/stm32/libraries/HAL_Drivers/Kconfig
index 45160eee82..41cf5cf08b 100644
--- a/bsp/stm32/libraries/HAL_Drivers/Kconfig
+++ b/bsp/stm32/libraries/HAL_Drivers/Kconfig
@@ -40,7 +40,21 @@ config BSP_USING_RNG
depends on (SOC_SERIES_STM32L4 || SOC_SERIES_STM32F4 || SOC_SERIES_STM32F7 || \
SOC_SERIES_STM32H7 || SOC_SERIES_STM32MP1)
default n
-
+
+config BSP_USING_HASH
+ bool "Enable HASH (Hash House Harriers)"
+ select RT_USING_HWCRYPTO
+ select RT_HWCRYPTO_USING_HASH
+ depends on (SOC_SERIES_STM32MP1)
+ default n
+
+config BSP_USING_CRYP
+ bool "Enable CRYP (Encrypt And Decrypt Data)"
+ select RT_USING_HWCRYPTO
+ select RT_HWCRYPTO_USING_CRYP
+ depends on (SOC_SERIES_STM32MP1)
+ default n
+
config BSP_USING_UDID
bool "Enable UDID (Unique Device Identifier)"
select RT_USING_HWCRYPTO
diff --git a/bsp/stm32/libraries/HAL_Drivers/config/l4/dac_config.h b/bsp/stm32/libraries/HAL_Drivers/config/l4/dac_config.h
new file mode 100644
index 0000000000..6ca3932831
--- /dev/null
+++ b/bsp/stm32/libraries/HAL_Drivers/config/l4/dac_config.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-06-16 thread-liu first version
+ */
+
+#ifndef __DAC_CONFIG_H__
+#define __DAC_CONFIG_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef BSP_USING_DAC1
+#ifndef DAC1_CONFIG
+#define DAC1_CONFIG \
+ { \
+ .Instance = DAC1, \
+ }
+#endif /* DAC2_CONFIG */
+#endif /* BSP_USING_DAC2 */
+
+#ifdef BSP_USING_DAC2
+#ifndef DAC2_CONFIG
+#define DAC2_CONFIG \
+ { \
+ .Instance = DAC2, \
+ }
+#endif /* DAC2_CONFIG */
+#endif /* BSP_USING_DAC2 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DAC_CONFIG_H__ */
diff --git a/bsp/stm32/libraries/HAL_Drivers/config/mp1/dma_config.h b/bsp/stm32/libraries/HAL_Drivers/config/mp1/dma_config.h
index b56973ec98..8a2fc3a5fe 100644
--- a/bsp/stm32/libraries/HAL_Drivers/config/mp1/dma_config.h
+++ b/bsp/stm32/libraries/HAL_Drivers/config/mp1/dma_config.h
@@ -1,13 +1,11 @@
/*
- * Copyright (c) 2006-2018, RT-Thread Development Team
+ * Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
- * 2019-01-02 zylx first version
- * 2019-01-08 SummerGift clean up the code
- * 2020-06-20 thread-liu add stm32mp1
+ * 2020-06-20 thread-liu first version
*/
#ifndef __DMA_CONFIG_H__
@@ -19,6 +17,22 @@
extern "C" {
#endif
+/* DMA1 stream0 */
+
+/* DMA1 stream1 */
+
+/* DMA1 stream2 */
+
+/* DMA1 stream3 */
+
+/* DMA1 stream4 */
+
+/* DMA1 stream5 */
+
+/* DMA1 stream6 */
+
+/* DMA1 stream7 */
+
/* DMA2 stream0 */
#if defined(BSP_UART3_RX_USING_DMA) && !defined(UART3_RX_DMA_INSTANCE)
#define UART3_RX_DMA_IRQHandler DMA2_Stream0_IRQHandler
@@ -26,18 +40,12 @@ extern "C" {
#define UART3_RX_DMA_INSTANCE DMA2_Stream0
#define UART3_RX_DMA_CHANNEL DMA_REQUEST_USART3_RX
#define UART3_RX_DMA_IRQ DMA2_Stream0_IRQn
-#elif defined(BSP_SPI4_RX_USING_DMA) && !defined(SPI4_RX_DMA_INSTANCE)
-#define SPI4_DMA_RX_IRQHandler DMA2_Stream0_IRQHandler
-#define SPI4_RX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
-#define SPI4_RX_DMA_INSTANCE DMA2_Stream0
-#define SPI4_RX_DMA_CHANNEL DMA_REQUEST_SPI4_RX
-#define SPI4_RX_DMA_IRQ DMA2_Stream0_IRQn
-#elif defined(BSP_UART5_RX_USING_DMA) && !defined(UART5_RX_DMA_INSTANCE)
-#define UART5_DMA_RX_IRQHandler DMA2_Stream0_IRQHandler
-#define UART5_RX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
-#define UART5_RX_DMA_INSTANCE DMA2_Stream0
-#define UART5_RX_DMA_CHANNEL DMA_REQUEST_UART5_RX
-#define UART5_RX_DMA_IRQ DMA2_Stream0_IRQn
+#elif defined(BSP_SPI5_RX_USING_DMA) && !defined(SPI5_RX_DMA_INSTANCE)
+#define SPI5_DMA_RX_IRQHandler DMA2_Stream0_IRQHandler
+#define SPI5_RX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
+#define SPI5_RX_DMA_INSTANCE DMA2_Stream0
+#define SPI5_RX_DMA_CHANNEL DMA_REQUEST_SPI5_RX
+#define SPI5_RX_DMA_IRQ DMA2_Stream0_IRQn
#endif
/* DMA2 stream1 */
@@ -47,12 +55,12 @@ extern "C" {
#define UART3_TX_DMA_INSTANCE DMA2_Stream1
#define UART3_TX_DMA_CHANNEL DMA_REQUEST_USART3_TX
#define UART3_TX_DMA_IRQ DMA2_Stream1_IRQn
-#elif defined(BSP_SPI4_TX_USING_DMA) && !defined(SPI4_TX_DMA_INSTANCE)
-#define SPI4_DMA_TX_IRQHandler DMA2_Stream1_IRQHandler
-#define SPI4_TX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
-#define SPI4_TX_DMA_INSTANCE DMA2_Stream1
-#define SPI4_TX_DMA_CHANNEL DMA_REQUEST_SPI4_TX
-#define SPI4_TX_DMA_IRQ DMA2_Stream1_IRQn
+#elif defined(BSP_SPI5_TX_USING_DMA) && !defined(SPI5_TX_DMA_INSTANCE)
+#define SPI5_DMA_TX_IRQHandler DMA2_Stream1_IRQHandler
+#define SPI5_TX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
+#define SPI5_TX_DMA_INSTANCE DMA2_Stream1
+#define SPI5_TX_DMA_CHANNEL DMA_REQUEST_SPI5_TX
+#define SPI5_TX_DMA_IRQ DMA2_Stream1_IRQn
#endif
/* DMA2 stream2 */
@@ -65,48 +73,48 @@ extern "C" {
#endif
/* DMA2 stream3 */
-#if defined(BSP_SPI5_RX_USING_DMA) && !defined(SPI5_RX_DMA_INSTANCE)
-#define SPI5_DMA_RX_IRQHandler DMA2_Stream3_IRQHandler
-#define SPI5_RX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
-#define SPI5_RX_DMA_INSTANCE DMA2_Stream3
-#define SPI5_RX_DMA_CHANNEL DMA_REQUEST_SPI5_RX
-#define SPI5_RX_DMA_IRQ DMA2_Stream3_IRQn
+#if defined(BSP_UART4_RX_USING_DMA) && !defined(UART4_RX_DMA_INSTANCE)
+#define UART4_DMA_RX_IRQHandler DMA2_Stream3_IRQHandler
+#define UART4_RX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
+#define UART4_RX_DMA_INSTANCE DMA2_Stream3
+#define UART4_RX_DMA_CHANNEL DMA_REQUEST_UART4_RX
+#define UART4_RX_DMA_IRQ DMA2_Stream3_IRQn
#endif
/* DMA2 stream4 */
-#if defined(BSP_SPI5_TX_USING_DMA) && !defined(SPI5_TX_DMA_INSTANCE)
-#define SPI5_DMA_TX_IRQHandler DMA2_Stream4_IRQHandler
-#define SPI5_TX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
-#define SPI5_TX_DMA_INSTANCE DMA2_Stream4
-#define SPI5_TX_DMA_CHANNEL DMA_REQUEST_SPI5_TX
-#define SPI5_TX_DMA_IRQ DMA2_Stream4_IRQn
-#endif
-
-/* DMA2 stream5 */
#if defined(BSP_UART4_TX_USING_DMA) && !defined(UART5_TX_DMA_INSTANCE)
-#define UART4_DMA_TX_IRQHandler DMA2_Stream5_IRQHandler
+#define UART4_DMA_TX_IRQHandler DMA2_Stream4_IRQHandler
#define UART4_TX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
-#define UART4_TX_DMA_INSTANCE DMA2_Stream5
+#define UART4_TX_DMA_INSTANCE DMA2_Stream4
#define UART4_TX_DMA_CHANNEL DMA_REQUEST_UART4_TX
-#define UART4_TX_DMA_IRQ DMA2_Stream5_IRQn
+#define UART4_TX_DMA_IRQ DMA2_Stream4_IRQn
+#endif
+
+/* DMA2 stream5 */
+#if defined(BSP_USING_CRYP) && !defined(CRYP2_OUT_DMA_INSTANCE)
+#define CRYP2_DMA_OUT_IRQHandler DMA2_Stream5_IRQHandler
+#define CRYP2_OUT_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
+#define CRYP2_OUT_DMA_INSTANCE DMA2_Stream5
+#define CRYP2_OUT_DMA_CHANNEL DMA_REQUEST_CRYP2_OUT
+#define CRYP2_OUT_DMA_IRQ DMA2_Stream5_IRQn
#endif
/* DMA2 stream6 */
-#if defined(BSP_UART4_RX_USING_DMA) && !defined(UART4_RX_DMA_INSTANCE)
-#define UART4_DMA_RX_IRQHandler DMA2_Stream6_IRQHandler
-#define UART4_RX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
-#define UART4_RX_DMA_INSTANCE DMA2_Stream6
-#define UART4_RX_DMA_CHANNEL DMA_REQUEST_UART4_RX
-#define UART4_RX_DMA_IRQ DMA2_Stream6_IRQn
+#if defined(BSP_USING_CRYP) && !defined(CRYP2_IN_DMA_INSTANCE)
+#define CRYP2_DMA_IN_IRQHandler DMA2_Stream6_IRQHandler
+#define CRYP2_IN_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
+#define CRYP2_IN_DMA_INSTANCE DMA2_Stream6
+#define CRYP2_IN_DMA_CHANNEL DMA_REQUEST_CRYP2_IN
+#define CRYP2_IN_DMA_IRQ DMA2_Stream6_IRQn
#endif
/* DMA2 stream7 */
-#if defined(BSP_UART5_TX_USING_DMA) && !defined(UART5_TX_DMA_INSTANCE)
-#define UART5_DMA_TX_IRQHandler DMA2_Stream7_IRQHandler
-#define UART5_TX_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
-#define UART5_TX_DMA_INSTANCE DMA2_Stream7
-#define UART5_TX_DMA_CHANNEL DMA_REQUEST_UART5_TX
-#define UART5_TX_DMA_IRQ DMA2_Stream7_IRQn
+#if defined(BSP_USING_HASH) && !defined(HASH2_IN_DMA_INSTANCE)
+#define HASH2_DMA_IN_IRQHandler DMA2_Stream7_IRQHandler
+#define HASH2_IN_DMA_RCC RCC_MC_AHB2ENSETR_DMA2EN
+#define HASH2_IN_DMA_INSTANCE DMA2_Stream7
+#define HASH2_IN_DMA_CHANNEL DMA_REQUEST_HASH2_IN
+#define HASH2_IN_DMA_IRQ DMA2_Stream7_IRQn
#endif
#ifdef __cplusplus
diff --git a/bsp/stm32/libraries/HAL_Drivers/config/mp1/qspi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/mp1/qspi_config.h
new file mode 100644
index 0000000000..0dc48247e7
--- /dev/null
+++ b/bsp/stm32/libraries/HAL_Drivers/config/mp1/qspi_config.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2018-12-22 zylx first version
+ */
+
+#ifndef __QSPI_CONFIG_H__
+#define __QSPI_CONFIG_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef BSP_USING_QSPI
+#ifndef QSPI_BUS_CONFIG
+#define QSPI_BUS_CONFIG \
+ { \
+ .Instance = QUADSPI, \
+ .Init.FifoThreshold = 4, \
+ .Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE, \
+ .Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_4_CYCLE, \
+ }
+#endif /* QSPI_BUS_CONFIG */
+#endif /* BSP_USING_QSPI */
+
+#ifdef BSP_QSPI_USING_DMA
+#ifndef QSPI_DMA_CONFIG
+#define QSPI_DMA_CONFIG \
+ { \
+ .Instance = QSPI_DMA_INSTANCE, \
+ .Init.Channel = QSPI_DMA_CHANNEL, \
+ .Init.Direction = DMA_PERIPH_TO_MEMORY, \
+ .Init.PeriphInc = DMA_PINC_DISABLE, \
+ .Init.MemInc = DMA_MINC_ENABLE, \
+ .Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE, \
+ .Init.MemDataAlignment = DMA_MDATAALIGN_BYTE, \
+ .Init.Mode = DMA_NORMAL, \
+ .Init.Priority = DMA_PRIORITY_LOW \
+ }
+#endif /* QSPI_DMA_CONFIG */
+#endif /* BSP_QSPI_USING_DMA */
+
+#define QSPI_IRQn QUADSPI_IRQn
+#define QSPI_IRQHandler QUADSPI_IRQHandler
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __QSPI_CONFIG_H__ */
diff --git a/bsp/stm32/libraries/HAL_Drivers/config/mp1/spi_config.h b/bsp/stm32/libraries/HAL_Drivers/config/mp1/spi_config.h
index 69de2adccd..26edfa927c 100644
--- a/bsp/stm32/libraries/HAL_Drivers/config/mp1/spi_config.h
+++ b/bsp/stm32/libraries/HAL_Drivers/config/mp1/spi_config.h
@@ -23,7 +23,6 @@ extern "C" {
{ \
.Instance = SPI1, \
.bus_name = "spi1", \
- .irq_type = SPI1_IRQn, \
}
#endif /* SPI1_BUS_CONFIG */
#endif /* BSP_USING_SPI1 */
@@ -58,7 +57,6 @@ extern "C" {
{ \
.Instance = SPI2, \
.bus_name = "spi2", \
- .irq_type = SPI2_IRQn, \
}
#endif /* SPI2_BUS_CONFIG */
#endif /* BSP_USING_SPI2 */
@@ -93,7 +91,6 @@ extern "C" {
{ \
.Instance = SPI3, \
.bus_name = "spi3", \
- .irq_type = SPI3_IRQn, \
}
#endif /* SPI3_BUS_CONFIG */
#endif /* BSP_USING_SPI3 */
@@ -128,7 +125,6 @@ extern "C" {
{ \
.Instance = SPI4, \
.bus_name = "spi4", \
- .irq_type = SPI4_IRQn, \
}
#endif /* SPI4_BUS_CONFIG */
#endif /* BSP_USING_SPI4 */
diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_config.h b/bsp/stm32/libraries/HAL_Drivers/drv_config.h
index 95c1440560..5df86e8092 100644
--- a/bsp/stm32/libraries/HAL_Drivers/drv_config.h
+++ b/bsp/stm32/libraries/HAL_Drivers/drv_config.h
@@ -73,6 +73,7 @@ extern "C" {
#include "l4/spi_config.h"
#include "l4/qspi_config.h"
#include "l4/adc_config.h"
+#include "l4/dac_config.h"
#include "l4/tim_config.h"
#include "l4/sdio_config.h"
#include "l4/pwm_config.h"
@@ -109,6 +110,7 @@ extern "C" {
#elif defined(SOC_SERIES_STM32MP1)
#include "mp1/dma_config.h"
#include "mp1/uart_config.h"
+#include "mp1/qspi_config.h"
#include "mp1/spi_config.h"
#include "mp1/adc_config.h"
#include "mp1/dac_config.h"
diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_crypto.c b/bsp/stm32/libraries/HAL_Drivers/drv_crypto.c
index e82446c4a6..a6723f8a70 100644
--- a/bsp/stm32/libraries/HAL_Drivers/drv_crypto.c
+++ b/bsp/stm32/libraries/HAL_Drivers/drv_crypto.c
@@ -7,6 +7,8 @@
* Date Author Notes
* 2019-07-10 Ernest 1st version
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
+ * 2020-11-26 thread-liu add hash
+ * 2020-11-26 thread-liu add cryp
*/
#include <rtthread.h>
@@ -15,7 +17,8 @@
#include <string.h>
#include "drv_crypto.h"
#include "board.h"
-
+#include "drv_config.h"
+
struct stm32_hwcrypto_device
{
struct rt_hwcrypto_device dev;
@@ -24,12 +27,7 @@ struct stm32_hwcrypto_device
#if defined(BSP_USING_CRC)
-struct hash_ctx_des
-{
- CRC_HandleTypeDef contex;
-};
-
-#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB)
+#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32MP1)
static struct hwcrypto_crc_cfg crc_backup_cfg;
static int reverse_bit(rt_uint32_t n)
@@ -49,12 +47,12 @@ static rt_uint32_t _crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, r
rt_uint32_t result = 0;
struct stm32_hwcrypto_device *stm32_hw_dev = (struct stm32_hwcrypto_device *)ctx->parent.device->user_data;
-#if defined(SOC_SERIES_STM32L4)|| defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB)
+#if defined(SOC_SERIES_STM32L4)|| defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32MP1)
CRC_HandleTypeDef *HW_TypeDef = (CRC_HandleTypeDef *)(ctx->parent.contex);
#endif
rt_mutex_take(&stm32_hw_dev->mutex, RT_WAITING_FOREVER);
-#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB)
+#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32MP1)
if (memcmp(&crc_backup_cfg, &ctx->crc_cfg, sizeof(struct hwcrypto_crc_cfg)) != 0)
{
if (HW_TypeDef->Init.DefaultPolynomialUse == DEFAULT_POLYNOMIAL_DISABLE)
@@ -113,7 +111,7 @@ static rt_uint32_t _crc_update(struct hwcrypto_crc *ctx, const rt_uint8_t *in, r
result = HAL_CRC_Accumulate(ctx->parent.contex, (rt_uint32_t *)in, length);
-#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB)
+#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32MP1)
if (HW_TypeDef->Init.OutputDataInversionMode)
{
ctx ->crc_cfg.last_val = reverse_bit(result);
@@ -149,7 +147,7 @@ static rt_uint32_t _rng_rand(struct hwcrypto_rng *ctx)
{
return gen_random ;
}
-
+
return 0;
}
@@ -159,10 +157,213 @@ static const struct hwcrypto_rng_ops rng_ops =
};
#endif /* BSP_USING_RNG */
+#if defined(BSP_USING_HASH)
+static rt_err_t _hash_update(struct hwcrypto_hash *ctx, const rt_uint8_t *in, rt_size_t length)
+{
+ rt_uint32_t tickstart = 0;
+ rt_uint32_t result = RT_EOK;
+ struct stm32_hwcrypto_device *stm32_hw_dev = (struct stm32_hwcrypto_device *)ctx->parent.device->user_data;
+ rt_mutex_take(&stm32_hw_dev->mutex, RT_WAITING_FOREVER);
+
+#if defined(SOC_SERIES_STM32MP1)
+ HASH_HandleTypeDef *HW_TypeDef = (HASH_HandleTypeDef *)(ctx->parent.contex);
+ /* Start HASH computation using DMA transfer */
+ switch (ctx->parent.type)
+ {
+ case HWCRYPTO_TYPE_SHA224:
+ result = HAL_HASHEx_SHA224_Start_DMA(HW_TypeDef, (uint8_t *)in, length);
+ break;
+ case HWCRYPTO_TYPE_SHA256:
+ result = HAL_HASHEx_SHA256_Start_DMA(HW_TypeDef, (uint8_t *)in, length);
+ break;
+ case HWCRYPTO_TYPE_MD5:
+ result = HAL_HASH_MD5_Start_DMA(HW_TypeDef, (uint8_t *)in, length);
+ break;
+ case HWCRYPTO_TYPE_SHA1:
+ result = HAL_HASH_SHA1_Start_DMA(HW_TypeDef, (uint8_t *)in, length);
+ break;
+ default :
+ rt_kprintf("not support hash type: %x", ctx->parent.type);
+ break;
+ }
+ if (result != HAL_OK)
+ {
+ goto _exit;
+ }
+ /* Wait for DMA transfer to complete */
+ tickstart = rt_tick_get();
+ while (HAL_HASH_GetState(HW_TypeDef) == HAL_HASH_STATE_BUSY)
+ {
+ if (rt_tick_get() - tickstart > 0xFFFF)
+ {
+ result = RT_ETIMEOUT;
+ goto _exit;
+ }
+ }
+
+#endif
+_exit:
+ rt_mutex_release(&stm32_hw_dev->mutex);
+
+ return result;
+}
+
+static rt_err_t _hash_finish(struct hwcrypto_hash *ctx, rt_uint8_t *out, rt_size_t length)
+{
+ rt_uint32_t result = RT_EOK;
+ struct stm32_hwcrypto_device *stm32_hw_dev = (struct stm32_hwcrypto_device *)ctx->parent.device->user_data;
+ rt_mutex_take(&stm32_hw_dev->mutex, RT_WAITING_FOREVER);
+#if defined(SOC_SERIES_STM32MP1)
+ HASH_HandleTypeDef *HW_TypeDef = (HASH_HandleTypeDef *)(ctx->parent.contex);
+ /* Get the computed digest value */
+ switch (ctx->parent.type)
+ {
+ case HWCRYPTO_TYPE_SHA224:
+ result = HAL_HASHEx_SHA224_Finish(HW_TypeDef, (uint8_t *)out, length);
+ break;
+
+ case HWCRYPTO_TYPE_SHA256:
+ result = HAL_HASHEx_SHA256_Finish(HW_TypeDef, (uint8_t *)out, length);
+ break;
+
+ case HWCRYPTO_TYPE_MD5:
+ result = HAL_HASH_MD5_Finish(HW_TypeDef, (uint8_t *)out, length);
+ break;
+
+ case HWCRYPTO_TYPE_SHA1:
+ result = HAL_HASH_SHA1_Finish(HW_TypeDef, (uint8_t *)out, length);
+ break;
+
+ default :
+ rt_kprintf("not support hash type: %x", ctx->parent.type);
+ break;
+ }
+ if (result != HAL_OK)
+ {
+ goto _exit;
+ }
+#endif
+
+_exit:
+ rt_mutex_release(&stm32_hw_dev->mutex);
+
+ return result;
+}
+
+static const struct hwcrypto_hash_ops hash_ops =
+{
+ .update = _hash_update,
+ .finish = _hash_finish
+};
+
+#endif /* BSP_USING_HASH */
+
+#if defined(BSP_USING_CRYP)
+static rt_err_t _cryp_crypt(struct hwcrypto_symmetric *ctx,
+ struct hwcrypto_symmetric_info *info)
+{
+ rt_uint32_t result = RT_EOK;
+ rt_uint32_t tickstart = 0;
+
+ struct stm32_hwcrypto_device *stm32_hw_dev = (struct stm32_hwcrypto_device *)ctx->parent.device->user_data;
+ rt_mutex_take(&stm32_hw_dev->mutex, RT_WAITING_FOREVER);
+
+#if defined(SOC_SERIES_STM32MP1)
+ CRYP_HandleTypeDef *HW_TypeDef = (CRYP_HandleTypeDef *)(ctx->parent.contex);
+
+ switch (ctx->parent.type)
+ {
+ case HWCRYPTO_TYPE_AES_ECB:
+ HW_TypeDef->Init.Algorithm = CRYP_AES_ECB;
+ break;
+
+ case HWCRYPTO_TYPE_AES_CBC:
+ HW_TypeDef->Init.Algorithm = CRYP_AES_CBC;
+ break;
+
+ case HWCRYPTO_TYPE_AES_CTR:
+ HW_TypeDef->Init.Algorithm = CRYP_AES_CTR;
+ break;
+
+ case HWCRYPTO_TYPE_DES_ECB:
+ HW_TypeDef->Init.Algorithm = CRYP_DES_ECB;
+ break;
+
+ case HWCRYPTO_TYPE_DES_CBC:
+ HW_TypeDef->Init.Algorithm = CRYP_DES_CBC;
+ break;
+
+ default :
+ rt_kprintf("not support cryp type: %x", ctx->parent.type);
+ break;
+ }
+
+ HAL_CRYP_DeInit(HW_TypeDef);
+
+ HW_TypeDef->Init.DataType = CRYP_DATATYPE_8B;
+ HW_TypeDef->Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
+ HW_TypeDef->Init.KeySize = CRYP_KEYSIZE_128B;
+ HW_TypeDef->Init.pKey = (uint32_t*)ctx->key;
+
+ result = HAL_CRYP_Init(HW_TypeDef);
+ if (result != HAL_OK)
+ {
+ /* Initialization Error */
+ goto _exit;
+ }
+ if (info->mode == HWCRYPTO_MODE_ENCRYPT)
+ {
+ result = HAL_CRYP_Encrypt_DMA(HW_TypeDef, (uint32_t *)info->in, info->length, (uint32_t *)info->out);
+ }
+ else if (info->mode == HWCRYPTO_MODE_DECRYPT)
+ {
+ result = HAL_CRYP_Decrypt_DMA(HW_TypeDef, (uint32_t *)info->in, info->length, (uint32_t *)info->out);
+ }
+ else
+ {
+ rt_kprintf("error cryp mode : %02x!\n", info->mode);
+ result = RT_ERROR;
+ goto _exit;
+ }
+
+ if (result != HAL_OK)
+ {
+ goto _exit;
+ }
+
+ tickstart = rt_tick_get();
+ while (HAL_CRYP_GetState(HW_TypeDef) != HAL_CRYP_STATE_READY)
+ {
+ if (rt_tick_get() - tickstart > 0xFFFF)
+ {
+ result = RT_ETIMEOUT;
+ goto _exit;
+ }
+ }
+
+#endif
+
+ if (result != HAL_OK)
+ {
+ goto _exit;
+ }
+
+_exit:
+ rt_mutex_release(&stm32_hw_dev->mutex);
+
+ return result;
+}
+
+static const struct hwcrypto_symmetric_ops cryp_ops =
+{
+ .crypt = _cryp_crypt
+};
+#endif
+
static rt_err_t _crypto_create(struct rt_hwcrypto_ctx *ctx)
{
rt_err_t res = RT_EOK;
-
+
switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
{
#if defined(BSP_USING_RNG)
@@ -174,8 +375,11 @@ static rt_err_t _crypto_create(struct rt_hwcrypto_ctx *ctx)
res = -RT_ERROR;
break;
}
-
+#if defined(SOC_SERIES_STM32MP1)
+ hrng->Instance = RNG2;
+#else
hrng->Instance = RNG;
+#endif
HAL_RNG_Init(hrng);
ctx->contex = hrng;
((struct hwcrypto_rng *)ctx)->ops = &rng_ops;
@@ -193,9 +397,12 @@ static rt_err_t _crypto_create(struct rt_hwcrypto_ctx *ctx)
res = -RT_ERROR;
break;
}
-
+#if defined(SOC_SERIES_STM32MP1)
+ hcrc->Instance = CRC2;
+#else
hcrc->Instance = CRC;
-#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB)
+#endif
+#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB) || defined(SOC_SERIES_STM32MP1)
hcrc->Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
hcrc->Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
hcrc->Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE;
@@ -209,9 +416,77 @@ static rt_err_t _crypto_create(struct rt_hwcrypto_ctx *ctx)
#endif /* defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32F7) */
ctx->contex = hcrc;
((struct hwcrypto_crc *)ctx)->ops = &crc_ops;
+
break;
}
#endif /* BSP_USING_CRC */
+
+#if defined(BSP_USING_HASH)
+ case HWCRYPTO_TYPE_MD5:
+ case HWCRYPTO_TYPE_SHA1:
+ case HWCRYPTO_TYPE_SHA2:
+ {
+ HASH_HandleTypeDef *hash = rt_calloc(1, sizeof(HASH_HandleTypeDef));
+ if (RT_NULL == hash)
+ {
+ res = -RT_ERROR;
+ break;
+ }
+#if defined(SOC_SERIES_STM32MP1)
+ /* enable dma for hash */
+ __HAL_RCC_DMA2_CLK_ENABLE();
+ HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 2, 0);
+ HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
+
+ hash->Init.DataType = HASH_DATATYPE_8B;
+ if (HAL_HASH_Init(hash) != HAL_OK)
+ {
+ res = -RT_ERROR;
+ }
+#endif
+ ctx->contex = hash;
+ ((struct hwcrypto_hash *)ctx)->ops = &hash_ops;
+
+ break;
+ }
+#endif /* BSP_USING_HASH */
+
+#if defined(BSP_USING_CRYP)
+ case HWCRYPTO_TYPE_AES:
+ case HWCRYPTO_TYPE_DES:
+ case HWCRYPTO_TYPE_3DES:
+ case HWCRYPTO_TYPE_RC4:
+ case HWCRYPTO_TYPE_GCM:
+ {
+ CRYP_HandleTypeDef *cryp = rt_calloc(1, sizeof(CRYP_HandleTypeDef));
+ if (RT_NULL == cryp)
+ {
+ res = -RT_ERROR;
+ break;
+ }
+#if defined(SOC_SERIES_STM32MP1)
+ cryp->Instance = CRYP2;
+ /* enable dma for cryp */
+ __HAL_RCC_DMA2_CLK_ENABLE();
+
+ HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 2, 0);
+ HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);
+
+ HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 2, 0);
+ HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
+
+ if (HAL_CRYP_Init(cryp) != HAL_OK)
+ {
+ res = -RT_ERROR;
+ }
+#endif
+ ctx->contex = cryp;
+ ((struct hwcrypto_symmetric *)ctx)->ops = &cryp_ops;
+
+ break;
+ }
+#endif /* BSP_USING_CRYP */
+
default:
res = -RT_ERROR;
break;
@@ -234,6 +509,26 @@ static void _crypto_destroy(struct rt_hwcrypto_ctx *ctx)
HAL_CRC_DeInit((CRC_HandleTypeDef *)(ctx->contex));
break;
#endif /* BSP_USING_CRC */
+
+#if defined(BSP_USING_HASH)
+ case HWCRYPTO_TYPE_MD5:
+ case HWCRYPTO_TYPE_SHA1:
+ case HWCRYPTO_TYPE_SHA2:
+ __HAL_HASH_RESET_HANDLE_STATE((HASH_HandleTypeDef *)(ctx->contex));
+ HAL_HASH_DeInit((HASH_HandleTypeDef *)(ctx->contex));
+ break;
+#endif /* BSP_USING_HASH */
+
+#if defined(BSP_USING_CRYP)
+ case HWCRYPTO_TYPE_AES:
+ case HWCRYPTO_TYPE_DES:
+ case HWCRYPTO_TYPE_3DES:
+ case HWCRYPTO_TYPE_RC4:
+ case HWCRYPTO_TYPE_GCM:
+ HAL_CRYP_DeInit((CRYP_HandleTypeDef *)(ctx->contex));
+ break;
+#endif /* BSP_USING_CRYP */
+
default:
break;
}
@@ -251,7 +546,7 @@ static rt_err_t _crypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcry
case HWCRYPTO_TYPE_RNG:
if (des->contex && src->contex)
{
- rt_memcpy(des->contex, src->contex, sizeof(struct hash_ctx_des));
+ rt_memcpy(des->contex, src->contex, sizeof(RNG_HandleTypeDef));
}
break;
#endif /* BSP_USING_RNG */
@@ -260,10 +555,35 @@ static rt_err_t _crypto_clone(struct rt_hwcrypto_ctx *des, const struct rt_hwcry
case HWCRYPTO_TYPE_CRC:
if (des->contex && src->contex)
{
- rt_memcpy(des->contex, src->contex, sizeof(struct hash_ctx_des));
+ rt_memcpy(des->contex, src->contex, sizeof(CRC_HandleTypeDef));
}
break;
#endif /* BSP_USING_CRC */
+
+#if defined(BSP_USING_HASH)
+ case HWCRYPTO_TYPE_MD5:
+ case HWCRYPTO_TYPE_SHA1:
+ case HWCRYPTO_TYPE_SHA2:
+ if (des->contex && src->contex)
+ {
+ rt_memcpy(des->contex, src->contex, sizeof(HASH_HandleTypeDef));
+ }
+ break;
+#endif /* BSP_USING_HASH */
+
+#if defined(BSP_USING_CRYP)
+ case HWCRYPTO_TYPE_AES:
+ case HWCRYPTO_TYPE_DES:
+ case HWCRYPTO_TYPE_3DES:
+ case HWCRYPTO_TYPE_RC4:
+ case HWCRYPTO_TYPE_GCM:
+ if (des->contex && src->contex)
+ {
+ rt_memcpy(des->contex, src->contex, sizeof(CRYP_HandleTypeDef));
+ }
+ break;
+#endif /* BSP_USING_CRYP */
+
default:
res = -RT_ERROR;
break;
@@ -285,11 +605,68 @@ static void _crypto_reset(struct rt_hwcrypto_ctx *ctx)
__HAL_CRC_DR_RESET((CRC_HandleTypeDef *)ctx-> contex);
break;
#endif /* BSP_USING_CRC */
+
+#if defined(BSP_USING_HASH)
+ case HWCRYPTO_TYPE_MD5:
+ case HWCRYPTO_TYPE_SHA1:
+ case HWCRYPTO_TYPE_SHA2:
+ __HAL_HASH_RESET_HANDLE_STATE((HASH_HandleTypeDef *)(ctx->contex));
+ break;
+#endif /* BSP_USING_HASH*/
+
+#if defined(BSP_USING_CRYP)
+ case HWCRYPTO_TYPE_AES:
+ case HWCRYPTO_TYPE_DES:
+ case HWCRYPTO_TYPE_3DES:
+ case HWCRYPTO_TYPE_RC4:
+ case HWCRYPTO_TYPE_GCM:
+ break;
+#endif /* BSP_USING_CRYP */
+
default:
break;
}
}
+void HASH2_DMA_IN_IRQHandler(void)
+{
+ extern DMA_HandleTypeDef hdma_hash_in;
+
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_DMA_IRQHandler(&hdma_hash_in);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void CRYP2_DMA_IN_IRQHandler(void)
+{
+ extern DMA_HandleTypeDef hdma_cryp_in;
+
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_DMA_IRQHandler(&hdma_cryp_in);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void CRYP2_DMA_OUT_IRQHandler(void)
+{
+ extern DMA_HandleTypeDef hdma_cryp_out;
+
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_DMA_IRQHandler(&hdma_cryp_out);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
static const struct rt_hwcrypto_ops _ops =
{
.create = _crypto_create,
@@ -306,10 +683,10 @@ int stm32_hw_crypto_device_init(void)
_crypto_dev.dev.ops = &_ops;
#if defined(BSP_USING_UDID)
-#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32WB)
+#if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
cpuid[0] = HAL_GetUIDw0();
cpuid[1] = HAL_GetUIDw1();
-#elif defined(SOC_SERIES_STM32H7)
+#elif defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32MP1)
cpuid[0] = HAL_GetREVID();
cpuid[1] = HAL_GetDEVID();
#endif
diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_dac.c b/bsp/stm32/libraries/HAL_Drivers/drv_dac.c
index e4462b0e78..23d392150d 100644
--- a/bsp/stm32/libraries/HAL_Drivers/drv_dac.c
+++ b/bsp/stm32/libraries/HAL_Drivers/drv_dac.c
@@ -43,7 +43,7 @@ static rt_err_t stm32_dac_enabled(struct rt_dac_device *device, rt_uint32_t chan
RT_ASSERT(device != RT_NULL);
stm32_dac_handler = device->parent.user_data;
-#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
+#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4)
HAL_DAC_Start(stm32_dac_handler, channel);
#endif
@@ -56,7 +56,7 @@ static rt_err_t stm32_dac_disabled(struct rt_dac_device *device, rt_uint32_t cha
RT_ASSERT(device != RT_NULL);
stm32_dac_handler = device->parent.user_data;
-#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
+#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4)
HAL_DAC_Stop(stm32_dac_handler, channel);
#endif
@@ -96,7 +96,7 @@ static rt_err_t stm32_set_dac_value(struct rt_dac_device *device, rt_uint32_t ch
rt_memset(&DAC_ChanConf, 0, sizeof(DAC_ChanConf));
-#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
+#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4)
if ((channel <= 2) && (channel > 0))
{
/* set stm32 dac channel */
@@ -109,7 +109,7 @@ static rt_err_t stm32_set_dac_value(struct rt_dac_device *device, rt_uint32_t ch
}
#endif
-#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7)
+#if defined(SOC_SERIES_STM32MP1) || defined(SOC_SERIES_STM32H7) || defined(SOC_SERIES_STM32L4)
DAC_ChanConf.DAC_Trigger = DAC_TRIGGER_NONE;
DAC_ChanConf.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
#endif
diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_qspi.c b/bsp/stm32/libraries/HAL_Drivers/drv_qspi.c
index 52c184290e..81413d863a 100644
--- a/bsp/stm32/libraries/HAL_Drivers/drv_qspi.c
+++ b/bsp/stm32/libraries/HAL_Drivers/drv_qspi.c
@@ -52,8 +52,12 @@ static int stm32_qspi_init(struct rt_qspi_device *device, struct rt_qspi_configu
QSPI_HandleTypeDef QSPI_Handler_config = QSPI_BUS_CONFIG;
qspi_bus->QSPI_Handler = QSPI_Handler_config;
+#if defined(SOC_SERIES_STM32MP1)
+ while (cfg->max_hz < HAL_RCC_GetACLKFreq() / (i + 1))
+#else
while (cfg->max_hz < HAL_RCC_GetHCLKFreq() / (i + 1))
- {
+#endif
+ {
i++;
if (i == 255)
{
diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_sdio.c b/bsp/stm32/libraries/HAL_Drivers/drv_sdio.c
index 5e6d4f6934..78928105cb 100644
--- a/bsp/stm32/libraries/HAL_Drivers/drv_sdio.c
+++ b/bsp/stm32/libraries/HAL_Drivers/drv_sdio.c
@@ -353,7 +353,7 @@ static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
/**
* @brief This function send sdio request.
- * @param sdio rthw_sdio
+ * @param host rt_mmcsd_host
* @param req request
* @retval None
*/
@@ -525,11 +525,11 @@ void rthw_sdio_irq_update(struct rt_mmcsd_host *host, rt_int32_t enable)
}
/**
- * @brief This function delect sdcard.
+ * @brief This function detect sdcard.
* @param host rt_mmcsd_host
* @retval 0x01
*/
-static rt_int32_t rthw_sd_delect(struct rt_mmcsd_host *host)
+static rt_int32_t rthw_sd_detect(struct rt_mmcsd_host *host)
{
LOG_D("try to detect device");
return 0x01;
@@ -605,7 +605,7 @@ static const struct rt_mmcsd_host_ops ops =
{
rthw_sdio_request,
rthw_sdio_iocfg,
- rthw_sd_delect,
+ rthw_sd_detect,
rthw_sdio_irq_update,
};
diff --git a/bsp/stm32/libraries/STM32F0xx_HAL/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h b/bsp/stm32/libraries/STM32F0xx_HAL/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h
index f09577117a..e9747eeadb 100644
--- a/bsp/stm32/libraries/STM32F0xx_HAL/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h
+++ b/bsp/stm32/libraries/STM32F0xx_HAL/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h
@@ -44,7 +44,6 @@
/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx_hal_conf.h"
-#include <rtthread.h>
/** @addtogroup STM32F0xx_HAL_Driver
* @{
diff --git a/bsp/stm32/libraries/STM32F1xx_HAL/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h b/bsp/stm32/libraries/STM32F1xx_HAL/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
index 32f2dd4a77..ba2f673e8b 100644
--- a/bsp/stm32/libraries/STM32F1xx_HAL/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
+++ b/bsp/stm32/libraries/STM32F1xx_HAL/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
@@ -28,7 +28,6 @@ extern "C" {
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal_conf.h"
-#include <rtthread.h>
/** @addtogroup STM32F1xx_HAL_Driver
* @{
diff --git a/bsp/stm32/libraries/STM32F2xx_HAL/STM32F2xx_HAL_Driver/Inc/stm32f2xx_hal.h b/bsp/stm32/libraries/STM32F2xx_HAL/STM32F2xx_HAL_Driver/Inc/stm32f2xx_hal.h
index 345d1305b9..1fa049d31c 100644
--- a/bsp/stm32/libraries/STM32F2xx_HAL/STM32F2xx_HAL_Driver/Inc/stm32f2xx_hal.h
+++ b/bsp/stm32/libraries/STM32F2xx_HAL/STM32F2xx_HAL_Driver/Inc/stm32f2xx_hal.h
@@ -28,7 +28,6 @@
/* Includes ------------------------------------------------------------------*/
#include "stm32f2xx_hal_conf.h"
-#include <rtthread.h>
/** @addtogroup STM32F2xx_HAL_Driver
* @{
diff --git a/bsp/stm32/libraries/STM32F4xx_HAL/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h b/bsp/stm32/libraries/STM32F4xx_HAL/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h
index a8af863dd6..5b800df7de 100644
--- a/bsp/stm32/libraries/STM32F4xx_HAL/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h
+++ b/bsp/stm32/libraries/STM32F4xx_HAL/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal.h
@@ -28,7 +28,6 @@
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal_conf.h"
-#include <rtthread.h>
/** @addtogroup STM32F4xx_HAL_Driver
* @{
diff --git a/bsp/stm32/libraries/STM32F7xx_HAL/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal.h b/bsp/stm32/libraries/STM32F7xx_HAL/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal.h
index 9f81701a62..4df6fe3128 100644
--- a/bsp/stm32/libraries/STM32F7xx_HAL/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal.h
+++ b/bsp/stm32/libraries/STM32F7xx_HAL/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal.h
@@ -28,7 +28,6 @@
/* Includes ------------------------------------------------------------------*/
#include "stm32f7xx_hal_conf.h"
-#include <rtthread.h>
/** @addtogroup STM32F7xx_HAL_Driver
* @{
diff --git a/bsp/stm32/libraries/STM32G0xx_HAL/STM32G0xx_HAL_Driver/Inc/stm32g0xx_hal.h b/bsp/stm32/libraries/STM32G0xx_HAL/STM32G0xx_HAL_Driver/Inc/stm32g0xx_hal.h
index 499a9d2c53..e7e964dfa4 100644
--- a/bsp/stm32/libraries/STM32G0xx_HAL/STM32G0xx_HAL_Driver/Inc/stm32g0xx_hal.h
+++ b/bsp/stm32/libraries/STM32G0xx_HAL/STM32G0xx_HAL_Driver/Inc/stm32g0xx_hal.h
@@ -28,7 +28,6 @@ extern "C" {
/* Includes ------------------------------------------------------------------*/
#include "stm32g0xx_hal_conf.h"
-#include <rtthread.h>
/** @addtogroup STM32G0xx_HAL_Driver
* @{
diff --git a/bsp/stm32/libraries/STM32G4xx_HAL/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal.h b/bsp/stm32/libraries/STM32G4xx_HAL/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal.h
index d80b278be3..fcff7098aa 100644
--- a/bsp/stm32/libraries/STM32G4xx_HAL/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal.h
+++ b/bsp/stm32/libraries/STM32G4xx_HAL/STM32G4xx_HAL_Driver/Inc/stm32g4xx_hal.h
@@ -28,7 +28,6 @@ extern "C" {
/* Includes ------------------------------------------------------------------*/
#include "stm32g4xx_hal_conf.h"
-#include <rtthread.h>
/** @addtogroup STM32G4xx_HAL_Driver
* @{
diff --git a/bsp/stm32/libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h b/bsp/stm32/libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h
index 015519510d..094f7bfe8e 100644
--- a/bsp/stm32/libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h
+++ b/bsp/stm32/libraries/STM32H7xx_HAL/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal.h
@@ -28,7 +28,6 @@
/* Includes ------------------------------------------------------------------*/
#include "stm32h7xx_hal_conf.h"
-#include <rtthread.h>
/** @addtogroup STM32H7xx_HAL_Driver
* @{
diff --git a/bsp/stm32/libraries/STM32L0xx_HAL/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal.h b/bsp/stm32/libraries/STM32L0xx_HAL/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal.h
index 9e8ea13b5c..13d3923cb4 100644
--- a/bsp/stm32/libraries/STM32L0xx_HAL/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal.h
+++ b/bsp/stm32/libraries/STM32L0xx_HAL/STM32L0xx_HAL_Driver/Inc/stm32l0xx_hal.h
@@ -28,7 +28,6 @@
/* Includes ------------------------------------------------------------------*/
#include "stm32l0xx_hal_conf.h"
-#include <rtthread.h>
/** @addtogroup STM32L0xx_HAL_Driver
* @{
diff --git a/bsp/stm32/libraries/STM32L4xx_HAL/SConscript b/bsp/stm32/libraries/STM32L4xx_HAL/SConscript
index 037f91893e..46b9aa7bf7 100644
--- a/bsp/stm32/libraries/STM32L4xx_HAL/SConscript
+++ b/bsp/stm32/libraries/STM32L4xx_HAL/SConscript
@@ -59,6 +59,10 @@ if GetDepend(['RT_USING_ADC']):
src += ['STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c']
src += ['STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c']
+if GetDepend(['RT_USING_DAC']):
+ src += ['STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dac.c']
+ src += ['STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dac_ex.c']
+
if GetDepend(['RT_USING_RTC']):
src += ['STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c']
src += ['STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c']
diff --git a/bsp/stm32/libraries/STM32L4xx_HAL/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h b/bsp/stm32/libraries/STM32L4xx_HAL/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h
index 84d6d9c9b1..9643b494d4 100644
--- a/bsp/stm32/libraries/STM32L4xx_HAL/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h
+++ b/bsp/stm32/libraries/STM32L4xx_HAL/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h
@@ -28,7 +28,6 @@
/* Includes ------------------------------------------------------------------*/
#include "stm32l4xx_hal_conf.h"
-#include <rtthread.h>
/** @addtogroup STM32L4xx_HAL_Driver
* @{
diff --git a/bsp/stm32/libraries/STM32MPxx_HAL/SConscript b/bsp/stm32/libraries/STM32MPxx_HAL/SConscript
index 427cc65ac6..9e1d85e005 100644
--- a/bsp/stm32/libraries/STM32MPxx_HAL/SConscript
+++ b/bsp/stm32/libraries/STM32MPxx_HAL/SConscript
@@ -35,10 +35,6 @@ if GetDepend(['RT_USING_SERIAL']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_uart.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_uart_ex.c']
-#if GetDepend(['RT_USING_SPI']):
-# src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_spi.c']
-# src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_qspi.c']
-
if GetDepend(['RT_USING_USB_HOST']) or GetDepend(['RT_USING_USB_DEVICE']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_pccard.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_pcd.c']
@@ -49,14 +45,6 @@ if GetDepend(['RT_USING_USB_HOST']) or GetDepend(['RT_USING_USB_DEVICE']):
if GetDepend(['RT_USING_CAN']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_can.c']
-#if GetDepend(['RT_USING_HWTIMER']) or GetDepend(['RT_USING_PWM']) or GetDepend(['RT_USING_PULSE_ENCODER']):
-# src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_tim.c']
-# src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_tim_ex.c']
-# src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_lptim.c']
-
-if GetDepend(['BSP_USING_ETH']):
- src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_eth.c']
-
if GetDepend(['BSP_USING_WWDG']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_wwdg.c']
@@ -73,13 +61,14 @@ if GetDepend(['RT_USING_WDT']):
if GetDepend(['RT_USING_SDIO']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_sdmmc.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c']
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_delayblock.c']
if GetDepend(['RT_USING_AUDIO']):
- src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_i2s.c']
- src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_i2s_ex.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sai.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sai_ex.c']
-
+if GetDepend(['BSP_USING_DCMI']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dcmi.c']
+
if GetDepend(['BSP_USING_FMC']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_fmc.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_fsmc.c']
@@ -102,6 +91,38 @@ if GetDepend(['BSP_USING_LTDC']):
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_dma2d.c']
src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dsi.c']
+if GetDepend(['BSP_USING_FDCAN']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_fdcan.c']
+
+if GetDepend(['BSP_USING_QSPI']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_qspi.c']
+
+if GetDepend(['BSP_USING_SPDIFRX']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_spdifrx.c']
+
+if GetDepend(['BSP_USING_DFSDM']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dfsdm.c']
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_dfsdm_ex.c']
+
+if GetDepend(['BSP_USING_SDMMC']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_sdmmc.c']
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c']
+
+if GetDepend(['BSP_USING_HASH']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_hash.c']
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_hash_ex.c']
+
+if GetDepend(['BSP_USING_CRC']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_crc.c']
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_crc_ex.c']
+
+if GetDepend(['BSP_USING_RNG']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_rng.c']
+
+if GetDepend(['BSP_USING_CRYP']):
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_cryp.c']
+ src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_cryp_ex.c']
+
path = [cwd + '/STM32MP1xx_HAL_Driver/Inc',
cwd + '/CMSIS/Device/ST/STM32MP1xx/Include',
cwd + '/CMSIS/Core/Include',
diff --git a/bsp/stm32/libraries/STM32MPxx_HAL/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c b/bsp/stm32/libraries/STM32MPxx_HAL/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c
index 59044a2669..a7a01539d8 100644
--- a/bsp/stm32/libraries/STM32MPxx_HAL/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c
+++ b/bsp/stm32/libraries/STM32MPxx_HAL/STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c
@@ -3236,7 +3236,7 @@ uint32_t SD_HighSpeed(SD_HandleTypeDef *hsd)
{
SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance);
}
- loop += 8U;
+ loop ++;
}
if((HAL_GetTick()-Timeout) >= SDMMC_DATATIMEOUT)
@@ -3351,7 +3351,7 @@ uint32_t SD_UltraHighSpeed(SD_HandleTypeDef *hsd)
{
SD_hs[(8U*loop)+count] = SDMMC_ReadFIFO(hsd->Instance);
}
- loop += 8U;
+ loop ++;
}
if((HAL_GetTick()-Timeout) >= SDMMC_DATATIMEOUT)
diff --git a/bsp/stm32/stm32h743-atk-apollo/board/Kconfig b/bsp/stm32/stm32h743-atk-apollo/board/Kconfig
index e2d7618062..a2065dc17e 100644
--- a/bsp/stm32/stm32h743-atk-apollo/board/Kconfig
+++ b/bsp/stm32/stm32h743-atk-apollo/board/Kconfig
@@ -41,6 +41,13 @@ menu "Onboard Peripheral Drivers"
select RT_USING_DFS_ELMFAT
default n
+ config BSP_USING_OV2640
+ bool "Enable camera (ov2640)"
+ select BSP_USING_DCMI
+ select BSP_USING_I2C
+ select BSP_USING_I2C2
+ default n
+
endmenu
menu "On-chip Peripheral Drivers"
@@ -98,28 +105,55 @@ menu "On-chip Peripheral Drivers"
select RT_USING_SPI
default n
- menuconfig BSP_USING_I2C1
- bool "Enable I2C1 BUS (software simulation)"
- default n
- select RT_USING_I2C
- select RT_USING_I2C_BITOPS
- select RT_USING_PIN
- if BSP_USING_I2C1
- comment "Notice: PH4 --> 116; PH5 --> 117"
- config BSP_I2C1_SCL_PIN
- int "i2c1 scl pin number"
- range 1 176
- default 116
- config BSP_I2C1_SDA_PIN
- int "I2C1 sda pin number"
- range 1 176
- default 117
- endif
+ menuconfig BSP_USING_I2C
+ bool "Enable I2C BUS (software simulation)"
+ select RT_USING_I2C
+ select RT_USING_I2C_BITOPS
+ select RT_USING_PIN
+ default n
+ if BSP_USING_I2C
+ menuconfig BSP_USING_I2C1
+ bool "Enable I2C1 BUS (software simulation)"
+ default n
+ if BSP_USING_I2C1
+ comment "Notice: PH4 --> 116; PH5 --> 117"
+ config BSP_I2C1_SCL_PIN
+ int "i2c1 scl pin number"
+ range 1 176
+ default 116
+ config BSP_I2C1_SDA_PIN
+ int "I2C1 sda pin number"
+ range 1 176
+ default 117
+ menuconfig BSP_USING_I2C2
+ bool "Enable I2C2 BUS (software simulation)"
+ default n
+ endif
+
+ menuconfig BSP_USING_I2C2
+ bool "Enable I2C2 BUS (software simulation)"
+ default n
+ if BSP_USING_I2C2
+ comment "Notice: PH13 --> 125; PH15 --> 127"
+ config BSP_I2C2_SCL_PIN
+ int "i2c2 scl pin number"
+ range 1 176
+ default 127
+ config BSP_I2C2_SDA_PIN
+ int "I2C2 sda pin number"
+ range 1 176
+ default 125
+ endif
+ endif
config BSP_USING_ON_CHIP_FLASH
bool "Enable on-chip FLASH"
default n
+ config BSP_USING_DCMI
+ bool "Enable DCMI"
+ default n
+
menuconfig BSP_USING_ONCHIP_RTC
bool "Enable RTC"
select RT_USING_RTC
diff --git a/bsp/stm32/stm32h743-atk-apollo/board/SConscript b/bsp/stm32/stm32h743-atk-apollo/board/SConscript
index 8ed2e269df..07cbe41b4f 100644
--- a/bsp/stm32/stm32h743-atk-apollo/board/SConscript
+++ b/bsp/stm32/stm32h743-atk-apollo/board/SConscript
@@ -17,6 +17,10 @@ if GetDepend(['BSP_USING_QSPI_FLASH']):
src += Glob('ports/drv_qspi_flash.c')
if GetDepend(['BSP_USING_SDMMC']):
src += Glob('ports/drv_sdio.c')
+if GetDepend(['BSP_USING_DCMI']):
+ src += Glob('ports/drv_dcmi.c')
+if GetDepend(['BSP_USING_OV2640']):
+ src += Glob('ports/drv_ov2640.c')
path = [cwd]
path += [cwd + '/CubeMX_Config/Inc']
diff --git a/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_dcmi.c b/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_dcmi.c
new file mode 100644
index 0000000000..8a57c37e01
--- /dev/null
+++ b/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_dcmi.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu the first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_DCMI)
+
+#include <drv_dcmi.h>
+
+#define DRV_DEBUG
+#define LOG_TAG "drv.dcmi"
+#include <drv_log.h>
+
+struct stm32_dcmi
+{
+ DCMI_HandleTypeDef DCMI_Handle;
+ struct rt_dcmi_device dev;
+};
+static struct stm32_dcmi rt_dcmi = {0};
+
+DMA_HandleTypeDef hdma_dcmi;
+
+static void rt_hw_dcmi_dma_init(void)
+{
+ __HAL_RCC_DMA2_CLK_ENABLE();
+
+ hdma_dcmi.Instance = DMA2_Stream1;
+ hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
+ hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_dcmi.Init.Mode = DMA_CIRCULAR;
+ hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ HAL_DMA_DeInit(&hdma_dcmi);
+ HAL_DMA_Init(&hdma_dcmi);
+
+ __HAL_LINKDMA(&rt_dcmi.DCMI_Handle, DMA_Handle, hdma_dcmi);
+
+ HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0x00, 0x00);
+ HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);;
+}
+
+void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint32_t len)
+{
+ __HAL_UNLOCK(&hdma_dcmi);
+
+ HAL_DMAEx_MultiBufferStart(&hdma_dcmi, (rt_uint32_t)&DCMI->DR, dst_addr1, dst_addr2, len);
+
+ __HAL_DMA_ENABLE_IT(&hdma_dcmi, DMA_IT_TC);
+}
+
+static rt_err_t rt_hw_dcmi_init(DCMI_HandleTypeDef *device)
+{
+ RT_ASSERT(device != RT_NULL);
+
+ device->Instance = DCMI;
+ device->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
+ device->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
+ device->Init.VSPolarity = DCMI_VSPOLARITY_LOW;
+ device->Init.HSPolarity = DCMI_HSPOLARITY_LOW;
+ device->Init.CaptureRate = DCMI_CR_ALL_FRAME;
+ device->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
+ device->Init.JPEGMode = DCMI_JPEG_ENABLE;
+ device->Init.ByteSelectMode = DCMI_BSM_ALL;
+ device->Init.ByteSelectStart = DCMI_OEBS_ODD;
+ device->Init.LineSelectMode = DCMI_LSM_ALL;
+ device->Init.LineSelectStart = DCMI_OELS_ODD;
+
+ if (HAL_DCMI_Init(device) != HAL_OK)
+ {
+ LOG_E("dcmi init error!");
+ return RT_ERROR;
+ }
+
+ DCMI->IER = 0x0;
+
+ __HAL_DCMI_ENABLE_IT(device, DCMI_IT_FRAME);
+ __HAL_DCMI_ENABLE(device);
+
+ return RT_EOK;
+}
+
+void DCMI_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_DCMI_IRQHandler(&rt_dcmi.DCMI_Handle);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void DCMI_Start(void)
+{
+ __HAL_DMA_ENABLE(&hdma_dcmi);
+ DCMI->CR |= DCMI_CR_CAPTURE;
+}
+
+void DCMI_Stop(void)
+{
+ DCMI->CR &= ~(DCMI_CR_CAPTURE);
+ while (DCMI->CR & 0x01);
+ __HAL_DMA_DISABLE(&hdma_dcmi);
+}
+
+/* Capture a frame of the image */
+void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
+{
+ extern void camera_frame_data_process(void);
+ /* enter interrupt */
+ rt_interrupt_enter();
+ /* move frame data to buffer */
+ camera_frame_data_process();
+
+ __HAL_DCMI_ENABLE_IT(&rt_dcmi.DCMI_Handle, DCMI_IT_FRAME);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void DMA2_Stream1_IRQHandler(void)
+{
+ extern void camera_dma_data_process(void);
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ if (__HAL_DMA_GET_FLAG(&hdma_dcmi, DMA_FLAG_TCIF1_5) != RESET)
+ {
+ __HAL_DMA_CLEAR_FLAG(&hdma_dcmi, DMA_FLAG_TCIF1_5);
+ /* move dma data to buffer */
+ camera_dma_data_process();
+ }
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+static rt_err_t rt_dcmi_init(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+ rt_err_t result = RT_EOK;
+
+ result = rt_hw_dcmi_init(&rt_dcmi.DCMI_Handle);
+ if (result != RT_EOK)
+ {
+ return result;
+ }
+
+ rt_hw_dcmi_dma_init();
+
+ return result;
+}
+
+static rt_err_t rt_dcmi_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_dcmi_close(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_dcmi_control(rt_device_t dev, int cmd, void *args)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_dcmi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_dcmi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+int dcmi_init(void)
+{
+ rt_dcmi.dev.parent.type = RT_Device_Class_Miscellaneous;
+ rt_dcmi.dev.parent.init = rt_dcmi_init;
+ rt_dcmi.dev.parent.open = rt_dcmi_open;
+ rt_dcmi.dev.parent.close = rt_dcmi_close;
+ rt_dcmi.dev.parent.read = rt_dcmi_read;
+ rt_dcmi.dev.parent.write = rt_dcmi_write;
+ rt_dcmi.dev.parent.control = rt_dcmi_control;
+ rt_dcmi.dev.parent.user_data = RT_NULL;
+
+ rt_device_register(&rt_dcmi.dev.parent, "dcmi", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+ LOG_I("dcmi init success!");
+
+ return RT_EOK;
+}
+INIT_BOARD_EXPORT(dcmi_init);
+
+#endif
diff --git a/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_dcmi.h b/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_dcmi.h
new file mode 100644
index 0000000000..af519987dd
--- /dev/null
+++ b/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_dcmi.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu the first version
+ */
+
+#ifndef __DRV_DCMI_H__
+#define __DRV_DCMI_H__
+
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct rt_dcmi_device
+{
+ struct rt_device parent;
+};
+
+extern DMA_HandleTypeDef hdma_dcmi;
+extern void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint32_t len);
+extern void DCMI_Start(void);
+extern void DCMI_Stop(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_ov2640.c b/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_ov2640.c
new file mode 100644
index 0000000000..0ed9345156
--- /dev/null
+++ b/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_ov2640.c
@@ -0,0 +1,751 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-08-03 thread-liu the first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_OV2640)
+
+#include <dfs_posix.h>
+#include <drv_ov2640.h>
+#include <drv_dcmi.h>
+#include "pcf8574.h"
+
+#define DRV_DEBUG
+//#define CAMERA_DUMP
+#define LOG_TAG "drv.ov2640"
+#include <drv_log.h>
+
+#define DEV_ADDRESS 0x30 /* OV2640 address */
+#define I2C_NAME "i2c2"
+
+#define RESET_PIN GET_PIN(A, 15) /* camera reset pin */
+
+/* camera PWDN pin */
+#define DCMI_PWDN_IO 2 /* pcf8574 (0-7) */
+
+volatile rt_uint32_t jpeg_data_len = 0;
+volatile rt_uint8_t jpeg_data_ok = 0;
+struct rt_i2c_bus_device *i2c_bus = RT_NULL;
+
+#define JPEG_BUF_SIZE 32 * 1024
+#define JPEG_LINE_SIZE 1 * 1024
+
+static pcf8574_device_t pcf_dev = RT_NULL;
+
+static rt_uint32_t *jpeg_data_buf = RT_NULL;
+static rt_uint32_t JPEG_LINE0_BUF[JPEG_LINE_SIZE];
+static rt_uint32_t JPEG_LINE1_BUF[JPEG_LINE_SIZE];
+
+#if defined(CAMERA_DUMP)
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
+{
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%08x:", i);
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j < buflen)
+ {
+ rt_kprintf("%02x", buf[i + j]);
+ }
+ else
+ {
+ rt_kprintf(" ");
+ }
+ }
+ rt_kprintf(" ");
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j < buflen)
+ {
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ }
+ }
+ rt_kprintf("\n");
+ }
+}
+#endif
+
+static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf)
+{
+ struct rt_i2c_msg msg[2];
+
+ RT_ASSERT(bus != RT_NULL);
+
+ msg[0].addr = DEV_ADDRESS;
+ msg[0].flags = RT_I2C_WR;
+ msg[0].buf = &reg;
+ msg[0].len = 2;
+
+ msg[1].addr = DEV_ADDRESS;
+ msg[1].flags = RT_I2C_RD;
+ msg[1].len = len;
+ msg[1].buf = buf;
+
+ if (rt_i2c_transfer(bus, msg, 2) == 2)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* i2c write reg */
+static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t data)
+{
+ rt_uint8_t buf[2];
+ struct rt_i2c_msg msgs;
+
+ RT_ASSERT(bus != RT_NULL);
+
+ buf[0] = reg ;
+ buf[1] = data;
+
+ msgs.addr = DEV_ADDRESS;
+ msgs.flags = RT_I2C_WR;
+ msgs.buf = buf;
+ msgs.len = 2;
+
+ if (rt_i2c_transfer(bus, &msgs, 1) == 1)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+static rt_err_t ov2640_read_id(struct rt_i2c_bus_device *bus)
+{
+ rt_uint8_t read_value[2];
+ rt_uint16_t id = 0;
+ read_reg(bus, OV2640_SENSOR_MIDH, 1, &read_value[0]);
+ read_reg(bus, OV2640_SENSOR_MIDL, 1, &read_value[1]);
+ id = ((rt_uint16_t)(read_value[0] << 8) & 0xFF00);
+ id |= ((rt_uint16_t)(read_value[1]) & 0x00FF);
+
+ if (id != OV2640_MID)
+ {
+ LOG_E("ov2640 init error, mid: 0x%04x", id);
+ return RT_ERROR;
+ }
+
+ LOG_I("ov2640 read mid success, mid: 0x%04x", id);
+
+ read_reg(bus, OV2640_SENSOR_PIDH, 1, &read_value[0]);
+ read_reg(bus, OV2640_SENSOR_PIDL, 1, &read_value[1]);
+ id = ((rt_uint16_t)(read_value[0] << 8) & 0xFF00);
+ id |= ((rt_uint16_t)(read_value[1]) & 0x00FF);
+
+ if (id != OV2640_PID)
+ {
+ LOG_E("ov2640 init error, pid: 0x%04x", id);
+ return RT_ERROR;
+ }
+
+ LOG_I("ov2640 read hid success, pid: 0x%04x", id);
+
+ return RT_EOK;
+}
+
+/* change ov2640 to jpeg mode */
+void ov2640_jpeg_mode(void)
+{
+ rt_uint16_t i=0;
+ /* set yun422 mode */
+ for (i = 0; i < (sizeof(ov2640_yuv422_reg_tbl) / 2); i++)
+ {
+ write_reg(i2c_bus, ov2640_yuv422_reg_tbl[i][0],ov2640_yuv422_reg_tbl[i][1]);
+ }
+
+ /* set jpeg mode */
+ for(i=0;i<(sizeof(ov2640_jpeg_reg_tbl)/2);i++)
+ {
+ write_reg(i2c_bus, ov2640_jpeg_reg_tbl[i][0],ov2640_jpeg_reg_tbl[i][1]);
+ }
+}
+
+/* change ov2640 to rgb565 mode */
+void ov2640_rgb565_mode(void)
+{
+ rt_uint16_t i=0;
+ for (i = 0; i < (sizeof(ov2640_rgb565_reg_tbl) / 2); i++)
+ {
+ write_reg(i2c_bus, ov2640_rgb565_reg_tbl[i][0],ov2640_rgb565_reg_tbl[i][1]);
+ }
+}
+
+/* set auto exposure */
+void ov2640_set_auto_exposure(rt_uint8_t level)
+{
+ rt_uint8_t i = 0;
+ rt_uint8_t *p = (rt_uint8_t*)OV2640_AUTOEXPOSURE_LEVEL[level];
+ for (i = 0; i < 4; i++)
+ {
+ write_reg(i2c_bus, p[i*2],p[i*2+1]);
+ }
+}
+
+/* set light mode
+ * 0: auto
+ * 1: sunny
+ * 2: cloudy
+ * 3: office
+ * 4: home
+ * */
+void ov2640_set_light_mode(rt_uint8_t mode)
+{
+ rt_uint8_t regccval, regcdval, regceval;
+
+ switch(mode)
+ {
+ case 0:
+ write_reg(i2c_bus, 0xFF, 0x00);
+ write_reg(i2c_bus, 0xC7, 0x10);
+ return;
+
+ case 2:
+ regccval = 0x65;
+ regcdval = 0x41;
+ regceval = 0x4F;
+ break;
+
+ case 3:
+ regccval = 0x52;
+ regcdval = 0x41;
+ regceval = 0x66;
+ break;
+
+ case 4:
+ regccval = 0x42;
+ regcdval = 0x3F;
+ regceval = 0x71;
+ break;
+
+ default:
+ regccval = 0x5E;
+ regcdval = 0x41;
+ regceval = 0x54;
+ break;
+ }
+
+ write_reg(i2c_bus, 0xFF, 0x00);
+ write_reg(i2c_bus, 0xC7, 0x40);
+ write_reg(i2c_bus, 0xCC, regccval);
+ write_reg(i2c_bus, 0xCD, regcdval);
+ write_reg(i2c_bus, 0xCE, regceval);
+}
+
+/* set color saturation
+ * 0: -2
+ * 1: -1
+ * 2: 0
+ * 3: +1
+ * 4: +2
+ * */
+void ov2640_set_color_saturation(rt_uint8_t sat)
+{
+ rt_uint8_t reg7dval = ((sat+2)<<4) | 0x08;
+ write_reg(i2c_bus, 0xFF, 0X00);
+ write_reg(i2c_bus, 0x7C, 0X00);
+ write_reg(i2c_bus, 0x7D, 0X02);
+ write_reg(i2c_bus, 0x7C, 0X03);
+ write_reg(i2c_bus, 0x7D, reg7dval);
+ write_reg(i2c_bus, 0x7D, reg7dval);
+}
+
+/* set brightness
+ * 0: -2
+ * 1: -1
+ * 2: 0
+ * 3: 1
+ * 4: 2
+ * */
+void ov2640_set_brightness(rt_uint8_t bright)
+{
+ write_reg(i2c_bus, 0xff, 0x00);
+ write_reg(i2c_bus, 0x7c, 0x00);
+ write_reg(i2c_bus, 0x7d, 0x04);
+ write_reg(i2c_bus, 0x7c, 0x09);
+ write_reg(i2c_bus, 0x7d, bright << 4);
+ write_reg(i2c_bus, 0x7d, 0x00);
+}
+
+/* set contrast
+ * 0: -2
+ * 1: -1
+ * 2: 0
+ * 3: 1
+ * 4: 2
+ * */
+void ov2640_set_contrast(rt_uint8_t contrast)
+{
+ rt_uint8_t reg7d0val, reg7d1val;
+
+ switch(contrast)
+ {
+ case 0:
+ reg7d0val = 0x18;
+ reg7d1val = 0x34;
+ break;
+
+ case 1:
+ reg7d0val = 0x1C;
+ reg7d1val = 0x2A;
+ break;
+
+ case 3:
+ reg7d0val = 0x24;
+ reg7d1val = 0x16;
+ break;
+
+ case 4:
+ reg7d0val = 0x28;
+ reg7d1val = 0x0C;
+ break;
+
+ default:
+ reg7d0val = 0x20;
+ reg7d1val = 0x20;
+ break;
+ }
+ write_reg(i2c_bus, 0xff, 0x00);
+ write_reg(i2c_bus, 0x7c, 0x00);
+ write_reg(i2c_bus, 0x7d, 0x04);
+ write_reg(i2c_bus, 0x7c, 0x07);
+ write_reg(i2c_bus, 0x7d, 0x20);
+ write_reg(i2c_bus, 0x7d, reg7d0val);
+ write_reg(i2c_bus, 0x7d, reg7d1val);
+ write_reg(i2c_bus, 0x7d, 0x06);
+}
+
+/* set special effects
+ * 0: noraml
+ * 1: negative film
+ * 2: black-and-white
+ * 3: the red
+ * 4: the green
+ * 5: the blue
+ * 6: Retro
+*/
+void ov2640_set_special_effects(rt_uint8_t eft)
+{
+ rt_uint8_t reg7d0val, reg7d1val, reg7d2val;
+
+ switch(eft)
+ {
+ case 1:
+ reg7d0val = 0x40;
+ break;
+ case 2:
+ reg7d0val = 0x18;
+ break;
+ case 3:
+ reg7d0val = 0x18;
+ reg7d1val = 0x40;
+ reg7d2val = 0xC0;
+ break;
+ case 4:
+ reg7d0val = 0x18;
+ reg7d1val = 0x40;
+ reg7d2val = 0x40;
+ break;
+ case 5:
+ reg7d0val = 0x18;
+ reg7d1val = 0xA0;
+ reg7d2val = 0x40;
+ break;
+ case 6:
+ reg7d0val = 0x18;
+ reg7d1val = 0x40;
+ reg7d2val = 0xA6;
+ break;
+ default:
+ reg7d0val = 0x00;
+ reg7d1val = 0x80;
+ reg7d2val = 0x80;
+ break;
+ }
+ write_reg(i2c_bus, 0xff, 0x00);
+ write_reg(i2c_bus, 0x7c, 0x00);
+ write_reg(i2c_bus, 0x7d, reg7d0val);
+ write_reg(i2c_bus, 0x7c, 0x05);
+ write_reg(i2c_bus, 0x7d, reg7d1val);
+ write_reg(i2c_bus, 0x7d, reg7d2val);
+}
+
+/* set the image output window */
+void ov2640_set_window_size(rt_uint16_t sx,rt_uint16_t sy,rt_uint16_t width,rt_uint16_t height)
+{
+ rt_uint16_t endx;
+ rt_uint16_t endy;
+ rt_uint8_t temp;
+ endx = sx + width / 2;
+ endy = sy + height / 2;
+
+ write_reg(i2c_bus, 0xFF, 0x01);
+ read_reg(i2c_bus, 0x03, 1, &temp);
+ temp &= 0xF0;
+ temp |= ((endy & 0x03) << 2) | (sy & 0x03);
+ write_reg(i2c_bus, 0x03, temp);
+ write_reg(i2c_bus, 0x19, sy>>2);
+ write_reg(i2c_bus, 0x1A, endy>>2);
+
+ read_reg(i2c_bus, 0x32, 1, &temp);
+ temp &= 0xC0;
+ temp |= ((endx & 0x07) << 3) | (sx & 0x07);
+ write_reg(i2c_bus, 0x32, temp);
+ write_reg(i2c_bus, 0x17, sx>>3);
+ write_reg(i2c_bus, 0x18, endx>>3);
+}
+
+/* set the image output size */
+rt_uint8_t ov2640_set_image_out_size(rt_uint16_t width,rt_uint16_t height)
+{
+ rt_uint16_t outh, outw;
+ rt_uint8_t temp;
+
+ if(width%4)return 1;
+ if(height%4)return 2;
+ outw = width / 4;
+ outh = height / 4;
+ write_reg(i2c_bus, 0xFF, 0x00);
+ write_reg(i2c_bus, 0xE0, 0x04);
+ write_reg(i2c_bus, 0x5A, outw & 0XFF);
+ write_reg(i2c_bus, 0x5B, outh & 0XFF);
+ temp = (outw >> 8) & 0x03;
+ temp |= (outh >> 6) & 0x04;
+ write_reg(i2c_bus, 0x5C, temp);
+ write_reg(i2c_bus, 0xE0, 0X00);
+
+ return RT_EOK;
+}
+
+/* set the image window size */
+rt_uint8_t ov2640_set_image_window_size(rt_uint16_t offx, rt_uint16_t offy, rt_uint16_t width, rt_uint16_t height)
+{
+ rt_uint16_t hsize, vsize;
+ rt_uint8_t temp;
+ if ((width % 4) || (height%4))
+ {
+ return RT_ERROR;
+ }
+ hsize = width / 4;
+ vsize = height / 4;
+ write_reg(i2c_bus, 0XFF,0X00);
+ write_reg(i2c_bus, 0XE0,0X04);
+ write_reg(i2c_bus, 0X51,hsize&0XFF);
+ write_reg(i2c_bus, 0X52,vsize&0XFF);
+ write_reg(i2c_bus, 0X53,offx&0XFF);
+ write_reg(i2c_bus, 0X54,offy&0XFF);
+ temp=(vsize>>1)&0X80;
+ temp|=(offy>>4)&0X70;
+ temp|=(hsize>>5)&0X08;
+ temp|=(offx>>8)&0X07;
+ write_reg(i2c_bus, 0X55,temp);
+ write_reg(i2c_bus, 0X57,(hsize>>2)&0X80);
+ write_reg(i2c_bus, 0XE0,0X00);
+ return 0;
+}
+
+/* set output resolution */
+rt_uint8_t ov2640_set_image_size(rt_uint16_t width ,rt_uint16_t height)
+{
+ rt_uint8_t temp;
+ write_reg(i2c_bus, 0xFF, 0x00);
+ write_reg(i2c_bus, 0xE0, 0x04);
+ write_reg(i2c_bus, 0xC0, (width >>3) & 0xFF);
+ write_reg(i2c_bus, 0xC1, (height >> 3) & 0xFF);
+ temp = (width & 0x07) << 3;
+ temp |= height & 0x07;
+ temp |= (width >> 4) & 0x80;
+ write_reg(i2c_bus, 0x8C, temp);
+ write_reg(i2c_bus, 0xE0, 0x00);
+
+ return RT_EOK;
+}
+
+void camera_dma_data_process(void)
+{
+ rt_uint16_t i;
+ rt_uint32_t *pbuf;
+ pbuf = jpeg_data_buf + jpeg_data_len;
+
+ if (DMA2_Stream1->CR & (1<<19))
+ {
+ for (i = 0; i < JPEG_LINE_SIZE; i++)
+ {
+ pbuf[i] = JPEG_LINE0_BUF[i];
+ }
+ jpeg_data_len += JPEG_LINE_SIZE;
+ }
+ else
+ {
+ for (i = 0; i < JPEG_LINE_SIZE; i++)
+ {
+ pbuf[i] = JPEG_LINE1_BUF[i];
+ }
+ jpeg_data_len += JPEG_LINE_SIZE;
+ }
+ SCB_CleanInvalidateDCache();
+}
+
+/* After a frame of picture data has been collected. */
+void camera_frame_data_process(void)
+{
+ rt_uint16_t i, rlen;
+ rt_uint32_t *pbuf = RT_NULL;
+
+ if (jpeg_data_ok == 0)
+ {
+ DMA2_Stream1->CR &= ~(1<<0);
+ while(DMA2_Stream1->CR & 0x01);
+
+ rlen = JPEG_LINE_SIZE - DMA2_Stream1->NDTR;
+ pbuf = jpeg_data_buf + jpeg_data_len;
+
+ if (DMA2_Stream1->CR & (1<<19))
+ {
+ for (i = 0; i < rlen; i++)
+ {
+ pbuf[i] = JPEG_LINE1_BUF[i];
+ }
+ }
+ else
+ {
+ for (i = 0; i < rlen; i++)
+ {
+ pbuf[i] = JPEG_LINE0_BUF[i];
+ }
+ }
+ jpeg_data_len += rlen;
+ jpeg_data_ok = 1;
+ }
+ if (jpeg_data_ok==2)
+ {
+ DMA2_Stream1->NDTR = JPEG_LINE_SIZE;
+ DMA2_Stream1->CR |= 1<<0;
+ jpeg_data_ok = 0;
+ jpeg_data_len = 0;
+ }
+}
+
+int ov2640_pwdn_set(rt_uint8_t sta)
+{
+ if (pcf_dev == RT_NULL)
+ {
+ LOG_E("can't find pcf8574 device!");
+ return -1;
+ }
+ pcf8574_pin_write(pcf_dev, DCMI_PWDN_IO, sta);
+
+ return 0;
+}
+
+void sw_ov2640_mode(void)
+{
+ GPIO_InitTypeDef GPIO_Initure = {0};
+
+ ov2640_pwdn_set(0);
+
+ GPIO_Initure.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_11;
+ GPIO_Initure.Mode = GPIO_MODE_AF_PP;
+ GPIO_Initure.Pull = GPIO_PULLUP;
+ GPIO_Initure.Speed = GPIO_SPEED_HIGH;
+ GPIO_Initure.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOC,&GPIO_Initure);
+}
+
+void sw_sdcard_mode(void)
+{
+ GPIO_InitTypeDef GPIO_Initure = {0};
+
+ ov2640_pwdn_set(1); /* OV2640 Power Down */
+
+ GPIO_Initure.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_11;
+ GPIO_Initure.Mode = GPIO_MODE_AF_PP;
+ GPIO_Initure.Pull = GPIO_PULLUP;
+ GPIO_Initure.Speed = GPIO_SPEED_HIGH;
+ GPIO_Initure.Alternate = GPIO_AF12_SDMMC1;
+ HAL_GPIO_Init(GPIOC, &GPIO_Initure);
+}
+
+int rt_ov2640_init(void)
+{
+ rt_uint16_t i = 0;
+ rt_err_t result = RT_EOK;
+ rt_device_t dcmi_dev = RT_NULL;
+
+ sw_ov2640_mode();
+ pcf_dev = pcf8574_init("i2c1", RT_NULL);
+ if (pcf_dev == RT_NULL)
+ {
+ LOG_E("can't find pcf8574, please check it");
+ return -RT_ERROR;
+ }
+
+ ov2640_pwdn_set(0);
+ rt_thread_delay(20);
+
+ /* ov2640 hard reset */
+ rt_pin_mode(RESET_PIN, PIN_MODE_OUTPUT);
+ rt_pin_write(RESET_PIN, PIN_LOW);
+ rt_thread_delay(20);
+ rt_pin_write(RESET_PIN, PIN_HIGH);
+ rt_thread_delay(20);
+
+ i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
+ if (i2c_bus == RT_NULL)
+ {
+ LOG_E("can't find %s deivce", I2C_NAME);
+ return RT_ERROR;
+ }
+ /* Prepare the camera to be configured */
+ result = write_reg(i2c_bus, OV2640_DSP_RA_DLMT, 0x01);
+ if (result != RT_EOK )
+ {
+ LOG_E("ov2640 write reg error!");
+ return RT_ERROR;
+ }
+ rt_thread_delay(10);
+ result = write_reg(i2c_bus, OV2640_SENSOR_COM7, 0x80);
+ if (result != RT_EOK)
+ {
+ LOG_E("ov2640 soft reset error!");
+ return RT_ERROR;
+ }
+ rt_thread_delay(20);
+
+ result = ov2640_read_id(i2c_bus);
+ if (result != RT_EOK )
+ {
+ LOG_E("ov2640 read id error!");
+ return RT_ERROR;
+ }
+
+ for (i = 0; i < sizeof(ov2640_svga_init_reg_tbl) / 2; i++)
+ {
+ write_reg(i2c_bus, ov2640_svga_init_reg_tbl[i][0], ov2640_svga_init_reg_tbl[i][1]);
+ }
+
+ ov2640_rgb565_mode();
+ ov2640_set_light_mode(0);
+ ov2640_set_color_saturation(3);
+ ov2640_set_brightness(4);
+ ov2640_set_contrast(3);
+ ov2640_jpeg_mode();
+ ov2640_set_image_window_size(0, 0, 320, 240);
+ ov2640_set_image_out_size(320, 240);
+
+ dcmi_dev = rt_device_find("dcmi");
+ if (dcmi_dev == RT_NULL)
+ {
+ LOG_E("can't find dcmi device!");
+ return RT_ERROR;
+ }
+ rt_device_open(dcmi_dev, RT_DEVICE_FLAG_RDWR);
+
+ jpeg_data_buf = rt_malloc(JPEG_BUF_SIZE);
+ if (RT_NULL == jpeg_data_buf)
+ {
+ rt_kprintf("jpeg data buf malloc error!\n");
+ return RT_ERROR;
+ }
+
+ /* start dcmi capture */
+ rt_hw_dcmi_dma_config((rt_uint32_t)JPEG_LINE0_BUF, (rt_uint32_t)JPEG_LINE1_BUF, JPEG_LINE_SIZE);
+
+ rt_kprintf("camera init success!\n");
+
+ return RT_EOK;
+}
+INIT_APP_EXPORT(rt_ov2640_init);
+
+int camera_sample(int argc, char **argv)
+{
+ rt_err_t result = RT_EOK;
+ int fd = -1;
+ rt_uint32_t i, jpg_start, jpg_len;
+ rt_uint8_t jpg_head = 0;
+ rt_uint8_t *p = RT_NULL;
+
+ if (argc != 2)
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("camera_sample file.jpg\n");
+ return -1;
+ }
+
+ sw_ov2640_mode();
+ DCMI_Start();
+
+ while (1)
+ {
+ while (jpeg_data_ok != 1);
+ jpeg_data_ok = 2;
+ while (jpeg_data_ok != 1);
+ DCMI_Stop();
+
+ p = (rt_uint8_t *)jpeg_data_buf;
+ jpg_len = 0;
+ jpg_head = 0;
+ for (i = 0; i < jpeg_data_len * 4; i++)
+ {
+ /* jpg head */
+ if ((p[i] == 0xFF) && (p[i + 1] == 0xD8))
+ {
+ jpg_start = i;
+ jpg_head = 1;
+ }
+ /* jpg end */
+ if ((p[i] == 0xFF) && (p[i + 1] == 0xD9) && jpg_head)
+ {
+ jpg_len = i - jpg_start + 2; /* a picture len */
+ break;
+ }
+ }
+ if (jpg_len)
+ {
+ p += jpg_start;
+ sw_sdcard_mode();
+ fd = open(argv[1], O_WRONLY | O_CREAT);
+ if (fd < 0)
+ {
+ rt_kprintf("open file for recording failed!\n");
+ result = -RT_ERROR;
+ goto _exit;
+ }
+ else
+ {
+ write(fd, p, jpg_len);
+ close(fd);
+ rt_kprintf("%s picture capture complate!\n", argv[1]);
+ break;
+ }
+ }
+ else
+ {
+ rt_kprintf("jpg_len error!\n");
+ result = -RT_ERROR;
+ goto _exit;
+ }
+ }
+
+_exit:
+ return result;;
+}
+MSH_CMD_EXPORT(camera_sample, record picture to a jpg file);
+
+#endif
diff --git a/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_ov2640.h b/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_ov2640.h
new file mode 100644
index 0000000000..4ff948b0c6
--- /dev/null
+++ b/bsp/stm32/stm32h743-atk-apollo/board/ports/drv_ov2640.h
@@ -0,0 +1,778 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu first version
+ */
+
+#ifndef __DRV_OV2640_H__
+#define __DRV_OV2640_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <board.h>
+
+#define OV2640_MID 0X7FA2
+#define OV2640_PID 0X2642
+
+
+//褰撻�夋嫨DSP鍦板潃(0XFF=0X00)鏃�,OV2640鐨凞SP瀵勫瓨鍣ㄥ湴鍧�鏄犲皠琛�
+#define OV2640_DSP_R_BYPASS 0x05
+#define OV2640_DSP_Qs 0x44
+#define OV2640_DSP_CTRL 0x50
+#define OV2640_DSP_HSIZE1 0x51
+#define OV2640_DSP_VSIZE1 0x52
+#define OV2640_DSP_XOFFL 0x53
+#define OV2640_DSP_YOFFL 0x54
+#define OV2640_DSP_VHYX 0x55
+#define OV2640_DSP_DPRP 0x56
+#define OV2640_DSP_TEST 0x57
+#define OV2640_DSP_ZMOW 0x5A
+#define OV2640_DSP_ZMOH 0x5B
+#define OV2640_DSP_ZMHH 0x5C
+#define OV2640_DSP_BPADDR 0x7C
+#define OV2640_DSP_BPDATA 0x7D
+#define OV2640_DSP_CTRL2 0x86
+#define OV2640_DSP_CTRL3 0x87
+#define OV2640_DSP_SIZEL 0x8C
+#define OV2640_DSP_HSIZE2 0xC0
+#define OV2640_DSP_VSIZE2 0xC1
+#define OV2640_DSP_CTRL0 0xC2
+#define OV2640_DSP_CTRL1 0xC3
+#define OV2640_DSP_R_DVP_SP 0xD3
+#define OV2640_DSP_IMAGE_MODE 0xDA
+#define OV2640_DSP_RESET 0xE0
+#define OV2640_DSP_MS_SP 0xF0
+#define OV2640_DSP_SS_ID 0x7F
+#define OV2640_DSP_SS_CTRL 0xF8
+#define OV2640_DSP_MC_BIST 0xF9
+#define OV2640_DSP_MC_AL 0xFA
+#define OV2640_DSP_MC_AH 0xFB
+#define OV2640_DSP_MC_D 0xFC
+#define OV2640_DSP_P_STATUS 0xFE
+#define OV2640_DSP_RA_DLMT 0xFF
+
+//褰撻�夋嫨浼犳劅鍣ㄥ湴鍧�(0XFF=0X01)鏃�,OV2640鐨凞SP瀵勫瓨鍣ㄥ湴鍧�鏄犲皠琛�
+#define OV2640_SENSOR_GAIN 0x00
+#define OV2640_SENSOR_COM1 0x03
+#define OV2640_SENSOR_REG04 0x04
+#define OV2640_SENSOR_REG08 0x08
+#define OV2640_SENSOR_COM2 0x09
+#define OV2640_SENSOR_PIDH 0x0A
+#define OV2640_SENSOR_PIDL 0x0B
+#define OV2640_SENSOR_COM3 0x0C
+#define OV2640_SENSOR_COM4 0x0D
+#define OV2640_SENSOR_AEC 0x10
+#define OV2640_SENSOR_CLKRC 0x11
+#define OV2640_SENSOR_COM7 0x12
+#define OV2640_SENSOR_COM8 0x13
+#define OV2640_SENSOR_COM9 0x14
+#define OV2640_SENSOR_COM10 0x15
+#define OV2640_SENSOR_HREFST 0x17
+#define OV2640_SENSOR_HREFEND 0x18
+#define OV2640_SENSOR_VSTART 0x19
+#define OV2640_SENSOR_VEND 0x1A
+#define OV2640_SENSOR_MIDH 0x1C
+#define OV2640_SENSOR_MIDL 0x1D
+#define OV2640_SENSOR_AEW 0x24
+#define OV2640_SENSOR_AEB 0x25
+#define OV2640_SENSOR_W 0x26
+#define OV2640_SENSOR_REG2A 0x2A
+#define OV2640_SENSOR_FRARL 0x2B
+#define OV2640_SENSOR_ADDVSL 0x2D
+#define OV2640_SENSOR_ADDVHS 0x2E
+#define OV2640_SENSOR_YAVG 0x2F
+#define OV2640_SENSOR_REG32 0x32
+#define OV2640_SENSOR_ARCOM2 0x34
+#define OV2640_SENSOR_REG45 0x45
+#define OV2640_SENSOR_FLL 0x46
+#define OV2640_SENSOR_FLH 0x47
+#define OV2640_SENSOR_COM19 0x48
+#define OV2640_SENSOR_ZOOMS 0x49
+#define OV2640_SENSOR_COM22 0x4B
+#define OV2640_SENSOR_COM25 0x4E
+#define OV2640_SENSOR_BD50 0x4F
+#define OV2640_SENSOR_BD60 0x50
+#define OV2640_SENSOR_REG5D 0x5D
+#define OV2640_SENSOR_REG5E 0x5E
+#define OV2640_SENSOR_REG5F 0x5F
+#define OV2640_SENSOR_REG60 0x60
+#define OV2640_SENSOR_HISTO_LOW 0x61
+#define OV2640_SENSOR_HISTO_HIGH 0x62
+
+/* Automatic exposure setting parameters table, support 5 levels */
+const rt_uint8_t OV2640_AUTOEXPOSURE_LEVEL[5][8]=
+{
+ {
+ 0xFF,0x01,
+ 0x24,0x20,
+ 0x25,0x18,
+ 0x26,0x60,
+ },
+ {
+ 0xFF,0x01,
+ 0x24,0x34,
+ 0x25,0x1c,
+ 0x26,0x00,
+ },
+ {
+ 0xFF,0x01,
+ 0x24,0x3e,
+ 0x25,0x38,
+ 0x26,0x81,
+ },
+ {
+ 0xFF,0x01,
+ 0x24,0x48,
+ 0x25,0x40,
+ 0x26,0x81,
+ },
+ {
+ 0xFF,0x01,
+ 0x24,0x58,
+ 0x25,0x50,
+ 0x26,0x92,
+ },
+};
+
+const rt_uint8_t ov2640_sxga_init_reg_tbl[][2]=
+{
+ {0xff, 0x00},
+ {0x2c, 0xff},
+ {0x2e, 0xdf},
+ {0xff, 0x01},
+ {0x3c, 0x32},
+ {0x11, 0x00},
+ {0x09, 0x02},
+ {0x04, 0xD8},
+ {0x13, 0xe5},
+ {0x14, 0x48},
+ {0x2c, 0x0c},
+ {0x33, 0x78},
+ {0x3a, 0x33},
+ {0x3b, 0xfB},
+ {0x3e, 0x00},
+ {0x43, 0x11},
+ {0x16, 0x10},
+ {0x39, 0x92},
+ {0x35, 0xda},
+ {0x22, 0x1a},
+ {0x37, 0xc3},
+ {0x23, 0x00},
+ {0x34, 0xc0},
+ {0x36, 0x1a},
+ {0x06, 0x88},
+ {0x07, 0xc0},
+ {0x0d, 0x87},
+ {0x0e, 0x41},
+ {0x4c, 0x00},
+ {0x48, 0x00},
+ {0x5B, 0x00},
+ {0x42, 0x03},
+ {0x4a, 0x81},
+ {0x21, 0x99},
+ {0x24, 0x40},
+ {0x25, 0x38},
+ {0x26, 0x82},
+ {0x5c, 0x00},
+ {0x63, 0x00},
+ {0x46, 0x00},
+ {0x0c, 0x3c},
+ {0x61, 0x70},
+ {0x62, 0x80},
+ {0x7c, 0x05},
+ {0x20, 0x80},
+ {0x28, 0x30},
+ {0x6c, 0x00},
+ {0x6d, 0x80},
+ {0x6e, 0x00},
+ {0x70, 0x02},
+ {0x71, 0x94},
+ {0x73, 0xc1},
+ {0x3d, 0x34},
+ {0x5a, 0x57},
+ {0x12, 0x00},
+ {0x17, 0x11},
+ {0x18, 0x75},
+ {0x19, 0x01},
+ {0x1a, 0x97},
+ {0x32, 0x36},
+ {0x03, 0x0f},
+ {0x37, 0x40},
+ {0x4f, 0xca},
+ {0x50, 0xa8},
+ {0x5a, 0x23},
+ {0x6d, 0x00},
+ {0x6d, 0x38},
+ {0xff, 0x00},
+ {0xe5, 0x7f},
+ {0xf9, 0xc0},
+ {0x41, 0x24},
+ {0xe0, 0x14},
+ {0x76, 0xff},
+ {0x33, 0xa0},
+ {0x42, 0x20},
+ {0x43, 0x18},
+ {0x4c, 0x00},
+ {0x87, 0xd5},
+ {0x88, 0x3f},
+ {0xd7, 0x03},
+ {0xd9, 0x10},
+ {0xd3, 0x82},
+ {0xc8, 0x08},
+ {0xc9, 0x80},
+ {0x7c, 0x00},
+ {0x7d, 0x00},
+ {0x7c, 0x03},
+ {0x7d, 0x48},
+ {0x7d, 0x48},
+ {0x7c, 0x08},
+ {0x7d, 0x20},
+ {0x7d, 0x10},
+ {0x7d, 0x0e},
+ {0x90, 0x00},
+ {0x91, 0x0e},
+ {0x91, 0x1a},
+ {0x91, 0x31},
+ {0x91, 0x5a},
+ {0x91, 0x69},
+ {0x91, 0x75},
+ {0x91, 0x7e},
+ {0x91, 0x88},
+ {0x91, 0x8f},
+ {0x91, 0x96},
+ {0x91, 0xa3},
+ {0x91, 0xaf},
+ {0x91, 0xc4},
+ {0x91, 0xd7},
+ {0x91, 0xe8},
+ {0x91, 0x20},
+ {0x92, 0x00},
+ {0x93, 0x06},
+ {0x93, 0xe3},
+ {0x93, 0x05},
+ {0x93, 0x05},
+ {0x93, 0x00},
+ {0x93, 0x04},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x96, 0x00},
+ {0x97, 0x08},
+ {0x97, 0x19},
+ {0x97, 0x02},
+ {0x97, 0x0c},
+ {0x97, 0x24},
+ {0x97, 0x30},
+ {0x97, 0x28},
+ {0x97, 0x26},
+ {0x97, 0x02},
+ {0x97, 0x98},
+ {0x97, 0x80},
+ {0x97, 0x00},
+ {0x97, 0x00},
+ {0xc3, 0xef},
+ {0xa4, 0x00},
+ {0xa8, 0x00},
+ {0xc5, 0x11},
+ {0xc6, 0x51},
+ {0xbf, 0x80},
+ {0xc7, 0x10},
+ {0xb6, 0x66},
+ {0xb8, 0xA5},
+ {0xb7, 0x64},
+ {0xb9, 0x7C},
+ {0xb3, 0xaf},
+ {0xb4, 0x97},
+ {0xb5, 0xFF},
+ {0xb0, 0xC5},
+ {0xb1, 0x94},
+ {0xb2, 0x0f},
+ {0xc4, 0x5c},
+ {0xc0, 0xc8},
+ {0xc1, 0x96},
+ {0x8c, 0x00},
+ {0x86, 0x3d},
+ {0x50, 0x00},
+ {0x51, 0x90},
+ {0x52, 0x2c},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x88},
+ {0x5a, 0x90},
+ {0x5b, 0x2C},
+ {0x5c, 0x05},
+ {0xd3, 0x02},
+ {0xc3, 0xed},
+ {0x7f, 0x00},
+ {0xda, 0x09},
+ {0xe5, 0x1f},
+ {0xe1, 0x67},
+ {0xe0, 0x00},
+ {0xdd, 0x7f},
+ {0x05, 0x00},
+};
+
+/* SVGA 800*600 */
+const rt_uint8_t ov2640_svga_init_reg_tbl[][2]=
+{
+ {0xff, 0x00},
+ {0x2c, 0xff},
+ {0x2e, 0xdf},
+ {0xff, 0x01},
+ {0x3c, 0x32},
+ {0x11, 0x00},
+ {0x09, 0x02},
+ {0x04, 0xD8},
+ {0x13, 0xe5},
+ {0x14, 0x48},
+ {0x2c, 0x0c},
+ {0x33, 0x78},
+ {0x3a, 0x33},
+ {0x3b, 0xfB},
+ {0x3e, 0x00},
+ {0x43, 0x11},
+ {0x16, 0x10},
+ {0x39, 0x92},
+ {0x35, 0xda},
+ {0x22, 0x1a},
+ {0x37, 0xc3},
+ {0x23, 0x00},
+ {0x34, 0xc0},
+ {0x36, 0x1a},
+ {0x06, 0x88},
+ {0x07, 0xc0},
+ {0x0d, 0x87},
+ {0x0e, 0x41},
+ {0x4c, 0x00},
+ {0x48, 0x00},
+ {0x5B, 0x00},
+ {0x42, 0x03},
+ {0x4a, 0x81},
+ {0x21, 0x99},
+ {0x24, 0x40},
+ {0x25, 0x38},
+ {0x26, 0x82},
+ {0x5c, 0x00},
+ {0x63, 0x00},
+ {0x46, 0x22},
+ {0x0c, 0x3c},
+ {0x61, 0x70},
+ {0x62, 0x80},
+ {0x7c, 0x05},
+ {0x20, 0x80},
+ {0x28, 0x30},
+ {0x6c, 0x00},
+ {0x6d, 0x80},
+ {0x6e, 0x00},
+ {0x70, 0x02},
+ {0x71, 0x94},
+ {0x73, 0xc1},
+ {0x3d, 0x34},
+ {0x5a, 0x57},
+ {0x12, 0x40},
+ {0x17, 0x11},
+ {0x18, 0x43},
+ {0x19, 0x00},
+ {0x1a, 0x4b},
+ {0x32, 0x09},
+ {0x37, 0xc0},
+ {0x4f, 0xca},
+ {0x50, 0xa8},
+ {0x5a, 0x23},
+ {0x6d, 0x00},
+ {0x3d, 0x38},
+ {0xff, 0x00},
+ {0xe5, 0x7f},
+ {0xf9, 0xc0},
+ {0x41, 0x24},
+ {0xe0, 0x14},
+ {0x76, 0xff},
+ {0x33, 0xa0},
+ {0x42, 0x20},
+ {0x43, 0x18},
+ {0x4c, 0x00},
+ {0x87, 0xd5},
+ {0x88, 0x3f},
+ {0xd7, 0x03},
+ {0xd9, 0x10},
+ {0xd3, 0x82},
+ {0xc8, 0x08},
+ {0xc9, 0x80},
+ {0x7c, 0x00},
+ {0x7d, 0x00},
+ {0x7c, 0x03},
+ {0x7d, 0x48},
+ {0x7d, 0x48},
+ {0x7c, 0x08},
+ {0x7d, 0x20},
+ {0x7d, 0x10},
+ {0x7d, 0x0e},
+ {0x90, 0x00},
+ {0x91, 0x0e},
+ {0x91, 0x1a},
+ {0x91, 0x31},
+ {0x91, 0x5a},
+ {0x91, 0x69},
+ {0x91, 0x75},
+ {0x91, 0x7e},
+ {0x91, 0x88},
+ {0x91, 0x8f},
+ {0x91, 0x96},
+ {0x91, 0xa3},
+ {0x91, 0xaf},
+ {0x91, 0xc4},
+ {0x91, 0xd7},
+ {0x91, 0xe8},
+ {0x91, 0x20},
+ {0x92, 0x00},
+ {0x93, 0x06},
+ {0x93, 0xe3},
+ {0x93, 0x05},
+ {0x93, 0x05},
+ {0x93, 0x00},
+ {0x93, 0x04},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x96, 0x00},
+ {0x97, 0x08},
+ {0x97, 0x19},
+ {0x97, 0x02},
+ {0x97, 0x0c},
+ {0x97, 0x24},
+ {0x97, 0x30},
+ {0x97, 0x28},
+ {0x97, 0x26},
+ {0x97, 0x02},
+ {0x97, 0x98},
+ {0x97, 0x80},
+ {0x97, 0x00},
+ {0x97, 0x00},
+ {0xc3, 0xed},
+ {0xa4, 0x00},
+ {0xa8, 0x00},
+ {0xc5, 0x11},
+ {0xc6, 0x51},
+ {0xbf, 0x80},
+ {0xc7, 0x10},
+ {0xb6, 0x66},
+ {0xb8, 0xA5},
+ {0xb7, 0x64},
+ {0xb9, 0x7C},
+ {0xb3, 0xaf},
+ {0xb4, 0x97},
+ {0xb5, 0xFF},
+ {0xb0, 0xC5},
+ {0xb1, 0x94},
+ {0xb2, 0x0f},
+ {0xc4, 0x5c},
+ {0xc0, 0x64},
+ {0xc1, 0x4B},
+ {0x8c, 0x00},
+ {0x86, 0x3D},
+ {0x50, 0x00},
+ {0x51, 0xC8},
+ {0x52, 0x96},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x5a, 0xC8},
+ {0x5b, 0x96},
+ {0x5c, 0x00},
+ {0xd3, 0x02},
+ {0xc3, 0xed},
+ {0x7f, 0x00},
+ {0xda, 0x09},
+ {0xe5, 0x1f},
+ {0xe1, 0x67},
+ {0xe0, 0x00},
+ {0xdd, 0x7f},
+ {0x05, 0x00},
+};
+
+/* Initialization sequence for QVGA resolution (320x240) */
+const unsigned char OV2640_QVGA[][2]=
+{
+ {0xff, 0x00},
+ {0x2c, 0xff},
+ {0x2e, 0xdf},
+ {0xff, 0x01},
+ {0x3c, 0x32},
+ {0x11, 0x00},
+ {0x09, 0x02},
+ {0x04, 0xA8},
+ {0x13, 0xe5},
+ {0x14, 0x48},
+ {0x2c, 0x0c},
+ {0x33, 0x78},
+ {0x3a, 0x33},
+ {0x3b, 0xfB},
+ {0x3e, 0x00},
+ {0x43, 0x11},
+ {0x16, 0x10},
+ {0x4a, 0x81},
+ {0x21, 0x99},
+ {0x24, 0x40},
+ {0x25, 0x38},
+ {0x26, 0x82},
+ {0x5c, 0x00},
+ {0x63, 0x00},
+ {0x46, 0x3f},
+ {0x0c, 0x3c},
+ {0x61, 0x70},
+ {0x62, 0x80},
+ {0x7c, 0x05},
+ {0x20, 0x80},
+ {0x28, 0x30},
+ {0x6c, 0x00},
+ {0x6d, 0x80},
+ {0x6e, 0x00},
+ {0x70, 0x02},
+ {0x71, 0x94},
+ {0x73, 0xc1},
+ {0x3d, 0x34},
+ {0x5a, 0x57},
+ {0x12, 0x00},
+ {0x11, 0x00},
+ {0x17, 0x11},
+ {0x18, 0x75},
+ {0x19, 0x01},
+ {0x1a, 0x97},
+ {0x32, 0x36},
+ {0x03, 0x0f},
+ {0x37, 0x40},
+ {0x4f, 0xbb},
+ {0x50, 0x9c},
+ {0x5a, 0x57},
+ {0x6d, 0x80},
+ {0x6d, 0x38},
+ {0x39, 0x02},
+ {0x35, 0x88},
+ {0x22, 0x0a},
+ {0x37, 0x40},
+ {0x23, 0x00},
+ {0x34, 0xa0},
+ {0x36, 0x1a},
+ {0x06, 0x02},
+ {0x07, 0xc0},
+ {0x0d, 0xb7},
+ {0x0e, 0x01},
+ {0x4c, 0x00},
+ {0xff, 0x00},
+ {0xe5, 0x7f},
+ {0xf9, 0xc0},
+ {0x41, 0x24},
+ {0xe0, 0x14},
+ {0x76, 0xff},
+ {0x33, 0xa0},
+ {0x42, 0x20},
+ {0x43, 0x18},
+ {0x4c, 0x00},
+ {0x87, 0xd0},
+ {0x88, 0x3f},
+ {0xd7, 0x03},
+ {0xd9, 0x10},
+ {0xd3, 0x82},
+ {0xc8, 0x08},
+ {0xc9, 0x80},
+ {0x7d, 0x00},
+ {0x7c, 0x03},
+ {0x7d, 0x48},
+ {0x7c, 0x08},
+ {0x7d, 0x20},
+ {0x7d, 0x10},
+ {0x7d, 0x0e},
+ {0x90, 0x00},
+ {0x91, 0x0e},
+ {0x91, 0x1a},
+ {0x91, 0x31},
+ {0x91, 0x5a},
+ {0x91, 0x69},
+ {0x91, 0x75},
+ {0x91, 0x7e},
+ {0x91, 0x88},
+ {0x91, 0x8f},
+ {0x91, 0x96},
+ {0x91, 0xa3},
+ {0x91, 0xaf},
+ {0x91, 0xc4},
+ {0x91, 0xd7},
+ {0x91, 0xe8},
+ {0x91, 0x20},
+ {0x92, 0x00},
+ {0x93, 0x06},
+ {0x93, 0xe3},
+ {0x93, 0x02},
+ {0x93, 0x02},
+ {0x93, 0x00},
+ {0x93, 0x04},
+ {0x93, 0x00},
+ {0x93, 0x03},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x93, 0x00},
+ {0x96, 0x00},
+ {0x97, 0x08},
+ {0x97, 0x19},
+ {0x97, 0x02},
+ {0x97, 0x0c},
+ {0x97, 0x24},
+ {0x97, 0x30},
+ {0x97, 0x28},
+ {0x97, 0x26},
+ {0x97, 0x02},
+ {0x97, 0x98},
+ {0x97, 0x80},
+ {0x97, 0x00},
+ {0x97, 0x00},
+ {0xc3, 0xef},
+ {0xff, 0x00},
+ {0xba, 0xdc},
+ {0xbb, 0x08},
+ {0xb6, 0x24},
+ {0xb8, 0x33},
+ {0xb7, 0x20},
+ {0xb9, 0x30},
+ {0xb3, 0xb4},
+ {0xb4, 0xca},
+ {0xb5, 0x43},
+ {0xb0, 0x5c},
+ {0xb1, 0x4f},
+ {0xb2, 0x06},
+ {0xc7, 0x00},
+ {0xc6, 0x51},
+ {0xc5, 0x11},
+ {0xc4, 0x9c},
+ {0xbf, 0x00},
+ {0xbc, 0x64},
+ {0xa6, 0x00},
+ {0xa7, 0x1e},
+ {0xa7, 0x6b},
+ {0xa7, 0x47},
+ {0xa7, 0x33},
+ {0xa7, 0x00},
+ {0xa7, 0x23},
+ {0xa7, 0x2e},
+ {0xa7, 0x85},
+ {0xa7, 0x42},
+ {0xa7, 0x33},
+ {0xa7, 0x00},
+ {0xa7, 0x23},
+ {0xa7, 0x1b},
+ {0xa7, 0x74},
+ {0xa7, 0x42},
+ {0xa7, 0x33},
+ {0xa7, 0x00},
+ {0xa7, 0x23},
+ {0xc0, 0xc8},
+ {0xc1, 0x96},
+ {0x8c, 0x00},
+ {0x86, 0x3d},
+ {0x50, 0x92},
+ {0x51, 0x90},
+ {0x52, 0x2c},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x88},
+ {0x5a, 0x50},
+ {0x5b, 0x3c},
+ {0x5c, 0x00},
+ {0xd3, 0x04},
+ {0x7f, 0x00},
+ {0xda, 0x00},
+ {0xe5, 0x1f},
+ {0xe1, 0x67},
+ {0xe0, 0x00},
+ {0xdd, 0x7f},
+ {0x05, 0x00},
+ {0xff, 0x00},
+ {0xe0, 0x04},
+ {0xc0, 0xc8},
+ {0xc1, 0x96},
+ {0x86, 0x3d},
+ {0x50, 0x92},
+ {0x51, 0x90},
+ {0x52, 0x2c},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x88},
+ {0x57, 0x00},
+ {0x5a, 0x50},
+ {0x5b, 0x3C},
+ {0x5c, 0x00},
+ {0xd3, 0x08},
+ {0xe0, 0x00},
+ {0xFF, 0x00},
+ {0x05, 0x00},
+ {0xDA, 0x08},
+ {0xda, 0x09},
+ {0x98, 0x00},
+ {0x99, 0x00},
+ {0x00, 0x00},
+};
+
+const rt_uint8_t ov2640_jpeg_reg_tbl[][2]=
+{
+ {0xff, 0x01},
+ {0xe0, 0x14},
+ {0xe1, 0x77},
+ {0xe5, 0x1f},
+ {0xd7, 0x03},
+ {0xda, 0x10},
+ {0xe0, 0x00},
+};
+
+const rt_uint8_t ov2640_rgb565_reg_tbl[][2]=
+{
+ {0xFF, 0x00},
+ {0xDA, 0x09},
+ {0xD7, 0x03},
+ {0xDF, 0x02},
+ {0x33, 0xa0},
+ {0x3C, 0x00},
+ {0xe1, 0x67},
+
+ {0xff, 0x01},
+ {0xe0, 0x00},
+ {0xe1, 0x00},
+ {0xe5, 0x00},
+ {0xd7, 0x00},
+ {0xda, 0x00},
+ {0xe0, 0x00},
+};
+const rt_uint8_t ov2640_yuv422_reg_tbl[][2] =
+{
+ {0xFF, 0x00},
+ {0xDA, 0x10},
+ {0xD7, 0x03},
+ {0xDF, 0x00},
+ {0x33, 0x80},
+ {0x3C, 0x40},
+ {0xe1, 0x77},
+ {0x00, 0x00},
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject
index f56464c131..c2677f50a6 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/.mxproject
@@ -1,11 +1,5 @@
-[PreviousGenFiles]
-HeaderPath=E:/1-thread-source/rt-thread_f/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc
-HeaderFiles=stm32l4xx_it.h;stm32l4xx_hal_conf.h;main.h;
-SourcePath=E:/1-thread-source/rt-thread_f/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src
-SourceFiles=stm32l4xx_it.c;stm32l4xx_hal_msp.c;main.c;
-
[PreviousLibFiles]
-LibFiles=Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_lptim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_sdmmc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_lptim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_sdmmc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_lptim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_sdmmc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l475xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;Drivers/CMSIS/Include/cmsis_armcc.h;Drivers/CMSIS/Include/cmsis_armclang.h;Drivers/CMSIS/Include/cmsis_compiler.h;Drivers/CMSIS/Include/cmsis_gcc.h;Drivers/CMSIS/Include/cmsis_iccarm.h;Drivers/CMSIS/Include/cmsis_version.h;Drivers/CMSIS/Include/core_armv8mbl.h;Drivers/CMSIS/Include/core_armv8mml.h;Drivers/CMSIS/Include/core_cm0.h;Drivers/CMSIS/Include/core_cm0plus.h;Drivers/CMSIS/Include/core_cm1.h;Drivers/CMSIS/Include/core_cm23.h;Drivers/CMSIS/Include/core_cm3.h;Drivers/CMSIS/Include/core_cm33.h;Drivers/CMSIS/Include/core_cm4.h;Drivers/CMSIS/Include/core_cm7.h;Drivers/CMSIS/Include/core_sc000.h;Drivers/CMSIS/Include/core_sc300.h;Drivers/CMSIS/Include/mpu_armv7.h;Drivers/CMSIS/Include/mpu_armv8.h;Drivers/CMSIS/Include/tz_context.h;
+LibFiles=Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dac.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dac_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_lptim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_sdmmc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dac.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dac_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_lptim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_sdmmc.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_adc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_adc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_def.h;Drivers/STM32L4xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_i2c_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rcc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_flash_ramfunc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_gpio_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dma_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pwr_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_cortex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_exti.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dac.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_dac_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_iwdg.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_lptim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_qspi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_rtc_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sai_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_sdmmc.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_sd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_spi_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_tim_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_pcd_ex.h;Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_ll_usb.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l475xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Include/system_stm32l4xx.h;Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;
[PreviousUsedKeilFiles]
SourceFiles=..\Src\main.c;..\Src\stm32l4xx_it.c;..\Src\stm32l4xx_hal_msp.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_lptim.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_sdmmc.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;..\\Src/system_stm32l4xx.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_adc_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_iwdg.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_lptim.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_qspi.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rtc_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sai_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_sdmmc.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_sd_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_spi_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pcd_ex.c;..\Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_ll_usb.c;..\\Src/system_stm32l4xx.c;..\Drivers/CMSIS/Device/ST/STM32L4xx/Source/Templates/system_stm32l4xx.c;;
@@ -15,3 +9,9 @@ CDefines=USE_HAL_DRIVER;STM32L475xx;USE_HAL_DRIVER;USE_HAL_DRIVER;
[]
SourceFiles=;;
+[PreviousGenFiles]
+HeaderPath=G:/workspaces/rt-thread-gitee/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc
+HeaderFiles=stm32l4xx_it.h;stm32l4xx_hal_conf.h;main.h;
+SourcePath=G:/workspaces/rt-thread-gitee/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src
+SourceFiles=stm32l4xx_it.c;stm32l4xx_hal_msp.c;main.c;
+
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h
index 0b52b6e496..0fbd8f3767 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_hal_conf.h
@@ -1,40 +1,27 @@
/**
******************************************************************************
* @file stm32l4xx_hal_conf.h
- * @brief HAL configuration file.
+ * @author MCD Application Team
+ * @brief HAL configuration template file.
+ * This file should be copied to the application folder and renamed
+ * to stm32l4xx_hal_conf.h.
******************************************************************************
* @attention
*
- * <h2><center>&copy; COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
+ * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
+ * All rights reserved.</center></h2>
*
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
- */
+ */
/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32L4xx_HAL_CONF_H
-#define __STM32L4xx_HAL_CONF_H
+#ifndef STM32L4xx_HAL_CONF_H
+#define STM32L4xx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
@@ -45,17 +32,16 @@
/* ########################## Module Selection ############################## */
/**
- * @brief This is the list of modules to be used in the HAL driver
+ * @brief This is the list of modules to be used in the HAL driver
*/
-
-#define HAL_MODULE_ENABLED
+#define HAL_MODULE_ENABLED
#define HAL_ADC_MODULE_ENABLED
/*#define HAL_CRYP_MODULE_ENABLED */
/*#define HAL_CAN_MODULE_ENABLED */
/*#define HAL_COMP_MODULE_ENABLED */
/*#define HAL_CRC_MODULE_ENABLED */
/*#define HAL_CRYP_MODULE_ENABLED */
-/*#define HAL_DAC_MODULE_ENABLED */
+#define HAL_DAC_MODULE_ENABLED
/*#define HAL_DCMI_MODULE_ENABLED */
/*#define HAL_DMA2D_MODULE_ENABLED */
/*#define HAL_DFSDM_MODULE_ENABLED */
@@ -97,7 +83,7 @@
/*#define HAL_EXTI_MODULE_ENABLED */
/*#define HAL_PSSI_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
-#define HAL_EXTI_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
#define HAL_I2C_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
@@ -109,9 +95,9 @@
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
- * (when HSE is used as system clock source, directly or through the PLL).
+ * (when HSE is used as system clock source, directly or through the PLL).
*/
-#if !defined (HSE_VALUE)
+#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
@@ -129,7 +115,7 @@
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
- * (when HSI is used as system clock source, directly or through the PLL).
+ * (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
@@ -142,7 +128,7 @@
* When the CRS is not used, the HSI48 RC oscillator runs on it default frequency
* which is subject to manufacturing process variations.
*/
-#if !defined (HSI48_VALUE)
+#if !defined (HSI48_VALUE)
#define HSI48_VALUE ((uint32_t)48000000U) /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz.
The real value my vary depending on manufacturing process variations.*/
#endif /* HSI48_VALUE */
@@ -150,8 +136,8 @@
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
-#if !defined (LSI_VALUE)
- #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE 32000U /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
@@ -161,29 +147,29 @@
* This value is used by the UART, RTC HAL module to compute the system frequency
*/
#if !defined (LSE_VALUE)
- #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External oscillator in Hz*/
+ #define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
- #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
+ #define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for SAI1 peripheral
- * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
+ * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
* frequency.
*/
#if !defined (EXTERNAL_SAI1_CLOCK_VALUE)
- #define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t)2097000U) /*!< Value of the SAI1 External clock source in Hz*/
+ #define EXTERNAL_SAI1_CLOCK_VALUE 2097000U /*!< Value of the SAI1 External clock source in Hz*/
#endif /* EXTERNAL_SAI1_CLOCK_VALUE */
/**
* @brief External clock source for SAI2 peripheral
- * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
+ * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
* frequency.
*/
#if !defined (EXTERNAL_SAI2_CLOCK_VALUE)
- #define EXTERNAL_SAI2_CLOCK_VALUE ((uint32_t)2097000U) /*!< Value of the SAI2 External clock source in Hz*/
+ #define EXTERNAL_SAI2_CLOCK_VALUE 2097000U /*!< Value of the SAI2 External clock source in Hz*/
#endif /* EXTERNAL_SAI2_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
@@ -192,22 +178,67 @@
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
- */
-
-#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
-#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
-#define USE_RTOS 0U
+ */
+
+#define VDD_VALUE 3300U /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */
+#define USE_RTOS 0U
#define PREFETCH_ENABLE 0U
#define INSTRUCTION_CACHE_ENABLE 1U
#define DATA_CACHE_ENABLE 1U
/* ########################## Assert Selection ############################## */
/**
- * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
+/* ################## Register callback feature configuration ############### */
+/**
+ * @brief Set below the peripheral configuration to "1U" to add the support
+ * of HAL callback registration/deregistration feature for the HAL
+ * driver(s). This allows user application to provide specific callback
+ * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting
+ * the default weak callback functions (see each stm32l4xx_hal_ppp.h file
+ * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef
+ * for each PPP peripheral).
+ */
+#define USE_HAL_ADC_REGISTER_CALLBACKS 0U
+#define USE_HAL_CAN_REGISTER_CALLBACKS 0U
+#define USE_HAL_COMP_REGISTER_CALLBACKS 0U
+#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U
+#define USE_HAL_DAC_REGISTER_CALLBACKS 0U
+#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U
+#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U
+#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U
+#define USE_HAL_DSI_REGISTER_CALLBACKS 0U
+#define USE_HAL_GFXMMU_REGISTER_CALLBACKS 0U
+#define USE_HAL_HASH_REGISTER_CALLBACKS 0U
+#define USE_HAL_HCD_REGISTER_CALLBACKS 0U
+#define USE_HAL_I2C_REGISTER_CALLBACKS 0U
+#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U
+#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U
+#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U
+#define USE_HAL_MMC_REGISTER_CALLBACKS 0U
+#define USE_HAL_OPAMP_REGISTER_CALLBACKS 0U
+#define USE_HAL_OSPI_REGISTER_CALLBACKS 0U
+#define USE_HAL_PCD_REGISTER_CALLBACKS 0U
+#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U
+#define USE_HAL_RNG_REGISTER_CALLBACKS 0U
+#define USE_HAL_RTC_REGISTER_CALLBACKS 0U
+#define USE_HAL_SAI_REGISTER_CALLBACKS 0U
+#define USE_HAL_SD_REGISTER_CALLBACKS 0U
+#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U
+#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U
+#define USE_HAL_SPI_REGISTER_CALLBACKS 0U
+#define USE_HAL_SWPMI_REGISTER_CALLBACKS 0U
+#define USE_HAL_TIM_REGISTER_CALLBACKS 0U
+#define USE_HAL_TSC_REGISTER_CALLBACKS 0U
+#define USE_HAL_UART_REGISTER_CALLBACKS 0U
+#define USE_HAL_USART_REGISTER_CALLBACKS 0U
+#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U
+
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
@@ -224,20 +255,14 @@
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32l4xx_hal_rcc.h"
- #include "stm32l4xx_hal_rcc_ex.h"
#endif /* HAL_RCC_MODULE_ENABLED */
-#ifdef HAL_EXTI_MODULE_ENABLED
- #include "stm32l4xx_hal_exti.h"
-#endif /* HAL_EXTI_MODULE_ENABLED */
-
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32l4xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32l4xx_hal_dma.h"
- #include "stm32l4xx_hal_dma_ex.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_DFSDM_MODULE_ENABLED
@@ -256,6 +281,10 @@
#include "stm32l4xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */
+#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
+ #include "Legacy/stm32l4xx_hal_can_legacy.h"
+#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
+
#ifdef HAL_COMP_MODULE_ENABLED
#include "stm32l4xx_hal_comp.h"
#endif /* HAL_COMP_MODULE_ENABLED */
@@ -284,6 +313,14 @@
#include "stm32l4xx_hal_dsi.h"
#endif /* HAL_DSI_MODULE_ENABLED */
+#ifdef HAL_EXTI_MODULE_ENABLED
+ #include "stm32l4xx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_GFXMMU_MODULE_ENABLED
+ #include "stm32l4xx_hal_gfxmmu.h"
+#endif /* HAL_GFXMMU_MODULE_ENABLED */
+
#ifdef HAL_FIREWALL_MODULE_ENABLED
#include "stm32l4xx_hal_firewall.h"
#endif /* HAL_FIREWALL_MODULE_ENABLED */
@@ -296,26 +333,18 @@
#include "stm32l4xx_hal_hash.h"
#endif /* HAL_HASH_MODULE_ENABLED */
-#ifdef HAL_SRAM_MODULE_ENABLED
- #include "stm32l4xx_hal_sram.h"
-#endif /* HAL_SRAM_MODULE_ENABLED */
-
-#ifdef HAL_MMC_MODULE_ENABLED
- #include "stm32l4xx_hal_mmc.h"
-#endif /* HAL_MMC_MODULE_ENABLED */
-
-#ifdef HAL_NOR_MODULE_ENABLED
- #include "stm32l4xx_hal_nor.h"
-#endif /* HAL_NOR_MODULE_ENABLED */
-
-#ifdef HAL_NAND_MODULE_ENABLED
- #include "stm32l4xx_hal_nand.h"
-#endif /* HAL_NAND_MODULE_ENABLED */
+#ifdef HAL_HCD_MODULE_ENABLED
+ #include "stm32l4xx_hal_hcd.h"
+#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32l4xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32l4xx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32l4xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
@@ -332,6 +361,18 @@
#include "stm32l4xx_hal_ltdc.h"
#endif /* HAL_LTDC_MODULE_ENABLED */
+#ifdef HAL_MMC_MODULE_ENABLED
+ #include "stm32l4xx_hal_mmc.h"
+#endif /* HAL_MMC_MODULE_ENABLED */
+
+#ifdef HAL_NAND_MODULE_ENABLED
+ #include "stm32l4xx_hal_nand.h"
+#endif /* HAL_NAND_MODULE_ENABLED */
+
+#ifdef HAL_NOR_MODULE_ENABLED
+ #include "stm32l4xx_hal_nor.h"
+#endif /* HAL_NOR_MODULE_ENABLED */
+
#ifdef HAL_OPAMP_MODULE_ENABLED
#include "stm32l4xx_hal_opamp.h"
#endif /* HAL_OPAMP_MODULE_ENABLED */
@@ -340,9 +381,17 @@
#include "stm32l4xx_hal_ospi.h"
#endif /* HAL_OSPI_MODULE_ENABLED */
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32l4xx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
#ifdef HAL_PKA_MODULE_ENABLED
#include "stm32l4xx_hal_pka.h"
-#endif /* HAL_PWR_MODULE_ENABLED */
+#endif /* HAL_PKA_MODULE_ENABLED */
+
+#ifdef HAL_PSSI_MODULE_ENABLED
+ #include "stm32l4xx_hal_pssi.h"
+#endif /* HAL_PSSI_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32l4xx_hal_pwr.h"
@@ -368,6 +417,10 @@
#include "stm32l4xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32l4xx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32l4xx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
@@ -376,6 +429,10 @@
#include "stm32l4xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
+#ifdef HAL_SRAM_MODULE_ENABLED
+ #include "stm32l4xx_hal_sram.h"
+#endif /* HAL_SRAM_MODULE_ENABLED */
+
#ifdef HAL_SWPMI_MODULE_ENABLED
#include "stm32l4xx_hal_swpmi.h"
#endif /* HAL_SWPMI_MODULE_ENABLED */
@@ -396,39 +453,15 @@
#include "stm32l4xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
-#ifdef HAL_IRDA_MODULE_ENABLED
- #include "stm32l4xx_hal_irda.h"
-#endif /* HAL_IRDA_MODULE_ENABLED */
-
-#ifdef HAL_SMARTCARD_MODULE_ENABLED
- #include "stm32l4xx_hal_smartcard.h"
-#endif /* HAL_SMARTCARD_MODULE_ENABLED */
-
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32l4xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
-#ifdef HAL_PCD_MODULE_ENABLED
- #include "stm32l4xx_hal_pcd.h"
-#endif /* HAL_PCD_MODULE_ENABLED */
-
-#ifdef HAL_HCD_MODULE_ENABLED
- #include "stm32l4xx_hal_hcd.h"
-#endif /* HAL_HCD_MODULE_ENABLED */
-
-#ifdef HAL_GFXMMU_MODULE_ENABLED
- #include "stm32l4xx_hal_gfxmmu.h"
-#endif /* HAL_GFXMMU_MODULE_ENABLED */
-
-#ifdef HAL_PSSI_MODULE_ENABLED
- #include "stm32l4xx_hal_pssi.h"
-#endif /* HAL_PSSI_MODULE_ENABLED */
-
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
- * @param expr: If expr is false, it calls assert_failed function
+ * @param expr If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
@@ -436,7 +469,7 @@
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
- void assert_failed(char *file, uint32_t line);
+ void assert_failed(uint8_t *file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
@@ -445,6 +478,6 @@
}
#endif
-#endif /* __STM32L4xx_HAL_CONF_H */
+#endif /* STM32L4xx_HAL_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_it.h b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_it.h
index 666700442b..c609646383 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_it.h
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Inc/stm32l4xx_it.h
@@ -39,7 +39,7 @@
#ifdef __cplusplus
extern "C" {
-#endif
+#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc
index 5b1083a232..3a59471b8a 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/STM32L475VE.ioc
@@ -1,363 +1,369 @@
#MicroXplorer Configuration settings - do not modify
+ADC1.Channel-15\#ChannelRegularConversion=ADC_CHANNEL_14
+ADC1.IPParameters=Rank-15\#ChannelRegularConversion,Channel-15\#ChannelRegularConversion,SamplingTime-15\#ChannelRegularConversion,OffsetNumber-15\#ChannelRegularConversion,NbrOfConversionFlag,master
+ADC1.NbrOfConversionFlag=1
+ADC1.OffsetNumber-15\#ChannelRegularConversion=ADC_OFFSET_NONE
+ADC1.Rank-15\#ChannelRegularConversion=1
+ADC1.SamplingTime-15\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
+ADC1.master=1
+File.Version=6
+KeepUserPlacement=false
Mcu.Family=STM32L4
-ProjectManager.MainLocation=Src
-PA6.Mode=Full_Duplex_Master
-SH.S_TIM4_CH2.ConfNb=1
-RCC.USART1Freq_Value=80000000
-RCC.SAI1Freq_Value=13714285.714285715
-USART2.IPParameters=VirtualMode-Asynchronous
-RCC.CortexFreq_Value=80000000
-SPI3.Direction=SPI_DIRECTION_2LINES
-VP_TIM17_VS_ClockSourceINT.Mode=Enable_Timer
-SPI3.VirtualType=VM_MASTER
-ProjectManager.KeepUserCode=true
-Mcu.UserName=STM32L475VETx
-SPI1.VirtualType=VM_MASTER
-SPI2.VirtualType=VM_MASTER
-PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN
-TIM1.IPParameters=Channel-PWM Generation1 CH1
-PC10.Signal=SDMMC1_D2
-PC12.Signal=SDMMC1_CK
-VP_IWDG_VS_IWDG.Mode=IWDG_Activate
-RCC.PLLSAI1RoutputFreq_Value=48000000
-ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true,5-MX_QUADSPI_Init-QUADSPI-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_SPI2_Init-SPI2-false-HAL-true,8-MX_RTC_Init-RTC-false-HAL-true,9-MX_ADC1_Init-ADC1-false-HAL-true,10-MX_IWDG_Init-IWDG-false-HAL-true,11-MX_TIM17_Init-TIM17-false-HAL-true,12-MX_TIM16_Init-TIM16-false-HAL-true,13-MX_TIM15_Init-TIM15-false-HAL-true,14-MX_TIM4_Init-TIM4-false-HAL-true,15-MX_TIM1_Init-TIM1-false-HAL-true,16-MX_SAI1_Init-SAI1-false-HAL-true,17-MX_SPI3_Init-SPI3-false-HAL-true,18-MX_TIM2_Init-TIM2-false-HAL-true,19-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true
-SAI1.VirtualProtocol-SAI_A_BASIC=VM_BASIC_PROTOCOL
-VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
-SAI1.Instance-SAI_A_MasterWithClock=SAI$Index_Block_A
-PA11.Mode=Device_Only
-RCC.RTCFreq_Value=32768
-RCC.USART2Freq_Value=80000000
-PC15-OSC32_OUT\ (PC15).Mode=LSE-External-Oscillator
-SH.S_TIM1_CH1.ConfNb=1
-USART1.IPParameters=VirtualMode-Asynchronous
-PB11.Signal=S_TIM2_CH4
-PB13.Signal=SPI2_SCK
-PB15.Signal=SPI2_MOSI
-PinOutPanel.RotationAngle=0
-RCC.MCO1PinFreq_Value=80000000
-RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
-ProjectManager.StackSize=0x400
-PB3\ (JTDO-TRACESWO).Signal=SPI3_SCK
-PC14-OSC32_IN\ (PC14).Mode=LSE-External-Oscillator
-PA14\ (JTCK-SWCLK).Signal=SYS_JTCK-SWCLK
-RCC.I2C3Freq_Value=80000000
-RCC.LPTIM1Freq_Value=80000000
-Mcu.IP4=QUADSPI
-Mcu.IP5=RCC
-RCC.FCLKCortexFreq_Value=80000000
-Mcu.IP2=LPTIM1
-NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false
-Mcu.IP3=NVIC
Mcu.IP0=ADC1
-Mcu.IP1=IWDG
-PA12.Signal=USB_OTG_FS_DP
-Mcu.UserConstants=
-PE11.Mode=Single Bank
-RCC.VCOSAI1OutputFreq_Value=96000000
-SAI1.VirtualMode-SAI_B_SyncSlave=VM_SLAVE
-RCC.SDMMCFreq_Value=48000000
-Mcu.ThirdPartyNb=0
-SPI1.Direction=SPI_DIRECTION_2LINES
-RCC.HCLKFreq_Value=80000000
-PE2.Mode=SAI_A_MasterWithClock
-Mcu.IPNb=22
-TIM2.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4
-ProjectManager.PreviousToolchain=
-RCC.APB2TimFreq_Value=80000000
-VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC.Signal=SAI1_VP_$IpInstance_SAIB_SAI_BASIC
-SPI1.CalculateBaudRate=40.0 MBits/s
-Mcu.Pin6=PC15-OSC32_OUT (PC15)
-RCC.SAI2Freq_Value=13714285.714285715
-Mcu.Pin7=PH0-OSC_IN (PH0)
-VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
-Mcu.Pin8=PH1-OSC_OUT (PH1)
-PE5.Signal=SAI1_SCK_A
-Mcu.Pin9=PA2
-RCC.AHBFreq_Value=80000000
-PB13.Locked=true
+Mcu.IP1=DAC1
+Mcu.IP10=SPI1
+Mcu.IP11=SPI2
+Mcu.IP12=SPI3
+Mcu.IP13=SYS
+Mcu.IP14=TIM1
+Mcu.IP15=TIM2
+Mcu.IP16=TIM4
+Mcu.IP17=TIM15
+Mcu.IP18=TIM16
+Mcu.IP19=TIM17
+Mcu.IP2=IWDG
+Mcu.IP20=USART1
+Mcu.IP21=USART2
+Mcu.IP22=USB_OTG_FS
+Mcu.IP3=LPTIM1
+Mcu.IP4=NVIC
+Mcu.IP5=QUADSPI
+Mcu.IP6=RCC
+Mcu.IP7=RTC
+Mcu.IP8=SAI1
+Mcu.IP9=SDMMC1
+Mcu.IPNb=23
+Mcu.Name=STM32L475V(C-E-G)Tx
+Mcu.Package=LQFP100
Mcu.Pin0=PE2
-PE14.Locked=true
Mcu.Pin1=PE3
+Mcu.Pin10=PA3
+Mcu.Pin11=PA4
+Mcu.Pin12=PA5
+Mcu.Pin13=PA6
+Mcu.Pin14=PA7
+Mcu.Pin15=PC5
+Mcu.Pin16=PE9
+Mcu.Pin17=PE10
+Mcu.Pin18=PE11
+Mcu.Pin19=PE12
Mcu.Pin2=PE4
+Mcu.Pin20=PE13
+Mcu.Pin21=PE14
+Mcu.Pin22=PE15
+Mcu.Pin23=PB10
+Mcu.Pin24=PB11
+Mcu.Pin25=PB13
+Mcu.Pin26=PB14
+Mcu.Pin27=PB15
+Mcu.Pin28=PC8
+Mcu.Pin29=PC9
Mcu.Pin3=PE5
-RCC.USART3Freq_Value=80000000
+Mcu.Pin30=PA9
+Mcu.Pin31=PA10
+Mcu.Pin32=PA11
+Mcu.Pin33=PA12
+Mcu.Pin34=PA13 (JTMS-SWDIO)
+Mcu.Pin35=PA14 (JTCK-SWCLK)
+Mcu.Pin36=PC10
+Mcu.Pin37=PC11
+Mcu.Pin38=PC12
+Mcu.Pin39=PD2
Mcu.Pin4=PE6
+Mcu.Pin40=PB3 (JTDO-TRACESWO)
+Mcu.Pin41=PB5
+Mcu.Pin42=PB7
+Mcu.Pin43=PB8
+Mcu.Pin44=VP_IWDG_VS_IWDG
+Mcu.Pin45=VP_LPTIM1_VS_LPTIM_counterModeInternalClock
+Mcu.Pin46=VP_RTC_VS_RTC_Activate
+Mcu.Pin47=VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC
+Mcu.Pin48=VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC
+Mcu.Pin49=VP_SYS_VS_Systick
Mcu.Pin5=PC14-OSC32_IN (PC14)
-ProjectManager.ProjectBuild=false
-PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator
-RCC.HSE_VALUE=8000000
-TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
-NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+Mcu.Pin50=VP_TIM1_VS_ClockSourceINT
+Mcu.Pin51=VP_TIM2_VS_ClockSourceINT
+Mcu.Pin52=VP_TIM4_VS_ClockSourceINT
+Mcu.Pin53=VP_TIM15_VS_ClockSourceINT
+Mcu.Pin54=VP_TIM16_VS_ClockSourceINT
+Mcu.Pin55=VP_TIM17_VS_ClockSourceINT
+Mcu.Pin6=PC15-OSC32_OUT (PC15)
+Mcu.Pin7=PH0-OSC_IN (PH0)
+Mcu.Pin8=PH1-OSC_OUT (PH1)
+Mcu.Pin9=PA2
+Mcu.PinsNb=56
+Mcu.ThirdPartyNb=0
+Mcu.UserConstants=
+Mcu.UserName=STM32L475VETx
+MxCube.Version=6.0.1
+MxDb.Version=DB.6.0.0
+NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false
-SH.ADCx_IN14.ConfNb=1
-Mcu.IP10=SPI2
-USART2.VirtualMode-Asynchronous=VM_ASYNC
+NVIC.ForceEnableDMAVector=true
+NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+NVIC.OTG_FS_IRQn=true\:0\:0\:false\:false\:true\:true\:true
+NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
+NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false
NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true
-RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE
-Mcu.IP12=SYS
-Mcu.IP11=SPI3
-ADC1.OffsetNumber-15\#ChannelRegularConversion=ADC_OFFSET_NONE
-Mcu.IP18=TIM17
-ProjectManager.FirmwarePackage=STM32Cube FW_L4 V1.15.1
-Mcu.IP17=TIM16
-MxDb.Version=DB.5.0.60
-PE15.Locked=true
-Mcu.IP19=USART1
-Mcu.IP14=TIM2
-Mcu.IP13=TIM1
-PE13.Signal=QUADSPI_BK1_IO1
-Mcu.IP16=TIM15
-ProjectManager.BackupPrevious=false
-Mcu.IP15=TIM4
-RCC.VCOInputFreq_Value=8000000
-TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
-PE9.Signal=S_TIM1_CH1
+NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+PA10.Mode=Asynchronous
+PA10.Signal=USART1_RX
+PA11.Mode=Device_Only
+PA11.Signal=USB_OTG_FS_DM
+PA12.Mode=Device_Only
+PA12.Signal=USB_OTG_FS_DP
+PA13\ (JTMS-SWDIO).Mode=Serial_Wire
+PA13\ (JTMS-SWDIO).Signal=SYS_JTMS-SWDIO
+PA14\ (JTCK-SWCLK).Mode=Serial_Wire
+PA14\ (JTCK-SWCLK).Signal=SYS_JTCK-SWCLK
+PA2.Mode=Asynchronous
+PA2.Signal=USART2_TX
+PA3.Mode=Asynchronous
+PA3.Signal=USART2_RX
+PA4.Signal=COMP_DAC11_group
+PA5.Mode=Full_Duplex_Master
+PA5.Signal=SPI1_SCK
+PA6.Mode=Full_Duplex_Master
+PA6.Signal=SPI1_MISO
+PA7.Mode=Full_Duplex_Master
+PA7.Signal=SPI1_MOSI
+PA9.Mode=Asynchronous
+PA9.Signal=USART1_TX
+PB10.Signal=S_TIM2_CH3
+PB11.Signal=S_TIM2_CH4
+PB13.Locked=true
+PB13.Mode=Full_Duplex_Master
+PB13.Signal=SPI2_SCK
+PB14.Locked=true
PB14.Mode=Full_Duplex_Master
+PB14.Signal=SPI2_MISO
+PB15.Locked=true
+PB15.Mode=Full_Duplex_Master
+PB15.Signal=SPI2_MOSI
+PB3\ (JTDO-TRACESWO).Locked=true
+PB3\ (JTDO-TRACESWO).Mode=TX_Only_Simplex_Unidirect_Master
+PB3\ (JTDO-TRACESWO).Signal=SPI3_SCK
+PB5.Locked=true
PB5.Mode=TX_Only_Simplex_Unidirect_Master
-File.Version=6
-PC9.Mode=SD_4_bits_Wide_bus
-SPI2.CalculateBaudRate=40.0 MBits/s
-SAI1.InitProtocol-SAI_A_MasterWithClock=Enable
-SH.S_TIM4_CH2.0=TIM4_CH2,PWM Generation2 CH2
-PE2.Signal=SAI1_MCLK_A
+PB5.Signal=SPI3_MOSI
+PB7.Locked=true
PB7.Signal=S_TIM4_CH2
-Mcu.IP21=USB_OTG_FS
PB8.Locked=true
-Mcu.IP20=USART2
-RCC.PLLRCLKFreq_Value=80000000
+PB8.Signal=S_TIM4_CH3
+PC10.Mode=SD_4_bits_Wide_bus
+PC10.Signal=SDMMC1_D2
+PC11.Mode=SD_4_bits_Wide_bus
+PC11.Signal=SDMMC1_D3
+PC12.Mode=SD_4_bits_Wide_bus
+PC12.Signal=SDMMC1_CK
+PC14-OSC32_IN\ (PC14).Mode=LSE-External-Oscillator
+PC14-OSC32_IN\ (PC14).Signal=RCC_OSC32_IN
+PC15-OSC32_OUT\ (PC15).Mode=LSE-External-Oscillator
+PC15-OSC32_OUT\ (PC15).Signal=RCC_OSC32_OUT
+PC5.Signal=ADCx_IN14
+PC8.Mode=SD_4_bits_Wide_bus
+PC8.Signal=SDMMC1_D0
+PC9.Mode=SD_4_bits_Wide_bus
+PC9.Signal=SDMMC1_D1
+PD2.Mode=SD_4_bits_Wide_bus
+PD2.Signal=SDMMC1_CMD
+PE10.Mode=Single Bank
+PE10.Signal=QUADSPI_CLK
+PE11.Mode=Single Bank
+PE11.Signal=QUADSPI_NCS
+PE12.Locked=true
+PE12.Mode=Single Bank
+PE12.Signal=QUADSPI_BK1_IO0
+PE13.Locked=true
PE13.Mode=Single Bank
-NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+PE13.Signal=QUADSPI_BK1_IO1
+PE14.Locked=true
+PE14.Mode=Single Bank
+PE14.Signal=QUADSPI_BK1_IO2
+PE15.Locked=true
+PE15.Mode=Single Bank
+PE15.Signal=QUADSPI_BK1_IO3
+PE2.Mode=SAI_A_MasterWithClock
+PE2.Signal=SAI1_MCLK_A
+PE3.Mode=SAI_B_SyncSlave
+PE3.Signal=SAI1_SD_B
PE4.Mode=SAI_A_MasterWithClock
-ADC1.Channel-15\#ChannelRegularConversion=ADC_CHANNEL_14
PE4.Signal=SAI1_FS_A
-PE10.Signal=QUADSPI_CLK
-VP_TIM15_VS_ClockSourceINT.Signal=TIM15_VS_ClockSourceINT
+PE5.Mode=SAI_A_MasterWithClock
+PE5.Signal=SAI1_SCK_A
+PE6.Mode=SAI_A_MasterWithClock
+PE6.Signal=SAI1_SD_A
+PE9.Signal=S_TIM1_CH1
+PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator
+PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN
+PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator
+PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT
+PinOutPanel.RotationAngle=0
+ProjectManager.AskForMigrate=true
+ProjectManager.BackupPrevious=false
+ProjectManager.CompilerOptimize=6
+ProjectManager.ComputerToolchain=false
+ProjectManager.CoupleFile=false
+ProjectManager.CustomerFirmwarePackage=
+ProjectManager.DefaultFWLocation=true
+ProjectManager.DeletePrevious=true
+ProjectManager.DeviceId=STM32L475VETx
+ProjectManager.FirmwarePackage=STM32Cube FW_L4 V1.16.0
+ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
-VP_TIM1_VS_ClockSourceINT.Mode=Internal
+ProjectManager.HeapSize=0x200
+ProjectManager.KeepUserCode=true
+ProjectManager.LastFirmware=true
+ProjectManager.LibraryCopy=0
+ProjectManager.MainLocation=Src
+ProjectManager.NoMain=false
+ProjectManager.PreviousToolchain=
+ProjectManager.ProjectBuild=false
+ProjectManager.ProjectFileName=STM32L475VE.ioc
ProjectManager.ProjectName=STM32L475VE
-ADC1.Rank-15\#ChannelRegularConversion=1
-SAI1.OutputDrive-SAI_A_MasterWithClock=SAI_OUTPUTDRIVE_ENABLE
-Mcu.Package=LQFP100
-SAI1.AudioFrequency-SAI_A_MasterWithClock=SAI_AUDIO_FREQUENCY_44K
-PA6.Signal=SPI1_MISO
-SPI2.Mode=SPI_MODE_MASTER
-SPI3.Mode=SPI_MODE_MASTER
-SH.ADCx_IN14.0=ADC1_IN14,IN14-Single-Ended
-NVIC.OTG_FS_IRQn=true\:0\:0\:false\:false\:true\:true\:true
+ProjectManager.RegisterCallBack=
+ProjectManager.StackSize=0x400
+ProjectManager.TargetToolchain=MDK-ARM V5
ProjectManager.ToolChainLocation=
-RCC.LSI_VALUE=32000
-VP_LPTIM1_VS_LPTIM_counterModeInternalClock.Mode=Counts__internal_clock_event_00
-VP_SYS_VS_Systick.Signal=SYS_VS_Systick
-RCC.LSCOPinFreq_Value=32000
-PA10.Signal=USART1_RX
-USB_OTG_FS.VirtualMode=Device_Only
-RCC.DFSDMFreq_Value=80000000
-PC11.Mode=SD_4_bits_Wide_bus
-ADC1.SamplingTime-15\#ChannelRegularConversion=ADC_SAMPLETIME_2CYCLES_5
-RCC.PLLPoutputFreq_Value=22857142.85714286
+ProjectManager.UnderRoot=false
+ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true,5-MX_QUADSPI_Init-QUADSPI-false-HAL-true,6-MX_SPI1_Init-SPI1-false-HAL-true,7-MX_SPI2_Init-SPI2-false-HAL-true,8-MX_RTC_Init-RTC-false-HAL-true,9-MX_ADC1_Init-ADC1-false-HAL-true,10-MX_IWDG_Init-IWDG-false-HAL-true,11-MX_TIM17_Init-TIM17-false-HAL-true,12-MX_TIM16_Init-TIM16-false-HAL-true,13-MX_TIM15_Init-TIM15-false-HAL-true,14-MX_TIM4_Init-TIM4-false-HAL-true,15-MX_TIM1_Init-TIM1-false-HAL-true,16-MX_SAI1_Init-SAI1-false-HAL-true,17-MX_SPI3_Init-SPI3-false-HAL-true,18-MX_TIM2_Init-TIM2-false-HAL-true,19-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true,20-MX_LPTIM1_Init-LPTIM1-false-HAL-true,21-MX_SDMMC1_SD_Init-SDMMC1-false-HAL-true,22-MX_DAC1_Init-DAC1-false-HAL-true
+RCC.ADCFreq_Value=48000000
+RCC.AHBFreq_Value=80000000
+RCC.APB1Freq_Value=80000000
RCC.APB1TimFreq_Value=80000000
-NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
+RCC.APB2Freq_Value=80000000
+RCC.APB2TimFreq_Value=80000000
+RCC.CortexFreq_Value=80000000
+RCC.DFSDMFreq_Value=80000000
+RCC.FCLKCortexFreq_Value=80000000
+RCC.FamilyName=M
+RCC.HCLKFreq_Value=80000000
+RCC.HSE_VALUE=8000000
+RCC.HSI_VALUE=16000000
+RCC.I2C1Freq_Value=80000000
+RCC.I2C2Freq_Value=80000000
+RCC.I2C3Freq_Value=80000000
+RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,DFSDMFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSI_VALUE,MCO1PinFreq_Value,MSI_VALUE,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1N,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PLLSAI2PoutputFreq_Value,PLLSAI2RoutputFreq_Value,PLLSourceVirtual,PWRFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMCFreq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value,VCOSAI2OutputFreq_Value
+RCC.LPTIM1Freq_Value=80000000
+RCC.LPTIM2Freq_Value=80000000
RCC.LPUART1Freq_Value=80000000
-SPI3.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate
-SPI2.Direction=SPI_DIRECTION_2LINES
-PC5.Signal=ADCx_IN14
-USB_OTG_FS.IPParameters=VirtualMode
-PB13.Mode=Full_Duplex_Master
-SH.S_TIM2_CH4.ConfNb=1
-PA13\ (JTMS-SWDIO).Signal=SYS_JTMS-SWDIO
-PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator
-PE12.Locked=true
-PE3.Mode=SAI_B_SyncSlave
-ProjectManager.CustomerFirmwarePackage=
-PB15.Locked=true
-PB3\ (JTDO-TRACESWO).Locked=true
-RCC.PLLSAI1N=12
-PA3.Signal=USART2_RX
-PA5.Mode=Full_Duplex_Master
-PE12.Mode=Single Bank
-VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
+RCC.LSCOPinFreq_Value=32000
+RCC.LSI_VALUE=32000
+RCC.MCO1PinFreq_Value=80000000
RCC.MSI_VALUE=4000000
-RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
-PA14\ (JTCK-SWCLK).Mode=Serial_Wire
+RCC.PLLN=20
+RCC.PLLPoutputFreq_Value=22857142.85714286
RCC.PLLQoutputFreq_Value=80000000
-ProjectManager.ProjectFileName=STM32L475VE.ioc
-TIM2.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
-PA7.Mode=Full_Duplex_Master
-PA10.Mode=Asynchronous
-Mcu.PinsNb=55
-VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC.Mode=SAI_A_BASIC
-ProjectManager.NoMain=false
-SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate
-ADC1.IPParameters=Rank-15\#ChannelRegularConversion,Channel-15\#ChannelRegularConversion,SamplingTime-15\#ChannelRegularConversion,OffsetNumber-15\#ChannelRegularConversion,NbrOfConversionFlag,master
-SAI1.MClockEnable-SAI_A_MasterWithClock=SAI_MASTERCLOCK_ENABLE
-PC11.Signal=SDMMC1_D3
+RCC.PLLRCLKFreq_Value=80000000
+RCC.PLLSAI1N=12
+RCC.PLLSAI1PoutputFreq_Value=13714285.714285715
+RCC.PLLSAI1QoutputFreq_Value=48000000
+RCC.PLLSAI1RoutputFreq_Value=48000000
+RCC.PLLSAI2PoutputFreq_Value=9142857.142857144
+RCC.PLLSAI2RoutputFreq_Value=32000000
+RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
+RCC.PWRFreq_Value=80000000
+RCC.RNGFreq_Value=48000000
+RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE
+RCC.RTCFreq_Value=32768
+RCC.SAI1Freq_Value=13714285.714285715
+RCC.SAI2Freq_Value=13714285.714285715
+RCC.SDMMCFreq_Value=48000000
RCC.SWPMI1Freq_Value=80000000
-PC8.Signal=SDMMC1_D0
-PE10.Mode=Single Bank
-PC10.Mode=SD_4_bits_Wide_bus
-VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC.Signal=SAI1_VP_$IpInstance_SAIA_SAI_BASIC
-ProjectManager.DefaultFWLocation=true
-SAI1.ErrorAudioFreq-SAI_A_MasterWithClock=-72.09 %
-PC15-OSC32_OUT\ (PC15).Signal=RCC_OSC32_OUT
-VP_TIM16_VS_ClockSourceINT.Mode=Enable_Timer
-ProjectManager.DeletePrevious=true
-PB14.Locked=true
+RCC.SYSCLKFreq_VALUE=80000000
+RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
+RCC.UART4Freq_Value=80000000
+RCC.UART5Freq_Value=80000000
+RCC.USART1Freq_Value=80000000
+RCC.USART2Freq_Value=80000000
+RCC.USART3Freq_Value=80000000
+RCC.USBFreq_Value=48000000
+RCC.VCOInputFreq_Value=8000000
+RCC.VCOOutputFreq_Value=160000000
+RCC.VCOSAI1OutputFreq_Value=96000000
RCC.VCOSAI2OutputFreq_Value=64000000
-VP_TIM17_VS_ClockSourceINT.Signal=TIM17_VS_ClockSourceINT
-RCC.FamilyName=M
-PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT
-USART1.VirtualMode-Asynchronous=VM_ASYNC
-PA3.Mode=Asynchronous
+SAI1.AudioFrequency-SAI_A_MasterWithClock=SAI_AUDIO_FREQUENCY_44K
+SAI1.ErrorAudioFreq-SAI_A_MasterWithClock=-72.09 %
+SAI1.IPParameters=Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock,InitProtocol-SAI_A_MasterWithClock,VirtualProtocol-SAI_A_BASIC,AudioFrequency-SAI_A_MasterWithClock,OutputDrive-SAI_A_MasterWithClock,Instance-SAI_B_SyncSlave,VirtualMode-SAI_B_SyncSlave,InitProtocol-SAI_B_SyncSlave,VirtualProtocol-SAI_B_BASIC
+SAI1.InitProtocol-SAI_A_MasterWithClock=Enable
+SAI1.InitProtocol-SAI_B_SyncSlave=Enable
+SAI1.Instance-SAI_A_MasterWithClock=SAI$Index_Block_A
+SAI1.Instance-SAI_B_SyncSlave=SAI$Index_Block_B
+SAI1.MClockEnable-SAI_A_MasterWithClock=SAI_MASTERCLOCK_ENABLE
+SAI1.OutputDrive-SAI_A_MasterWithClock=SAI_OUTPUTDRIVE_ENABLE
SAI1.RealAudioFreq-SAI_A_MasterWithClock=53.571 KHz
-PA9.Mode=Asynchronous
+SAI1.VirtualMode-SAI_A_MasterWithClock=VM_MASTER
+SAI1.VirtualMode-SAI_B_SyncSlave=VM_SLAVE
+SAI1.VirtualProtocol-SAI_A_BASIC=VM_BASIC_PROTOCOL
+SAI1.VirtualProtocol-SAI_B_BASIC=VM_BASIC_PROTOCOL
+SH.ADCx_IN14.0=ADC1_IN14,IN14-Single-Ended
+SH.ADCx_IN14.ConfNb=1
+SH.COMP_DAC11_group.0=DAC1_OUT1,DAC_OUT1
+SH.COMP_DAC11_group.ConfNb=1
SH.S_TIM1_CH1.0=TIM1_CH1,PWM Generation1 CH1
-VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT
-ProjectManager.TargetToolchain=MDK-ARM V5
-TIM4.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation2 CH2
-Mcu.Pin51=VP_TIM4_VS_ClockSourceINT
-Mcu.Pin52=VP_TIM15_VS_ClockSourceINT
-Mcu.Pin50=VP_TIM2_VS_ClockSourceINT
+SH.S_TIM1_CH1.ConfNb=1
+SH.S_TIM2_CH3.0=TIM2_CH3,PWM Generation3 CH3
+SH.S_TIM2_CH3.ConfNb=1
+SH.S_TIM2_CH4.0=TIM2_CH4,PWM Generation4 CH4
+SH.S_TIM2_CH4.ConfNb=1
+SH.S_TIM4_CH2.0=TIM4_CH2,PWM Generation2 CH2
+SH.S_TIM4_CH2.ConfNb=1
SH.S_TIM4_CH3.0=TIM4_CH3,PWM Generation3 CH3
-Mcu.Pin53=VP_TIM16_VS_ClockSourceINT
-Mcu.Pin54=VP_TIM17_VS_ClockSourceINT
-PA9.Signal=USART1_TX
-VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT
-PB5.Locked=true
-SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate
-RCC.USBFreq_Value=48000000
-PE11.Signal=QUADSPI_NCS
-Mcu.Pin48=VP_SYS_VS_Systick
-Mcu.Pin49=VP_TIM1_VS_ClockSourceINT
-RCC.PLLSAI1PoutputFreq_Value=13714285.714285715
-Mcu.Pin46=VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC
-Mcu.Pin47=VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC
-PB10.Signal=S_TIM2_CH3
-SAI1.VirtualMode-SAI_A_MasterWithClock=VM_MASTER
SH.S_TIM4_CH3.ConfNb=1
-VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC.Mode=SAI_B_BASIC
-PB14.Signal=SPI2_MISO
-PD2.Mode=SD_4_bits_Wide_bus
-RCC.PLLSAI2RoutputFreq_Value=32000000
-PA5.Signal=SPI1_SCK
-Mcu.Pin40=PB5
-Mcu.Pin41=PB7
-PC12.Mode=SD_4_bits_Wide_bus
-Mcu.Pin44=VP_LPTIM1_VS_LPTIM_counterModeInternalClock
-Mcu.Pin45=VP_RTC_VS_RTC_Activate
-Mcu.Pin42=PB8
-board=custom
-Mcu.Pin43=VP_IWDG_VS_IWDG
-SAI1.IPParameters=Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock,InitProtocol-SAI_A_MasterWithClock,VirtualProtocol-SAI_A_BASIC,AudioFrequency-SAI_A_MasterWithClock,OutputDrive-SAI_A_MasterWithClock,Instance-SAI_B_SyncSlave,VirtualMode-SAI_B_SyncSlave,InitProtocol-SAI_B_SyncSlave,VirtualProtocol-SAI_B_BASIC
-RCC.VCOOutputFreq_Value=160000000
-ProjectManager.LastFirmware=true
-PB15.Mode=Full_Duplex_Master
-TIM4.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
-RCC.APB2Freq_Value=80000000
-PE14.Signal=QUADSPI_BK1_IO2
-RCC.UART4Freq_Value=80000000
-SPI3.CalculateBaudRate=40.0 MBits/s
-PE6.Mode=SAI_A_MasterWithClock
-PE15.Signal=QUADSPI_BK1_IO3
-MxCube.Version=5.6.0
-Mcu.Pin37=PC12
-Mcu.Pin38=PD2
-Mcu.Pin35=PC10
-VP_TIM2_VS_ClockSourceINT.Mode=Internal
-RCC.I2C1Freq_Value=80000000
-SH.S_TIM2_CH3.0=TIM2_CH3,PWM Generation3 CH3
-Mcu.Pin36=PC11
+SPI1.CalculateBaudRate=40.0 MBits/s
+SPI1.Direction=SPI_DIRECTION_2LINES
+SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate
SPI1.Mode=SPI_MODE_MASTER
-Mcu.Pin39=PB3 (JTDO-TRACESWO)
-PE14.Mode=Single Bank
-PB3\ (JTDO-TRACESWO).Mode=TX_Only_Simplex_Unidirect_Master
-RCC.RNGFreq_Value=48000000
-PE5.Mode=SAI_A_MasterWithClock
-RCC.PLLSAI1QoutputFreq_Value=48000000
-Mcu.Pin30=PA10
-RCC.ADCFreq_Value=48000000
-VP_SYS_VS_Systick.Mode=SysTick
+SPI1.VirtualType=VM_MASTER
+SPI2.CalculateBaudRate=40.0 MBits/s
+SPI2.Direction=SPI_DIRECTION_2LINES
+SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate
+SPI2.Mode=SPI_MODE_MASTER
+SPI2.VirtualType=VM_MASTER
+SPI3.CalculateBaudRate=40.0 MBits/s
+SPI3.Direction=SPI_DIRECTION_2LINES
+SPI3.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate
+SPI3.Mode=SPI_MODE_MASTER
+SPI3.VirtualType=VM_MASTER
+TIM1.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
+TIM1.IPParameters=Channel-PWM Generation1 CH1
TIM2.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
-Mcu.Pin33=PA13 (JTMS-SWDIO)
-Mcu.Pin34=PA14 (JTCK-SWCLK)
-Mcu.Pin31=PA11
-Mcu.Pin32=PA12
-VP_TIM16_VS_ClockSourceINT.Signal=TIM16_VS_ClockSourceINT
-NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false
-SH.S_TIM2_CH3.ConfNb=1
-PE6.Signal=SAI1_SD_A
-RCC.UART5Freq_Value=80000000
-ProjectManager.FreePins=false
-RCC.IPParameters=ADCFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,CortexFreq_Value,DFSDMFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI_VALUE,I2C1Freq_Value,I2C2Freq_Value,I2C3Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSI_VALUE,MCO1PinFreq_Value,MSI_VALUE,PLLN,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1N,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PLLSAI2PoutputFreq_Value,PLLSAI2RoutputFreq_Value,PLLSourceVirtual,PWRFreq_Value,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SAI2Freq_Value,SDMMCFreq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,UART4Freq_Value,UART5Freq_Value,USART1Freq_Value,USART2Freq_Value,USART3Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value,VCOSAI2OutputFreq_Value
-ProjectManager.AskForMigrate=true
-Mcu.Name=STM32L475V(C-E-G)Tx
-RCC.LPTIM2Freq_Value=80000000
-Mcu.Pin26=PB15
-PE12.Signal=QUADSPI_BK1_IO0
-Mcu.Pin27=PC8
-PA2.Signal=USART2_TX
-Mcu.Pin24=PB13
-ProjectManager.UnderRoot=false
-Mcu.Pin25=PB14
-PE13.Locked=true
-Mcu.IP8=SDMMC1
-Mcu.IP9=SPI1
-Mcu.Pin28=PC9
-Mcu.IP6=RTC
-PC8.Mode=SD_4_bits_Wide_bus
-Mcu.Pin29=PA9
-Mcu.IP7=SAI1
-ProjectManager.CoupleFile=false
-PA13\ (JTMS-SWDIO).Mode=Serial_Wire
-RCC.SYSCLKFreq_VALUE=80000000
-Mcu.Pin22=PB10
-PB5.Signal=SPI3_MOSI
-Mcu.Pin23=PB11
-Mcu.Pin20=PE14
-ADC1.master=1
-Mcu.Pin21=PE15
-PA12.Mode=Device_Only
-NVIC.ForceEnableDMAVector=true
-RCC.PLLSAI2PoutputFreq_Value=9142857.142857144
-KeepUserPlacement=false
-PC14-OSC32_IN\ (PC14).Signal=RCC_OSC32_IN
-NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false
-ProjectManager.CompilerOptimize=6
-SAI1.Instance-SAI_B_SyncSlave=SAI$Index_Block_B
-PA11.Signal=USB_OTG_FS_DM
+TIM2.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
+TIM2.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4
+TIM4.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2
+TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
+TIM4.IPParameters=Channel-PWM Generation3 CH3,Channel-PWM Generation2 CH2
+USART1.IPParameters=VirtualMode-Asynchronous
+USART1.VirtualMode-Asynchronous=VM_ASYNC
+USART2.IPParameters=VirtualMode-Asynchronous
+USART2.VirtualMode-Asynchronous=VM_ASYNC
+USB_OTG_FS.IPParameters=VirtualMode
+USB_OTG_FS.VirtualMode=Device_Only
+VP_IWDG_VS_IWDG.Mode=IWDG_Activate
VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG
+VP_LPTIM1_VS_LPTIM_counterModeInternalClock.Mode=Counts__internal_clock_event_00
+VP_LPTIM1_VS_LPTIM_counterModeInternalClock.Signal=LPTIM1_VS_LPTIM_counterModeInternalClock
+VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled
+VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate
+VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC.Mode=SAI_A_BASIC
+VP_SAI1_VP_$IpInstance_SAIA_SAI_BASIC.Signal=SAI1_VP_$IpInstance_SAIA_SAI_BASIC
+VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC.Mode=SAI_B_BASIC
+VP_SAI1_VP_$IpInstance_SAIB_SAI_BASIC.Signal=SAI1_VP_$IpInstance_SAIB_SAI_BASIC
+VP_SYS_VS_Systick.Mode=SysTick
+VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM15_VS_ClockSourceINT.Mode=Internal
-ProjectManager.HeapSize=0x200
-Mcu.Pin15=PE9
-NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false
-Mcu.Pin16=PE10
-Mcu.Pin13=PA7
-SH.S_TIM2_CH4.0=TIM2_CH4,PWM Generation4 CH4
-Mcu.Pin14=PC5
-Mcu.Pin19=PE13
-ProjectManager.ComputerToolchain=false
-Mcu.Pin17=PE11
-RCC.HSI_VALUE=16000000
-Mcu.Pin18=PE12
+VP_TIM15_VS_ClockSourceINT.Signal=TIM15_VS_ClockSourceINT
+VP_TIM16_VS_ClockSourceINT.Mode=Enable_Timer
+VP_TIM16_VS_ClockSourceINT.Signal=TIM16_VS_ClockSourceINT
+VP_TIM17_VS_ClockSourceINT.Mode=Enable_Timer
+VP_TIM17_VS_ClockSourceINT.Signal=TIM17_VS_ClockSourceINT
+VP_TIM1_VS_ClockSourceINT.Mode=Internal
+VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT
+VP_TIM2_VS_ClockSourceINT.Mode=Internal
+VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
VP_TIM4_VS_ClockSourceINT.Mode=Internal
-SAI1.VirtualProtocol-SAI_B_BASIC=VM_BASIC_PROTOCOL
-NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
-ADC1.NbrOfConversionFlag=1
-Mcu.Pin11=PA5
-Mcu.Pin12=PA6
-RCC.PLLN=20
-Mcu.Pin10=PA3
-PB7.Locked=true
-PE3.Signal=SAI1_SD_B
-PA2.Mode=Asynchronous
-PB8.Signal=S_TIM4_CH3
-VP_LPTIM1_VS_LPTIM_counterModeInternalClock.Signal=LPTIM1_VS_LPTIM_counterModeInternalClock
-RCC.PWRFreq_Value=80000000
-PC9.Signal=SDMMC1_D1
-PD2.Signal=SDMMC1_CMD
-RCC.I2C2Freq_Value=80000000
-RCC.APB1Freq_Value=80000000
-SAI1.InitProtocol-SAI_B_SyncSlave=Enable
-ProjectManager.DeviceId=STM32L475VETx
-ProjectManager.LibraryCopy=0
-PE15.Mode=Single Bank
-PA7.Signal=SPI1_MOSI
+VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT
+board=custom
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c
index 5a91b40917..2a9dcd82a7 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/main.c
@@ -37,7 +37,6 @@
******************************************************************************
*/
/* USER CODE END Header */
-
/* Includes ------------------------------------------------------------------*/
#include "main.h"
@@ -64,6 +63,8 @@
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
+DAC_HandleTypeDef hdac1;
+
IWDG_HandleTypeDef hiwdg;
LPTIM_HandleTypeDef hlptim1;
@@ -120,6 +121,7 @@ static void MX_TIM2_Init(void);
static void MX_USB_OTG_FS_PCD_Init(void);
static void MX_LPTIM1_Init(void);
static void MX_SDMMC1_SD_Init(void);
+static void MX_DAC1_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
@@ -177,6 +179,7 @@ int main(void)
MX_USB_OTG_FS_PCD_Init();
MX_LPTIM1_Init();
MX_SDMMC1_SD_Init();
+ MX_DAC1_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
@@ -204,11 +207,12 @@ void SystemClock_Config(void)
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
- /** Configure LSE Drive Capability
+ /** Configure LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
- /** Initializes the CPU, AHB and APB busses clocks
+ /** Initializes the RCC Oscillators according to the specified parameters
+ * in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE
|RCC_OSCILLATORTYPE_LSE;
@@ -226,7 +230,7 @@ void SystemClock_Config(void)
{
Error_Handler();
}
- /** Initializes the CPU, AHB and APB busses clocks
+ /** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
@@ -263,7 +267,7 @@ void SystemClock_Config(void)
{
Error_Handler();
}
- /** Configure the main internal regulator output voltage
+ /** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
@@ -289,7 +293,7 @@ static void MX_ADC1_Init(void)
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
- /** Common config
+ /** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
@@ -301,7 +305,6 @@ static void MX_ADC1_Init(void)
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
- hadc1.Init.NbrOfDiscConversion = 1;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
@@ -311,14 +314,14 @@ static void MX_ADC1_Init(void)
{
Error_Handler();
}
- /** Configure the ADC multi-mode
+ /** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
- /** Configure Regular Channel
+ /** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_14;
sConfig.Rank = ADC_REGULAR_RANK_1;
@@ -337,6 +340,47 @@ static void MX_ADC1_Init(void)
}
/**
+ * @brief DAC1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_DAC1_Init(void)
+{
+
+ /* USER CODE BEGIN DAC1_Init 0 */
+
+ /* USER CODE END DAC1_Init 0 */
+
+ DAC_ChannelConfTypeDef sConfig = {0};
+
+ /* USER CODE BEGIN DAC1_Init 1 */
+
+ /* USER CODE END DAC1_Init 1 */
+ /** DAC Initialization
+ */
+ hdac1.Instance = DAC1;
+ if (HAL_DAC_Init(&hdac1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /** DAC channel OUT1 config
+ */
+ sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
+ sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
+ sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
+ sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_DISABLE;
+ sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
+ if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN DAC1_Init 2 */
+
+ /* USER CODE END DAC1_Init 2 */
+
+}
+
+/**
* @brief IWDG Initialization Function
* @param None
* @retval None
@@ -447,7 +491,7 @@ static void MX_RTC_Init(void)
/* USER CODE BEGIN RTC_Init 1 */
/* USER CODE END RTC_Init 1 */
- /** Initialize RTC Only
+ /** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
@@ -695,7 +739,7 @@ static void MX_TIM1_Init(void)
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim1.Init.Period = 0;
+ htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
@@ -774,7 +818,7 @@ static void MX_TIM2_Init(void)
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim2.Init.Period = 0;
+ htim2.Init.Period = 4294967295;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
@@ -837,7 +881,7 @@ static void MX_TIM4_Init(void)
htim4.Instance = TIM4;
htim4.Init.Prescaler = 0;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim4.Init.Period = 0;
+ htim4.Init.Period = 65535;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
@@ -899,7 +943,7 @@ static void MX_TIM15_Init(void)
htim15.Instance = TIM15;
htim15.Init.Prescaler = 0;
htim15.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim15.Init.Period = 0;
+ htim15.Init.Period = 65535;
htim15.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim15.Init.RepetitionCounter = 0;
htim15.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
@@ -942,7 +986,7 @@ static void MX_TIM16_Init(void)
htim16.Instance = TIM16;
htim16.Init.Prescaler = 0;
htim16.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim16.Init.Period = 0;
+ htim16.Init.Period = 65535;
htim16.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim16.Init.RepetitionCounter = 0;
htim16.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
@@ -974,7 +1018,7 @@ static void MX_TIM17_Init(void)
htim17.Instance = TIM17;
htim17.Init.Prescaler = 0;
htim17.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim17.Init.Period = 0;
+ htim17.Init.Period = 65535;
htim17.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim17.Init.RepetitionCounter = 0;
htim17.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
@@ -1138,7 +1182,7 @@ void Error_Handler(void)
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
-{
+{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c
index 7dc7cc3ad7..a3f28f6117 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_hal_msp.c
@@ -78,7 +78,7 @@
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
-
+
void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
/**
* Initializes the Global MSP.
@@ -115,10 +115,10 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
/* USER CODE END ADC1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_ADC_CLK_ENABLE();
-
+
__HAL_RCC_GPIOC_CLK_ENABLE();
- /**ADC1 GPIO Configuration
- PC5 ------> ADC1_IN14
+ /**ADC1 GPIO Configuration
+ PC5 ------> ADC1_IN14
*/
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
@@ -147,9 +147,9 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
/* USER CODE END ADC1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ADC_CLK_DISABLE();
-
- /**ADC1 GPIO Configuration
- PC5 ------> ADC1_IN14
+
+ /**ADC1 GPIO Configuration
+ PC5 ------> ADC1_IN14
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_5);
@@ -161,6 +161,67 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
}
/**
+* @brief DAC MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hdac: DAC handle pointer
+* @retval None
+*/
+void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hdac->Instance==DAC1)
+ {
+ /* USER CODE BEGIN DAC1_MspInit 0 */
+
+ /* USER CODE END DAC1_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_DAC1_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ /**DAC1 GPIO Configuration
+ PA4 ------> DAC1_OUT1
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_4;
+ GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN DAC1_MspInit 1 */
+
+ /* USER CODE END DAC1_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief DAC MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hdac: DAC handle pointer
+* @retval None
+*/
+void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac)
+{
+ if(hdac->Instance==DAC1)
+ {
+ /* USER CODE BEGIN DAC1_MspDeInit 0 */
+
+ /* USER CODE END DAC1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_DAC1_CLK_DISABLE();
+
+ /**DAC1 GPIO Configuration
+ PA4 ------> DAC1_OUT1
+ */
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4);
+
+ /* USER CODE BEGIN DAC1_MspDeInit 1 */
+
+ /* USER CODE END DAC1_MspDeInit 1 */
+ }
+
+}
+
+/**
* @brief LPTIM MSP Initialization
* This function configures the hardware resources used in this example
* @param hlptim: LPTIM handle pointer
@@ -220,17 +281,17 @@ void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi)
/* USER CODE END QUADSPI_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_QSPI_CLK_ENABLE();
-
+
__HAL_RCC_GPIOE_CLK_ENABLE();
- /**QUADSPI GPIO Configuration
+ /**QUADSPI GPIO Configuration
PE10 ------> QUADSPI_CLK
PE11 ------> QUADSPI_NCS
PE12 ------> QUADSPI_BK1_IO0
PE13 ------> QUADSPI_BK1_IO1
PE14 ------> QUADSPI_BK1_IO2
- PE15 ------> QUADSPI_BK1_IO3
+ PE15 ------> QUADSPI_BK1_IO3
*/
- GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13
+ GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13
|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
@@ -260,16 +321,16 @@ void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi)
/* USER CODE END QUADSPI_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_QSPI_CLK_DISABLE();
-
- /**QUADSPI GPIO Configuration
+
+ /**QUADSPI GPIO Configuration
PE10 ------> QUADSPI_CLK
PE11 ------> QUADSPI_NCS
PE12 ------> QUADSPI_BK1_IO0
PE13 ------> QUADSPI_BK1_IO1
PE14 ------> QUADSPI_BK1_IO2
- PE15 ------> QUADSPI_BK1_IO3
+ PE15 ------> QUADSPI_BK1_IO3
*/
- HAL_GPIO_DeInit(GPIOE, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13
|GPIO_PIN_14|GPIO_PIN_15);
/* USER CODE BEGIN QUADSPI_MspDeInit 1 */
@@ -339,18 +400,18 @@ void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
/* USER CODE END SDMMC1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SDMMC1_CLK_ENABLE();
-
+
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
- /**SDMMC1 GPIO Configuration
+ /**SDMMC1 GPIO Configuration
PC8 ------> SDMMC1_D0
PC9 ------> SDMMC1_D1
PC10 ------> SDMMC1_D2
PC11 ------> SDMMC1_D3
PC12 ------> SDMMC1_CK
- PD2 ------> SDMMC1_CMD
+ PD2 ------> SDMMC1_CMD
*/
- GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
@@ -387,16 +448,16 @@ void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
/* USER CODE END SDMMC1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SDMMC1_CLK_DISABLE();
-
- /**SDMMC1 GPIO Configuration
+
+ /**SDMMC1 GPIO Configuration
PC8 ------> SDMMC1_D0
PC9 ------> SDMMC1_D1
PC10 ------> SDMMC1_D2
PC11 ------> SDMMC1_D3
PC12 ------> SDMMC1_CK
- PD2 ------> SDMMC1_CMD
+ PD2 ------> SDMMC1_CMD
*/
- HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12);
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
@@ -424,12 +485,12 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
/* USER CODE END SPI1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
-
+
__HAL_RCC_GPIOA_CLK_ENABLE();
- /**SPI1 GPIO Configuration
+ /**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
- PA7 ------> SPI1_MOSI
+ PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -449,12 +510,12 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
/* USER CODE END SPI2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
-
+
__HAL_RCC_GPIOB_CLK_ENABLE();
- /**SPI2 GPIO Configuration
+ /**SPI2 GPIO Configuration
PB13 ------> SPI2_SCK
PB14 ------> SPI2_MISO
- PB15 ------> SPI2_MOSI
+ PB15 ------> SPI2_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -474,11 +535,11 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
/* USER CODE END SPI3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI3_CLK_ENABLE();
-
+
__HAL_RCC_GPIOB_CLK_ENABLE();
- /**SPI3 GPIO Configuration
+ /**SPI3 GPIO Configuration
PB3 (JTDO-TRACESWO) ------> SPI3_SCK
- PB5 ------> SPI3_MOSI
+ PB5 ------> SPI3_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -509,11 +570,11 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
/* USER CODE END SPI1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI1_CLK_DISABLE();
-
- /**SPI1 GPIO Configuration
+
+ /**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
- PA7 ------> SPI1_MOSI
+ PA7 ------> SPI1_MOSI
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
@@ -528,11 +589,11 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
/* USER CODE END SPI2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI2_CLK_DISABLE();
-
- /**SPI2 GPIO Configuration
+
+ /**SPI2 GPIO Configuration
PB13 ------> SPI2_SCK
PB14 ------> SPI2_MISO
- PB15 ------> SPI2_MOSI
+ PB15 ------> SPI2_MOSI
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);
@@ -547,10 +608,10 @@ void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
/* USER CODE END SPI3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI3_CLK_DISABLE();
-
- /**SPI3 GPIO Configuration
+
+ /**SPI3 GPIO Configuration
PB3 (JTDO-TRACESWO) ------> SPI3_SCK
- PB5 ------> SPI3_MOSI
+ PB5 ------> SPI3_MOSI
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_5);
@@ -647,8 +708,8 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
/* USER CODE END TIM1_MspPostInit 0 */
__HAL_RCC_GPIOE_CLK_ENABLE();
- /**TIM1 GPIO Configuration
- PE9 ------> TIM1_CH1
+ /**TIM1 GPIO Configuration
+ PE9 ------> TIM1_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -666,11 +727,11 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
/* USER CODE BEGIN TIM2_MspPostInit 0 */
/* USER CODE END TIM2_MspPostInit 0 */
-
+
__HAL_RCC_GPIOB_CLK_ENABLE();
- /**TIM2 GPIO Configuration
+ /**TIM2 GPIO Configuration
PB10 ------> TIM2_CH3
- PB11 ------> TIM2_CH4
+ PB11 ------> TIM2_CH4
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -688,11 +749,11 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
/* USER CODE BEGIN TIM4_MspPostInit 0 */
/* USER CODE END TIM4_MspPostInit 0 */
-
+
__HAL_RCC_GPIOB_CLK_ENABLE();
- /**TIM4 GPIO Configuration
+ /**TIM4 GPIO Configuration
PB7 ------> TIM4_CH2
- PB8 ------> TIM4_CH3
+ PB8 ------> TIM4_CH3
*/
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -800,11 +861,11 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
-
+
__HAL_RCC_GPIOA_CLK_ENABLE();
- /**USART1 GPIO Configuration
+ /**USART1 GPIO Configuration
PA9 ------> USART1_TX
- PA10 ------> USART1_RX
+ PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -824,11 +885,11 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
/* USER CODE END USART2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
-
+
__HAL_RCC_GPIOA_CLK_ENABLE();
- /**USART2 GPIO Configuration
+ /**USART2 GPIO Configuration
PA2 ------> USART2_TX
- PA3 ------> USART2_RX
+ PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -859,10 +920,10 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
-
- /**USART1 GPIO Configuration
+
+ /**USART1 GPIO Configuration
PA9 ------> USART1_TX
- PA10 ------> USART1_RX
+ PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
@@ -877,10 +938,10 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
-
- /**USART2 GPIO Configuration
+
+ /**USART2 GPIO Configuration
PA2 ------> USART2_TX
- PA3 ------> USART2_RX
+ PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
@@ -905,11 +966,11 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)
/* USER CODE BEGIN USB_OTG_FS_MspInit 0 */
/* USER CODE END USB_OTG_FS_MspInit 0 */
-
+
__HAL_RCC_GPIOA_CLK_ENABLE();
- /**USB_OTG_FS GPIO Configuration
+ /**USB_OTG_FS GPIO Configuration
PA11 ------> USB_OTG_FS_DM
- PA12 ------> USB_OTG_FS_DP
+ PA12 ------> USB_OTG_FS_DP
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -957,10 +1018,10 @@ void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd)
/* USER CODE END USB_OTG_FS_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USB_OTG_FS_CLK_DISABLE();
-
- /**USB_OTG_FS GPIO Configuration
+
+ /**USB_OTG_FS GPIO Configuration
PA11 ------> USB_OTG_FS_DM
- PA12 ------> USB_OTG_FS_DP
+ PA12 ------> USB_OTG_FS_DP
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
@@ -1000,12 +1061,12 @@ void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
__HAL_RCC_SAI1_CLK_ENABLE();
}
SAI1_client ++;
-
- /**SAI1_A_Block_A GPIO Configuration
+
+ /**SAI1_A_Block_A GPIO Configuration
PE2 ------> SAI1_MCLK_A
PE4 ------> SAI1_FS_A
PE5 ------> SAI1_SCK_A
- PE6 ------> SAI1_SD_A
+ PE6 ------> SAI1_SD_A
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -1023,9 +1084,9 @@ void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
__HAL_RCC_SAI1_CLK_ENABLE();
}
SAI1_client ++;
-
- /**SAI1_B_Block_B GPIO Configuration
- PE3 ------> SAI1_SD_B
+
+ /**SAI1_B_Block_B GPIO Configuration
+ PE3 ------> SAI1_SD_B
*/
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
@@ -1045,15 +1106,15 @@ void HAL_SAI_MspDeInit(SAI_HandleTypeDef* hsai)
SAI1_client --;
if (SAI1_client == 0)
{
- /* Peripheral clock disable */
+ /* Peripheral clock disable */
__HAL_RCC_SAI1_CLK_DISABLE();
}
-
- /**SAI1_A_Block_A GPIO Configuration
+
+ /**SAI1_A_Block_A GPIO Configuration
PE2 ------> SAI1_MCLK_A
PE4 ------> SAI1_FS_A
PE5 ------> SAI1_SCK_A
- PE6 ------> SAI1_SD_A
+ PE6 ------> SAI1_SD_A
*/
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);
@@ -1066,9 +1127,9 @@ void HAL_SAI_MspDeInit(SAI_HandleTypeDef* hsai)
/* Peripheral clock disable */
__HAL_RCC_SAI1_CLK_DISABLE();
}
-
- /**SAI1_B_Block_B GPIO Configuration
- PE3 ------> SAI1_SD_B
+
+ /**SAI1_B_Block_B GPIO Configuration
+ PE3 ------> SAI1_SD_B
*/
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_3);
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_it.c b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_it.c
index 2fc0793b0e..7c46b34cef 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_it.c
+++ b/bsp/stm32/stm32l475-atk-pandora/board/CubeMX_Config/Src/stm32l4xx_it.c
@@ -77,7 +77,7 @@ extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
/* USER CODE END EV */
/******************************************************************************/
-/* Cortex-M4 Processor Interruption and Exception Handlers */
+/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
diff --git a/bsp/stm32/stm32l475-atk-pandora/board/Kconfig b/bsp/stm32/stm32l475-atk-pandora/board/Kconfig
index e49b1ee9fb..f6d822573b 100644
--- a/bsp/stm32/stm32l475-atk-pandora/board/Kconfig
+++ b/bsp/stm32/stm32l475-atk-pandora/board/Kconfig
@@ -308,6 +308,16 @@ menu "On-chip Peripheral Drivers"
default n
endif
+ menuconfig BSP_USING_DAC
+ bool "Enable DAC"
+ default n
+ select RT_USING_DAC
+ if BSP_USING_DAC
+ config BSP_USING_DAC1
+ bool "Enable DAC1"
+ default n
+ endif
+
menuconfig BSP_USING_ONCHIP_RTC
bool "Enable RTC"
select RT_USING_RTC
diff --git a/bsp/stm32/stm32mp157a-st-discovery/.config b/bsp/stm32/stm32mp157a-st-discovery/.config
index 01ca2120fa..5715750c67 100644
--- a/bsp/stm32/stm32mp157a-st-discovery/.config
+++ b/bsp/stm32/stm32mp157a-st-discovery/.config
@@ -123,6 +123,7 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
# CONFIG_RT_USING_HWTIMER is not set
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
+# CONFIG_RT_USING_PHY is not set
CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_ADC is not set
# CONFIG_RT_USING_DAC is not set
@@ -199,12 +200,15 @@ CONFIG_RT_USING_PIN=y
#
# IoT - internet of things
#
+# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_UMQTT is not set
# CONFIG_PKG_USING_WEBCLIENT is not set
# CONFIG_PKG_USING_WEBNET is not set
# CONFIG_PKG_USING_MONGOOSE is not set
# CONFIG_PKG_USING_MYMQTT is not set
# CONFIG_PKG_USING_KAWAII_MQTT is not set
+# CONFIG_PKG_USING_BC28_MQTT is not set
# CONFIG_PKG_USING_WEBTERMINAL is not set
# CONFIG_PKG_USING_CJSON is not set
# CONFIG_PKG_USING_JSMN is not set
@@ -231,6 +235,7 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_COAP is not set
# CONFIG_PKG_USING_NOPOLL is not set
# CONFIG_PKG_USING_NETUTILS is not set
+# CONFIG_PKG_USING_CMUX is not set
# CONFIG_PKG_USING_PPP_DEVICE is not set
# CONFIG_PKG_USING_AT_DEVICE is not set
# CONFIG_PKG_USING_ATSRV_SOCKET is not set
@@ -243,7 +248,7 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_GAGENT_CLOUD is not set
# CONFIG_PKG_USING_ALI_IOTKIT is not set
# CONFIG_PKG_USING_AZURE is not set
-# CONFIG_PKG_USING_TENCENT_IOTHUB is not set
+# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
# CONFIG_PKG_USING_JIOT-C-SDK is not set
# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
# CONFIG_PKG_USING_JOYLINK is not set
@@ -265,6 +270,11 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_CAPNP is not set
# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
# CONFIG_PKG_USING_AGILE_TELNET is not set
+# CONFIG_PKG_USING_NMEALIB is not set
+# CONFIG_PKG_USING_AGILE_JSMN is not set
+# CONFIG_PKG_USING_PDULIB is not set
+# CONFIG_PKG_USING_BTSTACK is not set
+# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
#
# security packages
@@ -273,6 +283,7 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_libsodium is not set
# CONFIG_PKG_USING_TINYCRYPT is not set
# CONFIG_PKG_USING_TFM is not set
+# CONFIG_PKG_USING_YD_CRYPTO is not set
#
# language packages
@@ -289,6 +300,8 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_STEMWIN is not set
# CONFIG_PKG_USING_WAVPLAYER is not set
# CONFIG_PKG_USING_TJPGD is not set
+# CONFIG_PKG_USING_HELIX is not set
+# CONFIG_PKG_USING_AZUREGUIX is not set
#
# tools packages
@@ -307,6 +320,9 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
# CONFIG_PKG_USING_BS8116A is not set
+# CONFIG_PKG_USING_GPS_RMC is not set
+# CONFIG_PKG_USING_URLENCODE is not set
+# CONFIG_PKG_USING_UMCN is not set
#
# system packages
@@ -318,6 +334,7 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_LWEXT4 is not set
# CONFIG_PKG_USING_PARTITION is not set
# CONFIG_PKG_USING_FAL is not set
+# CONFIG_PKG_USING_FLASHDB is not set
# CONFIG_PKG_USING_SQLITE is not set
# CONFIG_PKG_USING_RTI is not set
# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
@@ -330,6 +347,19 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_SYSWATCH is not set
# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
# CONFIG_PKG_USING_PLCCORE is not set
+# CONFIG_PKG_USING_RAMDISK is not set
+# CONFIG_PKG_USING_MININI is not set
+# CONFIG_PKG_USING_QBOOT is not set
+
+#
+# Micrium: Micrium software products porting for RT-Thread
+#
+# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
+# CONFIG_PKG_USING_UC_CRC is not set
+# CONFIG_PKG_USING_UC_CLK is not set
+# CONFIG_PKG_USING_UC_COMMON is not set
+# CONFIG_PKG_USING_UC_MODBUS is not set
+# CONFIG_PKG_USING_PPOOL is not set
#
# peripheral libraries and drivers
@@ -367,6 +397,7 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_RPLIDAR is not set
# CONFIG_PKG_USING_AS608 is not set
# CONFIG_PKG_USING_RC522 is not set
+# CONFIG_PKG_USING_WS2812B is not set
# CONFIG_PKG_USING_EMBARC_BSP is not set
# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
# CONFIG_PKG_USING_MULTI_RTIMER is not set
@@ -374,6 +405,17 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_BEEP is not set
# CONFIG_PKG_USING_EASYBLINK is not set
# CONFIG_PKG_USING_PMS_SERIES is not set
+# CONFIG_PKG_USING_CAN_YMODEM is not set
+# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
+# CONFIG_PKG_USING_QLED is not set
+# CONFIG_PKG_USING_PAJ7620 is not set
+# CONFIG_PKG_USING_AGILE_CONSOLE is not set
+# CONFIG_PKG_USING_LD3320 is not set
+# CONFIG_PKG_USING_WK2124 is not set
+# CONFIG_PKG_USING_LY68L6400 is not set
+# CONFIG_PKG_USING_DM9051 is not set
+# CONFIG_PKG_USING_SSD1306 is not set
+# CONFIG_PKG_USING_QKEY is not set
#
# miscellaneous packages
@@ -403,13 +445,20 @@ CONFIG_RT_USING_PIN=y
# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
# CONFIG_PKG_USING_HELLO is not set
# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_KI is not set
# CONFIG_PKG_USING_NNOM is not set
# CONFIG_PKG_USING_LIBANN is not set
# CONFIG_PKG_USING_ELAPACK is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
# CONFIG_PKG_USING_VT100 is not set
+# CONFIG_PKG_USING_TETRIS is not set
# CONFIG_PKG_USING_ULAPACK is not set
# CONFIG_PKG_USING_UKAL is not set
+# CONFIG_PKG_USING_CRCLIB is not set
+# CONFIG_PKG_USING_THREES is not set
+# CONFIG_PKG_USING_2048 is not set
+# CONFIG_PKG_USING_LWGPS is not set
+# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
CONFIG_SOC_FAMILY_STM32=y
CONFIG_SOC_SERIES_STM32MP1=y
@@ -427,6 +476,10 @@ CONFIG_BSP_USING_STLINK_TO_USART=y
# CONFIG_BSP_USING_PWR is not set
# CONFIG_BSP_USING_RCC is not set
# CONFIG_BSP_USING_OPENAMP is not set
+# CONFIG_BSP_USING_RS485 is not set
+# CONFIG_BSP_USING_GBE is not set
+# CONFIG_BSP_USING_SDMMC is not set
+# CONFIG_BSP_USING_AUDIO is not set
#
# On-chip Peripheral Drivers
@@ -435,7 +488,6 @@ CONFIG_BSP_USING_GPIO=y
# CONFIG_BSP_USING_WWDG is not set
CONFIG_BSP_USING_UART=y
# CONFIG_BSP_USING_UART3 is not set
-# CONFIG_BSP_UART3_RX_USING_DMA is not set
CONFIG_BSP_USING_UART4=y
# CONFIG_BSP_UART4_RX_USING_DMA is not set
# CONFIG_BSP_UART4_TX_USING_DMA is not set
@@ -448,6 +500,8 @@ CONFIG_BSP_USING_UART4=y
# CONFIG_BSP_USING_SPI is not set
# CONFIG_BSP_USING_CRC is not set
# CONFIG_BSP_USING_RNG is not set
+# CONFIG_BSP_USING_HASH is not set
+# CONFIG_BSP_USING_CRYP is not set
# CONFIG_BSP_USING_UDID is not set
#
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h b/bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
index 424bdc02a2..3ba077b0b5 100644
--- a/bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
@@ -34,8 +34,8 @@
#define HAL_MODULE_ENABLED
#define HAL_ADC_MODULE_ENABLED
/*#define HAL_CEC_MODULE_ENABLED */
-/*#define HAL_CRC_MODULE_ENABLED */
-/*#define HAL_CRYP_MODULE_ENABLED */
+#define HAL_CRC_MODULE_ENABLED
+#define HAL_CRYP_MODULE_ENABLED
#define HAL_DAC_MODULE_ENABLED
/*#define HAL_DCMI_MODULE_ENABLED */
/*#define HAL_DSI_MODULE_ENABLED */
@@ -43,7 +43,7 @@
/*#define HAL_DTS_MODULE_ENABLED */
/*#define HAL_ETH_MODULE_ENABLED */
/*#define HAL_FDCAN_MODULE_ENABLED */
-/*#define HAL_HASH_MODULE_ENABLED */
+#define HAL_HASH_MODULE_ENABLED
/*#define HAL_HCD_MODULE_ENABLED */
#define HAL_HSEM_MODULE_ENABLED
#define HAL_I2C_MODULE_ENABLED
@@ -56,9 +56,9 @@
/*#define HAL_NOR_MODULE_ENABLED */
/*#define HAL_PCD_MODULE_ENABLED */
/*#define HAL_QSPI_MODULE_ENABLED */
-/*#define HAL_RNG_MODULE_ENABLED */
-/*#define HAL_SAI_MODULE_ENABLED */
-/*#define HAL_SD_MODULE_ENABLED */
+#define HAL_RNG_MODULE_ENABLED
+#define HAL_SAI_MODULE_ENABLED
+#define HAL_SD_MODULE_ENABLED
/*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_RTC_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c b/bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
index d31aa64197..2ddf367caa 100644
--- a/bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
@@ -26,7 +26,9 @@
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
-
+DMA_HandleTypeDef hdma_hash_in = {0};
+DMA_HandleTypeDef hdma_cryp_in = {0};
+DMA_HandleTypeDef hdma_cryp_out = {0};
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
@@ -58,8 +60,7 @@
/* USER CODE END 0 */
-void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
- /**
+/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
@@ -943,6 +944,107 @@ void HAL_I2C_MspInit(I2C_HandleTypeDef *hI2c)
}
/**
+* @brief SD MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hsd: SD handle pointer
+* @retval None
+*/
+void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+ if(hsd->Instance==SDMMC1)
+ {
+ /* USER CODE BEGIN SDMMC1_MspInit 0 */
+ if (IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.Sdmmc12ClockSelection = RCC_SDMMC12CLKSOURCE_PLL4;
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC12;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+ /* USER CODE END SDMMC1_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SDMMC1_CLK_ENABLE();
+
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ /**SDMMC1 GPIO Configuration
+ PC8 ------> SDMMC1_D0
+ PC9 ------> SDMMC1_D1
+ PC10 ------> SDMMC1_D2
+ PC11 ------> SDMMC1_D3
+ PC12 ------> SDMMC1_CK
+ PD2 ------> SDMMC1_CMD
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ |GPIO_PIN_12;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_2;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ __HAL_RCC_SDMMC1_FORCE_RESET();
+ __HAL_RCC_SDMMC1_RELEASE_RESET();
+
+ /* SDMMC1 interrupt Init */
+ HAL_NVIC_SetPriority(SDMMC1_IRQn, 2, 0);
+ HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
+ /* USER CODE BEGIN SDMMC1_MspInit 1 */
+
+ /* USER CODE END SDMMC1_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief SD MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hsd: SD handle pointer
+* @retval None
+*/
+void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
+{
+ if(hsd->Instance==SDMMC1)
+ {
+ /* USER CODE BEGIN SDMMC1_MspDeInit 0 */
+
+ /* USER CODE END SDMMC1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SDMMC1_CLK_DISABLE();
+
+ /**SDMMC1 GPIO Configuration
+ PC8 ------> SDMMC1_D0
+ PC9 ------> SDMMC1_D1
+ PC10 ------> SDMMC1_D2
+ PC11 ------> SDMMC1_D3
+ PC12 ------> SDMMC1_CK
+ PD2 ------> SDMMC1_CMD
+ */
+ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ |GPIO_PIN_12);
+
+ HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
+
+ /* SDMMC1 interrupt DeInit */
+ HAL_NVIC_DisableIRQ(SDMMC1_IRQn);
+ /* USER CODE BEGIN SDMMC1_MspDeInit 1 */
+
+ /* USER CODE END SDMMC1_MspDeInit 1 */
+ }
+
+}
+
+/**
* @brief DeInitializes I2C MSP.
* @param hI2c : I2C handler
* @retval None
@@ -967,6 +1069,250 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hI2c)
}
/**
+* @brief CRC MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hcrc: CRC handle pointer
+* @retval None
+*/
+void HAL_CRC_MspInit(CRC_HandleTypeDef* hcrc)
+{
+ if(hcrc->Instance==CRC2)
+ {
+ /* USER CODE BEGIN CRC2_MspInit 0 */
+
+ /* USER CODE END CRC2_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_CRC2_CLK_ENABLE();
+ /* USER CODE BEGIN CRC2_MspInit 1 */
+
+ /* USER CODE END CRC2_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief CRC MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hcrc: CRC handle pointer
+* @retval None
+*/
+void HAL_CRC_MspDeInit(CRC_HandleTypeDef* hcrc)
+{
+ if(hcrc->Instance==CRC2)
+ {
+ /* USER CODE BEGIN CRC2_MspDeInit 0 */
+
+ /* USER CODE END CRC2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_CRC2_CLK_DISABLE();
+ /* USER CODE BEGIN CRC2_MspDeInit 1 */
+
+ /* USER CODE END CRC2_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief RNG MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hrng: RNG handle pointer
+* @retval None
+*/
+void HAL_RNG_MspInit(RNG_HandleTypeDef* hrng)
+{
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+ if(hrng->Instance==RNG2)
+ {
+ /* USER CODE BEGIN RNG2_MspInit 0 */
+
+ /* USER CODE END RNG2_MspInit 0 */
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RNG2;
+ PeriphClkInit.Rng2ClockSelection = RCC_RNG2CLKSOURCE_CSI;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ }
+
+ /* Peripheral clock enable */
+ __HAL_RCC_RNG2_CLK_ENABLE();
+ /* USER CODE BEGIN RNG2_MspInit 1 */
+
+ /* USER CODE END RNG2_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief RNG MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hrng: RNG handle pointer
+* @retval None
+*/
+void HAL_RNG_MspDeInit(RNG_HandleTypeDef* hrng)
+{
+ if(hrng->Instance==RNG2)
+ {
+ /* USER CODE BEGIN RNG2_MspDeInit 0 */
+
+ /* USER CODE END RNG2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_RNG2_CLK_DISABLE();
+ /* USER CODE BEGIN RNG2_MspDeInit 1 */
+
+ /* USER CODE END RNG2_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief HASH MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hhash: HASH handle pointer
+* @retval None
+*/
+void HAL_HASH_MspInit(HASH_HandleTypeDef* hhash)
+{
+ /* USER CODE BEGIN HASH2_MspInit 0 */
+ /* USER CODE END HASH2_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_HASH2_CLK_ENABLE();
+ /* USER CODE BEGIN HASH2_MspInit 1 */
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+
+ /* Peripheral DMA init*/
+ hdma_hash_in.Instance = DMA2_Stream7;
+ hdma_hash_in.Init.Request = DMA_REQUEST_HASH2_IN;
+ hdma_hash_in.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_hash_in.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_hash_in.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_hash_in.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_hash_in.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_hash_in.Init.Mode = DMA_NORMAL;
+ hdma_hash_in.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_hash_in.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_hash_in.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
+ hdma_hash_in.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_hash_in.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ if (HAL_DMA_DeInit(&hdma_hash_in) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_DMA_Init(&hdma_hash_in) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(hhash,hdmain,hdma_hash_in);
+ /* USER CODE END HASH2_MspInit 1 */
+
+}
+
+/**
+* @brief HASH MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hhash: HASH handle pointer
+* @retval None
+*/
+void HAL_HASH_MspDeInit(HASH_HandleTypeDef* hhash)
+{
+ /* USER CODE BEGIN HASH2_MspDeInit 0 */
+
+ /* USER CODE END HASH2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_HASH2_CLK_DISABLE();
+ /* USER CODE BEGIN HASH2_MspDeInit 1 */
+
+ /* USER CODE END HASH2_MspDeInit 1 */
+
+}
+
+#if defined (CRYP1) || defined (CRYP2)
+void HAL_CRYP_MspInit(CRYP_HandleTypeDef* hcryp)
+{
+ if(hcryp->Instance==CRYP2)
+ {
+ /* Peripheral clock enable */
+ __HAL_RCC_CRYP2_CLK_ENABLE();
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+
+ /* Peripheral DMA init*/
+ hdma_cryp_in.Instance = DMA2_Stream6;
+ hdma_cryp_in.Init.Request = DMA_REQUEST_CRYP2_IN;
+ hdma_cryp_in.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_cryp_in.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_cryp_in.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_cryp_in.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_cryp_in.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_cryp_in.Init.Mode = DMA_NORMAL;
+ hdma_cryp_in.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_cryp_in.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ if (HAL_DMA_DeInit(&hdma_cryp_in) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_DMA_Init(&hdma_cryp_in) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(hcryp,hdmain,hdma_cryp_in);
+
+ hdma_cryp_out.Instance = DMA2_Stream5;
+ hdma_cryp_out.Init.Request = DMA_REQUEST_CRYP2_OUT;
+ hdma_cryp_out.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_cryp_out.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_cryp_out.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_cryp_out.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_cryp_out.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_cryp_out.Init.Mode = DMA_NORMAL;
+ hdma_cryp_out.Init.Priority = DMA_PRIORITY_VERY_HIGH;
+ hdma_cryp_out.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ if (HAL_DMA_DeInit(&hdma_cryp_out) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_DMA_Init(&hdma_cryp_out) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(hcryp,hdmaout,hdma_cryp_out);
+
+ /* USER CODE BEGIN CRYP_MspInit 1 */
+
+ /* USER CODE END CRYP_MspInit 1 */
+ }
+}
+
+void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef* hcryp)
+{
+
+ if(hcryp->Instance==CRYP2)
+ {
+ /* USER CODE BEGIN CRYP_MspDeInit 0 */
+
+ /* USER CODE END CRYP_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_CRYP2_CLK_DISABLE();
+
+ /* Peripheral DMA DeInit*/
+ HAL_DMA_DeInit(hcryp->hdmain);
+ HAL_DMA_DeInit(hcryp->hdmaout);
+ }
+ /* USER CODE BEGIN CRYP_MspDeInit 1 */
+
+ /* USER CODE END CRYP_MspDeInit 1 */
+
+}
+#endif
+/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/Kconfig b/bsp/stm32/stm32mp157a-st-discovery/board/Kconfig
index 2ea8df97ab..9191443847 100644
--- a/bsp/stm32/stm32mp157a-st-discovery/board/Kconfig
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/Kconfig
@@ -50,7 +50,37 @@ menu "Onboard Peripheral Drivers"
config RS485_UART_DEVICE_NAME
string "the uart name for rs485"
default "uart3"
+ endif
+
+ config BSP_USING_GBE
+ bool "Enable Ethernet"
+ default n
+ select RT_USING_LWIP
+
+ config BSP_USING_SDMMC
+ bool "Enable SDMMC (SD card)"
+ select RT_USING_SDIO
+ select RT_USING_DFS
+ select RT_USING_DFS_ELMFAT
+ default n
+
+ menuconfig BSP_USING_AUDIO
+ bool "Enable Audio Device"
+ select RT_USING_AUDIO
+ select BSP_USING_PMIC
+ select BSP_USING_SDMMC
+ select BSP_USING_I2C
+ select BSP_USING_I2C4
+ default n
+
+ if BSP_USING_AUDIO
+ config BSP_USING_AUDIO_PLAY
+ bool "Enable Audio Play"
+ default y
+ config BSP_USING_AUDIO_RECORD
+ bool "Enable Audio Record"
+ default n
endif
endmenu
@@ -196,7 +226,7 @@ menu "On-chip Peripheral Drivers"
range 1 176
default 117
endif
- menuconfig BSP_USING_I2C3
+ menuconfig BSP_USING_I2C3
bool "Enable I2C3 BUS (software simulation)"
default n
if BSP_USING_I2C3
@@ -210,6 +240,21 @@ menu "On-chip Peripheral Drivers"
range 1 191
default 181
endif
+ menuconfig BSP_USING_I2C4
+ bool "Enable I2C4 BUS (software simulation)"
+ default n
+ if BSP_USING_I2C4
+ comment "Notice: PD12 --> 60; PF15 --> 95"
+ config BSP_I2C4_SCL_PIN
+ int "i2c4 scl pin number"
+ range 1 191
+ default 60
+ config BSP_I2C4_SDA_PIN
+ int "I2C4 sda pin number"
+ range 1 191
+ default 95
+ endif
+
endif
menuconfig BSP_USING_SPI
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/SConscript b/bsp/stm32/stm32mp157a-st-discovery/board/SConscript
index a99f95d786..f1de10714b 100644
--- a/bsp/stm32/stm32mp157a-st-discovery/board/SConscript
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/SConscript
@@ -40,6 +40,23 @@ if GetDepend(['BSP_USING_PMIC']):
if GetDepend(['BSP_USING_RS485']):
src += Glob('ports/drv_rs485.c')
+if GetDepend(['BSP_USING_GBE']):
+ src += Glob('ports/drv_eth.c')
+
+if GetDepend(['BSP_USING_SDMMC']):
+ src += Glob('ports/drv_sdio.c')
+
+if GetDepend(['BSP_USING_AUDIO']):
+ src += Glob('ports/audio/drv_cs42l51.c')
+ src += Glob('ports/audio/drv_sound.c')
+ src += Glob('ports/audio/audio_play.c')
+
+if GetDepend(['BSP_USING_AUDIO_RECORD']):
+ src += Glob('ports/audio/drv_mic.c')
+
+if GetDepend(['(BSP_USING_RNG)']) or GetDepend(['(BSP_USING_HASH)']) or GetDepend(['(BSP_USING_CRC)']) or GetDepend(['BSP_USING_CRYP']):
+ src += Glob('ports/crypto/crypto_sample.c')
+
if GetDepend(['BSP_USING_OPENAMP']):
src += Glob('CubeMX_Config/CM4/Src/ipcc.c')
src += Glob('CubeMX_Config/CM4/Src/openamp.c')
@@ -58,6 +75,7 @@ if GetDepend(['BSP_USING_OPENAMP']):
path = [cwd]
path += [cwd + '/CubeMX_Config/CM4/Inc']
path += [cwd + '/ports']
+path += [cwd + '/ports/audio']
if GetDepend(['BSP_USING_OPENAMP']):
path += [cwd + '/ports/OpenAMP']
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/board.h b/bsp/stm32/stm32mp157a-st-discovery/board/board.h
index 23fac89b39..18cab2141c 100644
--- a/bsp/stm32/stm32mp157a-st-discovery/board/board.h
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/board.h
@@ -32,7 +32,7 @@ extern "C" {
#if defined(BSP_USING_OPENAMP)
-#define STM32_SRAM_BEGIN (uint32_t)0x10020000
+#define STM32_SRAM_BEGIN (uint32_t)0x10030000
#else
#define STM32_SRAM_BEGIN (uint32_t)0x2FFF0000
#endif
@@ -42,8 +42,6 @@ extern "C" {
#define HEAP_BEGIN STM32_SRAM_BEGIN
#define HEAP_END STM32_SRAM_END
-#define HEAP_END STM32_SRAM_END
-
void SystemClock_Config(void);
extern void _Error_Handler(char *s, int num);
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/linker_scripts/link.icf b/bsp/stm32/stm32mp157a-st-discovery/board/linker_scripts/link.icf
index 543a8a37d2..de9f6960b4 100644
--- a/bsp/stm32/stm32mp157a-st-discovery/board/linker_scripts/link.icf
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/linker_scripts/link.icf
@@ -5,7 +5,7 @@
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_text_start__ = 0x10000000;
-define symbol __ICFEDIT_region_text_end__ = 0x1001FFFF;
+define symbol __ICFEDIT_region_text_end__ = 0x1002FFFF;
define symbol __ICFEDIT_region_data_start__ = 0x10030000;
define symbol __ICFEDIT_region_data_end__ = 0x1003FFFF;
/*-Sizes-*/
@@ -27,11 +27,6 @@ define symbol __OPENAMP_region_size__ = 0x8000;
export symbol __OPENAMP_region_start__;
export symbol __OPENAMP_region_size__;
-define symbol __SDMMC_region_start__ = 0x10048000;
-define symbol __SDMMC_region_size__ = 0x1FFFF;
-export symbol __SDMMC_region_start__;
-export symbol __SDMMC_region_size__;
-
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/audio_play.c b/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/audio_play.c
new file mode 100644
index 0000000000..315f6320d5
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/audio_play.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-11-24 thread-liu first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <dfs_posix.h>
+
+#if defined(BSP_USING_AUDIO) && defined(BSP_USING_SDMMC)
+#define BUFSZ 1024
+#define SOUND_DEVICE_NAME "sound0"
+static rt_device_t snd_dev;
+
+struct RIFF_HEADER_DEF
+{
+ char riff_id[4]; // 'R','I','F','F'
+ uint32_t riff_size;
+ char riff_format[4]; // 'W','A','V','E'
+};
+
+struct WAVE_FORMAT_DEF
+{
+ uint16_t FormatTag;
+ uint16_t Channels;
+ uint32_t SamplesPerSec;
+ uint32_t AvgBytesPerSec;
+ uint16_t BlockAlign;
+ uint16_t BitsPerSample;
+};
+
+struct FMT_BLOCK_DEF
+{
+ char fmt_id[4]; // 'f','m','t',' '
+ uint32_t fmt_size;
+ struct WAVE_FORMAT_DEF wav_format;
+};
+
+struct DATA_BLOCK_DEF
+{
+ char data_id[4]; // 'R','I','F','F'
+ uint32_t data_size;
+};
+
+struct wav_info
+{
+ struct RIFF_HEADER_DEF header;
+ struct FMT_BLOCK_DEF fmt_block;
+ struct DATA_BLOCK_DEF data_block;
+};
+
+int wavplay_sample(int argc, char **argv)
+{
+ int fd = -1;
+ uint8_t *buffer = NULL;
+ struct wav_info *info = NULL;
+ struct rt_audio_caps caps = {0};
+
+ if (argc != 2)
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("wavplay_sample song.wav\n");
+ return 0;
+ }
+
+ fd = open(argv[1], O_WRONLY);
+ if (fd < 0)
+ {
+ rt_kprintf("open file failed!\n");
+ goto __exit;
+ }
+
+ buffer = rt_malloc(BUFSZ);
+ if (buffer == RT_NULL)
+ goto __exit;
+
+ info = (struct wav_info *) rt_malloc(sizeof * info);
+ if (info == RT_NULL)
+ goto __exit;
+
+ if (read(fd, &(info->header), sizeof(struct RIFF_HEADER_DEF)) <= 0)
+ goto __exit;
+ if (read(fd, &(info->fmt_block), sizeof(struct FMT_BLOCK_DEF)) <= 0)
+ goto __exit;
+ if (read(fd, &(info->data_block), sizeof(struct DATA_BLOCK_DEF)) <= 0)
+ goto __exit;
+
+ rt_kprintf("wav information:\n");
+ rt_kprintf("samplerate %d\n", info->fmt_block.wav_format.SamplesPerSec);
+ rt_kprintf("channel %d\n", info->fmt_block.wav_format.Channels);
+
+ snd_dev = rt_device_find(SOUND_DEVICE_NAME);
+
+ rt_device_open(snd_dev, RT_DEVICE_OFLAG_WRONLY);
+
+ caps.main_type = AUDIO_TYPE_OUTPUT;
+ caps.sub_type = AUDIO_DSP_PARAM;
+ caps.udata.config.samplerate = info->fmt_block.wav_format.SamplesPerSec;
+ caps.udata.config.channels = info->fmt_block.wav_format.Channels;
+ caps.udata.config.samplebits = 16;
+ rt_device_control(snd_dev, AUDIO_CTL_CONFIGURE, &caps);
+
+ while (1)
+ {
+ int length;
+
+ length = read(fd, buffer, BUFSZ);
+
+ if (length <= 0)
+ break;
+
+ rt_device_write(snd_dev, 0, buffer, length);
+ }
+
+ rt_device_close(snd_dev);
+
+__exit:
+
+ if (fd >= 0)
+ close(fd);
+
+ if (buffer)
+ rt_free(buffer);
+
+ if (info)
+ rt_free(info);
+
+ return 0;
+}
+
+MSH_CMD_EXPORT(wavplay_sample, play wav file);
+
+#endif
+
+#if defined(BSP_USING_AUDIO) && defined(BSP_USING_SDMMC) && defined(BSP_USING_AUDIO_RECORD)
+
+#define RECORD_TIME_MS 5000
+#define RECORD_SAMPLERATE 16000
+#define RECORD_CHANNEL 2
+#define RECORD_CHUNK_SZ ((RECORD_SAMPLERATE * RECORD_CHANNEL * 2) * 20 / 1000)
+
+#define MIC_DEVICE_NAME "mic0"
+static rt_device_t mic_dev;
+
+struct wav_header
+{
+ char riff_id[4]; /* "RIFF" */
+ int riff_datasize; /* RIFF chunk data size,exclude riff_id[4] and riff_datasize,total - 8 */
+ char riff_type[4]; /* "WAVE" */
+ char fmt_id[4]; /* "fmt " */
+ int fmt_datasize; /* fmt chunk data size,16 for pcm */
+ short fmt_compression_code; /* 1 for PCM */
+ short fmt_channels; /* 1(mono) or 2(stereo) */
+ int fmt_sample_rate; /* samples per second */
+ int fmt_avg_bytes_per_sec; /* sample_rate * channels * bit_per_sample / 8 */
+ short fmt_block_align; /* number bytes per sample, bit_per_sample * channels / 8 */
+ short fmt_bit_per_sample; /* bits of each sample(8,16,32). */
+ char data_id[4]; /* "data" */
+ int data_datasize; /* data chunk size,pcm_size - 44 */
+};
+
+static void wavheader_init(struct wav_header *header, int sample_rate, int channels, int datasize)
+{
+ memcpy(header->riff_id, "RIFF", 4);
+ header->riff_datasize = datasize + 44 - 8;
+ memcpy(header->riff_type, "WAVE", 4);
+ memcpy(header->fmt_id, "fmt ", 4);
+ header->fmt_datasize = 16;
+ header->fmt_compression_code = 1;
+ header->fmt_channels = channels;
+ header->fmt_sample_rate = sample_rate;
+ header->fmt_bit_per_sample = 16;
+ header->fmt_avg_bytes_per_sec = header->fmt_sample_rate * header->fmt_channels * header->fmt_bit_per_sample / 8;
+ header->fmt_block_align = header->fmt_bit_per_sample * header->fmt_channels / 8;
+ memcpy(header->data_id, "data", 4);
+ header->data_datasize = datasize;
+}
+
+int wavrecord_sample(int argc, char **argv)
+{
+ int fd = -1;
+ uint8_t *buffer = NULL;
+ struct wav_header header;
+ struct rt_audio_caps caps = {0};
+ int length, total_length = 0;
+
+ if (argc != 2)
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("wavrecord_sample file.wav\n");
+ return -1;
+ }
+
+ fd = open(argv[1], O_WRONLY | O_CREAT);
+ if (fd < 0)
+ {
+ rt_kprintf("open file for recording failed!\n");
+ return -1;
+ }
+ write(fd, &header, sizeof(struct wav_header));
+
+ buffer = rt_malloc(RECORD_CHUNK_SZ);
+ if (buffer == RT_NULL)
+ goto __exit;
+
+ mic_dev = rt_device_find(MIC_DEVICE_NAME);
+ if (mic_dev == RT_NULL)
+ goto __exit;
+
+ rt_device_open(mic_dev, RT_DEVICE_OFLAG_RDONLY);
+
+ caps.main_type = AUDIO_TYPE_INPUT;
+ caps.sub_type = AUDIO_DSP_PARAM;
+ caps.udata.config.samplerate = RECORD_SAMPLERATE;
+ caps.udata.config.channels = RECORD_CHANNEL;
+ caps.udata.config.samplebits = 16;
+ rt_device_control(mic_dev, AUDIO_CTL_CONFIGURE, &caps);
+
+ while (1)
+ {
+ length = rt_device_read(mic_dev, 0, buffer, RECORD_CHUNK_SZ);
+
+ if (length)
+ {
+ write(fd, buffer, length);
+ total_length += length;
+ }
+
+ if ((total_length / RECORD_CHUNK_SZ) > (RECORD_TIME_MS / 20))
+ break;
+ }
+
+ /* write wav file head */
+ wavheader_init(&header, RECORD_SAMPLERATE, RECORD_CHANNEL, total_length);
+ lseek(fd, 0, SEEK_SET);
+ write(fd, &header, sizeof(struct wav_header));
+ close(fd);
+
+ /* close audio mic device */
+ rt_device_close(mic_dev);
+
+__exit:
+ if (fd >= 0)
+ close(fd);
+
+ if (buffer)
+ rt_free(buffer);
+
+ return 0;
+}
+MSH_CMD_EXPORT(wavrecord_sample, record voice to a wav file);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_cs42l51.c b/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_cs42l51.c
new file mode 100644
index 0000000000..e0ae5f1b5e
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_cs42l51.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-02 thread-liu first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_AUDIO)
+#include <drv_cs42l51.h>
+
+#define DRV_DEBUG
+#define LOG_TAG "drv.audio"
+#include <drv_log.h>
+
+/* CS42L51 address */
+#define CHIP_ADDRESS 0x4A
+/* reset pin, active low */
+#define CS42L51_RESET_PIN GET_PIN(G, 9)
+
+static uint16_t CS42L51_Device = OUT_HEADPHONE;
+static struct rt_i2c_bus_device *audio_dev = RT_NULL;
+
+/* i2c read reg */
+static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t len, rt_uint8_t *buf)
+{
+ struct rt_i2c_msg msg[2] = {0, 0};
+
+ RT_ASSERT(bus != RT_NULL);
+
+ msg[0].addr = CHIP_ADDRESS; /* Slave address */
+ msg[0].flags = RT_I2C_WR; /* Write flag */
+ msg[0].buf = &reg; /* Slave register address */
+ msg[0].len = 1; /* Number of bytes sent */
+
+ msg[1].addr = CHIP_ADDRESS;
+ msg[1].flags = RT_I2C_RD;
+ msg[1].len = len;
+ msg[1].buf = buf;
+
+ if (rt_i2c_transfer(bus, msg, 2) == 2)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* i2c write reg */
+static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t data)
+{
+ rt_uint8_t buf[2];
+ struct rt_i2c_msg msgs;
+
+ RT_ASSERT(bus != RT_NULL);
+
+ buf[0] = reg;
+ buf[1] = data;
+
+ msgs.addr = CHIP_ADDRESS;
+ msgs.flags = RT_I2C_WR;
+ msgs.buf = buf;
+ msgs.len = 2;
+
+ if (rt_i2c_transfer(bus, &msgs, 1) == 1)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/**
+ * @brief deinitializes cs42l51 low level.
+ * @retval none
+ */
+static void cs42l51_lowlevel_deinit(void)
+{
+ rt_uint8_t temp = 0;
+
+ /* Mute DAC and ADC */
+ read_reg(audio_dev, CS42L51_DAC_OUT_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_DAC_OUT_CTL, (temp | 0x03));
+ read_reg(audio_dev, CS42L51_ADC_INPUT, 1, &temp);
+ write_reg(audio_dev, CS42L51_ADC_INPUT, (temp | 0x03));
+
+ /* Disable soft ramp and zero cross */
+ read_reg(audio_dev, CS42L51_ADC_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_ADC_CTL, (temp & 0xF0));
+
+ /* Set PDN to 1 */
+ read_reg(audio_dev, CS42L51_POWER_CTL1, 1, &temp);
+ write_reg(audio_dev, CS42L51_POWER_CTL1, (temp | 0x01));
+
+ /* Set all power down bits to 1 */
+ write_reg(audio_dev, CS42L51_POWER_CTL1, 0x7F);
+ read_reg(audio_dev, CS42L51_MIC_POWER_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_MIC_POWER_CTL, (temp | 0x0E));
+
+ /* Power off the codec */
+ rt_pin_write(CS42L51_RESET_PIN, PIN_LOW);
+}
+
+/**
+ * @brief initializes cs42l51 low level.
+ * @retval none
+ */
+static void cs42l51_lowlevel_init(void)
+{
+ rt_uint8_t temp = 0;
+
+ /* Initialized RESET IO */
+ rt_pin_mode(CS42L51_RESET_PIN, PIN_MODE_OUTPUT);
+
+ /* Power off the cs42l51 */
+ rt_pin_write(CS42L51_RESET_PIN, PIN_LOW);
+
+ /* wait until power supplies are stable */
+ rt_thread_mdelay(10);
+
+ /* Power on the cs42l51 */
+ rt_pin_write(CS42L51_RESET_PIN, PIN_HIGH);
+
+ /* Wait at least 500ns after reset */
+ rt_thread_mdelay(1);
+
+ /* Set the device in standby mode */
+ read_reg(audio_dev, CS42L51_POWER_CTL1, 1, &temp);
+ write_reg(audio_dev, CS42L51_POWER_CTL1, (temp | 0x01));
+
+ /* Set all power down bits to 1 */
+ write_reg(audio_dev, CS42L51_POWER_CTL1, 0x7F);
+ read_reg(audio_dev, CS42L51_MIC_POWER_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_MIC_POWER_CTL, (temp | 0x0E));
+}
+
+/**
+ * @brief Initializes CS42L51.
+ * @param Device: Audio type.
+ * @param bus_name I2C device name.
+ * @param volume: Initial output volume level (from 0 (-100dB) to 100 (0dB)).
+ * @retval 0 if correct communication, else wrong communication
+ */
+static rt_err_t cs42l51_init(uint16_t device, const char *bus_name, uint8_t volume)
+{
+ static uint8_t init_flag = 0;
+ rt_uint8_t temp = 0;
+ rt_uint8_t value = 0;
+
+ /* check if codec is already initialized */
+ if (init_flag == 0)
+ {
+ audio_dev = rt_i2c_bus_device_find(bus_name);
+
+ if (audio_dev == RT_NULL)
+ {
+ LOG_E("%s bus not found\n", bus_name);
+ return -RT_ERROR;
+ }
+ /* hard reset cs42l51 */
+ cs42l51_drv.reset();
+ /* Wait at least 500ns after reset */
+ rt_thread_mdelay(1);
+ /* Set the device in standby mode */
+ read_reg(audio_dev, CS42L51_POWER_CTL1, 1, &temp);
+ write_reg(audio_dev, CS42L51_POWER_CTL1, (temp | 0x01));
+ /* Set all power down bits to 1 */
+ write_reg(audio_dev, CS42L51_POWER_CTL1, 0x7F);
+ read_reg(audio_dev, CS42L51_MIC_POWER_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_MIC_POWER_CTL, (temp | 0x0E));
+
+ init_flag = 1;
+ }
+ else
+ {
+ /* Set all power down bits to 1 exept PDN to mute ADCs and DACs*/
+ write_reg(audio_dev, CS42L51_POWER_CTL1, 0x7E);
+ read_reg(audio_dev, CS42L51_MIC_POWER_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_MIC_POWER_CTL, (temp | 0x0E));
+ /* Disable zero cross and soft ramp */
+ read_reg(audio_dev, CS42L51_DAC_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_DAC_CTL, (temp & 0xFC));
+
+ /* Power control : Enter standby (PDN = 1) */
+ read_reg(audio_dev, CS42L51_POWER_CTL1, 1, &temp);
+ write_reg(audio_dev, CS42L51_POWER_CTL1, (temp | 0x01));
+ }
+ /* Mic Power and Speed Control : Auto detect on, Speed mode SSM, tri state off, MCLK divide by 2 off */
+ read_reg(audio_dev, CS42L51_MIC_POWER_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_MIC_POWER_CTL, ((temp & 0x0E) | 0xA0));
+ /* Interface control : Loopback off, Slave, I2S (SDIN and SOUT), Digital mix off, Mic mix off */
+ write_reg(audio_dev, CS42L51_INTF_CTL, 0x0C);
+ /* Mic control : ADC single volume off, ADCB boost off, ADCA boost off, MicBias on AIN3B/MICIN2 pin, MicBias level 0.8xVA, MICB boost 16db, MICA boost 16dB */
+ write_reg(audio_dev, CS42L51_MIC_CTL, 0x00);
+ /* ADC control : ADCB HPF off, ADCB HPF freeze off, ADCA HPF off, ADCA HPF freeze off, Soft ramp B off, Zero cross B off, Soft ramp A off, Zero cross A off */
+ write_reg(audio_dev, CS42L51_ADC_CTL, 0x00);
+ /* ADC Input Select, Invert and Mute : AIN1B to PGAB, AIN3A to PreAmp to PGAA, ADCB invert off, ADCA invert off, ADCB mute on, ADCA mute off */
+ write_reg(audio_dev, CS42L51_ADC_INPUT, 0x32);
+ /* DAC output control : HP Gain to 1, Single volume control off, PCM invert signals polarity off, DAC channels mute on */
+ write_reg(audio_dev, CS42L51_DAC_OUT_CTL, 0xC3);
+ /* DAC control : Signal processing to DAC, Freeze off, De-emphasis off, Analog output auto mute off, DAC soft ramp */
+ write_reg(audio_dev, CS42L51_DAC_CTL, 0x42);
+ /* ALCA and PGAA Control : ALCA soft ramp disable on, ALCA zero cross disable on, PGA A Gain 0dB */
+ write_reg(audio_dev, CS42L51_ALC_PGA_CTL, 0xC0);
+ /* ALCB and PGAB Control : ALCB soft ramp disable on, ALCB zero cross disable on, PGA B Gain 0dB */
+ write_reg(audio_dev, CS42L51_ALC_PGB_CTL, 0xC0);
+ /* ADCA Attenuator : 0dB */
+ write_reg(audio_dev, CS42L51_ADCA_ATT, 0x00);
+ /* ADCB Attenuator : 0dB */
+ write_reg(audio_dev, CS42L51_ADCB_ATT, 0x00);
+ /* ADCA mixer volume control : ADCA mixer channel mute on, ADCA mixer volume 0dB */
+ write_reg(audio_dev, CS42L51_ADCA_VOL, 0x80);
+ /* ADCB mixer volume control : ADCB mixer channel mute on, ADCB mixer volume 0dB */
+ write_reg(audio_dev, CS42L51_ADCB_VOL, 0x80);
+ /* PCMA mixer volume control : PCMA mixer channel mute off, PCMA mixer volume 0dB */
+ write_reg(audio_dev, CS42L51_PCMA_VOL, 0x00);
+ /* PCMB mixer volume control : PCMB mixer channel mute off, PCMB mixer volume 0dB */
+ write_reg(audio_dev, CS42L51_PCMB_VOL, 0x00);
+ /* PCM channel mixer : AOUTA Left, AOUTB Right */
+ write_reg(audio_dev, CS42L51_PCM_MIXER, 0x00);
+
+ if(device & OUT_HEADPHONE)
+ {
+ value = VOLUME_CONVERT(volume);
+ /* AOUTA volume control : AOUTA volume */
+ write_reg(audio_dev, CS42L51_AOUTA_VOL, value);
+ /* AOUTB volume control : AOUTB volume */
+ write_reg(audio_dev, CS42L51_AOUTB_VOL, value);
+ }
+
+ CS42L51_Device = device;
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Deinitialize the audio codec.
+ * @param None
+ * @retval None
+ */
+static void cs42l51_deinit(void)
+{
+ /* Deinitialize Audio Codec interface */
+ rt_uint8_t temp = 0;
+
+ /* Mute DAC and ADC */
+ read_reg(audio_dev, CS42L51_DAC_OUT_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_DAC_OUT_CTL, (temp | 0x03));
+ read_reg(audio_dev, CS42L51_ADC_INPUT, 1, &temp);
+ write_reg(audio_dev, CS42L51_ADC_INPUT, (temp | 0x03));
+
+ /* Disable soft ramp and zero cross */
+ read_reg(audio_dev, CS42L51_ADC_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_ADC_CTL, (temp & 0xF0));
+
+ /* Set PDN to 1 */
+ read_reg(audio_dev, CS42L51_POWER_CTL1, 1, &temp);
+ write_reg(audio_dev, CS42L51_POWER_CTL1, (temp | 0x01));
+
+ /* Set all power down bits to 1 */
+ write_reg(audio_dev, CS42L51_POWER_CTL1, 0x7F);
+ read_reg(audio_dev, CS42L51_MIC_POWER_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_MIC_POWER_CTL, (temp | 0x0E));
+
+ /* Power off CS42L51*/
+ rt_pin_write(CS42L51_RESET_PIN, PIN_LOW);
+}
+
+/**
+ * @brief Verify that we have a CS42L51.
+ * @retval 0 if correct communication, else wrong communication
+ */
+
+static uint32_t cs42l51_read_id(void)
+{
+ uint8_t temp;
+
+ /* read cs42l51 id */
+ read_reg(audio_dev, CS42L51_CHIP_REV_ID, 1, &temp);
+
+ if ((temp != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
+ (temp != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B)))
+ {
+ LOG_E("device id : 0x%02x", temp);
+ return RT_ERROR;
+ }
+
+ LOG_D("device id : 0x%02x", temp);
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Start the audio Codec play feature.
+ * @note For this codec no Play options are required.
+ * @retval 0 if correct communication, else wrong communication
+ */
+static uint32_t cs42l51_play(void)
+{
+ rt_uint8_t temp = 0;
+
+ switch (CS42L51_Device)
+ {
+ case OUT_HEADPHONE:
+ {
+ /* Unmute the output first */
+ cs42l51_drv.set_mute(AUDIO_MUTE_OFF);
+ /* DAC control : Signal processing to DAC, Freeze off, De-emphasis off, Analog output auto mute off, DAC soft ramp */
+ write_reg(audio_dev, CS42L51_DAC_CTL, 0x42);
+ /* Power control 1 : PDN_DACA, PDN_DACB disable. */
+ read_reg(audio_dev, CS42L51_POWER_CTL1, 1, &temp);
+ write_reg(audio_dev, CS42L51_POWER_CTL1, (temp & 0x9F));
+ break;
+ }
+
+ case IN_LINE1:
+ {
+ /* ADC Input Select, Invert and Mute : AIN1B to PGAB, AIN1A to PGAA, ADCB invert off, ADCA invert off, ADCB mute off, ADCA mute off */
+ write_reg(audio_dev, CS42L51_ADC_INPUT, 0x00);
+ /* Power control 1 : PDN_PGAA, PDN_PGAA, PDN_ADCB, PDN_ADCA disable. */
+ read_reg(audio_dev, CS42L51_POWER_CTL1, 1, &temp);
+ write_reg(audio_dev, CS42L51_POWER_CTL1, (temp & 0x9F));
+ break;
+ }
+
+ case IN_MIC1:
+ {
+ /* ADC Input Select, Invert and Mute : AIN1B to PGAB, AIN3A to PreAmp to PGAA, ADCB invert off, ADCA invert off, ADCB mute on, ADCA mute off */
+ write_reg(audio_dev, CS42L51_ADC_INPUT, 0x32);
+ /* Power control 1 : PDN_PGAA, PDN_ADCA disable. */
+ read_reg(audio_dev, CS42L51_POWER_CTL1, 1, &temp);
+ write_reg(audio_dev, CS42L51_POWER_CTL1, (temp & 0xF5));
+ /* Mic Power and Speed Control : PDN_MICA, PDN_MIC_BIAS disable. */
+ read_reg(audio_dev, CS42L51_MIC_POWER_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_MIC_POWER_CTL,(temp & 0xF9));
+ break;
+ }
+
+ case IN_MIC2:
+ {
+ /* Power control 1 : PDN_PGAB, PDN_ADCB disable. */
+ read_reg(audio_dev, CS42L51_POWER_CTL1, 1, &temp);
+ write_reg(audio_dev, CS42L51_POWER_CTL1, (temp & 0xEB));
+ /* Mic Power and Speed Control : PDN_MICB, PDN_MIC_BIAS disable. */
+ read_reg(audio_dev, CS42L51_MIC_POWER_CTL, 1, &temp);
+ write_reg(audio_dev, CS42L51_MIC_POWER_CTL,(temp & 0xF5));
+ break;
+ }
+
+ default:
+ LOG_D("error audio play mode!");
+ break;
+ }
+
+ /* Power control : Exit standby (PDN = 0) */
+ read_reg(audio_dev, CS42L51_POWER_CTL1, 1, &temp);
+ write_reg(audio_dev, CS42L51_POWER_CTL1, (temp & 0xFE));
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Pause playing on the audio codec.
+ * @param audio_dev: Device address on communication Bus.
+ * @retval 0 if correct communication, else wrong communication
+ */
+static uint32_t cs42l51_pause(void)
+{
+
+ /* Pause the audio file playing */
+ /* Mute the output first */
+ return cs42l51_drv.set_mute(AUDIO_MUTE_ON);
+
+}
+
+/**
+ * @brief Resume playing on the audio codec.
+ * @param audio_dev: Device address on communication Bus.
+ * @retval 0 if correct communication, else wrong communication
+ */
+static uint32_t cs42l51_resume(void)
+{
+ /* Unmute the output */
+ return cs42l51_drv.set_mute(AUDIO_MUTE_OFF);
+}
+
+/**
+ * @brief Stop audio Codec playing. It powers down the codec.
+ * @retval 0 if correct communication, else wrong communication
+ */
+static uint32_t cs42l51_stop(void)
+{
+ rt_uint8_t temp = 0;
+
+ /* Set all power down bits to 1 exept PDN to mute ADCs and DACs*/
+ write_reg(audio_dev, 0x02, 0x7E);
+ read_reg(audio_dev, 0x03, 1, &temp);
+ write_reg(audio_dev, 0x03, (temp | 0x0E));
+
+ /* Disable zero cross and soft ramp */
+ read_reg(audio_dev, 0x09, 1, &temp);
+ write_reg(audio_dev, 0x09, (temp & 0xFC));
+
+ /* Power control : Enter standby (PDN = 1) */
+ read_reg(audio_dev, 0x02, 1, &temp);
+ write_reg(audio_dev, 0x02, (temp | 0x01));
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Set new frequency.
+ * @param AudioFreq: Audio frequency used to play the audio stream.
+ * @retval 0 if correct communication, else wrong communication
+ */
+static uint32_t cs42l51_set_frequency(uint32_t AudioFreq)
+{
+ return RT_EOK;
+}
+
+/**
+ * @brief Set higher or lower the codec volume level.
+ * @param Volume: output volume level (from 0 (-100dB) to 100 (0dB)).
+ * @retval 0 if correct communication, else wrong communication
+ */
+static uint32_t cs42l51_set_volume(uint8_t Volume)
+{
+ uint8_t convertedvol = VOLUME_CONVERT(Volume);
+
+ /* AOUTA volume control : AOUTA volume */
+ write_reg(audio_dev, CS42L51_AOUTA_VOL, convertedvol);
+ /* AOUTB volume control : AOUTB volume */
+ write_reg(audio_dev, CS42L51_AOUTB_VOL, convertedvol);
+
+ return RT_EOK;
+}
+
+/**
+ * @brief get higher or lower the codec volume level.
+ * @retval value if correct communication
+ */
+static uint32_t cs42l51_get_volume(void)
+{
+ rt_uint8_t temp = 0;
+
+ /* AOUTA volume control : AOUTA volume */
+ read_reg(audio_dev, CS42L51_AOUTA_VOL, 1, &temp);
+
+ temp = VOLUME_INVERT(temp);
+
+ return temp;
+}
+
+/**
+* @brief Enable or disable the mute feature on the audio codec.
+* @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the
+* mute mode.
+* @retval 0 if correct communication, else wrong communication
+*/
+static uint32_t cs42l51_set_mute(uint32_t cmd)
+{
+ rt_uint8_t temp = 0;
+
+ /* Read DAC output control register */
+ read_reg(audio_dev, 0x08, 1, &temp);
+
+ /* Set the Mute mode */
+ if(cmd == AUDIO_MUTE_ON)
+ {
+ /* Mute DAC channels */
+ write_reg(audio_dev, CS42L51_DAC_OUT_CTL, (temp | 0x03));
+ }
+ else /* AUDIO_MUTE_OFF Disable the Mute */
+ {
+ /* Unmute DAC channels */
+ write_reg(audio_dev, CS42L51_DAC_OUT_CTL, (temp & 0xFC));
+ }
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Switch dynamically (while audio file is played) the output target
+ * (speaker, headphone, etc).
+ * @note This function is currently not used (only headphone output device).
+ * @param Output: specifies the audio output device target.
+ * @retval 0 if correct communication, else wrong communication
+ */
+static uint32_t cs42l51_set_output_mode(uint8_t Output)
+{
+ return RT_EOK;
+}
+
+/**
+ * @brief Reset CS42L51 registers.
+ * @retval 0 if correct communication, else wrong communication
+ */
+static uint32_t cs42l51_reset(void)
+{
+ cs42l51_lowlevel_deinit();
+
+ cs42l51_lowlevel_init();
+
+ return RT_EOK;
+}
+
+/* Audio codec driver structure initialization */
+AUDIO_DrvTypeDef cs42l51_drv =
+{
+ cs42l51_init,
+ cs42l51_deinit,
+ cs42l51_read_id,
+
+ cs42l51_play,
+ cs42l51_pause,
+ cs42l51_resume,
+ cs42l51_stop,
+
+ cs42l51_set_frequency,
+ cs42l51_set_volume,
+ cs42l51_get_volume,
+ cs42l51_set_mute,
+ cs42l51_set_output_mode,
+ cs42l51_reset,
+};
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_cs42l51.h b/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_cs42l51.h
new file mode 100644
index 0000000000..b3d7f78dca
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_cs42l51.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Date Author Notes
+ * 2020-07-02 thread-liu first version
+ */
+
+#ifndef __DRV_CS42L51_H__
+#define __DRV_CS42L51_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ rt_err_t (*init)(uint16_t , const char *, uint8_t);
+ void (*deinit)(void);
+ uint32_t (*read_id)(void);
+ uint32_t (*play)(void);
+ uint32_t (*pause)(void);
+ uint32_t (*resume)(void);
+ uint32_t (*stop)(void);
+ uint32_t (*set_frequency)(uint32_t);
+ uint32_t (*set_volume)(uint8_t);
+ uint32_t (*get_volume)(void);
+ uint32_t (*set_mute)(uint32_t);
+ uint32_t (*set_output_mode)(uint8_t);
+ uint32_t (*reset)(void);
+}AUDIO_DrvTypeDef;
+
+extern AUDIO_DrvTypeDef cs42l51_drv;
+
+/* CS42L51 register space */
+#define CS42L51_CHIP_ID 0x1B
+#define CS42L51_CHIP_REV_A 0x00
+#define CS42L51_CHIP_REV_B 0x01
+
+#define CS42L51_CHIP_REV_ID 0x01
+#define CS42L51_MK_CHIP_REV(a, b) ((a)<<3|(b))
+
+#define CS42L51_POWER_CTL1 0x02
+#define CS42L51_POWER_CTL1_PDN_DACB (1<<6)
+#define CS42L51_POWER_CTL1_PDN_DACA (1<<5)
+#define CS42L51_POWER_CTL1_PDN_PGAB (1<<4)
+#define CS42L51_POWER_CTL1_PDN_PGAA (1<<3)
+#define CS42L51_POWER_CTL1_PDN_ADCB (1<<2)
+#define CS42L51_POWER_CTL1_PDN_ADCA (1<<1)
+#define CS42L51_POWER_CTL1_PDN (1<<0)
+
+#define CS42L51_MIC_POWER_CTL 0x03
+#define CS42L51_MIC_POWER_CTL_AUTO (1<<7)
+#define CS42L51_MIC_POWER_CTL_SPEED(x) (((x)&3)<<5)
+#define CS42L51_QSM_MODE 3
+#define CS42L51_HSM_MODE 2
+#define CS42L51_SSM_MODE 1
+#define CS42L51_DSM_MODE 0
+#define CS42L51_MIC_POWER_CTL_3ST_SP (1<<4)
+#define CS42L51_MIC_POWER_CTL_PDN_MICB (1<<3)
+#define CS42L51_MIC_POWER_CTL_PDN_MICA (1<<2)
+#define CS42L51_MIC_POWER_CTL_PDN_BIAS (1<<1)
+#define CS42L51_MIC_POWER_CTL_MCLK_DIV2 (1<<0)
+
+#define CS42L51_INTF_CTL 0x04
+#define CS42L51_INTF_CTL_LOOPBACK (1<<7)
+#define CS42L51_INTF_CTL_MASTER (1<<6)
+#define CS42L51_INTF_CTL_DAC_FORMAT(x) (((x)&7)<<3)
+#define CS42L51_DAC_DIF_LJ24 0x00
+#define CS42L51_DAC_DIF_I2S 0x01
+#define CS42L51_DAC_DIF_RJ24 0x02
+#define CS42L51_DAC_DIF_RJ20 0x03
+#define CS42L51_DAC_DIF_RJ18 0x04
+#define CS42L51_DAC_DIF_RJ16 0x05
+#define CS42L51_INTF_CTL_ADC_I2S (1<<2)
+#define CS42L51_INTF_CTL_DIGMIX (1<<1)
+#define CS42L51_INTF_CTL_MICMIX (1<<0)
+
+#define CS42L51_MIC_CTL 0x05
+#define CS42L51_MIC_CTL_ADC_SNGVOL (1<<7)
+#define CS42L51_MIC_CTL_ADCD_DBOOST (1<<6)
+#define CS42L51_MIC_CTL_ADCA_DBOOST (1<<5)
+#define CS42L51_MIC_CTL_MICBIAS_SEL (1<<4)
+#define CS42L51_MIC_CTL_MICBIAS_LVL(x) (((x)&3)<<2)
+#define CS42L51_MIC_CTL_MICB_BOOST (1<<1)
+#define CS42L51_MIC_CTL_MICA_BOOST (1<<0)
+
+#define CS42L51_ADC_CTL 0x06
+#define CS42L51_ADC_CTL_ADCB_HPFEN (1<<7)
+#define CS42L51_ADC_CTL_ADCB_HPFRZ (1<<6)
+#define CS42L51_ADC_CTL_ADCA_HPFEN (1<<5)
+#define CS42L51_ADC_CTL_ADCA_HPFRZ (1<<4)
+#define CS42L51_ADC_CTL_SOFTB (1<<3)
+#define CS42L51_ADC_CTL_ZCROSSB (1<<2)
+#define CS42L51_ADC_CTL_SOFTA (1<<1)
+#define CS42L51_ADC_CTL_ZCROSSA (1<<0)
+
+#define CS42L51_ADC_INPUT 0x07
+#define CS42L51_ADC_INPUT_AINB_MUX(x) (((x)&3)<<6)
+#define CS42L51_ADC_INPUT_AINA_MUX(x) (((x)&3)<<4)
+#define CS42L51_ADC_INPUT_INV_ADCB (1<<3)
+#define CS42L51_ADC_INPUT_INV_ADCA (1<<2)
+#define CS42L51_ADC_INPUT_ADCB_MUTE (1<<1)
+#define CS42L51_ADC_INPUT_ADCA_MUTE (1<<0)
+
+#define CS42L51_DAC_OUT_CTL 0x08
+#define CS42L51_DAC_OUT_CTL_HP_GAIN(x) (((x)&7)<<5)
+#define CS42L51_DAC_OUT_CTL_DAC_SNGVOL (1<<4)
+#define CS42L51_DAC_OUT_CTL_INV_PCMB (1<<3)
+#define CS42L51_DAC_OUT_CTL_INV_PCMA (1<<2)
+#define CS42L51_DAC_OUT_CTL_DACB_MUTE (1<<1)
+#define CS42L51_DAC_OUT_CTL_DACA_MUTE (1<<0)
+
+#define CS42L51_DAC_CTL 0x09
+#define CS42L51_DAC_CTL_DATA_SEL(x) (((x)&3)<<6)
+#define CS42L51_DAC_CTL_FREEZE (1<<5)
+#define CS42L51_DAC_CTL_DEEMPH (1<<3)
+#define CS42L51_DAC_CTL_AMUTE (1<<2)
+#define CS42L51_DAC_CTL_DACSZ(x) (((x)&3)<<0)
+
+#define CS42L51_ALC_PGA_CTL 0x0A
+#define CS42L51_ALC_PGB_CTL 0x0B
+#define CS42L51_ALC_PGX_ALCX_SRDIS (1<<7)
+#define CS42L51_ALC_PGX_ALCX_ZCDIS (1<<6)
+#define CS42L51_ALC_PGX_PGX_VOL(x) (((x)&0x1f)<<0)
+
+#define CS42L51_ADCA_ATT 0x0C
+#define CS42L51_ADCB_ATT 0x0D
+
+#define CS42L51_ADCA_VOL 0x0E
+#define CS42L51_ADCB_VOL 0x0F
+#define CS42L51_PCMA_VOL 0x10
+#define CS42L51_PCMB_VOL 0x11
+#define CS42L51_MIX_MUTE_ADCMIX (1<<7)
+#define CS42L51_MIX_VOLUME(x) (((x)&0x7f)<<0)
+
+#define CS42L51_BEEP_FREQ 0x12
+#define CS42L51_BEEP_VOL 0x13
+#define CS42L51_BEEP_CONF 0x14
+
+#define CS42L51_TONE_CTL 0x15
+#define CS42L51_TONE_CTL_TREB(x) (((x)&0xf)<<4)
+#define CS42L51_TONE_CTL_BASS(x) (((x)&0xf)<<0)
+
+#define CS42L51_AOUTA_VOL 0x16
+#define CS42L51_AOUTB_VOL 0x17
+#define CS42L51_PCM_MIXER 0x18
+#define CS42L51_LIMIT_THRES_DIS 0x19
+#define CS42L51_LIMIT_REL 0x1A
+#define CS42L51_LIMIT_ATT 0x1B
+#define CS42L51_ALC_EN 0x1C
+#define CS42L51_ALC_REL 0x1D
+#define CS42L51_ALC_THRES 0x1E
+#define CS42L51_NOISE_CONF 0x1F
+
+#define CS42L51_STATUS 0x20
+#define CS42L51_STATUS_SP_CLKERR (1<<6)
+#define CS42L51_STATUS_SPEA_OVFL (1<<5)
+#define CS42L51_STATUS_SPEB_OVFL (1<<4)
+#define CS42L51_STATUS_PCMA_OVFL (1<<3)
+#define CS42L51_STATUS_PCMB_OVFL (1<<2)
+#define CS42L51_STATUS_ADCA_OVFL (1<<1)
+#define CS42L51_STATUS_ADCB_OVFL (1<<0)
+
+#define CS42L51_CHARGE_FREQ 0x21
+#define CS42L51_FIRSTREG 0x01
+
+enum play_type {
+ NONE,
+ OUT_HEADPHONE,
+ IN_MIC1,
+ IN_MIC2,
+ IN_LINE1,
+ IN_LINE2,
+ IN_LINE3,
+};
+
+/*
+ * Hack: with register 0x21, it makes 33 registers. Looks like someone in the
+ * i2c layer doesn't like i2c smbus block read of 33 regs. Workaround by using
+ * 32 regs
+ */
+#define CS42L51_LASTREG 0x20
+#define CS42L51_NUMREGS (CS42L51_LASTREG - CS42L51_FIRSTREG + 1)
+
+#define VOLUME_CONVERT(Volume) ((Volume >= 100) ? 0 : ((uint8_t)(((Volume * 2) + 56))))
+#define VOLUME_INVERT(Volume) (((Volume) == 0U) ? 100U : ((uint8_t)(((Volume) - 56U) / 2U)))
+
+/* MUTE commands */
+#define AUDIO_MUTE_ON 1
+#define AUDIO_MUTE_OFF 0
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_mic.c b/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_mic.c
new file mode 100644
index 0000000000..20e98d4826
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_mic.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-07-31 Zero-Free first implementation
+ * 2020-07-02 thread-liu Porting for STM32MP1
+ */
+
+#include <board.h>
+
+#if defined(BSP_USING_AUDIO_RECORD)
+
+#include "drv_cs42l51.h"
+
+//#define DRV_DEBUG
+#define DBG_TAG "drv.audio"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#define MIC_BUS_NAME "i2c4"
+
+/* SYSRAM */
+#define RX_FIFO_SIZE (4096)
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+rt_uint8_t MIC_RX_FIFO[RX_FIFO_SIZE] __attribute__((at(0x2FFC2000)));
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFC2000
+rt_uint8_t MIC_RX_FIFO[RX_FIFO_SIZE];
+#elif defined ( __GNUC__ )
+rt_uint8_t MIC_RX_FIFO[RX_FIFO_SIZE] __attribute__((at(0x2FFC2000)));
+#endif
+
+struct mic_device
+{
+ struct rt_audio_device audio;
+ struct rt_audio_configure record_config;
+ rt_uint8_t *rx_fifo;
+ rt_uint8_t volume;
+};
+
+static struct mic_device mic_dev = {0};
+static rt_uint16_t zero_frame[2] = {0};
+
+extern SAI_HandleTypeDef hsai_BlockA2;
+extern DMA_HandleTypeDef hdma_sai2_a;
+extern SAI_HandleTypeDef hsai_BlockB2;
+extern DMA_HandleTypeDef hdma_sai2_b;
+extern void SAIA_Frequency_Set(uint32_t frequency);
+
+void SAIB_Init(void)
+{
+ HAL_SAI_DeInit(&hsai_BlockB2);
+
+ hsai_BlockB2.Instance = SAI2_Block_B;
+ hsai_BlockB2.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;
+ hsai_BlockB2.Init.AudioMode = SAI_MODESLAVE_RX;
+ hsai_BlockB2.Init.Synchro = SAI_SYNCHRONOUS;
+ hsai_BlockB2.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
+ hsai_BlockB2.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+ hsai_BlockB2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
+ hsai_BlockB2.Init.Mckdiv = 0;
+ hsai_BlockB2.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
+ hsai_BlockB2.Init.MonoStereoMode = SAI_STEREOMODE;
+ hsai_BlockB2.Init.CompandingMode = SAI_NOCOMPANDING;
+ hsai_BlockB2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
+ hsai_BlockB2.Init.PdmInit.Activation = DISABLE;
+ hsai_BlockB2.Init.PdmInit.MicPairsNbr = 1;
+ hsai_BlockB2.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
+ hsai_BlockB2.Init.Protocol = SAI_FREE_PROTOCOL;
+ hsai_BlockB2.Init.DataSize = SAI_DATASIZE_16;
+ hsai_BlockB2.Init.FirstBit = SAI_FIRSTBIT_MSB;
+ hsai_BlockB2.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
+
+ hsai_BlockB2.FrameInit.FrameLength = 64;
+ hsai_BlockB2.FrameInit.ActiveFrameLength = 32;
+ hsai_BlockB2.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+ hsai_BlockB2.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+ hsai_BlockB2.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+
+ hsai_BlockB2.SlotInit.FirstBitOffset = 0;
+ hsai_BlockB2.SlotInit.SlotSize = SAI_SLOTSIZE_32B;
+ hsai_BlockB2.SlotInit.SlotNumber = 2;
+ hsai_BlockB2.SlotInit.SlotActive = SAI_SLOTACTIVE_0|SAI_SLOTACTIVE_1;
+
+ /* DeInit SAI PDM input */
+ HAL_SAI_DeInit(&hsai_BlockB2);
+
+ /* Init SAI PDM input */
+ if(HAL_OK != HAL_SAI_Init(&hsai_BlockB2))
+ {
+ Error_Handler();
+ }
+
+ /* Enable SAI to generate clock used by audio driver */
+ __HAL_SAI_ENABLE(&hsai_BlockB2);
+}
+
+void SAIB_Channels_Set(uint8_t channels)
+{
+ if (channels == 1)
+ {
+ hsai_BlockB2.Init.MonoStereoMode = SAI_MONOMODE;
+ }
+ else
+ {
+ hsai_BlockB2.Init.MonoStereoMode = SAI_STEREOMODE;
+ }
+
+ __HAL_SAI_DISABLE(&hsai_BlockB2);
+ HAL_SAI_Init(&hsai_BlockB2);
+ __HAL_SAI_ENABLE(&hsai_BlockB2);
+}
+
+void DMA2_Stream4_IRQHandler(void)
+{
+ HAL_DMA_IRQHandler(&hdma_sai2_b);
+}
+
+void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ rt_audio_rx_done(&mic_dev.audio, &mic_dev.rx_fifo[0], RX_FIFO_SIZE / 2);
+}
+
+void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ rt_audio_rx_done(&mic_dev.audio, &mic_dev.rx_fifo[RX_FIFO_SIZE / 2], RX_FIFO_SIZE / 2);
+}
+
+static rt_err_t mic_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+ rt_err_t result = RT_EOK;
+ struct mic_device *mic_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ mic_dev = (struct mic_device *)audio->parent.user_data;
+
+ switch (caps->main_type)
+ {
+ case AUDIO_TYPE_QUERY: /* qurey the types of hw_codec device */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_TYPE_QUERY:
+ caps->udata.mask = AUDIO_TYPE_INPUT | AUDIO_TYPE_MIXER;
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_INPUT: /* Provide capabilities of INPUT unit */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_DSP_PARAM:
+ caps->udata.config.samplerate = mic_dev->record_config.samplerate;
+ caps->udata.config.channels = mic_dev->record_config.channels;
+ caps->udata.config.samplebits = mic_dev->record_config.samplebits;
+ break;
+
+ case AUDIO_DSP_SAMPLERATE:
+ caps->udata.config.samplerate = mic_dev->record_config.samplerate;
+ break;
+
+ case AUDIO_DSP_CHANNELS:
+ caps->udata.config.channels = mic_dev->record_config.channels;
+ break;
+
+ case AUDIO_DSP_SAMPLEBITS:
+ caps->udata.config.samplebits = mic_dev->record_config.samplebits;
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_MIXER: /* report the Mixer Units */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_MIXER_QUERY:
+ caps->udata.mask = AUDIO_MIXER_VOLUME | AUDIO_MIXER_LINE;
+ break;
+
+ case AUDIO_MIXER_VOLUME:
+ caps->udata.value = mic_dev->volume;
+ break;
+
+ case AUDIO_MIXER_LINE:
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ return result;
+}
+
+static rt_err_t mic_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+ rt_err_t result = RT_EOK;
+ struct mic_device *mic_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ mic_dev = (struct mic_device *)audio->parent.user_data;
+
+ switch (caps->main_type)
+ {
+ case AUDIO_TYPE_MIXER:
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_MIXER_VOLUME:
+ {
+ rt_uint32_t volume = caps->udata.value;
+ mic_dev->volume = volume;
+ LOG_D("set volume %d", volume);
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_INPUT:
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_DSP_PARAM:
+ {
+ SAIA_Frequency_Set(caps->udata.config.samplerate);
+ HAL_SAI_DMAStop(&hsai_BlockB2);
+ SAIB_Channels_Set(caps->udata.config.channels);
+ HAL_SAI_Transmit(&hsai_BlockA2, (uint8_t *)&zero_frame[0], 2, 0);
+ HAL_SAI_Receive_DMA(&hsai_BlockB2, mic_dev->rx_fifo, RX_FIFO_SIZE / 2);
+
+ /* save configs */
+ mic_dev->record_config.samplerate = caps->udata.config.samplerate;
+ mic_dev->record_config.channels = caps->udata.config.channels;
+ mic_dev->record_config.samplebits = caps->udata.config.samplebits;
+ LOG_D("set samplerate %d", mic_dev->record_config.samplerate);
+ LOG_D("set channels %d", mic_dev->record_config.channels);
+ break;
+ }
+
+ case AUDIO_DSP_SAMPLERATE:
+ {
+ mic_dev->record_config.samplerate = caps->udata.config.samplerate;
+ LOG_D("set channels %d", mic_dev->record_config.channels);
+ break;
+ }
+
+ case AUDIO_DSP_CHANNELS:
+ {
+ mic_dev->record_config.channels = caps->udata.config.channels;
+ LOG_D("set channels %d", mic_dev->record_config.channels);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static rt_err_t mic_init(struct rt_audio_device *audio)
+{
+ struct mic_device *mic_dev;
+ RT_ASSERT(audio != RT_NULL);
+
+ mic_dev = (struct mic_device *)audio->parent.user_data;
+ SAIB_Init();
+ /* set default params */
+ SAIB_Channels_Set(mic_dev->record_config.channels);
+
+ return RT_EOK;
+}
+
+static rt_err_t mic_start(struct rt_audio_device *audio, int stream)
+{
+ struct mic_device *mic_dev;
+ RT_ASSERT(audio != RT_NULL);
+
+ mic_dev = (struct mic_device *)audio->parent.user_data;
+ if (stream == AUDIO_STREAM_RECORD)
+ {
+ cs42l51_drv.init(IN_MIC1, MIC_BUS_NAME, 40);
+ /* open receive */
+ if (HAL_SAI_Receive_DMA(&hsai_BlockB2, mic_dev->rx_fifo, RX_FIFO_SIZE / 2) != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+ /* supply clk */
+ HAL_SAI_Transmit(&hsai_BlockA2, (uint8_t *)&zero_frame[0], 2, 0);
+
+ cs42l51_drv.play();
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t mic_stop(struct rt_audio_device *audio, int stream)
+{
+ if (stream == AUDIO_STREAM_RECORD)
+ {
+ HAL_SAI_DMAStop(&hsai_BlockB2);
+ HAL_SAI_Abort(&hsai_BlockB2);
+ cs42l51_drv.stop();
+ }
+
+ return RT_EOK;
+}
+
+static struct rt_audio_ops mic_ops =
+{
+ .getcaps = mic_getcaps,
+ .configure = mic_configure,
+ .init = mic_init,
+ .start = mic_start,
+ .stop = mic_stop,
+ .transmit = RT_NULL,
+ .buffer_info = RT_NULL,
+};
+
+int rt_hw_mic_init(void)
+{
+ rt_err_t result = RT_EOK;
+ struct rt_device *device;
+
+ rt_memset(MIC_RX_FIFO, 0, RX_FIFO_SIZE);
+ mic_dev.rx_fifo = MIC_RX_FIFO;
+
+ /* init default configuration */
+ {
+ mic_dev.record_config.samplerate = 44100;
+ mic_dev.record_config.channels = 2;
+ mic_dev.record_config.samplebits = 16;
+ mic_dev.volume = 55;
+ }
+
+ /* register sound device */
+ mic_dev.audio.ops = &mic_ops;
+ result = rt_audio_register(&mic_dev.audio, "mic0", RT_DEVICE_FLAG_RDONLY, &mic_dev);
+
+ if (result != RT_EOK)
+ {
+ device = &(mic_dev.audio.parent);
+ rt_device_unregister(device);
+ LOG_E("mic device init error!");
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+INIT_DEVICE_EXPORT(rt_hw_mic_init);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_sound.c b/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_sound.c
new file mode 100644
index 0000000000..5d94bfc399
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/audio/drv_sound.c
@@ -0,0 +1,603 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-07-31 Zero-Free first implementation
+ * 2020-07-02 thread-liu Porting for STM32MP1
+ */
+
+#include "board.h"
+#include "drv_cs42l51.h"
+
+#ifdef BSP_USING_AUDIO
+
+//#define DRV_DEBUG
+#define LOG_TAG "drv.audio"
+#include <drv_log.h>
+
+#define SOUND_BUS_NAME "i2c4"
+
+/* SYSRAM */
+#define TX_FIFO_SIZE (4096)
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+rt_uint8_t AUDIO_TX_FIFO[TX_FIFO_SIZE] __attribute__((at(0x2FFC3000)));
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFC3000
+rt_uint8_t AUDIO_TX_FIFO[TX_FIFO_SIZE];
+#elif defined ( __GNUC__ )
+rt_uint8_t AUDIO_TX_FIFO[TX_FIFO_SIZE] __attribute__((at(0x2FFC3000)));
+#endif
+
+struct sound_device
+{
+ struct rt_audio_device audio;
+ struct rt_audio_configure replay_config;
+ rt_uint8_t *tx_fifo;
+ rt_uint8_t volume;
+};
+
+static struct sound_device snd_dev = {0};
+
+SAI_HandleTypeDef hsai_BlockA2 = {0};
+DMA_HandleTypeDef hdma_sai2_a = {0};
+SAI_HandleTypeDef hsai_BlockB2 = {0};
+DMA_HandleTypeDef hdma_sai2_b = {0};
+
+void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
+{
+
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+ /* SAI2 */
+ if(hsai->Instance==SAI2_Block_A)
+ {
+ /* Peripheral clock enable */
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
+ PeriphClkInit.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLL3_Q;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOI_CLK_ENABLE();
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_SAI2_CLK_ENABLE();
+
+ /**SAI2_A_Block_A GPIO Configuration
+ PE0 ------> SAI2_MCLK_A
+ PI7 ------> SAI2_FS_A
+ PI5 ------> SAI2_SCK_A
+ PI6 ------> SAI2_SD_A
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_0;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_5|GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
+ HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
+
+ /* Configure DMA used for SAI2 */
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+ __HAL_RCC_DMA2_CLK_ENABLE();
+
+ hdma_sai2_a.Instance = DMA2_Stream5;
+ hdma_sai2_a.Init.Request = DMA_REQUEST_SAI2_A;
+ hdma_sai2_a.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_sai2_a.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai2_a.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai2_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+ hdma_sai2_a.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+ hdma_sai2_a.Init.Mode = DMA_CIRCULAR;
+ hdma_sai2_a.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai2_a.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+
+ HAL_DMA_DeInit(&hdma_sai2_a);
+ if (HAL_DMA_Init(&hdma_sai2_a) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ __HAL_LINKDMA(hsai,hdmatx,hdma_sai2_a);
+ __HAL_DMA_ENABLE(&hdma_sai2_a);
+ HAL_NVIC_SetPriority(DMA2_Stream5_IRQn, 2, 0);
+ HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);
+ }
+
+ if(hsai->Instance==SAI2_Block_B)
+ {
+ /* Peripheral clock enable */
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
+ PeriphClkInit.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLL3_Q;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ }
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_SAI2_CLK_ENABLE();
+
+ /**SAI2_B_Block_B GPIO Configuration
+ PF11 ------> SAI2_SD_B
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_11;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+ __HAL_RCC_DMA2_CLK_ENABLE();
+
+ /* Peripheral DMA init*/
+ hdma_sai2_b.Instance = DMA2_Stream4;
+ hdma_sai2_b.Init.Request = DMA_REQUEST_SAI2_B;
+ hdma_sai2_b.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_sai2_b.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai2_b.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai2_b.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+ hdma_sai2_b.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+ hdma_sai2_b.Init.Mode = DMA_CIRCULAR;
+ hdma_sai2_b.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai2_b.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ hdma_sai2_b.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_sai2_b.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_sai2_b.Init.PeriphBurst = DMA_PBURST_SINGLE;
+ __HAL_LINKDMA(hsai,hdmarx,hdma_sai2_b);
+ HAL_DMA_DeInit(&hdma_sai2_b);
+ if (HAL_DMA_Init(&hdma_sai2_b) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ __HAL_LINKDMA(hsai,hdmarx,hdma_sai2_b);
+ __HAL_DMA_ENABLE(&hdma_sai2_b);
+ HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 2, 0);
+ HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);
+ }
+}
+
+void HAL_SAI_MspDeInit(SAI_HandleTypeDef* hsai)
+{
+ /* SAI2 */
+ if(hsai->Instance==SAI2_Block_A)
+ {
+
+ /* Peripheral clock disable */
+ __HAL_RCC_SAI2_CLK_DISABLE();
+
+ /**SAI2_A_Block_A GPIO Configuration
+ PE0 ------> SAI2_MCLK_A
+ PI7 ------> SAI2_FS_A
+ PI5 ------> SAI2_SCK_A
+ PI6 ------> SAI2_SD_A
+ */
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_0);
+
+ HAL_GPIO_DeInit(GPIOI, GPIO_PIN_7|GPIO_PIN_5|GPIO_PIN_6);
+
+ HAL_DMA_DeInit(hsai->hdmarx);
+ HAL_DMA_DeInit(hsai->hdmatx);
+ }
+
+ if(hsai->Instance==SAI2_Block_B)
+ {
+ /* Peripheral clock disable */
+ __HAL_RCC_SAI2_CLK_DISABLE();
+
+ /**SAI2_B_Block_B GPIO Configuration
+ PF11 ------> SAI2_SD_B
+ */
+ HAL_GPIO_DeInit(GPIOF, GPIO_PIN_11);
+
+ HAL_DMA_DeInit(hsai->hdmarx);
+ HAL_DMA_DeInit(hsai->hdmatx);
+ }
+}
+
+static void rt_hw_sai2a_init(void)
+{
+ HAL_SAI_DeInit(&hsai_BlockA2);
+ hsai_BlockA2.Instance = SAI2_Block_A;
+ hsai_BlockA2.Init.Protocol = SAI_FREE_PROTOCOL;
+ hsai_BlockA2.Init.AudioMode = SAI_MODEMASTER_TX;
+ hsai_BlockA2.Init.DataSize = SAI_DATASIZE_16;
+ hsai_BlockA2.Init.FirstBit = SAI_FIRSTBIT_MSB;
+ hsai_BlockA2.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
+ hsai_BlockA2.Init.Synchro = SAI_ASYNCHRONOUS;
+ hsai_BlockA2.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
+ hsai_BlockA2.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+ hsai_BlockA2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
+ hsai_BlockA2.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;
+ hsai_BlockA2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
+ hsai_BlockA2.Init.MonoStereoMode = SAI_STEREOMODE;
+ hsai_BlockA2.Init.CompandingMode = SAI_NOCOMPANDING;
+ hsai_BlockA2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
+ hsai_BlockA2.Init.PdmInit.Activation = DISABLE;
+ hsai_BlockA2.Init.PdmInit.MicPairsNbr = 0;
+ hsai_BlockA2.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
+
+ hsai_BlockA2.FrameInit.FrameLength = 64;
+ hsai_BlockA2.FrameInit.ActiveFrameLength = 32;
+ hsai_BlockA2.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+ hsai_BlockA2.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+ hsai_BlockA2.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+
+ hsai_BlockA2.SlotInit.FirstBitOffset = 0;
+ hsai_BlockA2.SlotInit.SlotSize = SAI_SLOTSIZE_32B;
+ hsai_BlockA2.SlotInit.SlotNumber = 2;
+ hsai_BlockA2.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
+
+ if(HAL_OK != HAL_SAI_Init(&hsai_BlockA2))
+ {
+ Error_Handler();
+ }
+ /* Enable SAI to generate clock used by audio driver */
+ __HAL_SAI_ENABLE(&hsai_BlockA2);
+}
+
+void DMA2_Stream5_IRQHandler(void)
+{
+ HAL_DMA_IRQHandler(&hdma_sai2_a);
+}
+
+void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ if (hsai == &hsai_BlockA2)
+ {
+ rt_audio_tx_complete(&snd_dev.audio);
+ }
+}
+
+void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ if (hsai == &hsai_BlockA2)
+ {
+ rt_audio_tx_complete(&snd_dev.audio);
+ }
+}
+
+void SAIA_Frequency_Set(uint32_t frequency)
+{
+ return;
+}
+
+void SAIA_Channels_Set(uint8_t channels)
+{
+ if (channels == 1)
+ {
+ hsai_BlockA2.Init.MonoStereoMode = SAI_MONOMODE;
+ }
+ else
+ {
+ hsai_BlockA2.Init.MonoStereoMode = SAI_STEREOMODE;
+ }
+
+ __HAL_SAI_DISABLE(&hsai_BlockA2);
+ HAL_SAI_Init(&hsai_BlockA2);
+ __HAL_SAI_ENABLE(&hsai_BlockA2);
+}
+
+/**
+ * RT-Thread Audio Device Driver Interface
+ */
+static rt_err_t sound_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+ rt_err_t result = RT_EOK;
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ switch (caps->main_type)
+ {
+ case AUDIO_TYPE_QUERY: /* qurey the types of hw_codec device */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_TYPE_QUERY:
+ caps->udata.mask = AUDIO_TYPE_OUTPUT | AUDIO_TYPE_MIXER;
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_OUTPUT: /* Provide capabilities of OUTPUT unit */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_DSP_PARAM:
+ caps->udata.config.samplerate = snd_dev->replay_config.samplerate;
+ caps->udata.config.channels = snd_dev->replay_config.channels;
+ caps->udata.config.samplebits = snd_dev->replay_config.samplebits;
+ break;
+
+ case AUDIO_DSP_SAMPLERATE:
+ caps->udata.config.samplerate = snd_dev->replay_config.samplerate;
+ break;
+
+ case AUDIO_DSP_CHANNELS:
+ caps->udata.config.channels = snd_dev->replay_config.channels;
+ break;
+
+ case AUDIO_DSP_SAMPLEBITS:
+ caps->udata.config.samplebits = snd_dev->replay_config.samplebits;
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_MIXER: /* report the Mixer Units */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_MIXER_QUERY:
+ caps->udata.mask = AUDIO_MIXER_VOLUME;
+ break;
+
+ case AUDIO_MIXER_VOLUME:
+ caps->udata.value = cs42l51_drv.get_volume();
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ return result;
+}
+
+static rt_err_t sound_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+ rt_err_t result = RT_EOK;
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ switch (caps->main_type)
+ {
+ case AUDIO_TYPE_MIXER:
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_MIXER_VOLUME:
+ {
+ rt_uint8_t volume = caps->udata.value;
+
+ cs42l51_drv.set_volume(volume);
+
+ snd_dev->volume = volume;
+
+ LOG_D("set volume %d", volume);
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_OUTPUT:
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_DSP_PARAM:
+ {
+ /* set samplerate */
+ SAIA_Frequency_Set(caps->udata.config.samplerate);
+ /* set channels */
+ SAIA_Channels_Set(caps->udata.config.channels);
+
+ /* save configs */
+ snd_dev->replay_config.samplerate = caps->udata.config.samplerate;
+ snd_dev->replay_config.channels = caps->udata.config.channels;
+ snd_dev->replay_config.samplebits = caps->udata.config.samplebits;
+ LOG_D("set samplerate %d", snd_dev->replay_config.samplerate);
+ break;
+ }
+
+ case AUDIO_DSP_SAMPLERATE:
+ {
+ SAIA_Frequency_Set(caps->udata.config.samplerate);
+ snd_dev->replay_config.samplerate = caps->udata.config.samplerate;
+ LOG_D("set samplerate %d", snd_dev->replay_config.samplerate);
+ break;
+ }
+
+ case AUDIO_DSP_CHANNELS:
+ {
+ SAIA_Channels_Set(caps->udata.config.channels);
+ snd_dev->replay_config.channels = caps->udata.config.channels;
+ LOG_D("set channels %d", snd_dev->replay_config.channels);
+ break;
+ }
+
+ case AUDIO_DSP_SAMPLEBITS:
+ {
+ /* not support */
+ snd_dev->replay_config.samplebits = caps->udata.config.samplebits;
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static rt_err_t sound_init(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ cs42l51_drv.init(OUT_HEADPHONE, SOUND_BUS_NAME, 40);
+
+ if (cs42l51_drv.read_id() != RT_EOK)
+ {
+ LOG_E("can't find low level audio device!");
+ return RT_ERROR;
+ }
+
+ rt_hw_sai2a_init();
+
+ /* set default params */
+ SAIA_Frequency_Set(snd_dev->replay_config.samplerate);
+ SAIA_Channels_Set(snd_dev->replay_config.channels);
+
+ return result;
+}
+
+static rt_err_t sound_start(struct rt_audio_device *audio, int stream)
+{
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ if (stream == AUDIO_STREAM_REPLAY)
+ {
+ LOG_D("open sound device");
+
+ cs42l51_drv.init(OUT_HEADPHONE, SOUND_BUS_NAME, 60); /* set work mode */
+ cs42l51_drv.play();
+
+ if (HAL_SAI_Transmit_DMA(&hsai_BlockA2, snd_dev->tx_fifo, TX_FIFO_SIZE / 2) != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t sound_stop(struct rt_audio_device *audio, int stream)
+{
+ RT_ASSERT(audio != RT_NULL);
+
+ if (stream == AUDIO_STREAM_REPLAY)
+ {
+ HAL_SAI_DMAStop(&hsai_BlockA2);
+ HAL_SAI_Abort(&hsai_BlockA2);
+ cs42l51_drv.stop();
+
+ LOG_D("close sound device");
+ }
+
+ return RT_EOK;
+}
+
+static void sound_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info)
+{
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ /**
+ * TX_FIFO
+ * +----------------+----------------+
+ * | block1 | block2 |
+ * +----------------+----------------+
+ * \ block_size /
+ */
+ info->buffer = snd_dev->tx_fifo;
+ info->total_size = TX_FIFO_SIZE;
+ info->block_size = TX_FIFO_SIZE / 2;
+ info->block_count = 2;
+}
+
+static struct rt_audio_ops snd_ops =
+{
+ .getcaps = sound_getcaps,
+ .configure = sound_configure,
+ .init = sound_init,
+ .start = sound_start,
+ .stop = sound_stop,
+ .transmit = RT_NULL,
+ .buffer_info = sound_buffer_info,
+};
+
+int rt_hw_sound_init(void)
+{
+ rt_err_t result = RT_EOK;
+ struct rt_device *device = RT_NULL;
+
+ rt_memset(AUDIO_TX_FIFO, 0, TX_FIFO_SIZE);
+ snd_dev.tx_fifo = AUDIO_TX_FIFO;
+
+ /* init default configuration */
+ snd_dev.replay_config.samplerate = 44100;
+ snd_dev.replay_config.channels = 2;
+ snd_dev.replay_config.samplebits = 16;
+ snd_dev.volume = 55;
+
+ /* register sound device */
+ snd_dev.audio.ops = &snd_ops;
+ result = rt_audio_register(&snd_dev.audio, "sound0", RT_DEVICE_FLAG_WRONLY, &snd_dev);
+ if (result != RT_EOK)
+ {
+ device = &(snd_dev.audio.parent);
+ rt_device_unregister(device);
+ LOG_E("sound device init error!");
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+INIT_APP_EXPORT(rt_hw_sound_init);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/crypto/crypto_sample.c b/bsp/stm32/stm32mp157a-st-discovery/board/ports/crypto/crypto_sample.c
new file mode 100644
index 0000000000..e3eb609559
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/crypto/crypto_sample.c
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-06-27 thread-liu first version
+ */
+
+#include <board.h>
+
+#include "drv_crypto.h"
+#include <hwcrypto.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
+{
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%08X: ", i);
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j < buflen)
+ {
+ rt_kprintf("%02X ", buf[i + j]);
+ }
+ else
+ {
+ rt_kprintf(" ");
+ }
+ }
+ rt_kprintf(" ");
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j < buflen)
+ {
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ }
+ }
+ rt_kprintf("\n");
+ }
+}
+
+#if defined(BSP_USING_RNG)
+static rt_err_t hw_rng_sample(int random_num)
+{
+ rt_err_t result = RT_EOK;
+ int i = 0, num0 = 0, num1 = 0;
+
+ if (random_num == 0)
+ {
+ return RT_ERROR;
+ }
+
+ for (i = 0; i< random_num; i++)
+ {
+ result = rt_hwcrypto_rng_update();
+ rt_kprintf("%d ", result);
+ result%2 ? num1++ : num0++;
+ }
+ rt_kprintf("\neven numbers : %d, odd numbers: %d\n",num1, num0);
+
+ return RT_EOK;
+}
+#endif
+
+#if defined(BSP_USING_CRC)
+static void hw_crc_sample(uint8_t *temp, int size)
+{
+ struct rt_hwcrypto_ctx *ctx;
+ rt_uint32_t result = 0;
+
+ struct hwcrypto_crc_cfg cfg =
+ {
+ .last_val = 0xFFFFFFFF,
+ .poly = 0x04C11DB7,
+ .width = 32,
+ .xorout = 0x00000000,
+ .flags = 0,
+ };
+
+ ctx = rt_hwcrypto_crc_create(rt_hwcrypto_dev_default(), HWCRYPTO_CRC_CRC32);
+ rt_hwcrypto_crc_cfg(ctx, &cfg);
+
+ result = rt_hwcrypto_crc_update(ctx, temp, size);
+
+ rt_kprintf("crc result: %x \n", result);
+
+ rt_hwcrypto_crc_destroy(ctx);
+}
+#endif
+
+#if defined(BSP_USING_HASH)
+static void hw_hash_sample()
+{
+ struct rt_hwcrypto_ctx *ctx = RT_NULL;
+ const uint8_t hash_input[] = "RT-Thread was born in 2006, it is an open source, neutral, and community-based real-time operating system (RTOS).";
+
+ static uint8_t sha1_output[20];
+ static uint8_t sha1_except[20] = {0xff, 0x3c, 0x95, 0x54, 0x95, 0xf0, 0xad,
+ 0x02, 0x1b, 0xa8, 0xbc, 0xa2, 0x2e, 0xa5,
+ 0xb0, 0x62, 0x1b, 0xdf, 0x7f, 0xec};
+
+ static uint8_t md5_output[16];
+ static uint8_t md5_except[16] = {0x40, 0x86, 0x03, 0x80, 0x0d, 0x8c, 0xb9,
+ 0x4c, 0xd6, 0x7d, 0x28, 0xfc, 0xf6, 0xc3,
+ 0xac, 0x8b};
+
+ static uint8_t sha224_output[28];
+ static uint8_t sha224_except[28] = {0x6f, 0x62, 0x52, 0x7d, 0x80, 0xe6,
+ 0x9f, 0x82, 0x78, 0x7a, 0x46, 0x91,
+ 0xb0, 0xe9, 0x64, 0x89, 0xe6, 0xc3,
+ 0x6b, 0x7e, 0xcf, 0xca, 0x11, 0x42,
+ 0xc8, 0x77, 0x13, 0x79};
+ static uint8_t sha256_output[32];
+ static uint8_t sha256_except[32] = {0x74, 0x19, 0xb9, 0x0e, 0xd1, 0x46,
+ 0x37, 0x0a, 0x55, 0x18, 0x26, 0x6c,
+ 0x50, 0xd8, 0x71, 0x34, 0xfa, 0x1f,
+ 0x5f, 0x5f, 0xe4, 0x9a, 0xe9, 0x40,
+ 0x0a, 0x7d, 0xa0, 0x26, 0x1b, 0x86,
+ 0x67, 0x45};
+ rt_kprintf("======================== Hash Test start ========================\n");
+ rt_kprintf("Hash Test string: \n");
+ dump_hex(hash_input, sizeof(hash_input));
+
+ /* sh1 test*/
+ rt_kprintf("\n============ SHA1 Test Start ============\n");
+ ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA1);
+ if (ctx == RT_NULL)
+ {
+ rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA1);
+ return ;
+ }
+ rt_kprintf("Create sha1 type success!\n");
+ rt_kprintf("Except sha1 result:\n");
+ dump_hex(sha1_except, sizeof(sha1_except));
+
+ /* start sha1 */
+ rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
+ /* get sha1 result */
+ rt_hwcrypto_hash_finish(ctx, sha1_output, rt_strlen((char const *)sha1_output));
+
+ rt_kprintf("Actual sha1 result:\n");
+ dump_hex(sha1_output, sizeof(sha1_output));
+
+ if(rt_memcmp(sha1_output, sha1_except, sizeof(sha1_except)/sizeof(sha1_except[0])) != 0)
+ {
+ rt_kprintf("Hash type sha1 Test error, The actual result is not equal to the except result\n");
+ }
+ else
+ {
+ rt_kprintf("Hash type sha1 Test success, The actual result is equal to the except result\n");
+ }
+ /* deinit hash*/
+ rt_hwcrypto_hash_destroy(ctx);
+ rt_kprintf("============ SHA1 Test Over ============\n");
+
+ /* md5 test*/
+ rt_kprintf("\n============ MD5 Test Start ============\n");
+ ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_MD5);
+ if (ctx == RT_NULL)
+ {
+ rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_MD5);
+ return ;
+ }
+ rt_kprintf("Create md5 type success!\n");
+ rt_kprintf("Except md5 result:\n");
+ dump_hex(md5_except, sizeof(md5_except));
+
+ /* start md5 */
+ rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
+ /* get md5 result */
+ rt_hwcrypto_hash_finish(ctx, md5_output, rt_strlen((char const *)md5_output));
+
+ rt_kprintf("Actual md5 result:\n");
+ dump_hex(md5_output, sizeof(md5_output));
+
+ if(rt_memcmp(md5_output, md5_except, sizeof(md5_except)/sizeof(md5_except[0])) != 0)
+ {
+ rt_kprintf("Hash type md5 Test error, The actual result is not equal to the except result\n");
+ }
+ else
+ {
+ rt_kprintf("Hash type md5 Test success, The actual result is equal to the except result\n");
+ }
+ /* deinit hash*/
+ rt_hwcrypto_hash_destroy(ctx);
+ rt_kprintf("============ MD5 Test Over ============\n");
+
+ /* sha224 test */
+ rt_kprintf("\n============ SHA224 Test Start ============\n");
+ ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA224);
+ if (ctx == RT_NULL)
+ {
+ rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA224);
+ return ;
+ }
+ rt_kprintf("Create sha224 type success!\n");
+ rt_kprintf("Except sha224 result:\n");
+ dump_hex(sha224_except, sizeof(sha224_except));
+
+ /* start sha224 */
+ rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
+ /* get sha224 result */
+ rt_hwcrypto_hash_finish(ctx, sha224_output, rt_strlen((char const *)sha224_output));
+
+ rt_kprintf("Actual sha224 result:\n");
+ dump_hex(sha224_output, sizeof(sha224_output));
+
+ if(rt_memcmp(sha224_output, sha224_except, sizeof(sha224_except)/sizeof(sha224_except[0])) != 0)
+ {
+ rt_kprintf("Hash type sha224 Test error, The actual result is not equal to the except result\n");
+ }
+ else
+ {
+ rt_kprintf("Hash type sha224 Test success, The actual result is equal to the except result\n");
+ }
+ rt_hwcrypto_hash_destroy(ctx);
+ rt_kprintf("============ SHA224 Test Over ============\n");
+
+ /* sha256 test*/
+ rt_kprintf("\n============ SHA256 Test Start ============\n");
+ ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA256);
+ if (ctx == RT_NULL)
+ {
+ rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA256);
+ return ;
+ }
+
+ rt_kprintf("Create sha256 type success!\n");
+ rt_kprintf("Except sha256 result:\n");
+ dump_hex(sha256_except, sizeof(sha256_except));
+
+ /* start sha256 */
+ rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
+ /* get sha256 result */
+ rt_hwcrypto_hash_finish(ctx, sha256_output, rt_strlen((char const *)sha256_output));
+
+ rt_kprintf("Actual sha256 result\n");
+ dump_hex(sha256_output, sizeof(sha256_output));
+
+ if(rt_memcmp(sha256_output, sha256_except, sizeof(sha256_except)/sizeof(sha256_except[0])) != 0)
+ {
+ rt_kprintf("Hash type sha256 Test error, The actual result is not equal to the except result\n");
+ }
+ else
+ {
+ rt_kprintf("Hash type sha256 Test success, The actual result is equal to the except result\n");
+ }
+ /* destory */
+ rt_hwcrypto_hash_destroy(ctx);
+ rt_kprintf("============ SHA256 Test Over ============\n");
+ rt_kprintf("======================== Hash Test over! ========================\n");
+}
+#endif
+
+#if defined(BSP_USING_CRYP)
+/* key*/
+static const rt_uint8_t cryp_key[16] = {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
+
+static void hw_aes_cbc(const rt_uint8_t in[32], rt_uint8_t out[32], hwcrypto_mode mode)
+{
+ struct rt_hwcrypto_ctx *ctx;
+
+ ctx = rt_hwcrypto_symmetric_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_AES_CBC);
+ if (ctx == RT_NULL)
+ {
+ rt_kprintf("create AES-CBC context err!");
+ return;
+ }
+ rt_hwcrypto_symmetric_setkey(ctx, cryp_key, 128);
+ rt_hwcrypto_symmetric_crypt(ctx, mode, 32, in, out);
+ rt_hwcrypto_symmetric_destroy(ctx);
+}
+
+static void hw_cryp_sample()
+{
+ rt_uint8_t buf_in[32];
+ rt_uint8_t buf_out[32];
+ int i;
+
+ /* Populating test data */
+ for (i = 0; i < sizeof(buf_in); i++)
+ {
+ buf_in[i] = i;
+ }
+
+ /* dump primitive data */
+ rt_kprintf("key : \n");
+ dump_hex(cryp_key, sizeof(cryp_key));
+ rt_kprintf("primitive data : \n");
+ dump_hex(buf_in, sizeof(buf_in));
+
+ rt_memset(buf_out, 0, sizeof(buf_out));
+
+ /* encrypt */
+ hw_aes_cbc(buf_in, buf_out, HWCRYPTO_MODE_ENCRYPT);
+ /* dump encrypt data */
+ rt_kprintf("AES-enc : \n");
+ dump_hex(buf_out, sizeof(buf_out));
+
+ rt_memset(buf_in, 0, sizeof(buf_in));
+
+ /* decrypt */
+ hw_aes_cbc(buf_out, buf_in, HWCRYPTO_MODE_DECRYPT);
+
+ /* dump decrypt data */
+ rt_kprintf("AES-dec : \n");
+ dump_hex(buf_in, sizeof(buf_in));
+}
+#endif
+
+static int crypto(int argc, char **argv)
+{
+ int result = RT_EOK;
+ static rt_device_t device = RT_NULL;
+ char *result_str;
+
+ if (argc > 1)
+ {
+ if (!strcmp(argv[1], "probe"))
+ {
+ if (argc == 3)
+ {
+ char *dev_name = argv[2];
+ device = rt_device_find(dev_name);
+ result_str = (device == RT_NULL) ? "failure" : "success";
+ rt_kprintf("probe %s %s \n", argv[2], result_str);
+ }
+ else
+ {
+ rt_kprintf("crypto probe <crypto_name> - probe crypto by name\n");
+ }
+ }
+ else
+ {
+ if (device == RT_NULL)
+ {
+ rt_kprintf("Please using 'crypto probe <crypto_name>' first\n");
+ return -RT_ERROR;
+ }
+ if (!strcmp(argv[1], "rng"))
+ {
+#if defined (BSP_USING_RNG)
+ if (argc == 3)
+ {
+ result = hw_rng_sample(atoi(argv[2]));
+ if(result != RT_EOK)
+ {
+ rt_kprintf("please input a legal number, not <%d>\n", atoi(argv[2]));
+ }
+ }
+ else
+ {
+ rt_kprintf("rng <number> - generate <number> digital\n");
+ }
+
+#else
+ rt_kprintf("please enable RNG first!\n");
+#endif
+ }
+ else if (!strcmp(argv[1], "crc"))
+ {
+#if defined (BSP_USING_CRC)
+ int size = 0, i = 0;
+ if (argc > 3)
+ {
+ size = argc - 2;
+ uint8_t *data = rt_malloc(size);
+ if (data)
+ {
+ for (i = 0; i < size; i++)
+ {
+ data[i] = strtol(argv[2 + i], NULL, 0);
+ }
+ hw_crc_sample(data, size);
+ rt_free(data);
+ }
+ else
+ {
+ rt_kprintf("Low memory!\n");
+ }
+ }
+ else
+ {
+ rt_kprintf("crypto crc data1 ... dataN - calculate data1 ... dataN crc\n");
+ }
+#else
+ rt_kprintf("please enable CRC first!\n");
+#endif
+ }
+ else if (!strcmp(argv[1], "hash"))
+ {
+#if defined (BSP_USING_HASH)
+ if (argc == 3)
+ {
+ hw_hash_sample();
+ }
+ else
+ {
+ rt_kprintf("crypto hash sample - hash use sample\n");
+ }
+#else
+ rt_kprintf("please enable CRC first!\n");
+#endif
+ }
+ else if (!strcmp(argv[1], "cryp"))
+ {
+#if defined (BSP_USING_CRYP)
+ if (argc == 3)
+ {
+ hw_cryp_sample();
+ }
+ else
+ {
+ rt_kprintf("crypto cryp sample - encrypt and decrypt data sample\n");
+ }
+#else
+ rt_kprintf("please enable CRYP first!\n");
+#endif
+ }
+ else
+ {
+ rt_kprintf("Unknown command. Please enter 'crypto' for help\n");
+ }
+ }
+ }
+ else
+ {
+ rt_kprintf("Usage: \n");
+ rt_kprintf("crypto probe <crypto_name> - probe crypto by name\n");
+ rt_kprintf("crypto rng number - generate numbers digital\n");
+ rt_kprintf("crypto crc data1 ... dataN - calculate data1 ... dataN crc\n");
+ rt_kprintf("crypto hash sample - hash use sample\n");
+ rt_kprintf("crypto cryp sample - encrypt and decrypt data\n");
+ result = -RT_ERROR;
+ }
+
+ return result;
+}
+MSH_CMD_EXPORT(crypto, crypto function);
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_eth.c b/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_eth.c
new file mode 100644
index 0000000000..b2fbc3561b
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_eth.c
@@ -0,0 +1,882 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-20 thread-liu the first version
+ */
+
+#include "board.h"
+#include "drv_config.h"
+#include <netif/ethernetif.h>
+#include "lwipopts.h"
+#include "drv_eth.h"
+
+#if defined(BSP_USING_GBE)
+
+#define DRV_DEBUG
+//#define ETH_RX_DUMP
+//#define ETH_TX_DUMP
+#define LOG_TAG "drv.emac"
+#include <drv_log.h>
+
+#define MAX_ADDR_LEN 6
+rt_base_t level;
+
+#define TX_ADD_BASE 0x2FFC3000
+#define RX_ADD_BASE 0x2FFC5000
+#define TX_DMA_ADD_BASE 0x2FFC7000
+#define RX_DMA_ADD_BASE 0x2FFC7100
+
+#if defined(__ICCARM__)
+/* transmit buffer */
+#pragma location = TX_ADD_BASE
+static rt_uint8_t txBuffer[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
+/* Receive buffer */
+#pragma location = RX_ADD_BASE
+static rt_uint8_t rxBuffer[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
+/* Transmit DMA descriptors */
+#pragma location = TX_DMA_ADD_BASE
+static TxDmaDesc txDmaDesc[ETH_TXBUFNB];
+/* Receive DMA descriptors */
+#pragma location = RX_DMA_ADD_BASE
+static RxDmaDesc rxDmaDesc[ETH_RXBUFNB];
+
+#elif defined(__CC_ARM) || defined(__CLANG_ARM)
+/* transmit buffer */
+static rt_uint8_t txBuffer[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__((at(TX_ADD_BASE)));
+/* Receive buffer */
+static rt_uint8_t rxBuffer[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__((at(RX_ADD_BASE)));
+/* Transmit DMA descriptors */
+static TxDmaDesc txDmaDesc[ETH_TXBUFNB] __attribute__((at(TX_DMA_ADD_BASE)));
+/* Receive DMA descriptors */
+static RxDmaDesc rxDmaDesc[ETH_RXBUFNB] __attribute__((at(RX_DMA_ADD_BASE)));
+
+#elif defined ( __GNUC__ )
+/* transmit buffer */
+static rt_uint8_t txBuffer[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__((at(TX_ADD_BASE)));
+/* Receive buffer */
+static rt_uint8_t rxBuffer[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__((at(RX_ADD_BASE)));
+/* Transmit DMA descriptors */
+static TxDmaDesc txDmaDesc[ETH_TXBUFNB] __attribute__((at(TX_DMA_ADD_BASE)));
+/* Receive DMA descriptors */
+static RxDmaDesc rxDmaDesc[ETH_RXBUFNB] __attribute__((at(RX_DMA_ADD_BASE)));
+#endif
+
+/* Current transmit descriptor */
+static rt_uint8_t txIndex = 0;
+/* Current receive descriptor */
+static rt_uint8_t rxIndex = 0;
+
+/* eth rx event */
+static struct rt_event rx_event = {0};
+
+#define ETH_TIME_OUT 100000
+
+struct rt_stm32_eth
+{
+ /* inherit from ethernet device */
+ struct eth_device parent;
+#ifndef PHY_USING_INTERRUPT_MODE
+ rt_timer_t poll_link_timer;
+#endif
+ /* interface address info, hw address */
+ rt_uint8_t dev_addr[MAX_ADDR_LEN];
+ /* eth speed */
+ rt_uint32_t eth_speed;
+ /* eth duplex mode */
+ rt_uint32_t eth_mode;
+};
+static struct rt_stm32_eth stm32_eth_device = {0};
+
+#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
+{
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%08X: ", i);
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j < buflen)
+ {
+ rt_kprintf("%02X ", buf[i + j]);
+ }
+ else
+ {
+ rt_kprintf(" ");
+ }
+ }
+ rt_kprintf(" ");
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j < buflen)
+ {
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ }
+ }
+ rt_kprintf("\n");
+ }
+}
+#endif
+
+static rt_err_t phy_write_reg(uint8_t phy_addr, uint8_t reg_addr, uint16_t reg_value)
+{
+ uint32_t temp;
+ volatile uint32_t tickstart = 0;
+ /* Take care not to alter MDC clock configuration */
+ temp = ETH->MACMDIOAR & ETH_MACMDIOAR_CR;
+ /* Set up a write operation */
+ temp |= ETH_MACMDIOAR_GOC_Val(1) | ETH_MACMDIOAR_GB;
+ /* PHY address */
+ temp |= (phy_addr << 21) & ETH_MACMDIOAR_PA;
+ /* Register address */
+ temp |= (reg_addr << 16) & ETH_MACMDIOAR_RDA;
+
+ /* Data to be written in the PHY register */
+ ETH->MACMDIODR = reg_value & ETH_MACMDIODR_GD;
+
+ /* Start a write operation */
+ ETH->MACMDIOAR = temp;
+ /* Wait for the write to complete */
+ tickstart = rt_tick_get();
+ while((ETH->MACMDIOAR & ETH_MACMDIOAR_GB) != 0)
+ {
+ /* judge timeout */
+ if((rt_tick_get() - tickstart) > ETH_TIME_OUT)
+ {
+ LOG_E("PHY write reg %02x date %04x timeout!", reg_addr, reg_value);
+ return -RT_ETIMEOUT;
+ }
+ }
+
+ return RT_EOK;
+}
+
+static uint16_t phy_read_reg(uint8_t phy_addr, uint8_t reg_addr)
+{
+ uint16_t reg_value = 0;
+ uint32_t status = 0;
+ volatile uint32_t tickstart = 0;
+
+ /* Take care not to alter MDC clock configuration */
+ status = ETH->MACMDIOAR & ETH_MACMDIOAR_CR;
+ /* Set up a read operation */
+ status |= ETH_MACMDIOAR_GOC_Val(3) | ETH_MACMDIOAR_GB;
+ /* PHY address */
+ status |= (phy_addr << 21) & ETH_MACMDIOAR_PA;
+ /* Register address */
+ status |= (reg_addr << 16) & ETH_MACMDIOAR_RDA;
+
+ /* Start a read operation */
+ ETH->MACMDIOAR = status;
+ /* Wait for the read to complete */
+ tickstart = rt_tick_get();
+ while((ETH->MACMDIOAR & ETH_MACMDIOAR_GB) != 0)
+ {
+ /* judge timeout */
+ if((rt_tick_get() - tickstart) > ETH_TIME_OUT)
+ {
+ LOG_E("PHY read reg %02x timeout!", reg_addr);
+ return RT_ETIMEOUT;
+ }
+ }
+
+ /* Get register value */
+ reg_value = ETH->MACMDIODR & ETH_MACMDIODR_GD;
+
+ return reg_value;
+}
+
+static rt_err_t update_mac_mode(rt_uint32_t eth_speed, rt_uint32_t eth_mode)
+{
+ uint32_t status;
+
+ /* Read current MAC configuration */
+ status = ETH->MACCR;
+
+ if (eth_speed == PHY_1000M)
+ {
+ status &= ~ETH_MACCR_PS;
+ status &= ~ETH_MACCR_FES;
+ }
+ else if (eth_speed == PHY_100M)
+ {
+ status |= ETH_MACCR_PS;
+ status |= ETH_MACCR_FES;
+ }
+ /* 10M */
+ else
+ {
+ status |= ETH_MACCR_PS;
+ status &= ~ETH_MACCR_FES;
+ }
+
+ if (eth_mode == PHY_FULL_DUPLEX)
+ {
+ status |= ETH_MACCR_DM;
+ }
+ else
+ {
+ status &= ~ETH_MACCR_DM;
+ }
+
+ /* Update MAC configuration register */
+ ETH->MACCR = status;
+
+ return RT_EOK;
+}
+
+static void HAL_ETH_MspInit(void)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ETH;
+ PeriphClkInit.EthClockSelection = RCC_ETHCLKSOURCE_PLL4;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+
+ /* Enable SYSCFG clock */
+ __HAL_RCC_SYSCFG_CLK_ENABLE();
+
+ /* Enable GPIO clocks */
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+
+ /* Select RGMII interface mode */
+ HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_RGMII);
+
+ /* Enable Ethernet MAC clock */
+ __HAL_RCC_ETH1MAC_CLK_ENABLE();
+ __HAL_RCC_ETH1TX_CLK_ENABLE();
+ __HAL_RCC_ETH1RX_CLK_ENABLE();
+
+ /**ETH1 GPIO Configuration
+ PA1 ------> ETH1_RX_CLK
+ PA7 ------> ETH1_RX_CTL
+ PB0 ------> ETH1_RXD2
+ PB1 ------> ETH1_RXD3
+ PC4 ------> ETH1_RXD0
+ PC5 ------> ETH1_RXD1
+ PA2 ------> ETH1_MDIO
+ PB11 ------> ETH1_TX_CTL
+ PC1 ------> ETH1_MDC
+ PC2 ------> ETH1_TXD2
+ PE2 ------> ETH1_TXD3
+ PG4 ------> ETH1_GTX_CLK
+ PG5 ------> ETH1_CLK125
+ PG13 ------> ETH1_TXD0
+ PG14 ------> ETH1_TXD1
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_11;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_2;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_13|GPIO_PIN_14;
+ HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
+
+ /* ETH interrupt Init */
+ HAL_NVIC_SetPriority(ETH1_IRQn, 0x01, 0x00);
+ HAL_NVIC_EnableIRQ(ETH1_IRQn);
+
+ /* Configure PHY_RST (PG0) */
+ GPIO_InitStruct.Pin = GPIO_PIN_0;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
+
+ /* Reset PHY transceiver */
+ HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_RESET);
+ rt_thread_mdelay(20);
+ HAL_GPIO_WritePin(GPIOG, GPIO_PIN_0, GPIO_PIN_SET);
+ rt_thread_mdelay(20);
+}
+
+static rt_err_t rt_stm32_eth_init(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ rt_uint32_t status, i;
+ volatile rt_uint32_t tickstart = 0;
+ rt_uint8_t *macAddr = &stm32_eth_device.dev_addr[0];
+
+ /* Initialize TX descriptor index */
+ txIndex = 0;
+ /* Initialize RX descriptor index */
+ rxIndex = 0;
+
+ HAL_ETH_MspInit();
+
+ /* Reset Ethernet MAC peripheral */
+ __HAL_RCC_ETH1MAC_FORCE_RESET();
+ __HAL_RCC_ETH1MAC_RELEASE_RESET();
+
+ /* Ethernet Software reset */
+ ETH->DMAMR |= ETH_DMAMR_SWR;
+ /* Wait for the reset to complete */
+ tickstart = rt_tick_get();
+ while (READ_BIT(ETH->DMAMR, ETH_DMAMR_SWR))
+ {
+ if(((HAL_GetTick() - tickstart ) > ETH_TIME_OUT))
+ {
+ LOG_E("ETH software reset timeout!");
+ return RT_ERROR;
+ }
+ }
+
+ /* Adjust MDC clock range depending on HCLK frequency */
+ ETH->MACMDIOAR = ETH_MACMDIOAR_CR_Val(5);
+
+ /* Use default MAC configuration */
+ ETH->MACCR = ETH_MACCR_DO;
+
+ /* Set the MAC address of the station */
+ ETH->MACA0LR = ((macAddr[3] << 24) | (macAddr[2] << 16) | (macAddr[1] << 8) | macAddr[0]);
+ ETH->MACA0HR = ((macAddr[5] << 8) | macAddr[4]);
+
+ /* The MAC supports 3 additional addresses for unicast perfect filtering */
+ ETH->MACA1LR = 0;
+ ETH->MACA1HR = 0;
+ ETH->MACA2LR = 0;
+ ETH->MACA2HR = 0;
+ ETH->MACA3LR = 0;
+ ETH->MACA3HR = 0;
+
+ /* Initialize hash table */
+ ETH->MACHT0R = 0;
+ ETH->MACHT1R = 0;
+
+ /* Configure the receive filter */
+ ETH->MACPFR = ETH_MACPFR_HPF | ETH_MACPFR_HMC;
+
+ /* Disable flow control */
+ ETH->MACQ0TXFCR = 0;
+ ETH->MACRXFCR = 0;
+
+ /* Enable the first RX queue */
+ ETH->MACRXQC0R = ETH_MACRXQC0R_RXQ0EN_Val(1);
+
+ /* Configure DMA operating mode */
+ ETH->DMAMR = ETH_DMAMR_INTM_Val(0) | ETH_DMAMR_PR_Val(0);
+
+ /* Configure system bus mode */
+ ETH->DMASBMR |= ETH_DMASBMR_AAL;
+
+ /* The DMA takes the descriptor table as contiguous */
+ ETH->DMAC0CR = ETH_DMAC0CR_DSL_Val(0);
+
+ /* Configure TX features */
+ ETH->DMAC0TXCR = ETH_DMAC0TXCR_TXPBL_Val(1);
+
+ /* Configure RX features */
+ ETH->DMAC0RXCR = ETH_DMAC0RXCR_RXPBL_Val(1) | ETH_DMAC0RXCR_RBSZ_Val(ETH_RX_BUF_SIZE);
+
+ /* Enable store and forward mode for transmission */
+ ETH->MTLTXQ0OMR = ETH_MTLTXQ0OMR_TQS_Val(7) | ETH_MTLTXQ0OMR_TXQEN_Val(2) | ETH_MTLTXQ0OMR_TSF;
+
+ /* Enable store and forward mode for reception */
+ ETH->MTLRXQ0OMR = ETH_MTLRXQ0OMR_RQS_Val(7) | ETH_MTLRXQ0OMR_RSF;
+
+ /* Initialize TX DMA descriptor list */
+ for (i = 0; i < ETH_TXBUFNB; i++)
+ {
+ /* The descriptor is initially owned by the application */
+ txDmaDesc[i].tdes0 = 0;
+ txDmaDesc[i].tdes1 = 0;
+ txDmaDesc[i].tdes2 = 0;
+ txDmaDesc[i].tdes3 = 0;
+ }
+
+ /* Initialize RX DMA descriptor list */
+ for (i = 0; i < ETH_RXBUFNB; i++)
+ {
+ /* The descriptor is initially owned by the DMA */
+ rxDmaDesc[i].rdes0 = (uint32_t) rxBuffer[i];
+ rxDmaDesc[i].rdes1 = 0;
+ rxDmaDesc[i].rdes2 = 0;
+ rxDmaDesc[i].rdes3 = ETH_RDES3_OWN | ETH_RDES3_IOC | ETH_RDES3_BUF1V;
+ }
+
+ /* Set Transmit Descriptor List Address Register */
+ ETH->DMAC0TXDLAR = (uint32_t) &txDmaDesc[0];
+ /* Length of the transmit descriptor ring */
+ ETH->DMAC0TXRLR = ETH_TXBUFNB - 1;
+
+ /* Set Receive Descriptor List Address Register */
+ ETH->DMAC0RXDLAR = (uint32_t) &rxDmaDesc[0];
+ /* Length of the receive descriptor ring */
+ ETH->DMAC0RXRLR = ETH_RXBUFNB - 1;
+
+ /* Prevent interrupts from being generated when the transmit statistic
+ * counters reach half their maximum value */
+ ETH->MMCTXIMR = ETH_MMCTXIMR_TXLPITRCIM | ETH_MMCTXIMR_TXLPIUSCIM | ETH_MMCTXIMR_TXGPKTIM | ETH_MMCTXIMR_TXMCOLGPIM | ETH_MMCTXIMR_TXSCOLGPIM;
+
+ /* Prevent interrupts from being generated when the receive statistic
+ * counters reach half their maximum value */
+ ETH->MMCRXIMR = ETH_MMCRXIMR_RXLPITRCIM | ETH_MMCRXIMR_RXLPIUSCIM | ETH_MMCRXIMR_RXUCGPIM | ETH_MMCRXIMR_RXALGNERPIM | ETH_MMCRXIMR_RXCRCERPIM;
+
+ /* Disable MAC interrupts */
+ ETH->MACIER = 0;
+
+ /* Enable the desired DMA interrupts */
+ ETH->DMAC0IER = ETH_DMAC0IER_NIE | ETH_DMAC0IER_RIE | ETH_DMAC0IER_TIE;
+
+ /* Enable MAC transmission and reception */
+ ETH->MACCR |= ETH_MACCR_TE | ETH_MACCR_RE;
+
+ /* Enable DMA transmission and reception */
+ ETH->DMAC0TXCR |= ETH_DMAC0TXCR_ST;
+ ETH->DMAC0RXCR |= ETH_DMAC0RXCR_SR;
+
+ /* Reset PHY transceiver */
+ phy_write_reg(RTL8211F_PHY_ADDR, RTL8211F_BMCR, RTL8211F_BMCR_RESET);
+ status = phy_read_reg(RTL8211F_PHY_ADDR, RTL8211F_BMCR);
+ /* Wait for the reset to complete */
+ tickstart = rt_tick_get();
+ while (status & RTL8211F_BMCR_RESET)
+ {
+ if((rt_tick_get() - tickstart) > ETH_TIME_OUT)
+ {
+ LOG_E("PHY software reset timeout!");
+ return RT_ETIMEOUT;
+ }
+ else
+ {
+ status = phy_read_reg(RTL8211F_PHY_ADDR, RTL8211F_BMCR);
+ }
+ }
+
+ /* The PHY will generate interrupts when link status changes are detected */
+ phy_write_reg(RTL8211F_PHY_ADDR, RTL8211F_INER, RTL8211F_INER_AN_COMPLETE | RTL8211F_INER_LINK_STATUS);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ LOG_D("emac open");
+ return RT_EOK;
+}
+
+static rt_err_t rt_stm32_eth_close(rt_device_t dev)
+{
+ LOG_D("emac close");
+ return RT_EOK;
+}
+
+static rt_size_t rt_stm32_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ LOG_D("emac read");
+ rt_set_errno(-RT_ENOSYS);
+ return 0;
+}
+
+static rt_size_t rt_stm32_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ LOG_D("emac write");
+ rt_set_errno(-RT_ENOSYS);
+ return 0;
+}
+
+static rt_err_t rt_stm32_eth_control(rt_device_t dev, int cmd, void *args)
+{
+ switch (cmd)
+ {
+ case NIOCTL_GADDR:
+ /* get mac address */
+ if (args)
+ {
+ rt_memcpy(args, stm32_eth_device.dev_addr, 6);
+ }
+ else
+ {
+ return -RT_ERROR;
+ }
+ break;
+
+ default :
+ break;
+ }
+
+ return RT_EOK;
+}
+
+rt_err_t rt_stm32_eth_tx(rt_device_t dev, struct pbuf *p)
+{
+ uint32_t framelen = 0;
+ struct pbuf *q = RT_NULL;
+
+ /* Copy user data to the transmit buffer */
+ for (q = p; q != NULL; q = q->next)
+ {
+ /* Make sure the current buffer is available for writing */
+ if((txDmaDesc[txIndex].tdes3 & ETH_TDES3_OWN) != 0)
+ {
+ LOG_D("buffer not valid");
+ return ERR_USE;
+ }
+
+ level = rt_hw_interrupt_disable();
+ rt_memcpy(&txBuffer[txIndex][framelen], q->payload, q->len);
+ framelen += q->len;
+ rt_hw_interrupt_enable(level);
+
+ /* Check the frame length */
+ if (framelen > ETH_TX_BUF_SIZE - 1)
+ {
+ LOG_D(" tx buffer frame length over : %d", framelen);
+ return ERR_USE;
+ }
+ }
+
+#ifdef ETH_TX_DUMP
+ rt_kprintf("Tx dump, len= %d\r\n", framelen);
+ dump_hex(txBuffer[txIndex], framelen);
+#endif
+
+ /* Set the start address of the buffer */
+ txDmaDesc[txIndex].tdes0 = (uint32_t)txBuffer[txIndex];
+ /* Write the number of bytes to send */
+ txDmaDesc[txIndex].tdes2 = ETH_TDES2_IOC | (framelen & ETH_TDES2_B1L);
+ /* Give the ownership of the descriptor to the DMA */
+ txDmaDesc[txIndex].tdes3 = ETH_TDES3_OWN | ETH_TDES3_FD | ETH_TDES3_LD;
+
+ /* Data synchronization barrier */
+ __DSB();
+
+ /* Clear TBU flag to resume processing */
+ ETH->DMAC0SR = ETH_DMAC0SR_TBU;
+ /* Instruct the DMA to poll the transmit descriptor list */
+ ETH->DMAC0TXDTPR = 0;
+
+ if (++txIndex > ETH_TXBUFNB - 1)
+ {
+ txIndex = 0;
+ }
+
+ return ERR_OK;
+}
+
+struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
+{
+ rt_uint32_t framelength = 0;
+ uint32_t framelen = 0;
+ struct pbuf *p = RT_NULL, *q = RT_NULL;
+
+ /* The current buffer is available for reading */
+ if (!(rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_OWN))
+ {
+ /* FD and LD flags should be set */
+ if ((rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_FD) && (rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_LD))
+ {
+ /* Make sure no error occurred */
+ if(!(rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_ES))
+ {
+ /* Retrieve the length of the frame */
+ framelength = rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_PL;
+ /* check the frame length */
+ framelength = (framelength > ETH_RX_BUF_SIZE) ? ETH_RX_BUF_SIZE : framelength;
+
+ p = pbuf_alloc(PBUF_RAW, framelength, PBUF_RAM);
+ if (p != NULL)
+ {
+ for (q = p; q != NULL; q = q->next)
+ {
+ level=rt_hw_interrupt_disable();
+ rt_memcpy(q->payload, &rxBuffer[rxIndex][framelen], q->len);
+ framelen += q->len;
+ rt_hw_interrupt_enable(level);
+
+ if (framelen > framelength)
+ {
+ LOG_E("frame len is too long!");
+ return RT_NULL;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* The received packet contains an error */
+ LOG_D("the received packet contains an error!");
+ return RT_NULL;
+ }
+
+ }
+ else
+ {
+ /* The packet is not valid */
+ LOG_D("the packet is not valid");
+ return RT_NULL;
+ }
+
+ /* Set the start address of the buffer */
+ rxDmaDesc[rxIndex].rdes0 = (uint32_t)rxBuffer[rxIndex];
+ /* Give the ownership of the descriptor back to the DMA */
+ rxDmaDesc[rxIndex].rdes3 = ETH_RDES3_OWN | ETH_RDES3_IOC | ETH_RDES3_BUF1V;
+
+#ifdef ETH_RX_DUMP
+ rt_kprintf("Rx dump, len= %d\r\n", framelen);
+ dump_hex(rxBuffer[rxIndex], framelen);
+#endif
+ /* Increment index and wrap around if necessary */
+ if (++rxIndex > ETH_RXBUFNB - 1)
+ {
+ rxIndex = 0;
+ }
+ /* Clear RBU flag to resume processing */
+ ETH->DMAC0SR = ETH_DMAC0SR_RBU;
+ /* Instruct the DMA to poll the receive descriptor list */
+ ETH->DMAC0RXDTPR = 0;
+ }
+
+ return p;
+}
+
+void ETH1_IRQHandler(void)
+{
+ rt_uint32_t status = 0;
+
+ /* enter interrupt */
+ rt_interrupt_enter();
+ /* Read DMA status register */
+ status = ETH->DMAC0SR;
+ /* Frame transmitted */
+ if (status & ETH_DMAC0SR_TI)
+ {
+ /* Clear the Eth DMA Tx IT pending bits */
+ ETH->DMAC0SR = ETH_DMAC0SR_TI;
+ }
+ /* Frame received */
+ else if (status & ETH_DMAC0SR_RI)
+ {
+ /* Disable RIE interrupt */
+ ETH->DMAC0IER &= ~ETH_DMAC0IER_RIE;
+
+ rt_event_send(&rx_event, status);
+ }
+ /* ETH DMA Error */
+ if (status & ETH_DMAC0SR_AIS)
+ {
+ ETH->DMAC0IER &= ~ETH_DMAC0IER_AIE;
+ LOG_E("eth dam err");
+ }
+ /* Clear the interrupt flags */
+ ETH->DMAC0SR = ETH_DMAC0SR_NIS;
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+
+}
+
+static void phy_linkchange()
+{
+ rt_uint32_t status = 0;
+
+ /* Read status register to acknowledge the interrupt */
+ status = phy_read_reg(RTL8211F_PHY_ADDR, RTL8211F_INSR);
+
+
+ if (status & (RTL8211F_BMSR_LINK_STATUS | RTL8211F_INSR_AN_COMPLETE))
+ {
+ status = phy_read_reg(RTL8211F_PHY_ADDR, RTL8211F_BMSR);
+ status = phy_read_reg(RTL8211F_PHY_ADDR, RTL8211F_BMSR);
+ if (status & RTL8211F_BMSR_LINK_STATUS)
+ {
+ LOG_D("link up");
+
+ status = phy_read_reg(RTL8211F_PHY_ADDR, RTL8211F_PHYSR);
+ switch (status & RTL8211F_PHYSR_SPEED)
+ {
+ case RTL8211F_PHYSR_SPEED_10MBPS:
+ {
+ LOG_D("speed: 10M");
+ stm32_eth_device.eth_speed |= PHY_10M;
+ }
+ break;
+
+ case RTL8211F_PHYSR_SPEED_100MBPS:
+ {
+ LOG_D("speed: 100M");
+ stm32_eth_device.eth_speed |= PHY_100M;
+ }
+ break;
+
+ case RTL8211F_PHYSR_SPEED_1000MBPS:
+ {
+ LOG_D("speed: 1000M");
+ stm32_eth_device.eth_speed |= PHY_1000M;
+ }
+ break;
+
+ /* Unknown speed */
+ default:
+ rt_kprintf("Invalid speed.");
+ break;
+ }
+
+ stm32_eth_device.eth_mode = (status & RTL8211F_PHYSR_DUPLEX)? PHY_FULL_DUPLEX : PHY_HALF_DUPLEX ;
+
+ update_mac_mode(stm32_eth_device.eth_speed, stm32_eth_device.eth_mode);
+ /* send link up. */
+ eth_device_linkchange(&stm32_eth_device.parent, RT_TRUE);
+ }
+ else
+ {
+ LOG_I("link down");
+ eth_device_linkchange(&stm32_eth_device.parent, RT_FALSE);
+ }
+ }
+}
+
+#ifdef PHY_USING_INTERRUPT_MODE
+static void eth_phy_isr(void *args)
+{
+ rt_uint32_t status = 0;
+
+ phy_read_reg(RTL8211F_PHY_ADDR, PHY_INTERRUPT_FLAG_REG, (uint32_t *)&status);
+ LOG_D("phy interrupt status reg is 0x%X", status);
+
+ phy_linkchange();
+}
+#endif /* PHY_USING_INTERRUPT_MODE */
+
+static void phy_monitor_thread_entry(void *parameter)
+{
+ rt_uint32_t status = 0;
+ phy_linkchange();
+#ifdef PHY_USING_INTERRUPT_MODE
+ /* configuration intterrupt pin */
+ rt_pin_mode(PHY_INT_PIN, PIN_MODE_INPUT_PULLUP);
+ rt_pin_attach_irq(PHY_INT_PIN, PIN_IRQ_MODE_FALLING, eth_phy_isr, (void *)"callbackargs");
+ rt_pin_irq_enable(PHY_INT_PIN, PIN_IRQ_ENABLE);
+
+ /* enable phy interrupt */
+ phy_write_reg(RTL8211F_PHY_ADDR, PHY_INTERRUPT_MASK_REG, PHY_INT_MASK);
+#if defined(PHY_INTERRUPT_CTRL_REG)
+ phy_write_reg( RTL8211F_PHY_ADDR, PHY_INTERRUPT_CTRL_REG, PHY_INTERRUPT_EN);
+#endif
+#else /* PHY_USING_INTERRUPT_MODE */
+ stm32_eth_device.poll_link_timer = rt_timer_create("phylnk", (void (*)(void*))phy_linkchange,
+ NULL, RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC);
+ if (!stm32_eth_device.poll_link_timer || rt_timer_start(stm32_eth_device.poll_link_timer) != RT_EOK)
+ {
+ LOG_E("Start link change detection timer failed");
+ }
+#endif /* PHY_USING_INTERRUPT_MODE */
+ while(1)
+ {
+ if (rt_event_recv(&rx_event, 0xffffffff, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ RT_WAITING_FOREVER, &status) == RT_EOK)
+ {
+ /* check dma rx buffer */
+ if (ETH->DMAC0SR & ETH_DMAC0SR_RI)
+ {
+ /* Clear interrupt flag */
+ ETH->DMAC0SR = ETH_DMAC0SR_RI;
+ /* Process all pending packets */
+ while (rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_PL)
+ {
+ /* trigger lwip receive thread */
+ eth_device_ready(&(stm32_eth_device.parent));
+ }
+ }
+
+ /* enable DMA interrupts */
+ ETH->DMAC0IER = ETH_DMAC0IER_NIE | ETH_DMAC0IER_RIE | ETH_DMAC0IER_TIE;
+ }
+ }
+}
+
+/* Register the EMAC device */
+static int rt_hw_stm32_eth_init(void)
+{
+ rt_err_t state = RT_EOK;
+
+ /* OUI 00-80-E1 STMICROELECTRONICS. */
+ stm32_eth_device.dev_addr[0] = 0x00;
+ stm32_eth_device.dev_addr[1] = 0x80;
+ stm32_eth_device.dev_addr[2] = 0xE1;
+ /* generate MAC addr from 96bit unique ID (only for test). */
+ stm32_eth_device.dev_addr[3] = *(rt_uint8_t *)(UID_BASE + 4);
+ stm32_eth_device.dev_addr[4] = *(rt_uint8_t *)(UID_BASE + 2);
+ stm32_eth_device.dev_addr[5] = *(rt_uint8_t *)(UID_BASE + 0);
+
+ stm32_eth_device.parent.parent.init = rt_stm32_eth_init;
+ stm32_eth_device.parent.parent.open = rt_stm32_eth_open;
+ stm32_eth_device.parent.parent.close = rt_stm32_eth_close;
+ stm32_eth_device.parent.parent.read = rt_stm32_eth_read;
+ stm32_eth_device.parent.parent.write = rt_stm32_eth_write;
+ stm32_eth_device.parent.parent.control = rt_stm32_eth_control;
+ stm32_eth_device.parent.parent.user_data = RT_NULL;
+
+ stm32_eth_device.parent.eth_rx = rt_stm32_eth_rx;
+ stm32_eth_device.parent.eth_tx = rt_stm32_eth_tx;
+
+ rt_event_init(&rx_event, "eth_rx", RT_IPC_FLAG_FIFO);
+
+ /* register eth device */
+ state = eth_device_init(&(stm32_eth_device.parent), "e0");
+ if (RT_EOK == state)
+ {
+ LOG_D("emac device init success");
+ }
+ else
+ {
+ LOG_E("emac device init faild: %d", state);
+ state = -RT_ERROR;
+ }
+
+ /* start phy monitor */
+ rt_thread_t tid;
+ tid = rt_thread_create("phy",
+ phy_monitor_thread_entry,
+ RT_NULL,
+ 1024,
+ RT_THREAD_PRIORITY_MAX - 2,
+ 2);
+ if (tid != RT_NULL)
+ {
+ rt_thread_startup(tid);
+ }
+ else
+ {
+ state = -RT_ERROR;
+ }
+
+ return state;
+}
+INIT_DEVICE_EXPORT(rt_hw_stm32_eth_init);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_eth.h b/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_eth.h
new file mode 100644
index 0000000000..40d7db8353
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_eth.h
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-20 thread-liu the first version
+ */
+
+#ifndef __DRV_ETH_H__
+#define __DRV_ETH_H__
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <rtdevice.h>
+#include <board.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ uint32_t Speed; /*!< Sets the Ethernet speed: 10/100/1000 Mbps.
+ This parameter can be a value of @ref ETH_Speed */
+ uint32_t DuplexMode; /*!< Selects the MAC duplex mode: Half-Duplex or Full-Duplex mode
+ This parameter can be a value of @ref ETH_Duplex_Mode */
+} ETH_MACConfigTypeDef;
+
+/**
+ * @brief Transmit descriptor
+ **/
+typedef struct
+{
+ uint32_t tdes0;
+ uint32_t tdes1;
+ uint32_t tdes2;
+ uint32_t tdes3;
+} TxDmaDesc;
+
+/**
+ * @brief Receive descriptor
+ **/
+typedef struct
+{
+ uint32_t rdes0;
+ uint32_t rdes1;
+ uint32_t rdes2;
+ uint32_t rdes3;
+} RxDmaDesc;
+
+enum {
+ PHY_LINK = (1 << 0),
+ PHY_10M = (1 << 1),
+ PHY_100M = (1 << 2),
+ PHY_1000M = (1 << 3),
+ PHY_FULL_DUPLEX = (1 << 4),
+ PHY_HALF_DUPLEX = (1 << 5)
+};
+
+
+#define RTL8211F_PHY_ADDR 1 /* PHY address */
+
+#define ETH_TXBUFNB 4 /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+#define ETH_TX_BUF_SIZE 1536 /* buffer size for transmit */
+#define ETH_RXBUFNB 4 /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_RX_BUF_SIZE 1536 /* buffer size for receive */
+
+#define ETH_MMC_INTERRUPT_MASK_TXLPITRCIM_Msk ETH_MMCTXIMR_TXLPITRCIM_Msk /* ETH_MMCTXIMR register */
+
+/* Register access macros */
+#define ETH_MACRXQC0R_RXQ0EN_Val(n) (((n) << ETH_MACRXQC0R_RXQ0EN_Pos) & ETH_MACRXQC0R_RXQ0EN_Msk)
+#define ETH_MACMDIOAR_CR_Val(n) (((n) << ETH_MACMDIOAR_CR_Pos) & ETH_MACMDIOAR_CR_Msk)
+#define ETH_MACMDIOAR_GOC_Val(n) (((n) << ETH_MACMDIOAR_GOC_Pos) & ETH_MACMDIOAR_GOC_Msk)
+#define ETH_MTLTXQ0OMR_TQS_Val(n) (((n) << ETH_MTLTXQ0OMR_TQS_Pos) & ETH_MTLTXQ0OMR_TQS_Msk)
+#define ETH_MTLTXQ0OMR_TXQEN_Val(n) (((n) << ETH_MTLTXQ0OMR_TXQEN_Pos) & ETH_MTLTXQ0OMR_TXQEN_Msk)
+#define ETH_MTLRXQ0OMR_RQS_Val(n) (((n) << ETH_MTLRXQ0OMR_RQS_Pos) & ETH_MTLRXQ0OMR_RQS_Msk)
+#define ETH_DMAMR_INTM_Val(n) (((n) << ETH_DMAMR_INTM_Pos) & ETH_DMAMR_INTM_Msk)
+#define ETH_DMAMR_PR_Val(n) (((n) << ETH_DMAMR_PR_Pos) & ETH_DMAMR_PR_Msk)
+#define ETH_DMAC0CR_DSL_Val(n) (((n) << ETH_DMAC0CR_DSL_Pos) & ETH_DMAC0CR_DSL_Msk)
+#define ETH_DMAC0TXCR_TXPBL_Val(n) (((n) << ETH_DMAC0TXCR_TXPBL_Pos) & ETH_DMAC0TXCR_TXPBL_Msk)
+#define ETH_DMAC0RXCR_RXPBL_Val(n) (((n) << ETH_DMAC0RXCR_RXPBL_Pos) & ETH_DMAC0RXCR_RXPBL_Msk)
+#define ETH_DMAC0RXCR_RBSZ_Val(n) (((n) << ETH_DMAC0RXCR_RBSZ_Pos) & ETH_DMAC0RXCR_RBSZ_Msk)
+
+/* Transmit normal descriptor (read format) */
+#define ETH_TDES0_BUF1AP 0xFFFFFFFF
+#define ETH_TDES1_BUF2AP 0xFFFFFFFF
+#define ETH_TDES2_IOC 0x80000000
+#define ETH_TDES2_TTSE 0x40000000
+#define ETH_TDES2_B2L 0x3FFF0000
+#define ETH_TDES2_VTIR 0x0000C000
+#define ETH_TDES2_B1L 0x00003FFF
+#define ETH_TDES3_OWN 0x80000000
+#define ETH_TDES3_CTXT 0x40000000
+#define ETH_TDES3_FD 0x20000000
+#define ETH_TDES3_LD 0x10000000
+#define ETH_TDES3_CPC 0x0C000000
+#define ETH_TDES3_SAIC 0x03800000
+#define ETH_TDES3_THL 0x00780000
+#define ETH_TDES3_TSE 0x00040000
+#define ETH_TDES3_CIC 0x00030000
+#define ETH_TDES3_FL 0x00007FFF
+
+/* Transmit normal descriptor (write-back format) */
+#define ETH_TDES0_TTSL 0xFFFFFFFF
+#define ETH_TDES1_TTSH 0xFFFFFFFF
+#define ETH_TDES3_OWN 0x80000000
+#define ETH_TDES3_CTXT 0x40000000
+#define ETH_TDES3_FD 0x20000000
+#define ETH_TDES3_LD 0x10000000
+#define ETH_TDES3_TTSS 0x00020000
+#define ETH_TDES3_ES 0x00008000
+#define ETH_TDES3_JT 0x00004000
+#define ETH_TDES3_FF 0x00002000
+#define ETH_TDES3_PCE 0x00001000
+#define ETH_TDES3_LOC 0x00000800
+#define ETH_TDES3_NC 0x00000400
+#define ETH_TDES3_LC 0x00000200
+#define ETH_TDES3_EC 0x00000100
+#define ETH_TDES3_CC 0x000000F0
+#define ETH_TDES3_ED 0x00000008
+#define ETH_TDES3_UF 0x00000004
+#define ETH_TDES3_DB 0x00000002
+#define ETH_TDES3_IHE 0x00000001
+
+/* Transmit context descriptor */
+#define ETH_TDES0_TTSL 0xFFFFFFFF
+#define ETH_TDES1_TTSH 0xFFFFFFFF
+#define ETH_TDES2_IVT 0xFFFF0000
+#define ETH_TDES2_MSS 0x00003FFF
+#define ETH_TDES3_OWN 0x80000000
+#define ETH_TDES3_CTXT 0x40000000
+#define ETH_TDES3_OSTC 0x08000000
+#define ETH_TDES3_TCMSSV 0x04000000
+#define ETH_TDES3_CDE 0x00800000
+#define ETH_TDES3_IVLTV 0x00020000
+#define ETH_TDES3_VLTV 0x00010000
+#define ETH_TDES3_VT 0x0000FFFF
+
+/* Receive normal descriptor (read format) */
+#define ETH_RDES0_BUF1AP 0xFFFFFFFF
+#define ETH_RDES2_BUF2AP 0xFFFFFFFF
+#define ETH_RDES3_OWN 0x80000000
+#define ETH_RDES3_IOC 0x40000000
+#define ETH_RDES3_BUF2V 0x02000000
+#define ETH_RDES3_BUF1V 0x01000000
+
+/* Receive normal descriptor (write-back format) */
+#define ETH_RDES0_IVT 0xFFFF0000
+#define ETH_RDES0_OVT 0x0000FFFF
+#define ETH_RDES1_OPC 0xFFFF0000
+#define ETH_RDES1_TD 0x00008000
+#define ETH_RDES1_TSA 0x00004000
+#define ETH_RDES1_PV 0x00002000
+#define ETH_RDES1_PFT 0x00001000
+#define ETH_RDES1_PMT 0x00000F00
+#define ETH_RDES1_IPCE 0x00000080
+#define ETH_RDES1_IPCB 0x00000040
+#define ETH_RDES1_IPV6 0x00000020
+#define ETH_RDES1_IPV4 0x00000010
+#define ETH_RDES1_IPHE 0x00000008
+#define ETH_RDES1_PT 0x00000007
+#define ETH_RDES2_L3L4FM 0xE0000000
+#define ETH_RDES2_L4FM 0x10000000
+#define ETH_RDES2_L3FM 0x08000000
+#define ETH_RDES2_MADRM 0x07F80000
+#define ETH_RDES2_HF 0x00040000
+#define ETH_RDES2_DAF 0x00020000
+#define ETH_RDES2_SAF 0x00010000
+#define ETH_RDES2_VF 0x00008000
+#define ETH_RDES2_ARPRN 0x00000400
+#define ETH_RDES3_OWN 0x80000000
+#define ETH_RDES3_CTXT 0x40000000
+#define ETH_RDES3_FD 0x20000000
+#define ETH_RDES3_LD 0x10000000
+#define ETH_RDES3_RS2V 0x08000000
+#define ETH_RDES3_RS1V 0x04000000
+#define ETH_RDES3_RS0V 0x02000000
+#define ETH_RDES3_CE 0x01000000
+#define ETH_RDES3_GP 0x00800000
+#define ETH_RDES3_RWT 0x00400000
+#define ETH_RDES3_OE 0x00200000
+#define ETH_RDES3_RE 0x00100000
+#define ETH_RDES3_DE 0x00080000
+#define ETH_RDES3_LT 0x00070000
+#define ETH_RDES3_ES 0x00008000
+#define ETH_RDES3_PL 0x00007FFF
+
+/* Receive context descriptor */
+#define ETH_RDES0_RTSL 0xFFFFFFFF
+#define ETH_RDES1_RTSH 0xFFFFFFFF
+#define ETH_RDES3_OWN 0x80000000
+#define ETH_RDES3_CTXT 0x40000000
+
+#define RTL8211F_BMCR ((uint16_t)0x0000U) /* Basic Mode Control Register. */
+#define RTL8211F_BMSR ((uint16_t)0x0001U) /* Basic Mode Status Register. */
+#define RTL8211F_PHYID1 ((uint16_t)0x0002U) /* PHY Identifier Register 1. */
+#define RTL8211F_PHYID2 ((uint16_t)0x0003U) /* PHY Identifier Register 2. */
+#define RTL8211F_ANAR ((uint16_t)0x0004U) /* Auto-Negotiation Advertising Register. */
+#define RTL8211F_ANLPAR ((uint16_t)0x0005U) /* Auto-Negotiation Link Partner Ability Register. */
+#define RTL8211F_ANER ((uint16_t)0x0006U) /* Auto-Negotiation Expansion Register.*/
+#define RTL8211F_ANNPTR ((uint16_t)0x0007U) /* Auto-Negotiation Next Page Transmit Register.*/
+#define RTL8211F_ANNPRR ((uint16_t)0x0008U) /* Auto-Negotiation Next Page Receive Register. */
+#define RTL8211F_GBCR ((uint16_t)0x0009U) /* 1000Base-T Control Register. */
+#define RTL8211F_GBSR ((uint16_t)0x000AU) /* 1000Base-T Status Register. */
+#define RTL8211F_MMDACR ((uint16_t)0x000DU) /* MMD Access Control Register. */
+#define RTL8211F_MMDAADR ((uint16_t)0x000EU) /* MMD Access Address Data Register. */
+#define RTL8211F_GBESR ((uint16_t)0x000FU) /* 1000Base-T Extended Status Register. */
+#define RTL8211F_LCR ((uint16_t)0x0010U) /* LED Control Register. */
+#define RTL8211F_INER ((uint16_t)0x0012U) /* Interrupt Enable Register. */
+#define RTL8211F_PHYSCR ((uint16_t)0x0014U) /* PHY Special Cofig Register */
+#define RTL8211F_PHYCR1 ((uint16_t)0x0018U) /* PHY Specific Control Register 1. */
+#define RTL8211F_PHYCR2 ((uint16_t)0x0019U) /* PHY Specific Control Register 2. */
+#define RTL8211F_PHYSR ((uint16_t)0x001AU) /* PHY Specific Status Register. */
+#define RTL8211F_INSR ((uint16_t)0x001DU) /* Interrupt Status Register. */
+#define RTL8211F_PAGSR ((uint16_t)0x001FU) /* Page Select Register. */
+
+/* Basic Mode Control register */
+#define RTL8211F_BMCR_RESET 0x8000
+#define RTL8211F_BMCR_LOOPBACK 0x4000
+#define RTL8211F_BMCR_SPEED_SEL_LSB 0x2000
+#define RTL8211F_BMCR_AN_EN 0x1000
+#define RTL8211F_BMCR_POWER_DOWN 0x0800
+#define RTL8211F_BMCR_ISOLATE 0x0400
+#define RTL8211F_BMCR_RESTART_AN 0x0200
+#define RTL8211F_BMCR_DUPLEX_MODE 0x0100
+#define RTL8211F_BMCR_COL_TEST 0x0080
+#define RTL8211F_BMCR_SPEED_SEL_MSB 0x0040
+#define RTL8211F_BMCR_UNI_DIR_EN 0x0020
+
+/* Basic Mode Status register */
+#define RTL8211F_BMSR_100BT4 0x8000
+#define RTL8211F_BMSR_100BTX_FD 0x4000
+#define RTL8211F_BMSR_100BTX_HD 0x2000
+#define RTL8211F_BMSR_10BT_FD 0x1000
+#define RTL8211F_BMSR_10BT_HD 0x0800
+#define RTL8211F_BMSR_100BT2_FD 0x0400
+#define RTL8211F_BMSR_100BT2_HD 0x0200
+#define RTL8211F_BMSR_EXTENDED_STATUS 0x0100
+#define RTL8211F_BMSR_UNI_DIR_CAPABLE 0x0080
+#define RTL8211F_BMSR_PREAMBLE_SUPPR 0x0040
+#define RTL8211F_BMSR_AN_COMPLETE 0x0020
+#define RTL8211F_BMSR_REMOTE_FAULT 0x0010
+#define RTL8211F_BMSR_AN_CAPABLE 0x0008
+#define RTL8211F_BMSR_LINK_STATUS 0x0004
+#define RTL8211F_BMSR_JABBER_DETECT 0x0002
+#define RTL8211F_BMSR_EXTENDED_CAPABLE 0x0001
+
+/* PHY Identifier 1 register */
+#define RTL8211F_PHYID1_OUI_MSB 0xFFFF
+#define RTL8211F_PHYID1_OUI_MSB_DEFAULT 0x001C
+
+/* PHY Identifier 2 register */
+#define RTL8211F_PHYID2_OUI_LSB 0xFC00
+#define RTL8211F_PHYID2_OUI_LSB_DEFAULT 0xC800
+#define RTL8211F_PHYID2_MODEL_NUM 0x03F0
+#define RTL8211F_PHYID2_MODEL_NUM_DEFAULT 0x0110
+#define RTL8211F_PHYID2_REVISION_NUM 0x000F
+#define RTL8211F_PHYID2_REVISION_NUM_DEFAULT 0x0006
+
+/* Auto-Negotiation Advertisement register */
+#define RTL8211F_ANAR_NEXT_PAGE 0x8000
+#define RTL8211F_ANAR_REMOTE_FAULT 0x2000
+#define RTL8211F_ANAR_ASYM_PAUSE 0x0800
+#define RTL8211F_ANAR_PAUSE 0x0400
+#define RTL8211F_ANAR_100BT4 0x0200
+#define RTL8211F_ANAR_100BTX_FD 0x0100
+#define RTL8211F_ANAR_100BTX_HD 0x0080
+#define RTL8211F_ANAR_10BT_FD 0x0040
+#define RTL8211F_ANAR_10BT_HD 0x0020
+#define RTL8211F_ANAR_SELECTOR 0x001F
+#define RTL8211F_ANAR_SELECTOR_DEFAULT 0x0001
+
+/* Auto-Negotiation Link Partner Ability register */
+#define RTL8211F_ANLPAR_NEXT_PAGE 0x8000
+#define RTL8211F_ANLPAR_ACK 0x4000
+#define RTL8211F_ANLPAR_REMOTE_FAULT 0x2000
+#define RTL8211F_ANLPAR_ASYM_PAUSE 0x0800
+#define RTL8211F_ANLPAR_PAUSE 0x0400
+#define RTL8211F_ANLPAR_100BT4 0x0200
+#define RTL8211F_ANLPAR_100BTX_FD 0x0100
+#define RTL8211F_ANLPAR_100BTX_HD 0x0080
+#define RTL8211F_ANLPAR_10BT_FD 0x0040
+#define RTL8211F_ANLPAR_10BT_HD 0x0020
+#define RTL8211F_ANLPAR_SELECTOR 0x001F
+#define RTL8211F_ANLPAR_SELECTOR_DEFAULT 0x0001
+
+/* Auto-Negotiation Expansion register */
+#define RTL8211F_ANER_RX_NP_LOCATION_ABLE 0x0040
+#define RTL8211F_ANER_RX_NP_LOCATION 0x0020
+#define RTL8211F_ANER_PAR_DETECT_FAULT 0x0010
+#define RTL8211F_ANER_LP_NEXT_PAGE_ABLE 0x0008
+#define RTL8211F_ANER_NEXT_PAGE_ABLE 0x0004
+#define RTL8211F_ANER_PAGE_RECEIVED 0x0002
+#define RTL8211F_ANER_LP_AN_ABLE 0x0001
+
+/* Auto-Negotiation Next Page Transmit register */
+#define RTL8211F_ANNPTR_NEXT_PAGE 0x8000
+#define RTL8211F_ANNPTR_MSG_PAGE 0x2000
+#define RTL8211F_ANNPTR_ACK2 0x1000
+#define RTL8211F_ANNPTR_TOGGLE 0x0800
+#define RTL8211F_ANNPTR_MESSAGE 0x07FF
+
+/* Auto-Negotiation Next Page Receive register */
+#define RTL8211F_ANNPRR_NEXT_PAGE 0x8000
+#define RTL8211F_ANNPRR_ACK 0x4000
+#define RTL8211F_ANNPRR_MSG_PAGE 0x2000
+#define RTL8211F_ANNPRR_ACK2 0x1000
+#define RTL8211F_ANNPRR_TOGGLE 0x0800
+#define RTL8211F_ANNPRR_MESSAGE 0x07FF
+
+/* 1000Base-T Control register */
+#define RTL8211F_GBCR_TEST_MODE 0xE000
+#define RTL8211F_GBCR_MS_MAN_CONF_EN 0x1000
+#define RTL8211F_GBCR_MS_MAN_CONF_VAL 0x0800
+#define RTL8211F_GBCR_PORT_TYPE 0x0400
+#define RTL8211F_GBCR_1000BT_FD 0x0200
+
+/* 1000Base-T Status register */
+#define RTL8211F_GBSR_MS_CONF_FAULT 0x8000
+#define RTL8211F_GBSR_MS_CONF_RES 0x4000
+#define RTL8211F_GBSR_LOCAL_RECEIVER_STATUS 0x2000
+#define RTL8211F_GBSR_REMOTE_RECEIVER_STATUS 0x1000
+#define RTL8211F_GBSR_LP_1000BT_FD 0x0800
+#define RTL8211F_GBSR_LP_1000BT_HD 0x0400
+#define RTL8211F_GBSR_IDLE_ERR_COUNT 0x00FF
+
+/* MMD Access Control register */
+#define RTL8211F_MMDACR_FUNC 0xC000
+#define RTL8211F_MMDACR_FUNC_ADDR 0x0000
+#define RTL8211F_MMDACR_FUNC_DATA_NO_POST_INC 0x4000
+#define RTL8211F_MMDACR_FUNC_DATA_POST_INC_RW 0x8000
+#define RTL8211F_MMDACR_FUNC_DATA_POST_INC_W 0xC000
+#define RTL8211F_MMDACR_DEVAD 0x001F
+
+/* 1000Base-T Extended Status register */
+#define RTL8211F_GBESR_1000BX_FD 0x8000
+#define RTL8211F_GBESR_1000BX_HD 0x4000
+#define RTL8211F_GBESR_1000BT_FD 0x2000
+#define RTL8211F_GBESR_1000BT_HD 0x1000
+
+/* Interrupt Enable register */
+#define RTL8211F_INER_JABBER 0x0400
+#define RTL8211F_INER_ALDPS_STATE 0x0200
+#define RTL8211F_INER_PME 0x0080
+#define RTL8211F_INER_PHY_REG_ACCESS 0x0020
+#define RTL8211F_INER_LINK_STATUS 0x0010
+#define RTL8211F_INER_AN_COMPLETE 0x0008
+#define RTL8211F_INER_PAGE_RECEIVED 0x0004
+#define RTL8211F_INER_AN_ERROR 0x0001
+
+/* PHY Specific Control 1 register */
+#define RTL8211F_PHYCR1_PHYAD_0_EN 0x2000
+#define RTL8211F_PHYCR1_MDI_MODE_MANUAL_CONFIG 0x0200
+#define RTL8211F_PHYCR1_MDI_MODE 0x0100
+#define RTL8211F_PHYCR1_TX_CRS_EN 0x0080
+#define RTL8211F_PHYCR1_PHYAD_NON_ZERO_DETECT 0x0040
+#define RTL8211F_PHYCR1_PREAMBLE_CHECK_EN 0x0010
+#define RTL8211F_PHYCR1_JABBER_DETECT_EN 0x0008
+#define RTL8211F_PHYCR1_ALDPS_EN 0x0004
+
+/* PHY Specific Control 2 register */
+#define RTL8211F_PHYCR2_CLKOUT_FREQ_SEL 0x0800
+#define RTL8211F_PHYCR2_CLKOUT_SSC_EN 0x0080
+#define RTL8211F_PHYCR2_RXC_SSC_EN 0x0008
+#define RTL8211F_PHYCR2_RXC_EN 0x0002
+#define RTL8211F_PHYCR2_CLKOUT_EN 0x0001
+
+/* PHY Specific Status register */
+#define RTL8211F_PHYSR_ALDPS_STATE 0x4000
+#define RTL8211F_PHYSR_MDI_PLUG 0x2000
+#define RTL8211F_PHYSR_NWAY_EN 0x1000
+#define RTL8211F_PHYSR_MASTER_MODE 0x0800
+#define RTL8211F_PHYSR_EEE_CAPABLE 0x0100
+#define RTL8211F_PHYSR_RX_FLOW_EN 0x0080
+#define RTL8211F_PHYSR_TX_FLOW_EN 0x0040
+#define RTL8211F_PHYSR_SPEED 0x0030
+#define RTL8211F_PHYSR_SPEED_10MBPS 0x0000
+#define RTL8211F_PHYSR_SPEED_100MBPS 0x0010
+#define RTL8211F_PHYSR_SPEED_1000MBPS 0x0020
+#define RTL8211F_PHYSR_DUPLEX 0x0008
+#define RTL8211F_PHYSR_LINK 0x0004
+#define RTL8211F_PHYSR_MDI_CROSSOVER_STATUS 0x0002
+#define RTL8211F_PHYSR_JABBER 0x0001
+
+/* Interrupt Status register */
+#define RTL8211F_INSR_JABBER 0x0400
+#define RTL8211F_INSR_ALDPS_STATE 0x0200
+#define RTL8211F_INSR_PME 0x0080
+#define RTL8211F_INSR_PHY_REG_ACCESS 0x0020
+#define RTL8211F_INSR_LINK_STATUS 0x0010
+#define RTL8211F_INSR_AN_COMPLETE 0x0008
+#define RTL8211F_INSR_PAGE_RECEIVED 0x0004
+#define RTL8211F_INSR_AN_ERROR 0x0001
+
+/* Page Select register */
+#define RTL8211F_PAGSR_PAGE_SEL 0x0007
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_pmic.c b/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_pmic.c
index 95e385f1b8..c5f26596cc 100644
--- a/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_pmic.c
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_pmic.c
@@ -19,6 +19,8 @@
#define LOG_TAG "drv.pmic"
#include <drv_log.h>
+#define I2C_NAME "i2c3"
+
static struct rt_i2c_bus_device *pmic_dev = RT_NULL;
/* i2c read reg */
@@ -796,47 +798,47 @@ static rt_err_t rt_hw_pmic_init_register(void)
stpmu1_write_reg(BUCK_ICC_TURNOFF_REG, 0x30);
stpmu1_write_reg(LDO_ICC_TURNOFF_REG, 0x3b);
- /* vddcore */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK1, 1200);
- STPMU1_Regulator_Enable(STPMU1_BUCK1);
+ /* vddcore */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK1, 1200);
+ STPMU1_Regulator_Enable(STPMU1_BUCK1);
- /* vddddr */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK2, 1350);
- STPMU1_Regulator_Enable(STPMU1_BUCK2);
+ /* vddddr */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK2, 1350);
+ STPMU1_Regulator_Enable(STPMU1_BUCK2);
- /* vdd */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK3, 3300);
- STPMU1_Regulator_Enable(STPMU1_BUCK3);
+ /* vdd */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK3, 3300);
+ STPMU1_Regulator_Enable(STPMU1_BUCK3);
- /* 3v3 */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK4, 3300);
- STPMU1_Regulator_Enable(STPMU1_BUCK4);
+// /* 3v3 */
+// STPMU1_Regulator_Voltage_Set(STPMU1_BUCK4, 3300);
+// STPMU1_Regulator_Enable(STPMU1_BUCK4);
- /* vdda */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO1, 2900);
- STPMU1_Regulator_Enable(STPMU1_LDO1);
+ /* 1v8_audio */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO1, 1800);
+ STPMU1_Regulator_Enable(STPMU1_LDO1);
- /* 2v8 */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO2, 2800);
- STPMU1_Regulator_Enable(STPMU1_LDO2);
+ /* vdd_emmc */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO2, 2900);
+ STPMU1_Regulator_Enable(STPMU1_LDO2);
- /* vtt_ddr lod3 mode buck2/2 */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO3, 0xFFFF);
- STPMU1_Regulator_Enable(STPMU1_LDO3);
+ /* vdd1_ddr */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO3, 0xFFFF);
+ STPMU1_Regulator_Enable(STPMU1_LDO3);
- /* vdd_usb */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO4, 3300);
- STPMU1_Regulator_Enable(STPMU1_LDO4);
+ /* vdd_usb */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO4, 3300);
+ STPMU1_Regulator_Enable(STPMU1_LDO4);
- /* vdd_sd */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO5, 2900);
- STPMU1_Regulator_Enable(STPMU1_LDO5);
+ /* vdda */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO5, 2900);
+ STPMU1_Regulator_Enable(STPMU1_LDO5);
- /* 1v8 */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO6, 1800);
- STPMU1_Regulator_Enable(STPMU1_LDO6);
+ /* 2v8 */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO6, 2800);
+ STPMU1_Regulator_Enable(STPMU1_LDO6);
- STPMU1_Regulator_Enable(STPMU1_VREFDDR);
+ STPMU1_Regulator_Enable(STPMU1_VREFDDR);
return RT_EOK;
}
@@ -884,7 +886,7 @@ static int pmic_init(void)
{
BSP_PMIC_MspInit();
- result = rt_hw_pmic_init("i2c3");
+ result = rt_hw_pmic_init(I2C_NAME);
if(result != RT_EOK)
{
LOG_D("stpmic init failed: %02x", result);
@@ -893,10 +895,7 @@ static int pmic_init(void)
}
rt_hw_pmic_init_register();
- }
-
- if(IS_ENGINEERING_BOOT_MODE())
- {
+
__HAL_RCC_VREF_CLK_ENABLE();
HAL_SYSCFG_VREFBUF_HighImpedanceConfig(SYSCFG_VREFBUF_HIGH_IMPEDANCE_DISABLE);
HAL_SYSCFG_EnableVREFBUF();
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_sdio.c b/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_sdio.c
new file mode 100644
index 0000000000..3e5085c3cd
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_sdio.c
@@ -0,0 +1,555 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-16 thread-liu first version
+ */
+
+#include "board.h"
+#include "drv_sdio.h"
+#include <dfs_fs.h>
+
+#ifdef BSP_USING_SDMMC
+
+//#define DRV_DEBUG
+#define DBG_TAG "drv.sdio"
+#ifdef DRV_DEBUG
+#define DBG_LVL DBG_LOG
+#else
+#define DBG_LVL DBG_INFO
+#endif /* DRV_DEBUG */
+#include <rtdbg.h>
+
+static SD_HandleTypeDef hsd;
+static struct rt_mmcsd_host *host;
+#define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS (100000)
+
+#define RTHW_SDIO_LOCK(_sdio) rt_mutex_take(&_sdio->mutex, RT_WAITING_FOREVER)
+#define RTHW_SDIO_UNLOCK(_sdio) rt_mutex_release(&_sdio->mutex);
+
+struct sdio_pkg
+{
+ struct rt_mmcsd_cmd *cmd;
+ void *buff;
+ rt_uint32_t flag;
+};
+
+struct rthw_sdio
+{
+ struct rt_mmcsd_host *host;
+ struct stm32_sdio_des sdio_des;
+ struct rt_event event;
+ struct rt_mutex mutex;
+ struct sdio_pkg *pkg;
+};
+
+/* SYSRAM SDMMC1/2 accesses */
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+rt_uint8_t cache_buf[SDIO_BUFF_SIZE] __attribute__((at(0x2FFC0000)));
+#elif defined(__ICCARM__)
+#pragma location=0x2FFC0000
+rt_uint8_t cache_buf[SDIO_BUFF_SIZE];
+#elif defined(__GNUC__)
+rt_uint8_t cache_buf[SDIO_BUFF_SIZE] __attribute__((at(0x2FFC0000)));
+#endif
+
+/**
+ * @brief This function get order from sdio.
+ * @param data
+ * @retval sdio order
+ */
+static int get_order(rt_uint32_t data)
+{
+ int order = 0;
+
+ switch (data)
+ {
+ case 1:
+ order = 0;
+ break;
+ case 2:
+ order = 1;
+ break;
+ case 4:
+ order = 2;
+ break;
+ case 8:
+ order = 3;
+ break;
+ case 16:
+ order = 4;
+ break;
+ case 32:
+ order = 5;
+ break;
+ case 64:
+ order = 6;
+ break;
+ case 128:
+ order = 7;
+ break;
+ case 256:
+ order = 8;
+ break;
+ case 512:
+ order = 9;
+ break;
+ case 1024:
+ order = 10;
+ break;
+ case 2048:
+ order = 11;
+ break;
+ case 4096:
+ order = 12;
+ break;
+ case 8192:
+ order = 13;
+ break;
+ case 16384:
+ order = 14;
+ break;
+ default :
+ order = 0;
+ break;
+ }
+ return order;
+}
+
+/**
+ * @brief This function wait sdio cmd completed.
+ * @param sdio rthw_sdio
+ * @retval None
+ */
+static void rthw_sdio_wait_completed(struct rthw_sdio *sdio)
+{
+ rt_uint32_t status;
+ struct rt_mmcsd_cmd *cmd = sdio->pkg->cmd;
+ struct rt_mmcsd_data *data = cmd->data;
+ struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
+
+ if (rt_event_recv(&sdio->event, 0xffffffff, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ rt_tick_from_millisecond(5000), &status) != RT_EOK)
+ {
+ LOG_E("wait cmd completed timeout");
+ cmd->err = -RT_ETIMEOUT;
+ return;
+ }
+
+ if (sdio->pkg == RT_NULL)
+ {
+ return;
+ }
+
+ cmd->resp[0] = hw_sdio->resp1;
+ cmd->resp[1] = hw_sdio->resp2;
+ cmd->resp[2] = hw_sdio->resp3;
+ cmd->resp[3] = hw_sdio->resp4;
+
+ if (status & SDIO_ERRORS)
+ {
+ if ((status & SDMMC_STA_CCRCFAIL) && (resp_type(cmd) & (RESP_R3 | RESP_R4)))
+ {
+ cmd->err = RT_EOK;
+ }
+ else
+ {
+ cmd->err = -RT_ERROR;
+ }
+
+ if (status & SDMMC_STA_CTIMEOUT)
+ {
+ cmd->err = -RT_ETIMEOUT;
+ }
+
+ if (status & SDMMC_STA_DCRCFAIL)
+ {
+ data->err = -RT_ERROR;
+ }
+
+ if (status & SDMMC_STA_DTIMEOUT)
+ {
+ data->err = -RT_ETIMEOUT;
+ }
+
+ if (cmd->err == RT_EOK)
+ {
+ LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
+ }
+ else
+ {
+ LOG_D("err:0x%08x, %s%s%s%s%s%s%s cmd:%d arg:0x%08x rw:%c len:%d blksize:%d",
+ status,
+ status & SDMMC_STA_CCRCFAIL ? "CCRCFAIL " : "",
+ status & SDMMC_STA_DCRCFAIL ? "DCRCFAIL " : "",
+ status & SDMMC_STA_CTIMEOUT ? "CTIMEOUT " : "",
+ status & SDMMC_STA_DTIMEOUT ? "DTIMEOUT " : "",
+ status & SDMMC_STA_TXUNDERR ? "TXUNDERR " : "",
+ status & SDMMC_STA_RXOVERR ? "RXOVERR " : "",
+ status == 0 ? "NULL" : "",
+ cmd->cmd_code,
+ cmd->arg,
+ data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-',
+ data ? data->blks * data->blksize : 0,
+ data ? data->blksize : 0
+ );
+ }
+
+ }
+ else
+ {
+ cmd->err = RT_EOK;
+ LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
+ }
+}
+
+/**
+ * @brief This function send command.
+ * @param sdio rthw_sdio
+ * @param pkg sdio package
+ * @retval None
+ */
+static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
+{
+ struct rt_mmcsd_cmd *cmd = pkg->cmd;
+ struct rt_mmcsd_data *data = cmd->data;
+ struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
+ rt_uint32_t reg_cmd;
+
+ sdio->pkg = pkg;
+
+ LOG_D("CMD:%d ARG:0x%08x RES:%s%s%s%s%s%s%s%s%s rw:%c len:%d blksize:%d\n",
+ cmd->cmd_code,
+ cmd->arg,
+ resp_type(cmd) == RESP_NONE ? "NONE" : "",
+ resp_type(cmd) == RESP_R1 ? "R1" : "",
+ resp_type(cmd) == RESP_R1B ? "R1B" : "",
+ resp_type(cmd) == RESP_R2 ? "R2" : "",
+ resp_type(cmd) == RESP_R3 ? "R3" : "",
+ resp_type(cmd) == RESP_R4 ? "R4" : "",
+ resp_type(cmd) == RESP_R5 ? "R5" : "",
+ resp_type(cmd) == RESP_R6 ? "R6" : "",
+ resp_type(cmd) == RESP_R7 ? "R7" : "",
+ data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-',
+ data ? data->blks * data->blksize : 0,
+ data ? data->blksize : 0
+ );
+
+ /* config cmd reg */
+ reg_cmd = cmd->cmd_code | SDMMC_CMD_CPSMEN;
+ if (resp_type(cmd) == RESP_NONE)
+ reg_cmd |= SDMMC_RESPONSE_NO;
+ else if (resp_type(cmd) == RESP_R2)
+ reg_cmd |= SDMMC_RESPONSE_LONG;
+ else
+ reg_cmd |= SDMMC_RESPONSE_SHORT;
+
+ hw_sdio->mask |= SDIO_MASKR_ALL;
+
+ /* data pre configuration */
+ if (data != RT_NULL)
+ {
+ hw_sdio->dctrl = 0;
+ hw_sdio->mask &= ~(SDMMC_MASK_CMDRENDIE | SDMMC_MASK_CMDSENTIE);
+ reg_cmd |= SDMMC_CMD_CMDTRANS;
+ hw_sdio->dtimer = HW_SDIO_DATATIMEOUT;
+ hw_sdio->dlen = data->blks * data->blksize;
+ hw_sdio->dctrl = (get_order(data->blksize)<<4) | (data->flags & DATA_DIR_READ ? SDMMC_DCTRL_DTDIR : 0);
+ hw_sdio->idmabase0r = (rt_uint32_t)cache_buf;
+ hw_sdio->idmatrlr = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
+ }
+
+ hw_sdio->arg = cmd->arg;
+ hw_sdio->cmd = reg_cmd;
+ /* wait completed */
+ rthw_sdio_wait_completed(sdio);
+
+ /* Waiting for data to be sent to completion */
+ if (data != RT_NULL)
+ {
+ volatile rt_uint32_t count = SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS;
+
+ while (count && (hw_sdio->sta & SDMMC_STA_DPSMACT))
+ {
+ count--;
+ }
+ if ((count == 0) || (hw_sdio->sta & SDIO_ERRORS))
+ {
+ cmd->err = -RT_ERROR;
+ }
+ }
+
+ /* close irq, keep sdio irq */
+ hw_sdio->mask = hw_sdio->mask & SDMMC_IT_SDIOIT ? SDMMC_IT_SDIOIT : 0x00;
+
+ /* data post configuration */
+ if (data != RT_NULL)
+ {
+ if (data->flags & DATA_DIR_READ)
+ {
+ rt_memcpy(data->buf, cache_buf, data->blks * data->blksize);
+ }
+ }
+}
+
+/**
+ * @brief This function send sdio request.
+ * @param sdio rthw_sdio
+ * @param req request
+ * @retval None
+ */
+static void rthw_sdio_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
+{
+ struct sdio_pkg pkg;
+ struct rthw_sdio *sdio = host->private_data;
+ struct rt_mmcsd_data *data;
+
+ RTHW_SDIO_LOCK(sdio);
+
+ if (req->cmd != RT_NULL)
+ {
+ rt_memset(&pkg, 0, sizeof(pkg));
+ data = req->cmd->data;
+ pkg.cmd = req->cmd;
+
+ if (data != RT_NULL)
+ {
+ rt_uint32_t size = data->blks * data->blksize;
+
+ RT_ASSERT(size <= SDIO_BUFF_SIZE);
+
+ if (data->flags & DATA_DIR_WRITE)
+ {
+ rt_memcpy(cache_buf, data->buf, size);
+ }
+ }
+
+ rthw_sdio_send_command(sdio, &pkg);
+ }
+
+ if (req->stop != RT_NULL)
+ {
+ rt_memset(&pkg, 0, sizeof(pkg));
+ pkg.cmd = req->stop;
+ rthw_sdio_send_command(sdio, &pkg);
+ }
+
+ RTHW_SDIO_UNLOCK(sdio);
+
+ mmcsd_req_complete(sdio->host);
+}
+
+
+/**
+ * @brief This function interrupt process function.
+ * @param host rt_mmcsd_host
+ * @retval None
+ */
+void rthw_sdio_irq_process(struct rt_mmcsd_host *host)
+{
+ struct rthw_sdio *sdio = host->private_data;
+ struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
+ rt_uint32_t intstatus = hw_sdio->sta;
+
+ /* clear irq flag*/
+ hw_sdio->icr = intstatus;
+
+ rt_event_send(&sdio->event, intstatus);
+}
+
+/**
+ * @brief This function config sdio.
+ * @param host rt_mmcsd_host
+ * @param io_cfg rt_mmcsd_io_cfg
+ * @retval None
+ */
+static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
+{
+ rt_uint32_t temp, clk_src;
+ rt_uint32_t clk = io_cfg->clock;
+ struct rthw_sdio *sdio = host->private_data;
+ struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
+
+ LOG_D("clk:%dK width:%s%s%s power:%s%s%s",
+ clk/1000,
+ io_cfg->bus_width == MMCSD_BUS_WIDTH_8 ? "8" : "",
+ io_cfg->bus_width == MMCSD_BUS_WIDTH_4 ? "4" : "",
+ io_cfg->bus_width == MMCSD_BUS_WIDTH_1 ? "1" : "",
+ io_cfg->power_mode == MMCSD_POWER_OFF ? "OFF" : "",
+ io_cfg->power_mode == MMCSD_POWER_UP ? "UP" : "",
+ io_cfg->power_mode == MMCSD_POWER_ON ? "ON" : ""
+ );
+
+ RTHW_SDIO_LOCK(sdio);
+
+ clk_src = SDIO_CLOCK_FREQ;
+
+ if (clk > 0)
+ {
+ if (clk > host->freq_max)
+ {
+ clk = host->freq_max;
+ }
+ temp = DIV_ROUND_UP(clk_src, 2 * clk);
+ if (temp > 0x3FF)
+ {
+ temp = 0x3FF;
+ }
+ }
+
+ if (io_cfg->bus_width == MMCSD_BUS_WIDTH_8)
+ {
+ temp |= SDMMC_BUS_WIDE_8B;
+ }
+ else if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
+ {
+ temp |= SDMMC_BUS_WIDE_4B;
+ }
+ else
+ {
+ temp |= SDMMC_BUS_WIDE_1B;
+ }
+
+ hw_sdio->clkcr = temp;
+
+ if (io_cfg->power_mode == MMCSD_POWER_ON)
+ hw_sdio->power |= SDMMC_POWER_PWRCTRL;
+
+ RTHW_SDIO_UNLOCK(sdio);
+}
+
+static const struct rt_mmcsd_host_ops ops =
+{
+ rthw_sdio_request,
+ rthw_sdio_iocfg,
+ RT_NULL,
+ RT_NULL,
+};
+
+/**
+ * @brief This function create mmcsd host.
+ * @param sdio_des stm32_sdio_des
+ * @retval rt_mmcsd_host
+ */
+struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
+{
+ struct rt_mmcsd_host *host;
+ struct rthw_sdio *sdio = RT_NULL;
+
+ if (sdio_des == RT_NULL)
+ {
+ return RT_NULL;
+ }
+
+ sdio = rt_malloc(sizeof(struct rthw_sdio));
+ if (sdio == RT_NULL)
+ {
+ LOG_E("malloc rthw_sdio fail");
+ return RT_NULL;
+ }
+ rt_memset(sdio, 0, sizeof(struct rthw_sdio));
+
+ host = mmcsd_alloc_host();
+ if (host == RT_NULL)
+ {
+ LOG_E("alloc host fail");
+ goto err;
+ }
+
+ rt_memcpy(&sdio->sdio_des, sdio_des, sizeof(struct stm32_sdio_des));
+
+ sdio->sdio_des.hw_sdio = (struct stm32_sdio *)SDIO_BASE_ADDRESS;
+
+ rt_event_init(&sdio->event, "sdio", RT_IPC_FLAG_FIFO);
+ rt_mutex_init(&sdio->mutex, "sdio", RT_IPC_FLAG_FIFO);
+ /* set host default attributes */
+ host->ops = &ops;
+ host->freq_min = 400 * 1000;
+ host->freq_max = SDIO_MAX_FREQ;
+ host->valid_ocr = 0X00FFFF80;/* The voltage range supported is 1.65v-3.6v */
+#ifndef SDIO_USING_1_BIT
+ host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED;
+#else
+ host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED;
+#endif
+
+ host->max_seg_size = SDIO_BUFF_SIZE;
+ host->max_dma_segs = 1;
+ host->max_blk_size = 512;
+ host->max_blk_count = 512;
+
+ /* link up host and sdio */
+ sdio->host = host;
+ host->private_data = sdio;
+
+ /* ready to change */
+ mmcsd_change(host);
+
+ return host;
+
+err:
+ if (sdio)
+ {
+ rt_free(sdio);
+ }
+
+ return RT_NULL;
+}
+
+void SDMMC1_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ /* Process All SDIO Interrupt Sources */
+ rthw_sdio_irq_process(host);
+
+ rt_interrupt_leave();
+}
+
+int rt_hw_sdio_init(void)
+{
+ struct stm32_sdio_des sdio_des;
+
+ hsd.Instance = SDMMC1;
+ HAL_SD_MspInit(&hsd);
+
+ host = sdio_host_create(&sdio_des);
+ if (host == RT_NULL)
+ {
+ LOG_E("host create fail");
+ return RT_NULL;
+ }
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_sdio_init);
+
+int mnt_init(void)
+{
+ rt_device_t sd = RT_NULL;
+
+ rt_thread_delay(RT_TICK_PER_SECOND);
+
+ sd = rt_device_find("sd0");
+ if (sd == RT_NULL)
+ {
+ rt_kprintf("can't find sd0 device!\n");
+ return RT_ERROR;
+ }
+
+ if (dfs_mount("sd0", "/", "elm", 0, 0) != 0)
+ {
+ rt_kprintf("file system mount failed!\n");
+ }
+ else
+ {
+ rt_kprintf("file system mount success!\n");
+ }
+
+ return RT_EOK;
+}
+INIT_ENV_EXPORT(mnt_init);
+
+#endif /* BSP_USING_SDMMC */
diff --git a/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_sdio.h b/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_sdio.h
new file mode 100644
index 0000000000..a4428e4e71
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-discovery/board/ports/drv_sdio.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2006-2020, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-16 thread-liu first version
+ */
+
+#ifndef __DRV_SDIO_H__
+#define __DRV_SDIO_H__
+
+#include <rtthread.h>
+#include "rtdevice.h"
+#include <rthw.h>
+#include <drv_common.h>
+#include <string.h>
+#include <drivers/mmcsd_core.h>
+#include <drivers/sdio.h>
+
+#define SDIO_BUFF_SIZE 4096
+#define SDIO_ALIGN_LEN 32
+
+#ifndef SDIO_BASE_ADDRESS
+#define SDIO_BASE_ADDRESS (SDMMC1)
+#endif
+
+#ifndef SDIO_CLOCK_FREQ
+#define SDIO_CLOCK_FREQ (99U * 1000 * 1000)
+#endif
+
+#ifndef SDIO_BUFF_SIZE
+#define SDIO_BUFF_SIZE (4096)
+#endif
+
+#ifndef SDIO_ALIGN_LEN
+#define SDIO_ALIGN_LEN (32)
+#endif
+
+#ifndef SDIO_MAX_FREQ
+#define SDIO_MAX_FREQ (50 * 1000 * 1000)
+#endif
+
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
+#define SDMMC_POWER_OFF (0x00U)
+#define SDMMC_POWER_UP (0x02U)
+#define SDMMC_POWER_ON (0x03U)
+
+#define SDIO_ERRORS \
+ (SDMMC_STA_IDMATE | SDMMC_STA_ACKTIMEOUT | \
+ SDMMC_STA_RXOVERR | SDMMC_STA_TXUNDERR | \
+ SDMMC_STA_DTIMEOUT | SDMMC_STA_CTIMEOUT | \
+ SDMMC_STA_DCRCFAIL | SDMMC_STA_CCRCFAIL)
+
+#define SDIO_MASKR_ALL \
+ (SDMMC_MASK_CCRCFAILIE | SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_CTIMEOUTIE | \
+ SDMMC_MASK_TXUNDERRIE | SDMMC_MASK_RXOVERRIE | SDMMC_MASK_CMDRENDIE | \
+ SDMMC_MASK_CMDSENTIE | SDMMC_MASK_DATAENDIE | SDMMC_MASK_ACKTIMEOUTIE)
+
+#define HW_SDIO_DATATIMEOUT (0xFFFFFFFFU)
+
+struct stm32_sdio
+{
+ volatile rt_uint32_t power; /* offset 0x00 */
+ volatile rt_uint32_t clkcr; /* offset 0x04 */
+ volatile rt_uint32_t arg; /* offset 0x08 */
+ volatile rt_uint32_t cmd; /* offset 0x0C */
+ volatile rt_uint32_t respcmd; /* offset 0x10 */
+ volatile rt_uint32_t resp1; /* offset 0x14 */
+ volatile rt_uint32_t resp2; /* offset 0x18 */
+ volatile rt_uint32_t resp3; /* offset 0x1C */
+ volatile rt_uint32_t resp4; /* offset 0x20 */
+ volatile rt_uint32_t dtimer; /* offset 0x24 */
+ volatile rt_uint32_t dlen; /* offset 0x28 */
+ volatile rt_uint32_t dctrl; /* offset 0x2C */
+ volatile rt_uint32_t dcount; /* offset 0x30 */
+ volatile rt_uint32_t sta; /* offset 0x34 */
+ volatile rt_uint32_t icr; /* offset 0x38 */
+ volatile rt_uint32_t mask; /* offset 0x3C */
+ volatile rt_uint32_t acktimer; /* offset 0x40 */
+ volatile rt_uint32_t reserved0[3]; /* offset 0x44 ~ 0x4C */
+ volatile rt_uint32_t idmatrlr; /* offset 0x50 */
+ volatile rt_uint32_t idmabsizer; /* offset 0x54 */
+ volatile rt_uint32_t idmabase0r; /* offset 0x58 */
+ volatile rt_uint32_t idmabase1r; /* offset 0x5C */
+ volatile rt_uint32_t reserved1[1]; /* offset 0x60 */
+ volatile rt_uint32_t idmalar;
+ volatile rt_uint32_t idmabar;
+ volatile rt_uint32_t reserved2[5];
+ volatile rt_uint32_t fifo;
+ volatile rt_uint32_t reserved3[220];
+ volatile rt_uint32_t verr;
+ volatile rt_uint32_t ipidr;
+ volatile rt_uint32_t sidr;
+};
+
+typedef rt_uint32_t (*sdio_clk_get)(struct stm32_sdio *hw_sdio);
+
+struct stm32_sdio_des
+{
+ struct stm32_sdio *hw_sdio;
+ sdio_clk_get clk_get;
+};
+
+/* stm32 sdio dirver class */
+struct stm32_sdio_class
+{
+ struct stm32_sdio_des *des;
+ const struct stm32_sdio_config *cfg;
+ struct rt_mmcsd_host host;
+};
+
+extern void stm32_mmcsd_change(void);
+
+#endif /* __DRV_SDIO_H__ */
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
index 424bdc02a2..39709fbedc 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
@@ -34,16 +34,16 @@
#define HAL_MODULE_ENABLED
#define HAL_ADC_MODULE_ENABLED
/*#define HAL_CEC_MODULE_ENABLED */
-/*#define HAL_CRC_MODULE_ENABLED */
-/*#define HAL_CRYP_MODULE_ENABLED */
+#define HAL_CRC_MODULE_ENABLED
+#define HAL_CRYP_MODULE_ENABLED
#define HAL_DAC_MODULE_ENABLED
-/*#define HAL_DCMI_MODULE_ENABLED */
+#define HAL_DCMI_MODULE_ENABLED
/*#define HAL_DSI_MODULE_ENABLED */
-/*#define HAL_DFSDM_MODULE_ENABLED */
+#define HAL_DFSDM_MODULE_ENABLED
/*#define HAL_DTS_MODULE_ENABLED */
/*#define HAL_ETH_MODULE_ENABLED */
-/*#define HAL_FDCAN_MODULE_ENABLED */
-/*#define HAL_HASH_MODULE_ENABLED */
+#define HAL_FDCAN_MODULE_ENABLED
+#define HAL_HASH_MODULE_ENABLED
/*#define HAL_HCD_MODULE_ENABLED */
#define HAL_HSEM_MODULE_ENABLED
#define HAL_I2C_MODULE_ENABLED
@@ -55,14 +55,14 @@
/*#define HAL_NAND_MODULE_ENABLED */
/*#define HAL_NOR_MODULE_ENABLED */
/*#define HAL_PCD_MODULE_ENABLED */
-/*#define HAL_QSPI_MODULE_ENABLED */
-/*#define HAL_RNG_MODULE_ENABLED */
-/*#define HAL_SAI_MODULE_ENABLED */
-/*#define HAL_SD_MODULE_ENABLED */
+#define HAL_QSPI_MODULE_ENABLED
+#define HAL_RNG_MODULE_ENABLED
+#define HAL_SAI_MODULE_ENABLED
+#define HAL_SD_MODULE_ENABLED
/*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_RTC_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
-/*#define HAL_SPDIFRX_MODULE_ENABLED */
+#define HAL_SPDIFRX_MODULE_ENABLED
#define HAL_SPI_MODULE_ENABLED
/*#define HAL_SRAM_MODULE_ENABLED */
/*#define HAL_TAMP_MODULE_ENABLED */
@@ -153,6 +153,8 @@
#define CSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* CSI_VALUE */
+#define USE_SD_TRANSCEIVER 1U
+
/**
* @brief External clock source for I2S peripheral
* This value is used by the I2S HAL module to compute the I2S clock source
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
index 5e6a4a3d34..6442f98075 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
@@ -26,7 +26,15 @@
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
-
+DMA_HandleTypeDef hdma_hash_in = {0};
+DMA_HandleTypeDef hdma_cryp_in = {0};
+DMA_HandleTypeDef hdma_cryp_out = {0};
+DMA_HandleTypeDef hdma_sai2_a = {0};
+DMA_HandleTypeDef hdma_sai2_b = {0};
+DMA_HandleTypeDef hdma_sai4_a = {0};
+DMA_HandleTypeDef hdma_spdifrx_rx = {0};
+DMA_HandleTypeDef hdma_dfsdm1_flt0 = {0};
+DMA_HandleTypeDef hdma_dfsdm1_flt1 = {0};
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
@@ -289,7 +297,7 @@ void HAL_LPTIM_MspInit(LPTIM_HandleTypeDef* hlptim)
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1;
- PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_PCLK1;
+ PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
@@ -512,17 +520,17 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
- if(hspi->Instance==SPI5)
+ if(hspi->Instance==SPI1)
{
- /* USER CODE BEGIN SPI5_MspInit 0 */
+ /* USER CODE BEGIN SPI1_MspInit 0 */
- /* USER CODE END SPI5_MspInit 0 */
+ /* USER CODE END SPI1_MspInit 0 */
if(IS_ENGINEERING_BOOT_MODE())
{
/** Initializes the peripherals clock
*/
- PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI45;
- PeriphClkInit.Spi45ClockSelection = RCC_SPI45CLKSOURCE_PCLK2;
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPI1;
+ PeriphClkInit.Spi1ClockSelection = RCC_SPI1CLKSOURCE_PLL4;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
@@ -531,19 +539,20 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
}
/* Peripheral clock enable */
- __HAL_RCC_SPI5_CLK_ENABLE();
+ __HAL_RCC_SPI1_CLK_ENABLE();
- __HAL_RCC_GPIOF_CLK_ENABLE();
- /**SPI5 GPIO Configuration
- PF9 ------> SPI5_MOSI
- PF7 ------> SPI5_SCK
+ __HAL_RCC_GPIOZ_CLK_ENABLE();
+ /**SPI1 GPIO Configuration
+ PZ2 ------> SPI1_MOSI
+ PZ1 ------> SPI1_MISO
+ PZ0 ------> SPI1_SCK
*/
- GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_7;
+ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
- GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
- HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+ GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
+ HAL_GPIO_Init(GPIOZ, &GPIO_InitStruct);
/* USER CODE BEGIN SPI5_MspInit 1 */
@@ -966,6 +975,1100 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hI2c)
}
/**
+* @brief SD MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hsd: SD handle pointer
+* @retval None
+*/
+void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+ if(hsd->Instance==SDMMC1)
+ {
+ /* USER CODE BEGIN SDMMC1_MspInit 0 */
+ if (IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.Sdmmc12ClockSelection = RCC_SDMMC12CLKSOURCE_PLL4;
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC12;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+ /* USER CODE END SDMMC1_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SDMMC1_CLK_ENABLE();
+
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ /**SDMMC1 GPIO Configuration
+ PB9 ------> SDMMC1_CDIR
+ PC7 ------> SDMMC1_D123DIR
+ PC8 ------> SDMMC1_D0
+ PC9 ------> SDMMC1_D1
+ PC10 ------> SDMMC1_D2
+ PC11 ------> SDMMC1_D3
+ PC12 ------> SDMMC1_CK
+ PD2 ------> SDMMC1_CMD
+ PE4 ------> SDMMC1_CKIN
+ PF2 ------> SDMMC1_D0DIR
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_9;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF11_SDIO1;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_2;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_7;
+ GPIO_InitStruct.Alternate = GPIO_AF8_SDIO1;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_4;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ |GPIO_PIN_12;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_2;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ __HAL_RCC_SDMMC1_FORCE_RESET();
+ __HAL_RCC_SDMMC1_RELEASE_RESET();
+
+ /* SDMMC1 interrupt Init */
+ HAL_NVIC_SetPriority(SDMMC1_IRQn, 2, 0);
+ HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
+ /* USER CODE BEGIN SDMMC1_MspInit 1 */
+
+ /* USER CODE END SDMMC1_MspInit 1 */
+ }
+
+ if(hsd->Instance==SDMMC2)
+ {
+ /* USER CODE BEGIN SDMMC2_MspInit 0 */
+ if (IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.Sdmmc12ClockSelection = RCC_SDMMC12CLKSOURCE_PLL4;
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC12;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+ /* USER CODE END SDMMC2_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_SDMMC2_CLK_ENABLE();
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+ /**SDMMC2 GPIO Configuration
+ PB14 ------> SDMMC2_D0
+ PB15 ------> SDMMC2_D1
+ PB3 ------> SDMMC2_D2
+ PB4 ------> SDMMC2_D3
+ PA8 ------> SDMMC2_D4
+ PA9 ------> SDMMC2_D5
+ PE5 ------> SDMMC2_D6
+ PD3 ------> SDMMC2_D7
+ PE3 ------> SDMMC2_CK
+ PG6 ------> SDMMC2_CMD
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_14|GPIO_PIN_15;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF9_SDIO2;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_8;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_3;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_5;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_9;
+ GPIO_InitStruct.Alternate = GPIO_AF10_SDIO2;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
+
+ __HAL_RCC_SDMMC2_FORCE_RESET();
+ __HAL_RCC_SDMMC2_RELEASE_RESET();
+
+ /* SDMMC2 interrupt Init */
+ HAL_NVIC_SetPriority(SDMMC2_IRQn, 0X05, 0);
+ HAL_NVIC_EnableIRQ(SDMMC2_IRQn);
+ /* USER CODE BEGIN SDMMC2_MspInit 1 */
+
+ /* USER CODE END SDMMC2_MspInit 1 */
+ }
+}
+
+/**
+* @brief SD MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hsd: SD handle pointer
+* @retval None
+*/
+void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
+{
+ if(hsd->Instance==SDMMC1)
+ {
+ /* USER CODE BEGIN SDMMC1_MspDeInit 0 */
+
+ /* USER CODE END SDMMC1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SDMMC1_CLK_DISABLE();
+
+ /**SDMMC1 GPIO Configuration
+ PB9 ------> SDMMC1_CDIR
+ PC7 ------> SDMMC1_D123DIR
+ PC8 ------> SDMMC1_D0
+ PC9 ------> SDMMC1_D1
+ PC10 ------> SDMMC1_D2
+ PC11 ------> SDMMC1_D3
+ PC12 ------> SDMMC1_CK
+ PD2 ------> SDMMC1_CMD
+ PE4 ------> SDMMC1_CKIN
+ PF2 ------> SDMMC1_D0DIR
+ */
+ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
+ |GPIO_PIN_12);
+
+ HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
+
+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9);
+
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_4);
+
+ HAL_GPIO_DeInit(GPIOF, GPIO_PIN_2);
+ /* SDMMC1 interrupt DeInit */
+ HAL_NVIC_DisableIRQ(SDMMC1_IRQn);
+ /* USER CODE BEGIN SDMMC1_MspDeInit 1 */
+
+ /* USER CODE END SDMMC1_MspDeInit 1 */
+ }
+
+ if(hsd->Instance==SDMMC2)
+ {
+ /* USER CODE BEGIN SDMMC2_MspDeInit 0 */
+
+ /* USER CODE END SDMMC2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_SDMMC2_CLK_DISABLE();
+
+ /**SDMMC2 GPIO Configuration
+ PB14 ------> SDMMC2_D0
+ PB15 ------> SDMMC2_D1
+ PB3 ------> SDMMC2_D2
+ PB4 ------> SDMMC2_D3
+ PA8 ------> SDMMC2_D4
+ PA9 ------> SDMMC2_D5
+ PE5 ------> SDMMC2_D6
+ PD3 ------> SDMMC2_D7
+ PE3 ------> SDMMC2_CK
+ PG6 ------> SDMMC2_CMD
+ */
+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_14|GPIO_PIN_15);
+
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_8|GPIO_PIN_9);
+
+ HAL_GPIO_DeInit(GPIOD, GPIO_PIN_3);
+
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_3|GPIO_PIN_5);
+
+ HAL_GPIO_DeInit(GPIOF, GPIO_PIN_6);
+ /* SDMMC2 interrupt DeInit */
+ HAL_NVIC_DisableIRQ(SDMMC2_IRQn);
+ /* USER CODE BEGIN SDMMC2_MspDeInit 1 */
+
+ /* USER CODE END SDMMC2_MspDeInit 1 */
+ }
+}
+
+void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+ /* SAI2 */
+ if (hsai->Instance==SAI2_Block_A)
+ {
+ /* Peripheral clock enable */
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
+ PeriphClkInit.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLL3_Q;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOI_CLK_ENABLE();
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_SAI2_CLK_ENABLE();
+
+ /**SAI2_A_Block_A GPIO Configuration
+ PE0 ------> SAI2_MCLK_A
+ PI7 ------> SAI2_FS_A
+ PI5 ------> SAI2_SCK_A
+ PI6 ------> SAI2_SD_A
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_0;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_5|GPIO_PIN_6;
+ HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
+
+ /* Configure DMA used for SAI2 */
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+ __HAL_RCC_DMA1_CLK_ENABLE();
+
+ hdma_sai2_a.Instance = DMA1_Stream0;
+ hdma_sai2_a.Init.Request = DMA_REQUEST_SAI2_A;
+ hdma_sai2_a.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_sai2_a.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai2_a.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai2_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+ hdma_sai2_a.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+ hdma_sai2_a.Init.Mode = DMA_CIRCULAR;
+ hdma_sai2_a.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai2_a.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_sai2_a.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_sai2_a.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_sai2_a.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ HAL_DMA_DeInit(&hdma_sai2_a);
+ if (HAL_DMA_Init(&hdma_sai2_a) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ __HAL_LINKDMA(hsai,hdmatx,hdma_sai2_a);
+ __HAL_DMA_ENABLE(&hdma_sai2_a);
+
+ HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0x02, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
+ }
+
+ if (hsai->Instance==SAI2_Block_B)
+ {
+ /* Peripheral clock enable */
+ if (IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
+ PeriphClkInit.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLL3_Q;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ }
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_SAI2_CLK_ENABLE();
+
+ /**SAI2_B_Block_B GPIO Configuration
+ PE12 ------> SAI2_MCLK_B
+ PE13 ------> SAI2_FS_B
+ PE14 ------> SAI2_SCK_B
+ PF11 ------> SAI2_SD_B
+ */
+
+ GPIO_InitStruct.Pin = GPIO_PIN_11;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+ __HAL_RCC_DMA1_CLK_ENABLE();
+
+ /* Peripheral DMA init*/
+ hdma_sai2_b.Instance = DMA1_Stream1;
+ hdma_sai2_b.Init.Request = DMA_REQUEST_SAI2_B;
+ hdma_sai2_b.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_sai2_b.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai2_b.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai2_b.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+ hdma_sai2_b.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+ hdma_sai2_b.Init.Mode = DMA_CIRCULAR;
+ hdma_sai2_b.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai2_b.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_sai2_b.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_sai2_b.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_sai2_b.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ HAL_DMA_DeInit(&hdma_sai2_b);
+ if (HAL_DMA_Init(&hdma_sai2_b) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ __HAL_LINKDMA(hsai,hdmarx,hdma_sai2_b);
+ __HAL_DMA_ENABLE(&hdma_sai2_b);
+ HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0x02, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
+ }
+ /* SAI4 */
+ if(hsai->Instance==SAI4_Block_A)
+ {
+ /* Peripheral clock enable */
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SAI4;
+ PeriphClkInit.Sai4ClockSelection = RCC_SAI4CLKSOURCE_PLL3_Q;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ }
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_SAI4_CLK_ENABLE();
+
+ /**SAI4_A_Block_A GPIO Configuration
+ PB5 ------> SAI4_SD_A
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_5;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF10_SAI4;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /* Peripheral DMA init*/
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+ __HAL_RCC_DMA1_CLK_ENABLE();
+
+ hdma_sai4_a.Instance = DMA1_Stream2;
+ hdma_sai4_a.Init.Request = DMA_REQUEST_SAI4_A;
+ hdma_sai4_a.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_sai4_a.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_sai4_a.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_sai4_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+ hdma_sai4_a.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+ hdma_sai4_a.Init.Mode = DMA_CIRCULAR;
+ hdma_sai4_a.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_sai4_a.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_sai4_a.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_sai4_a.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_sai4_a.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ HAL_DMA_DeInit(&hdma_sai4_a);
+ if (HAL_DMA_Init(&hdma_sai4_a) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ __HAL_LINKDMA(hsai,hdmatx,hdma_sai4_a);
+ __HAL_DMA_ENABLE(&hdma_sai4_a);
+ HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0x02, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
+ }
+}
+
+/**
+* @brief DCMI MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hdcmi: DCMI handle pointer
+* @retval None
+*/
+void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ if(hdcmi->Instance==DCMI)
+ {
+ /* USER CODE BEGIN DCMI_MspInit 0 */
+
+ /* USER CODE END DCMI_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_DCMI_CLK_ENABLE();
+
+ __HAL_RCC_GPIOH_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOI_CLK_ENABLE();
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+
+ /**DCMI GPIO Configuration
+ PH9 ------> DCMI_D0
+ PH10 ------> DCMI_D1
+ PH11 ------> DCMI_D2
+ PH12 ------> DCMI_D3
+ PH14 ------> DCMI_D4
+ PI4 ------> DCMI_D5
+ PB8 ------> DCMI_D6
+ PE6 ------> DCMI_D7
+ PH8 ------> DCMI_HSYNC
+ PB7 ------> DCMI_VSYNC
+ PA6 ------> DCMI_PIXCLK
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_14|GPIO_PIN_8
+ |GPIO_PIN_9|GPIO_PIN_12;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_4;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ HAL_NVIC_SetPriority(DCMI_IRQn, 0x03, 0x00);
+ HAL_NVIC_EnableIRQ(DCMI_IRQn);
+
+ /* USER CODE BEGIN DCMI_MspInit 1 */
+ /* USER CODE END DCMI_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief DCMI MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hdcmi: DCMI handle pointer
+* @retval None
+*/
+void HAL_DCMI_MspDeInit(DCMI_HandleTypeDef* hdcmi)
+{
+ if(hdcmi->Instance==DCMI)
+ {
+ /* USER CODE BEGIN DCMI_MspDeInit 0 */
+
+ /* USER CODE END DCMI_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_DCMI_CLK_DISABLE();
+
+ /**DCMI GPIO Configuration
+ PH10 ------> DCMI_D1
+ PH11 ------> DCMI_D2
+ PH14 ------> DCMI_D4
+ PH8 ------> DCMI_HSYNC
+ PH9 ------> DCMI_D0
+ PE6 ------> DCMI_D7
+ PH12 ------> DCMI_D3
+ PB7 ------> DCMI_VSYNC
+ PI4 ------> DCMI_D5
+ PA6 ------> DCMI_PIXCLK
+ PB8 ------> DCMI_D6
+ */
+ HAL_GPIO_DeInit(GPIOH, GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_14|GPIO_PIN_8
+ |GPIO_PIN_9|GPIO_PIN_12);
+
+ HAL_GPIO_DeInit(GPIOE, GPIO_PIN_6);
+
+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7|GPIO_PIN_8);
+
+ HAL_GPIO_DeInit(GPIOI, GPIO_PIN_4);
+
+ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_6);
+
+ /* USER CODE BEGIN DCMI_MspDeInit 1 */
+ HAL_DMA_DeInit(hdcmi->DMA_Handle);
+ /* USER CODE END DCMI_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief FDCAN MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hfdcan: FDCAN handle pointer
+* @retval None
+*/
+void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* hfdcan)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+ if(hfdcan->Instance==FDCAN1)
+ {
+ /* USER CODE BEGIN FDCAN1_MspInit 0 */
+
+ /* USER CODE END FDCAN1_MspInit 0 */
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
+ PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_HSE;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ }
+
+ /* Peripheral clock enable */
+ __HAL_RCC_FDCAN_CLK_ENABLE();
+
+ __HAL_RCC_GPIOH_CLK_ENABLE();
+ __HAL_RCC_GPIOI_CLK_ENABLE();
+ /**FDCAN1 GPIO Configuration
+ PH13 ------> FDCAN1_TX
+ PI9 ------> FDCAN1_RX
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_13;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
+ HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_9;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
+ HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
+
+ /* FDCAN1 interrupt Init */
+ HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 0x02, 0);
+ HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
+ HAL_NVIC_SetPriority(FDCAN1_IT1_IRQn, 0x02, 0);
+ HAL_NVIC_EnableIRQ(FDCAN1_IT1_IRQn);
+ HAL_NVIC_SetPriority(FDCAN_CAL_IRQn, 0x02, 0);
+ HAL_NVIC_EnableIRQ(FDCAN_CAL_IRQn);
+ /* USER CODE BEGIN FDCAN1_MspInit 1 */
+ /* USER CODE END FDCAN1_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief FDCAN MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hfdcan: FDCAN handle pointer
+* @retval None
+*/
+void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* hfdcan)
+{
+ if(hfdcan->Instance==FDCAN1)
+ {
+ /* USER CODE BEGIN FDCAN1_MspDeInit 0 */
+
+ /* USER CODE END FDCAN1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_FDCAN_CLK_DISABLE();
+
+ /**FDCAN1 GPIO Configuration
+ PH13 ------> FDCAN1_TX
+ PI9 ------> FDCAN1_RX
+ */
+ HAL_GPIO_DeInit(GPIOH, GPIO_PIN_13);
+
+ HAL_GPIO_DeInit(GPIOI, GPIO_PIN_9);
+
+ /* FDCAN1 interrupt DeInit */
+ HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn);
+ HAL_NVIC_DisableIRQ(FDCAN1_IT1_IRQn);
+ HAL_NVIC_DisableIRQ(FDCAN_CAL_IRQn);
+ /* USER CODE BEGIN FDCAN1_MspDeInit 1 */
+
+ /* USER CODE END FDCAN1_MspDeInit 1 */
+ }
+
+}
+
+void HAL_SPDIFRX_MspInit(SPDIFRX_HandleTypeDef* hspdifrx)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+ if(hspdifrx->Instance==SPDIFRX)
+ {
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SPDIFRX;
+ PeriphClkInit.SpdifrxClockSelection = RCC_SPDIFRXCLKSOURCE_PLL4;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+ /* Peripheral clock enable */
+ __HAL_RCC_SPDIFRX_CLK_ENABLE();
+
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+
+ GPIO_InitStruct.Pin = GPIO_PIN_12;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF8_SPDIF;
+ HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
+
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+ __HAL_RCC_DMA1_CLK_ENABLE();
+
+ hdma_spdifrx_rx.Instance = DMA1_Stream7;
+ hdma_spdifrx_rx.Init.Request = DMA_REQUEST_SPDIF_RX_DT;
+ hdma_spdifrx_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_spdifrx_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_spdifrx_rx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_spdifrx_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_spdifrx_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_spdifrx_rx.Init.Mode = DMA_CIRCULAR;
+ hdma_spdifrx_rx.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_spdifrx_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_spdifrx_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_spdifrx_rx.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_spdifrx_rx.Init.PeriphBurst = DMA_MBURST_SINGLE;
+
+ HAL_DMA_DeInit(&hdma_spdifrx_rx);
+ if (HAL_DMA_Init(&hdma_spdifrx_rx) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(hspdifrx, hdmaDrRx, hdma_spdifrx_rx);
+
+ HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 0x02, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn);
+ }
+}
+
+void HAL_SPDIFRX_MspDeInit(SPDIFRX_HandleTypeDef* hspdifrx)
+{
+ if(hspdifrx->Instance==SPDIFRX)
+ {
+ __HAL_RCC_SPDIFRX_CLK_DISABLE();
+
+ HAL_GPIO_DeInit(GPIOG, GPIO_PIN_12);
+ HAL_DMA_DeInit(hspdifrx->hdmaDrRx);
+ }
+}
+
+void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef* hdfsdm_channel)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_DFSDM1;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+ /* Peripheral clock enable */
+ __HAL_RCC_DFSDM1_CLK_ENABLE();
+
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ /**DFSDM1 GPIO Configuration
+ PC3 ------> DFSDM1_DATIN1
+ PB13 ------> DFSDM1_CKOUT
+ PF13 ------> DFSDM1_DATIN3
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_13;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF3_DFSDM1;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_3;
+ GPIO_InitStruct.Alternate = GPIO_AF3_DFSDM1;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_13;
+ GPIO_InitStruct.Alternate = GPIO_AF6_DFSDM1;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+}
+
+void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef* hdfsdm_filter)
+{
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_DFSDM1;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+
+ __HAL_RCC_DFSDM1_CLK_ENABLE();
+ /* DMA controller clock enable */
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+ __HAL_RCC_DMA2_CLK_ENABLE();
+
+ if(hdfsdm_filter->Instance == DFSDM1_Filter0)
+ {
+ hdma_dfsdm1_flt0.Instance = DMA2_Stream2;
+ hdma_dfsdm1_flt0.Init.Request = DMA_REQUEST_DFSDM1_FLT0;
+ hdma_dfsdm1_flt0.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_dfsdm1_flt0.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_dfsdm1_flt0.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_dfsdm1_flt0.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_dfsdm1_flt0.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_dfsdm1_flt0.Init.Mode = DMA_CIRCULAR;
+ hdma_dfsdm1_flt0.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_dfsdm1_flt0.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_dfsdm1_flt0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_dfsdm1_flt0.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_dfsdm1_flt0.Init.PeriphBurst = DMA_PBURST_SINGLE;
+ if (HAL_DMA_Init(&hdma_dfsdm1_flt0) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /* Several peripheral DMA handle pointers point to the same DMA handle.
+ Be aware that there is only one channel to perform all the requested DMAs. */
+ __HAL_LINKDMA(hdfsdm_filter,hdmaReg,hdma_dfsdm1_flt0);
+
+ HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 2, 0);
+ HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
+ }
+
+ if(hdfsdm_filter->Instance == DFSDM1_Filter1)
+ {
+ hdma_dfsdm1_flt1.Instance = DMA2_Stream1;
+ hdma_dfsdm1_flt1.Init.Request = DMA_REQUEST_DFSDM1_FLT1;
+ hdma_dfsdm1_flt1.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_dfsdm1_flt1.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_dfsdm1_flt1.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_dfsdm1_flt1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_dfsdm1_flt1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_dfsdm1_flt1.Init.Mode = DMA_CIRCULAR;
+ hdma_dfsdm1_flt1.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_dfsdm1_flt1.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_dfsdm1_flt1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_dfsdm1_flt1.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_dfsdm1_flt1.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ if (HAL_DMA_Init(&hdma_dfsdm1_flt1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(hdfsdm_filter,hdmaReg,hdma_dfsdm1_flt1);
+
+ HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 2, 0);
+ HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
+ }
+}
+
+void HAL_DFSDM_FilterMspDeInit(DFSDM_Filter_HandleTypeDef* hdfsdm_filter)
+{
+ HAL_DMA_DeInit(hdfsdm_filter->hdmaReg);
+}
+
+void HAL_DFSDM_ChannelMspDeInit(DFSDM_Channel_HandleTypeDef* hdfsdm_channel)
+{
+ __HAL_RCC_DFSDM1_CLK_DISABLE();
+ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3);
+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13);
+ HAL_GPIO_DeInit(GPIOF, GPIO_PIN_13);
+}
+
+/**
+* @brief HASH MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hhash: HASH handle pointer
+* @retval None
+*/
+void HAL_HASH_MspInit(HASH_HandleTypeDef* hhash)
+{
+ /* USER CODE BEGIN HASH2_MspInit 0 */
+ /* USER CODE END HASH2_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_HASH2_CLK_ENABLE();
+ /* USER CODE BEGIN HASH2_MspInit 1 */
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+
+ /* Peripheral DMA init*/
+ hdma_hash_in.Instance = DMA2_Stream7;
+ hdma_hash_in.Init.Request = DMA_REQUEST_HASH2_IN;
+ hdma_hash_in.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_hash_in.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_hash_in.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_hash_in.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_hash_in.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_hash_in.Init.Mode = DMA_NORMAL;
+ hdma_hash_in.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_hash_in.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_hash_in.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
+ hdma_hash_in.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_hash_in.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ if (HAL_DMA_DeInit(&hdma_hash_in) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_DMA_Init(&hdma_hash_in) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(hhash,hdmain,hdma_hash_in);
+ /* USER CODE END HASH2_MspInit 1 */
+
+}
+
+/**
+* @brief HASH MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hhash: HASH handle pointer
+* @retval None
+*/
+void HAL_HASH_MspDeInit(HASH_HandleTypeDef* hhash)
+{
+ /* USER CODE BEGIN HASH2_MspDeInit 0 */
+
+ /* USER CODE END HASH2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_HASH2_CLK_DISABLE();
+ /* USER CODE BEGIN HASH2_MspDeInit 1 */
+
+ /* USER CODE END HASH2_MspDeInit 1 */
+
+}
+
+/**
+* @brief CRC MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hcrc: CRC handle pointer
+* @retval None
+*/
+void HAL_CRC_MspInit(CRC_HandleTypeDef* hcrc)
+{
+ if(hcrc->Instance==CRC2)
+ {
+ /* USER CODE BEGIN CRC2_MspInit 0 */
+
+ /* USER CODE END CRC2_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_CRC2_CLK_ENABLE();
+ /* USER CODE BEGIN CRC2_MspInit 1 */
+
+ /* USER CODE END CRC2_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief CRC MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hcrc: CRC handle pointer
+* @retval None
+*/
+void HAL_CRC_MspDeInit(CRC_HandleTypeDef* hcrc)
+{
+ if(hcrc->Instance==CRC2)
+ {
+ /* USER CODE BEGIN CRC2_MspDeInit 0 */
+
+ /* USER CODE END CRC2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_CRC2_CLK_DISABLE();
+ /* USER CODE BEGIN CRC2_MspDeInit 1 */
+
+ /* USER CODE END CRC2_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief RNG MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hrng: RNG handle pointer
+* @retval None
+*/
+void HAL_RNG_MspInit(RNG_HandleTypeDef* hrng)
+{
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+ if(hrng->Instance==RNG2)
+ {
+ /* USER CODE BEGIN RNG2_MspInit 0 */
+
+ /* USER CODE END RNG2_MspInit 0 */
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RNG2;
+ PeriphClkInit.Rng2ClockSelection = RCC_RNG2CLKSOURCE_LSE;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ }
+
+ /* Peripheral clock enable */
+ __HAL_RCC_RNG2_CLK_ENABLE();
+ /* USER CODE BEGIN RNG2_MspInit 1 */
+
+ /* USER CODE END RNG2_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief RNG MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hrng: RNG handle pointer
+* @retval None
+*/
+void HAL_RNG_MspDeInit(RNG_HandleTypeDef* hrng)
+{
+ if(hrng->Instance==RNG2)
+ {
+ /* USER CODE BEGIN RNG2_MspDeInit 0 */
+
+ /* USER CODE END RNG2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_RNG2_CLK_DISABLE();
+ /* USER CODE BEGIN RNG2_MspDeInit 1 */
+
+ /* USER CODE END RNG2_MspDeInit 1 */
+ }
+
+}
+
+#if defined (CRYP1) || defined (CRYP2)
+void HAL_CRYP_MspInit(CRYP_HandleTypeDef* hcryp)
+{
+ if(hcryp->Instance==CRYP2)
+ {
+ /* Peripheral clock enable */
+ __HAL_RCC_CRYP2_CLK_ENABLE();
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+
+ /* Peripheral DMA init*/
+ hdma_cryp_in.Instance = DMA2_Stream6;
+ hdma_cryp_in.Init.Request = DMA_REQUEST_CRYP2_IN;
+ hdma_cryp_in.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_cryp_in.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_cryp_in.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_cryp_in.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_cryp_in.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_cryp_in.Init.Mode = DMA_NORMAL;
+ hdma_cryp_in.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_cryp_in.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ if (HAL_DMA_DeInit(&hdma_cryp_in) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_DMA_Init(&hdma_cryp_in) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(hcryp,hdmain,hdma_cryp_in);
+
+ hdma_cryp_out.Instance = DMA2_Stream5;
+ hdma_cryp_out.Init.Request = DMA_REQUEST_CRYP2_OUT;
+ hdma_cryp_out.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_cryp_out.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_cryp_out.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_cryp_out.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_cryp_out.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_cryp_out.Init.Mode = DMA_NORMAL;
+ hdma_cryp_out.Init.Priority = DMA_PRIORITY_VERY_HIGH;
+ hdma_cryp_out.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ if (HAL_DMA_DeInit(&hdma_cryp_out) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_DMA_Init(&hdma_cryp_out) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(hcryp,hdmaout,hdma_cryp_out);
+
+ /* USER CODE BEGIN CRYP_MspInit 1 */
+
+ /* USER CODE END CRYP_MspInit 1 */
+ }
+}
+
+void HAL_CRYP_MspDeInit(CRYP_HandleTypeDef* hcryp)
+{
+
+ if(hcryp->Instance==CRYP2)
+ {
+ /* USER CODE BEGIN CRYP_MspDeInit 0 */
+
+ /* USER CODE END CRYP_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_CRYP2_CLK_DISABLE();
+
+ /* Peripheral DMA DeInit*/
+ HAL_DMA_DeInit(hcryp->hdmain);
+ HAL_DMA_DeInit(hcryp->hdmaout);
+ }
+ /* USER CODE BEGIN CRYP_MspDeInit 1 */
+
+ /* USER CODE END CRYP_MspDeInit 1 */
+
+}
+#endif
+
+/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig b/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
index e52a1601fe..c69447c2f7 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
@@ -14,6 +14,10 @@ menu "Onboard Peripheral Drivers"
select BSP_USING_UART
select BSP_USING_UART4
default y
+
+ config BSP_USING_EXTI
+ bool "Enable exti sample"
+ default n
config BSP_USING_PMIC
bool "Enable PMIC"
@@ -21,6 +25,12 @@ menu "Onboard Peripheral Drivers"
select BSP_USING_I2C3
default y
+ config BSP_USING_PWR
+ bool "Enable PM (power control)"
+ select BSP_USING_LPTIM
+ select BSP_USING_LPTIM1
+ default n
+
config BSP_USING_NAND
bool "Enable FMC (MT29F8G08ABACAH4)"
select RT_USING_FMC
@@ -28,11 +38,88 @@ menu "Onboard Peripheral Drivers"
select RT_MTD_NAND_DEBUG
default n
+ config BSP_USING_QSPI_FLASH
+ bool "Enable QSPI FLASH (MX25L51245G)"
+ select BSP_USING_QSPI
+ select RT_USING_SFUD
+ select RT_SFUD_USING_QSPI
+ default n
+
config BSP_USING_OPENAMP
bool "Enable OpenAMP"
select RT_USING_OPENAMP
default n
+ config BSP_USING_GBE
+ bool "Enable Ethernet"
+ default n
+ select RT_USING_LWIP
+
+ menuconfig BSP_USING_SDMMC
+ bool "Enable SDMMC"
+ select RT_USING_SDIO
+ select RT_USING_DFS
+ select RT_USING_DFS_ELMFAT
+ select BSP_USING_PMIC
+ if BSP_USING_SDMMC
+ menuconfig BSP_USING_SD_CARD
+ bool "Enable sd card"
+ default n
+ if BSP_USING_SD_CARD
+ config SD_USING_DFS
+ bool "sd card fatfs"
+ default y
+ endif
+
+ menuconfig BSP_USING_EMMC
+ bool "Enable eMMC (32 Gbits)"
+ default n
+ if BSP_USING_EMMC
+ config EMMC_USING_DFS
+ bool "emmc card fatfs"
+ default n
+ endif
+ endif
+
+ config BSP_USING_AUDIO
+ bool "Enable Audio Device (WM8994)"
+ select RT_USING_AUDIO
+ select BSP_USING_PMIC
+ select BSP_USING_SDMMC
+ select BSP_USING_SD_CARD
+ select SD_USING_DFS
+ select BSP_USING_I2C
+ select BSP_USING_I2C2
+ default n
+
+ config BSP_USING_DCMI
+ bool "Enable CAMERA (ov5640)"
+ select BSP_USING_MFX
+ select BSP_USING_PMIC
+ select BSP_USING_I2C
+ select BSP_USING_I2C2
+ default n
+
+ config BSP_USING_MFX
+ bool "Enable Multi Function eXpander"
+ default n
+
+ menuconfig BSP_USING_RS485
+ bool "Enable RS485 "
+ default n
+ if BSP_USING_RS485
+ comment "set rts pin number "
+ config BSP_RS485_RTS_PIN
+ int "RS485 rts pin number"
+ range 1 176
+ default 5
+
+ config RS485_UART_DEVICE_NAME
+ string "the uart name for rs485"
+ default "uart3"
+
+ endif
+
endmenu
menu "On-chip Peripheral Drivers"
@@ -41,6 +128,28 @@ menu "On-chip Peripheral Drivers"
select RT_USING_PIN
default y
+ config BSP_USING_WWDG
+ bool "Enable WWDG"
+ select RT_USING_WWDG
+ select RT_USING_WDT
+ default n
+
+ config BSP_USING_QSPI
+ bool "Enable QSPI BUS"
+ select RT_USING_QSPI
+ select RT_USING_SPI
+ default n
+
+ config BSP_USING_SPDIFRX
+ bool "Enable spdifrx"
+ select BSP_USING_AUDIO
+ default n
+
+ config BSP_USING_DFSDM
+ bool "Enable dfsdm"
+ select BSP_USING_AUDIO
+ default n
+
menuconfig BSP_USING_UART
bool "Enable UART"
select RT_USING_SERIAL
@@ -48,11 +157,11 @@ menu "On-chip Peripheral Drivers"
if BSP_USING_UART
config BSP_USING_UART3
bool "Enable UART3"
- default y
+ default n
config BSP_UART3_RX_USING_DMA
bool "Enable UART3 RX DMA"
- depends on BSP_USING_UART4 && RT_SERIAL_USING_DMA
+ depends on BSP_USING_UART3 && RT_SERIAL_USING_DMA
default n
config BSP_UART3_TX_USING_DMA
@@ -62,7 +171,7 @@ menu "On-chip Peripheral Drivers"
config BSP_USING_UART4
bool "Enable UART4"
- default y
+ default n
config BSP_UART4_RX_USING_DMA
bool "Enable UART4 RX DMA"
@@ -94,6 +203,16 @@ menu "On-chip Peripheral Drivers"
default n
endif
+ menuconfig BSP_USING_LPTIM
+ bool "Enable lptimer"
+ default n
+ select RT_USING_LPTIMER
+ if BSP_USING_LPTIM
+ config BSP_USING_LPTIM1
+ bool "Enable LPTIM1"
+ default n
+ endif
+
menuconfig BSP_USING_PWM
bool "Enable pwm"
default n
@@ -185,22 +304,21 @@ menu "On-chip Peripheral Drivers"
select RT_USING_SPI
default n
if BSP_USING_SPI
- config BSP_USING_SPI5
- bool "Enable SPI5 BUS"
- default n
-
- config BSP_SPI5_TX_USING_DMA
- bool "Enable SPI5 TX DMA"
- depends on BSP_USING_SPI5
+ config BSP_USING_SPI1
+ bool "Enable SPI1 BUS"
default n
- config BSP_SPI5_RX_USING_DMA
- bool "Enable SPI5 RX DMA"
- depends on BSP_USING_SPI5
- select BSP_SPI5_TX_USING_DMA
- default n
endif
+ menuconfig BSP_USING_FDCAN
+ bool "Enable FDCAN"
+ default n
+ if BSP_USING_FDCAN
+ config BSP_USING_FDCAN1
+ bool "Enable FDCAN1"
+ default n
+ endif
+
source "../libraries/HAL_Drivers/Kconfig"
endmenu
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/SConscript b/bsp/stm32/stm32mp157a-st-ev1/board/SConscript
index 15e6070c81..5b4ffbfab1 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/SConscript
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/SConscript
@@ -13,12 +13,69 @@ CubeMX_Config/Common/System/system_stm32mp1xx.c
CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
''')
+if GetDepend(['BSP_USING_SPI1']):
+ src += Glob('ports/spi_sample.c')
+
if GetDepend(['BSP_USING_PMIC']):
src += Glob('ports/drv_pmic.c')
if GetDepend(['BSP_USING_NAND']):
src += Glob('ports/drv_nand.c')
+if GetDepend(['BSP_USING_GBE']):
+ src += Glob('ports/eth/drv_eth.c')
+
+if GetDepend(['BSP_USING_SD_CARD']):
+ src += Glob('ports/drv_sdcard.c')
+
+if GetDepend(['BSP_USING_EMMC']):
+ src += Glob('ports/drv_emmc.c')
+
+if GetDepend(['BSP_USING_AUDIO']):
+ src += Glob('ports/drv_wm8994.c')
+ src += Glob('ports/drv_sound.c')
+
+if GetDepend(['BSP_USING_DCMI']):
+ src += Glob('ports/drv_dcmi.c')
+ src += Glob('ports/drv_ov5640.c')
+
+if GetDepend(['BSP_USING_MFX']):
+ src += Glob('ports/drv_mfx.c')
+ src += Glob('ports/mfxstm32l152.c')
+
+if GetDepend(['BSP_USING_FDCAN']):
+ src += Glob('ports/drv_fdcan.c')
+
+if GetDepend(['BSP_USING_QSPI']):
+ src += Glob('ports/drv_qspi_flash.c')
+
+if GetDepend(['BSP_USING_SPDIFRX']):
+ src += Glob('ports/drv_spdifrx.c')
+
+if GetDepend(['BSP_USING_DFSDM']):
+ src += Glob('ports/drv_dfsdm.c')
+
+if GetDepend(['BSP_USING_WWDG']):
+ src += Glob('ports/drv_wwdg.c')
+
+if GetDepend(['BSP_USING_EXTI']):
+ src += Glob('ports/drv_exti.c')
+
+if GetDepend(['BSP_USING_RNG']) or GetDepend(['BSP_USING_HASH']) or GetDepend(['BSP_USING_CRC']) or GetDepend(['BSP_USING_CRYP']):
+ src += Glob('ports/crypto_sample.c')
+
+if GetDepend(['BSP_USING_PWR']):
+ src += Glob('ports/drv_pwr.c')
+
+if GetDepend(['BSP_USING_LPTIM1']):
+ src += Glob('ports/drv_lptim.c')
+
+if GetDepend(['BSP_USING_RS485']):
+ src += Glob('ports/drv_rs485.c')
+
+if GetDepend(['BSP_USING_TIM14']):
+ src += Glob('ports/timer_sample.c')
+
if GetDepend(['BSP_USING_OPENAMP']):
src += Glob('CubeMX_Config/CM4/Src/ipcc.c')
src += Glob('CubeMX_Config/CM4/Src/openamp.c')
@@ -45,6 +102,9 @@ if GetDepend(['BSP_USING_OPENAMP']):
path += [cwd + '/ports/OpenAMP/virtual_driver']
path += [cwd + '/CubeMX_Config/CM4/Inc']
+if GetDepend(['BSP_USING_GBE']):
+ path += [cwd + '/ports/eth']
+
startup_path_prefix = SDK_LIB
if rtconfig.CROSS_TOOL == 'gcc':
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/board.h b/bsp/stm32/stm32mp157a-st-ev1/board/board.h
index 84e097714a..81cdaa92fb 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/board.h
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/board.h
@@ -23,16 +23,11 @@ extern "C" {
#endif
#define STM32_FLASH_START_ADRESS ((uint32_t)0x10000000)
-#if defined(BSP_USING_OPENAMP)
-#define STM32_FLASH_SIZE (64 * 1024)
-#else
-#define STM32_FLASH_SIZE (256 * 1024)
-#endif
+#define STM32_FLASH_SIZE (191 * 1024)
#define STM32_FLASH_END_ADDRESS ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE))
-
#if defined(BSP_USING_OPENAMP)
-#define STM32_SRAM_BEGIN (uint32_t)0x10020000
+#define STM32_SRAM_BEGIN (uint32_t)0x10030000
#else
#define STM32_SRAM_BEGIN (uint32_t)0x2FFF0000
#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/linker_scripts/link.icf b/bsp/stm32/stm32mp157a-st-ev1/board/linker_scripts/link.icf
index ee4ff6ade6..9f3374e051 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/linker_scripts/link.icf
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/linker_scripts/link.icf
@@ -5,7 +5,7 @@
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_text_start__ = 0x10000000;
-define symbol __ICFEDIT_region_text_end__ = 0x1001FFFF;
+define symbol __ICFEDIT_region_text_end__ = 0x1002FFFF;
define symbol __ICFEDIT_region_data_start__ = 0x10030000;
define symbol __ICFEDIT_region_data_end__ = 0x1003FFFF;
/*-Sizes-*/
@@ -28,11 +28,6 @@ define symbol __OPENAMP_region_size__ = 0x8000;
export symbol __OPENAMP_region_start__;
export symbol __OPENAMP_region_size__;
-define symbol __SDMMC_region_start__ = 0x10048000;
-define symbol __SDMMC_region_size__ = 0x1FFFF;
-export symbol __SDMMC_region_start__;
-export symbol __SDMMC_region_size__;
-
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/OpenAMP/drv_openamp.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/OpenAMP/drv_openamp.c
index 2705f068a3..12651efa1a 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/ports/OpenAMP/drv_openamp.c
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/OpenAMP/drv_openamp.c
@@ -12,6 +12,7 @@
#ifdef BSP_USING_OPENAMP
+#include <finsh.h>
#include <drv_openamp.h>
#include <openamp.h>
#include <virt_uart.h>
@@ -235,7 +236,10 @@ int rt_hw_openamp_init(void)
rt_hw_openamp_register(&dev_openamp, "openamp", 0, NULL);
- rt_console_set_device("openamp");
+ if (RT_CONSOLE_DEVICE_NAME == "openamp")
+ {
+ rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+ }
return RT_EOK;
}
@@ -289,4 +293,36 @@ static int creat_openamp_thread(void)
}
INIT_APP_EXPORT(creat_openamp_thread);
+#ifdef FINSH_USING_MSH
+
+static int console(int argc, char **argv)
+{
+ rt_err_t result = RT_EOK;
+
+ if (argc > 1)
+ {
+ if (!strcmp(argv[1], "set"))
+ {
+ rt_kprintf("console change to %s\n", argv[2]);
+ rt_console_set_device(argv[2]);
+ finsh_set_device(argv[2]);
+ }
+ else
+ {
+ rt_kprintf("Unknown command. Please enter 'console' for help\n");
+ result = -RT_ERROR;
+ }
+ }
+ else
+ {
+ rt_kprintf("Usage: \n");
+ rt_kprintf("console set <name> - change console by name\n");
+ result = -RT_ERROR;
+ }
+ return result;
+}
+MSH_CMD_EXPORT(console, set console name);
+
+#endif /* FINSH_USING_MSH */
+
#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/crypto_sample.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/crypto_sample.c
new file mode 100644
index 0000000000..fcad8fb9ff
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/crypto_sample.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-06-27 thread-liu first version
+ */
+
+#include <board.h>
+
+#include "drv_crypto.h"
+#include <hwcrypto.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if defined(BSP_USING_RNG)
+static rt_err_t hw_rng_sample(int random_num)
+{
+ rt_err_t result = RT_EOK;
+ int i = 0, num0 = 0, num1 = 0;
+
+ if (random_num == 0)
+ {
+ return RT_ERROR;
+ }
+
+ for (i = 0; i< random_num; i++)
+ {
+ result = rt_hwcrypto_rng_update();
+ rt_kprintf("%d ", result);
+ result%2 ? num1++ : num0++;
+ }
+ rt_kprintf("\neven numbers : %d, odd numbers: %d\n",num1, num0);
+
+ return RT_EOK;
+}
+#endif
+
+#if defined(BSP_USING_CRC)
+static void hw_crc_sample(uint8_t *temp, int size)
+{
+ struct rt_hwcrypto_ctx *ctx;
+ rt_uint32_t result = 0;
+
+ struct hwcrypto_crc_cfg cfg =
+ {
+ .last_val = 0xFFFFFFFF,
+ .poly = 0x04C11DB7,
+ .width = 32,
+ .xorout = 0x00000000,
+ .flags = 0,
+ };
+
+ ctx = rt_hwcrypto_crc_create(rt_hwcrypto_dev_default(), HWCRYPTO_CRC_CRC32);
+ rt_hwcrypto_crc_cfg(ctx, &cfg);
+
+ result = rt_hwcrypto_crc_update(ctx, temp, size);
+
+ rt_kprintf("crc result: %x \n", result);
+
+ rt_hwcrypto_crc_destroy(ctx);
+}
+#endif
+
+#if defined(BSP_USING_HASH)
+static void hw_hash_sample()
+{
+ int i = 0;
+ struct rt_hwcrypto_ctx *ctx = RT_NULL;
+ const uint8_t hash_input[] = "RT-Thread was born in 2006, it is an open source, neutral, and community-based real-time operating system (RTOS).";
+
+ static uint8_t sha1_output[20];
+ static uint8_t sha1_except[20] = {0xff, 0x3c, 0x95, 0x54, 0x95, 0xf0, 0xad,
+ 0x02, 0x1b, 0xa8, 0xbc, 0xa2, 0x2e, 0xa5,
+ 0xb0, 0x62, 0x1b, 0xdf, 0x7f, 0xec};
+
+ static uint8_t md5_output[16];
+ static uint8_t md5_except[16] = {0x40, 0x86, 0x03, 0x80, 0x0d, 0x8c, 0xb9,
+ 0x4c, 0xd6, 0x7d, 0x28, 0xfc, 0xf6, 0xc3,
+ 0xac, 0x8b};
+
+ static uint8_t sha224_output[28];
+ static uint8_t sha224_except[28] = {0x6f, 0x62, 0x52, 0x7d, 0x80, 0xe6,
+ 0x9f, 0x82, 0x78, 0x7a, 0x46, 0x91,
+ 0xb0, 0xe9, 0x64, 0x89, 0xe6, 0xc3,
+ 0x6b, 0x7e, 0xcf, 0xca, 0x11, 0x42,
+ 0xc8, 0x77, 0x13, 0x79};
+ static uint8_t sha256_output[32];
+ static uint8_t sha256_except[32] = {0x74, 0x19, 0xb9, 0x0e, 0xd1, 0x46,
+ 0x37, 0x0a, 0x55, 0x18, 0x26, 0x6c,
+ 0x50, 0xd8, 0x71, 0x34, 0xfa, 0x1f,
+ 0x5f, 0x5f, 0xe4, 0x9a, 0xe9, 0x40,
+ 0x0a, 0x7d, 0xa0, 0x26, 0x1b, 0x86,
+ 0x67, 0x45};
+ rt_kprintf("Hash Test start: \n");
+ rt_kprintf("Hash Test string: \n");
+ for (i = 0; i < sizeof(hash_input); i++)
+ {
+ rt_kprintf("%c", hash_input[i]);
+ }
+ rt_kprintf("\n");
+
+ /* sh1 test*/
+ ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA1);
+ if (ctx == RT_NULL)
+ {
+ rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA1);
+ return ;
+ }
+ rt_kprintf("Create sha1 type success!\n");
+ rt_kprintf("Except sha1 result: \n");
+ for (i = 0; i < sizeof(sha1_except); i++)
+ {
+ rt_kprintf("%x ", sha1_except[i]);
+ }
+ rt_kprintf("\n");
+ /* start sha1 */
+ rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
+ /* get sha1 result */
+ rt_hwcrypto_hash_finish(ctx, sha1_output, rt_strlen((char const *)sha1_output));
+
+ rt_kprintf("Actual sha1 result: \n");
+ for (i = 0; i < sizeof(sha1_output); i++)
+ {
+ rt_kprintf("%x ", sha1_output[i]);
+ }
+ rt_kprintf("\n");
+ if(rt_memcmp(sha1_output, sha1_except, sizeof(sha1_except)/sizeof(sha1_except[0])) != 0)
+ {
+ rt_kprintf("Hash type sha1 Test error, The actual result is not equal to the except result\n");
+ }
+ else
+ {
+ rt_kprintf("Hash type sha1 Test success, The actual result is equal to the except result\n");
+ }
+ /* deinit hash*/
+ rt_hwcrypto_hash_destroy(ctx);
+
+ /* md5 test*/
+ ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_MD5);
+ if (ctx == RT_NULL)
+ {
+ rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_MD5);
+ return ;
+ }
+ rt_kprintf("Create md5 type success!\n");
+ rt_kprintf("Except md5 result: \n");
+ for (i = 0; i < sizeof(md5_except); i++)
+ {
+ rt_kprintf("%x ", md5_except[i]);
+ }
+ rt_kprintf("\n");
+ /* start md5 */
+ rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
+ /* get md5 result */
+ rt_hwcrypto_hash_finish(ctx, md5_output, rt_strlen((char const *)md5_output));
+
+ rt_kprintf("Actual md5 result: \n");
+ for (i = 0; i < sizeof(md5_output); i++)
+ {
+ rt_kprintf("%x ", md5_output[i]);
+ }
+ rt_kprintf("\n");
+ if(rt_memcmp(md5_output, md5_except, sizeof(md5_except)/sizeof(md5_except[0])) != 0)
+ {
+ rt_kprintf("Hash type md5 Test error, The actual result is not equal to the except result\n");
+ }
+ else
+ {
+ rt_kprintf("Hash type md5 Test success, The actual result is equal to the except result\n");
+ }
+ /* deinit hash*/
+ rt_hwcrypto_hash_destroy(ctx);
+
+ /* sha224 test */
+ ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA224);
+ if (ctx == RT_NULL)
+ {
+ rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA224);
+ return ;
+ }
+ rt_kprintf("Create sha224 type success!\n");
+ rt_kprintf("Except sha224 result: \n");
+ for (i = 0; i < sizeof(sha224_except); i++)
+ {
+ rt_kprintf("%x ", sha224_except[i]);
+ }
+ rt_kprintf("\n");
+ /* start sha224 */
+ rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
+ /* get sha224 result */
+ rt_hwcrypto_hash_finish(ctx, sha224_output, rt_strlen((char const *)sha224_output));
+
+ rt_kprintf("Actual sha224 result: \n");
+ for (i = 0; i < sizeof(sha224_output); i++)
+ {
+ rt_kprintf("%x ", sha224_output[i]);
+ }
+ rt_kprintf("\n");
+ if(rt_memcmp(sha224_output, sha224_except, sizeof(sha224_except)/sizeof(sha224_except[0])) != 0)
+ {
+ rt_kprintf("Hash type sha224 Test error, The actual result is not equal to the except result\n");
+ }
+ else
+ {
+ rt_kprintf("Hash type sha224 Test success, The actual result is equal to the except result\n");
+ }
+ rt_hwcrypto_hash_destroy(ctx);
+
+ /* sha256 test*/
+ ctx = rt_hwcrypto_hash_create(rt_hwcrypto_dev_default(), HWCRYPTO_TYPE_SHA256);
+ if (ctx == RT_NULL)
+ {
+ rt_kprintf("create hash[%08x] context err!\n", HWCRYPTO_TYPE_SHA256);
+ return ;
+ }
+
+ rt_kprintf("Create sha256 type success!\n");
+ rt_kprintf("Except sha256 result: \n");
+ for (i = 0; i < sizeof(sha256_except); i++)
+ {
+ rt_kprintf("%x ", sha256_except[i]);
+ }
+ rt_kprintf("\n");
+ /* start sha256 */
+ rt_hwcrypto_hash_update(ctx, hash_input, rt_strlen((char const *)hash_input));
+ /* get sha256 result */
+ rt_hwcrypto_hash_finish(ctx, sha256_output, rt_strlen((char const *)sha256_output));
+
+ rt_kprintf("Actual sha256 result: \n");
+ for (i = 0; i < sizeof(sha256_output); i++)
+ {
+ rt_kprintf("%x ", sha256_output[i]);
+ }
+ rt_kprintf("\n");
+
+ if(rt_memcmp(sha256_output, sha256_except, sizeof(sha256_except)/sizeof(sha256_except[0])) != 0)
+ {
+ rt_kprintf("Hash type sha256 Test error, The actual result is not equal to the except result\n");
+ }
+ else
+ {
+ rt_kprintf("Hash type sha256 Test success, The actual result is equal to the except result\n");
+ }
+ rt_hwcrypto_hash_destroy(ctx);
+ rt_kprintf("Hash Test over!\n");
+}
+#endif
+
+static int crypto(int argc, char **argv)
+{
+ int result = RT_EOK;
+ static rt_device_t device = RT_NULL;
+ char *result_str;
+
+ if (argc > 1)
+ {
+ if (!strcmp(argv[1], "probe"))
+ {
+ if (argc == 3)
+ {
+ char *dev_name = argv[2];
+ device = rt_device_find(dev_name);
+ result_str = (device == RT_NULL) ? "failure" : "success";
+ rt_kprintf("probe %s %s \n", argv[2], result_str);
+ }
+ else
+ {
+ rt_kprintf("crypto probe <crypto_name> - probe crypto by name\n");
+ }
+ }
+ else
+ {
+ if (device == RT_NULL)
+ {
+ rt_kprintf("Please using 'crypto probe <crypto_name>' first\n");
+ return -RT_ERROR;
+ }
+ if (!strcmp(argv[1], "rng"))
+ {
+#if defined (BSP_USING_RNG)
+ if (argc == 3)
+ {
+ result = hw_rng_sample(atoi(argv[2]));
+ if(result != RT_EOK)
+ {
+ rt_kprintf("please input a legal number, not <%d>\n", atoi(argv[2]));
+ }
+ }
+ else
+ {
+ rt_kprintf("rng <number> - generate <number> digital\n");
+ }
+
+#else
+ rt_kprintf("please enable RNG first!\n");
+#endif
+ }
+ else if (!strcmp(argv[1], "crc"))
+ {
+#if defined (BSP_USING_CRC)
+ int size = 0, i = 0;
+ if (argc > 3)
+ {
+ size = argc - 2;
+ uint8_t *data = rt_malloc(size);
+ if (data)
+ {
+ for (i = 0; i < size; i++)
+ {
+ data[i] = strtol(argv[2 + i], NULL, 0);
+ }
+ hw_crc_sample(data, size);
+ rt_free(data);
+ }
+ else
+ {
+ rt_kprintf("Low memory!\n");
+ }
+ }
+ else
+ {
+ rt_kprintf("crypto crc data1 ... dataN - calculate data1 ... dataN crc\n");
+ }
+#else
+ rt_kprintf("please enable CRC first!\n");
+#endif
+ }
+ else if (!strcmp(argv[1], "hash"))
+ {
+#if defined (BSP_USING_HASH)
+ if (argc == 3)
+ {
+ hw_hash_sample();
+ }
+ else
+ {
+ rt_kprintf("crypto hash sample - hash use sample\n");
+ }
+#else
+ rt_kprintf("please enable CRC first!\n");
+#endif
+
+ }
+ else
+ {
+ rt_kprintf("Unknown command. Please enter 'crypto' for help\n");
+ }
+ }
+ }
+ else
+ {
+ rt_kprintf("Usage: \n");
+ rt_kprintf("crypto probe <crypto_name> - probe crypto by name\n");
+ rt_kprintf("crypto rng number - generate numbers digital\n");
+ rt_kprintf("crypto crc data1 ... dataN - calculate data1 ... dataN crc\n");
+ rt_kprintf("crypto hash sample - hash use sample\n");
+ result = -RT_ERROR;
+ }
+
+ return result;
+}
+MSH_CMD_EXPORT(crypto, crypto function);
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.c
new file mode 100644
index 0000000000..def5dfd461
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu the first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_DCMI)
+#include "drv_dcmi.h"
+
+#define DRV_DEBUG
+#define LOG_TAG "drv.dcmi"
+#include <drv_log.h>
+
+struct stm32_dcmi
+{
+ struct rt_device dev;
+};
+static struct stm32_dcmi rt_dcmi = {0};
+DCMI_HandleTypeDef dcmi = {0};
+DMA_HandleTypeDef hdma_dcmi = {0};
+
+extern void jpeg_data_process(void);
+
+static void rt_hw_dmci_dma_init(void)
+{
+ __HAL_RCC_DMAMUX_CLK_ENABLE();
+ __HAL_RCC_DMA1_CLK_ENABLE();
+
+ hdma_dcmi.Instance = DMA1_Stream3;
+ hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
+ hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
+ hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
+ hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
+ hdma_dcmi.Init.Mode = DMA_CIRCULAR;
+ hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH;
+ hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
+ hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
+ hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE;
+ hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;
+
+ HAL_DMA_Init(&hdma_dcmi);
+
+ __HAL_LINKDMA(&dcmi, DMA_Handle, hdma_dcmi);
+
+ HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0x02, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);
+}
+
+void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint16_t len)
+{
+ HAL_DMAEx_MultiBufferStart(&hdma_dcmi, (rt_uint32_t)&DCMI->DR, dst_addr1, dst_addr2, len);
+ __HAL_DMA_ENABLE_IT(&hdma_dcmi, DMA_IT_TC);
+}
+
+static rt_err_t rt_hw_dcmi_init(DCMI_HandleTypeDef *device)
+{
+ RT_ASSERT(device != RT_NULL);
+
+ device->Instance = DCMI;
+ device->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
+ device->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
+ device->Init.VSPolarity = DCMI_VSPOLARITY_LOW;
+ device->Init.HSPolarity = DCMI_HSPOLARITY_LOW;
+ device->Init.CaptureRate = DCMI_CR_ALL_FRAME;
+ device->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
+ device->Init.JPEGMode = DCMI_JPEG_DISABLE;
+ device->Init.ByteSelectMode = DCMI_BSM_ALL;
+ device->Init.ByteSelectStart = DCMI_OEBS_ODD;
+ device->Init.LineSelectMode = DCMI_LSM_ALL;
+ device->Init.LineSelectStart = DCMI_OELS_ODD;
+
+ if (HAL_DCMI_Init(device) != HAL_OK)
+ {
+ LOG_E("dcmi init error!");
+ return RT_ERROR;
+ }
+
+ DCMI->IER = 0x0;
+
+ __HAL_DCMI_ENABLE_IT(device, DCMI_IT_FRAME);
+ __HAL_DCMI_ENABLE(device);
+
+ rt_hw_dmci_dma_init();
+
+ return RT_EOK;
+}
+
+void DCMI_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_DCMI_IRQHandler(&dcmi);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+/* Capture a frame of the image */
+void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ jpeg_data_process();
+ __HAL_DCMI_ENABLE_IT(&dcmi,DCMI_IT_FRAME);
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void DMA1_Stream3_IRQHandler(void)
+{
+ extern void rt_hw_camera_rx_callback(void);
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ if(__HAL_DMA_GET_FLAG(&hdma_dcmi, DMA_FLAG_TCIF3_7)!=RESET)
+ {
+ __HAL_DMA_CLEAR_FLAG(&hdma_dcmi, DMA_FLAG_TCIF3_7);
+ rt_hw_camera_rx_callback();
+ }
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+static rt_err_t rt_dcmi_init(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+ rt_err_t result = RT_EOK;
+
+ result = rt_hw_dcmi_init(&dcmi);
+ if (result != RT_EOK)
+ {
+ return result;
+ }
+
+ return result;
+}
+
+static rt_err_t rt_dcmi_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_dcmi_close(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_dcmi_control(rt_device_t dev, int cmd, void *args)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_dcmi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_dcmi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+int dcmi_init(void)
+{
+ rt_dcmi.dev.type = RT_Device_Class_Miscellaneous;
+ rt_dcmi.dev.init = rt_dcmi_init;
+ rt_dcmi.dev.open = rt_dcmi_open;
+ rt_dcmi.dev.close = rt_dcmi_close;
+ rt_dcmi.dev.read = rt_dcmi_read;
+ rt_dcmi.dev.write = rt_dcmi_write;
+ rt_dcmi.dev.control = rt_dcmi_control;
+ rt_dcmi.dev.user_data = RT_NULL;
+
+ rt_device_register(&rt_dcmi.dev, "dcmi", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+ LOG_I("dcmi init success!");
+
+ return RT_EOK;
+}
+INIT_BOARD_EXPORT(dcmi_init);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.h
new file mode 100644
index 0000000000..39fe3bdd26
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dcmi.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu first version
+ */
+
+#ifndef __DRV_DCMI_H__
+#define __DRV_DCMI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.c
new file mode 100644
index 0000000000..c348751881
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-07 thread-liu first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_DFSDM)
+#include "drv_wm8994.h"
+#include "drv_dfsdm.h"
+
+#define DRV_DEBUG
+#define LOG_TAG "drv.dfsdm"
+#include <drv_log.h>
+
+#define FILTER_FIFO_SIZE (1024)
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFC8000)))
+#elif defined ( __GNUC__ )
+__attribute__((at(0x2FFC8000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFC8000
+#endif
+rt_int32_t FILTER0_FIFO[FILTER_FIFO_SIZE];
+
+#define PALY_SIZE 2048
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFCA000)))
+#elif defined ( __GNUC__ )
+__attribute__((at(0x2FFCA000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFCA000
+#endif
+static rt_int16_t PLAY_BUF[PALY_SIZE];
+
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFC9000)))
+#elif defined ( __GNUC__ )
+__attribute__((at(0x2FFC9000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFC9000
+#endif
+rt_int32_t FILTER1_FIFO[FILTER_FIFO_SIZE];
+
+static volatile rt_uint8_t DmaLeftRecBuffCplt = 0;
+static volatile rt_uint8_t DmaRightRecBuffCplt = 0;
+static volatile rt_uint8_t DmaLeftRecHalfBuffCplt = 0;
+static volatile rt_uint8_t DmaRightRecHalfBuffCplt = 0;
+
+static DFSDM_Channel_HandleTypeDef hdfsdm1_channel0 = {0}; /* data_in1_right */
+static DFSDM_Channel_HandleTypeDef hdfsdm1_channel1 = {0}; /* data_in1_left */
+
+static DFSDM_Filter_HandleTypeDef hdfsdm1_filter0 = {0}; /* data_in1_right */
+static DFSDM_Filter_HandleTypeDef hdfsdm1_filter1 = {0}; /* data_in1_left */
+
+extern DMA_HandleTypeDef hdma_dfsdm1_flt0;
+extern DMA_HandleTypeDef hdma_dfsdm1_flt1;
+
+static struct rt_device dfsdm_dev = {0};
+
+void DMA2_Stream2_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_DMA_IRQHandler(&hdma_dfsdm1_flt1);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void DMA2_Stream1_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_DMA_IRQHandler(&hdma_dfsdm1_flt0);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void HAL_DFSDM_FilterRegConvHalfCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
+{
+ if(hdfsdm_filter == &hdfsdm1_filter1)
+ {
+ DmaLeftRecHalfBuffCplt = 1;
+ }
+ else
+ {
+ DmaRightRecHalfBuffCplt = 1;
+ }
+}
+
+void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
+{
+ if (hdfsdm_filter == &hdfsdm1_filter1)
+ {
+ DmaLeftRecBuffCplt = 1;
+ }
+ else
+ {
+ DmaRightRecBuffCplt = 1;
+ }
+}
+
+static int rt_hw_dfsdm_init(void)
+{
+ /* DATAIN1_LEFT */
+ __HAL_DFSDM_CHANNEL_RESET_HANDLE_STATE(&hdfsdm1_channel1);
+ hdfsdm1_channel1.Instance = DFSDM1_Channel1;
+ hdfsdm1_channel1.Init.OutputClock.Activation = ENABLE;
+ hdfsdm1_channel1.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM; /* 209MHZ */
+ hdfsdm1_channel1.Init.OutputClock.Divider = 74; /* 209/74 = 2.82MHZ*/
+ hdfsdm1_channel1.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
+ hdfsdm1_channel1.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
+ hdfsdm1_channel1.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
+ hdfsdm1_channel1.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING ; /* left */
+ hdfsdm1_channel1.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
+ hdfsdm1_channel1.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER;
+ hdfsdm1_channel1.Init.Awd.Oversampling = 10;
+ hdfsdm1_channel1.Init.Offset = 0;
+ hdfsdm1_channel1.Init.RightBitShift = 2;
+ if(HAL_OK != HAL_DFSDM_ChannelInit(&hdfsdm1_channel1))
+ {
+ return RT_ERROR;
+ }
+
+ /* DATAIN1_RIGHT */
+ __HAL_DFSDM_CHANNEL_RESET_HANDLE_STATE(&hdfsdm1_channel0);
+ hdfsdm1_channel0.Instance = DFSDM1_Channel0;
+ hdfsdm1_channel0.Init.OutputClock.Activation = ENABLE;
+ hdfsdm1_channel0.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_SYSTEM;
+ hdfsdm1_channel0.Init.OutputClock.Divider = 74; /* 209/74 = 2.82MHZ*/
+ hdfsdm1_channel0.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
+ hdfsdm1_channel0.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
+ hdfsdm1_channel0.Init.Input.Pins = DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS;
+ hdfsdm1_channel0.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_FALLING; /* right */
+ hdfsdm1_channel0.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
+ hdfsdm1_channel0.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER;
+ hdfsdm1_channel0.Init.Awd.Oversampling = 10;
+ hdfsdm1_channel0.Init.Offset = 0;
+ hdfsdm1_channel0.Init.RightBitShift = 2;
+ if(HAL_OK != HAL_DFSDM_ChannelInit(&hdfsdm1_channel0))
+ {
+ return RT_ERROR;
+ }
+
+ /* Initialize filter 0 (data_in1 right channel) */
+ __HAL_DFSDM_FILTER_RESET_HANDLE_STATE(&hdfsdm1_filter0);
+ hdfsdm1_filter0.Instance = DFSDM1_Filter0;
+ hdfsdm1_filter0.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
+ hdfsdm1_filter0.Init.RegularParam.FastMode = ENABLE;
+ hdfsdm1_filter0.Init.RegularParam.DmaMode = ENABLE;
+ hdfsdm1_filter0.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
+ hdfsdm1_filter0.Init.InjectedParam.ScanMode = DISABLE;
+ hdfsdm1_filter0.Init.InjectedParam.DmaMode = DISABLE;
+ hdfsdm1_filter0.Init.FilterParam.SincOrder = DFSDM_FILTER_SINC3_ORDER;
+ hdfsdm1_filter0.Init.FilterParam.Oversampling = 64; /* 209 / ( 74 * 64) = 44.1KHZ*/
+ hdfsdm1_filter0.Init.FilterParam.IntOversampling = 1;
+ if (HAL_OK != HAL_DFSDM_FilterInit(&hdfsdm1_filter0))
+ {
+ return RT_ERROR;
+ }
+
+ /* Initialize filter 1 (data_in1 left channel) */
+ __HAL_DFSDM_FILTER_RESET_HANDLE_STATE(&hdfsdm1_filter1);
+ hdfsdm1_filter1.Instance = DFSDM1_Filter1;
+ hdfsdm1_filter1.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
+ hdfsdm1_filter1.Init.RegularParam.FastMode = ENABLE;
+ hdfsdm1_filter1.Init.RegularParam.DmaMode = ENABLE;
+ hdfsdm1_filter1.Init.InjectedParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
+ hdfsdm1_filter1.Init.InjectedParam.ScanMode = DISABLE;
+ hdfsdm1_filter1.Init.InjectedParam.DmaMode = DISABLE;
+ hdfsdm1_filter1.Init.FilterParam.SincOrder = DFSDM_FILTER_SINC3_ORDER;
+ hdfsdm1_filter1.Init.FilterParam.Oversampling = 64; /* 209 / ( 74 * 64) = 44.1KHZ*/
+ hdfsdm1_filter1.Init.FilterParam.IntOversampling = 1;
+ if (HAL_OK != HAL_DFSDM_FilterInit(&hdfsdm1_filter1))
+ {
+ return RT_ERROR;
+ }
+
+ /* Configure regular channel and continuous mode for filter 0 (data_in1 left channel) */
+ if (HAL_OK != HAL_DFSDM_FilterConfigRegChannel(&hdfsdm1_filter1, DFSDM_CHANNEL_1, DFSDM_CONTINUOUS_CONV_ON))
+ {
+ return RT_ERROR;
+ }
+
+ /* Configure regular channel and continuous mode for filter 1 (data_in1 right channel) */
+ if (HAL_OK != HAL_DFSDM_FilterConfigRegChannel(&hdfsdm1_filter0, DFSDM_CHANNEL_0, DFSDM_CONTINUOUS_CONV_ON))
+ {
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+/* dfsdm start coversions */
+static rt_err_t rt_hw_dfsdm_open(void)
+{
+ if (HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, FILTER0_FIFO, FILTER_FIFO_SIZE))
+ {
+ LOG_E("DFSDM DATA_IN1 rifht channel start conversions failed!");
+ return RT_ERROR;
+ }
+
+ if (HAL_OK != HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter1, FILTER1_FIFO, FILTER_FIFO_SIZE))
+ {
+ LOG_E("DFSDM DATA_IN1 left channel start conversions failed!");
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _init(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ rt_hw_dfsdm_init();
+
+ return RT_EOK;
+}
+
+static rt_err_t _open(rt_device_t dev, rt_uint16_t oflag)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ rt_hw_dfsdm_open();
+
+ return RT_EOK;
+}
+
+static rt_err_t _close(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ HAL_DFSDM_FilterRegularStop_DMA(&hdfsdm1_filter0);
+ HAL_DFSDM_FilterRegularStop_DMA(&hdfsdm1_filter1);
+
+ return RT_EOK;
+}
+
+static rt_size_t _read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+ rt_uint32_t i = 0;
+ rt_int16_t *p = RT_NULL;
+ p = (rt_int16_t *)buffer;
+
+ if (!pos)
+ {
+ for (i = 0; i < 512; i++)
+ {
+ p[2*i] = (int16_t)SaturaLH((FILTER0_FIFO[i] >> 8), -32768, 32767);
+ p[(2*i)+1] = (int16_t)SaturaLH((FILTER1_FIFO[i] >> 8), -32768, 32767);
+ }
+ }
+ else
+ {
+ for (i = 512; i < 1024; i++)
+ {
+ p[2*i] = (int16_t)SaturaLH((FILTER0_FIFO[i] >> 8), -32768, 32767);
+ p[(2*i)+1] = (int16_t)SaturaLH((FILTER1_FIFO[i] >> 8), -32768, 32767);
+ }
+ }
+
+ return size;
+}
+
+static rt_size_t _write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t _control(rt_device_t dev, int cmd, void *args)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+int dfsdm_init(void)
+{
+ dfsdm_dev.type = RT_Device_Class_Miscellaneous;
+ dfsdm_dev.init = _init;
+ dfsdm_dev.open = _open;
+ dfsdm_dev.close = _close;
+ dfsdm_dev.read = _read;
+ dfsdm_dev.write = _write;
+ dfsdm_dev.control = _control;
+ dfsdm_dev.user_data = RT_NULL;
+
+ rt_device_register(&dfsdm_dev, "dfsdm1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+ LOG_I("dfsdm1 init success!");
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(dfsdm_init);
+
+static int dfsdm_sample(int argc, char **argv)
+{
+ if (argc != 1)
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("dfsdm_sample\n");
+ return -1;
+ }
+
+ static struct rt_device *dfsdm_dev = RT_NULL;
+ static struct rt_device *sound_dev = RT_NULL;
+ rt_uint16_t play_type = OUTPUT_DEVICE_HEADPHONE;
+ rt_uint16_t tickstart = 0;
+
+ extern SAI_HandleTypeDef hsai_BlockA2;
+
+ dfsdm_dev = rt_device_find("dfsdm1");
+ if (dfsdm_dev == RT_NULL)
+ {
+ rt_kprintf("no dfsdm device!");
+ return RT_ERROR;
+ }
+
+ sound_dev = rt_device_find("decoder");
+ if (sound_dev == RT_NULL)
+ {
+ rt_kprintf("no decoder device!");
+ return RT_ERROR;
+ }
+
+ /* open dfsdm device */
+ rt_device_open(dfsdm_dev, RT_DEVICE_OFLAG_RDWR);
+ /* open sound device */
+ rt_device_open(sound_dev, RT_DEVICE_OFLAG_WRONLY);
+
+ rt_device_control(sound_dev, SET_PLAY_TYPE, &play_type);
+ rt_device_control(sound_dev, START_PLAY, RT_NULL);
+
+ rt_memset(PLAY_BUF, 0, PALY_SIZE);
+
+ tickstart = rt_tick_get();
+ if (HAL_SAI_Transmit_DMA(&hsai_BlockA2, (uint8_t *)PLAY_BUF, PALY_SIZE) != HAL_OK)
+ {
+ rt_kprintf("sai transmit dma failed!\n");
+ return RT_ERROR;
+ }
+ rt_kprintf("dfsdm audio record test begin!\n");
+
+ while (1)
+ {
+ if ((rt_tick_get() - tickstart) > 0x1000)
+ {
+ HAL_SAI_DMAStop(&hsai_BlockA2);
+ rt_device_close(dfsdm_dev);
+ break;
+ }
+ if (DmaLeftRecHalfBuffCplt && DmaRightRecHalfBuffCplt)
+ {
+ rt_device_read(dfsdm_dev, 0, PLAY_BUF, 512);
+ DmaLeftRecHalfBuffCplt = 0;
+ DmaRightRecHalfBuffCplt = 0;
+ }
+ else if (DmaLeftRecBuffCplt && DmaRightRecBuffCplt)
+ {
+ rt_device_read(dfsdm_dev, 1, PLAY_BUF, 512);
+ DmaLeftRecBuffCplt = 0;
+ DmaRightRecBuffCplt = 0;
+ }
+ }
+
+ rt_kprintf("dfsdm audio record test end!\n");
+
+ return RT_EOK;
+}
+MSH_CMD_EXPORT(dfsdm_sample, dfsdm audiorecord test);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.h
new file mode 100644
index 0000000000..bf40fbf2f8
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_dfsdm.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-07 thread-liu first version
+ */
+
+#ifndef __DRV_DFSDM_H__
+#define __DRV_DFSDM_H__
+
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SaturaLH(N, L, H) (((N)<(L))?(L):(((N)>(H))?(H):(N)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.c
new file mode 100644
index 0000000000..f7d4eeffc2
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-16 thread-liu first version
+ */
+
+#include "board.h"
+#include "drv_emmc.h"
+#include <dfs_fs.h>
+
+#ifdef BSP_USING_EMMC
+
+//#define DRV_DEBUG
+//#define EMMC_RX_DUMP
+//#define EMMC_TX_DUMP
+#define DBG_TAG "drv.emmc"
+#ifdef DRV_DEBUG
+#define DBG_LVL DBG_LOG
+#else
+#define DBG_LVL DBG_INFO
+#endif /* DRV_DEBUG */
+#include <rtdbg.h>
+
+static SD_HandleTypeDef hsd;
+static struct rt_mmcsd_host *host;
+#define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS (100000)
+
+#define RTHW_SDIO_LOCK(_sdio) rt_mutex_take(&_sdio->mutex, RT_WAITING_FOREVER)
+#define RTHW_SDIO_UNLOCK(_sdio) rt_mutex_release(&_sdio->mutex);
+
+struct sdio_pkg
+{
+ struct rt_mmcsd_cmd *cmd;
+ void *buff;
+ rt_uint32_t flag;
+};
+
+struct rthw_sdio
+{
+ struct rt_mmcsd_host *host;
+ struct stm32_sdio_des sdio_des;
+ struct rt_event event;
+ struct rt_mutex mutex;
+ struct sdio_pkg *pkg;
+};
+
+#define EMMC_BUFF_SIZE 4096
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+rt_uint8_t cache_buf[SDIO_BUFF_SIZE] __attribute__((at(0x2FFCB000)));
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFCB000
+rt_uint8_t cache_buf[EMMC_BUFF_SIZE];
+#elif defined ( __GNUC__ )
+rt_uint8_t cache_buf[SDIO_BUFF_SIZE] __attribute__((at(0x2FFCB000)));
+#endif
+
+#if defined(EMMC_RX_DUMP) || defined(EMMC_TX_DUMP)
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
+{
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%08X: ", i);
+
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%02X ", buf[i + j]);
+ else
+ rt_kprintf(" ");
+ rt_kprintf(" ");
+
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ rt_kprintf("\n");
+ }
+}
+#endif
+
+/**
+ * @brief This function get order from sdio.
+ * @param data
+ * @retval sdio order
+ */
+static int get_order(rt_uint32_t data)
+{
+ int order = 0;
+
+ switch (data)
+ {
+ case 1:
+ order = 0;
+ break;
+ case 2:
+ order = 1;
+ break;
+ case 4:
+ order = 2;
+ break;
+ case 8:
+ order = 3;
+ break;
+ case 16:
+ order = 4;
+ break;
+ case 32:
+ order = 5;
+ break;
+ case 64:
+ order = 6;
+ break;
+ case 128:
+ order = 7;
+ break;
+ case 256:
+ order = 8;
+ break;
+ case 512:
+ order = 9;
+ break;
+ case 1024:
+ order = 10;
+ break;
+ case 2048:
+ order = 11;
+ break;
+ case 4096:
+ order = 12;
+ break;
+ case 8192:
+ order = 13;
+ break;
+ case 16384:
+ order = 14;
+ break;
+ default :
+ order = 0;
+ break;
+ }
+ return order;
+}
+
+/**
+ * @brief This function wait sdio cmd completed.
+ * @param sdio rthw_sdio
+ * @retval None
+ */
+static void rthw_sdio_wait_completed(struct rthw_sdio *sdio)
+{
+ rt_uint32_t status;
+ struct rt_mmcsd_cmd *cmd = sdio->pkg->cmd;
+ struct rt_mmcsd_data *data = cmd->data;
+ struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
+
+ if (rt_event_recv(&sdio->event, 0xffffffff, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ rt_tick_from_millisecond(5000), &status) != RT_EOK)
+ {
+ LOG_E("wait cmd completed timeout");
+ cmd->err = -RT_ETIMEOUT;
+ return;
+ }
+
+ if (sdio->pkg == RT_NULL)
+ {
+ return;
+ }
+
+ cmd->resp[0] = hw_sdio->resp1;
+ cmd->resp[1] = hw_sdio->resp2;
+ cmd->resp[2] = hw_sdio->resp3;
+ cmd->resp[3] = hw_sdio->resp4;
+
+ if (status & SDMMC_ERRORS)
+ {
+ if ((status & SDMMC_STA_CCRCFAIL) && (resp_type(cmd) & (RESP_R3 | RESP_R4)))
+ {
+ cmd->err = RT_EOK;
+ }
+ else
+ {
+ cmd->err = -RT_ERROR;
+ }
+
+ if (status & SDMMC_STA_CTIMEOUT)
+ {
+ cmd->err = -RT_ETIMEOUT;
+ }
+
+ if (status & SDMMC_STA_DCRCFAIL)
+ {
+ data->err = -RT_ERROR;
+ }
+
+ if (status & SDMMC_STA_DTIMEOUT)
+ {
+ data->err = -RT_ETIMEOUT;
+ }
+
+ if (cmd->err == RT_EOK)
+ {
+ LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
+ }
+ else
+ {
+ LOG_D("err:0x%08x, %s%s%s%s%s%s%s cmd:%d arg:0x%08x rw:%c len:%d blksize:%d",
+ status,
+ status & SDMMC_STA_CCRCFAIL ? "CCRCFAIL " : "",
+ status & SDMMC_STA_DCRCFAIL ? "DCRCFAIL " : "",
+ status & SDMMC_STA_CTIMEOUT ? "CTIMEOUT " : "",
+ status & SDMMC_STA_DTIMEOUT ? "DTIMEOUT " : "",
+ status & SDMMC_STA_TXUNDERR ? "TXUNDERR " : "",
+ status & SDMMC_STA_RXOVERR ? "RXOVERR " : "",
+ status == 0 ? "NULL" : "",
+ cmd->cmd_code,
+ cmd->arg,
+ data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-',
+ data ? data->blks * data->blksize : 0,
+ data ? data->blksize : 0
+ );
+ }
+
+ }
+ else
+ {
+ cmd->err = RT_EOK;
+ LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
+ }
+}
+
+/**
+ * @brief This function send command.
+ * @param sdio rthw_sdio
+ * @param pkg sdio package
+ * @retval None
+ */
+static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
+{
+ struct rt_mmcsd_cmd *cmd = pkg->cmd;
+ struct rt_mmcsd_data *data = cmd->data;
+ struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
+ rt_uint32_t reg_cmd;
+
+ sdio->pkg = pkg;
+
+ LOG_D("CMD:%d ARG:0x%08x RES:%s%s%s%s%s%s%s%s%s rw:%c len:%d blksize:%d\n",
+ cmd->cmd_code,
+ cmd->arg,
+ resp_type(cmd) == RESP_NONE ? "NONE" : "",
+ resp_type(cmd) == RESP_R1 ? "R1" : "",
+ resp_type(cmd) == RESP_R1B ? "R1B" : "",
+ resp_type(cmd) == RESP_R2 ? "R2" : "",
+ resp_type(cmd) == RESP_R3 ? "R3" : "",
+ resp_type(cmd) == RESP_R4 ? "R4" : "",
+ resp_type(cmd) == RESP_R5 ? "R5" : "",
+ resp_type(cmd) == RESP_R6 ? "R6" : "",
+ resp_type(cmd) == RESP_R7 ? "R7" : "",
+ data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-',
+ data ? data->blks * data->blksize : 0,
+ data ? data->blksize : 0
+ );
+
+ /* config cmd reg */
+ reg_cmd = cmd->cmd_code | SDMMC_CMD_CPSMEN;
+ if (resp_type(cmd) == RESP_NONE)
+ {
+ reg_cmd |= SDMMC_RESPONSE_NO;
+ }
+ else if (resp_type(cmd) == RESP_R2)
+ {
+ reg_cmd |= SDMMC_RESPONSE_LONG;
+ }
+ else
+ {
+ reg_cmd |= SDMMC_RESPONSE_SHORT;
+ }
+ hw_sdio->mask |= SDIO_MASKR_ALL;
+
+ /* data pre configuration */
+ if (data != RT_NULL)
+ {
+ hw_sdio->dctrl = 0;
+ hw_sdio->mask &= ~(SDMMC_MASK_CMDRENDIE | SDMMC_MASK_CMDSENTIE);
+ reg_cmd |= SDMMC_CMD_CMDTRANS;
+ hw_sdio->dtimer = HW_SDIO_DATATIMEOUT;
+ hw_sdio->dlen = data->blks * data->blksize;
+ hw_sdio->dctrl = (get_order(data->blksize)<<4) | (data->flags & DATA_DIR_READ ? SDMMC_DCTRL_DTDIR : 0);
+ hw_sdio->idmabase0r = (rt_uint32_t)cache_buf;
+ hw_sdio->idmatrlr = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
+ }
+
+ hw_sdio->arg = cmd->arg;
+ hw_sdio->cmd = reg_cmd;
+ /* wait completed */
+ rthw_sdio_wait_completed(sdio);
+
+ /* Waiting for data to be sent to completion */
+ if (data != RT_NULL)
+ {
+ volatile rt_uint32_t count = SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS;
+
+ while (count && (hw_sdio->sta & SDMMC_STA_DPSMACT))
+ {
+ count--;
+ }
+ if ((count == 0) || (hw_sdio->sta & SDMMC_ERRORS))
+ {
+ cmd->err = -RT_ERROR;
+ }
+ }
+
+ /* data post configuration */
+ if (data != RT_NULL)
+ {
+ if (data->flags & DATA_DIR_READ)
+ {
+#if defined(EMMC_RX_DUMP)
+ rt_kprintf("\nEMMC Rx:\n");
+ dump_hex(cache_buf, data->blks * data->blksize);
+#endif
+ rt_memcpy(data->buf, cache_buf, data->blks * data->blksize);
+ }
+ }
+}
+
+/**
+ * @brief This function send sdio request.
+ * @param sdio rthw_sdio
+ * @param req request
+ * @retval None
+ */
+static void rthw_sdio_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
+{
+ struct sdio_pkg pkg;
+ struct rthw_sdio *sdio = host->private_data;
+ struct rt_mmcsd_data *data;
+
+ RTHW_SDIO_LOCK(sdio);
+
+ if (req->cmd != RT_NULL)
+ {
+ rt_memset(&pkg, 0, sizeof(pkg));
+ data = req->cmd->data;
+ pkg.cmd = req->cmd;
+
+ if (data != RT_NULL)
+ {
+ rt_uint32_t size = data->blks * data->blksize;
+
+ RT_ASSERT(size <= SDIO_BUFF_SIZE);
+
+ if (data->flags & DATA_DIR_WRITE)
+ {
+#if defined(EMMC_TX_DUMP)
+ rt_kprintf("\nEMMC Tx:\n");
+ dump_hex(cache_buf, data->blks * data->blksize);
+#endif
+ rt_memcpy(cache_buf, data->buf, size);
+ }
+ }
+
+ rthw_sdio_send_command(sdio, &pkg);
+ }
+
+ if (req->stop != RT_NULL)
+ {
+ rt_memset(&pkg, 0, sizeof(pkg));
+ pkg.cmd = req->stop;
+ rthw_sdio_send_command(sdio, &pkg);
+ }
+
+ RTHW_SDIO_UNLOCK(sdio);
+
+ mmcsd_req_complete(sdio->host);
+}
+
+
+/**
+ * @brief This function interrupt process function.
+ * @param host rt_mmcsd_host
+ * @retval None
+ */
+void rthw_sdio_irq_process(struct rt_mmcsd_host *host)
+{
+ struct rthw_sdio *sdio = host->private_data;
+ struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
+ rt_uint32_t intstatus = hw_sdio->sta;
+
+ /* clear irq flag*/
+ hw_sdio->icr = intstatus;
+
+ rt_event_send(&sdio->event, intstatus);
+}
+
+/**
+ * @brief This function config sdio.
+ * @param host rt_mmcsd_host
+ * @param io_cfg rt_mmcsd_io_cfg
+ * @retval None
+ */
+static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
+{
+ rt_uint32_t temp, clk_src;
+ rt_uint32_t clk = io_cfg->clock;
+ struct rthw_sdio *sdio = host->private_data;
+ struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
+
+ LOG_D("clk:%dK width:%s%s%s power:%s%s%s",
+ clk/1000,
+ io_cfg->bus_width == MMCSD_BUS_WIDTH_8 ? "8" : "",
+ io_cfg->bus_width == MMCSD_BUS_WIDTH_4 ? "4" : "",
+ io_cfg->bus_width == MMCSD_BUS_WIDTH_1 ? "1" : "",
+ io_cfg->power_mode == MMCSD_POWER_OFF ? "OFF" : "",
+ io_cfg->power_mode == MMCSD_POWER_UP ? "UP" : "",
+ io_cfg->power_mode == MMCSD_POWER_ON ? "ON" : ""
+ );
+
+ RTHW_SDIO_LOCK(sdio);
+
+ clk_src = EMMC_CLOCK_FREQ;
+
+ if (clk > 0)
+ {
+ if (clk > host->freq_max)
+ {
+ clk = host->freq_max;
+ }
+ temp = DIV_ROUND_UP(clk_src, 2 * clk);
+ if (temp > 0x3FF)
+ {
+ temp = 0x3FF;
+ }
+ }
+
+ if (io_cfg->bus_width == MMCSD_BUS_WIDTH_8)
+ {
+ temp |= SDMMC_BUS_WIDE_8B;
+ }
+ else if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
+ {
+ temp |= SDMMC_BUS_WIDE_4B;
+ }
+ else
+ {
+ temp |= SDMMC_BUS_WIDE_1B;
+ }
+
+ hw_sdio->clkcr = temp;
+
+ if (io_cfg->power_mode == MMCSD_POWER_ON)
+ hw_sdio->power |= SDMMC_POWER_PWRCTRL;
+
+ RTHW_SDIO_UNLOCK(sdio);
+}
+
+static const struct rt_mmcsd_host_ops ops =
+{
+ rthw_sdio_request,
+ rthw_sdio_iocfg,
+ RT_NULL,
+ RT_NULL,
+};
+
+/**
+ * @brief This function create mmcsd host.
+ * @param sdio_des stm32_sdio_des
+ * @retval rt_mmcsd_host
+ */
+struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
+{
+ struct rt_mmcsd_host *host;
+ struct rthw_sdio *sdio = RT_NULL;
+
+ if (sdio_des == RT_NULL)
+ {
+ return RT_NULL;
+ }
+
+ sdio = rt_malloc(sizeof(struct rthw_sdio));
+ if (sdio == RT_NULL)
+ {
+ LOG_E("malloc rthw_sdio fail");
+ return RT_NULL;
+ }
+ rt_memset(sdio, 0, sizeof(struct rthw_sdio));
+
+ host = mmcsd_alloc_host();
+ if (host == RT_NULL)
+ {
+ LOG_E("alloc host fail");
+ goto err;
+ }
+
+ rt_memcpy(&sdio->sdio_des, sdio_des, sizeof(struct stm32_sdio_des));
+
+ sdio->sdio_des.hw_sdio = (struct stm32_sdio *)EMMC_BASE_ADDRESS;
+
+ rt_event_init(&sdio->event, "sdio", RT_IPC_FLAG_FIFO);
+ rt_mutex_init(&sdio->mutex, "sdio", RT_IPC_FLAG_FIFO);
+ /* set host default attributes */
+ host->ops = &ops;
+ host->freq_min = 400 * 1000;
+ host->freq_max = EMMC_MAX_FREQ;
+ host->valid_ocr = 0X00FFFF80; /* The voltage range supported is 1.65v-3.6v */
+ host->flags = MMCSD_BUSWIDTH_8 | MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED;
+ host->max_seg_size = SDIO_BUFF_SIZE;
+ host->max_dma_segs = 1;
+ host->max_blk_size = 512;
+ host->max_blk_count = 512;
+
+ /* link up host and sdio */
+ sdio->host = host;
+ host->private_data = sdio;
+
+ /* ready to change */
+ mmcsd_change(host);
+
+ return host;
+
+err:
+ if (sdio)
+ {
+ rt_free(sdio);
+ }
+
+ return RT_NULL;
+}
+
+void SDMMC2_IRQHandler(void)
+{
+ rt_interrupt_enter();
+ /* Process All SDIO Interrupt Sources */
+ rthw_sdio_irq_process(host);
+
+ rt_interrupt_leave();
+}
+
+int rt_hw_sdio_init(void)
+{
+ struct stm32_sdio_des sdio_des;
+
+ hsd.Instance = SDMMC2;
+ HAL_SD_MspInit(&hsd);
+
+ host = sdio_host_create(&sdio_des);
+ if (host == RT_NULL)
+ {
+ LOG_E("host create fail");
+ return RT_NULL;
+ }
+ return 0;
+}
+INIT_DEVICE_EXPORT(rt_hw_sdio_init);
+
+#if defined(EMMC_USING_DFS)
+int mnt_init(void)
+{
+ rt_device_t sd = RT_NULL;
+
+#if defined(EMMC_RX_DUMP) || defined(EMMC_TX_DUMP)
+ rt_thread_delay(3000);
+#else
+ rt_thread_delay(RT_TICK_PER_SECOND);
+#endif
+
+ sd = rt_device_find("sd0");
+ if (sd == RT_NULL)
+ {
+ rt_kprintf("can't find emmc device!\n");
+ return RT_ERROR;
+ }
+
+ if (dfs_mount("sd0", "/", "elm", 0, 0) != 0)
+ {
+ rt_kprintf("file system mount failed!\n");
+ }
+ else
+ {
+ rt_kprintf("file system mount success!\n");
+ }
+
+ return 0;
+}
+INIT_APP_EXPORT(mnt_init);
+#endif
+
+#endif /* BSP_USING_SDMMC */
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.h
new file mode 100644
index 0000000000..bd385cbb14
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-16 thread-liu first version
+ */
+
+#ifndef __DRV_EMMC_H__
+#define __DRV_EMMC_H__
+
+#include <rtthread.h>
+#include "rtdevice.h"
+#include <rthw.h>
+#include <drv_common.h>
+#include <string.h>
+#include <drivers/mmcsd_core.h>
+#include <drivers/sdio.h>
+
+#define SDIO_BUFF_SIZE 4096
+
+#ifndef EMMC_BASE_ADDRESS
+#define EMMC_BASE_ADDRESS (SDMMC2)
+#endif
+
+#ifndef EMMC_CLOCK_FREQ
+#define EMMC_CLOCK_FREQ (99U * 1000 * 1000)
+#endif
+
+#ifndef EMMC_MAX_FREQ
+#define EMMC_MAX_FREQ (50 * 1000 * 1000)
+#endif
+
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
+#define SDMMC_ERRORS \
+ (SDMMC_STA_IDMATE | SDMMC_STA_ACKTIMEOUT | \
+ SDMMC_STA_RXOVERR | SDMMC_STA_TXUNDERR | \
+ SDMMC_STA_DTIMEOUT | SDMMC_STA_CTIMEOUT | \
+ SDMMC_STA_DCRCFAIL | SDMMC_STA_CCRCFAIL)
+
+#define SDIO_MASKR_ALL \
+ (SDMMC_MASK_CCRCFAILIE | SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_CTIMEOUTIE | \
+ SDMMC_MASK_TXUNDERRIE | SDMMC_MASK_RXOVERRIE | SDMMC_MASK_CMDRENDIE | \
+ SDMMC_MASK_CMDSENTIE | SDMMC_MASK_DATAENDIE | SDMMC_MASK_ACKTIMEOUTIE)
+
+#define HW_SDIO_DATATIMEOUT (0xFFFFFFFFU)
+
+struct stm32_sdio
+{
+ volatile rt_uint32_t power; /* offset 0x00 */
+ volatile rt_uint32_t clkcr; /* offset 0x04 */
+ volatile rt_uint32_t arg; /* offset 0x08 */
+ volatile rt_uint32_t cmd; /* offset 0x0C */
+ volatile rt_uint32_t respcmd; /* offset 0x10 */
+ volatile rt_uint32_t resp1; /* offset 0x14 */
+ volatile rt_uint32_t resp2; /* offset 0x18 */
+ volatile rt_uint32_t resp3; /* offset 0x1C */
+ volatile rt_uint32_t resp4; /* offset 0x20 */
+ volatile rt_uint32_t dtimer; /* offset 0x24 */
+ volatile rt_uint32_t dlen; /* offset 0x28 */
+ volatile rt_uint32_t dctrl; /* offset 0x2C */
+ volatile rt_uint32_t dcount; /* offset 0x30 */
+ volatile rt_uint32_t sta; /* offset 0x34 */
+ volatile rt_uint32_t icr; /* offset 0x38 */
+ volatile rt_uint32_t mask; /* offset 0x3C */
+ volatile rt_uint32_t acktimer; /* offset 0x40 */
+ volatile rt_uint32_t reserved0[3]; /* offset 0x44 ~ 0x4C */
+ volatile rt_uint32_t idmatrlr; /* offset 0x50 */
+ volatile rt_uint32_t idmabsizer; /* offset 0x54 */
+ volatile rt_uint32_t idmabase0r; /* offset 0x58 */
+ volatile rt_uint32_t idmabase1r; /* offset 0x5C */
+ volatile rt_uint32_t reserved1[1]; /* offset 0x60 */
+ volatile rt_uint32_t idmalar;
+ volatile rt_uint32_t idmabar;
+ volatile rt_uint32_t reserved2[5];
+ volatile rt_uint32_t fifo;
+ volatile rt_uint32_t reserved3[220];
+ volatile rt_uint32_t verr;
+ volatile rt_uint32_t ipidr;
+ volatile rt_uint32_t sidr;
+};
+
+typedef rt_uint32_t (*sdio_clk_get)(struct stm32_sdio *hw_sdio);
+
+struct stm32_sdio_des
+{
+ struct stm32_sdio *hw_sdio;
+ sdio_clk_get clk_get;
+};
+
+/* stm32 sdio dirver class */
+struct stm32_sdio_class
+{
+ struct stm32_sdio_des *des;
+ const struct stm32_sdio_config *cfg;
+ struct rt_mmcsd_host host;
+};
+
+extern void stm32_mmcsd_change(void);
+
+#endif /* __DRV_SDIO_H__ */
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_exti.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_exti.c
new file mode 100644
index 0000000000..d3d118fd9f
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_exti.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu first version
+ */
+
+#include "board.h"
+#ifdef BSP_USING_EXTI
+
+//#define DRV_DEBUG
+#define LOG_TAG "drv.exti"
+#include <drv_log.h>
+
+/* defined the KEY2 pin: */
+#define KEY2_PIN GET_PIN(A, 13)
+
+void key2_on(void *args)
+{
+ rt_kprintf("press key2!\n");
+}
+
+static int exti_sample(void)
+{
+ rt_pin_mode(KEY2_PIN, PIN_MODE_INPUT_PULLUP);
+ rt_pin_attach_irq(KEY2_PIN, PIN_IRQ_MODE_FALLING, key2_on, RT_NULL);
+ rt_pin_irq_enable(KEY2_PIN, PIN_IRQ_ENABLE);
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(exti_sample);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_fdcan.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_fdcan.c
new file mode 100644
index 0000000000..78c18e8594
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_fdcan.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-06 thread-liu first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_FDCAN1) || defined(BSP_USING_FDCAN2)
+
+#include "drv_fdcan.h"
+
+//#define DRV_DEBUG
+#define LOG_TAG "drv.fdcan"
+#include <drv_log.h>
+
+struct stm32_fdcan
+{
+ struct rt_device dev;
+ FDCAN_HandleTypeDef fdcan;
+ FDCAN_FilterTypeDef filter;
+ FDCAN_TxHeaderTypeDef tx_config;
+ FDCAN_RxHeaderTypeDef rx_config;
+ volatile rt_uint8_t fifo0;
+ volatile rt_uint8_t fifo1;
+};
+static struct stm32_fdcan rt_fdcan = {0};
+
+static rt_err_t rt_fdcan_init(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+ struct stm32_fdcan *device = (struct stm32_fdcan *)dev;
+
+ device->fdcan.Instance = FDCAN1;
+ device->fdcan.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
+ device->fdcan.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK;
+ device->fdcan.Init.AutoRetransmission = ENABLE;
+ device->fdcan.Init.TransmitPause = DISABLE;
+ device->fdcan.Init.ProtocolException = ENABLE;
+ device->fdcan.Init.NominalPrescaler = 0x01; /* tq = NominalPrescaler x (1/fdcan_ker_ck) */
+ device->fdcan.Init.NominalSyncJumpWidth = 0x08;
+ device->fdcan.Init.DataPrescaler = 0x01;
+ device->fdcan.Init.DataSyncJumpWidth = 0x04;
+ device->fdcan.Init.DataTimeSeg1 = 0x05; /* DataTimeSeg1 = Propagation_segment + Phase_segment_1 */
+ device->fdcan.Init.DataTimeSeg2 = 0x04;
+ device->fdcan.Init.NominalTimeSeg1 = 0x1F; /* NominalTimeSeg1 = Propagation_segment + Phase_segment_1 */
+ device->fdcan.Init.NominalTimeSeg2 = 0x08;
+ device->fdcan.Init.MessageRAMOffset = 0x00;
+ device->fdcan.Init.StdFiltersNbr = 0x01;
+ device->fdcan.Init.ExtFiltersNbr = 0x01;
+ device->fdcan.Init.RxFifo0ElmtsNbr = 0x01;
+ device->fdcan.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
+ device->fdcan.Init.RxFifo1ElmtsNbr = 0x02;
+ device->fdcan.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
+ device->fdcan.Init.RxBuffersNbr = 0x00;
+ device->fdcan.Init.TxEventsNbr = 0x00;
+ device->fdcan.Init.TxBuffersNbr = 0x00;
+ device->fdcan.Init.TxFifoQueueElmtsNbr = 0x01;
+ device->fdcan.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
+ device->fdcan.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
+
+ if (HAL_FDCAN_Init(&device->fdcan) != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+
+ device->filter.IdType = FDCAN_EXTENDED_ID;
+ device->filter.FilterIndex = 0;
+ device->filter.FilterType = FDCAN_FILTER_MASK;
+ device->filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
+ device->filter.FilterID1 = 0x1111111;
+ device->filter.FilterID2 = 0x2222222;
+
+ if (HAL_FDCAN_ConfigFilter(&device->fdcan, &device->filter)!=HAL_OK)
+ {
+ return RT_ERROR;
+ }
+ HAL_FDCAN_Start(&device->fdcan);
+ HAL_FDCAN_ActivateNotification(&device->fdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); /* open rx fifo0 new message it */
+
+ device->fifo0 = RESET;
+ device->fifo1 = RESET;
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_fdcan_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_fdcan_close(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_fdcan_control(rt_device_t dev, int cmd, void *args)
+{
+ RT_ASSERT(dev != RT_NULL);
+ struct stm32_fdcan *device = (struct stm32_fdcan *)dev;
+
+ switch (cmd)
+ {
+ case FDCAN_MODE_NORMAL:
+ device->fdcan.Init.Mode = FDCAN_MODE_NORMAL;
+ break;
+ case FDCAN_MODE_INTERNAL_LOOPBACK:
+ device->fdcan.Init.Mode = FDCAN_MODE_INTERNAL_LOOPBACK;
+ break;
+ default:
+ break;
+ }
+
+ HAL_FDCAN_Init(&device->fdcan);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_fdcan_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+ struct stm32_fdcan *device = (struct stm32_fdcan *)dev;
+
+ if (rt_fdcan.fifo0 == SET)
+ {
+ rt_fdcan.fifo0 = RESET;
+ if (HAL_FDCAN_GetRxMessage(&device->fdcan, FDCAN_RX_FIFO0, &device->rx_config, (uint8_t *)buffer) != HAL_OK)
+ {
+ LOG_E("get msg error from fdcan fifo0!");
+ return 0;
+ }
+
+ return device->rx_config.DataLength >> 16;
+ }
+ if (rt_fdcan.fifo1 == SET)
+ {
+ rt_fdcan.fifo0 = RESET;
+ if (HAL_FDCAN_GetRxMessage(&device->fdcan, FDCAN_RX_FIFO1, &device->rx_config, (uint8_t *)buffer) != HAL_OK)
+ {
+ LOG_E("get msg error from fdcan fifo1!");
+ return 0;
+ }
+
+ return device->rx_config.DataLength >> 16;
+ }
+
+ return 0;
+}
+
+static rt_size_t rt_fdcan_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+ struct stm32_fdcan *device = (struct stm32_fdcan *)dev;
+
+ device->tx_config.Identifier = 0x1111112;
+ device->tx_config.IdType = FDCAN_EXTENDED_ID;
+ device->tx_config.TxFrameType = FDCAN_DATA_FRAME;
+ device->tx_config.DataLength = FDCAN_DLC_BYTES_8;
+ device->tx_config.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
+ device->tx_config.BitRateSwitch = FDCAN_BRS_OFF;
+ device->tx_config.FDFormat = FDCAN_CLASSIC_CAN;
+ device->tx_config.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
+ device->tx_config.MessageMarker = 0xCC;
+
+ if (HAL_FDCAN_AddMessageToTxFifoQ(&device->fdcan, &device->tx_config, (uint8_t *)buffer) != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+void FDCAN1_IT0_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_FDCAN_IRQHandler(&rt_fdcan.fdcan);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void FDCAN1_IT1_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_FDCAN_IRQHandler(&rt_fdcan.fdcan);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
+{
+ if (hfdcan->Instance == FDCAN1)
+ {
+ if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
+ {
+ rt_fdcan.fifo0 = SET;
+ HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
+ }
+ }
+}
+
+void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
+{
+ if ((RxFifo1ITs & FDCAN_IT_RX_FIFO1_NEW_MESSAGE) != RESET)
+ {
+ rt_fdcan.fifo1 = SET;
+ HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0);
+ }
+}
+
+int fdcan_init(void)
+{
+ rt_fdcan.dev.type = RT_Device_Class_CAN;
+ rt_fdcan.dev.init = rt_fdcan_init;
+ rt_fdcan.dev.open = rt_fdcan_open;
+ rt_fdcan.dev.close = rt_fdcan_close;
+ rt_fdcan.dev.read = rt_fdcan_read;
+ rt_fdcan.dev.write = rt_fdcan_write;
+ rt_fdcan.dev.control = rt_fdcan_control;
+ rt_fdcan.dev.user_data = RT_NULL;
+
+ rt_device_register(&rt_fdcan.dev, "fdcan1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+ LOG_I("fdcan1 init success!");
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(fdcan_init);
+
+#ifdef FINSH_USING_MSH
+#include <finsh.h>
+
+int fdcan_sample(int argc, char **argv)
+{
+ rt_err_t result = RT_EOK;
+ rt_uint8_t i, rx_buf[8], tx_buf[8];
+ struct rt_device *dev = RT_NULL;
+
+ if (argc != 9)
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("fdcan_sample 1 2 3 4 5 6 7 8\n");
+ return -1;
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ tx_buf[i] = atoi(argv[i+1]);
+ }
+
+ dev = rt_device_find("fdcan1");
+ if (dev == RT_NULL)
+ {
+ rt_kprintf("can't find fdcan1 device!\n");
+ return RT_ERROR;
+ }
+ rt_device_open(dev, RT_DEVICE_OFLAG_RDWR);
+
+ rt_device_write(dev, 0, tx_buf, 8);
+ rt_thread_delay(1);
+ rt_device_read(dev, 0, rx_buf, 8);
+
+ rt_kprintf("fdcan1 loopback test over, rbuf = ");
+ for (i = 0; i < 8; i++)
+ {
+ rt_kprintf(" %x ", rx_buf[i]);
+ }
+ rt_kprintf("\n");
+
+ return result;
+}
+
+MSH_CMD_EXPORT(fdcan_sample, fdcan loopback mode test);
+
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_fdcan.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_fdcan.h
new file mode 100644
index 0000000000..ab4280d360
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_fdcan.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-06 thread-liu first version
+ */
+
+#ifndef __DRV_FDCAN_H__
+#define __DRV_FDCAN_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_lptim.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_lptim.c
new file mode 100644
index 0000000000..195345c19d
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_lptim.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-06-19 thread-liu first version
+ */
+
+#include <board.h>
+
+#ifdef BSP_USING_LPTIM
+#include "drv_config.h"
+#include <string.h>
+#include <stdlib.h>
+
+//#define DRV_DEBUG
+#define LOG_TAG "drv.lptimer"
+#include <drv_log.h>
+
+#define LED5_PIN GET_PIN(D, 9)
+LPTIM_HandleTypeDef hlptim1;
+
+extern int lptim_stop(void);
+
+void LPTIM1_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_LPTIM_IRQHandler(&hlptim1);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
+{
+ if(hlptim->Instance == LPTIM1)
+ {
+ HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_9);
+ }
+
+#if defined(BSP_USING_PWR)
+ /* All level of ITs can interrupt */
+ __set_BASEPRI(0U);
+
+ lptim_stop();
+ rt_kprintf("system returns to normal!\n");
+#endif
+}
+
+static int lptim_control(uint8_t pre_value)
+{
+ if(pre_value > 7)
+ {
+ pre_value = 7;
+ }
+ hlptim1.Instance->CFGR &= ~(7 << 9); /* clear PRESC[2:0] */
+ hlptim1.Instance->CFGR |= pre_value << 9; /* set PRESC[2:0] */
+ rt_kprintf("set lptim pre value [0x%x] success!\n", pre_value);
+
+ return RT_EOK;
+}
+
+int lptim_start(void)
+{
+ /* ### Start counting in interrupt mode ############################# */
+ if (HAL_LPTIM_Counter_Start_IT(&hlptim1, 32767) != HAL_OK)
+ {
+ LOG_D("lptim1 start counting failed!\n");
+ return -RT_ERROR;
+ }
+
+ LOG_D("lptim1 start counting success!\n");
+
+ return RT_EOK;
+}
+
+int lptim_stop(void)
+{
+ if (HAL_LPTIM_Counter_Stop_IT(&hlptim1) != HAL_OK)
+ {
+ LOG_D("lptim1 stop failed!\n");
+ return -RT_ERROR;
+ }
+
+ LOG_D("lptim1 stop counting success!\n");
+
+ return RT_EOK;
+}
+
+int lptim_init(void)
+{
+ rt_pin_mode(LED5_PIN, PIN_MODE_OUTPUT);
+
+ hlptim1.Instance = LPTIM1;
+ hlptim1.Init.Clock.Source = LPTIM_CLOCKSOURCE_APBCLOCK_LPOSC;
+ hlptim1.Init.Clock.Prescaler = LPTIM_PRESCALER_DIV8;
+ hlptim1.Init.UltraLowPowerClock.Polarity = LPTIM_CLOCKPOLARITY_RISING;
+ hlptim1.Init.UltraLowPowerClock.SampleTime = LPTIM_CLOCKSAMPLETIME_DIRECTTRANSITION;
+ hlptim1.Init.Trigger.Source = LPTIM_TRIGSOURCE_SOFTWARE;
+ hlptim1.Init.OutputPolarity = LPTIM_OUTPUTPOLARITY_HIGH;
+ hlptim1.Init.UpdateMode = LPTIM_UPDATE_IMMEDIATE;
+ hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
+ hlptim1.Init.Input1Source = LPTIM_INPUT1SOURCE_GPIO;
+ hlptim1.Init.Input2Source = LPTIM_INPUT2SOURCE_GPIO;
+ if (HAL_LPTIM_Init(&hlptim1) != HAL_OK)
+ {
+ LOG_D("lptim init failed!\n");
+ return -RT_ERROR;
+ }
+ LOG_D("lptim init success!\n");
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(lptim_init);
+
+static int lptim_sample(int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ if (!strcmp(argv[1], "start"))
+ {
+ lptim_start();
+ return RT_EOK;
+ }
+ else if (!strcmp(argv[1], "stop"))
+ {
+ lptim_stop();
+ return RT_EOK;
+ }
+ else if (!strcmp(argv[1], "set"))
+ {
+ if (argc > 2)
+ {
+ lptim_control(atoi(argv[2]));
+ return RT_EOK;
+ }
+ else
+ {
+ goto _exit;
+ }
+ }
+ else
+ {
+ goto _exit;
+ }
+ }
+_exit:
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("lptim_sample start - start lptim, the LED5 will start blink\n");
+ rt_kprintf("lptim_sample stop - stop lptim, the LED5 will stop blink\n");
+ rt_kprintf("lptim_sample set - set the lptim prescaler to change LED5 blink frquency, lptim_sample set [0 - 7]\n");
+ }
+
+ return -RT_ERROR;
+}
+MSH_CMD_EXPORT(lptim_sample, low power timer sample);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.c
new file mode 100644
index 0000000000..071f833a10
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-08-08 thread-liu first version
+ */
+
+#include "board.h"
+
+#include "mfxstm32l152.h"
+#define DRV_DEBUG
+#define LOG_TAG "drv.mfx"
+#include <drv_log.h>
+
+#define CHIP_ADDRESS 0x42 /* mfx address */
+#define I2C_NAME "i2c2"
+
+struct st_mfx
+{
+ struct rt_device dev;
+ struct rt_i2c_bus_device *i2c_bus;
+ rt_uint8_t id;
+ rt_uint16_t type;
+};
+static struct st_mfx rt_mfx = {0};
+static IO_DrvTypeDef *IoDrv = NULL;
+
+static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint16_t len, rt_uint8_t *buf)
+{
+ struct rt_i2c_msg msg[2] = {0, 0};
+
+ RT_ASSERT(bus != RT_NULL);
+
+ msg[0].addr = CHIP_ADDRESS;
+ msg[0].flags = RT_I2C_WR;
+ msg[0].buf = &reg;
+ msg[0].len = 1;
+
+ msg[1].addr = CHIP_ADDRESS;
+ msg[1].flags = RT_I2C_RD;
+ msg[1].len = len;
+ msg[1].buf = buf;
+
+ if (rt_i2c_transfer(bus, msg, 2) == 2)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* i2c write reg */
+static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t data)
+{
+ rt_uint8_t buf[2];
+ struct rt_i2c_msg msgs;
+
+ RT_ASSERT(bus != RT_NULL);
+ buf[0] = reg;
+ buf[1] = data;
+
+ msgs.addr = CHIP_ADDRESS;
+ msgs.flags = RT_I2C_WR;
+ msgs.buf = buf;
+ msgs.len = sizeof(buf);
+
+ if (rt_i2c_transfer(bus, &msgs, 1) == 1)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+void MFX_IO_Init(void)
+{
+ rt_mfx.i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
+ if (rt_mfx.i2c_bus == RT_NULL)
+ {
+ LOG_E("can't find %c deivce", I2C_NAME);
+ }
+}
+
+void MFX_IO_DeInit(void)
+{
+}
+
+void MFX_IO_ITConfig(void)
+{
+ static rt_uint8_t mfx_io_it_enabled = 0;
+ GPIO_InitTypeDef gpio_init_structure;
+
+ if(mfx_io_it_enabled == 0)
+ {
+ mfx_io_it_enabled = 1;
+ /* Enable the GPIO EXTI clock */
+ __HAL_RCC_GPIOI_CLK_ENABLE();
+
+ gpio_init_structure.Pin = GPIO_PIN_8;
+ gpio_init_structure.Pull = GPIO_NOPULL;
+ gpio_init_structure.Speed = GPIO_SPEED_FREQ_LOW;
+ gpio_init_structure.Mode = GPIO_MODE_IT_RISING;
+ HAL_GPIO_Init(GPIOI, &gpio_init_structure);
+
+ /* Enable and set GPIO EXTI Interrupt to the lowest priority */
+ HAL_NVIC_SetPriority((IRQn_Type)(EXTI8_IRQn), 0x04, 0x00);
+ HAL_NVIC_EnableIRQ((IRQn_Type)(EXTI8_IRQn));
+ }
+}
+
+void MFX_IO_Write(rt_uint16_t Addr, rt_uint8_t Reg, rt_uint8_t Value)
+{
+ write_reg(rt_mfx.i2c_bus, Reg, Value);
+}
+
+rt_uint8_t MFX_IO_Read(rt_uint16_t Addr, rt_uint8_t Reg)
+{
+ rt_uint8_t value = 0;
+ read_reg(rt_mfx.i2c_bus, Reg, 1, &value);
+
+ return value;
+}
+
+rt_uint16_t MFX_IO_ReadMultiple(rt_uint16_t Addr, rt_uint8_t Reg, rt_uint8_t *Buffer, rt_uint16_t Length)
+{
+ return read_reg(rt_mfx.i2c_bus, Reg, Length, Buffer);
+}
+
+RT_WEAK void MFX_IO_Delay(rt_uint32_t Delay)
+{
+ rt_thread_delay(Delay);
+}
+
+RT_WEAK void MFX_IO_Wakeup(void)
+{
+}
+
+RT_WEAK void MFX_IO_EnableWakeupPin(void)
+{
+}
+
+rt_uint8_t BSP_IO_DeInit(void)
+{
+ IoDrv = NULL;
+ return RT_EOK;
+}
+
+rt_uint32_t BSP_IO_ITGetStatus(rt_uint32_t IoPin)
+{
+ /* Return the IO Pin IT status */
+ return (IoDrv->ITStatus(0, IoPin));
+}
+
+/**
+ * @brief Clears all the IO IT pending bits.
+ * @retval None
+ */
+void BSP_IO_ITClear(void)
+{
+ /* Clear all IO IT pending bits */
+ IoDrv->ClearIT(0, MFXSTM32L152_GPIO_PINS_ALL);
+}
+
+void BSP_IO_ITClearPin(rt_uint32_t IO_Pins_To_Clear)
+{
+ /* Clear only the selected list of IO IT pending bits */
+ IoDrv->ClearIT(0, IO_Pins_To_Clear);
+}
+
+/**
+ * @brief Configures the IO pin(s) according to IO mode structure value.
+ * @param IoPin: IO pin(s) to be configured.
+ * This parameter can be one of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @param IoMode: IO pin mode to configure
+ * This parameter can be one of the following values:
+ * @arg IO_MODE_INPUT
+ * @arg IO_MODE_OUTPUT
+ * @arg IO_MODE_IT_RISING_EDGE
+ * @arg IO_MODE_IT_FALLING_EDGE
+ * @arg IO_MODE_IT_LOW_LEVEL
+ * @arg IO_MODE_IT_HIGH_LEVEL
+ * @arg IO_MODE_ANALOG
+ * @arg IO_MODE_OFF
+ * @arg IO_MODE_INPUT_PU,
+ * @arg IO_MODE_INPUT_PD,
+ * @arg IO_MODE_OUTPUT_OD,
+ * @arg IO_MODE_OUTPUT_OD_PU,
+ * @arg IO_MODE_OUTPUT_OD_PD,
+ * @arg IO_MODE_OUTPUT_PP,
+ * @arg IO_MODE_OUTPUT_PP_PU,
+ * @arg IO_MODE_OUTPUT_PP_PD,
+ * @arg IO_MODE_IT_RISING_EDGE_PU
+ * @arg IO_MODE_IT_FALLING_EDGE_PU
+ * @arg IO_MODE_IT_LOW_LEVEL_PU
+ * @arg IO_MODE_IT_HIGH_LEVEL_PU
+ * @arg IO_MODE_IT_RISING_EDGE_PD
+ * @arg IO_MODE_IT_FALLING_EDGE_PD
+ * @arg IO_MODE_IT_LOW_LEVEL_PD
+ * @arg IO_MODE_IT_HIGH_LEVEL_PD
+ * @retval RT_EOK if all initializations are OK. Other value if error.
+ */
+rt_uint8_t rt_mfx_pin_mode(rt_uint32_t IoPin, IO_ModeTypedef IoMode)
+{
+ /* Configure the selected IO pin(s) mode */
+ IoDrv->Config(0, IoPin, IoMode);
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Sets the IRQ_OUT pin polarity and type
+ * @param IoIrqOutPinPolarity: High/Low
+ * @param IoIrqOutPinType: OpenDrain/PushPull
+ * @retval OK
+ */
+rt_uint8_t rt_mfx_config_irq(rt_uint8_t IoIrqOutPinPolarity, rt_uint8_t IoIrqOutPinType)
+{
+ if((rt_mfx.id == MFXSTM32L152_ID_1) || (rt_mfx.id == MFXSTM32L152_ID_2))
+ {
+ /* Initialize the IO driver structure */
+ mfxstm32l152_SetIrqOutPinPolarity(0, IoIrqOutPinPolarity);
+ mfxstm32l152_SetIrqOutPinType(0, IoIrqOutPinType);
+ }
+
+ return RT_EOK;
+}
+
+/**
+ * @brief Sets the selected pins state.
+ * @param IoPin: Selected pins to write.
+ * This parameter can be any combination of the IO pins.
+ * @param PinState: New pins state to write
+ * @retval None
+ */
+void rt_mfx_pin_write(rt_uint32_t IoPin, rt_base_t PinState)
+{
+ /* Set the Pin state */
+ IoDrv->WritePin(0, IoPin, PinState);
+}
+
+/**
+ * @brief Gets the selected pins current state.
+ * @param IoPin: Selected pins to read.
+ * This parameter can be any combination of the IO pins.
+ * @retval The current pins state
+ */
+rt_uint32_t rt_mfx_pin_read(rt_uint32_t IoPin)
+{
+ return(IoDrv->ReadPin(0, IoPin));
+}
+
+/**
+ * @brief Toggles the selected pins state.
+ * @param IoPin: Selected pins to toggle.
+ * This parameter can be any combination of the IO pins.
+ * @note This function is only used to toggle one pin in the same time
+ * @retval None
+ */
+void rt_mfx_pin_toggle(rt_uint32_t IoPin)
+{
+ /* Toggle the current pin state */
+ if(IoDrv->ReadPin(0, IoPin) != 0)
+ {
+ IoDrv->WritePin(0, IoPin, 0); /* Reset */
+ }
+ else
+ {
+ IoDrv->WritePin(0, IoPin, 1); /* Set */
+ }
+}
+
+int rt_mfx_init(void)
+{
+ /* Read ID and verify the MFX is ready */
+ rt_mfx.id = mfxstm32l152_io_drv.ReadID(0);
+ if((rt_mfx.id == MFXSTM32L152_ID_1) || (rt_mfx.id == MFXSTM32L152_ID_2))
+ {
+ /* Initialize the IO driver structure */
+ IoDrv = &mfxstm32l152_io_drv;
+
+ /* Initialize MFX */
+ IoDrv->Init(0);
+ IoDrv->Start(0, IO_PIN_ALL);
+
+ LOG_I("mfx init success, id: 0x%x", rt_mfx.id);
+
+ return RT_EOK;
+ }
+ LOG_I("mfx init error, id: 0x%x", rt_mfx.id);
+
+ return RT_ERROR;
+}
+INIT_DEVICE_EXPORT(rt_mfx_init);
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.h
new file mode 100644
index 0000000000..a0cf46777c
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_mfx.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-08-08 thread-liu first version
+ */
+
+#ifndef __DRV_MFX_H__
+#define __DRV_MFX_H__
+
+#include "board.h"
+#include "mfxstm32l152.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ BSP_IO_PIN_RESET = 0,
+ BSP_IO_PIN_SET = 1
+}BSP_IO_PinStateTypeDef;
+
+#define CAMERA_RST1 MFXSTM32L152_AGPIO_PIN_3
+#define CAMERA_XSDN MFXSTM32L152_AGPIO_PIN_2
+#define CARMERA_PLUG MFXSTM32L152_GPIO_PIN_12
+
+void rt_mfx_init(void);
+rt_uint32_t BSP_IO_ITGetStatus(rt_uint32_t IoPin);
+void BSP_IO_ITClear(void);
+void BSP_IO_ITClearPin(rt_uint32_t IO_Pins_To_Clear);
+rt_uint8_t rt_mfx_pin_mode(rt_uint32_t IoPin, IO_ModeTypedef IoMode);
+rt_uint8_t rt_mfx_config_irq(rt_uint8_t IoIrqOutPinPolarity, rt_uint8_t IoIrqOutPinType);
+void rt_mfx_pin_write(rt_uint32_t IoPin, rt_base_t PinState);
+rt_uint32_t rt_mfx_pin_read(rt_uint32_t IoPin);
+void rt_mfx_pin_toggle(rt_uint32_t IoPin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.c
new file mode 100644
index 0000000000..b8dada9d5a
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.c
@@ -0,0 +1,666 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-08-03 thread-liu the first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_DCMI)
+
+#include "drv_mfx.h"
+#include <dfs_posix.h>
+#include "drv_ov5640.h"
+
+//#define DRV_DEBUG
+//#define CAMERA_DUMP
+#define LOG_TAG "drv.ov5640"
+#include <drv_log.h>
+
+#define CHIP_ADDRESS 0x3C /* OV5640 address */
+#define I2C_NAME "i2c2"
+
+#define JPEG_BUF_SIZE 8 * 1024
+#define JPEG_LINE_SIZE 1 * 1024
+
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFCC000)))
+#elif defined(__GNUC__)
+__attribute__((at(0x2FFCC000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFCC000
+#endif
+static rt_int32_t JPEG_DATA_BUF[JPEG_BUF_SIZE];
+
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFDC000)))
+#elif defined(__GNUC__)
+__attribute__((at(0x2FFDC000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFDC000
+#endif
+static rt_int32_t JPEG_LINE_BUF[2][JPEG_LINE_SIZE];
+
+
+volatile rt_uint32_t jpeg_data_len = 0;
+volatile rt_uint8_t jpeg_data_ok = 0;
+struct rt_i2c_bus_device *i2c_bus = RT_NULL;
+extern DCMI_HandleTypeDef dcmi;
+extern DMA_HandleTypeDef hdma_dcmi;
+
+#if defined(CAMERA_DUMP)
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
+{
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%08x:", i);
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j < buflen)
+ {
+ rt_kprintf("%02x", buf[i + j]);
+ }
+ else
+ {
+ rt_kprintf(" ");
+ }
+ }
+ rt_kprintf(" ");
+
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j < buflen)
+ {
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ }
+ }
+ rt_kprintf("\n");
+ }
+}
+#endif
+
+static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint8_t len, rt_uint8_t *buf)
+{
+ struct rt_i2c_msg msg[2] = {0, 0};
+ static rt_uint8_t i2c_reg[2] = {0, 0};
+
+ RT_ASSERT(bus != RT_NULL);
+
+ i2c_reg[0] = ((uint16_t)(reg >> 8) & 0xFF);
+ i2c_reg[1] = ((uint16_t)(reg & 0xFF));
+
+ msg[0].addr = CHIP_ADDRESS;
+ msg[0].flags = RT_I2C_WR;
+ msg[0].buf = i2c_reg;
+ msg[0].len = 2;
+
+ msg[1].addr = CHIP_ADDRESS;
+ msg[1].flags = RT_I2C_RD;
+ msg[1].len = len;
+ msg[1].buf = buf;
+
+ if (rt_i2c_transfer(bus, msg, 2) == 2)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* i2c write reg */
+static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint8_t data)
+{
+ rt_uint8_t buf[3];
+ struct rt_i2c_msg msgs;
+
+ RT_ASSERT(bus != RT_NULL);
+
+ buf[0] = ((uint16_t)(reg >> 8) & 0xFF);
+ buf[1] = ((uint16_t)(reg)&0xFF);
+
+ buf[2] = data;
+
+ msgs.addr = CHIP_ADDRESS;
+ msgs.flags = RT_I2C_WR;
+ msgs.buf = buf;
+ msgs.len = 3;
+
+ if (rt_i2c_transfer(bus, &msgs, 1) == 1)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+static rt_err_t ov5640_read_id(struct rt_i2c_bus_device *bus, rt_uint16_t *id)
+{
+ rt_uint8_t read_value[2];
+
+ read_reg(bus, 0x300A, 1, &read_value[0]);
+ read_reg(bus, 0x300B, 1, &read_value[1]);
+ *id = ((uint16_t)(read_value[0] << 8) & 0xFF00);
+ *id |= ((uint16_t)(read_value[1]) & 0x00FF);
+
+ if (*id != OV5640_ID)
+ {
+ LOG_E("ov5640 init error, id: 0x%04x", *id);
+ return RT_ERROR;
+ }
+
+ LOG_I("ov5640 init success, id: 0x%04x", *id);
+
+ return RT_EOK;
+}
+
+static rt_err_t ov5640_hard_reset(struct rt_i2c_bus_device *bus)
+{
+ /* Camera sensor RESET sequence */
+ rt_mfx_pin_mode(CAMERA_RST1, IO_MODE_OUTPUT);
+ rt_mfx_pin_mode(CAMERA_XSDN, IO_MODE_OUTPUT);
+
+ /* Assert the camera STANDBY pin (active high) */
+ rt_mfx_pin_write(CAMERA_XSDN, BSP_IO_PIN_SET);
+
+ /* Assert the camera RSTI pin (active low) */
+ rt_mfx_pin_write(CAMERA_RST1, BSP_IO_PIN_RESET);
+
+ rt_thread_delay(100); /* RST and XSDN signals asserted during 100ms */
+
+ /* De-assert the camera STANDBY pin (active high) */
+ rt_mfx_pin_write(CAMERA_XSDN, BSP_IO_PIN_RESET);
+
+ rt_thread_delay(3); /* RST de-asserted and XSDN asserted during 3ms */
+
+ /* De-assert the camera RSTI pin (active low) */
+ rt_mfx_pin_write(CAMERA_RST1, BSP_IO_PIN_SET);
+
+ rt_thread_delay(6); /* RST de-asserted during 3ms */
+
+ return RT_EOK;
+}
+
+void OV5640_Flash_Ctrl(struct rt_i2c_bus_device *bus, rt_uint8_t sw)
+{
+ write_reg(bus, 0x3016, 0X02);
+ write_reg(bus, 0x301C, 0X02);
+ if (sw)
+ {
+ write_reg(bus, 0X3019, 0X02);
+ }
+ else
+ {
+ write_reg(bus, 0X3019, 0X00);
+ }
+}
+
+static rt_err_t ov5640_config(struct rt_i2c_bus_device *bus)
+{
+ rt_uint32_t i = 0;
+ rt_uint8_t value = 0;
+
+ write_reg(bus, 0x3103, 0X11); /* system clock from pad, bit[1] */
+ write_reg(bus, 0X3008, 0X82); /* soft reset */
+
+ rt_thread_delay(10);
+
+ for (i = 0; i < (sizeof(RGB565_Init) / 4); i++)
+ {
+ write_reg(bus, RGB565_Init[i][0], RGB565_Init[i][1]);
+ rt_thread_delay(10);
+ read_reg(bus, RGB565_Init[i][0], 1, &value);
+
+ if (RGB565_Init[i][1] != value)
+ {
+ LOG_D("error reg value[0x%x]:0x%02x - 0x%02x", RGB565_Init[i][0], RGB565_Init[i][1], value);
+ }
+ }
+
+ OV5640_Flash_Ctrl(bus, 1); /* open camera flash*/
+ rt_thread_delay(3);
+ OV5640_Flash_Ctrl(bus, 0); /* close camera flash*/
+
+ return RT_EOK;
+}
+
+/* JPEG */
+void ov5640_jpeg_mode(struct rt_i2c_bus_device *bus)
+{
+ rt_uint16_t i = 0;
+ for (i = 0; i < (sizeof(OV5640_jpeg_reg_tbl) / 4); i++)
+ {
+ write_reg(bus, OV5640_jpeg_reg_tbl[i][0], OV5640_jpeg_reg_tbl[i][1]);
+ }
+}
+
+/* RGB565 */
+void ov5640_rgb565_mode(struct rt_i2c_bus_device *bus)
+{
+ rt_uint16_t i = 0;
+ for (i = 0; i < (sizeof(ov5640_rgb565_reg_tbl) / 4); i++)
+ {
+ write_reg(bus, ov5640_rgb565_reg_tbl[i][0], ov5640_rgb565_reg_tbl[i][1]);
+ }
+
+ write_reg(bus, 0x3821, 0x06);
+}
+
+rt_uint8_t ov5640_focus_init(struct rt_i2c_bus_device *bus)
+{
+ rt_uint16_t tickstart = 0 ,i = 0;
+ rt_uint16_t addr = 0x8000;
+ rt_uint8_t state = 0x8F;
+
+ write_reg(bus, 0x3000, 0x20); //reset MCU
+ for (i = 0; i < sizeof(OV5640_AF_Config); i++)
+ {
+ write_reg(bus, addr, OV5640_AF_Config[i]);
+ addr++;
+ }
+ write_reg(bus, 0x3022, 0x00);
+ write_reg(bus, 0x3023, 0x00);
+ write_reg(bus, 0x3024, 0x00);
+ write_reg(bus, 0x3025, 0x00);
+ write_reg(bus, 0x3026, 0x00);
+ write_reg(bus, 0x3027, 0x00);
+ write_reg(bus, 0x3028, 0x00);
+ write_reg(bus, 0x3029, 0x7f);
+ write_reg(bus, 0x3000, 0x00);
+ i = 0;
+
+ tickstart = rt_tick_get();
+ do
+ {
+ read_reg(bus, 0x3029, 1, &state);
+ if (rt_tick_get() - tickstart > 1000)
+ {
+ return RT_ERROR;
+ }
+ } while (state != 0x70);
+
+ return RT_EOK;
+}
+
+void ov5640_set_light(struct rt_i2c_bus_device *bus, rt_uint8_t mode)
+{
+ rt_uint8_t i = 0;
+ write_reg(bus, 0x3212, 0x03); //start group 3
+
+ for (i = 0; i < 7; i++)
+ {
+ write_reg(bus, 0x3400 + i, OV5640_LIGHTMODE_TBL[mode][i]);
+ }
+
+ write_reg(bus, 0x3212, 0x13); //end group 3
+ write_reg(bus, 0x3212, 0xa3); //launch group 3
+}
+
+/* sat:0~6 */
+void ov5640_color_saturation(struct rt_i2c_bus_device *bus, rt_uint8_t sat)
+{
+ rt_uint8_t i = 0;
+ write_reg(bus, 0x3212, 0x03); //start group 3
+ write_reg(bus, 0x5381, 0x1c);
+ write_reg(bus, 0x5382, 0x5a);
+ write_reg(bus, 0x5383, 0x06);
+ for (i = 0; i < 6; i++)
+ {
+ write_reg(bus, 0x5384 + i, OV5640_SATURATION_TBL[sat][i]);
+ }
+ write_reg(bus, 0x538b, 0x98);
+ write_reg(bus, 0x538a, 0x01);
+ write_reg(bus, 0x3212, 0x13); //end group 3
+ write_reg(bus, 0x3212, 0xa3); //launch group 3
+}
+
+/* bright:0~8 */
+void ov5640_set_brightness(struct rt_i2c_bus_device *bus, rt_uint8_t bright)
+{
+ rt_uint8_t brtval;
+ if (bright < 4)
+ {
+ brtval = 4 - bright;
+ }
+ else
+ {
+ brtval = bright - 4;
+ }
+ write_reg(bus, 0x3212, 0x03); //start group 3
+ write_reg(bus, 0x5587, brtval << 4);
+ if (bright < 4)
+ {
+ write_reg(bus, 0x5588, 0x09);
+ }
+ else
+ {
+ write_reg(bus, 0x5588, 0x01);
+ }
+ write_reg(bus, 0x3212, 0x13); //end group 3
+ write_reg(bus, 0x3212, 0xa3); //launch group 3
+}
+
+/* contrast:0~6 */
+void ov5640_contrast(struct rt_i2c_bus_device *bus, rt_uint8_t contrast)
+{
+ rt_uint8_t reg0val = 0x00;
+ rt_uint8_t reg1val = 0x20;
+ switch (contrast)
+ {
+ case 0:
+ reg1val = reg0val = 0X14;
+ break;
+
+ case 1:
+ reg1val = reg0val = 0X18;
+ break;
+
+ case 2:
+ reg1val = reg0val = 0X1C;
+ break;
+
+ case 4:
+ reg0val = 0X10;
+ reg1val = 0X24;
+ break;
+
+ case 5:
+ reg0val = 0X18;
+ reg1val = 0X28;
+ break;
+
+ case 6:
+ reg0val = 0X1C;
+ reg1val = 0X2C;
+
+ break;
+ }
+ write_reg(bus, 0x3212, 0x03); //start group 3
+ write_reg(bus, 0x5585, reg0val);
+ write_reg(bus, 0x5586, reg1val);
+ write_reg(bus, 0x3212, 0x13); //end group 3
+ write_reg(bus, 0x3212, 0xa3); //launch group 3
+}
+/* sharp:0~33 */
+void ov5640_set_sharpness(struct rt_i2c_bus_device *bus, rt_uint8_t sharp)
+{
+ if (sharp < 33)
+ {
+ write_reg(bus, 0x5308, 0x65);
+ write_reg(bus, 0x5302, sharp);
+ }
+ else
+ {
+ write_reg(bus, 0x5308, 0x25);
+ write_reg(bus, 0x5300, 0x08);
+ write_reg(bus, 0x5301, 0x30);
+ write_reg(bus, 0x5302, 0x10);
+ write_reg(bus, 0x5303, 0x00);
+ write_reg(bus, 0x5309, 0x08);
+ write_reg(bus, 0x530a, 0x30);
+ write_reg(bus, 0x530b, 0x04);
+ write_reg(bus, 0x530c, 0x06);
+ }
+}
+
+rt_uint8_t ov5640_focus_constant(struct rt_i2c_bus_device *bus)
+{
+ rt_uint8_t temp = 0;
+ rt_uint16_t tickstrat = 0;
+
+ write_reg(bus, 0x3023, 0x01);
+ write_reg(bus, 0x3022, 0x08);
+ do
+ {
+ tickstrat = rt_tick_get();
+ read_reg(bus, 0x3023, 1, &temp);
+ if (rt_tick_get() - tickstrat > 1000)
+ {
+ return RT_ERROR;
+ }
+ } while (temp != 0x00);
+
+ write_reg(bus, 0x3023, 0x01);
+ write_reg(bus, 0x3022, 0x04);
+
+ do
+ {
+ tickstrat = rt_tick_get();
+ read_reg(bus, 0x3023, 1, &temp);
+ if (rt_tick_get() - tickstrat > 1000)
+ {
+ return RT_ERROR;
+ }
+ } while (temp != 0x00);
+
+ return 0;
+}
+
+rt_uint8_t ov5640_set_outsize(struct rt_i2c_bus_device *bus, rt_uint16_t offx, rt_uint16_t offy, rt_uint16_t width, rt_uint16_t height)
+{
+ write_reg(bus, 0X3212, 0X03);
+
+ write_reg(bus, 0x3808, width >> 8);
+ write_reg(bus, 0x3809, width & 0xff);
+ write_reg(bus, 0x380a, height >> 8);
+ write_reg(bus, 0x380b, height & 0xff);
+
+ write_reg(bus, 0x3810, offx >> 8);
+ write_reg(bus, 0x3811, offx & 0xff);
+
+ write_reg(bus, 0x3812, offy >> 8);
+ write_reg(bus, 0x3813, offy & 0xff);
+
+ write_reg(bus, 0X3212, 0X13);
+ write_reg(bus, 0X3212, 0Xa3);
+
+ return RT_EOK;
+}
+
+void rt_hw_camera_rx_callback(void)
+{
+ rt_uint16_t i;
+ rt_int32_t *pbuf = RT_NULL;
+ pbuf = JPEG_DATA_BUF + jpeg_data_len;
+
+ if (hdma_dcmi.Instance->CR & (1 << 19))
+ {
+ for (i = 0; i < JPEG_LINE_SIZE; i++)
+ {
+ pbuf[i] = JPEG_LINE_BUF[0][i];
+ }
+ jpeg_data_len += JPEG_LINE_SIZE;
+
+ }
+ else
+ {
+ for (i = 0; i < JPEG_LINE_SIZE; i++)
+ {
+ pbuf[i] = JPEG_LINE_BUF[1][i];
+ }
+ jpeg_data_len += JPEG_LINE_SIZE;
+ }
+}
+
+/* After a frame of JPEG data has been collected. */
+void jpeg_data_process(void)
+{
+ rt_uint16_t i, rlen;
+ int *pbuf = RT_NULL;
+
+ if (!jpeg_data_ok)
+ {
+ __HAL_DMA_DISABLE(&hdma_dcmi);
+ rlen = JPEG_LINE_SIZE - __HAL_DMA_GET_COUNTER(&hdma_dcmi);
+ pbuf = JPEG_DATA_BUF + jpeg_data_len;
+ if (hdma_dcmi.Instance->CR & (1 << 19))
+ {
+ for (i = 0; i < rlen; i++)
+ {
+ pbuf[i] = JPEG_LINE_BUF[1][i];
+ }
+ }
+ else
+ {
+ for (i = 0; i < rlen; i++)
+ {
+ pbuf[i] = JPEG_LINE_BUF[0][i];
+ }
+ }
+ jpeg_data_len += rlen;
+ jpeg_data_ok = 1;
+ }
+
+ if (jpeg_data_ok == 2)
+ {
+ __HAL_DMA_SET_COUNTER(&hdma_dcmi, JPEG_LINE_SIZE);
+ __HAL_DMA_ENABLE(&hdma_dcmi);
+
+ jpeg_data_ok = 0;
+ jpeg_data_len = 0;
+ }
+}
+
+int rt_hw_ov5640_init(void)
+{
+ extern void rt_hw_dcmi_dma_config(rt_uint32_t dst_addr1, rt_uint32_t dst_addr2, rt_uint16_t len);
+
+ static rt_uint16_t id = 0;
+ rt_device_t dcmi_dev = RT_NULL;
+
+ i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
+ if (i2c_bus == RT_NULL)
+ {
+ LOG_E("can't find %c deivce", I2C_NAME);
+ return RT_ERROR;
+ }
+
+ ov5640_hard_reset(i2c_bus);
+ ov5640_read_id(i2c_bus, &id);
+ ov5640_config(i2c_bus);
+ ov5640_rgb565_mode(i2c_bus); /* rgb565 mode */
+ ov5640_focus_init(i2c_bus);
+ ov5640_jpeg_mode(i2c_bus); /* jpeg mode */
+ ov5640_set_light(i2c_bus, 0); /* auto mode */
+ ov5640_color_saturation(i2c_bus, 3);
+ ov5640_set_brightness(i2c_bus, 4); /* brigetness 0 */
+ ov5640_contrast(i2c_bus, 3);
+ ov5640_set_sharpness(i2c_bus, 33);
+ ov5640_focus_constant(i2c_bus);
+
+ /* dcmi init */
+ dcmi_dev = rt_device_find("dcmi");
+ if (dcmi_dev == RT_NULL)
+ {
+ LOG_E("can't find dcmi device!");
+ return RT_ERROR;
+ }
+ rt_device_open(dcmi_dev, RT_DEVICE_FLAG_RDWR);
+
+ rt_hw_dcmi_dma_config((rt_uint32_t)&JPEG_LINE_BUF[0], (rt_uint32_t)&JPEG_LINE_BUF[1], JPEG_LINE_SIZE);
+ ov5640_set_outsize(i2c_bus, 4, 0, jpeg_picture_size[1][0], jpeg_picture_size[1][1]);
+
+ return RT_EOK;
+}
+INIT_APP_EXPORT(rt_hw_ov5640_init);
+
+int camera_sample(int argc, char **argv)
+{
+
+ int fd = -1;
+ rt_uint32_t i, jpg_start, jpg_len;
+ rt_uint16_t tickstart = 0;
+ rt_uint8_t jpg_head = 0;
+ rt_uint8_t *p = RT_NULL;
+
+ if (argc != 2)
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("camera_sample file.jpg\n");
+ return -1;
+ }
+
+ /* start dcmi capture */
+ __HAL_DMA_ENABLE(&hdma_dcmi);
+ dcmi.Instance->CR |= DCMI_CR_CAPTURE;
+
+ tickstart = rt_tick_get();
+ while (1)
+ {
+ if (rt_tick_get() - tickstart > 1000)
+ {
+ LOG_E("picture capture overtime!");
+ break;
+ }
+
+ if (jpeg_data_ok == 1)
+ {
+ dcmi.Instance->CR &= ~(DCMI_CR_CAPTURE);
+ tickstart = rt_tick_get();
+ while(dcmi.Instance->CR & 0x01)
+ {
+ if (rt_tick_get() - tickstart > 0x1000)
+ {
+ rt_kprintf("dcmi close failed!\n");
+ jpeg_data_ok = 2;
+ break;
+ }
+ }
+ __HAL_DMA_DISABLE(&hdma_dcmi);
+
+ p = (rt_uint8_t *)JPEG_DATA_BUF;
+ jpg_len = 0;
+ jpg_head = 0;
+ for (i = 0; i < jpeg_data_len * 4; i++)
+ {
+ /* jpg head */
+ if ((p[i] == 0xFF) && (p[i + 1] == 0xD8))
+ {
+ jpg_start = i;
+ jpg_head = 1;
+ }
+ /* jpg end */
+ if ((p[i] == 0xFF) && (p[i + 1] == 0xD9) && jpg_head)
+ {
+ jpg_len = i - jpg_start + 2; /* a picture len */
+ break;
+ }
+ }
+
+ if (jpg_len)
+ {
+ p += jpg_start;
+
+ fd = open(argv[1], O_WRONLY | O_CREAT);
+ if (fd < 0)
+ {
+ rt_kprintf("open file for recording failed!\n");
+ return -RT_ERROR;
+ }
+ else
+ {
+ write(fd, p, jpg_len);
+ close(fd);
+ rt_kprintf("picture capture complate!\n");
+
+ break;
+ }
+ }
+
+ jpeg_data_ok = 2;
+ }
+ }
+
+ return RT_EOK;
+}
+MSH_CMD_EXPORT(camera_sample, record picture to a jpg file);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.h
new file mode 100644
index 0000000000..d005150482
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_ov5640.h
@@ -0,0 +1,653 @@
+
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu first version
+ */
+
+#ifndef __DRV_OV5640_H__
+#define __DRV_OV5640_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief OV5640 ID
+ */
+#define OV5640_ID 0x5640U
+
+/* JPEG picture size table */
+static const unsigned short jpeg_picture_size[][2] =
+{
+ 160, 120, /* QQVGA */
+ 320, 240, /* QVGA */
+ 640, 480, /* VGA */
+ 800, 600, /* SVGA */
+ 1024, 768, /* XGA */
+ 1280, 800, /* WXGA */
+ 1440, 900, /* WXGA+ */
+ 1280, 1024, /* SXGA */
+ 1600, 1200, /* UXGA */
+ 1920, 1080, /* 1080P */
+ 2048, 1536, /* QXGA */
+ 2592, 1944, /* 500W */
+};
+
+/* camera light mode */
+static const unsigned char OV5640_LIGHTMODE_TBL[5][7]=
+{
+ 0x04,0X00,0X04,0X00,0X04,0X00,0X00, /* Auto */
+ 0x06,0X1C,0X04,0X00,0X04,0XF3,0X01, /* Sunny */
+ 0x05,0X48,0X04,0X00,0X07,0XCF,0X01, /* Office */
+ 0x06,0X48,0X04,0X00,0X04,0XD3,0X01, /* Cloudy */
+ 0x04,0X10,0X04,0X00,0X08,0X40,0X01, /* Home */
+};
+
+/* Table of color saturation setting parameters */
+static const unsigned char OV5640_SATURATION_TBL[7][6]=
+{
+ 0X0C,0x30,0X3D,0X3E,0X3D,0X01, /* -3 */
+ 0X10,0x3D,0X4D,0X4E,0X4D,0X01, /* -2 */
+ 0X15,0x52,0X66,0X68,0X66,0X02, /* -1 */
+ 0X1A,0x66,0X80,0X82,0X80,0X02, /* 0 */
+ 0X1F,0x7A,0X9A,0X9C,0X9A,0X02, /* 1 */
+ 0X24,0x8F,0XB3,0XB6,0XB3,0X03, /* 2 */
+ 0X2B,0xAB,0XD6,0XDA,0XD6,0X04, /* 3 */
+};
+
+static const unsigned short OV5640_jpeg_reg_tbl[][2]=
+{
+ 0x4300, 0x30, // YUV 422, YUYV
+ 0x501f, 0x00, // YUV 422
+ // Input clock = 24Mhz
+ 0x3035, 0x21, // PLL
+ 0x3036, 0x69, // PLL
+ 0x3c07, 0x07, // lightmeter 1 threshold[7:0]
+ 0x3820, 0x46, // flip
+ 0x3821, 0x20, // mirror
+ 0x3814, 0x11, // timing X inc
+ 0x3815, 0x11, // timing Y inc
+ 0x3800, 0x00, // HS
+ 0x3801, 0x00, // HS
+ 0x3802, 0x00, // VS
+ 0x3803, 0x00, // VS
+ 0x3804, 0x0a, // HW (HE)
+ 0x3805, 0x3f, // HW (HE)
+ 0x3806, 0x07, // VH (VE)
+ 0x3807, 0x9f, // VH (VE)
+
+ 0x3808, 0x02, // DVPHO
+ 0x3809, 0x80, // DVPHO
+ 0x380a, 0x01, // DVPVO
+ 0x380b, 0xe0, // DVPVO
+
+ 0x380c, 0x0b, // HTS //
+ 0x380d, 0x1c, // HTS
+ 0x380e, 0x07, // VTS //
+ 0x380f, 0xb0, // VTS
+ 0x3813, 0x04, // timing V offset 04
+ 0x3618, 0x04,
+ 0x3612, 0x2b,
+ 0x3709, 0x12,
+ 0x370c, 0x00,
+
+ 0x4004, 0x06, // BLC line number
+ 0x3002, 0x00, // enable JFIFO, SFIFO, JPG
+ 0x3006, 0xff, // enable clock of JPEG2x, JPEG
+ 0x4713, 0x03, // JPEG mode 3
+ 0x4407, 0x01, // Quantization sacle
+ 0x460b, 0x35,
+ 0x460c, 0x22,
+ 0x4837, 0x16, // MIPI global timing
+ 0x3824, 0x02, // PCLK manual divider
+ 0x5001, 0xA3, // SDE on, Scaling on, CMX on, AWB on
+ 0x3503, 0x00, // AEC/AGC on
+};
+
+/* RGB565 configuration, 15 frames */
+static const unsigned short ov5640_rgb565_reg_tbl[][2]=
+{
+ 0x4300, 0X6F,
+ 0X501F, 0x01,
+ // 1280x800, 15fps
+ // input clock 24Mhz, PCLK 42Mhz
+ 0x3035, 0x41, // PLL
+ 0x3036, 0x69, // PLL
+ 0x3c07, 0x07, // lightmeter 1 threshold[7:0]
+ 0x3820, 0x46, // flip
+ 0x3821, 0x00, // mirror
+ 0x3814, 0x31, // timing X inc
+ 0x3815, 0x31, // timing Y inc
+ 0x3800, 0x00, // HS
+ 0x3801, 0x00, // HS
+ 0x3802, 0x00, // VS
+ 0x3803, 0x00, // VS
+ 0x3804, 0x0a, // HW (HE)
+ 0x3805, 0x3f, // HW (HE)
+ 0x3806, 0x06, // VH (VE)
+ 0x3807, 0xa9, // VH (VE)
+ 0x3808, 0x05, // DVPHO
+ 0x3809, 0x00, // DVPHO
+ 0x380a, 0x02, // DVPVO
+ 0x380b, 0xd0, // DVPVO
+ 0x380c, 0x05, // HTS
+ 0x380d, 0xF8, // HTS
+ 0x380e, 0x03, // VTS
+ 0x380f, 0x84, // VTS
+ 0x3813, 0x04, // timing V offset
+ 0x3618, 0x00,
+ 0x3612, 0x29,
+ 0x3709, 0x52,
+ 0x370c, 0x03,
+ 0x3a02, 0x02, // 60Hz max exposure
+ 0x3a03, 0xe0, // 60Hz max exposure
+
+ 0x3a14, 0x02, // 50Hz max exposure
+ 0x3a15, 0xe0, // 50Hz max exposure
+ 0x4004, 0x02, // BLC line number
+ 0x3002, 0x1c, // reset JFIFO, SFIFO, JPG
+ 0x3006, 0xc3, // disable clock of JPEG2x, JPEG
+ 0x4713, 0x03, // JPEG mode 3
+ 0x4407, 0x04, // Quantization scale
+ 0x460b, 0x37,
+ 0x460c, 0x20,
+ 0x4837, 0x16, // MIPI global timing
+ 0x3824, 0x04, // PCLK manual divider
+ 0x5001, 0xA3, // SDE on, scale on, UV average off, color matrix on, AWB on
+ 0x3503, 0x00, // AEC/AGC on
+};
+
+static const unsigned short RGB565_Init[][2]=
+{
+ /* 24MHz input clock, 24MHz PCLK */
+ 0x3008, 0x42, // software power down, bit[6]
+ 0x3103, 0x03, // system clock from PLL, bit[1]
+ 0x3017, 0xff, // FREX, Vsync, HREF, PCLK, D[9:6] output enable
+ 0x3018, 0xff, // D[5:0], GPIO[1:0] output enable
+ 0x3034, 0x1a, // MIPI 10-bit
+ 0x3037, 0x13, // PLL root divider, bit[4], PLL pre-divider, bit[3:0]
+ 0x3108, 0x01, // PCLK root divider, bit[5:4], SCLK2x root divider, bit[3:2]
+
+ // SCLK root divider, bit[1:0]
+ 0x3630, 0x36,
+ 0x3631, 0x0e,
+ 0x3632, 0xe2,
+ 0x3633, 0x12,
+ 0x3621, 0xe0,
+ 0x3704, 0xa0,
+ 0x3703, 0x5a,
+ 0x3715, 0x78,
+ 0x3717, 0x01,
+ 0x370b, 0x60,
+ 0x3705, 0x1a,
+ 0x3905, 0x02,
+ 0x3906, 0x10,
+ 0x3901, 0x0a,
+ 0x3731, 0x12,
+ 0x3600, 0x08, // VCM control
+ 0x3601, 0x33, // VCM control
+ 0x302d, 0x60, // system control
+ 0x3620, 0x52,
+ 0x371b, 0x20,
+ 0x471c, 0x50,
+ 0x3a13, 0x43, // pre-gain = 1.047x
+ 0x3a18, 0x00, // gain ceiling
+ 0x3a19, 0xf8, // gain ceiling = 15.5x
+ 0x3635, 0x13,
+ 0x3636, 0x03,
+ 0x3634, 0x40,
+ 0x3622, 0x01,
+ // 50/60Hz detection 50/60Hz
+ 0x3c01, 0x34, // Band auto, bit[7]
+ 0x3c04, 0x28, // threshold low sum
+ 0x3c05, 0x98, // threshold high sum
+ 0x3c06, 0x00, // light meter 1 threshold[15:8]
+ 0x3c07, 0x08, // light meter 1 threshold[7:0]
+ 0x3c08, 0x00, // light meter 2 threshold[15:8]
+ 0x3c09, 0x1c, // light meter 2 threshold[7:0]
+ 0x3c0a, 0x9c, // sample number[15:8]
+ 0x3c0b, 0x40, // sample number[7:0]
+ 0x3810, 0x00, // Timing Hoffset[11:8]
+ 0x3811, 0x10, // Timing Hoffset[7:0]
+ 0x3812, 0x00, // Timing Voffset[10:8]
+ 0x3708, 0x64,
+ 0x4001, 0x02, // BLC start from line 2
+ 0x4005, 0x1a, // BLC always update
+ 0x3000, 0x00, // enable blocks
+ 0x3004, 0xff, // enable clocks
+ 0x300e, 0x58, // MIPI power down, DVP enable
+ 0x302e, 0x00,
+ 0x4300, 0x30, // YUV 422, YUYV
+ 0x501f, 0x00, // YUV 422
+ 0x440e, 0x00,
+ 0x5000, 0xa7, // Lenc on, raw gamma on, BPC on, WPC on, CIP on
+ // AEC target
+ 0x3a0f, 0x30, // stable range in high
+ 0x3a10, 0x28, // stable range in low
+ 0x3a1b, 0x30, // stable range out high
+ 0x3a1e, 0x26, // stable range out low
+ 0x3a11, 0x60, // fast zone high
+ 0x3a1f, 0x14, // fast zone low
+ // Lens correction
+ 0x5800, 0x23,
+ 0x5801, 0x14,
+ 0x5802, 0x0f,
+ 0x5803, 0x0f,
+ 0x5804, 0x12,
+ 0x5805, 0x26,
+ 0x5806, 0x0c,
+ 0x5807, 0x08,
+ 0x5808, 0x05,
+ 0x5809, 0x05,
+ 0x580a, 0x08,
+
+ 0x580b, 0x0d,
+ 0x580c, 0x08,
+ 0x580d, 0x03,
+ 0x580e, 0x00,
+ 0x580f, 0x00,
+ 0x5810, 0x03,
+ 0x5811, 0x09,
+ 0x5812, 0x07,
+ 0x5813, 0x03,
+ 0x5814, 0x00,
+ 0x5815, 0x01,
+ 0x5816, 0x03,
+ 0x5817, 0x08,
+ 0x5818, 0x0d,
+ 0x5819, 0x08,
+ 0x581a, 0x05,
+ 0x581b, 0x06,
+ 0x581c, 0x08,
+ 0x581d, 0x0e,
+ 0x581e, 0x29,
+ 0x581f, 0x17,
+ 0x5820, 0x11,
+ 0x5821, 0x11,
+ 0x5822, 0x15,
+ 0x5823, 0x28,
+ 0x5824, 0x46,
+ 0x5825, 0x26,
+ 0x5826, 0x08,
+ 0x5827, 0x26,
+ 0x5828, 0x64,
+ 0x5829, 0x26,
+ 0x582a, 0x24,
+ 0x582b, 0x22,
+ 0x582c, 0x24,
+ 0x582d, 0x24,
+ 0x582e, 0x06,
+ 0x582f, 0x22,
+ 0x5830, 0x40,
+ 0x5831, 0x42,
+ 0x5832, 0x24,
+ 0x5833, 0x26,
+ 0x5834, 0x24,
+ 0x5835, 0x22,
+ 0x5836, 0x22,
+ 0x5837, 0x26,
+ 0x5838, 0x44,
+ 0x5839, 0x24,
+ 0x583a, 0x26,
+ 0x583b, 0x28,
+ 0x583c, 0x42,
+ 0x583d, 0xce, // lenc BR offset
+ // AWB
+ 0x5180, 0xff, // AWB B block
+ 0x5181, 0xf2, // AWB control
+ 0x5182, 0x00, // [7:4] max local counter, [3:0] max fast counter
+ 0x5183, 0x14, // AWB advanced
+ 0x5184, 0x25,
+ 0x5185, 0x24,
+ 0x5186, 0x09,
+ 0x5187, 0x09,
+ 0x5188, 0x09,
+ 0x5189, 0x75,
+ 0x518a, 0x54,
+ 0x518b, 0xe0,
+ 0x518c, 0xb2,
+ 0x518d, 0x42,
+ 0x518e, 0x3d,
+ 0x518f, 0x56,
+ 0x5190, 0x46,
+ 0x5191, 0xf8, // AWB top limit
+ 0x5192, 0x04, // AWB bottom limit
+ 0x5193, 0x70, // red limit
+ 0x5194, 0xf0, // green limit
+ 0x5195, 0xf0, // blue limit
+ 0x5196, 0x03, // AWB control
+ 0x5197, 0x01, // local limit
+ 0x5198, 0x04,
+ 0x5199, 0x12,
+ 0x519a, 0x04,
+ 0x519b, 0x00,
+ 0x519c, 0x06,
+ 0x519d, 0x82,
+ 0x519e, 0x38, // AWB control
+ // Gamma
+ 0x5480, 0x01, // Gamma bias plus on, bit[0]
+ 0x5481, 0x08,
+ 0x5482, 0x14,
+ 0x5483, 0x28,
+ 0x5484, 0x51,
+ 0x5485, 0x65,
+ 0x5486, 0x71,
+ 0x5487, 0x7d,
+ 0x5488, 0x87,
+ 0x5489, 0x91,
+ 0x548a, 0x9a,
+ 0x548b, 0xaa,
+ 0x548c, 0xb8,
+ 0x548d, 0xcd,
+ 0x548e, 0xdd,
+ 0x548f, 0xea,
+ 0x5490, 0x1d,
+ // color matrix
+ 0x5381, 0x1e, // CMX1 for Y
+ 0x5382, 0x5b, // CMX2 for Y
+ 0x5383, 0x08, // CMX3 for Y
+ 0x5384, 0x0a, // CMX4 for U
+ 0x5385, 0x7e, // CMX5 for U
+ 0x5386, 0x88, // CMX6 for U
+ 0x5387, 0x7c, // CMX7 for V
+ 0x5388, 0x6c, // CMX8 for V
+ 0x5389, 0x10, // CMX9 for V
+ 0x538a, 0x01, // sign[9]
+ 0x538b, 0x98, // sign[8:1]
+ // UV adjust UV
+ 0x5580, 0x06, // saturation on, bit[1]
+ 0x5583, 0x40,
+ 0x5584, 0x10,
+ 0x5589, 0x10,
+ 0x558a, 0x00,
+ 0x558b, 0xf8,
+ 0x501d, 0x40, // enable manual offset of contrast
+ // CIP
+ 0x5300, 0x08, // CIP sharpen MT threshold 1
+ 0x5301, 0x30, // CIP sharpen MT threshold 2
+ 0x5302, 0x10, // CIP sharpen MT offset 1
+ 0x5303, 0x00, // CIP sharpen MT offset 2
+ 0x5304, 0x08, // CIP DNS threshold 1
+ 0x5305, 0x30, // CIP DNS threshold 2
+ 0x5306, 0x08, // CIP DNS offset 1
+ 0x5307, 0x16, // CIP DNS offset 2
+ 0x5309, 0x08, // CIP sharpen TH threshold 1
+ 0x530a, 0x30, // CIP sharpen TH threshold 2
+ 0x530b, 0x04, // CIP sharpen TH offset 1
+ 0x530c, 0x06, // CIP sharpen TH offset 2
+ 0x5025, 0x00,
+ 0x3008, 0x02, // wake up from standby, bit[6]
+
+ 0x4740, 0X21, //VSYNC
+};
+
+/* Autofocus initialization configuration */
+const unsigned char OV5640_AF_Config[] =
+{
+ 0x02, 0x0f, 0xd6, 0x02, 0x0a, 0x39, 0xc2, 0x01, 0x22, 0x22, 0x00, 0x02, 0x0f, 0xb2, 0xe5, 0x1f, //0x8000,
+ 0x70, 0x72, 0xf5, 0x1e, 0xd2, 0x35, 0xff, 0xef, 0x25, 0xe0, 0x24, 0x4e, 0xf8, 0xe4, 0xf6, 0x08, //0x8010,
+ 0xf6, 0x0f, 0xbf, 0x34, 0xf2, 0x90, 0x0e, 0x93, 0xe4, 0x93, 0xff, 0xe5, 0x4b, 0xc3, 0x9f, 0x50, //0x8020,
+ 0x04, 0x7f, 0x05, 0x80, 0x02, 0x7f, 0xfb, 0x78, 0xbd, 0xa6, 0x07, 0x12, 0x0f, 0x04, 0x40, 0x04, //0x8030,
+ 0x7f, 0x03, 0x80, 0x02, 0x7f, 0x30, 0x78, 0xbc, 0xa6, 0x07, 0xe6, 0x18, 0xf6, 0x08, 0xe6, 0x78, //0x8040,
+ 0xb9, 0xf6, 0x78, 0xbc, 0xe6, 0x78, 0xba, 0xf6, 0x78, 0xbf, 0x76, 0x33, 0xe4, 0x08, 0xf6, 0x78, //0x8050,
+ 0xb8, 0x76, 0x01, 0x75, 0x4a, 0x02, 0x78, 0xb6, 0xf6, 0x08, 0xf6, 0x74, 0xff, 0x78, 0xc1, 0xf6, //0x8060,
+ 0x08, 0xf6, 0x75, 0x1f, 0x01, 0x78, 0xbc, 0xe6, 0x75, 0xf0, 0x05, 0xa4, 0xf5, 0x4b, 0x12, 0x0a, //0x8070,
+ 0xff, 0xc2, 0x37, 0x22, 0x78, 0xb8, 0xe6, 0xd3, 0x94, 0x00, 0x40, 0x02, 0x16, 0x22, 0xe5, 0x1f, //0x8080,
+ 0xb4, 0x05, 0x23, 0xe4, 0xf5, 0x1f, 0xc2, 0x01, 0x78, 0xb6, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x78, //0x8090,
+ 0x4e, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0xa2, 0x37, 0xe4, 0x33, 0xf5, 0x3c, 0x90, 0x30, 0x28, 0xf0, //0x80a0,
+ 0x75, 0x1e, 0x10, 0xd2, 0x35, 0x22, 0xe5, 0x4b, 0x75, 0xf0, 0x05, 0x84, 0x78, 0xbc, 0xf6, 0x90, //0x80b0,
+ 0x0e, 0x8c, 0xe4, 0x93, 0xff, 0x25, 0xe0, 0x24, 0x0a, 0xf8, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x78, //0x80c0,
+ 0xbc, 0xe6, 0x25, 0xe0, 0x24, 0x4e, 0xf8, 0xa6, 0x04, 0x08, 0xa6, 0x05, 0xef, 0x12, 0x0f, 0x0b, //0x80d0,
+ 0xd3, 0x78, 0xb7, 0x96, 0xee, 0x18, 0x96, 0x40, 0x0d, 0x78, 0xbc, 0xe6, 0x78, 0xb9, 0xf6, 0x78, //0x80e0,
+ 0xb6, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x90, 0x0e, 0x8c, 0xe4, 0x93, 0x12, 0x0f, 0x0b, 0xc3, 0x78, //0x80f0,
+ 0xc2, 0x96, 0xee, 0x18, 0x96, 0x50, 0x0d, 0x78, 0xbc, 0xe6, 0x78, 0xba, 0xf6, 0x78, 0xc1, 0xa6, //0x8100,
+ 0x06, 0x08, 0xa6, 0x07, 0x78, 0xb6, 0xe6, 0xfe, 0x08, 0xe6, 0xc3, 0x78, 0xc2, 0x96, 0xff, 0xee, //0x8110,
+ 0x18, 0x96, 0x78, 0xc3, 0xf6, 0x08, 0xa6, 0x07, 0x90, 0x0e, 0x95, 0xe4, 0x18, 0x12, 0x0e, 0xe9, //0x8120,
+ 0x40, 0x02, 0xd2, 0x37, 0x78, 0xbc, 0xe6, 0x08, 0x26, 0x08, 0xf6, 0xe5, 0x1f, 0x64, 0x01, 0x70, //0x8130,
+ 0x4a, 0xe6, 0xc3, 0x78, 0xc0, 0x12, 0x0e, 0xdf, 0x40, 0x05, 0x12, 0x0e, 0xda, 0x40, 0x39, 0x12, //0x8140,
+ 0x0f, 0x02, 0x40, 0x04, 0x7f, 0xfe, 0x80, 0x02, 0x7f, 0x02, 0x78, 0xbd, 0xa6, 0x07, 0x78, 0xb9, //0x8150,
+ 0xe6, 0x24, 0x03, 0x78, 0xbf, 0xf6, 0x78, 0xb9, 0xe6, 0x24, 0xfd, 0x78, 0xc0, 0xf6, 0x12, 0x0f, //0x8160,
+ 0x02, 0x40, 0x06, 0x78, 0xc0, 0xe6, 0xff, 0x80, 0x04, 0x78, 0xbf, 0xe6, 0xff, 0x78, 0xbe, 0xa6, //0x8170,
+ 0x07, 0x75, 0x1f, 0x02, 0x78, 0xb8, 0x76, 0x01, 0x02, 0x02, 0x4a, 0xe5, 0x1f, 0x64, 0x02, 0x60, //0x8180,
+ 0x03, 0x02, 0x02, 0x2a, 0x78, 0xbe, 0xe6, 0xff, 0xc3, 0x78, 0xc0, 0x12, 0x0e, 0xe0, 0x40, 0x08, //0x8190,
+ 0x12, 0x0e, 0xda, 0x50, 0x03, 0x02, 0x02, 0x28, 0x12, 0x0f, 0x02, 0x40, 0x04, 0x7f, 0xff, 0x80, //0x81a0,
+ 0x02, 0x7f, 0x01, 0x78, 0xbd, 0xa6, 0x07, 0x78, 0xb9, 0xe6, 0x04, 0x78, 0xbf, 0xf6, 0x78, 0xb9, //0x81b0,
+ 0xe6, 0x14, 0x78, 0xc0, 0xf6, 0x18, 0x12, 0x0f, 0x04, 0x40, 0x04, 0xe6, 0xff, 0x80, 0x02, 0x7f, //0x81c0,
+ 0x00, 0x78, 0xbf, 0xa6, 0x07, 0xd3, 0x08, 0xe6, 0x64, 0x80, 0x94, 0x80, 0x40, 0x04, 0xe6, 0xff, //0x81d0,
+ 0x80, 0x02, 0x7f, 0x00, 0x78, 0xc0, 0xa6, 0x07, 0xc3, 0x18, 0xe6, 0x64, 0x80, 0x94, 0xb3, 0x50, //0x81e0,
+ 0x04, 0xe6, 0xff, 0x80, 0x02, 0x7f, 0x33, 0x78, 0xbf, 0xa6, 0x07, 0xc3, 0x08, 0xe6, 0x64, 0x80, //0x81f0,
+ 0x94, 0xb3, 0x50, 0x04, 0xe6, 0xff, 0x80, 0x02, 0x7f, 0x33, 0x78, 0xc0, 0xa6, 0x07, 0x12, 0x0f, //0x8200,
+ 0x02, 0x40, 0x06, 0x78, 0xc0, 0xe6, 0xff, 0x80, 0x04, 0x78, 0xbf, 0xe6, 0xff, 0x78, 0xbe, 0xa6, //0x8210,
+ 0x07, 0x75, 0x1f, 0x03, 0x78, 0xb8, 0x76, 0x01, 0x80, 0x20, 0xe5, 0x1f, 0x64, 0x03, 0x70, 0x26, //0x8220,
+ 0x78, 0xbe, 0xe6, 0xff, 0xc3, 0x78, 0xc0, 0x12, 0x0e, 0xe0, 0x40, 0x05, 0x12, 0x0e, 0xda, 0x40, //0x8230,
+ 0x09, 0x78, 0xb9, 0xe6, 0x78, 0xbe, 0xf6, 0x75, 0x1f, 0x04, 0x78, 0xbe, 0xe6, 0x75, 0xf0, 0x05, //0x8240,
+ 0xa4, 0xf5, 0x4b, 0x02, 0x0a, 0xff, 0xe5, 0x1f, 0xb4, 0x04, 0x10, 0x90, 0x0e, 0x94, 0xe4, 0x78, //0x8250,
+ 0xc3, 0x12, 0x0e, 0xe9, 0x40, 0x02, 0xd2, 0x37, 0x75, 0x1f, 0x05, 0x22, 0x30, 0x01, 0x03, 0x02, //0x8260,
+ 0x04, 0xc0, 0x30, 0x02, 0x03, 0x02, 0x04, 0xc0, 0x90, 0x51, 0xa5, 0xe0, 0x78, 0x93, 0xf6, 0xa3, //0x8270,
+ 0xe0, 0x08, 0xf6, 0xa3, 0xe0, 0x08, 0xf6, 0xe5, 0x1f, 0x70, 0x3c, 0x75, 0x1e, 0x20, 0xd2, 0x35, //0x8280,
+ 0x12, 0x0c, 0x7a, 0x78, 0x7e, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x78, 0x8b, 0xa6, 0x09, 0x18, 0x76, //0x8290,
+ 0x01, 0x12, 0x0c, 0x5b, 0x78, 0x4e, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x78, 0x8b, 0xe6, 0x78, 0x6e, //0x82a0,
+ 0xf6, 0x75, 0x1f, 0x01, 0x78, 0x93, 0xe6, 0x78, 0x90, 0xf6, 0x78, 0x94, 0xe6, 0x78, 0x91, 0xf6, //0x82b0,
+ 0x78, 0x95, 0xe6, 0x78, 0x92, 0xf6, 0x22, 0x79, 0x90, 0xe7, 0xd3, 0x78, 0x93, 0x96, 0x40, 0x05, //0x82c0,
+ 0xe7, 0x96, 0xff, 0x80, 0x08, 0xc3, 0x79, 0x93, 0xe7, 0x78, 0x90, 0x96, 0xff, 0x78, 0x88, 0x76, //0x82d0,
+ 0x00, 0x08, 0xa6, 0x07, 0x79, 0x91, 0xe7, 0xd3, 0x78, 0x94, 0x96, 0x40, 0x05, 0xe7, 0x96, 0xff, //0x82e0,
+ 0x80, 0x08, 0xc3, 0x79, 0x94, 0xe7, 0x78, 0x91, 0x96, 0xff, 0x12, 0x0c, 0x8e, 0x79, 0x92, 0xe7, //0x82f0,
+ 0xd3, 0x78, 0x95, 0x96, 0x40, 0x05, 0xe7, 0x96, 0xff, 0x80, 0x08, 0xc3, 0x79, 0x95, 0xe7, 0x78, //0x8300,
+ 0x92, 0x96, 0xff, 0x12, 0x0c, 0x8e, 0x12, 0x0c, 0x5b, 0x78, 0x8a, 0xe6, 0x25, 0xe0, 0x24, 0x4e, //0x8310,
+ 0xf8, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x78, 0x8a, 0xe6, 0x24, 0x6e, 0xf8, 0xa6, 0x09, 0x78, 0x8a, //0x8320,
+ 0xe6, 0x24, 0x01, 0xff, 0xe4, 0x33, 0xfe, 0xd3, 0xef, 0x94, 0x0f, 0xee, 0x64, 0x80, 0x94, 0x80, //0x8330,
+ 0x40, 0x04, 0x7f, 0x00, 0x80, 0x05, 0x78, 0x8a, 0xe6, 0x04, 0xff, 0x78, 0x8a, 0xa6, 0x07, 0xe5, //0x8340,
+ 0x1f, 0xb4, 0x01, 0x0a, 0xe6, 0x60, 0x03, 0x02, 0x04, 0xc0, 0x75, 0x1f, 0x02, 0x22, 0x12, 0x0c, //0x8350,
+ 0x7a, 0x78, 0x80, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0x12, 0x0c, 0x7a, 0x78, 0x82, 0xa6, 0x06, 0x08, //0x8360,
+ 0xa6, 0x07, 0x78, 0x6e, 0xe6, 0x78, 0x8c, 0xf6, 0x78, 0x6e, 0xe6, 0x78, 0x8d, 0xf6, 0x7f, 0x01, //0x8370,
+ 0xef, 0x25, 0xe0, 0x24, 0x4f, 0xf9, 0xc3, 0x78, 0x81, 0xe6, 0x97, 0x18, 0xe6, 0x19, 0x97, 0x50, //0x8380,
+ 0x0a, 0x12, 0x0c, 0x82, 0x78, 0x80, 0xa6, 0x04, 0x08, 0xa6, 0x05, 0x74, 0x6e, 0x2f, 0xf9, 0x78, //0x8390,
+ 0x8c, 0xe6, 0xc3, 0x97, 0x50, 0x08, 0x74, 0x6e, 0x2f, 0xf8, 0xe6, 0x78, 0x8c, 0xf6, 0xef, 0x25, //0x83a0,
+ 0xe0, 0x24, 0x4f, 0xf9, 0xd3, 0x78, 0x83, 0xe6, 0x97, 0x18, 0xe6, 0x19, 0x97, 0x40, 0x0a, 0x12, //0x83b0,
+ 0x0c, 0x82, 0x78, 0x82, 0xa6, 0x04, 0x08, 0xa6, 0x05, 0x74, 0x6e, 0x2f, 0xf9, 0x78, 0x8d, 0xe6, //0x83c0,
+ 0xd3, 0x97, 0x40, 0x08, 0x74, 0x6e, 0x2f, 0xf8, 0xe6, 0x78, 0x8d, 0xf6, 0x0f, 0xef, 0x64, 0x10, //0x83d0,
+ 0x70, 0x9e, 0xc3, 0x79, 0x81, 0xe7, 0x78, 0x83, 0x96, 0xff, 0x19, 0xe7, 0x18, 0x96, 0x78, 0x84, //0x83e0,
+ 0xf6, 0x08, 0xa6, 0x07, 0xc3, 0x79, 0x8c, 0xe7, 0x78, 0x8d, 0x96, 0x08, 0xf6, 0xd3, 0x79, 0x81, //0x83f0,
+ 0xe7, 0x78, 0x7f, 0x96, 0x19, 0xe7, 0x18, 0x96, 0x40, 0x05, 0x09, 0xe7, 0x08, 0x80, 0x06, 0xc3, //0x8400,
+ 0x79, 0x7f, 0xe7, 0x78, 0x81, 0x96, 0xff, 0x19, 0xe7, 0x18, 0x96, 0xfe, 0x78, 0x86, 0xa6, 0x06, //0x8410,
+ 0x08, 0xa6, 0x07, 0x79, 0x8c, 0xe7, 0xd3, 0x78, 0x8b, 0x96, 0x40, 0x05, 0xe7, 0x96, 0xff, 0x80, //0x8420,
+ 0x08, 0xc3, 0x79, 0x8b, 0xe7, 0x78, 0x8c, 0x96, 0xff, 0x78, 0x8f, 0xa6, 0x07, 0xe5, 0x1f, 0x64, //0x8430,
+ 0x02, 0x70, 0x69, 0x90, 0x0e, 0x91, 0x93, 0xff, 0x18, 0xe6, 0xc3, 0x9f, 0x50, 0x72, 0x12, 0x0c, //0x8440,
+ 0x4a, 0x12, 0x0c, 0x2f, 0x90, 0x0e, 0x8e, 0x12, 0x0c, 0x38, 0x78, 0x80, 0x12, 0x0c, 0x6b, 0x7b, //0x8450,
+ 0x04, 0x12, 0x0c, 0x1d, 0xc3, 0x12, 0x06, 0x45, 0x50, 0x56, 0x90, 0x0e, 0x92, 0xe4, 0x93, 0xff, //0x8460,
+ 0x78, 0x8f, 0xe6, 0x9f, 0x40, 0x02, 0x80, 0x11, 0x90, 0x0e, 0x90, 0xe4, 0x93, 0xff, 0xd3, 0x78, //0x8470,
+ 0x89, 0xe6, 0x9f, 0x18, 0xe6, 0x94, 0x00, 0x40, 0x03, 0x75, 0x1f, 0x05, 0x12, 0x0c, 0x4a, 0x12, //0x8480,
+ 0x0c, 0x2f, 0x90, 0x0e, 0x8f, 0x12, 0x0c, 0x38, 0x78, 0x7e, 0x12, 0x0c, 0x6b, 0x7b, 0x40, 0x12, //0x8490,
+ 0x0c, 0x1d, 0xd3, 0x12, 0x06, 0x45, 0x40, 0x18, 0x75, 0x1f, 0x05, 0x22, 0xe5, 0x1f, 0xb4, 0x05, //0x84a0,
+ 0x0f, 0xd2, 0x01, 0xc2, 0x02, 0xe4, 0xf5, 0x1f, 0xf5, 0x1e, 0xd2, 0x35, 0xd2, 0x33, 0xd2, 0x36, //0x84b0,
+ 0x22, 0xef, 0x8d, 0xf0, 0xa4, 0xa8, 0xf0, 0xcf, 0x8c, 0xf0, 0xa4, 0x28, 0xce, 0x8d, 0xf0, 0xa4, //0x84c0,
+ 0x2e, 0xfe, 0x22, 0xbc, 0x00, 0x0b, 0xbe, 0x00, 0x29, 0xef, 0x8d, 0xf0, 0x84, 0xff, 0xad, 0xf0, //0x84d0,
+ 0x22, 0xe4, 0xcc, 0xf8, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xec, 0x33, 0xfc, //0x84e0,
+ 0xee, 0x9d, 0xec, 0x98, 0x40, 0x05, 0xfc, 0xee, 0x9d, 0xfe, 0x0f, 0xd5, 0xf0, 0xe9, 0xe4, 0xce, //0x84f0,
+ 0xfd, 0x22, 0xed, 0xf8, 0xf5, 0xf0, 0xee, 0x84, 0x20, 0xd2, 0x1c, 0xfe, 0xad, 0xf0, 0x75, 0xf0, //0x8500,
+ 0x08, 0xef, 0x2f, 0xff, 0xed, 0x33, 0xfd, 0x40, 0x07, 0x98, 0x50, 0x06, 0xd5, 0xf0, 0xf2, 0x22, //0x8510,
+ 0xc3, 0x98, 0xfd, 0x0f, 0xd5, 0xf0, 0xea, 0x22, 0xe8, 0x8f, 0xf0, 0xa4, 0xcc, 0x8b, 0xf0, 0xa4, //0x8520,
+ 0x2c, 0xfc, 0xe9, 0x8e, 0xf0, 0xa4, 0x2c, 0xfc, 0x8a, 0xf0, 0xed, 0xa4, 0x2c, 0xfc, 0xea, 0x8e, //0x8530,
+ 0xf0, 0xa4, 0xcd, 0xa8, 0xf0, 0x8b, 0xf0, 0xa4, 0x2d, 0xcc, 0x38, 0x25, 0xf0, 0xfd, 0xe9, 0x8f, //0x8540,
+ 0xf0, 0xa4, 0x2c, 0xcd, 0x35, 0xf0, 0xfc, 0xeb, 0x8e, 0xf0, 0xa4, 0xfe, 0xa9, 0xf0, 0xeb, 0x8f, //0x8550,
+ 0xf0, 0xa4, 0xcf, 0xc5, 0xf0, 0x2e, 0xcd, 0x39, 0xfe, 0xe4, 0x3c, 0xfc, 0xea, 0xa4, 0x2d, 0xce, //0x8560,
+ 0x35, 0xf0, 0xfd, 0xe4, 0x3c, 0xfc, 0x22, 0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, //0x8570,
+ 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc, 0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, //0x8580,
+ 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40, 0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, //0x8590,
+ 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6, 0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, //0x85a0,
+ 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9, 0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, //0x85b0,
+ 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb, 0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, //0x85c0,
+ 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb, 0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, //0x85d0,
+ 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9, 0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, //0x85e0,
+ 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, //0x85f0,
+ 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a, 0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, //0x8600,
+ 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, //0x8610,
+ 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07, 0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, //0x8620,
+ 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8, 0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, //0x8630,
+ 0xfa, 0xe4, 0xc8, 0xf9, 0x22, 0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, //0x8640,
+ 0xf0, 0xe8, 0x9c, 0x45, 0xf0, 0x22, 0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, //0x8650,
+ 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff, 0xd8, 0xf1, 0x22, 0xe8, 0x60, 0x0f, 0xef, 0xc3, 0x33, 0xff, //0x8660,
+ 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xd8, 0xf1, 0x22, 0xe4, 0x93, 0xfc, 0x74, //0x8670,
+ 0x01, 0x93, 0xfd, 0x74, 0x02, 0x93, 0xfe, 0x74, 0x03, 0x93, 0xff, 0x22, 0xe6, 0xfb, 0x08, 0xe6, //0x8680,
+ 0xf9, 0x08, 0xe6, 0xfa, 0x08, 0xe6, 0xcb, 0xf8, 0x22, 0xec, 0xf6, 0x08, 0xed, 0xf6, 0x08, 0xee, //0x8690,
+ 0xf6, 0x08, 0xef, 0xf6, 0x22, 0xa4, 0x25, 0x82, 0xf5, 0x82, 0xe5, 0xf0, 0x35, 0x83, 0xf5, 0x83, //0x86a0,
+ 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, //0x86b0,
+ 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, //0x86c0,
+ 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, 0x90, 0x38, 0x04, 0x78, 0x52, 0x12, 0x0b, 0xfd, 0x90, //0x86d0,
+ 0x38, 0x00, 0xe0, 0xfe, 0xa3, 0xe0, 0xfd, 0xed, 0xff, 0xc3, 0x12, 0x0b, 0x9e, 0x90, 0x38, 0x10, //0x86e0,
+ 0x12, 0x0b, 0x92, 0x90, 0x38, 0x06, 0x78, 0x54, 0x12, 0x0b, 0xfd, 0x90, 0x38, 0x02, 0xe0, 0xfe, //0x86f0,
+ 0xa3, 0xe0, 0xfd, 0xed, 0xff, 0xc3, 0x12, 0x0b, 0x9e, 0x90, 0x38, 0x12, 0x12, 0x0b, 0x92, 0xa3, //0x8700,
+ 0xe0, 0xb4, 0x31, 0x07, 0x78, 0x52, 0x79, 0x52, 0x12, 0x0c, 0x13, 0x90, 0x38, 0x14, 0xe0, 0xb4, //0x8710,
+ 0x71, 0x15, 0x78, 0x52, 0xe6, 0xfe, 0x08, 0xe6, 0x78, 0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, //0x8720,
+ 0xf9, 0x79, 0x53, 0xf7, 0xee, 0x19, 0xf7, 0x90, 0x38, 0x15, 0xe0, 0xb4, 0x31, 0x07, 0x78, 0x54, //0x8730,
+ 0x79, 0x54, 0x12, 0x0c, 0x13, 0x90, 0x38, 0x15, 0xe0, 0xb4, 0x71, 0x15, 0x78, 0x54, 0xe6, 0xfe, //0x8740,
+ 0x08, 0xe6, 0x78, 0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0x79, 0x55, 0xf7, 0xee, 0x19, //0x8750,
+ 0xf7, 0x79, 0x52, 0x12, 0x0b, 0xd9, 0x09, 0x12, 0x0b, 0xd9, 0xaf, 0x47, 0x12, 0x0b, 0xb2, 0xe5, //0x8760,
+ 0x44, 0xfb, 0x7a, 0x00, 0xfd, 0x7c, 0x00, 0x12, 0x04, 0xd3, 0x78, 0x5a, 0xa6, 0x06, 0x08, 0xa6, //0x8770,
+ 0x07, 0xaf, 0x45, 0x12, 0x0b, 0xb2, 0xad, 0x03, 0x7c, 0x00, 0x12, 0x04, 0xd3, 0x78, 0x56, 0xa6, //0x8780,
+ 0x06, 0x08, 0xa6, 0x07, 0xaf, 0x48, 0x78, 0x54, 0x12, 0x0b, 0xb4, 0xe5, 0x43, 0xfb, 0xfd, 0x7c, //0x8790,
+ 0x00, 0x12, 0x04, 0xd3, 0x78, 0x5c, 0xa6, 0x06, 0x08, 0xa6, 0x07, 0xaf, 0x46, 0x7e, 0x00, 0x78, //0x87a0,
+ 0x54, 0x12, 0x0b, 0xb6, 0xad, 0x03, 0x7c, 0x00, 0x12, 0x04, 0xd3, 0x78, 0x58, 0xa6, 0x06, 0x08, //0x87b0,
+ 0xa6, 0x07, 0xc3, 0x78, 0x5b, 0xe6, 0x94, 0x08, 0x18, 0xe6, 0x94, 0x00, 0x50, 0x05, 0x76, 0x00, //0x87c0,
+ 0x08, 0x76, 0x08, 0xc3, 0x78, 0x5d, 0xe6, 0x94, 0x08, 0x18, 0xe6, 0x94, 0x00, 0x50, 0x05, 0x76, //0x87d0,
+ 0x00, 0x08, 0x76, 0x08, 0x78, 0x5a, 0x12, 0x0b, 0xc6, 0xff, 0xd3, 0x78, 0x57, 0xe6, 0x9f, 0x18, //0x87e0,
+ 0xe6, 0x9e, 0x40, 0x0e, 0x78, 0x5a, 0xe6, 0x13, 0xfe, 0x08, 0xe6, 0x78, 0x57, 0x12, 0x0c, 0x08, //0x87f0,
+ 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x78, 0x5e, 0x12, 0x0b, 0xbe, 0xff, 0xd3, 0x78, 0x59, 0xe6, //0x8800,
+ 0x9f, 0x18, 0xe6, 0x9e, 0x40, 0x0e, 0x78, 0x5c, 0xe6, 0x13, 0xfe, 0x08, 0xe6, 0x78, 0x59, 0x12, //0x8810,
+ 0x0c, 0x08, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xe4, 0xfc, 0xfd, 0x78, 0x62, 0x12, 0x06, 0x99, //0x8820,
+ 0x78, 0x5a, 0x12, 0x0b, 0xc6, 0x78, 0x57, 0x26, 0xff, 0xee, 0x18, 0x36, 0xfe, 0x78, 0x66, 0x12, //0x8830,
+ 0x0b, 0xbe, 0x78, 0x59, 0x26, 0xff, 0xee, 0x18, 0x36, 0xfe, 0xe4, 0xfc, 0xfd, 0x78, 0x6a, 0x12, //0x8840,
+ 0x06, 0x99, 0x12, 0x0b, 0xce, 0x78, 0x66, 0x12, 0x06, 0x8c, 0xd3, 0x12, 0x06, 0x45, 0x40, 0x08, //0x8850,
+ 0x12, 0x0b, 0xce, 0x78, 0x66, 0x12, 0x06, 0x99, 0x78, 0x54, 0x12, 0x0b, 0xd0, 0x78, 0x6a, 0x12, //0x8860,
+ 0x06, 0x8c, 0xd3, 0x12, 0x06, 0x45, 0x40, 0x0a, 0x78, 0x54, 0x12, 0x0b, 0xd0, 0x78, 0x6a, 0x12, //0x8870,
+ 0x06, 0x99, 0x78, 0x61, 0xe6, 0x90, 0x60, 0x01, 0xf0, 0x78, 0x65, 0xe6, 0xa3, 0xf0, 0x78, 0x69, //0x8880,
+ 0xe6, 0xa3, 0xf0, 0x78, 0x55, 0xe6, 0xa3, 0xf0, 0x7d, 0x01, 0x78, 0x61, 0x12, 0x0b, 0xe9, 0x24, //0x8890,
+ 0x01, 0x12, 0x0b, 0xa6, 0x78, 0x65, 0x12, 0x0b, 0xe9, 0x24, 0x02, 0x12, 0x0b, 0xa6, 0x78, 0x69, //0x88a0,
+ 0x12, 0x0b, 0xe9, 0x24, 0x03, 0x12, 0x0b, 0xa6, 0x78, 0x6d, 0x12, 0x0b, 0xe9, 0x24, 0x04, 0x12, //0x88b0,
+ 0x0b, 0xa6, 0x0d, 0xbd, 0x05, 0xd4, 0xc2, 0x0e, 0xc2, 0x06, 0x22, 0x85, 0x08, 0x41, 0x90, 0x30, //0x88c0,
+ 0x24, 0xe0, 0xf5, 0x3d, 0xa3, 0xe0, 0xf5, 0x3e, 0xa3, 0xe0, 0xf5, 0x3f, 0xa3, 0xe0, 0xf5, 0x40, //0x88d0,
+ 0xa3, 0xe0, 0xf5, 0x3c, 0xd2, 0x34, 0xe5, 0x41, 0x12, 0x06, 0xb1, 0x09, 0x31, 0x03, 0x09, 0x35, //0x88e0,
+ 0x04, 0x09, 0x3b, 0x05, 0x09, 0x3e, 0x06, 0x09, 0x41, 0x07, 0x09, 0x4a, 0x08, 0x09, 0x5b, 0x12, //0x88f0,
+ 0x09, 0x73, 0x18, 0x09, 0x89, 0x19, 0x09, 0x5e, 0x1a, 0x09, 0x6a, 0x1b, 0x09, 0xad, 0x80, 0x09, //0x8900,
+ 0xb2, 0x81, 0x0a, 0x1d, 0x8f, 0x0a, 0x09, 0x90, 0x0a, 0x1d, 0x91, 0x0a, 0x1d, 0x92, 0x0a, 0x1d, //0x8910,
+ 0x93, 0x0a, 0x1d, 0x94, 0x0a, 0x1d, 0x98, 0x0a, 0x17, 0x9f, 0x0a, 0x1a, 0xec, 0x00, 0x00, 0x0a, //0x8920,
+ 0x38, 0x12, 0x0f, 0x74, 0x22, 0x12, 0x0f, 0x74, 0xd2, 0x03, 0x22, 0xd2, 0x03, 0x22, 0xc2, 0x03, //0x8930,
+ 0x22, 0xa2, 0x37, 0xe4, 0x33, 0xf5, 0x3c, 0x02, 0x0a, 0x1d, 0xc2, 0x01, 0xc2, 0x02, 0xc2, 0x03, //0x8940,
+ 0x12, 0x0d, 0x0d, 0x75, 0x1e, 0x70, 0xd2, 0x35, 0x02, 0x0a, 0x1d, 0x02, 0x0a, 0x04, 0x85, 0x40, //0x8950,
+ 0x4a, 0x85, 0x3c, 0x4b, 0x12, 0x0a, 0xff, 0x02, 0x0a, 0x1d, 0x85, 0x4a, 0x40, 0x85, 0x4b, 0x3c, //0x8960,
+ 0x02, 0x0a, 0x1d, 0xe4, 0xf5, 0x22, 0xf5, 0x23, 0x85, 0x40, 0x31, 0x85, 0x3f, 0x30, 0x85, 0x3e, //0x8970,
+ 0x2f, 0x85, 0x3d, 0x2e, 0x12, 0x0f, 0x46, 0x80, 0x1f, 0x75, 0x22, 0x00, 0x75, 0x23, 0x01, 0x74, //0x8980,
+ 0xff, 0xf5, 0x2d, 0xf5, 0x2c, 0xf5, 0x2b, 0xf5, 0x2a, 0x12, 0x0f, 0x46, 0x85, 0x2d, 0x40, 0x85, //0x8990,
+ 0x2c, 0x3f, 0x85, 0x2b, 0x3e, 0x85, 0x2a, 0x3d, 0xe4, 0xf5, 0x3c, 0x80, 0x70, 0x12, 0x0f, 0x16, //0x89a0,
+ 0x80, 0x6b, 0x85, 0x3d, 0x45, 0x85, 0x3e, 0x46, 0xe5, 0x47, 0xc3, 0x13, 0xff, 0xe5, 0x45, 0xc3, //0x89b0,
+ 0x9f, 0x50, 0x02, 0x8f, 0x45, 0xe5, 0x48, 0xc3, 0x13, 0xff, 0xe5, 0x46, 0xc3, 0x9f, 0x50, 0x02, //0x89c0,
+ 0x8f, 0x46, 0xe5, 0x47, 0xc3, 0x13, 0xff, 0xfd, 0xe5, 0x45, 0x2d, 0xfd, 0xe4, 0x33, 0xfc, 0xe5, //0x89d0,
+ 0x44, 0x12, 0x0f, 0x90, 0x40, 0x05, 0xe5, 0x44, 0x9f, 0xf5, 0x45, 0xe5, 0x48, 0xc3, 0x13, 0xff, //0x89e0,
+ 0xfd, 0xe5, 0x46, 0x2d, 0xfd, 0xe4, 0x33, 0xfc, 0xe5, 0x43, 0x12, 0x0f, 0x90, 0x40, 0x05, 0xe5, //0x89f0,
+ 0x43, 0x9f, 0xf5, 0x46, 0x12, 0x06, 0xd7, 0x80, 0x14, 0x85, 0x40, 0x48, 0x85, 0x3f, 0x47, 0x85, //0x8a00,
+ 0x3e, 0x46, 0x85, 0x3d, 0x45, 0x80, 0x06, 0x02, 0x06, 0xd7, 0x12, 0x0d, 0x7e, 0x90, 0x30, 0x24, //0x8a10,
+ 0xe5, 0x3d, 0xf0, 0xa3, 0xe5, 0x3e, 0xf0, 0xa3, 0xe5, 0x3f, 0xf0, 0xa3, 0xe5, 0x40, 0xf0, 0xa3, //0x8a20,
+ 0xe5, 0x3c, 0xf0, 0x90, 0x30, 0x23, 0xe4, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, //0x8a30,
+ 0xd0, 0x90, 0x3f, 0x0c, 0xe0, 0xf5, 0x32, 0xe5, 0x32, 0x30, 0xe3, 0x74, 0x30, 0x36, 0x66, 0x90, //0x8a40,
+ 0x60, 0x19, 0xe0, 0xf5, 0x0a, 0xa3, 0xe0, 0xf5, 0x0b, 0x90, 0x60, 0x1d, 0xe0, 0xf5, 0x14, 0xa3, //0x8a50,
+ 0xe0, 0xf5, 0x15, 0x90, 0x60, 0x21, 0xe0, 0xf5, 0x0c, 0xa3, 0xe0, 0xf5, 0x0d, 0x90, 0x60, 0x29, //0x8a60,
+ 0xe0, 0xf5, 0x0e, 0xa3, 0xe0, 0xf5, 0x0f, 0x90, 0x60, 0x31, 0xe0, 0xf5, 0x10, 0xa3, 0xe0, 0xf5, //0x8a70,
+ 0x11, 0x90, 0x60, 0x39, 0xe0, 0xf5, 0x12, 0xa3, 0xe0, 0xf5, 0x13, 0x30, 0x01, 0x06, 0x30, 0x33, //0x8a80,
+ 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x09, 0x30, 0x02, 0x06, 0x30, 0x33, 0x03, 0xd3, 0x80, 0x01, //0x8a90,
+ 0xc3, 0x92, 0x0a, 0x30, 0x33, 0x0c, 0x30, 0x03, 0x09, 0x20, 0x02, 0x06, 0x20, 0x01, 0x03, 0xd3, //0x8aa0,
+ 0x80, 0x01, 0xc3, 0x92, 0x0b, 0x90, 0x30, 0x01, 0xe0, 0x44, 0x40, 0xf0, 0xe0, 0x54, 0xbf, 0xf0, //0x8ab0,
+ 0xe5, 0x32, 0x30, 0xe1, 0x14, 0x30, 0x34, 0x11, 0x90, 0x30, 0x22, 0xe0, 0xf5, 0x08, 0xe4, 0xf0, //0x8ac0,
+ 0x30, 0x00, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x08, 0xe5, 0x32, 0x30, 0xe5, 0x12, 0x90, 0x56, //0x8ad0,
+ 0xa1, 0xe0, 0xf5, 0x09, 0x30, 0x31, 0x09, 0x30, 0x05, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x0d, //0x8ae0,
+ 0x90, 0x3f, 0x0c, 0xe5, 0x32, 0xf0, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, //0x8af0,
+ 0x0e, 0x7e, 0xe4, 0x93, 0xfe, 0x74, 0x01, 0x93, 0xff, 0xc3, 0x90, 0x0e, 0x7c, 0x74, 0x01, 0x93, //0x8b00,
+ 0x9f, 0xff, 0xe4, 0x93, 0x9e, 0xfe, 0xe4, 0x8f, 0x3b, 0x8e, 0x3a, 0xf5, 0x39, 0xf5, 0x38, 0xab, //0x8b10,
+ 0x3b, 0xaa, 0x3a, 0xa9, 0x39, 0xa8, 0x38, 0xaf, 0x4b, 0xfc, 0xfd, 0xfe, 0x12, 0x05, 0x28, 0x12, //0x8b20,
+ 0x0d, 0xe1, 0xe4, 0x7b, 0xff, 0xfa, 0xf9, 0xf8, 0x12, 0x05, 0xb3, 0x12, 0x0d, 0xe1, 0x90, 0x0e, //0x8b30,
+ 0x69, 0xe4, 0x12, 0x0d, 0xf6, 0x12, 0x0d, 0xe1, 0xe4, 0x85, 0x4a, 0x37, 0xf5, 0x36, 0xf5, 0x35, //0x8b40,
+ 0xf5, 0x34, 0xaf, 0x37, 0xae, 0x36, 0xad, 0x35, 0xac, 0x34, 0xa3, 0x12, 0x0d, 0xf6, 0x8f, 0x37, //0x8b50,
+ 0x8e, 0x36, 0x8d, 0x35, 0x8c, 0x34, 0xe5, 0x3b, 0x45, 0x37, 0xf5, 0x3b, 0xe5, 0x3a, 0x45, 0x36, //0x8b60,
+ 0xf5, 0x3a, 0xe5, 0x39, 0x45, 0x35, 0xf5, 0x39, 0xe5, 0x38, 0x45, 0x34, 0xf5, 0x38, 0xe4, 0xf5, //0x8b70,
+ 0x22, 0xf5, 0x23, 0x85, 0x3b, 0x31, 0x85, 0x3a, 0x30, 0x85, 0x39, 0x2f, 0x85, 0x38, 0x2e, 0x02, //0x8b80,
+ 0x0f, 0x46, 0xe0, 0xa3, 0xe0, 0x75, 0xf0, 0x02, 0xa4, 0xff, 0xae, 0xf0, 0xc3, 0x08, 0xe6, 0x9f, //0x8b90,
+ 0xf6, 0x18, 0xe6, 0x9e, 0xf6, 0x22, 0xff, 0xe5, 0xf0, 0x34, 0x60, 0x8f, 0x82, 0xf5, 0x83, 0xec, //0x8ba0,
+ 0xf0, 0x22, 0x78, 0x52, 0x7e, 0x00, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x02, 0x04, 0xc1, 0xe4, 0xfc, //0x8bb0,
+ 0xfd, 0x12, 0x06, 0x99, 0x78, 0x5c, 0xe6, 0xc3, 0x13, 0xfe, 0x08, 0xe6, 0x13, 0x22, 0x78, 0x52, //0x8bc0,
+ 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0xe4, 0xfc, 0xfd, 0x22, 0xe7, 0xc4, 0xf8, 0x54, 0xf0, 0xc8, 0x68, //0x8bd0,
+ 0xf7, 0x09, 0xe7, 0xc4, 0x54, 0x0f, 0x48, 0xf7, 0x22, 0xe6, 0xfc, 0xed, 0x75, 0xf0, 0x04, 0xa4, //0x8be0,
+ 0x22, 0x12, 0x06, 0x7c, 0x8f, 0x48, 0x8e, 0x47, 0x8d, 0x46, 0x8c, 0x45, 0x22, 0xe0, 0xfe, 0xa3, //0x8bf0,
+ 0xe0, 0xfd, 0xee, 0xf6, 0xed, 0x08, 0xf6, 0x22, 0x13, 0xff, 0xc3, 0xe6, 0x9f, 0xff, 0x18, 0xe6, //0x8c00,
+ 0x9e, 0xfe, 0x22, 0xe6, 0xc3, 0x13, 0xf7, 0x08, 0xe6, 0x13, 0x09, 0xf7, 0x22, 0xad, 0x39, 0xac, //0x8c10,
+ 0x38, 0xfa, 0xf9, 0xf8, 0x12, 0x05, 0x28, 0x8f, 0x3b, 0x8e, 0x3a, 0x8d, 0x39, 0x8c, 0x38, 0xab, //0x8c20,
+ 0x37, 0xaa, 0x36, 0xa9, 0x35, 0xa8, 0x34, 0x22, 0x93, 0xff, 0xe4, 0xfc, 0xfd, 0xfe, 0x12, 0x05, //0x8c30,
+ 0x28, 0x8f, 0x37, 0x8e, 0x36, 0x8d, 0x35, 0x8c, 0x34, 0x22, 0x78, 0x84, 0xe6, 0xfe, 0x08, 0xe6, //0x8c40,
+ 0xff, 0xe4, 0x8f, 0x37, 0x8e, 0x36, 0xf5, 0x35, 0xf5, 0x34, 0x22, 0x90, 0x0e, 0x8c, 0xe4, 0x93, //0x8c50,
+ 0x25, 0xe0, 0x24, 0x0a, 0xf8, 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x22, 0xe6, 0xfe, 0x08, 0xe6, 0xff, //0x8c60,
+ 0xe4, 0x8f, 0x3b, 0x8e, 0x3a, 0xf5, 0x39, 0xf5, 0x38, 0x22, 0x78, 0x4e, 0xe6, 0xfe, 0x08, 0xe6, //0x8c70,
+ 0xff, 0x22, 0xef, 0x25, 0xe0, 0x24, 0x4e, 0xf8, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0x22, 0x78, 0x89, //0x8c80,
+ 0xef, 0x26, 0xf6, 0x18, 0xe4, 0x36, 0xf6, 0x22, 0x75, 0x89, 0x03, 0x75, 0xa8, 0x01, 0x75, 0xb8, //0x8c90,
+ 0x04, 0x75, 0x34, 0xff, 0x75, 0x35, 0x0e, 0x75, 0x36, 0x15, 0x75, 0x37, 0x0d, 0x12, 0x0e, 0x9a, //0x8ca0,
+ 0x12, 0x00, 0x09, 0x12, 0x0f, 0x16, 0x12, 0x00, 0x06, 0xd2, 0x00, 0xd2, 0x34, 0xd2, 0xaf, 0x75, //0x8cb0,
+ 0x34, 0xff, 0x75, 0x35, 0x0e, 0x75, 0x36, 0x49, 0x75, 0x37, 0x03, 0x12, 0x0e, 0x9a, 0x30, 0x08, //0x8cc0,
+ 0x09, 0xc2, 0x34, 0x12, 0x08, 0xcb, 0xc2, 0x08, 0xd2, 0x34, 0x30, 0x0b, 0x09, 0xc2, 0x36, 0x12, //0x8cd0,
+ 0x02, 0x6c, 0xc2, 0x0b, 0xd2, 0x36, 0x30, 0x09, 0x09, 0xc2, 0x36, 0x12, 0x00, 0x0e, 0xc2, 0x09, //0x8ce0,
+ 0xd2, 0x36, 0x30, 0x0e, 0x03, 0x12, 0x06, 0xd7, 0x30, 0x35, 0xd3, 0x90, 0x30, 0x29, 0xe5, 0x1e, //0x8cf0,
+ 0xf0, 0xb4, 0x10, 0x05, 0x90, 0x30, 0x23, 0xe4, 0xf0, 0xc2, 0x35, 0x80, 0xc1, 0xe4, 0xf5, 0x4b, //0x8d00,
+ 0x90, 0x0e, 0x7a, 0x93, 0xff, 0xe4, 0x8f, 0x37, 0xf5, 0x36, 0xf5, 0x35, 0xf5, 0x34, 0xaf, 0x37, //0x8d10,
+ 0xae, 0x36, 0xad, 0x35, 0xac, 0x34, 0x90, 0x0e, 0x6a, 0x12, 0x0d, 0xf6, 0x8f, 0x37, 0x8e, 0x36, //0x8d20,
+ 0x8d, 0x35, 0x8c, 0x34, 0x90, 0x0e, 0x72, 0x12, 0x06, 0x7c, 0xef, 0x45, 0x37, 0xf5, 0x37, 0xee, //0x8d30,
+ 0x45, 0x36, 0xf5, 0x36, 0xed, 0x45, 0x35, 0xf5, 0x35, 0xec, 0x45, 0x34, 0xf5, 0x34, 0xe4, 0xf5, //0x8d40,
+ 0x22, 0xf5, 0x23, 0x85, 0x37, 0x31, 0x85, 0x36, 0x30, 0x85, 0x35, 0x2f, 0x85, 0x34, 0x2e, 0x12, //0x8d50,
+ 0x0f, 0x46, 0xe4, 0xf5, 0x22, 0xf5, 0x23, 0x90, 0x0e, 0x72, 0x12, 0x0d, 0xea, 0x12, 0x0f, 0x46, //0x8d60,
+ 0xe4, 0xf5, 0x22, 0xf5, 0x23, 0x90, 0x0e, 0x6e, 0x12, 0x0d, 0xea, 0x02, 0x0f, 0x46, 0xe5, 0x40, //0x8d70,
+ 0x24, 0xf2, 0xf5, 0x37, 0xe5, 0x3f, 0x34, 0x43, 0xf5, 0x36, 0xe5, 0x3e, 0x34, 0xa2, 0xf5, 0x35, //0x8d80,
+ 0xe5, 0x3d, 0x34, 0x28, 0xf5, 0x34, 0xe5, 0x37, 0xff, 0xe4, 0xfe, 0xfd, 0xfc, 0x78, 0x18, 0x12, //0x8d90,
+ 0x06, 0x69, 0x8f, 0x40, 0x8e, 0x3f, 0x8d, 0x3e, 0x8c, 0x3d, 0xe5, 0x37, 0x54, 0xa0, 0xff, 0xe5, //0x8da0,
+ 0x36, 0xfe, 0xe4, 0xfd, 0xfc, 0x78, 0x07, 0x12, 0x06, 0x56, 0x78, 0x10, 0x12, 0x0f, 0x9a, 0xe4, //0x8db0,
+ 0xff, 0xfe, 0xe5, 0x35, 0xfd, 0xe4, 0xfc, 0x78, 0x0e, 0x12, 0x06, 0x56, 0x12, 0x0f, 0x9d, 0xe4, //0x8dc0,
+ 0xff, 0xfe, 0xfd, 0xe5, 0x34, 0xfc, 0x78, 0x18, 0x12, 0x06, 0x56, 0x78, 0x08, 0x12, 0x0f, 0x9a, //0x8dd0,
+ 0x22, 0x8f, 0x3b, 0x8e, 0x3a, 0x8d, 0x39, 0x8c, 0x38, 0x22, 0x12, 0x06, 0x7c, 0x8f, 0x31, 0x8e, //0x8de0,
+ 0x30, 0x8d, 0x2f, 0x8c, 0x2e, 0x22, 0x93, 0xf9, 0xf8, 0x02, 0x06, 0x69, 0x00, 0x00, 0x00, 0x00, //0x8df0,
+ 0x12, 0x01, 0x17, 0x08, 0x31, 0x15, 0x53, 0x54, 0x44, 0x20, 0x20, 0x20, 0x20, 0x20, 0x13, 0x01, //0x8e00,
+ 0x10, 0x01, 0x56, 0x40, 0x1a, 0x30, 0x29, 0x7e, 0x00, 0x30, 0x04, 0x20, 0xdf, 0x30, 0x05, 0x40, //0x8e10,
+ 0xbf, 0x50, 0x03, 0x00, 0xfd, 0x50, 0x27, 0x01, 0xfe, 0x60, 0x00, 0x11, 0x00, 0x3f, 0x05, 0x30, //0x8e20,
+ 0x00, 0x3f, 0x06, 0x22, 0x00, 0x3f, 0x01, 0x2a, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x36, 0x06, 0x07, //0x8e30,
+ 0x00, 0x3f, 0x0b, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x40, 0xbf, 0x30, 0x01, 0x00, //0x8e40,
+ 0xbf, 0x30, 0x29, 0x70, 0x00, 0x3a, 0x00, 0x00, 0xff, 0x3a, 0x00, 0x00, 0xff, 0x36, 0x03, 0x36, //0x8e50,
+ 0x02, 0x41, 0x44, 0x58, 0x20, 0x18, 0x10, 0x0a, 0x04, 0x04, 0x00, 0x03, 0xff, 0x64, 0x00, 0x00, //0x8e60,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x06, 0x06, 0x00, 0x03, 0x51, 0x00, 0x7a, //0x8e70,
+ 0x50, 0x3c, 0x28, 0x1e, 0x10, 0x10, 0x50, 0x2d, 0x28, 0x16, 0x10, 0x10, 0x02, 0x00, 0x10, 0x0c, //0x8e80,
+ 0x10, 0x04, 0x0c, 0x6e, 0x06, 0x05, 0x00, 0xa5, 0x5a, 0x00, 0xae, 0x35, 0xaf, 0x36, 0xe4, 0xfd, //0x8e90,
+ 0xed, 0xc3, 0x95, 0x37, 0x50, 0x33, 0x12, 0x0f, 0xe2, 0xe4, 0x93, 0xf5, 0x38, 0x74, 0x01, 0x93, //0x8ea0,
+ 0xf5, 0x39, 0x45, 0x38, 0x60, 0x23, 0x85, 0x39, 0x82, 0x85, 0x38, 0x83, 0xe0, 0xfc, 0x12, 0x0f, //0x8eb0,
+ 0xe2, 0x74, 0x03, 0x93, 0x52, 0x04, 0x12, 0x0f, 0xe2, 0x74, 0x02, 0x93, 0x42, 0x04, 0x85, 0x39, //0x8ec0,
+ 0x82, 0x85, 0x38, 0x83, 0xec, 0xf0, 0x0d, 0x80, 0xc7, 0x22, 0x78, 0xbe, 0xe6, 0xd3, 0x08, 0xff, //0x8ed0,
+ 0xe6, 0x64, 0x80, 0xf8, 0xef, 0x64, 0x80, 0x98, 0x22, 0x93, 0xff, 0x7e, 0x00, 0xe6, 0xfc, 0x08, //0x8ee0,
+ 0xe6, 0xfd, 0x12, 0x04, 0xc1, 0x78, 0xc1, 0xe6, 0xfc, 0x08, 0xe6, 0xfd, 0xd3, 0xef, 0x9d, 0xee, //0x8ef0,
+ 0x9c, 0x22, 0x78, 0xbd, 0xd3, 0xe6, 0x64, 0x80, 0x94, 0x80, 0x22, 0x25, 0xe0, 0x24, 0x0a, 0xf8, //0x8f00,
+ 0xe6, 0xfe, 0x08, 0xe6, 0xff, 0x22, 0xe5, 0x3c, 0xd3, 0x94, 0x00, 0x40, 0x0b, 0x90, 0x0e, 0x88, //0x8f10,
+ 0x12, 0x0b, 0xf1, 0x90, 0x0e, 0x86, 0x80, 0x09, 0x90, 0x0e, 0x82, 0x12, 0x0b, 0xf1, 0x90, 0x0e, //0x8f20,
+ 0x80, 0xe4, 0x93, 0xf5, 0x44, 0xa3, 0xe4, 0x93, 0xf5, 0x43, 0xd2, 0x06, 0x30, 0x06, 0x03, 0xd3, //0x8f30,
+ 0x80, 0x01, 0xc3, 0x92, 0x0e, 0x22, 0xa2, 0xaf, 0x92, 0x32, 0xc2, 0xaf, 0xe5, 0x23, 0x45, 0x22, //0x8f40,
+ 0x90, 0x0e, 0x5d, 0x60, 0x0e, 0x12, 0x0f, 0xcb, 0xe0, 0xf5, 0x2c, 0x12, 0x0f, 0xc8, 0xe0, 0xf5, //0x8f50,
+ 0x2d, 0x80, 0x0c, 0x12, 0x0f, 0xcb, 0xe5, 0x30, 0xf0, 0x12, 0x0f, 0xc8, 0xe5, 0x31, 0xf0, 0xa2, //0x8f60,
+ 0x32, 0x92, 0xaf, 0x22, 0xd2, 0x01, 0xc2, 0x02, 0xe4, 0xf5, 0x1f, 0xf5, 0x1e, 0xd2, 0x35, 0xd2, //0x8f70,
+ 0x33, 0xd2, 0x36, 0xd2, 0x01, 0xc2, 0x02, 0xf5, 0x1f, 0xf5, 0x1e, 0xd2, 0x35, 0xd2, 0x33, 0x22, //0x8f80,
+ 0xfb, 0xd3, 0xed, 0x9b, 0x74, 0x80, 0xf8, 0x6c, 0x98, 0x22, 0x12, 0x06, 0x69, 0xe5, 0x40, 0x2f, //0x8f90,
+ 0xf5, 0x40, 0xe5, 0x3f, 0x3e, 0xf5, 0x3f, 0xe5, 0x3e, 0x3d, 0xf5, 0x3e, 0xe5, 0x3d, 0x3c, 0xf5, //0x8fa0,
+ 0x3d, 0x22, 0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x3f, 0x0d, 0xe0, 0xf5, 0x33, 0xe5, 0x33, //0x8fb0,
+ 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32, 0x90, 0x0e, 0x5f, 0xe4, 0x93, 0xfe, 0x74, 0x01, //0x8fc0,
+ 0x93, 0xf5, 0x82, 0x8e, 0x83, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0xcd, 0x02, //0x8fd0,
+ 0x0c, 0x98, 0x8f, 0x82, 0x8e, 0x83, 0x75, 0xf0, 0x04, 0xed, 0x02, 0x06, 0xa5, //0x8fe0
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c
index 4623f41923..174fd3bdac 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c
@@ -19,6 +19,8 @@
#define LOG_TAG "drv.pmic"
#include <drv_log.h>
+#define I2C_NAME "i2c3"
+
static struct rt_i2c_bus_device *pmic_dev = RT_NULL;
/* i2c read reg */
@@ -796,47 +798,47 @@ static rt_err_t rt_hw_pmic_init_register(void)
stpmu1_write_reg(BUCK_ICC_TURNOFF_REG, 0x30);
stpmu1_write_reg(LDO_ICC_TURNOFF_REG, 0x3b);
- /* vddcore */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK1, 1200);
- STPMU1_Regulator_Enable(STPMU1_BUCK1);
+ /* vddcore */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK1, 1200);
+ STPMU1_Regulator_Enable(STPMU1_BUCK1);
- /* vddddr */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK2, 1350);
- STPMU1_Regulator_Enable(STPMU1_BUCK2);
+ /* vddddr */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK2, 1350);
+ STPMU1_Regulator_Enable(STPMU1_BUCK2);
- /* vdd */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK3, 3300);
- STPMU1_Regulator_Enable(STPMU1_BUCK3);
+ /* vdd */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK3, 3300);
+ STPMU1_Regulator_Enable(STPMU1_BUCK3);
- /* 3v3 */
- STPMU1_Regulator_Voltage_Set(STPMU1_BUCK4, 3300);
- STPMU1_Regulator_Enable(STPMU1_BUCK4);
+ /* 3v3 */
+ STPMU1_Regulator_Voltage_Set(STPMU1_BUCK4, 3300);
+ STPMU1_Regulator_Enable(STPMU1_BUCK4);
- /* vdda */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO1, 2900);
- STPMU1_Regulator_Enable(STPMU1_LDO1);
+ /* vdda */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO1, 2900);
+ STPMU1_Regulator_Enable(STPMU1_LDO1);
- /* 2v8 */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO2, 2800);
- STPMU1_Regulator_Enable(STPMU1_LDO2);
+ /* 2v8 */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO2, 2800);
+ STPMU1_Regulator_Enable(STPMU1_LDO2);
- /* vtt_ddr lod3 mode buck2/2 */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO3, 0xFFFF);
- STPMU1_Regulator_Enable(STPMU1_LDO3);
+ /* vtt_ddr lod3 mode buck2/2 */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO3, 0xFFFF);
+ STPMU1_Regulator_Enable(STPMU1_LDO3);
- /* vdd_usb */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO4, 3300);
- STPMU1_Regulator_Enable(STPMU1_LDO4);
+ /* vdd_usb */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO4, 3300);
+ STPMU1_Regulator_Enable(STPMU1_LDO4);
- /* vdd_sd */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO5, 2900);
- STPMU1_Regulator_Enable(STPMU1_LDO5);
+ /* vdd_sd */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO5, 2900);
+ STPMU1_Regulator_Enable(STPMU1_LDO5);
- /* 1v8 */
- STPMU1_Regulator_Voltage_Set(STPMU1_LDO6, 1800);
- STPMU1_Regulator_Enable(STPMU1_LDO6);
+ /* 1v8 */
+ STPMU1_Regulator_Voltage_Set(STPMU1_LDO6, 1800);
+ STPMU1_Regulator_Enable(STPMU1_LDO6);
- STPMU1_Regulator_Enable(STPMU1_VREFDDR);
+ STPMU1_Regulator_Enable(STPMU1_VREFDDR);
return RT_EOK;
}
@@ -884,7 +886,7 @@ static int pmic_init(void)
{
BSP_PMIC_MspInit();
- result = rt_hw_pmic_init("i2c3");
+ result = rt_hw_pmic_init(I2C_NAME);
if(result != RT_EOK)
{
LOG_D("stpmic init failed: %02x", result);
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pwr.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pwr.c
new file mode 100644
index 0000000000..3aac57603d
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pwr.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu first version
+ */
+
+#include "board.h"
+//#define DRV_DEBUG
+#define LOG_TAG "drv.pwr"
+#include <drv_log.h>
+
+extern int lptim_start(void);
+extern int lptim_stop(void);
+
+static RCC_ClkInitTypeDef RCC_ClkInit = {0};
+
+#define __WAIT_EVENT_TIMEOUT(__CONDITION__, __TIMEOUT_VAL__) \
+ do { \
+ __IO uint32_t count = __TIMEOUT_VAL__ * (SystemCoreClock / 20U / 1000U); \
+ do \
+ { \
+ if (count-- == 0U) \
+ { \
+ return HAL_TIMEOUT; \
+ } \
+ } \
+ while (__CONDITION__ == 0U); \
+ } while(0)
+
+/* Back up clock tree */
+static void backup_cm4_clocks(void)
+{
+ rt_uint32_t *pFLatency = NULL;
+
+ /* Back up MCU clock configuration */
+ HAL_RCC_GetClockConfig(&RCC_ClkInit, pFLatency);
+}
+
+/* Restore the CM4 clock source muxer and the CM4 prescaler. */
+rt_err_t restore_cm4_clock(void)
+{
+ /* Update SystemCoreClock variable */
+ SystemCoreClock = HAL_RCC_GetSystemCoreClockFreq();
+
+ /* Enable PLL3 if needed */
+ if (RCC_ClkInit.MCUInit.MCU_Clock == RCC_MCUSSOURCE_PLL3)
+ {
+ /* Enable PLL3 */
+ __HAL_RCC_PLL3_ENABLE();
+
+ /* Wait till PLL3 is ready */
+ __WAIT_EVENT_TIMEOUT(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL3RDY), CLOCKSWITCH_TIMEOUT_VALUE);
+
+ /* Enable PLL3 outputs */
+ __HAL_RCC_PLL3CLKOUT_ENABLE(RCC_PLL3_DIVP | RCC_PLL3_DIVQ | RCC_PLL3_DIVR);
+ }
+
+ /* Configure MCU clock only */
+ __HAL_RCC_MCU_SOURCE(RCC_ClkInit.MCUInit.MCU_Clock);
+
+ /* Wait till MCU is ready */
+ __WAIT_EVENT_TIMEOUT(__HAL_RCC_GET_FLAG(RCC_FLAG_MCUSSRCRDY),
+ CLOCKSWITCH_TIMEOUT_VALUE);
+
+ /* Update SystemCoreClock variable */
+ SystemCoreClock = HAL_RCC_GetSystemCoreClockFreq();
+
+ /* Reconfigure Systick */
+ if (HAL_InitTick(uwTickPrio) != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+
+ /* Set MCU division factor */
+ __HAL_RCC_MCU_DIV(RCC_ClkInit.MCUInit.MCU_Div);
+
+ /* Wait till MCUDIV is ready */
+ __WAIT_EVENT_TIMEOUT(__HAL_RCC_GET_FLAG(RCC_FLAG_MCUDIVRDY),
+ CLOCKSWITCH_TIMEOUT_VALUE);
+
+ /* Update SystemCoreClock variable */
+ SystemCoreClock = HAL_RCC_GetSystemCoreClockFreq();
+
+ /* Reconfigure Systick */
+ if (HAL_InitTick(uwTickPrio) != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+void RCC_WAKEUP_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_RCC_WAKEUP_IRQHandler();
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void HAL_RCC_WAKEUP_Callback()
+{
+ if (__HAL_PWR_GET_FLAG(PWR_FLAG_STOP) == 1U)
+ {
+ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_STOP);
+ }
+
+ restore_cm4_clock();
+ /* All level of ITs can interrupt */
+ __set_BASEPRI(0U);
+
+ rt_kprintf("system exit stop mode success!\n");
+}
+
+static void enter_sleep_mode(void)
+{
+ __set_BASEPRI((1) << (8 - __NVIC_PRIO_BITS));
+
+ lptim_start();
+
+ HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
+}
+
+static void enter_stop_mode(void)
+{
+ /*
+ * Only the IT with the highest priority (0 value) can interrupt.
+ * RCC_WAKEUP_IRQn IT is intended to have the highest priority and to be the
+ * only one IT having this value
+ * RCC_WAKEUP_IRQn is generated only when RCC is completely resumed from
+ * CSTOP (protection mechanism)
+ */
+ __set_BASEPRI((1) << (8 - __NVIC_PRIO_BITS));
+
+ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_STOP);
+ backup_cm4_clocks();
+ HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
+}
+
+static void pm_wackup_key_init(void)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+
+ GPIO_InitStruct.Pin = GPIO_PIN_13;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ HAL_NVIC_SetPriority(EXTI13_IRQn, 0x01, 0);
+ HAL_NVIC_EnableIRQ(EXTI13_IRQn);
+}
+
+int drv_pm_hw_init(void)
+{
+ pm_wackup_key_init();
+
+ return RT_EOK;
+}
+INIT_BOARD_EXPORT(drv_pm_hw_init);
+
+static int pwr_sample(int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ if (!rt_strcmp(argv[1], "stop"))
+ {
+ rt_kprintf("system will enter stop mode! you can press USER2 button to exit this mode\n");
+ enter_stop_mode();
+ return RT_EOK;
+
+ }
+ else if (!rt_strcmp(argv[1], "sleep"))
+ {
+ rt_kprintf("system will enter sleep mode! lptim1 will wake up the system\n");
+ enter_sleep_mode();
+ return RT_EOK;
+ }
+ else
+ {
+ goto _exit;
+ }
+ }
+_exit:
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("pwr_sample stop - system enter stop mode\n");
+ rt_kprintf("pwr_sample sleep - system enter sleep mode\n");
+ }
+
+ return -RT_ERROR;
+}
+MSH_CMD_EXPORT(pwr_sample, enter low power mode sample);
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_qspi_flash.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_qspi_flash.c
new file mode 100644
index 0000000000..70fa977359
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_qspi_flash.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-07 thread-liu first version
+ */
+
+#include <board.h>
+#include <drv_qspi.h>
+#include <rtdevice.h>
+#include <rthw.h>
+#include <finsh.h>
+
+#ifdef BSP_USING_QSPI_FLASH
+
+#include "spi_flash.h"
+#include "spi_flash_sfud.h"
+
+/**
+* @brief QSPI MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hqspi: QSPI handle pointer
+* @retval None
+*/
+void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+ if(hqspi->Instance==QUADSPI)
+ {
+ /* USER CODE BEGIN QUADSPI_MspInit 0 */
+ if (IS_ENGINEERING_BOOT_MODE())
+ {
+ PeriphClkInit.Sdmmc12ClockSelection = RCC_QSPICLKSOURCE_ACLK;
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_QSPI;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+ /* USER CODE END QUADSPI_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_QSPI_CLK_ENABLE();
+
+ __HAL_RCC_GPIOF_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ /**QUADSPI GPIO Configuration
+ PF6 ------> QUADSPI_BK1_IO3
+ PF7 ------> QUADSPI_BK1_IO2
+ PF8 ------> QUADSPI_BK1_IO0
+ PF9 ------> QUADSPI_BK1_IO1
+ PF10 ------> QUADSPI_CLK
+ PB6 ------> QUADSPI_BK1_NCS
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_10;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
+ GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_7 | GPIO_PIN_6;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
+ GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
+ GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
+ HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+ /**QUADSPI GPIO Configuration
+ PC0 ------> QUADSPI_BK2_NCS
+ PH3 ------> QUADSPI_BK2_IO1
+ PG7 ------> QUADSPI_BK2_IO3
+ PG10 ------> QUADSPI_BK2_IO2
+ PH2 ------> QUADSPI_BK2_IO0
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_0;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
+ GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_2;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
+ GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
+ HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_10;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
+ GPIO_InitStruct.Alternate = GPIO_AF11_QUADSPI;
+ HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
+
+ /* USER CODE BEGIN QUADSPI_MspInit 1 */
+
+ /* USER CODE END QUADSPI_MspInit 1 */
+ }
+}
+
+/**
+* @brief QSPI MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hqspi: QSPI handle pointer
+* @retval None
+*/
+void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef* hqspi)
+{
+ if(hqspi->Instance==QUADSPI)
+ {
+ /* USER CODE BEGIN QUADSPI_MspDeInit 0 */
+
+ /* USER CODE END QUADSPI_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_QSPI_CLK_DISABLE();
+
+ /**QUADSPI GPIO Configuration
+ PC0 ------> QUADSPI_BK2_NCS
+ PF10 ------> QUADSPI_CLK
+ PB6 ------> QUADSPI_BK1_NCS
+ PH3 ------> QUADSPI_BK2_IO1
+ PG7 ------> QUADSPI_BK2_IO3
+ PG10 ------> QUADSPI_BK2_IO2
+ PF7 ------> QUADSPI_BK1_IO2
+ PF6 ------> QUADSPI_BK1_IO3
+ PH2 ------> QUADSPI_BK2_IO0
+ PF8 ------> QUADSPI_BK1_IO0
+ PF9 ------> QUADSPI_BK1_IO1
+ */
+ HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0);
+
+ HAL_GPIO_DeInit(GPIOF, GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10);
+
+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
+
+ HAL_GPIO_DeInit(GPIOH, GPIO_PIN_3|GPIO_PIN_2);
+
+ HAL_GPIO_DeInit(GPIOG, GPIO_PIN_7|GPIO_PIN_10);
+
+ /* USER CODE BEGIN QUADSPI_MspDeInit 1 */
+
+ /* USER CODE END QUADSPI_MspDeInit 1 */
+ }
+
+}
+
+static int rt_hw_qspi_flash_with_sfud_init(void)
+{
+ stm32_qspi_bus_attach_device("qspi1", "qspi10", RT_NULL, 4, RT_NULL, RT_NULL);
+ /* init MX25L51245G */
+ if (RT_NULL == rt_sfud_flash_probe("MX25L51245G", "qspi10"))
+ {
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_qspi_flash_with_sfud_init);
+
+#endif /* BSP_USING_QSPI_FLASH */
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_rs485.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_rs485.c
new file mode 100644
index 0000000000..44eba3be91
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_rs485.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-10-24 thread-liu first version
+ */
+
+#include <board.h>
+#include "drv_rs485.h"
+
+#ifdef BSP_USING_RS485
+
+#define RS485_OUT rt_pin_write(BSP_RS485_RTS_PIN, PIN_HIGH)
+#define RS485_IN rt_pin_write(BSP_RS485_RTS_PIN, PIN_LOW)
+
+static rt_device_t serial = {0};
+static struct rt_semaphore rx_sem = {0};
+
+/* uart send data callback function */
+static rt_err_t rs485_output(rt_device_t dev, void * buffer)
+{
+ return RT_EOK;
+}
+
+/* uart receive data callback function */
+static rt_err_t rs485_input(rt_device_t dev, rt_size_t size)
+{
+ rt_sem_release(&rx_sem);
+
+ return RT_EOK;
+}
+
+/* send string */
+int rs485_send_data(char *tbuf, rt_uint16_t t_len)
+{
+ /* change rs485 mode */
+ RS485_OUT;
+
+ /* send data */
+ rt_device_write(serial, 0, tbuf, t_len);
+
+ /* change rs485 mode */
+ RS485_IN;
+
+ return RT_EOK;
+}
+
+static void rs485_thread_entry(void *parameter)
+{
+ char ch;
+
+ while (1)
+ {
+ /* A byte of data is read from a serial port, and if it is not read, it waits for the received semaphore */
+ while (rt_device_read(serial, -1, &ch, 1) != 1)
+ {
+ rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
+ }
+
+ /* The data read through the serial port output dislocation */
+ ch = ch + 1;
+
+ /* send char */
+ rs485_send_data(&ch, 1);
+ }
+}
+
+/* rs485 rts pin init */
+static int rs485_init(void)
+{
+ /* find uart device */
+ serial = rt_device_find(RS485_UART_DEVICE_NAME);
+ if (!serial)
+ {
+ rt_kprintf("find %s failed!\n", RS485_UART_DEVICE_NAME);
+ return RT_ERROR;
+ }
+
+ rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
+
+ /* set receive data callback function */
+ rt_device_set_rx_indicate(serial, rs485_input);
+
+ /* set the send completion callback function */
+ rt_device_set_tx_complete(serial, rs485_output);
+
+ rt_pin_mode(BSP_RS485_RTS_PIN, PIN_MODE_OUTPUT);
+
+ RS485_IN;
+
+ rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
+ /* create rs485 thread */
+ rt_thread_t thread = rt_thread_create("rs485", rs485_thread_entry, RT_NULL, 1024, 25, 10);
+
+ if (thread != RT_NULL)
+ {
+ rt_thread_startup(thread);
+ }
+ else
+ {
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rs485_init);
+
+#endif /* bsp_using_RS485 */
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_rs485.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_rs485.h
new file mode 100644
index 0000000000..01edf84ae8
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_rs485.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-10-24 thread-liu first version
+ */
+
+#ifndef __DRV_RS485_H__
+#define __DRV_RS485_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RS485_SEND_MODE 0
+#define RS485_RECV_MODE 1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* drv_rs485.h */
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sdcard.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sdcard.c
new file mode 100644
index 0000000000..ca79b806d7
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sdcard.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-04 thread-liu the first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_SD_CARD)
+#include <dfs_fs.h>
+
+#define DRV_DEBUG
+//#define SDMMC_TX_DUMP
+//#define SDMMC_RX_DUMP
+#define LOG_TAG "drv.sdmmc"
+#include <drv_log.h>
+
+static SD_HandleTypeDef SDCARD_Handler = {0};
+static HAL_SD_CardInfoTypeDef SDCardInfo = {0};
+
+struct stm32_sd
+{
+ struct rt_device sdcard;
+ struct rt_semaphore sd_lock;
+ volatile rt_uint8_t write_flage;
+ volatile rt_uint8_t read_flage;
+ volatile rt_base_t level;
+};
+static struct stm32_sd sd_device;
+
+#define SD_TIMEOUT ((uint32_t)30 * 1000)
+#define DETECT_PIN GET_PIN(G, 1)
+#define LDO_PIN GET_PIN(F, 14)
+
+struct rt_completion tx_comp;
+struct rt_completion rx_comp;
+
+/* SYSRAM SDMMC1/2 accesses */
+#define SDIO_BUFF_SIZE 512
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFC0000)))
+#elif defined ( __GNUC__ )
+__attribute__((at(0x2FFC0000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFC0000
+#endif
+static rt_uint32_t cache_buf[SDIO_BUFF_SIZE];
+
+#if defined(SDMMC_RX_DUMP) || defined(SDMMC_TX_DUMP)
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
+{
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%08X: ", i);
+
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%02X ", buf[i + j]);
+ else
+ rt_kprintf(" ");
+ rt_kprintf(" ");
+
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ rt_kprintf("\n");
+ }
+}
+#endif
+
+static rt_err_t rt_hw_sd_is_detected(void)
+{
+ return rt_pin_read(DETECT_PIN);
+}
+
+static rt_err_t rt_hw_sd_init(void)
+{
+ /* sd ldo*/
+ rt_pin_mode(LDO_PIN, PIN_MODE_OUTPUT);
+ /* sd detect */
+ rt_pin_mode(DETECT_PIN, PIN_MODE_INPUT_PULLUP);
+ /* judge we have a sd card */
+ if (rt_hw_sd_is_detected() != 0x00)
+ {
+ LOG_E("can't find sd card!");
+ return RT_ERROR;
+ }
+
+ SDCARD_Handler.Instance = SDMMC1;
+ HAL_SD_DeInit(&SDCARD_Handler);
+
+ /* if CLKDIV = 0 then SDMMC Clock frequency = SDMMC Kernel Clock
+ else SDMMC Clock frequency = SDMMC Kernel Clock / [2 * CLKDIV].
+ SDMMC Kernel Clock = 99MHz, SDMMC Clock frequency = 50MHz */
+
+ SDCARD_Handler.Init.ClockDiv = 1;
+ SDCARD_Handler.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
+ SDCARD_Handler.Init.ClockEdge = SDMMC_CLOCK_EDGE_FALLING;
+ SDCARD_Handler.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
+ SDCARD_Handler.Init.BusWide = SDMMC_BUS_WIDE_4B;
+
+ if (HAL_SD_Init(&SDCARD_Handler) != RT_EOK)
+ {
+ LOG_E("sd device init error!");
+ return RT_ERROR;
+ }
+
+ if (HAL_SD_ConfigWideBusOperation(&SDCARD_Handler, SDMMC_BUS_WIDE_4B) != RT_EOK)
+ {
+ LOG_E("sd bus config error!");
+ return RT_ERROR;
+ }
+
+ if (HAL_SD_GetCardInfo(&SDCARD_Handler, &SDCardInfo) != RT_EOK)
+ {
+ LOG_E("sd get card info error!");
+ return RT_ERROR;
+ }
+
+ rt_thread_mdelay(100);
+
+ if(HAL_SD_GetCardState(&SDCARD_Handler) != HAL_SD_CARD_TRANSFER)
+ {
+ LOG_E("sd get card state error!");
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static void rt_hw_sd_deinit(void)
+{
+ HAL_SD_DeInit(&SDCARD_Handler);
+}
+
+static rt_err_t sdcard_wait_ok(void)
+{
+ rt_uint32_t tick_start = 0;
+
+ tick_start = rt_tick_get();
+ while ((rt_tick_get() - tick_start) < SD_TIMEOUT)
+ {
+ if (HAL_SD_GetCardState(&SDCARD_Handler) == HAL_SD_CARD_TRANSFER)
+ {
+ return HAL_OK;
+ }
+ }
+ return HAL_ERROR;
+}
+
+void HAL_SD_DriveTransceiver_1_8V_Callback(FlagStatus status)
+{
+ if (status == SET)
+ {
+ rt_pin_write(LDO_PIN, PIN_HIGH);
+ }
+ else
+ {
+ rt_pin_write(LDO_PIN, PIN_LOW);
+ }
+}
+
+static rt_err_t rt_sdcard_init(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+ struct stm32_sd *sd = (struct stm32_sd *)dev;
+
+ if (rt_sem_init(&sd->sd_lock, "sdlock", 1, RT_IPC_FLAG_FIFO) != RT_EOK)
+ {
+ LOG_E("init sd lock semaphore failed\n");
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ RT_ASSERT(dev != RT_NULL);
+ return RT_EOK;
+}
+
+static rt_err_t rt_sdcard_close(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+ return RT_EOK;
+}
+
+/**
+ * @brief Reads Sector(s)
+ * @param dev : sd dev
+ * @param sector: Sector address (LBA) Data buffer to store read data
+ * @param *buffer: Data buffer to store read data
+ * @param count: Number of sectors to read (1..128)
+ * @retval DRESULT: Operation result
+ */
+
+static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t sector, void *buffer, rt_size_t count)
+{
+ RT_ASSERT(dev != RT_NULL);
+ struct stm32_sd *sd = (struct stm32_sd *)dev;
+
+ rt_uint8_t ret = RT_EOK;
+ volatile uint32_t tickstart = 0;
+ sd->read_flage = 0;
+
+ rt_memset(cache_buf, 0x00, BLOCKSIZE * count);
+
+ ret = sdcard_wait_ok();
+ if (ret != RT_EOK)
+ {
+ LOG_D("sdmmc busy!");
+ return 0;
+ }
+
+ rt_sem_take(&sd->sd_lock, RT_WAITING_FOREVER);
+ ret = HAL_SD_ReadBlocks_DMA(&SDCARD_Handler, (rt_uint8_t *)cache_buf, (uint32_t)sector, count);
+ rt_sem_release(&sd->sd_lock);
+
+ /* Wait that writing process is completed or a timeout occurs */
+ tickstart = rt_tick_get();
+ if (ret == HAL_OK)
+ {
+ while ((sd->read_flage == 0) && (rt_tick_get() - tickstart) < SD_TIMEOUT)
+ {
+ }
+ /* over time */
+ if (sd->read_flage == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ sd->read_flage = 0;
+ tickstart = rt_tick_get();
+ while ((rt_tick_get() - tickstart) < SD_TIMEOUT)
+ {
+ if (sdcard_wait_ok() == RT_EOK)
+ {
+ sd->level=rt_hw_interrupt_disable();
+ rt_memcpy((rt_uint8_t *)(buffer), cache_buf, BLOCKSIZE * count);
+ rt_hw_interrupt_enable(sd->level);
+#if defined(SDMMC_RX_DUMP)
+ rt_kprintf("\nsd rx: \n");
+ dump_hex(cache_buf, BLOCKSIZE * count);
+#endif
+ return count;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Writes block(s) to a specified address in an SD card, in DMA mode.
+ * @param dev SD device
+ * @param sector Block index from where data is to be written P
+ * @param *buffer Pointer to the buffer that will contain the data to transmit
+ * @param count Number of SD blocks to write
+ * @retval BSP status
+ */
+static rt_size_t rt_sdcard_write(rt_device_t dev, rt_off_t sector, const void *buffer, rt_size_t count)
+{
+ RT_ASSERT(dev != RT_NULL);
+ struct stm32_sd *sd = (struct stm32_sd *)dev;
+ rt_uint32_t i = 0;
+ rt_uint8_t ret = RT_EOK;
+
+ for (i = 0; i < count; i++)
+ {
+ sd->level = rt_hw_interrupt_disable();
+ rt_memset(cache_buf, 0x00, BLOCKSIZE);
+ rt_memcpy(cache_buf, (rt_uint32_t *)((uintptr_t)buffer + BLOCKSIZE * i), BLOCKSIZE);
+ rt_hw_interrupt_enable(sd->level);
+
+#if defined(SDMMC_TX_DUMP)
+ rt_kprintf("\nsd tx: \n");
+ dump_hex(cache_buf, BLOCKSIZE);
+#endif
+ ret = sdcard_wait_ok();
+ if (ret != RT_EOK)
+ {
+ LOG_D("sdmmc busy!");
+ return 0;
+ }
+ rt_completion_init(&tx_comp);
+ ret = HAL_SD_WriteBlocks_DMA(&SDCARD_Handler, (rt_uint8_t *)cache_buf, (rt_uint32_t)(sector + i), 1);
+ if (ret != HAL_OK)
+ {
+ rt_kprintf("sd write error!\n");
+ return 0;
+ }
+ rt_completion_wait(&tx_comp,RT_WAITING_FOREVER);
+
+ }
+
+ return count;
+}
+
+static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
+ {
+ struct rt_device_blk_geometry *geometry;
+
+ geometry = (struct rt_device_blk_geometry *)args;
+
+ geometry->bytes_per_sector = 512;
+ geometry->block_size = SDCARD_Handler.SdCard.BlockSize;
+ geometry->sector_count = SDCARD_Handler.SdCard.BlockNbr;
+ }
+
+ return RT_EOK;
+}
+
+void SDMMC1_IRQHandler(void)
+{
+ rt_interrupt_enter();
+
+ HAL_SD_IRQHandler(&SDCARD_Handler);
+
+ rt_interrupt_leave();
+}
+
+void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
+{
+ if (hsd->Instance == SDCARD_Handler.Instance)
+ {
+ sd_device.read_flage = 1;
+ }
+}
+
+void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
+{
+ if (hsd->Instance == SDCARD_Handler.Instance)
+ {
+ rt_completion_done(&tx_comp);
+ }
+}
+
+int rt_hw_sdcard_init(void)
+{
+ if (rt_hw_sd_init() != RT_EOK)
+ {
+ rt_hw_sd_deinit();
+ LOG_E("sdcard init failed");
+
+ return RT_ERROR;
+ }
+ /* register sdcard device */
+ sd_device.sdcard.type = RT_Device_Class_Block;
+ sd_device.sdcard.init = rt_sdcard_init;
+ sd_device.sdcard.open = rt_sdcard_open;
+ sd_device.sdcard.close = rt_sdcard_close;
+ sd_device.sdcard.read = rt_sdcard_read;
+ sd_device.sdcard.write = rt_sdcard_write;
+ sd_device.sdcard.control = rt_sdcard_control;
+
+ /* no private */
+ sd_device.sdcard.user_data = &SDCardInfo;
+
+ rt_device_register(&sd_device.sdcard, "sd_card", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+ LOG_I("sd card init success!");
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_sdcard_init);
+
+#if defined(SD_USING_DFS)
+int mnt_init(void)
+{
+ rt_device_t sd_dev = RT_NULL;
+
+ LOG_I("init sd card file system.");
+#if defined(SDMMC_RX_DUMP) || defined(SDMMC_TX_DUMP)
+ rt_thread_delay(3000);
+#else
+ rt_thread_delay(RT_TICK_PER_SECOND);
+#endif
+ sd_dev = rt_device_find("sd_card");
+ if (sd_dev == RT_NULL)
+ {
+ LOG_E("can't find sd deivce name!");
+ return RT_ERROR;
+ }
+
+ if (dfs_mount("sd_card", "/", "elm", 0, 0) != 0)
+ {
+ rt_kprintf("file system mount failed!\n");
+ }
+ else
+ {
+ rt_kprintf("file system mount success!\n");
+ }
+
+ return 0;
+}
+INIT_APP_EXPORT(mnt_init);
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sound.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sound.c
new file mode 100644
index 0000000000..b9cfae9fb2
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sound.c
@@ -0,0 +1,572 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2019-07-31 Zero-Free first implementation
+ * 2020-07-02 thread-liu Porting for STM32MP1
+ */
+
+#include "board.h"
+
+#ifdef BSP_USING_AUDIO
+#include "drv_wm8994.h"
+#include <dfs_posix.h>
+
+#define DRV_DEBUG
+#define LOG_TAG "drv.sound"
+#include <drv_log.h>
+
+#define SOUND_BUS_NAME "i2c2"
+
+#define TX_FIFO_SIZE (4096)
+#if defined(__CC_ARM) || defined(__CLANG_ARM)
+__attribute__((at(0x2FFC2000)))
+#elif defined ( __GNUC__ )
+__attribute__((at(0x2FFC2000)))
+#elif defined(__ICCARM__)
+#pragma location = 0x2FFC2000
+#endif
+static rt_uint8_t AUDIO_TX_FIFO[TX_FIFO_SIZE];
+
+struct sound_device
+{
+ struct rt_audio_device audio;
+ struct rt_audio_configure replay_config;
+ rt_device_t decoder;
+ rt_uint8_t *tx_fifo;
+ rt_uint8_t volume;
+};
+static struct sound_device snd_dev = {0};
+
+SAI_HandleTypeDef hsai_BlockA2 = {0};
+extern DMA_HandleTypeDef hdma_sai2_a;
+
+static void rt_hw_sai2a_init(void)
+{
+ hsai_BlockA2.Instance = SAI2_Block_A;
+ hsai_BlockA2.Init.Protocol = SAI_FREE_PROTOCOL;
+ hsai_BlockA2.Init.AudioMode = SAI_MODEMASTER_TX;
+ hsai_BlockA2.Init.DataSize = SAI_DATASIZE_16;
+ hsai_BlockA2.Init.FirstBit = SAI_FIRSTBIT_MSB;
+ hsai_BlockA2.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
+ hsai_BlockA2.Init.Synchro = SAI_ASYNCHRONOUS;
+ hsai_BlockA2.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
+ hsai_BlockA2.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
+ hsai_BlockA2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
+ hsai_BlockA2.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_44K;
+ hsai_BlockA2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
+ hsai_BlockA2.Init.MonoStereoMode = SAI_STEREOMODE;
+ hsai_BlockA2.Init.CompandingMode = SAI_NOCOMPANDING;
+ hsai_BlockA2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
+ hsai_BlockA2.Init.PdmInit.Activation = DISABLE;
+ hsai_BlockA2.Init.PdmInit.MicPairsNbr = 0;
+ hsai_BlockA2.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
+
+ hsai_BlockA2.FrameInit.FrameLength = 64;
+ hsai_BlockA2.FrameInit.ActiveFrameLength = 32;
+ hsai_BlockA2.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
+ hsai_BlockA2.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+ hsai_BlockA2.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
+
+ hsai_BlockA2.SlotInit.FirstBitOffset = 0;
+ hsai_BlockA2.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
+ hsai_BlockA2.SlotInit.SlotNumber = 2;
+ hsai_BlockA2.SlotInit.SlotActive = (SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1 | SAI_SLOTACTIVE_2 | SAI_SLOTACTIVE_3);
+
+ if(HAL_OK != HAL_SAI_Init(&hsai_BlockA2))
+ {
+ Error_Handler();
+ }
+ /* Enable SAI to generate clock used by audio driver */
+ __HAL_SAI_ENABLE(&hsai_BlockA2);
+}
+
+void DMA1_Stream0_IRQHandler(void)
+{
+ HAL_DMA_IRQHandler(&hdma_sai2_a);
+}
+
+void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ if (hsai == &hsai_BlockA2)
+ {
+ rt_audio_tx_complete(&snd_dev.audio);
+ }
+}
+
+void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
+{
+ if (hsai == &hsai_BlockA2)
+ {
+ rt_audio_tx_complete(&snd_dev.audio);
+ }
+}
+
+void SAIA_Frequency_Set(uint32_t frequency)
+{
+ /* Disable SAI peripheral to allow access to SAI internal registers */
+ __HAL_SAI_DISABLE(&hsai_BlockA2);
+ /* Update the SAI audio frequency configuration */
+ hsai_BlockA2.Init.AudioFrequency = frequency;
+ HAL_SAI_Init(&hsai_BlockA2);
+ /* Enable SAI peripheral to generate MCLK */
+ __HAL_SAI_ENABLE(&hsai_BlockA2);
+}
+
+void SAIA_Channels_Set(uint8_t channels)
+{
+ if (channels == 1)
+ {
+ hsai_BlockA2.Init.MonoStereoMode = SAI_MONOMODE;
+ }
+ else
+ {
+ hsai_BlockA2.Init.MonoStereoMode = SAI_STEREOMODE;
+ }
+
+ __HAL_SAI_DISABLE(&hsai_BlockA2);
+ HAL_SAI_Init(&hsai_BlockA2);
+ __HAL_SAI_ENABLE(&hsai_BlockA2);
+}
+
+/**
+ * RT-Thread Audio Device Driver Interface
+ */
+static rt_err_t sound_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+ rt_err_t result = RT_EOK;
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ switch (caps->main_type)
+ {
+ case AUDIO_TYPE_QUERY: /* qurey the types of hw_codec device */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_TYPE_QUERY:
+ caps->udata.mask = AUDIO_TYPE_OUTPUT | AUDIO_TYPE_MIXER;
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_OUTPUT: /* Provide capabilities of OUTPUT unit */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_DSP_PARAM:
+ caps->udata.config.samplerate = snd_dev->replay_config.samplerate;
+ caps->udata.config.channels = snd_dev->replay_config.channels;
+ caps->udata.config.samplebits = snd_dev->replay_config.samplebits;
+ break;
+
+ case AUDIO_DSP_SAMPLERATE:
+ caps->udata.config.samplerate = snd_dev->replay_config.samplerate;
+ break;
+
+ case AUDIO_DSP_CHANNELS:
+ caps->udata.config.channels = snd_dev->replay_config.channels;
+ break;
+
+ case AUDIO_DSP_SAMPLEBITS:
+ caps->udata.config.samplebits = snd_dev->replay_config.samplebits;
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_MIXER: /* report the Mixer Units */
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_MIXER_QUERY:
+ caps->udata.mask = AUDIO_MIXER_VOLUME;
+ break;
+
+ case AUDIO_MIXER_VOLUME:
+ rt_device_control(snd_dev->decoder, GET_VOLUME, &(caps->udata.value));
+ break;
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ return result;
+}
+
+static rt_err_t sound_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+ rt_err_t result = RT_EOK;
+ struct sound_device *snd_dev;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ switch (caps->main_type)
+ {
+ case AUDIO_TYPE_MIXER:
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_MIXER_VOLUME:
+ {
+ rt_uint8_t volume = caps->udata.value;
+
+ rt_device_control(snd_dev->decoder, SET_VOLUME, &volume);
+
+ snd_dev->volume = volume;
+
+ LOG_D("set volume %d", volume);
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ case AUDIO_TYPE_OUTPUT:
+ {
+ switch (caps->sub_type)
+ {
+ case AUDIO_DSP_PARAM:
+ {
+ /* set samplerate */
+ SAIA_Frequency_Set(caps->udata.config.samplerate);
+ /* set channels */
+ SAIA_Channels_Set(caps->udata.config.channels);
+
+ /* save configs */
+ snd_dev->replay_config.samplerate = caps->udata.config.samplerate;
+ snd_dev->replay_config.channels = caps->udata.config.channels;
+ snd_dev->replay_config.samplebits = caps->udata.config.samplebits;
+ LOG_D("set samplerate %d", snd_dev->replay_config.samplerate);
+ break;
+ }
+
+ case AUDIO_DSP_SAMPLERATE:
+ {
+ SAIA_Frequency_Set(caps->udata.config.samplerate);
+ snd_dev->replay_config.samplerate = caps->udata.config.samplerate;
+ LOG_D("set samplerate %d", snd_dev->replay_config.samplerate);
+ break;
+ }
+
+ case AUDIO_DSP_CHANNELS:
+ {
+ SAIA_Channels_Set(caps->udata.config.channels);
+ snd_dev->replay_config.channels = caps->udata.config.channels;
+ LOG_D("set channels %d", snd_dev->replay_config.channels);
+ break;
+ }
+
+ case AUDIO_DSP_SAMPLEBITS:
+ {
+ /* not support */
+ snd_dev->replay_config.samplebits = caps->udata.config.samplebits;
+ break;
+ }
+
+ default:
+ result = -RT_ERROR;
+ break;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static rt_err_t sound_init(struct rt_audio_device *audio)
+{
+ rt_err_t result = RT_EOK;
+ struct sound_device *snd_dev;
+ rt_uint16_t play_type = OUTPUT_DEVICE_HEADPHONE;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ rt_hw_sai2a_init();
+
+ /* set default params */
+ SAIA_Frequency_Set(snd_dev->replay_config.samplerate);
+ SAIA_Channels_Set(snd_dev->replay_config.channels);
+
+ /* set audio play type */
+ rt_device_control(snd_dev->decoder, SET_PLAY_TYPE, &play_type);
+ /* open lowlevel audio device */
+ rt_device_open(snd_dev->decoder, RT_DEVICE_OFLAG_WRONLY);
+ rt_device_init(snd_dev->decoder);
+ /* check device id */
+ result = rt_device_control(snd_dev->decoder, GET_ID, RT_NULL);
+ if (result != RT_EOK)
+ {
+ LOG_E("can't find low level audio device!");
+ return RT_ERROR;
+ }
+
+ return result;
+}
+
+static rt_err_t sound_start(struct rt_audio_device *audio, int stream)
+{
+ struct sound_device *snd_dev;
+ rt_uint16_t play_type = OUTPUT_DEVICE_HEADPHONE;
+
+ RT_ASSERT(audio != RT_NULL);
+ snd_dev = (struct sound_device *)audio->parent.user_data;
+
+ if (stream == AUDIO_STREAM_REPLAY)
+ {
+ LOG_D("open sound device");
+
+ rt_device_control(snd_dev->decoder, SET_PLAY_TYPE, &play_type);
+ rt_device_control(snd_dev->decoder, START_PLAY, RT_NULL);
+
+ if (HAL_SAI_Transmit_DMA(&hsai_BlockA2, snd_dev->tx_fifo, TX_FIFO_SIZE / 2) != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t sound_stop(struct rt_audio_device *audio, int stream)
+{
+ struct sound_device *device;
+ RT_ASSERT(audio != RT_NULL);
+ device = (struct sound_device *)audio->parent.user_data;
+
+ if (stream == AUDIO_STREAM_REPLAY)
+ {
+ HAL_SAI_DMAStop(&hsai_BlockA2);
+
+ rt_device_close(device->decoder);
+
+ LOG_D("close sound device");
+ }
+
+ return RT_EOK;
+}
+
+static void sound_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info)
+{
+ struct sound_device *device;
+
+ RT_ASSERT(audio != RT_NULL);
+ device = (struct sound_device *)audio->parent.user_data;
+
+ info->buffer = device->tx_fifo;
+ info->total_size = TX_FIFO_SIZE;
+ info->block_size = TX_FIFO_SIZE / 2;
+ info->block_count = 2;
+}
+
+static struct rt_audio_ops snd_ops =
+{
+ .getcaps = sound_getcaps,
+ .configure = sound_configure,
+ .init = sound_init,
+ .start = sound_start,
+ .stop = sound_stop,
+ .transmit = RT_NULL,
+ .buffer_info = sound_buffer_info,
+};
+
+int rt_hw_sound_init(void)
+{
+ rt_err_t result = RT_EOK;
+ struct rt_device *device = RT_NULL;
+
+ rt_memset(AUDIO_TX_FIFO, 0, TX_FIFO_SIZE);
+ snd_dev.tx_fifo = AUDIO_TX_FIFO;
+
+ /* init default configuration */
+ snd_dev.replay_config.samplerate = 44100;
+ snd_dev.replay_config.channels = 2;
+ snd_dev.replay_config.samplebits = 16;
+ snd_dev.volume = 55;
+
+ /* find lowlevel decoder device*/
+ snd_dev.decoder = rt_device_find("decoder");
+ if (snd_dev.decoder == RT_NULL)
+ {
+ LOG_E("cant't find lowlevel decoder deivce!");
+ return RT_ERROR;
+ }
+
+ /* register sound device */
+ snd_dev.audio.ops = &snd_ops;
+ result = rt_audio_register(&snd_dev.audio, "sound0", RT_DEVICE_FLAG_WRONLY, &snd_dev);
+ /* check sound device register success or not */
+ if (result != RT_EOK)
+ {
+ device = &(snd_dev.audio.parent);
+ rt_device_unregister(device);
+ LOG_E("sound device init error!");
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+INIT_APP_EXPORT(rt_hw_sound_init);
+
+
+struct RIFF_HEADER_DEF
+{
+ char riff_id[4]; // 'R','I','F','F'
+ uint32_t riff_size;
+ char riff_format[4]; // 'W','A','V','E'
+};
+
+struct WAVE_FORMAT_DEF
+{
+ uint16_t FormatTag;
+ uint16_t Channels;
+ uint32_t SamplesPerSec;
+ uint32_t AvgBytesPerSec;
+ uint16_t BlockAlign;
+ uint16_t BitsPerSample;
+};
+
+struct FMT_BLOCK_DEF
+{
+ char fmt_id[4]; // 'f','m','t',' '
+ uint32_t fmt_size;
+ struct WAVE_FORMAT_DEF wav_format;
+};
+
+struct DATA_BLOCK_DEF
+{
+ char data_id[4]; // 'R','I','F','F'
+ uint32_t data_size;
+};
+
+struct wav_info
+{
+ struct RIFF_HEADER_DEF header;
+ struct FMT_BLOCK_DEF fmt_block;
+ struct DATA_BLOCK_DEF data_block;
+};
+
+int wavplay_sample(int argc, char **argv)
+{
+#define BUFSZ 1024
+#define SOUND_DEVICE_NAME "sound0"
+static rt_device_t sound_dev;
+
+ int fd = -1;
+ uint8_t *buffer = NULL;
+ struct wav_info *info = NULL;
+ struct rt_audio_caps caps = {0};
+
+ if (argc != 2)
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("wavplay_sample song.wav\n");
+ return 0;
+ }
+
+ fd = open(argv[1], O_WRONLY);
+ if (fd < 0)
+ {
+ rt_kprintf("open file failed!\n");
+ goto __exit;
+ }
+
+ buffer = rt_malloc(BUFSZ);
+ if (buffer == RT_NULL)
+ goto __exit;
+
+ info = (struct wav_info *) rt_malloc(sizeof * info);
+ if (info == RT_NULL)
+ goto __exit;
+
+ if (read(fd, &(info->header), sizeof(struct RIFF_HEADER_DEF)) <= 0)
+ goto __exit;
+ if (read(fd, &(info->fmt_block), sizeof(struct FMT_BLOCK_DEF)) <= 0)
+ goto __exit;
+ if (read(fd, &(info->data_block), sizeof(struct DATA_BLOCK_DEF)) <= 0)
+ goto __exit;
+
+ rt_kprintf("wav information:\n");
+ rt_kprintf("samplerate %d\n", info->fmt_block.wav_format.SamplesPerSec);
+ rt_kprintf("channel %d\n", info->fmt_block.wav_format.Channels);
+
+ sound_dev = rt_device_find(SOUND_DEVICE_NAME);
+
+ rt_device_open(sound_dev, RT_DEVICE_OFLAG_WRONLY);
+
+ caps.main_type = AUDIO_TYPE_OUTPUT;
+ caps.sub_type = AUDIO_DSP_PARAM;
+ caps.udata.config.samplerate = info->fmt_block.wav_format.SamplesPerSec;
+ caps.udata.config.channels = info->fmt_block.wav_format.Channels;
+ caps.udata.config.samplebits = 16;
+ rt_device_control(sound_dev, AUDIO_CTL_CONFIGURE, &caps);
+
+ while (1)
+ {
+ int length;
+
+ length = read(fd, buffer, BUFSZ);
+
+ if (length <= 0)
+ break;
+
+ rt_device_write(sound_dev, 0, buffer, length);
+ }
+
+ rt_device_close(sound_dev);
+
+__exit:
+
+ if (fd >= 0)
+ close(fd);
+
+ if (buffer)
+ rt_free(buffer);
+
+ if (info)
+ rt_free(info);
+
+ return 0;
+}
+
+MSH_CMD_EXPORT(wavplay_sample, play wav file);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_spdifrx.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_spdifrx.c
new file mode 100644
index 0000000000..6230b49a4f
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_spdifrx.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-28 thread-liu the first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_SPDIFRX)
+#include "drv_spdifrx.h"
+
+#define DRV_DEBUG
+#define LOG_TAG "drv.spdifrx"
+#include <drv_log.h>
+
+struct stm32_spdifrx
+{
+ struct rt_device dev;
+ SPDIFRX_HandleTypeDef spdifrx;
+ SAI_HandleTypeDef sai4;
+ volatile rt_uint8_t complate;
+};
+static struct stm32_spdifrx rt_spdifrx = {0};
+
+extern DMA_HandleTypeDef hdma_spdifrx_rx;
+extern DMA_HandleTypeDef hdma_sai4_a;
+
+static void sai4a_init(SAI_HandleTypeDef* sai)
+{
+ sai->Instance = SAI4_Block_A;
+ sai->Init.Protocol = SAI_SPDIF_PROTOCOL;
+ sai->Init.AudioMode = SAI_MODEMASTER_TX;
+ sai->Init.Synchro = SAI_ASYNCHRONOUS;
+ sai->Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
+ sai->Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
+ sai->Init.AudioFrequency = SAI_AUDIO_FREQUENCY_96K;
+ sai->Init.MonoStereoMode = SAI_STEREOMODE;
+ sai->Init.CompandingMode = SAI_NOCOMPANDING;
+ sai->Init.PdmInit.Activation = DISABLE;
+ sai->Init.PdmInit.MicPairsNbr = 0;
+ sai->Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
+ sai->Init.DataSize = SAI_DATASIZE_24;
+ sai->Init.FirstBit = SAI_FIRSTBIT_MSB;
+ sai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
+
+ sai->FrameInit.FrameLength = 64;
+ sai->FrameInit.ActiveFrameLength = 32;
+ sai->FrameInit.FSDefinition = SAI_FS_STARTFRAME;
+ sai->FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
+ sai->FrameInit.FSOffset = SAI_FS_FIRSTBIT;
+
+ sai->SlotInit.FirstBitOffset = 0;
+ sai->SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
+ sai->SlotInit.SlotNumber = 4;
+ sai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL;
+
+ if (HAL_SAI_Init(sai) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+void DMA1_Stream7_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_DMA_IRQHandler(&hdma_spdifrx_rx);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void DMA1_Stream2_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_DMA_IRQHandler(&hdma_sai4_a);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void HAL_SPDIFRX_RxCpltCallback(SPDIFRX_HandleTypeDef *hspdif)
+{
+ rt_spdifrx.complate = SET;
+}
+
+static rt_err_t _init(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+ struct stm32_spdifrx *device = (struct stm32_spdifrx *)dev;
+
+ device->spdifrx.Instance = SPDIFRX;
+ HAL_SPDIFRX_DeInit(&device->spdifrx);
+
+ device->spdifrx.Init.InputSelection = SPDIFRX_INPUT_IN1;
+ device->spdifrx.Init.Retries = SPDIFRX_MAXRETRIES_15;
+ device->spdifrx.Init.WaitForActivity = SPDIFRX_WAITFORACTIVITY_ON;
+ device->spdifrx.Init.ChannelSelection = SPDIFRX_CHANNEL_A;
+ device->spdifrx.Init.DataFormat = SPDIFRX_DATAFORMAT_MSB;
+ device->spdifrx.Init.StereoMode = SPDIFRX_STEREOMODE_ENABLE;
+ device->spdifrx.Init.PreambleTypeMask = SPDIFRX_PREAMBLETYPEMASK_ON;
+ device->spdifrx.Init.ChannelStatusMask = SPDIFRX_CHANNELSTATUS_ON;
+
+ if (HAL_SPDIFRX_Init(&device->spdifrx) != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+
+ sai4a_init(&device->sai4);
+
+ rt_spdifrx.complate = RESET;
+
+ return RT_EOK;
+}
+
+static rt_err_t _open(rt_device_t dev, rt_uint16_t oflag)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t _close(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_size_t _read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ rt_uint32_t tickstart = 0;
+
+ RT_ASSERT(dev != RT_NULL);
+ struct stm32_spdifrx *device = (struct stm32_spdifrx *)dev;
+ rt_err_t result = RT_EOK;
+
+ result = HAL_SPDIFRX_ReceiveDataFlow_DMA(&device->spdifrx, (uint32_t *)buffer, size);
+ if (result != HAL_OK)
+ {
+ return 0;
+ }
+
+ if(device->spdifrx.ErrorCode != HAL_SPDIFRX_ERROR_NONE)
+ {
+ return 0;
+ }
+
+ tickstart = rt_tick_get();
+ while (rt_spdifrx.complate == RESET)
+ {
+ if (rt_tick_get() - tickstart > 0xFFFF)
+ {
+ return 0;
+ }
+ }
+
+ rt_spdifrx.complate = RESET;
+
+ return size;
+}
+
+static rt_size_t _write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ struct stm32_spdifrx *device = (struct stm32_spdifrx *)dev;
+ rt_err_t result = RT_EOK;
+
+ result = HAL_SAI_Transmit_DMA(&device->sai4, (rt_uint8_t *)buffer, size);
+ if (result != HAL_OK)
+ {
+ return RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _control(rt_device_t dev, int cmd, void *args)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+int spdifrx_init(void)
+{
+ rt_spdifrx.dev.type = RT_Device_Class_Miscellaneous;
+ rt_spdifrx.dev.init = _init;
+ rt_spdifrx.dev.open = _open;
+ rt_spdifrx.dev.close = _close;
+ rt_spdifrx.dev.read = _read;
+ rt_spdifrx.dev.write = _write;
+ rt_spdifrx.dev.control = _control;
+ rt_spdifrx.dev.user_data = RT_NULL;
+
+ rt_device_register(&rt_spdifrx.dev, "spdifrx", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+ rt_device_init(&rt_spdifrx.dev);
+
+ LOG_I("spdifrx init success!");
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(spdifrx_init);
+
+#ifdef FINSH_USING_MSH
+#include <finsh.h>
+
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
+{
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%08X: ", i);
+
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%02X ", buf[i + j]);
+ else
+ rt_kprintf(" ");
+ rt_kprintf(" ");
+
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ rt_kprintf("\n");
+ }
+}
+
+static int spdifrx_sample(int argc, char **argv)
+{
+ extern SAI_HandleTypeDef hsai_block4_a;
+
+ if (argc != 1)
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("spdifrx_sample\n");
+ return -1;
+ }
+
+ /* 16 bit Data Buffer for Transmission */
+ static rt_uint16_t tx_buffer[64] = {
+ 0x5152, 0x5354, 0x5556, 0x5758, 0x595A, 0x5B5C, 0x5D5E, 0x5F60,
+ 0x6162, 0x6364, 0x6566, 0x6768, 0x696A, 0x6B6C, 0x6D6E, 0x6F70,
+ 0x7172, 0x7374, 0x7576, 0x7778, 0x797A, 0x7B7C, 0x7D7E, 0x7F80,
+ 0x8182, 0x8384, 0x8586, 0x8788, 0x898A, 0x8B8C, 0x8D8E, 0x8F90,
+ 0x5152, 0x5354, 0x5556, 0x5758, 0x595A, 0x5B5C, 0x5D5E, 0x5F60,
+ 0x6162, 0x6364, 0x6566, 0x6768, 0x696A, 0x6B6C, 0x6D6E, 0x6F70,
+ 0x7172, 0x7374, 0x7576, 0x7778, 0x797A, 0x7B7C, 0x7D7E, 0x7F80,
+ 0x8182, 0x8384, 0x8586, 0x8788, 0x898A, 0x8B8C, 0x8D8E, 0x8F90};
+
+ static rt_uint32_t *rx_buffer = NULL;
+ rt_uint8_t size = 64;
+ struct rt_device *dev = RT_NULL;
+
+ dev = rt_device_find("spdifrx");
+ if (dev == RT_NULL)
+ {
+ rt_kprintf("can't find spdifrx device!\n");
+ }
+
+ rt_device_open(dev, RT_DEVICE_OFLAG_RDWR);
+
+ rt_kprintf("spdifrx test tx data : \n");
+ dump_hex((rt_uint8_t *)tx_buffer, size);
+
+ rx_buffer = (rt_uint32_t *)rt_malloc(size);
+
+ rt_device_write(dev, 0, tx_buffer, size);
+ rt_device_read(dev, 0, rx_buffer, size);
+
+ /* Compare the received data with the expected one */
+ while (size--)
+ {
+ if (((rx_buffer[size] & 0x00ffff00) >> 8) != (tx_buffer[size]))
+ {
+ rt_kprintf("spdirex loopback mode test failed!\n");
+
+ return RT_ERROR;
+ }
+ }
+
+ rt_kprintf("spdifrx rx : \n");
+ dump_hex((rt_uint8_t *)rx_buffer, size);
+
+ rt_kprintf("spdirex loopback mode test success!\n");
+
+ return RT_EOK;
+}
+MSH_CMD_EXPORT(spdifrx_sample, spdifrx loopback test);
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_spdifrx.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_spdifrx.h
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_spdifrx.h
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wm8994.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wm8994.c
new file mode 100644
index 0000000000..b162d76b0f
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wm8994.c
@@ -0,0 +1,782 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-02 thread-liu first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_AUDIO)
+#include <drv_wm8994.h>
+
+#define DRV_DEBUG
+#define LOG_TAG "drv.wm8994"
+#include <drv_log.h>
+
+#define CHIP_ADDRESS 0x1B /* wm8994 address */
+#define I2C_NAME "i2c2"
+
+struct wm8994_dev
+{
+ struct rt_device dev;
+ struct rt_i2c_bus_device *i2c_bus;
+ rt_uint16_t id;
+ rt_uint16_t type;
+};
+static struct wm8994_dev rt_wm8994 = {0};
+
+/* i2c read reg */
+static rt_err_t read_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint8_t len, rt_uint8_t *buf)
+{
+ struct rt_i2c_msg msg[2] = {0, 0};
+ static rt_uint8_t i2c_reg[2] = {0, 0};
+
+ RT_ASSERT(bus != RT_NULL);
+
+ i2c_reg[0] = ((uint16_t)(reg >> 8) & 0xFF);
+ i2c_reg[1] = ((uint16_t)(reg) & 0xFF);
+
+ msg[0].addr = CHIP_ADDRESS;
+ msg[0].flags = RT_I2C_WR;
+ msg[0].buf = i2c_reg;
+ msg[0].len = 2;
+
+ msg[1].addr = CHIP_ADDRESS;
+ msg[1].flags = RT_I2C_RD;
+ msg[1].len = len;
+ msg[1].buf = buf;
+
+ if (rt_i2c_transfer(bus, msg, 2) == 2)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* i2c write reg */
+static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg, rt_uint16_t data)
+{
+ rt_uint8_t buf[4];
+ struct rt_i2c_msg msgs;
+
+ RT_ASSERT(bus != RT_NULL);
+
+ buf[0] = ((uint16_t)(reg >> 8) & 0xFF);
+ buf[1] = ((uint16_t)(reg) & 0xFF);
+
+ buf[2] = ((uint16_t)(data >> 8) & 0xFF);
+ buf[3] = ((uint16_t)(data) & 0xFF);
+
+ msgs.addr = CHIP_ADDRESS;
+ msgs.flags = RT_I2C_WR;
+ msgs.buf = buf;
+ msgs.len = 4;
+
+ if (rt_i2c_transfer(bus, &msgs, 1) == 1)
+ {
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+static rt_err_t wm8994_set_output_mode(struct rt_i2c_bus_device *bus, rt_uint16_t mode)
+{
+ switch (mode & 0x000F)
+ {
+ case OUTPUT_DEVICE_SPEAKER:
+ /* Enable DAC1 (Left), Enable DAC1 (Right),
+ * Disable DAC2 (Left), Disable DAC2 (Right) */
+ write_reg(bus, 0x0005, 0x0C0C);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+ write_reg(bus, 0x0601, 0x0000);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+ write_reg(bus, 0x0602, 0x0000);
+
+ /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ write_reg(bus, 0x0604, 0x0002);
+
+ /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ write_reg(bus, 0x0605, 0x0002);
+ break;
+
+ case OUTPUT_DEVICE_HEADPHONE:
+ /* Disable DAC1 (Left), Disable DAC1 (Right),
+ Enable DAC2 (Left), Enable DAC2 (Right)*/
+ write_reg(bus, 0x05, 0x0303);
+
+ /* Enable the AIF1 Timeslot 0 (Left) to DAC 1 (Left) mixer path */
+ write_reg(bus, 0x0601, 0x01);
+
+ /* Enable the AIF1 Timeslot 0 (Right) to DAC 1 (Right) mixer path */
+ write_reg(bus, 0x0602, 0x01);
+
+ /* Disable the AIF1 Timeslot 1 (Left) to DAC 2 (Left) mixer path */
+ write_reg(bus, 0x0604, 0x00);
+
+ /* Disable the AIF1 Timeslot 1 (Right) to DAC 2 (Right) mixer path */
+ write_reg(bus, 0x0605, 0x00);
+ break;
+
+ case OUTPUT_DEVICE_BOTH:
+ default:
+ break;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t wm8994_set_input_mode(struct rt_i2c_bus_device *bus, rt_uint16_t mode)
+{
+ switch (mode & 0x01F0)
+ {
+ case INPUT_DEVICE_DIGITAL_MICROPHONE_2:
+ /* Enable AIF1ADC2 (Left), Enable AIF1ADC2 (Right)
+ * Enable DMICDAT2 (Left), Enable DMICDAT2 (Right)
+ * Enable Left ADC, Enable Right ADC */
+ write_reg(bus, 0x04, 0x0C30);
+
+ /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
+ write_reg(bus, 0x0450, 0x00DB);
+
+ /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
+ write_reg(bus, 0x02, 0x6000);
+
+ /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
+ write_reg(bus, 0x0608, 0x0002);
+
+ /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
+ write_reg(bus, 0x0609, 0x0002);
+
+ /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC2 signal detect */
+ write_reg(bus, 0x0700, 0x000E);
+ break;
+
+ case INPUT_DEVICE_INPUT_LINE_1:
+ /* IN1LN_TO_IN1L, IN1LP_TO_VMID, IN1RN_TO_IN1R, IN1RP_TO_VMID */
+ write_reg(bus, 0x28, 0x0011);
+
+ /* Disable mute on IN1L_TO_MIXINL and +30dB on IN1L PGA output */
+ write_reg(bus, 0x29, 0x0035);
+
+ /* Disable mute on IN1R_TO_MIXINL, Gain = +30dB */
+ write_reg(bus, 0x2A, 0x0035);
+
+ /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
+ * Enable Left ADC, Enable Right ADC */
+ write_reg(bus, 0x04, 0x0303);
+
+ /* Enable AIF1 DRC1 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
+ write_reg(bus, 0x0440, 0x00DB);
+
+ /* Enable IN1L and IN1R, Disable IN2L and IN2R, Enable Thermal sensor & shutdown */
+ write_reg(bus, 0x02, 0x6350);
+
+ /* Enable the ADCL(Left) to AIF1 Timeslot 0 (Left) mixer path */
+ write_reg(bus, 0x0606, 0x0002);
+
+ /* Enable the ADCR(Right) to AIF1 Timeslot 0 (Right) mixer path */
+ write_reg(bus, 0x0607, 0x0002);
+
+ /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
+ write_reg(bus, 0x0700, 0x000D);
+ break;
+
+ case INPUT_DEVICE_DIGITAL_MICROPHONE_1:
+ /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
+ * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
+ * Enable Left ADC, Enable Right ADC */
+ write_reg(bus, 0x04, 0x030C);
+
+ /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
+ write_reg(bus, 0x0440, 0x00DB);
+
+ /* Disable IN1L, IN1R, IN2L, IN2R, Enable Thermal sensor & shutdown */
+ write_reg(bus, 0x02, 0x6350);
+
+ /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
+ write_reg(bus, 0x0606, 0x0002);
+
+ /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
+ write_reg(bus, 0x0607, 0x0002);
+
+ /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
+ write_reg(bus, 0x0700, 0x000D);
+ break;
+
+ case INPUT_DEVICE_DIGITAL_MIC1_MIC2:
+ /* Enable AIF1ADC1 (Left), Enable AIF1ADC1 (Right)
+ * Enable DMICDAT1 (Left), Enable DMICDAT1 (Right)
+ * Enable Left ADC, Enable Right ADC */
+ write_reg(bus, 0x04, 0x0F3C);
+
+ /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC2 Left/Right Timeslot 1 */
+ write_reg(bus, 0x0450, 0x00DB);
+
+ /* Enable AIF1 DRC2 Signal Detect & DRC in AIF1ADC1 Left/Right Timeslot 0 */
+ write_reg(bus, 0x0440, 0x00DB);
+
+ /* Disable IN1L, IN1R, Enable IN2L, IN2R, Thermal sensor & shutdown */
+ write_reg(bus, 0x02, 0x63A0);
+
+ /* Enable the DMIC2(Left) to AIF1 Timeslot 0 (Left) mixer path */
+ write_reg(bus, 0x0606, 0x0002);
+
+ /* Enable the DMIC2(Right) to AIF1 Timeslot 0 (Right) mixer path */
+ write_reg(bus, 0x0607, 0x0002);
+
+ /* Enable the DMIC2(Left) to AIF1 Timeslot 1 (Left) mixer path */
+ write_reg(bus, 0x0608, 0x0002);
+
+ /* Enable the DMIC2(Right) to AIF1 Timeslot 1 (Right) mixer path */
+ write_reg(bus, 0x0609, 0x0002);
+
+ /* GPIO1 pin configuration GP1_DIR = output, GP1_FN = AIF1 DRC1 signal detect */
+ write_reg(bus, 0x0700, 0x000D);
+ break;
+
+ case INPUT_DEVICE_INPUT_LINE_2:
+ default:
+ /* Actually, no other input devices supported */
+ break;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _wm8994_init(struct wm8994_dev *dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ /* wm8994 Errata Work-Arounds */
+ write_reg(dev->i2c_bus, 0x0102, 0x0003);
+ write_reg(dev->i2c_bus, 0x0817, 0x0000);
+ write_reg(dev->i2c_bus, 0x0102, 0x0000);
+
+ /* Enable VMID soft start (fast), Start-up Bias Current Enabled */
+ write_reg(dev->i2c_bus, 0x0039, 0x006C);
+
+ /* Enable bias generator, Enable VMID */
+ if ((dev->type & 0x01F0) != 0)
+ {
+ /* audio input */
+ write_reg(dev->i2c_bus, 0x0001, 0x0013);
+ }
+ else
+ {
+ /* audio output */
+ write_reg(dev->i2c_bus, 0x0001, 0x0003);
+ }
+ rt_thread_mdelay(50);
+
+ if ((dev->type & 0x000F) != 0 )
+ {
+ /* Path Configurations for output */
+ wm8994_set_output_mode(dev->i2c_bus, dev->type);
+ }
+ if ((dev->type & 0x01F0) != 0 )
+ {
+ /* Path Configurations for input */
+ wm8994_set_input_mode(dev->i2c_bus, dev->type);
+ }
+
+ if (dev->type & INPUT_DEVICE_DIGITAL_MIC1_MIC2)
+ {
+ /* AIF1 Word Length = 16-bits, AIF1 Format = DSP mode */
+ write_reg(dev->i2c_bus, 0x0300, 0x4018);
+ }
+ else
+ {
+ /* AIF1 Word Length = 16-bits, AIF1 Format = I2S (Default Register Value) */
+ write_reg(dev->i2c_bus, 0x0300, 0x4010);
+ }
+
+ /* slave mode */
+ write_reg(dev->i2c_bus, 0x0302, 0x0000);
+
+ /* Enable the DSP processing clock for AIF1, Enable the core clock */
+ write_reg(dev->i2c_bus, 0x0208, 0x000A);
+
+ /* Enable AIF1 Clock, AIF1 Clock Source = MCLK1 pin */
+ write_reg(dev->i2c_bus, 0x0200, 0x0001);
+
+ /* Audio output selected */
+ if ((dev->type & 0x000F) != 0 )
+ {
+ if (dev->type & OUTPUT_DEVICE_HEADPHONE)
+ {
+ /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
+ write_reg(dev->i2c_bus, 0x2D, 0x0100);
+
+ /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
+ write_reg(dev->i2c_bus, 0x2E, 0x0100);
+
+ /* Startup sequence for Headphone */
+ write_reg(dev->i2c_bus, 0x0110, 0x8100);
+
+ rt_thread_mdelay(300);
+
+ /* Soft un-Mute the AIF1 Timeslot 0 DAC1 path L&R */
+ write_reg(dev->i2c_bus, 0x0420, 0x0000);
+ }
+
+ /* Enable SPKRVOL PGA, Enable SPKMIXR, Enable SPKLVOL PGA, Enable SPKMIXL */
+ write_reg(dev->i2c_bus, 0x03, 0x0300);
+
+ /* Left Speaker Mixer Volume = 0dB */
+ write_reg(dev->i2c_bus, 0x22, 0x0000);
+
+ /* Speaker output mode = Class D, Right Speaker Mixer Volume = 0dB ((0x23, 0x0100) = class AB)*/
+ write_reg(dev->i2c_bus, 0x23, 0x0000);
+
+ /* Unmute DAC2 (Left) to Left Speaker Mixer (SPKMIXL) path,
+ Unmute DAC2 (Right) to Right Speaker Mixer (SPKMIXR) path */
+ write_reg(dev->i2c_bus, 0x36, 0x0300);
+
+ /* Enable bias generator, Enable VMID, Enable SPKOUTL, Enable SPKOUTR */
+ write_reg(dev->i2c_bus, 0x01, 0x3003);
+
+ /* Headphone/Speaker Enable */
+
+ if (dev->type & INPUT_DEVICE_DIGITAL_MIC1_MIC2)
+ {
+ /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslots 0 and 1 */
+ write_reg(dev->i2c_bus, 0x51, 0x0205);
+ }
+ else
+ {
+ /* Enable Class W, Class W Envelope Tracking = AIF1 Timeslot 0 */
+ write_reg(dev->i2c_bus, 0x51, 0x0005);
+ }
+
+ /* Enable bias generator, Enable VMID, Enable HPOUT1 (Left) and Enable HPOUT1 (Right) input stages */
+ /* idem for Speaker */
+ write_reg(dev->i2c_bus, 0x01, 0x3303);
+
+ /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate stages */
+ write_reg(dev->i2c_bus, 0x60, 0x0022);
+
+ /* Enable Charge Pump */
+ write_reg(dev->i2c_bus, 0x4C, 0x9F25);
+
+ /* Add Delay */
+ rt_thread_mdelay(15);
+
+ /* Select DAC1 (Left) to Left Headphone Output PGA (HPOUT1LVOL) path */
+ write_reg(dev->i2c_bus, 0x2D, 0x0001);
+
+ /* Select DAC1 (Right) to Right Headphone Output PGA (HPOUT1RVOL) path */
+ write_reg(dev->i2c_bus, 0x2E, 0x0001);
+
+ /* Enable Left Output Mixer (MIXOUTL), Enable Right Output Mixer (MIXOUTR) */
+ /* idem for SPKOUTL and SPKOUTR */
+ write_reg(dev->i2c_bus, 0x03, 0x0330);
+
+ /* Enable DC Servo and trigger start-up mode on left and right channels */
+ write_reg(dev->i2c_bus, 0x54, 0x0033);
+
+ /* Add Delay */
+ rt_thread_mdelay(200);
+
+ /* Enable HPOUT1 (Left) and HPOUT1 (Right) intermediate and output stages. Remove clamps */
+ write_reg(dev->i2c_bus, 0x60, 0x00EE);
+
+ /* Unmute DAC 1 (Left) */
+ write_reg(dev->i2c_bus, 0x0610, 0x00C0);
+
+ /* Unmute DAC 1 (Right) */
+ write_reg(dev->i2c_bus, 0x0611, 0x00C0);
+
+ /* Unmute the AIF1 Timeslot 0 DAC path */
+ write_reg(dev->i2c_bus, 0x0420, 0x0000);
+
+ /* Unmute DAC 2 (Left) */
+ write_reg(dev->i2c_bus, 0x0612, 0x00C0);
+
+ /* Unmute DAC 2 (Right) */
+ write_reg(dev->i2c_bus, 0x0613, 0x00C0);
+
+ /* Unmute the AIF1 Timeslot 1 DAC2 path */
+ write_reg(dev->i2c_bus, 0x0422, 0x0000);
+
+ }
+
+ /* Audio input selected */
+ if ((dev->type & 0x01F0) != 0 )
+ {
+ if ((dev->type & INPUT_DEVICE_DIGITAL_MICROPHONE_1) || (dev->type & INPUT_DEVICE_DIGITAL_MICROPHONE_2))
+ {
+ /* Enable Microphone bias 1 generator, Enable VMID */
+ write_reg(dev->i2c_bus, 0x01, 0x0013);
+
+ /* ADC oversample enable */
+ write_reg(dev->i2c_bus, 0x0620, 0x0002);
+
+ /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
+ write_reg(dev->i2c_bus, 0x0411, 0x3800);
+ }
+ else if (dev->type & INPUT_DEVICE_DIGITAL_MIC1_MIC2)
+ {
+ /* Enable Microphone bias 1 generator, Enable VMID */
+ write_reg(dev->i2c_bus, 0x01, 0x0013);
+
+ /* ADC oversample enable */
+ write_reg(dev->i2c_bus, 0x0620, 0x0002);
+
+ /* AIF ADC1 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
+ write_reg(dev->i2c_bus, 0x0410, 0x1800);
+
+ /* AIF ADC2 HPF enable, HPF cut = voice mode 1 fc=127Hz at fs=8kHz */
+ write_reg(dev->i2c_bus, 0x0411, 0x1800);
+ }
+ else if ((dev->type & INPUT_DEVICE_INPUT_LINE_1) || (dev->type & INPUT_DEVICE_INPUT_LINE_2))
+ {
+
+ /* Disable mute on IN1L, IN1L Volume = +0dB */
+ write_reg(dev->i2c_bus, 0x18, 0x000B);
+
+ /* Disable mute on IN1R, IN1R Volume = +0dB */
+ write_reg(dev->i2c_bus, 0x1A, 0x000B);
+
+ /* AIF ADC1 HPF enable, HPF cut = hifi mode fc=4Hz at fs=48kHz */
+ write_reg(dev->i2c_bus, 0x0410, 0x1800);
+ }
+ }
+
+ /* Return communication control value */
+ return RT_EOK;
+
+}
+
+static rt_err_t _read_id(struct rt_i2c_bus_device *bus, rt_uint16_t *id)
+{
+ rt_uint8_t read_value[2];
+
+ read_reg(bus, 0x0000, 2, read_value);
+ *id = ((uint16_t)(read_value[0] << 8) & 0xFF00);
+ *id |= ((uint16_t)(read_value[1])& 0x00FF);
+
+ if (*id != WM8994_ID)
+ {
+ LOG_E("error id: 0x%04x", *id);
+ return RT_ERROR;
+ }
+
+ LOG_I("wm8994 init success, id: %04x", *id);
+
+ return RT_EOK;
+}
+
+static rt_err_t _set_mute(struct rt_i2c_bus_device *bus, uint32_t cmd)
+{
+ /* Set the Mute mode */
+ if (cmd == AUDIO_MUTE_ON)
+ {
+ /* Soft Mute the AIF1 Timeslot 0 DAC1 path L&R */
+ write_reg(bus, 0x420, 0x0200);
+
+ /* Soft Mute the AIF1 Timeslot 1 DAC2 path L&R */
+ write_reg(bus, 0x422, 0x0200);
+ }
+ else /* AUDIO_MUTE_OFF Disable the Mute */
+ {
+ /* Unmute the AIF1 Timeslot 0 DAC1 path L&R */
+ write_reg(bus, 0x420, 0x0010);
+
+ /* Unmute the AIF1 Timeslot 1 DAC2 path L&R */
+ write_reg(bus, 0x422, 0x0010);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _play(struct rt_i2c_bus_device *bus)
+{
+ _set_mute(bus, AUDIO_MUTE_OFF);
+
+ return RT_EOK;
+}
+
+static rt_err_t _set_volume(struct rt_i2c_bus_device *bus, rt_uint16_t type, rt_uint8_t volume)
+{
+ rt_uint8_t convertedvol = VOLUME_CONVERT(volume);
+
+ if (type & 0x000F)
+ {
+ /* Output volume */
+ if(convertedvol > 0x3E)
+ {
+ /* Unmute audio codec */
+ _set_mute(bus, AUDIO_MUTE_OFF);
+
+ /* Left Headphone Volume */
+ write_reg(bus, 0x1C, 0x3F | 0x140);
+
+ /* Right Headphone Volume */
+ write_reg(bus, 0x1D, 0x3F | 0x140);
+
+ /* Left Speaker Volume */
+ write_reg(bus, 0x26, 0x3F | 0x140);
+
+ /* Right Speaker Volume */
+ write_reg(bus, 0x27, 0x3F | 0x140);
+ }
+ else if (volume == 0)
+ {
+ /* Mute audio codec */
+ _set_mute(bus, AUDIO_MUTE_ON);
+ }
+ else
+ {
+ /* Unmute audio codec */
+ _set_mute(bus, AUDIO_MUTE_OFF);
+
+ /* Left Headphone Volume */
+ write_reg(bus, 0x1C, convertedvol | 0x140);
+
+ /* Right Headphone Volume */
+ write_reg(bus, 0x1D, convertedvol | 0x140);
+
+ /* Left Speaker Volume */
+ write_reg(bus, 0x26, convertedvol | 0x140);
+
+ /* Right Speaker Volume */
+ write_reg(bus, 0x27, convertedvol | 0x140);
+ }
+ }
+ /* Input volume */
+ else
+ {
+ convertedvol = VOLUME_IN_CONVERT(volume);
+
+ /* Left AIF1 ADC1 volume */
+ write_reg(bus, 0x400, convertedvol | 0x100);
+
+ /* Right AIF1 ADC1 volume */
+ write_reg(bus, 0x401, convertedvol | 0x100);
+
+ /* Left AIF1 ADC2 volume */
+ write_reg(bus, 0x404, convertedvol | 0x100);
+
+ /* Right AIF1 ADC2 volume */
+ write_reg(bus, 0x405, convertedvol | 0x100);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _get_volume(struct rt_i2c_bus_device *bus, rt_uint32_t *value)
+{
+ rt_uint8_t read_value[2];
+
+ read_reg(bus, 0x001C, 2, read_value);
+
+ *value = ((uint16_t)(read_value[0] << 8) & 0xFF00);
+ *value |= ((uint16_t)(read_value[1])& 0x00FF);
+
+ return RT_EOK;
+}
+
+static rt_err_t _set_frequency(struct rt_i2c_bus_device *bus, rt_uint32_t freq)
+{
+ switch (freq)
+ {
+ case AUDIO_FREQUENCY_8K:
+ write_reg(bus, 0x210, 0x0003);
+ break;
+
+ case AUDIO_FREQUENCY_16K:
+ write_reg(bus, 0x210, 0x0033);
+ break;
+
+ case AUDIO_FREQUENCY_32K:
+ write_reg(bus, 0x210, 0x0063);
+ break;
+
+ case AUDIO_FREQUENCY_48K:
+ write_reg(bus, 0x210, 0x0083);
+ break;
+
+ case AUDIO_FREQUENCY_96K:
+ write_reg(bus, 0x210, 0x00A3);
+ break;
+
+ case AUDIO_FREQUENCY_11K:
+ write_reg(bus, 0x210, 0x0013);
+ break;
+
+ case AUDIO_FREQUENCY_22K:
+ write_reg(bus, 0x210, 0x0043);
+ break;
+
+ case AUDIO_FREQUENCY_44K:
+ write_reg(bus, 0x210, 0x0073);
+ break;
+
+ default:
+ write_reg(bus, 0x210, 0x0083);
+ break;
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t _reset(struct rt_i2c_bus_device *bus)
+{
+ /* Reset Codec by writing in 0x0000 address register */
+ write_reg(bus, 0x0000, 0x0000);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_wm8994_init(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+ rt_err_t result = RT_EOK;
+ static rt_uint16_t old_type = DEVICE_NONE;
+
+ struct wm8994_dev *device = (struct wm8994_dev *)dev;
+
+ if (old_type == device->type)
+ {
+ return RT_EOK;
+ }
+
+ old_type = device->type;
+
+ device->i2c_bus = rt_i2c_bus_device_find(I2C_NAME);
+ if (device->i2c_bus == RT_NULL)
+ {
+ LOG_E("can't find %c deivce", I2C_NAME);
+ return RT_ERROR;
+ }
+
+ result = _wm8994_init(device);
+ /* set volume */
+ _set_volume(device->i2c_bus, device->type, VOLUME_CONVERT(100));
+ /* set frequency */
+ _set_frequency(device->i2c_bus, AUDIO_FREQUENCY_44K);
+
+ return result;
+}
+
+static rt_err_t rt_wm8994_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_wm8994_close(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+ struct wm8994_dev *device = (struct wm8994_dev *)dev;
+
+ _set_mute(device->i2c_bus, AUDIO_MUTE_ON);
+
+ /* Mute the AIF1 Timeslot 0 DAC1 path */
+ write_reg(device->i2c_bus, 0x420, 0x0200);
+ /* Mute the AIF1 Timeslot 1 DAC2 path */
+ write_reg(device->i2c_bus, 0x422, 0x0200);
+ /* Disable DAC1L_TO_HPOUT1L */
+ write_reg(device->i2c_bus, 0x2D, 0x0000);
+ /* Disable DAC1R_TO_HPOUT1R */
+ write_reg(device->i2c_bus, 0x2E, 0x0000);
+ /* Disable DAC1 and DAC2 */
+ write_reg(device->i2c_bus, 0x05, 0x0000);
+ /* Reset Codec by writing in 0x0000 address register */
+ write_reg(device->i2c_bus, 0x0000, 0x0000);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_wm8994_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_size_t rt_wm8994_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_wm8994_control(rt_device_t dev, int cmd, void *args)
+{
+ RT_ASSERT(dev != RT_NULL);
+ struct wm8994_dev *device = (struct wm8994_dev *)dev;
+ rt_err_t result = RT_EOK;
+ switch (cmd)
+ {
+ case GET_ID:
+ result = _read_id(device->i2c_bus, (rt_uint16_t*)args);
+ break;
+
+ case SET_FREQUENCE:
+ result = _set_frequency(device->i2c_bus, (*(rt_uint32_t *)args));
+ break;
+
+ case SET_VOLUME:
+ result = _set_volume(device->i2c_bus, device->type, (*(rt_uint8_t*)args));
+ break;
+
+ case GET_VOLUME:
+ result = _get_volume(device->i2c_bus, (rt_uint32_t *)args);
+ break;
+
+ case SET_MUTE:
+ result = _set_mute(device->i2c_bus, (*(rt_uint32_t*)args));
+ break;
+
+ case SET_RESET:
+ result = _reset(device->i2c_bus);
+ break;
+
+ case START_PLAY:
+ result = _play(device->i2c_bus);
+ break;
+
+ case SET_PLAY_TYPE:
+ device->type = 0;
+ device->type = *(rt_uint32_t *)args;
+ rt_wm8994_init(dev);
+ break;
+
+ default:
+ LOG_D("not support cmd");
+ break;
+ }
+
+ return result;
+}
+
+int wm8994_init(void)
+{
+ rt_wm8994.dev.type = RT_Device_Class_Sound;
+ rt_wm8994.dev.init = rt_wm8994_init;
+ rt_wm8994.dev.open = rt_wm8994_open;
+ rt_wm8994.dev.close = rt_wm8994_close;
+ rt_wm8994.dev.read = rt_wm8994_read;
+ rt_wm8994.dev.write = rt_wm8994_write;
+ rt_wm8994.dev.control = rt_wm8994_control;
+ rt_wm8994.dev.user_data = RT_NULL;
+
+ rt_device_register(&rt_wm8994.dev, "decoder", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+ LOG_I("lowlevel decoder device init success!");
+
+ return RT_EOK;
+}
+INIT_DEVICE_EXPORT(wm8994_init);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wm8994.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wm8994.h
new file mode 100644
index 0000000000..872e02b162
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wm8994.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-02 thread-liu first version
+ */
+
+#ifndef __DRV_WM8994_H__
+#define __DRV_WM8994_H__
+
+#include "board.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum{
+ GET_ID,
+ SET_FREQUENCE,
+ SET_VOLUME,
+ GET_VOLUME,
+ SET_MUTE,
+ SET_RESET,
+ START_PLAY,
+ SET_PLAY_TYPE,
+};
+
+/* codec device play type */
+#define DEVICE_NONE ((uint16_t)0x0000)
+#define OUTPUT_DEVICE_SPEAKER ((uint16_t)0x0001)
+#define OUTPUT_DEVICE_HEADPHONE ((uint16_t)0x0002)
+#define OUTPUT_DEVICE_BOTH ((uint16_t)0x0004)
+#define OUTPUT_DEVICE_AUTO ((uint16_t)0x0008)
+#define INPUT_DEVICE_DIGITAL_MICROPHONE_1 ((uint16_t)0x0010)
+#define INPUT_DEVICE_DIGITAL_MICROPHONE_2 ((uint16_t)0x0020)
+#define INPUT_DEVICE_INPUT_LINE_1 ((uint16_t)0x0040)
+#define INPUT_DEVICE_INPUT_LINE_2 ((uint16_t)0x0080)
+#define INPUT_DEVICE_DIGITAL_MIC1_MIC2 ((uint16_t)0x0100)
+
+/* volume levels values */
+#define DEFAULT_VOLMIN 0x00
+#define DEFAULT_VOLMAX 0xFF
+#define DEFAULT_VOLSTEP 0x04
+
+#define AUDIO_PAUSE 0
+#define AUDIO_RESUME 1
+
+/* Codec POWER DOWN modes */
+#define CODEC_PDWN_HW 1
+#define CODEC_PDWN_SW 2
+
+/* MUTE commands */
+#define AUDIO_MUTE_ON 1
+#define AUDIO_MUTE_OFF 0
+
+/* AUDIO FREQUENCY */
+#define AUDIO_FREQUENCY_192K ((uint32_t)192000)
+#define AUDIO_FREQUENCY_96K ((uint32_t)96000)
+#define AUDIO_FREQUENCY_48K ((uint32_t)48000)
+#define AUDIO_FREQUENCY_44K ((uint32_t)44100)
+#define AUDIO_FREQUENCY_32K ((uint32_t)32000)
+#define AUDIO_FREQUENCY_22K ((uint32_t)22050)
+#define AUDIO_FREQUENCY_16K ((uint32_t)16000)
+#define AUDIO_FREQUENCY_11K ((uint32_t)11025)
+#define AUDIO_FREQUENCY_8K ((uint32_t)8000)
+
+#define VOLUME_CONVERT(Volume) (((Volume) > 100)? 100:((uint8_t)(((Volume) * 63) / 100)))
+#define VOLUME_IN_CONVERT(Volume) (((Volume) >= 100)? 239:((uint8_t)(((Volume) * 240) / 100)))
+
+#define WM8994_ID 0x8994
+#define WM8994_CHIPID_ADDR 0x00
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wwdg.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wwdg.c
new file mode 100644
index 0000000000..4e9910aa95
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_wwdg.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-06-18 thread-liu the first version
+ */
+
+#include <board.h>
+
+#if defined(BSP_USING_WWDG)
+#include "drv_config.h"
+#include <string.h>
+#include <stdlib.h>
+
+//#define DRV_DEBUG
+#define LOG_TAG "drv.wwg"
+#include <drv_log.h>
+
+#define LED5_PIN GET_PIN(A, 14)
+
+static rt_uint8_t feed_flag = 0;
+static WWDG_HandleTypeDef hwwdg1;
+
+void WWDG1_IRQHandler(void)
+{
+ /* enter interrupt */
+ rt_interrupt_enter();
+
+ HAL_WWDG_IRQHandler(&hwwdg1);
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef* hwwdg)
+{
+ if(hwwdg->Instance==WWDG1)
+ {
+ if (feed_flag)
+ {
+ HAL_WWDG_Refresh(&hwwdg1);
+ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_14);
+ }
+ }
+}
+
+static void wwdg_init()
+{
+ rt_pin_mode(LED5_PIN, PIN_MODE_OUTPUT);
+
+ hwwdg1.Instance = WWDG1;
+ hwwdg1.Init.Prescaler = WWDG_PRESCALER_8;
+ hwwdg1.Init.Window = 0X5F;
+ hwwdg1.Init.Counter = 0x7F;
+ hwwdg1.Init.EWIMode = WWDG_EWI_ENABLE;
+
+ if (HAL_WWDG_Init(&hwwdg1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ feed_flag = 1;
+}
+
+static void wwdg_control(uint8_t pre_value)
+{
+ if(pre_value > 7)
+ {
+ pre_value = 7;
+ }
+ hwwdg1.Instance->CFR &= ~(7 << 11); /* clear WDGTB[2:0] */
+ hwwdg1.Instance->CFR |= pre_value << 11; /* set WDGTB[2:0] */
+}
+
+static void wwdg_stop(void)
+{
+ feed_flag = 0;
+}
+
+static int wwdg_sample(int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ if (!strcmp(argv[1], "run"))
+ {
+ wwdg_init();
+ }
+ else if (!strcmp(argv[1], "set"))
+ {
+ if (argc > 2)
+ {
+ wwdg_control(atoi(argv[2]));
+ }
+ }
+ else if (!strcmp(argv[1], "stop"))
+ {
+ wwdg_stop();
+ }
+ }
+ else
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("wwdg_sample run - open wwdg, when feed wwdg in wwdg irq, the LD5 will blink\n");
+ rt_kprintf("wwdg_sample stop - stop to feed wwdg, system will reset\n");
+ rt_kprintf("wwdg_sample set - set the wwdg prescaler, wwdg_sample set [0 - 7]\n");
+ }
+
+ return RT_EOK;
+}
+MSH_CMD_EXPORT(wwdg_sample, window watch dog sample);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/eth/drv_eth.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/eth/drv_eth.c
new file mode 100644
index 0000000000..802014ee4c
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/eth/drv_eth.c
@@ -0,0 +1,870 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-20 thread-liu the first version
+ */
+
+#include "board.h"
+#include "drv_config.h"
+#include <netif/ethernetif.h>
+#include "lwipopts.h"
+#include "drv_eth.h"
+
+#if defined(BSP_USING_GBE)
+
+//#define DRV_DEBUG
+//#define ETH_RX_DUMP
+//#define ETH_TX_DUMP
+#define LOG_TAG "drv.emac"
+#include <drv_log.h>
+
+#define MAX_ADDR_LEN 6
+rt_base_t level;
+
+#define TX_ADD_BASE 0x2FFC3000
+#define RX_ADD_BASE 0x2FFC5000
+#define TX_DMA_ADD_BASE 0x2FFC7000
+#define RX_DMA_ADD_BASE 0x2FFC7100
+
+#if defined(__ICCARM__)
+/* transmit buffer */
+#pragma location = TX_ADD_BASE
+static uint8_t txBuffer[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
+/* Receive buffer */
+#pragma location = RX_ADD_BASE
+static uint8_t rxBuffer[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
+/* Transmit DMA descriptors */
+#pragma location = TX_DMA_ADD_BASE
+static TxDmaDesc txDmaDesc[ETH_TXBUFNB];
+/* Receive DMA descriptors */
+#pragma location = RX_DMA_ADD_BASE
+static RxDmaDesc rxDmaDesc[ETH_RXBUFNB];
+
+#elif defined(__CC_ARM) || defined(__CLANG_ARM)
+/* transmit buffer */
+static uint8_t txBuffer[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__((at(TX_ADD_BASE)));
+/* Receive buffer */
+static uint8_t rxBuffer[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__((at(RX_ADD_BASE)));
+/* Transmit DMA descriptors */
+static TxDmaDesc txDmaDesc[ETH_TXBUFNB] __attribute__((at(TX_DMA_ADD_BASE)));
+/* Receive DMA descriptors */
+static RxDmaDesc rxDmaDesc[ETH_RXBUFNB] __attribute__((at(RX_DMA_ADD_BASE)));
+
+#elif defined ( __GNUC__ )
+/* transmit buffer */
+static uint8_t txBuffer[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__((at(TX_ADD_BASE)));
+/* Receive buffer */
+static uint8_t rxBuffer[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__((at(RX_ADD_BASE)));
+/* Transmit DMA descriptors */
+static TxDmaDesc txDmaDesc[ETH_TXBUFNB] __attribute__((at(TX_DMA_ADD_BASE)));
+/* Receive DMA descriptors */
+static RxDmaDesc rxDmaDesc[ETH_RXBUFNB] __attribute__((at(RX_DMA_ADD_BASE)));
+#endif
+
+//Current transmit descriptor
+static rt_uint8_t txIndex = 0;
+//Current receive descriptor
+static rt_uint8_t rxIndex = 0;
+
+/* eth */
+static struct rt_event rx_event = {0};
+
+#define ETH_TIME_OUT 100000
+
+struct rt_stm32_eth
+{
+ /* inherit from ethernet device */
+ struct eth_device parent;
+#ifndef PHY_USING_INTERRUPT_MODE
+ rt_timer_t poll_link_timer;
+#endif
+ /* interface address info, hw address */
+ rt_uint8_t dev_addr[MAX_ADDR_LEN];
+ /* eth speed */
+ uint32_t eth_speed;
+ /* eth duplex mode */
+ uint32_t eth_mode;
+};
+static struct rt_stm32_eth stm32_eth_device = {0};
+
+#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
+{
+ unsigned char *buf = (unsigned char *)ptr;
+ int i, j;
+
+ for (i = 0; i < buflen; i += 16)
+ {
+ rt_kprintf("%08X: ", i);
+
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%02X ", buf[i + j]);
+ else
+ rt_kprintf(" ");
+ rt_kprintf(" ");
+
+ for (j = 0; j < 16; j++)
+ if (i + j < buflen)
+ rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+ rt_kprintf("\n");
+ }
+}
+#endif
+
+static rt_err_t phy_write_reg(uint8_t phy_addr, uint8_t reg_addr, uint16_t reg_value)
+{
+ uint32_t temp;
+ volatile uint32_t tickstart = 0;
+ /* Take care not to alter MDC clock configuration */
+ temp = ETH->MACMDIOAR & ETH_MACMDIOAR_CR;
+ /* Set up a write operation */
+ temp |= ETH_MACMDIOAR_GOC_Val(1) | ETH_MACMDIOAR_GB;
+ /* PHY address */
+ temp |= (phy_addr << 21) & ETH_MACMDIOAR_PA;
+ /* Register address */
+ temp |= (reg_addr << 16) & ETH_MACMDIOAR_RDA;
+
+ /* Data to be written in the PHY register */
+ ETH->MACMDIODR = reg_value & ETH_MACMDIODR_GD;
+
+ /* Start a write operation */
+ ETH->MACMDIOAR = temp;
+ /* Wait for the write to complete */
+ tickstart = rt_tick_get();
+ while((ETH->MACMDIOAR & ETH_MACMDIOAR_GB) != 0)
+ {
+ /* judge timeout */
+ if((rt_tick_get() - tickstart) > ETH_TIME_OUT)
+ {
+ LOG_E("PHY write reg %02x date %04x timeout!", reg_addr, reg_value);
+ return RT_ETIMEOUT;
+ }
+ }
+
+ return RT_EOK;
+}
+
+static uint16_t phy_read_reg(uint8_t phy_addr, uint8_t reg_addr)
+{
+ uint16_t reg_value = 0;
+ uint32_t status = 0;
+ volatile uint32_t tickstart = 0;
+
+ /* Take care not to alter MDC clock configuration */
+ status = ETH->MACMDIOAR & ETH_MACMDIOAR_CR;
+ /* Set up a read operation */
+ status |= ETH_MACMDIOAR_GOC_Val(3) | ETH_MACMDIOAR_GB;
+ /* PHY address */
+ status |= (phy_addr << 21) & ETH_MACMDIOAR_PA;
+ /* Register address */
+ status |= (reg_addr << 16) & ETH_MACMDIOAR_RDA;
+
+ /* Start a read operation */
+ ETH->MACMDIOAR = status;
+ /* Wait for the read to complete */
+ tickstart = rt_tick_get();
+ while((ETH->MACMDIOAR & ETH_MACMDIOAR_GB) != 0)
+ {
+ /* judge timeout */
+ if((rt_tick_get() - tickstart) > ETH_TIME_OUT)
+ {
+ LOG_E("PHY read reg %02x timeout!", reg_addr);
+ return RT_ETIMEOUT;
+ }
+ }
+
+ /* Get register value */
+ reg_value = ETH->MACMDIODR & ETH_MACMDIODR_GD;
+
+ return reg_value;
+}
+
+static rt_err_t update_mac_mode(void)
+{
+ uint32_t status;
+
+ /* Read current MAC configuration */
+ status = ETH->MACCR;
+
+ if (stm32_eth_device.eth_speed & PHY_1000M)
+ {
+ status &= ~ETH_MACCR_PS;
+ status &= ~ETH_MACCR_FES;
+ }
+ else if (stm32_eth_device.eth_speed & PHY_100M)
+ {
+ status |= ETH_MACCR_PS;
+ status |= ETH_MACCR_FES;
+ }
+ /* 10M */
+ else
+ {
+ status |= ETH_MACCR_PS;
+ status &= ~ETH_MACCR_FES;
+ }
+
+ if (stm32_eth_device.eth_mode & PHY_FULL_DUPLEX)
+ {
+ status |= ETH_MACCR_DM;
+ }
+ else
+ {
+ status &= ~ETH_MACCR_DM;
+ }
+
+ /* Update MAC configuration register */
+ ETH->MACCR = status;
+
+ return RT_EOK;
+}
+
+static void HAL_ETH_MspInit(void)
+{
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
+
+ if(IS_ENGINEERING_BOOT_MODE())
+ {
+ /** Initializes the peripherals clock
+ */
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ETH;
+ PeriphClkInit.EthClockSelection = RCC_ETHCLKSOURCE_PLL4;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ }
+
+ /* Enable SYSCFG clock */
+ __HAL_RCC_SYSCFG_CLK_ENABLE();
+
+ /* Enable GPIO clocks */
+ __HAL_RCC_GPIOA_CLK_ENABLE();
+ __HAL_RCC_GPIOB_CLK_ENABLE();
+ __HAL_RCC_GPIOC_CLK_ENABLE();
+ __HAL_RCC_GPIOD_CLK_ENABLE();
+ __HAL_RCC_GPIOE_CLK_ENABLE();
+ __HAL_RCC_GPIOG_CLK_ENABLE();
+
+ /* Select RGMII interface mode */
+ HAL_SYSCFG_ETHInterfaceSelect(SYSCFG_ETH_RGMII);
+
+ /* Enable Ethernet MAC clock */
+ __HAL_RCC_ETH1MAC_CLK_ENABLE();
+ __HAL_RCC_ETH1TX_CLK_ENABLE();
+ __HAL_RCC_ETH1RX_CLK_ENABLE();
+
+ /**ETH1 GPIO Configuration
+ PA1 ------> ETH1_RX_CLK
+ PA2 ------> ETH1_MDIO
+ PA7 ------> ETH1_RX_CTL
+ PB0 ------> ETH1_RXD2
+ PB1 ------> ETH1_RXD3
+ PB11 ------> ETH1_TX_CTL
+ PC1 ------> ETH1_MDC
+ PC2 ------> ETH1_TXD2
+ PC4 ------> ETH1_RXD0
+ PC5 ------> ETH1_RXD1
+ PE2 ------> ETH1_TXD3
+ PG4 ------> ETH1_GTX_CLK
+ PG5 ------> ETH1_CLK125
+ PG13 ------> ETH1_TXD0
+ PG14 ------> ETH1_TXD1
+ */
+ GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_7;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_11;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_2;
+ HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+ GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_13|GPIO_PIN_14;
+ HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
+
+ /* ETH interrupt Init */
+ HAL_NVIC_SetPriority(ETH1_IRQn, 0x01, 0x00);
+ HAL_NVIC_EnableIRQ(ETH1_IRQn);
+
+ /* Configure PHY_RST (PD10) */
+ GPIO_InitStruct.Pin = GPIO_PIN_10;
+ GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+ /* Reset PHY transceiver */
+ HAL_GPIO_WritePin(GPIOD, GPIO_PIN_10, GPIO_PIN_RESET);
+ rt_thread_mdelay(20);
+ HAL_GPIO_WritePin(GPIOD, GPIO_PIN_10, GPIO_PIN_SET);
+ rt_thread_mdelay(20);
+}
+
+static rt_err_t rt_stm32_eth_init(rt_device_t dev)
+{
+ RT_ASSERT(dev != RT_NULL);
+
+ rt_uint32_t status;
+ int i = 0 ;
+ volatile uint32_t tickstart = 0;
+ uint8_t *macAddr = &stm32_eth_device.dev_addr[0];
+
+ /* Initialize RX/TX descriptor index */
+ rxIndex = txIndex = 0;
+
+ HAL_ETH_MspInit();
+
+ /* Reset Ethernet MAC peripheral */
+ __HAL_RCC_ETH1MAC_FORCE_RESET();
+ __HAL_RCC_ETH1MAC_RELEASE_RESET();
+
+ /* Ethernet Software reset */
+ ETH->DMAMR |= ETH_DMAMR_SWR;
+ /* Wait for the reset to complete */
+ tickstart = rt_tick_get();
+ while (READ_BIT(ETH->DMAMR, ETH_DMAMR_SWR))
+ {
+ if(((HAL_GetTick() - tickstart ) > ETH_TIME_OUT))
+ {
+ LOG_E("ETH software reset timeout!");
+ return RT_ERROR;
+ }
+ }
+
+ /* Adjust MDC clock range depending on HCLK frequency */
+ ETH->MACMDIOAR = ETH_MACMDIOAR_CR_Val(5);
+
+ /* Use default MAC configuration */
+ ETH->MACCR = ETH_MACCR_DO;
+
+ /* Set the MAC address of the station */
+ ETH->MACA0LR = ((macAddr[3] << 24) | (macAddr[2] << 16) | (macAddr[1] << 8) | macAddr[0]);
+ ETH->MACA0HR = ((macAddr[5] << 8) | macAddr[4]);
+
+ /* The MAC supports 3 additional addresses for unicast perfect filtering */
+ ETH->MACA1LR = 0;
+ ETH->MACA1HR = 0;
+ ETH->MACA2LR = 0;
+ ETH->MACA2HR = 0;
+ ETH->MACA3LR = 0;
+ ETH->MACA3HR = 0;
+
+ /* Initialize hash table */
+ ETH->MACHT0R = 0;
+ ETH->MACHT1R = 0;
+
+ /* Configure the receive filter */
+ ETH->MACPFR = ETH_MACPFR_HPF | ETH_MACPFR_HMC;
+
+ /* Disable flow control */
+ ETH->MACQ0TXFCR = 0;
+ ETH->MACRXFCR = 0;
+
+ /* Enable the first RX queue */
+ ETH->MACRXQC0R = ETH_MACRXQC0R_RXQ0EN_Val(1);
+
+ /* Configure DMA operating mode */
+ ETH->DMAMR = ETH_DMAMR_INTM_Val(0) | ETH_DMAMR_PR_Val(0);
+
+ /* Configure system bus mode */
+ ETH->DMASBMR |= ETH_DMASBMR_AAL;
+
+ /* The DMA takes the descriptor table as contiguous */
+ ETH->DMAC0CR = ETH_DMAC0CR_DSL_Val(0);
+
+ /* Configure TX features */
+ ETH->DMAC0TXCR = ETH_DMAC0TXCR_TXPBL_Val(1);
+
+ /* Configure RX features */
+ ETH->DMAC0RXCR = ETH_DMAC0RXCR_RXPBL_Val(1) | ETH_DMAC0RXCR_RBSZ_Val(ETH_RX_BUF_SIZE);
+
+ /* Enable store and forward mode for transmission */
+ ETH->MTLTXQ0OMR = ETH_MTLTXQ0OMR_TQS_Val(7) | ETH_MTLTXQ0OMR_TXQEN_Val(2) | ETH_MTLTXQ0OMR_TSF;
+
+ /* Enable store and forward mode for reception */
+ ETH->MTLRXQ0OMR = ETH_MTLRXQ0OMR_RQS_Val(7) | ETH_MTLRXQ0OMR_RSF;
+
+ /* Initialize TX DMA descriptor list */
+ for (i = 0; i < ETH_TXBUFNB; i++)
+ {
+ /* The descriptor is initially owned by the application */
+ txDmaDesc[i].tdes0 = 0;
+ txDmaDesc[i].tdes1 = 0;
+ txDmaDesc[i].tdes2 = 0;
+ txDmaDesc[i].tdes3 = 0;
+ }
+
+ /* Initialize RX DMA descriptor list */
+ for (i = 0; i < ETH_RXBUFNB; i++)
+ {
+ /* The descriptor is initially owned by the DMA */
+ rxDmaDesc[i].rdes0 = (uint32_t)rxBuffer[i];
+ rxDmaDesc[i].rdes1 = 0;
+ rxDmaDesc[i].rdes2 = 0;
+ rxDmaDesc[i].rdes3 = ETH_RDES3_OWN | ETH_RDES3_IOC | ETH_RDES3_BUF1V;
+ }
+
+ /* Set Transmit Descriptor List Address Register */
+ ETH->DMAC0TXDLAR = (uint32_t)&txDmaDesc[0];
+ /* Length of the transmit descriptor ring */
+ ETH->DMAC0TXRLR = ETH_TXBUFNB - 1;
+
+ /* Set Receive Descriptor List Address Register */
+ ETH->DMAC0RXDLAR = (uint32_t)&rxDmaDesc[0];
+ /* Length of the receive descriptor ring */
+ ETH->DMAC0RXRLR = ETH_RXBUFNB - 1;
+
+ /* Prevent interrupts from being generated when the transmit statistic
+ * counters reach half their maximum value */
+ ETH->MMCTXIMR = ETH_MMCTXIMR_TXLPITRCIM | ETH_MMCTXIMR_TXLPIUSCIM | ETH_MMCTXIMR_TXGPKTIM | ETH_MMCTXIMR_TXMCOLGPIM | ETH_MMCTXIMR_TXSCOLGPIM;
+
+ /* Prevent interrupts from being generated when the receive statistic
+ * counters reach half their maximum value */
+ ETH->MMCRXIMR = ETH_MMCRXIMR_RXLPITRCIM | ETH_MMCRXIMR_RXLPIUSCIM | ETH_MMCRXIMR_RXUCGPIM | ETH_MMCRXIMR_RXALGNERPIM | ETH_MMCRXIMR_RXCRCERPIM;
+
+ /* Disable MAC interrupts */
+ ETH->MACIER = 0;
+
+ /* Enable the desired DMA interrupts */
+ ETH->DMAC0IER = ETH_DMAC0IER_NIE | ETH_DMAC0IER_RIE | ETH_DMAC0IER_TIE;
+
+ /* Enable MAC transmission and reception */
+ ETH->MACCR |= ETH_MACCR_TE | ETH_MACCR_RE;
+
+ /* Enable DMA transmission and reception */
+ ETH->DMAC0TXCR |= ETH_DMAC0TXCR_ST;
+ ETH->DMAC0RXCR |= ETH_DMAC0RXCR_SR;
+
+ /* Reset PHY transceiver */
+ phy_write_reg(RTL8211E_PHY_ADDR, RTL8211E_BMCR, RTL8211E_BMCR_RESET);
+ status = phy_read_reg(RTL8211E_PHY_ADDR, RTL8211E_BMCR);
+ /* Wait for the reset to complete */
+ tickstart = rt_tick_get();
+ while (status & RTL8211E_BMCR_RESET)
+ {
+ if((rt_tick_get() - tickstart) > ETH_TIME_OUT)
+ {
+ LOG_E("PHY software reset timeout!");
+ return RT_ETIMEOUT;
+ }
+ else
+ {
+ status = phy_read_reg(RTL8211E_PHY_ADDR, RTL8211E_BMCR);
+ }
+ }
+
+ /* The PHY will generate interrupts when link status changes are detected */
+ phy_write_reg(RTL8211E_PHY_ADDR, RTL8211E_INER, RTL8211E_INER_AN_COMPLETE | RTL8211E_INER_LINK_STATUS);
+
+ return RT_EOK;
+}
+
+static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag)
+{
+ LOG_D("emac open");
+ return RT_EOK;
+}
+
+static rt_err_t rt_stm32_eth_close(rt_device_t dev)
+{
+ LOG_D("emac close");
+ return RT_EOK;
+}
+
+static rt_size_t rt_stm32_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ LOG_D("emac read");
+ rt_set_errno(-RT_ENOSYS);
+ return 0;
+}
+
+static rt_size_t rt_stm32_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ LOG_D("emac write");
+ rt_set_errno(-RT_ENOSYS);
+ return 0;
+}
+
+static rt_err_t rt_stm32_eth_control(rt_device_t dev, int cmd, void *args)
+{
+ switch (cmd)
+ {
+ case NIOCTL_GADDR:
+ /* get mac address */
+ if (args)
+ {
+ rt_memcpy(args, stm32_eth_device.dev_addr, 6);
+ }
+ else
+ {
+ return -RT_ERROR;
+ }
+ break;
+
+ default :
+ break;
+ }
+
+ return RT_EOK;
+}
+
+rt_err_t rt_stm32_eth_tx(rt_device_t dev, struct pbuf *p)
+{
+ uint32_t framelen = 0;
+ struct pbuf *q = RT_NULL;
+
+ /* Copy user data to the transmit buffer */
+ for (q = p; q != NULL; q = q->next)
+ {
+ /* Make sure the current buffer is available for writing */
+ if((txDmaDesc[txIndex].tdes3 & ETH_TDES3_OWN) != 0)
+ {
+ LOG_D("buffer not valid");
+ return ERR_USE;
+ }
+
+ level = rt_hw_interrupt_disable();
+ rt_memcpy(&txBuffer[txIndex][framelen], q->payload, q->len);
+ framelen += q->len;
+ rt_hw_interrupt_enable(level);
+
+ /* Check the frame length */
+ if (framelen > ETH_TX_BUF_SIZE - 1)
+ {
+ LOG_D(" tx buffer frame length over : %d", framelen);
+ return ERR_USE;
+ }
+ }
+
+#ifdef ETH_TX_DUMP
+ rt_kprintf("Tx dump, len= %d\r\n", framelen);
+ dump_hex(txBuffer[txIndex], framelen);
+#endif
+
+ /* Set the start address of the buffer */
+ txDmaDesc[txIndex].tdes0 = (uint32_t)txBuffer[txIndex];
+ /* Write the number of bytes to send */
+ txDmaDesc[txIndex].tdes2 = ETH_TDES2_IOC | (framelen & ETH_TDES2_B1L);
+ /* Give the ownership of the descriptor to the DMA */
+ txDmaDesc[txIndex].tdes3 = ETH_TDES3_OWN | ETH_TDES3_FD | ETH_TDES3_LD;
+
+ /* Data synchronization barrier */
+ __DSB();
+
+ /* Clear TBU flag to resume processing */
+ ETH->DMAC0SR = ETH_DMAC0SR_TBU;
+ /* Instruct the DMA to poll the transmit descriptor list */
+ ETH->DMAC0TXDTPR = 0;
+
+ if (++txIndex > ETH_TXBUFNB - 1)
+ {
+ txIndex = 0;
+ }
+
+ return ERR_OK;
+}
+
+struct pbuf *rt_stm32_eth_rx(rt_device_t dev)
+{
+ rt_uint32_t framelength = 0;
+ uint32_t framelen = 0;
+ struct pbuf *p = RT_NULL, *q = RT_NULL;
+
+ /* The current buffer is available for reading */
+ if (!(rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_OWN))
+ {
+ /* FD and LD flags should be set */
+ if ((rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_FD) && (rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_LD))
+ {
+ /* Make sure no error occurred */
+ if(!(rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_ES))
+ {
+ /* Retrieve the length of the frame */
+ framelength = rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_PL;
+ /* check the frame length */
+ framelength = (framelength > ETH_RX_BUF_SIZE) ? ETH_RX_BUF_SIZE : framelength;
+ p = pbuf_alloc(PBUF_RAW, framelength, PBUF_RAM);
+ if (p != NULL)
+ {
+ for (q = p; q != NULL; q = q->next)
+ {
+ level=rt_hw_interrupt_disable();
+ rt_memcpy(q->payload, &rxBuffer[rxIndex][framelen], q->len);
+ framelen += q->len;
+ rt_hw_interrupt_enable(level);
+
+ if (framelen > framelength)
+ {
+ LOG_E("frame len is too long!");
+ return RT_NULL;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* The received packet contains an error */
+ LOG_D("the received packet contains an error!");
+ return RT_NULL;
+ }
+
+ }
+ else
+ {
+ /* The packet is not valid */
+ LOG_D("the packet is not valid");
+ return RT_NULL;
+ }
+
+ /* Set the start address of the buffer */
+ rxDmaDesc[rxIndex].rdes0 = (uint32_t)rxBuffer[rxIndex];
+ /* Give the ownership of the descriptor back to the DMA */
+ rxDmaDesc[rxIndex].rdes3 = ETH_RDES3_OWN | ETH_RDES3_IOC | ETH_RDES3_BUF1V;
+#ifdef ETH_RX_DUMP
+ rt_kprintf("Rx dump, len= %d\r\n", framelen);
+ dump_hex(rxBuffer[rxIndex], framelen);
+#endif
+ /* Increment index and wrap around if necessary */
+ if (++rxIndex > ETH_RXBUFNB - 1)
+ {
+ rxIndex = 0;
+ }
+ /* Clear RBU flag to resume processing */
+ ETH->DMAC0SR = ETH_DMAC0SR_RBU;
+ /* Instruct the DMA to poll the receive descriptor list */
+ ETH->DMAC0RXDTPR = 0;
+ }
+
+ return p;
+}
+
+void ETH1_IRQHandler(void)
+{
+ rt_uint32_t status = 0;
+
+ /* enter interrupt */
+ rt_interrupt_enter();
+ /* Read DMA status register */
+ status = ETH->DMAC0SR;
+ /* Frame transmitted */
+ if (status & ETH_DMAC0SR_TI)
+ {
+ /* Clear the Eth DMA Tx IT pending bits */
+ ETH->DMAC0SR = ETH_DMAC0SR_TI;
+ }
+ /* Frame received */
+ else if (status & ETH_DMAC0SR_RI)
+ {
+ /* Disable RIE interrupt */
+ ETH->DMAC0IER &= ~ETH_DMAC0IER_RIE;
+
+ rt_event_send(&rx_event, status);
+ }
+ /* ETH DMA Error */
+ if (status & ETH_DMAC0SR_AIS)
+ {
+ ETH->DMAC0IER &= ~ETH_DMAC0IER_AIE;
+ LOG_E("eth dam err");
+ }
+ /* Clear the interrupt flags */
+ ETH->DMAC0SR = ETH_DMAC0SR_NIS;
+
+ /* leave interrupt */
+ rt_interrupt_leave();
+}
+
+static void phy_linkchange()
+{
+ rt_uint32_t status = 0;
+
+ /* Read status register to acknowledge the interrupt */
+ status = phy_read_reg(RTL8211E_PHY_ADDR, RTL8211E_INSR);
+
+ if (status & (RTL8211E_INSR_AN_COMPLETE | RTL8211E_INSR_LINK_STATUS))
+ {
+ status = phy_read_reg(RTL8211E_PHY_ADDR, RTL8211E_BMSR);
+ status = phy_read_reg(RTL8211E_PHY_ADDR, RTL8211E_BMSR);
+
+ if (status & RTL8211E_BMSR_LINK_STATUS)
+ {
+ LOG_D("link up");
+
+ status = phy_read_reg(RTL8211E_PHY_ADDR, RTL8211E_PHYSR);
+
+ switch (status & RTL8211E_PHYSR_SPEED)
+ {
+ case RTL8211E_PHYSR_SPEED_10MBPS:
+ {
+ LOG_D("speed: 10M");
+ stm32_eth_device.eth_speed |= PHY_10M;
+ break;
+ }
+
+ case RTL8211E_PHYSR_SPEED_100MBPS:
+ {
+ LOG_D("speed: 100M");
+ stm32_eth_device.eth_speed |= PHY_100M;
+ break;
+ }
+
+ case RTL8211E_PHYSR_SPEED_1000MBPS:
+ {
+ LOG_D("speed: 1000M");
+ stm32_eth_device.eth_speed |= PHY_1000M;
+ break;
+ }
+
+ /* Unknown speed */
+ default:
+ rt_kprintf("Invalid speed.");
+ break;
+ }
+
+ stm32_eth_device.eth_mode = (status & RTL8211E_PHYSR_DUPLEX)? PHY_FULL_DUPLEX : PHY_HALF_DUPLEX;
+ update_mac_mode();
+ /* send link up. */
+ eth_device_linkchange(&stm32_eth_device.parent, RT_TRUE);
+ }
+ else
+ {
+ LOG_D("link down");
+ eth_device_linkchange(&stm32_eth_device.parent, RT_FALSE);
+ }
+ }
+}
+
+#ifdef PHY_USING_INTERRUPT_MODE
+static void eth_phy_isr(void *args)
+{
+ rt_uint32_t status = 0;
+
+ phy_read_reg(RTL8211E_PHY_ADDR, PHY_INTERRUPT_FLAG_REG, (uint32_t *)&status);
+ LOG_D("phy interrupt status reg is 0x%X", status);
+
+ phy_linkchange();
+}
+#endif /* PHY_USING_INTERRUPT_MODE */
+
+static void phy_monitor_thread_entry(void *parameter)
+{
+ rt_uint32_t status = 0;
+
+ phy_linkchange();
+#ifdef PHY_USING_INTERRUPT_MODE
+ /* configuration intterrupt pin */
+ rt_pin_mode(PHY_INT_PIN, PIN_MODE_INPUT_PULLUP);
+ rt_pin_attach_irq(PHY_INT_PIN, PIN_IRQ_MODE_FALLING, eth_phy_isr, (void *)"callbackargs");
+ rt_pin_irq_enable(PHY_INT_PIN, PIN_IRQ_ENABLE);
+
+ /* enable phy interrupt */
+ phy_write_reg(RTL8211E_PHY_ADDR, PHY_INTERRUPT_MASK_REG, PHY_INT_MASK);
+#if defined(PHY_INTERRUPT_CTRL_REG)
+ phy_write_reg( RTL8211E_PHY_ADDR, PHY_INTERRUPT_CTRL_REG, PHY_INTERRUPT_EN);
+#endif
+#else /* PHY_USING_INTERRUPT_MODE */
+ stm32_eth_device.poll_link_timer = rt_timer_create("phylnk", (void (*)(void*))phy_linkchange,
+ NULL, RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC);
+ if (!stm32_eth_device.poll_link_timer || rt_timer_start(stm32_eth_device.poll_link_timer) != RT_EOK)
+ {
+ LOG_E("Start link change detection timer failed");
+ }
+#endif /* PHY_USING_INTERRUPT_MODE */
+ while(1)
+ {
+ if (rt_event_recv(&rx_event, 0xffffffff, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
+ RT_WAITING_FOREVER, &status) == RT_EOK)
+ {
+ /* check dma rx buffer */
+ if (ETH->DMAC0SR & ETH_DMAC0SR_RI)
+ {
+ /* Clear interrupt flag */
+ ETH->DMAC0SR = ETH_DMAC0SR_RI;
+ /* Process all pending packets */
+ while (rxDmaDesc[rxIndex].rdes3 & ETH_RDES3_PL)
+ {
+ /* trigger lwip receive thread */
+ eth_device_ready(&(stm32_eth_device.parent));
+ }
+ }
+
+ /* enable DMA interrupts */
+ ETH->DMAC0IER = ETH_DMAC0IER_NIE | ETH_DMAC0IER_RIE | ETH_DMAC0IER_TIE;
+ }
+ }
+}
+
+/* Register the EMAC device */
+static int rt_hw_stm32_eth_init(void)
+{
+ rt_err_t state = RT_EOK;
+
+ /* OUI 00-80-E1 STMICROELECTRONICS. */
+ stm32_eth_device.dev_addr[0] = 0x00;
+ stm32_eth_device.dev_addr[1] = 0x80;
+ stm32_eth_device.dev_addr[2] = 0xE1;
+ /* generate MAC addr from 96bit unique ID. */
+ stm32_eth_device.dev_addr[3] = *(rt_uint8_t *)(UID_BASE + 4);
+ stm32_eth_device.dev_addr[4] = *(rt_uint8_t *)(UID_BASE + 2);
+ stm32_eth_device.dev_addr[5] = *(rt_uint8_t *)(UID_BASE + 0);
+
+ stm32_eth_device.parent.parent.init = rt_stm32_eth_init;
+ stm32_eth_device.parent.parent.open = rt_stm32_eth_open;
+ stm32_eth_device.parent.parent.close = rt_stm32_eth_close;
+ stm32_eth_device.parent.parent.read = rt_stm32_eth_read;
+ stm32_eth_device.parent.parent.write = rt_stm32_eth_write;
+ stm32_eth_device.parent.parent.control = rt_stm32_eth_control;
+ stm32_eth_device.parent.parent.user_data = RT_NULL;
+
+ stm32_eth_device.parent.eth_rx = rt_stm32_eth_rx;
+ stm32_eth_device.parent.eth_tx = rt_stm32_eth_tx;
+
+ rt_event_init(&rx_event, "eth_rx", RT_IPC_FLAG_FIFO);
+
+ /* register eth device */
+ state = eth_device_init(&(stm32_eth_device.parent), "e0");
+ if (RT_EOK == state)
+ {
+ LOG_D("emac device init success");
+ }
+ else
+ {
+ LOG_E("emac device init faild: %d", state);
+ state = -RT_ERROR;
+ }
+
+ /* start phy monitor */
+ rt_thread_t tid;
+ tid = rt_thread_create("phy",
+ phy_monitor_thread_entry,
+ RT_NULL,
+ 1024,
+ RT_THREAD_PRIORITY_MAX - 2,
+ 2);
+ if (tid != RT_NULL)
+ {
+ rt_thread_startup(tid);
+ }
+ else
+ {
+ state = -RT_ERROR;
+ }
+
+ return state;
+}
+INIT_DEVICE_EXPORT(rt_hw_stm32_eth_init);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/eth/drv_eth.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/eth/drv_eth.h
new file mode 100644
index 0000000000..9529d778a0
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/eth/drv_eth.h
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-20 thread-liu the first version
+ */
+
+#ifndef __DRV_ETH_H__
+#define __DRV_ETH_H__
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <rtdevice.h>
+#include <board.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Transmit descriptor
+ **/
+typedef struct
+{
+ uint32_t tdes0;
+ uint32_t tdes1;
+ uint32_t tdes2;
+ uint32_t tdes3;
+} TxDmaDesc;
+
+/**
+ * @brief Receive descriptor
+ **/
+typedef struct
+{
+ uint32_t rdes0;
+ uint32_t rdes1;
+ uint32_t rdes2;
+ uint32_t rdes3;
+} RxDmaDesc;
+
+enum {
+ PHY_LINK = (1 << 0),
+ PHY_10M = (1 << 1),
+ PHY_100M = (1 << 2),
+ PHY_1000M = (1 << 3),
+ PHY_FULL_DUPLEX = (1 << 4),
+ PHY_HALF_DUPLEX = (1 << 5)
+};
+
+#define RTL8211E_PHY_ADDR 7 /* PHY address */
+
+#define ETH_TXBUFNB 4 /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
+#define ETH_TX_BUF_SIZE 1536 /* buffer size for transmit */
+#define ETH_RXBUFNB 4 /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_RX_BUF_SIZE 1536 /* buffer size for receive */
+
+#define ETH_MMC_INTERRUPT_MASK_TXLPITRCIM_Msk ETH_MMCTXIMR_TXLPITRCIM_Msk /* ETH_MMCTXIMR register */
+
+/* Register access macros */
+#define ETH_MACRXQC0R_RXQ0EN_Val(n) (((n) << ETH_MACRXQC0R_RXQ0EN_Pos) & ETH_MACRXQC0R_RXQ0EN_Msk)
+#define ETH_MACMDIOAR_CR_Val(n) (((n) << ETH_MACMDIOAR_CR_Pos) & ETH_MACMDIOAR_CR_Msk)
+#define ETH_MACMDIOAR_GOC_Val(n) (((n) << ETH_MACMDIOAR_GOC_Pos) & ETH_MACMDIOAR_GOC_Msk)
+#define ETH_MTLTXQ0OMR_TQS_Val(n) (((n) << ETH_MTLTXQ0OMR_TQS_Pos) & ETH_MTLTXQ0OMR_TQS_Msk)
+#define ETH_MTLTXQ0OMR_TXQEN_Val(n) (((n) << ETH_MTLTXQ0OMR_TXQEN_Pos) & ETH_MTLTXQ0OMR_TXQEN_Msk)
+#define ETH_MTLRXQ0OMR_RQS_Val(n) (((n) << ETH_MTLRXQ0OMR_RQS_Pos) & ETH_MTLRXQ0OMR_RQS_Msk)
+#define ETH_DMAMR_INTM_Val(n) (((n) << ETH_DMAMR_INTM_Pos) & ETH_DMAMR_INTM_Msk)
+#define ETH_DMAMR_PR_Val(n) (((n) << ETH_DMAMR_PR_Pos) & ETH_DMAMR_PR_Msk)
+#define ETH_DMAC0CR_DSL_Val(n) (((n) << ETH_DMAC0CR_DSL_Pos) & ETH_DMAC0CR_DSL_Msk)
+#define ETH_DMAC0TXCR_TXPBL_Val(n) (((n) << ETH_DMAC0TXCR_TXPBL_Pos) & ETH_DMAC0TXCR_TXPBL_Msk)
+#define ETH_DMAC0RXCR_RXPBL_Val(n) (((n) << ETH_DMAC0RXCR_RXPBL_Pos) & ETH_DMAC0RXCR_RXPBL_Msk)
+#define ETH_DMAC0RXCR_RBSZ_Val(n) (((n) << ETH_DMAC0RXCR_RBSZ_Pos) & ETH_DMAC0RXCR_RBSZ_Msk)
+
+/* Transmit normal descriptor (read format) */
+#define ETH_TDES0_BUF1AP 0xFFFFFFFF
+#define ETH_TDES1_BUF2AP 0xFFFFFFFF
+#define ETH_TDES2_IOC 0x80000000
+#define ETH_TDES2_TTSE 0x40000000
+#define ETH_TDES2_B2L 0x3FFF0000
+#define ETH_TDES2_VTIR 0x0000C000
+#define ETH_TDES2_B1L 0x00003FFF
+#define ETH_TDES3_OWN 0x80000000
+#define ETH_TDES3_CTXT 0x40000000
+#define ETH_TDES3_FD 0x20000000
+#define ETH_TDES3_LD 0x10000000
+#define ETH_TDES3_CPC 0x0C000000
+#define ETH_TDES3_SAIC 0x03800000
+#define ETH_TDES3_THL 0x00780000
+#define ETH_TDES3_TSE 0x00040000
+#define ETH_TDES3_CIC 0x00030000
+#define ETH_TDES3_FL 0x00007FFF
+
+/* Transmit normal descriptor (write-back format) */
+#define ETH_TDES0_TTSL 0xFFFFFFFF
+#define ETH_TDES1_TTSH 0xFFFFFFFF
+#define ETH_TDES3_OWN 0x80000000
+#define ETH_TDES3_CTXT 0x40000000
+#define ETH_TDES3_FD 0x20000000
+#define ETH_TDES3_LD 0x10000000
+#define ETH_TDES3_TTSS 0x00020000
+#define ETH_TDES3_ES 0x00008000
+#define ETH_TDES3_JT 0x00004000
+#define ETH_TDES3_FF 0x00002000
+#define ETH_TDES3_PCE 0x00001000
+#define ETH_TDES3_LOC 0x00000800
+#define ETH_TDES3_NC 0x00000400
+#define ETH_TDES3_LC 0x00000200
+#define ETH_TDES3_EC 0x00000100
+#define ETH_TDES3_CC 0x000000F0
+#define ETH_TDES3_ED 0x00000008
+#define ETH_TDES3_UF 0x00000004
+#define ETH_TDES3_DB 0x00000002
+#define ETH_TDES3_IHE 0x00000001
+
+/* Transmit context descriptor */
+#define ETH_TDES0_TTSL 0xFFFFFFFF
+#define ETH_TDES1_TTSH 0xFFFFFFFF
+#define ETH_TDES2_IVT 0xFFFF0000
+#define ETH_TDES2_MSS 0x00003FFF
+#define ETH_TDES3_OWN 0x80000000
+#define ETH_TDES3_CTXT 0x40000000
+#define ETH_TDES3_OSTC 0x08000000
+#define ETH_TDES3_TCMSSV 0x04000000
+#define ETH_TDES3_CDE 0x00800000
+#define ETH_TDES3_IVLTV 0x00020000
+#define ETH_TDES3_VLTV 0x00010000
+#define ETH_TDES3_VT 0x0000FFFF
+
+/* Receive normal descriptor (read format) */
+#define ETH_RDES0_BUF1AP 0xFFFFFFFF
+#define ETH_RDES2_BUF2AP 0xFFFFFFFF
+#define ETH_RDES3_OWN 0x80000000
+#define ETH_RDES3_IOC 0x40000000
+#define ETH_RDES3_BUF2V 0x02000000
+#define ETH_RDES3_BUF1V 0x01000000
+
+/* Receive normal descriptor (write-back format) */
+#define ETH_RDES0_IVT 0xFFFF0000
+#define ETH_RDES0_OVT 0x0000FFFF
+#define ETH_RDES1_OPC 0xFFFF0000
+#define ETH_RDES1_TD 0x00008000
+#define ETH_RDES1_TSA 0x00004000
+#define ETH_RDES1_PV 0x00002000
+#define ETH_RDES1_PFT 0x00001000
+#define ETH_RDES1_PMT 0x00000F00
+#define ETH_RDES1_IPCE 0x00000080
+#define ETH_RDES1_IPCB 0x00000040
+#define ETH_RDES1_IPV6 0x00000020
+#define ETH_RDES1_IPV4 0x00000010
+#define ETH_RDES1_IPHE 0x00000008
+#define ETH_RDES1_PT 0x00000007
+#define ETH_RDES2_L3L4FM 0xE0000000
+#define ETH_RDES2_L4FM 0x10000000
+#define ETH_RDES2_L3FM 0x08000000
+#define ETH_RDES2_MADRM 0x07F80000
+#define ETH_RDES2_HF 0x00040000
+#define ETH_RDES2_DAF 0x00020000
+#define ETH_RDES2_SAF 0x00010000
+#define ETH_RDES2_VF 0x00008000
+#define ETH_RDES2_ARPRN 0x00000400
+#define ETH_RDES3_OWN 0x80000000
+#define ETH_RDES3_CTXT 0x40000000
+#define ETH_RDES3_FD 0x20000000
+#define ETH_RDES3_LD 0x10000000
+#define ETH_RDES3_RS2V 0x08000000
+#define ETH_RDES3_RS1V 0x04000000
+#define ETH_RDES3_RS0V 0x02000000
+#define ETH_RDES3_CE 0x01000000
+#define ETH_RDES3_GP 0x00800000
+#define ETH_RDES3_RWT 0x00400000
+#define ETH_RDES3_OE 0x00200000
+#define ETH_RDES3_RE 0x00100000
+#define ETH_RDES3_DE 0x00080000
+#define ETH_RDES3_LT 0x00070000
+#define ETH_RDES3_ES 0x00008000
+#define ETH_RDES3_PL 0x00007FFF
+
+/* Receive context descriptor */
+#define ETH_RDES0_RTSL 0xFFFFFFFF
+#define ETH_RDES1_RTSH 0xFFFFFFFF
+#define ETH_RDES3_OWN 0x80000000
+#define ETH_RDES3_CTXT 0x40000000
+
+#define RTL8211E_BMCR ((uint16_t)0x0000U) /* Basic Mode Control Register. */
+#define RTL8211E_BMSR ((uint16_t)0x0001U) /* Basic Mode Status Register. */
+#define RTL8211E_PHYID1 ((uint16_t)0x0002U) /* PHY Identifier Register 1. */
+#define RTL8211E_PHYID2 ((uint16_t)0x0003U) /* PHY Identifier Register 2. */
+#define RTL8211E_ANAR ((uint16_t)0x0004U) /* Auto-Negotiation Advertising Register. */
+#define RTL8211E_ANLPAR ((uint16_t)0x0005U) /* Auto-Negotiation Link Partner Ability Register. */
+#define RTL8211E_ANER ((uint16_t)0x0006U) /* Auto-Negotiation Expansion Register.*/
+#define RTL8211E_ANNPTR ((uint16_t)0x0007U) /* Auto-Negotiation Next Page Transmit Register.*/
+#define RTL8211E_ANNPRR ((uint16_t)0x0008U) /* Auto-Negotiation Next Page Receive Register. */
+#define RTL8211E_GBCR ((uint16_t)0x0009U) /* 1000Base-T Control Register. */
+#define RTL8211E_GBSR ((uint16_t)0x000AU) /* 1000Base-T Status Register. */
+#define RTL8211E_MMDACR ((uint16_t)0x000DU) /* MMD Access Control Register. */
+#define RTL8211E_MMDAADR ((uint16_t)0x000EU) /* MMD Access Address Data Register. */
+#define RTL8211E_GBESR ((uint16_t)0x000FU) /* 1000Base-T Extended Status Register. */
+#define RTL8211E_PHYCR ((uint16_t)0x0010U)
+#define RTL8211E_PHYSR ((uint16_t)0x0011U)
+#define RTL8211E_INER ((uint16_t)0x0012U) /* Interrupt Enable Register. */
+#define RTL8211E_INSR ((uint16_t)0x0013U) /* Interrupt Status Register. */
+#define RTL8211E_RXERC ((uint16_t)0x0018U)
+#define RTL8211E_LDPSR ((uint16_t)0x001BU)
+#define RTL8211E_EPAGSR ((uint16_t)0x001EU)
+#define RTL8211E_PAGSR ((uint16_t)0x001FU)
+
+/* Basic Mode Control register */
+#define RTL8211E_BMCR_RESET 0x8000
+#define RTL8211E_BMCR_LOOPBACK 0x4000
+#define RTL8211E_BMCR_SPEED_SEL_LSB 0x2000
+#define RTL8211E_BMCR_AN_EN 0x1000
+#define RTL8211E_BMCR_POWER_DOWN 0x0800
+#define RTL8211E_BMCR_ISOLATE 0x0400
+#define RTL8211E_BMCR_RESTART_AN 0x0200
+#define RTL8211E_BMCR_DUPLEX_MODE 0x0100
+#define RTL8211E_BMCR_COL_TEST 0x0080
+#define RTL8211E_BMCR_SPEED_SEL_MSB 0x0040
+
+/* Basic Mode Status register */
+#define RTL8211E_BMSR_100BT4 0x8000
+#define RTL8211E_BMSR_100BTX_FD 0x4000
+#define RTL8211E_BMSR_100BTX_HD 0x2000
+#define RTL8211E_BMSR_10BT_FD 0x1000
+#define RTL8211E_BMSR_10BT_HD 0x0800
+#define RTL8211E_BMSR_100BT2_FD 0x0400
+#define RTL8211E_BMSR_100BT2_HD 0x0200
+#define RTL8211E_BMSR_EXTENDED_STATUS 0x0100
+#define RTL8211E_BMSR_PREAMBLE_SUPPR 0x0040
+#define RTL8211E_BMSR_AN_COMPLETE 0x0020
+#define RTL8211E_BMSR_REMOTE_FAULT 0x0010
+#define RTL8211E_BMSR_AN_CAPABLE 0x0008
+#define RTL8211E_BMSR_LINK_STATUS 0x0004
+#define RTL8211E_BMSR_JABBER_DETECT 0x0002
+#define RTL8211E_BMSR_EXTENDED_CAPABLE 0x0001
+
+/* PHY Identifier 1 register */
+#define RTL8211E_PHYID1_OUI_MSB 0xFFFF
+#define RTL8211E_PHYID1_OUI_MSB_DEFAULT 0x001C
+
+/* PHY Identifier 2 register */
+#define RTL8211E_PHYID2_OUI_LSB 0xFC00
+#define RTL8211E_PHYID2_OUI_LSB_DEFAULT 0xC800
+#define RTL8211E_PHYID2_MODEL_NUM 0x03F0
+#define RTL8211E_PHYID2_MODEL_NUM_DEFAULT 0x0110
+#define RTL8211E_PHYID2_REVISION_NUM 0x000F
+#define RTL8211E_PHYID2_REVISION_NUM_DEFAULT 0x0005
+
+/* Auto-Negotiation Advertisement register */
+#define RTL8211E_ANAR_NEXT_PAGE 0x8000
+#define RTL8211E_ANAR_REMOTE_FAULT 0x2000
+#define RTL8211E_ANAR_ASYM_PAUSE 0x0800
+#define RTL8211E_ANAR_PAUSE 0x0400
+#define RTL8211E_ANAR_100BT4 0x0200
+#define RTL8211E_ANAR_100BTX_FD 0x0100
+#define RTL8211E_ANAR_100BTX_HD 0x0080
+#define RTL8211E_ANAR_10BT_FD 0x0040
+#define RTL8211E_ANAR_10BT_HD 0x0020
+#define RTL8211E_ANAR_SELECTOR 0x001F
+#define RTL8211E_ANAR_SELECTOR_DEFAULT 0x0001
+
+/* Auto-Negotiation Link Partner Ability register */
+#define RTL8211E_ANLPAR_NEXT_PAGE 0x8000
+#define RTL8211E_ANLPAR_ACK 0x4000
+#define RTL8211E_ANLPAR_REMOTE_FAULT 0x2000
+#define RTL8211E_ANLPAR_ASYM_PAUSE 0x0800
+#define RTL8211E_ANLPAR_PAUSE 0x0400
+#define RTL8211E_ANLPAR_100BT4 0x0200
+#define RTL8211E_ANLPAR_100BTX_FD 0x0100
+#define RTL8211E_ANLPAR_100BTX_HD 0x0080
+#define RTL8211E_ANLPAR_10BT_FD 0x0040
+#define RTL8211E_ANLPAR_10BT_HD 0x0020
+#define RTL8211E_ANLPAR_SELECTOR 0x001F
+#define RTL8211E_ANLPAR_SELECTOR_DEFAULT 0x0001
+
+/* Auto-Negotiation Expansion register */
+#define RTL8211E_ANER_PAR_DETECT_FAULT 0x0010
+#define RTL8211E_ANER_LP_NEXT_PAGE_ABLE 0x0008
+#define RTL8211E_ANER_NEXT_PAGE_ABLE 0x0004
+#define RTL8211E_ANER_PAGE_RECEIVED 0x0002
+#define RTL8211E_ANER_LP_AN_ABLE 0x0001
+
+/* Auto-Negotiation Next Page Transmit register */
+#define RTL8211E_ANNPTR_NEXT_PAGE 0x8000
+#define RTL8211E_ANNPTR_MSG_PAGE 0x2000
+#define RTL8211E_ANNPTR_ACK2 0x1000
+#define RTL8211E_ANNPTR_TOGGLE 0x0800
+#define RTL8211E_ANNPTR_MESSAGE 0x07FF
+
+/* Auto-Negotiation Next Page Receive register */
+#define RTL8211E_ANNPRR_NEXT_PAGE 0x8000
+#define RTL8211E_ANNPRR_ACK 0x4000
+#define RTL8211E_ANNPRR_MSG_PAGE 0x2000
+#define RTL8211E_ANNPRR_ACK2 0x1000
+#define RTL8211E_ANNPRR_TOGGLE 0x0800
+#define RTL8211E_ANNPRR_MESSAGE 0x07FF
+
+/* 1000Base-T Control register */
+#define RTL8211E_GBCR_TEST_MODE 0xE000
+#define RTL8211E_GBCR_MS_MAN_CONF_EN 0x1000
+#define RTL8211E_GBCR_MS_MAN_CONF_VAL 0x0800
+#define RTL8211E_GBCR_PORT_TYPE 0x0400
+#define RTL8211E_GBCR_1000BT_FD 0x0200
+
+/* 1000Base-T Status register */
+#define RTL8211E_GBSR_MS_CONF_FAULT 0x8000
+#define RTL8211E_GBSR_MS_CONF_RES 0x4000
+#define RTL8211E_GBSR_LOCAL_RECEIVER_STATUS 0x2000
+#define RTL8211E_GBSR_REMOTE_RECEIVER_STATUS 0x1000
+#define RTL8211E_GBSR_LP_1000BT_FD 0x0800
+#define RTL8211E_GBSR_LP_1000BT_HD 0x0400
+#define RTL8211E_GBSR_IDLE_ERR_COUNT 0x00FF
+
+/* MMD Access Control register */
+#define RTL8211E_MMDACR_FUNC 0xC000
+#define RTL8211E_MMDACR_FUNC_ADDR 0x0000
+#define RTL8211E_MMDACR_FUNC_DATA_NO_POST_INC 0x4000
+#define RTL8211E_MMDACR_FUNC_DATA_POST_INC_RW 0x8000
+#define RTL8211E_MMDACR_FUNC_DATA_POST_INC_W 0xC000
+#define RTL8211E_MMDACR_DEVAD 0x001F
+
+/* 1000Base-T Extended Status register */
+#define RTL8211E_GBESR_1000BX_FD 0x8000
+#define RTL8211E_GBESR_1000BX_HD 0x4000
+#define RTL8211E_GBESR_1000BT_FD 0x2000
+#define RTL8211E_GBESR_1000BT_HD 0x1000
+
+/* PHY Specific Control register */
+#define RTL8211E_PHYCR_RXC_DIS 0x8000
+#define RTL8211E_PHYCR_FPR_FAIL_SEL 0x7000
+#define RTL8211E_PHYCR_ASSERT_CRS_ON_TX 0x0800
+#define RTL8211E_PHYCR_FORCE_LINK_GOOD 0x0400
+#define RTL8211E_PHYCR_CROSSOVER_EN 0x0040
+#define RTL8211E_PHYCR_MDI_MODE 0x0020
+#define RTL8211E_PHYCR_CLK125_DIS 0x0010
+#define RTL8211E_PHYCR_JABBER_DIS 0x0001
+
+/* PHY Specific Status register */
+#define RTL8211E_PHYSR_SPEED 0xC000
+#define RTL8211E_PHYSR_SPEED_10MBPS 0x0000
+#define RTL8211E_PHYSR_SPEED_100MBPS 0x4000
+#define RTL8211E_PHYSR_SPEED_1000MBPS 0x8000
+#define RTL8211E_PHYSR_DUPLEX 0x2000
+#define RTL8211E_PHYSR_PAGE_RECEIVED 0x1000
+#define RTL8211E_PHYSR_SPEED_DUPLEX_RESOLVED 0x0800
+#define RTL8211E_PHYSR_LINK 0x0400
+#define RTL8211E_PHYSR_MDI_CROSSOVER_STATUS 0x0040
+#define RTL8211E_PHYSR_PRE_LINKOK 0x0002
+#define RTL8211E_PHYSR_JABBER 0x0001
+
+/* Interrupt Status register */
+#define RTL8211E_INER_AN_ERROR 0x8000
+#define RTL8211E_INER_PAGE_RECEIVED 0x1000
+#define RTL8211E_INER_AN_COMPLETE 0x0800
+#define RTL8211E_INER_LINK_STATUS 0x0400
+#define RTL8211E_INER_SYMBOL_ERROR 0x0200
+#define RTL8211E_INER_FALSE_CARRIER 0x0100
+#define RTL8211E_INER_JABBER 0x0001
+
+/* Interrupt Status register */
+#define RTL8211E_INSR_AN_ERROR 0x8000
+#define RTL8211E_INSR_PAGE_RECEIVED 0x1000
+#define RTL8211E_INSR_AN_COMPLETE 0x0800
+#define RTL8211E_INSR_LINK_STATUS 0x0400
+#define RTL8211E_INSR_SYMBOL_ERROR 0x0200
+#define RTL8211E_INSR_FALSE_CARRIER 0x0100
+#define RTL8211E_INSR_JABBER 0x0001
+
+/* Link Down Power Saving register */
+#define RTL8211E_LDPSR_POWER_SAVE_MODE 0x0001
+
+/* Extension Page Select register */
+#define RTL8211E_EPAGSR_EXT_PAGE_SEL 0x00FF
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.c
new file mode 100644
index 0000000000..d02902ca3e
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.c
@@ -0,0 +1,1602 @@
+/**
+ ******************************************************************************
+ * @file mfxstm32l152.c
+ * @author MCD Application Team
+ * @brief This file provides a set of functions needed to manage the MFXSTM32L152
+ * IO Expander devices.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "mfxstm32l152.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup MFXSTM32L152
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Types_Definitions
+ * @{
+ */
+
+/* Private define ------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Defines
+ * @{
+ */
+#define MFXSTM32L152_MAX_INSTANCE 3
+
+/* Private macro -------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Macros
+ * @{
+ */
+
+/* Private variables ---------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Variables
+ * @{
+ */
+
+/* Touch screen driver structure initialization */
+TS_DrvTypeDef mfxstm32l152_ts_drv =
+{
+ mfxstm32l152_Init,
+ mfxstm32l152_ReadID,
+ mfxstm32l152_Reset,
+
+ mfxstm32l152_TS_Start,
+ mfxstm32l152_TS_DetectTouch,
+ mfxstm32l152_TS_GetXY,
+
+ mfxstm32l152_TS_EnableIT,
+ mfxstm32l152_TS_ClearIT,
+ mfxstm32l152_TS_ITStatus,
+ mfxstm32l152_TS_DisableIT,
+};
+
+/* IO driver structure initialization */
+IO_DrvTypeDef mfxstm32l152_io_drv =
+{
+ mfxstm32l152_Init,
+ mfxstm32l152_ReadID,
+ mfxstm32l152_Reset,
+
+ mfxstm32l152_IO_Start,
+ mfxstm32l152_IO_Config,
+ mfxstm32l152_IO_WritePin,
+ mfxstm32l152_IO_ReadPin,
+
+ mfxstm32l152_IO_EnableIT,
+ mfxstm32l152_IO_DisableIT,
+ mfxstm32l152_IO_ITStatus,
+ mfxstm32l152_IO_ClearIT,
+};
+
+/* IDD driver structure initialization */
+IDD_DrvTypeDef mfxstm32l152_idd_drv =
+{
+ mfxstm32l152_Init,
+ mfxstm32l152_DeInit,
+ mfxstm32l152_ReadID,
+ mfxstm32l152_Reset,
+ mfxstm32l152_LowPower,
+ mfxstm32l152_WakeUp,
+
+ mfxstm32l152_IDD_Start,
+ mfxstm32l152_IDD_Config,
+ mfxstm32l152_IDD_GetValue,
+
+ mfxstm32l152_IDD_EnableIT,
+ mfxstm32l152_IDD_ClearIT,
+ mfxstm32l152_IDD_GetITStatus,
+ mfxstm32l152_IDD_DisableIT,
+
+ mfxstm32l152_Error_EnableIT,
+ mfxstm32l152_Error_ClearIT,
+ mfxstm32l152_Error_GetITStatus,
+ mfxstm32l152_Error_DisableIT,
+ mfxstm32l152_Error_ReadSrc,
+ mfxstm32l152_Error_ReadMsg
+};
+
+
+/* mfxstm32l152 instances by address */
+uint8_t mfxstm32l152[MFXSTM32L152_MAX_INSTANCE] = {0};
+/**
+ * @}
+ */
+
+/* Private function prototypes -----------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Function_Prototypes
+ * @{
+ */
+static uint8_t mfxstm32l152_GetInstance(uint16_t DeviceAddr);
+static uint8_t mfxstm32l152_ReleaseInstance(uint16_t DeviceAddr);
+static void mfxstm32l152_reg24_setPinValue(uint16_t DeviceAddr, uint8_t RegisterAddr, uint32_t PinPosition, uint8_t PinValue );
+
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Initialize the mfxstm32l152 and configure the needed hardware resources
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_Init(uint16_t DeviceAddr)
+{
+ uint8_t instance;
+ uint8_t empty;
+
+ /* Check if device instance already exists */
+ instance = mfxstm32l152_GetInstance(DeviceAddr);
+
+ /* To prevent double initialization */
+ if(instance == 0xFF)
+ {
+ /* Look for empty instance */
+ empty = mfxstm32l152_GetInstance(0);
+
+ if(empty < MFXSTM32L152_MAX_INSTANCE)
+ {
+ /* Register the current device instance */
+ mfxstm32l152[empty] = DeviceAddr;
+
+ /* Initialize IO BUS layer */
+ MFX_IO_Init();
+ }
+ }
+
+ mfxstm32l152_SetIrqOutPinPolarity(DeviceAddr, MFXSTM32L152_OUT_PIN_POLARITY_HIGH);
+ mfxstm32l152_SetIrqOutPinType(DeviceAddr, MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL);
+}
+
+/**
+ * @brief DeInitialize the mfxstm32l152 and unconfigure the needed hardware resources
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_DeInit(uint16_t DeviceAddr)
+{
+ uint8_t instance;
+
+ /* release existing instance */
+ instance = mfxstm32l152_ReleaseInstance(DeviceAddr);
+
+ /* De-Init only if instance was previously registered */
+ if(instance != 0xFF)
+ {
+ /* De-Initialize IO BUS layer */
+ MFX_IO_DeInit();
+ }
+}
+
+/**
+ * @brief Reset the mfxstm32l152 by Software.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_Reset(uint16_t DeviceAddr)
+{
+ /* Soft Reset */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, MFXSTM32L152_SWRST);
+
+ /* Wait for a delay to ensure registers erasing */
+ rt_thread_delay(10);
+}
+
+/**
+ * @brief Put mfxstm32l152 Device in Low Power standby mode
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_LowPower(uint16_t DeviceAddr)
+{
+ /* Enter standby mode */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, MFXSTM32L152_STANDBY);
+
+ /* enable wakeup pin */
+ MFX_IO_EnableWakeupPin();
+}
+
+/**
+ * @brief WakeUp mfxstm32l152 from standby mode
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_WakeUp(uint16_t DeviceAddr)
+{
+ uint8_t instance;
+
+ /* Check if device instance already exists */
+ instance = mfxstm32l152_GetInstance(DeviceAddr);
+
+ /* if instance does not exist, first initialize pins*/
+ if(instance == 0xFF)
+ {
+ /* enable wakeup pin */
+ MFX_IO_EnableWakeupPin();
+ }
+
+ /* toggle wakeup pin */
+ MFX_IO_Wakeup();
+}
+
+/**
+ * @brief Read the MFXSTM32L152 IO Expander device ID.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval The Device ID (two bytes).
+ */
+uint16_t mfxstm32l152_ReadID(uint16_t DeviceAddr)
+{
+ uint8_t id;
+
+ /* Wait for a delay to ensure the state of registers */
+ rt_thread_mdelay(1);
+
+ /* Initialize IO BUS layer */
+ MFX_IO_Init();
+
+ id = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_ID);
+
+ /* Return the device ID value */
+ return (id);
+}
+
+/**
+ * @brief Read the MFXSTM32L152 device firmware version.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval The Device FW version (two bytes).
+ */
+uint16_t mfxstm32l152_ReadFwVersion(uint16_t DeviceAddr)
+{
+ uint8_t data[2];
+
+ MFX_IO_ReadMultiple((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_FW_VERSION_MSB, data, sizeof(data)) ;
+
+ /* Recompose MFX firmware value */
+ return ((data[0] << 8) | data[1]);
+}
+
+/**
+ * @brief Enable the interrupt mode for the selected IT source
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: The interrupt source to be configured, could be:
+ * @arg MFXSTM32L152_IRQ_GPIO: IO interrupt
+ * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt
+ * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt
+ * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt
+ * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty
+ * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered
+ * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full
+ * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow
+ * @retval None
+ */
+void mfxstm32l152_EnableITSource(uint16_t DeviceAddr, uint8_t Source)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current value of the INT_EN register */
+ tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN);
+
+ /* Set the interrupts to be Enabled */
+ tmp |= Source;
+
+ /* Set the register */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN, tmp);
+}
+
+/**
+ * @brief Disable the interrupt mode for the selected IT source
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: The interrupt source to be configured, could be:
+ * @arg MFXSTM32L152_IRQ_GPIO: IO interrupt
+ * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt
+ * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt
+ * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt
+ * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty
+ * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered
+ * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full
+ * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow
+ * @retval None
+ */
+void mfxstm32l152_DisableITSource(uint16_t DeviceAddr, uint8_t Source)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current value of the INT_EN register */
+ tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN);
+
+ /* Set the interrupts to be Enabled */
+ tmp &= ~Source;
+
+ /* Set the register */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_SRC_EN, tmp);
+}
+
+
+/**
+ * @brief Returns the selected Global interrupt source pending bit value
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: the Global interrupt source to be checked, could be:
+ * @arg MFXSTM32L152_IRQ_GPIO: IO interrupt
+ * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt
+ * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt
+ * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt
+ * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty
+ * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered
+ * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full
+ * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow
+ * @retval The value of the checked Global interrupt source status.
+ */
+uint8_t mfxstm32l152_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source)
+{
+ /* Return the global IT source status (pending or not)*/
+ return((MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_PENDING) & Source));
+}
+
+/**
+ * @brief Clear the selected Global interrupt pending bit(s)
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Source: the Global interrupt source to be cleared, could be any combination
+ * of the below values. The acknowledge signal for MFXSTM32L152_GPIOs configured in input
+ * with interrupt is not on this register but in IRQ_GPI_ACK1, IRQ_GPI_ACK2 registers.
+ * @arg MFXSTM32L152_IRQ_IDD : IDD interrupt
+ * @arg MFXSTM32L152_IRQ_ERROR : Error interrupt
+ * @arg MFXSTM32L152_IRQ_TS_DET : Touch Screen Controller Touch Detected interrupt
+ * @arg MFXSTM32L152_IRQ_TS_NE : Touch Screen FIFO Not Empty
+ * @arg MFXSTM32L152_IRQ_TS_TH : Touch Screen FIFO threshold triggered
+ * @arg MFXSTM32L152_IRQ_TS_FULL : Touch Screen FIFO Full
+ * @arg MFXSTM32L152_IRQ_TS_OVF : Touch Screen FIFO Overflow
+ * /\/\ IMPORTANT NOTE /\/\ must not use MFXSTM32L152_IRQ_GPIO as argument, see IRQ_GPI_ACK1 and IRQ_GPI_ACK2 registers
+ * @retval None
+ */
+void mfxstm32l152_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source)
+{
+ /* Write 1 to the bits that have to be cleared */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_ACK, Source);
+}
+
+/**
+ * @brief Set the global interrupt Polarity of IRQ_OUT_PIN.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Polarity: the IT mode polarity, could be one of the following values:
+ * @arg MFXSTM32L152_OUT_PIN_POLARITY_LOW: Interrupt output line is active Low edge
+ * @arg MFXSTM32L152_OUT_PIN_POLARITY_HIGH: Interrupt line output is active High edge
+ * @retval None
+ */
+void mfxstm32l152_SetIrqOutPinPolarity(uint16_t DeviceAddr, uint8_t Polarity)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current register value */
+ tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT);
+
+ /* Mask the polarity bits */
+ tmp &= ~(uint8_t)0x02;
+
+ /* Modify the Interrupt Output line configuration */
+ tmp |= Polarity;
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT, tmp);
+
+ /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */
+ rt_thread_delay(1);
+
+}
+
+/**
+ * @brief Set the global interrupt Type of IRQ_OUT_PIN.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param Type: Interrupt line activity type, could be one of the following values:
+ * @arg MFXSTM32L152_OUT_PIN_TYPE_OPENDRAIN: Open Drain output Interrupt line
+ * @arg MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL: Push Pull output Interrupt line
+ * @retval None
+ */
+void mfxstm32l152_SetIrqOutPinType(uint16_t DeviceAddr, uint8_t Type)
+{
+ uint8_t tmp = 0;
+
+ /* Get the current register value */
+ tmp = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT);
+
+ /* Mask the type bits */
+ tmp &= ~(uint8_t)0x01;
+
+ /* Modify the Interrupt Output line configuration */
+ tmp |= Type;
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_MFX_IRQ_OUT, tmp);
+
+ /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */
+ rt_thread_delay(1);
+
+}
+
+
+/* ------------------------------------------------------------------ */
+/* ----------------------- GPIO ------------------------------------- */
+/* ------------------------------------------------------------------ */
+
+
+/**
+ * @brief Start the IO functionality used and enable the AF for selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param AF_en: 0 to disable, else enabled.
+ * @retval None
+ */
+void mfxstm32l152_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ uint8_t mode;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+ /* Set the IO Functionalities to be Enabled */
+ mode |= MFXSTM32L152_GPIO_EN;
+
+ /* Enable ALTERNATE functions */
+ /* AGPIO[0..3] can be either IDD or GPIO */
+ /* AGPIO[4..7] can be either TS or GPIO */
+ /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */
+ /* however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */
+ /* so if IDD and TS are both active it is better to let ALTERNATE off (0) */
+ /* if however IDD or TS are not connected then set it on gives more GPIOs availability */
+ /* remind that AGPIO are less efficient then normal GPIO (They use pooling rather then EXTI */
+ if (IO_Pin > 0xFFFF)
+ {
+ mode |= MFXSTM32L152_ALTERNATE_GPIO_EN;
+ }
+ else
+ {
+ mode &= ~MFXSTM32L152_ALTERNATE_GPIO_EN;
+ }
+
+ /* Write the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+
+ /* Wait for 1 ms for MFX to change IRQ_out pin config, before activate it */
+ rt_thread_delay(1);
+}
+
+/**
+ * @brief Configures the IO pin(s) according to IO mode structure value.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The output pin to be set or reset. This parameter can be one
+ * of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @param IO_Mode: The IO pin mode to configure, could be one of the following values:
+ * @arg IO_MODE_INPUT
+ * @arg IO_MODE_OUTPUT
+ * @arg IO_MODE_IT_RISING_EDGE
+ * @arg IO_MODE_IT_FALLING_EDGE
+ * @arg IO_MODE_IT_LOW_LEVEL
+ * @arg IO_MODE_IT_HIGH_LEVEL
+ * @arg IO_MODE_INPUT_PU,
+ * @arg IO_MODE_INPUT_PD,
+ * @arg IO_MODE_OUTPUT_OD_PU,
+ * @arg IO_MODE_OUTPUT_OD_PD,
+ * @arg IO_MODE_OUTPUT_PP_PU,
+ * @arg IO_MODE_OUTPUT_PP_PD,
+ * @arg IO_MODE_IT_RISING_EDGE_PU
+ * @arg IO_MODE_IT_FALLING_EDGE_PU
+ * @arg IO_MODE_IT_LOW_LEVEL_PU
+ * @arg IO_MODE_IT_HIGH_LEVEL_PU
+ * @arg IO_MODE_IT_RISING_EDGE_PD
+ * @arg IO_MODE_IT_FALLING_EDGE_PD
+ * @arg IO_MODE_IT_LOW_LEVEL_PD
+ * @arg IO_MODE_IT_HIGH_LEVEL_PD
+ * @retval None
+ */
+uint8_t mfxstm32l152_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode)
+{
+ uint8_t error_code = 0;
+
+ /* Configure IO pin according to selected IO mode */
+ switch(IO_Mode)
+ {
+ case IO_MODE_OFF: /* Off or analog mode */
+ case IO_MODE_ANALOG: /* Off or analog mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ break;
+
+ case IO_MODE_INPUT: /* Input mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ break;
+
+ case IO_MODE_INPUT_PU: /* Input mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ break;
+
+ case IO_MODE_INPUT_PD: /* Input mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ break;
+
+ case IO_MODE_OUTPUT: /* Output mode */
+ case IO_MODE_OUTPUT_PP_PD: /* Output mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_PUSH_PULL);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ break;
+
+ case IO_MODE_OUTPUT_PP_PU: /* Output mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_PUSH_PULL);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ break;
+
+ case IO_MODE_OUTPUT_OD_PD: /* Output mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_OPEN_DRAIN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ break;
+
+ case IO_MODE_OUTPUT_OD_PU: /* Output mode */
+ mfxstm32l152_IO_DisablePinIT(DeviceAddr, IO_Pin); /* first disable IT */
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_OUT);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPO_OPEN_DRAIN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ break;
+
+ case IO_MODE_IT_RISING_EDGE: /* Interrupt rising edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_RISING_EDGE_PU: /* Interrupt rising edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_RISING_EDGE_PD: /* Interrupt rising edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_FALLING_EDGE: /* Interrupt falling edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_FALLING_EDGE_PU: /* Interrupt falling edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_FALLING_EDGE_PD: /* Interrupt falling edge mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_EDGE);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_LOW_LEVEL: /* Low level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_LOW_LEVEL_PU: /* Low level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_LOW_LEVEL_PD: /* Low level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_LLFE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_HIGH_LEVEL: /* High level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_HIGH_LEVEL_PU: /* High level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_UP);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ case IO_MODE_IT_HIGH_LEVEL_PD: /* High level interrupt mode */
+ mfxstm32l152_IO_EnableIT(DeviceAddr);
+ mfxstm32l152_IO_InitPin(DeviceAddr, IO_Pin, MFXSTM32L152_GPIO_DIR_IN);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_TYPE1, IO_Pin, MFXSTM32L152_GPI_WITH_PULL_RESISTOR);
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_PUPD1, IO_Pin, MFXSTM32L152_GPIO_PULL_DOWN);
+ mfxstm32l152_IO_SetIrqEvtMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_EVT_LEVEL);
+ mfxstm32l152_IO_SetIrqTypeMode(DeviceAddr, IO_Pin, MFXSTM32L152_IRQ_GPI_TYPE_HLRE);
+ mfxstm32l152_IO_EnablePinIT(DeviceAddr, IO_Pin); /* last to do: enable IT */
+ break;
+
+ default:
+ error_code = (uint8_t) IO_Mode;
+ break;
+ }
+
+ return error_code;
+}
+
+/**
+ * @brief Initialize the selected IO pin direction.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin to be configured. This parameter could be any
+ * combination of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.
+ * @param Direction: could be MFXSTM32L152_GPIO_DIR_IN or MFXSTM32L152_GPIO_DIR_OUT.
+ * @retval None
+ */
+void mfxstm32l152_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction)
+{
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_DIR1, IO_Pin, Direction);
+}
+
+/**
+ * @brief Set the global interrupt Type.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin to be configured. This parameter could be any
+ * combination of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.
+ * @param Evt: Interrupt line activity type, could be one of the following values:
+ * @arg MFXSTM32L152_IRQ_GPI_EVT_LEVEL: Interrupt line is active in level model
+ * @arg MFXSTM32L152_IRQ_GPI_EVT_EDGE: Interrupt line is active in edge model
+ * @retval None
+ */
+void mfxstm32l152_IO_SetIrqEvtMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Evt)
+{
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_EVT1, IO_Pin, Evt);
+ rt_thread_delay(1);
+}
+
+/**
+ * @brief Configure the Edge for which a transition is detectable for the
+ * selected pin.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO pin to be configured. This parameter could be any
+ * combination of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.
+ * @param Evt: Interrupt line activity type, could be one of the following values:
+ * @arg MFXSTM32L152_IRQ_GPI_TYPE_LLFE: Interrupt line is active in Low Level or Falling Edge
+ * @arg MFXSTM32L152_IRQ_GPI_TYPE_HLRE: Interrupt line is active in High Level or Rising Edge
+ * @retval None
+ */
+void mfxstm32l152_IO_SetIrqTypeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Type)
+{
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE1, IO_Pin, Type);
+ rt_thread_delay(1);
+}
+
+/**
+ * @brief When GPIO is in output mode, puts the corresponding GPO in High (1) or Low (0) level.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The output pin to be set or reset. This parameter can be one
+ * of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @param PinState: The new IO pin state.
+ * @retval None
+ */
+void mfxstm32l152_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState)
+{
+ /* Apply the bit value to the selected pin */
+ if (PinState != 0)
+ {
+ /* Set the SET register */
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPO_SET1, IO_Pin, 1);
+ }
+ else
+ {
+ /* Set the CLEAR register */
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_GPO_CLR1, IO_Pin, 1);
+ }
+}
+
+/**
+ * @brief Return the state of the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The output pin to be set or reset. This parameter can be one
+ * of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @retval IO pin(s) state.
+ */
+uint32_t mfxstm32l152_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ uint32_t tmp1 = 0;
+ uint32_t tmp2 = 0;
+ uint32_t tmp3 = 0;
+
+ if(IO_Pin & 0x000000FF)
+ {
+ tmp1 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE1);
+ }
+ if(IO_Pin & 0x0000FF00)
+ {
+ tmp2 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE2);
+ }
+ if(IO_Pin & 0x00FF0000)
+ {
+ tmp3 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_GPIO_STATE3);
+ }
+
+ tmp3 = tmp1 + (tmp2 << 8) + (tmp3 << 16);
+
+ return(tmp3 & IO_Pin);
+}
+
+/**
+ * @brief Enable the global IO interrupt source.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_IO_EnableIT(uint16_t DeviceAddr)
+{
+ MFX_IO_ITConfig();
+
+ /* Enable global IO IT source */
+ mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_GPIO);
+}
+
+/**
+ * @brief Disable the global IO interrupt source.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_IO_DisableIT(uint16_t DeviceAddr)
+{
+ /* Disable global IO IT source */
+ mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_GPIO);
+}
+
+/**
+ * @brief Enable interrupt mode for the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO interrupt to be enabled. This parameter could be any
+ * combination of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @retval None
+ */
+void mfxstm32l152_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1, IO_Pin, 1);
+}
+
+/**
+ * @brief Disable interrupt mode for the selected IO pin(s).
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO interrupt to be disabled. This parameter could be any
+ * combination of the following values:
+ * @arg MFXSTM32L152_GPIO_PIN_x: where x can be from 0 to 23.
+ * @retval None
+ */
+void mfxstm32l152_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ mfxstm32l152_reg24_setPinValue(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1, IO_Pin, 0);
+}
+
+
+/**
+ * @brief Check the status of the selected IO interrupt pending bit
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: The IO interrupt to be checked could be:
+ * @arg MFXSTM32L152_GPIO_PIN_x Where x can be from 0 to 23.
+ * @retval Status of the checked IO pin(s).
+ */
+uint32_t mfxstm32l152_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ /* Get the Interrupt status */
+ uint8_t tmp1 = 0;
+ uint16_t tmp2 = 0;
+ uint32_t tmp3 = 0;
+
+ if(IO_Pin & 0xFF)
+ {
+ tmp1 = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING1);
+ }
+ if(IO_Pin & 0xFFFF00)
+ {
+ tmp2 = (uint16_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING2);
+ }
+ if(IO_Pin & 0xFFFF0000)
+ {
+ tmp3 = (uint32_t) MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING3);
+ }
+
+ tmp3 = tmp1 + (tmp2 << 8) + (tmp3 << 16);
+
+ return(tmp3 & IO_Pin);
+}
+
+/**
+ * @brief Clear the selected IO interrupt pending bit(s). It clear automatically also the general MFXSTM32L152_REG_ADR_IRQ_PENDING
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param IO_Pin: the IO interrupt to be cleared, could be:
+ * @arg MFXSTM32L152_GPIO_PIN_x: Where x can be from 0 to 23.
+ * @retval None
+ */
+void mfxstm32l152_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin)
+{
+ /* Clear the IO IT pending bit(s) by acknowledging */
+ /* it cleans automatically also the Global IRQ_GPIO */
+ /* normally this function is called under interrupt */
+ uint8_t pin_0_7, pin_8_15, pin_16_23;
+
+ pin_0_7 = IO_Pin & 0x0000ff;
+ pin_8_15 = IO_Pin >> 8;
+ pin_8_15 = pin_8_15 & 0x00ff;
+ pin_16_23 = IO_Pin >> 16;
+
+ if (pin_0_7)
+ {
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK1, pin_0_7);
+ }
+ if (pin_8_15)
+ {
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK2, pin_8_15);
+ }
+ if (pin_16_23)
+ {
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_IRQ_GPI_ACK3, pin_16_23);
+ }
+}
+
+
+/**
+ * @brief Enable the AF for aGPIO.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_IO_EnableAF(uint16_t DeviceAddr)
+{
+ uint8_t mode;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+ /* Enable ALTERNATE functions */
+ /* AGPIO[0..3] can be either IDD or GPIO */
+ /* AGPIO[4..7] can be either TS or GPIO */
+ /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */
+ /* however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */
+ /* so if IDD and TS are both active it is better to let ALTERNATE disabled (0) */
+ /* if however IDD or TS are not connected then set it on gives more GPIOs availability */
+ /* remind that AGPIO are less efficient then normal GPIO (they use pooling rather then EXTI) */
+ mode |= MFXSTM32L152_ALTERNATE_GPIO_EN;
+
+ /* Write the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+}
+
+/**
+ * @brief Disable the AF for aGPIO.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+ void mfxstm32l152_IO_DisableAF(uint16_t DeviceAddr)
+{
+ uint8_t mode;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+ /* Enable ALTERNATE functions */
+ /* AGPIO[0..3] can be either IDD or GPIO */
+ /* AGPIO[4..7] can be either TS or GPIO */
+ /* if IDD or TS are enabled no matter the value this bit GPIO are not available for those pins */
+ /* however the MFX will waste some cycles to to handle these potential GPIO (pooling, etc) */
+ /* so if IDD and TS are both active it is better to let ALTERNATE disabled (0) */
+ /* if however IDD or TS are not connected then set it on gives more GPIOs availability */
+ /* remind that AGPIO are less efficient then normal GPIO (they use pooling rather then EXTI) */
+ mode &= ~MFXSTM32L152_ALTERNATE_GPIO_EN;
+
+ /* Write the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+
+}
+
+
+/* ------------------------------------------------------------------ */
+/* --------------------- TOUCH SCREEN ------------------------------- */
+/* ------------------------------------------------------------------ */
+
+/**
+ * @brief Configures the touch Screen Controller (Single point detection)
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None.
+ */
+void mfxstm32l152_TS_Start(uint16_t DeviceAddr)
+{
+ uint8_t mode;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+ /* Set the Functionalities to be Enabled */
+ mode |= MFXSTM32L152_TS_EN;
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+
+ /* Wait for 2 ms */
+ rt_thread_delay(2);
+
+ /* Select 2 nF filter capacitor */
+ /* Configuration:
+ - Touch average control : 4 samples
+ - Touch delay time : 500 uS
+ - Panel driver setting time: 500 uS
+ */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_SETTLING, 0x32);
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_TOUCH_DET_DELAY, 0x5);
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_AVE, 0x04);
+
+ /* Configure the Touch FIFO threshold: single point reading */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, 0x01);
+
+ /* Clear the FIFO memory content. */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, MFXSTM32L152_TS_CLEAR_FIFO);
+
+ /* Touch screen control configuration :
+ - No window tracking index
+ */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_TRACK, 0x00);
+
+
+ /* Clear all the IT status pending bits if any */
+ mfxstm32l152_IO_ClearIT(DeviceAddr, 0xFFFFFF);
+
+ /* Wait for 1 ms delay */
+ rt_thread_delay(1);
+}
+
+/**
+ * @brief Return if there is touch detected or not.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Touch detected state.
+ */
+uint8_t mfxstm32l152_TS_DetectTouch(uint16_t DeviceAddr)
+{
+ uint8_t state;
+ uint8_t ret = 0;
+
+ state = MFX_IO_Read(DeviceAddr, MFXSTM32L152_TS_FIFO_STA);
+ state = ((state & (uint8_t)MFXSTM32L152_TS_CTRL_STATUS) == (uint8_t)MFXSTM32L152_TS_CTRL_STATUS);
+
+ if(state > 0)
+ {
+ if(MFX_IO_Read(DeviceAddr, MFXSTM32L152_TS_FIFO_LEVEL) > 0)
+ {
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * @brief Get the touch screen X and Y positions values
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param X: Pointer to X position value
+ * @param Y: Pointer to Y position value
+ * @retval None.
+ */
+void mfxstm32l152_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y)
+{
+ uint8_t data_xy[3];
+
+ MFX_IO_ReadMultiple(DeviceAddr, MFXSTM32L152_TS_XY_DATA, data_xy, sizeof(data_xy)) ;
+
+ /* Calculate positions values */
+ *X = (data_xy[1]<<4) + (data_xy[0]>>4);
+ *Y = (data_xy[2]<<4) + (data_xy[0]&4);
+
+ /* Reset the FIFO memory content. */
+ MFX_IO_Write(DeviceAddr, MFXSTM32L152_TS_FIFO_TH, MFXSTM32L152_TS_CLEAR_FIFO);
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_TS_EnableIT(uint16_t DeviceAddr)
+{
+ MFX_IO_ITConfig();
+
+ /* Enable global TS IT source */
+ mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_TS_DET);
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_TS_DisableIT(uint16_t DeviceAddr)
+{
+ /* Disable global TS IT source */
+ mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_TS_DET);
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval TS interrupts status
+ */
+uint8_t mfxstm32l152_TS_ITStatus(uint16_t DeviceAddr)
+{
+ /* Return TS interrupts status */
+ return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_TS));
+}
+
+/**
+ * @brief Configure the selected source to generate a global interrupt or not
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_TS_ClearIT(uint16_t DeviceAddr)
+{
+ /* Clear the global TS IT source */
+ mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_TS);
+}
+
+/* ------------------------------------------------------------------ */
+/* --------------------- IDD MEASUREMENT ---------------------------- */
+/* ------------------------------------------------------------------ */
+
+/**
+ * @brief Launch IDD current measurement
+ * @param DeviceAddr: Device address on communication Bus
+ * @retval None.
+ */
+void mfxstm32l152_IDD_Start(uint16_t DeviceAddr)
+{
+ uint8_t mode = 0;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL);
+
+ /* Set the Functionalities to be enabled */
+ mode |= MFXSTM32L152_IDD_CTRL_REQ;
+
+ /* Start measurement campaign */
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, mode);
+}
+
+/**
+ * @brief Configures the IDD current measurement
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param MfxIddConfig: Parameters depending on hardware config.
+ * @retval None
+ */
+void mfxstm32l152_IDD_Config(uint16_t DeviceAddr, IDD_ConfigTypeDef MfxIddConfig)
+{
+ uint8_t value = 0;
+ uint8_t mode = 0;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL);
+
+ if((mode & MFXSTM32L152_IDD_EN) != MFXSTM32L152_IDD_EN)
+ {
+ /* Set the Functionalities to be enabled */
+ mode |= MFXSTM32L152_IDD_EN;
+
+ /* Set the new register value */
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_SYS_CTRL, mode);
+ }
+
+ /* Control register setting: number of shunts */
+ value = ((MfxIddConfig.ShuntNbUsed << 1) & MFXSTM32L152_IDD_CTRL_SHUNT_NB);
+ value |= (MfxIddConfig.VrefMeasurement & MFXSTM32L152_IDD_CTRL_VREF_DIS);
+ value |= (MfxIddConfig.Calibration & MFXSTM32L152_IDD_CTRL_CAL_DIS);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, value);
+
+ /* Idd pre delay configuration: unit and value*/
+ value = (MfxIddConfig.PreDelayUnit & MFXSTM32L152_IDD_PREDELAY_UNIT) |
+ (MfxIddConfig.PreDelayValue & MFXSTM32L152_IDD_PREDELAY_VALUE);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_PRE_DELAY, value);
+
+ /* Shunt 0 register value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.Shunt0Value >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT0_MSB, value);
+ value = (uint8_t) (MfxIddConfig.Shunt0Value);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT0_LSB, value);
+
+ /* Shunt 1 register value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.Shunt1Value >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT1_MSB, value);
+ value = (uint8_t) (MfxIddConfig.Shunt1Value);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT1_LSB, value);
+
+ /* Shunt 2 register value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.Shunt2Value >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT2_MSB, value);
+ value = (uint8_t) (MfxIddConfig.Shunt2Value);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT2_LSB, value);
+
+ /* Shunt 3 register value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.Shunt3Value >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT3_MSB, value);
+ value = (uint8_t) (MfxIddConfig.Shunt3Value);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT3_LSB, value);
+
+ /* Shunt 4 register value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.Shunt4Value >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT4_MSB, value);
+ value = (uint8_t) (MfxIddConfig.Shunt4Value);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT4_LSB, value);
+
+ /* Shunt 0 stabilization delay */
+ value = MfxIddConfig.Shunt0StabDelay;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH0_STABILIZATION, value);
+
+ /* Shunt 1 stabilization delay */
+ value = MfxIddConfig.Shunt1StabDelay;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH1_STABILIZATION, value);
+
+ /* Shunt 2 stabilization delay */
+ value = MfxIddConfig.Shunt2StabDelay;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH2_STABILIZATION, value);
+
+ /* Shunt 3 stabilization delay */
+ value = MfxIddConfig.Shunt3StabDelay;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH3_STABILIZATION, value);
+
+ /* Shunt 4 stabilization delay */
+ value = MfxIddConfig.Shunt4StabDelay;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SH4_STABILIZATION, value);
+
+ /* Idd ampli gain value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.AmpliGain >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_GAIN_MSB, value);
+ value = (uint8_t) (MfxIddConfig.AmpliGain);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_GAIN_LSB, value);
+
+ /* Idd VDD min value: MSB then LSB */
+ value = (uint8_t) (MfxIddConfig.VddMin >> 8);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VDD_MIN_MSB, value);
+ value = (uint8_t) (MfxIddConfig.VddMin);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VDD_MIN_LSB, value);
+
+ /* Idd number of measurements */
+ value = MfxIddConfig.MeasureNb;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_NBR_OF_MEAS, value);
+
+ /* Idd delta delay configuration: unit and value */
+ value = (MfxIddConfig.DeltaDelayUnit & MFXSTM32L152_IDD_DELTADELAY_UNIT) |
+ (MfxIddConfig.DeltaDelayValue & MFXSTM32L152_IDD_DELTADELAY_VALUE);
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_MEAS_DELTA_DELAY, value);
+
+ /* Idd number of shut on board */
+ value = MfxIddConfig.ShuntNbOnBoard;
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNTS_ON_BOARD, value);
+}
+
+/**
+ * @brief This function allows to modify number of shunt used for a measurement
+ * @param DeviceAddr: Device address on communication Bus
+ * @retval None.
+ */
+void mfxstm32l152_IDD_ConfigShuntNbLimit(uint16_t DeviceAddr, uint8_t ShuntNbLimit)
+{
+ uint8_t mode = 0;
+
+ /* Get the current register value */
+ mode = MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL);
+
+ /* Clear number of shunt limit */
+ mode &= ~(MFXSTM32L152_IDD_CTRL_SHUNT_NB);
+
+ /* Clear number of shunt limit */
+ mode |= ((ShuntNbLimit << 1) & MFXSTM32L152_IDD_CTRL_SHUNT_NB);
+
+ /* Write noewx desired limit */
+ MFX_IO_Write((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_CTRL, mode);
+}
+
+/**
+ * @brief Get Idd current value
+ * @param DeviceAddr: Device address on communication Bus
+ * @param ReadValue: Pointer on value to be read
+ * @retval Idd value in 10 nA.
+ */
+void mfxstm32l152_IDD_GetValue(uint16_t DeviceAddr, uint32_t *ReadValue)
+{
+ uint8_t data[3];
+
+ MFX_IO_ReadMultiple((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_VALUE_MSB, data, sizeof(data)) ;
+
+ /* Recompose Idd current value */
+ *ReadValue = (data[0] << 16) | (data[1] << 8) | data[2];
+
+}
+
+/**
+ * @brief Get Last shunt used for measurement
+ * @param DeviceAddr: Device address on communication Bus
+ * @retval Last shunt used
+ */
+uint8_t mfxstm32l152_IDD_GetShuntUsed(uint16_t DeviceAddr)
+{
+ return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_IDD_SHUNT_USED));
+}
+
+/**
+ * @brief Configure mfx to enable Idd interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_IDD_EnableIT(uint16_t DeviceAddr)
+{
+ MFX_IO_ITConfig();
+
+ /* Enable global IDD interrupt source */
+ mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_IDD);
+}
+
+/**
+ * @brief Clear Idd global interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_IDD_ClearIT(uint16_t DeviceAddr)
+{
+ /* Clear the global IDD interrupt source */
+ mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_IDD);
+}
+
+/**
+ * @brief get Idd interrupt status
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval IDD interrupts status
+ */
+uint8_t mfxstm32l152_IDD_GetITStatus(uint16_t DeviceAddr)
+{
+ /* Return IDD interrupt status */
+ return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_IDD));
+}
+
+/**
+ * @brief disable Idd interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None.
+ */
+void mfxstm32l152_IDD_DisableIT(uint16_t DeviceAddr)
+{
+ /* Disable global IDD interrupt source */
+ mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_IDD);
+}
+
+
+/* ------------------------------------------------------------------ */
+/* --------------------- ERROR MANAGEMENT --------------------------- */
+/* ------------------------------------------------------------------ */
+
+/**
+ * @brief Read Error Source.
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Error message code with error source
+ */
+uint8_t mfxstm32l152_Error_ReadSrc(uint16_t DeviceAddr)
+{
+ /* Get the current source register value */
+ return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_ERROR_SRC));
+}
+
+/**
+ * @brief Read Error Message
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Error message code with error source
+ */
+uint8_t mfxstm32l152_Error_ReadMsg(uint16_t DeviceAddr)
+{
+ /* Get the current message register value */
+ return(MFX_IO_Read((uint8_t) DeviceAddr, MFXSTM32L152_REG_ADR_ERROR_MSG));
+}
+
+/**
+ * @brief Enable Error global interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+
+void mfxstm32l152_Error_EnableIT(uint16_t DeviceAddr)
+{
+ MFX_IO_ITConfig();
+
+ /* Enable global Error interrupt source */
+ mfxstm32l152_EnableITSource(DeviceAddr, MFXSTM32L152_IRQ_ERROR);
+}
+
+/**
+ * @brief Clear Error global interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None
+ */
+void mfxstm32l152_Error_ClearIT(uint16_t DeviceAddr)
+{
+ /* Clear the global Error interrupt source */
+ mfxstm32l152_ClearGlobalIT(DeviceAddr, MFXSTM32L152_IRQ_ERROR);
+}
+
+/**
+ * @brief get Error interrupt status
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Error interrupts status
+ */
+uint8_t mfxstm32l152_Error_GetITStatus(uint16_t DeviceAddr)
+{
+ /* Return Error interrupt status */
+ return(mfxstm32l152_GlobalITStatus(DeviceAddr, MFXSTM32L152_IRQ_ERROR));
+}
+
+/**
+ * @brief disable Error interrupt
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval None.
+ */
+void mfxstm32l152_Error_DisableIT(uint16_t DeviceAddr)
+{
+ /* Disable global Error interrupt source */
+ mfxstm32l152_DisableITSource(DeviceAddr, MFXSTM32L152_IRQ_ERROR);
+}
+
+/**
+ * @brief FOR DEBUG ONLY
+ */
+uint8_t mfxstm32l152_ReadReg(uint16_t DeviceAddr, uint8_t RegAddr)
+{
+ /* Get the current register value */
+ return(MFX_IO_Read((uint8_t) DeviceAddr, RegAddr));
+}
+
+void mfxstm32l152_WriteReg(uint16_t DeviceAddr, uint8_t RegAddr, uint8_t Value)
+{
+ /* set the current register value */
+ MFX_IO_Write((uint8_t) DeviceAddr, RegAddr, Value);
+}
+
+/* ------------------------------------------------------------------ */
+/* ----------------------- Private functions ------------------------ */
+/* ------------------------------------------------------------------ */
+/**
+ * @brief Check if the device instance of the selected address is already registered
+ * and return its index
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Index of the device instance if registered, 0xFF if not.
+ */
+static uint8_t mfxstm32l152_GetInstance(uint16_t DeviceAddr)
+{
+ uint8_t idx = 0;
+
+ /* Check all the registered instances */
+ for(idx = 0; idx < MFXSTM32L152_MAX_INSTANCE ; idx ++)
+ {
+ if(mfxstm32l152[idx] == DeviceAddr)
+ {
+ return idx;
+ }
+ }
+
+ return 0xFF;
+}
+
+/**
+ * @brief Release registered device instance
+ * @param DeviceAddr: Device address on communication Bus.
+ * @retval Index of released device instance, 0xFF if not.
+ */
+static uint8_t mfxstm32l152_ReleaseInstance(uint16_t DeviceAddr)
+{
+ uint8_t idx = 0;
+
+ /* Check for all the registered instances */
+ for(idx = 0; idx < MFXSTM32L152_MAX_INSTANCE ; idx ++)
+ {
+ if(mfxstm32l152[idx] == DeviceAddr)
+ {
+ mfxstm32l152[idx] = 0;
+ return idx;
+ }
+ }
+ return 0xFF;
+}
+
+/**
+ * @brief Internal routine
+ * @param DeviceAddr: Device address on communication Bus.
+ * @param RegisterAddr: Register Address
+ * @param PinPosition: Pin [0:23]
+ * @param PinValue: 0/1
+ * @retval None
+ */
+void mfxstm32l152_reg24_setPinValue(uint16_t DeviceAddr, uint8_t RegisterAddr, uint32_t PinPosition, uint8_t PinValue )
+{
+ uint8_t tmp = 0;
+ uint8_t pin_0_7, pin_8_15, pin_16_23;
+
+ pin_0_7 = PinPosition & 0x0000ff;
+ pin_8_15 = PinPosition >> 8;
+ pin_8_15 = pin_8_15 & 0x00ff;
+ pin_16_23 = PinPosition >> 16;
+
+ if (pin_0_7)
+ {
+ /* Get the current register value */
+ tmp = MFX_IO_Read(DeviceAddr, RegisterAddr);
+
+ /* Set the selected pin direction */
+ if (PinValue != 0)
+ {
+ tmp |= (uint8_t)pin_0_7;
+ }
+ else
+ {
+ tmp &= ~(uint8_t)pin_0_7;
+ }
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, RegisterAddr, tmp);
+ }
+
+ if (pin_8_15)
+ {
+ /* Get the current register value */
+ tmp = MFX_IO_Read(DeviceAddr, RegisterAddr+1);
+
+ /* Set the selected pin direction */
+ if (PinValue != 0)
+ {
+ tmp |= (uint8_t)pin_8_15;
+ }
+ else
+ {
+ tmp &= ~(uint8_t)pin_8_15;
+ }
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, RegisterAddr+1, tmp);
+ }
+
+ if (pin_16_23)
+ {
+ /* Get the current register value */
+ tmp = MFX_IO_Read(DeviceAddr, RegisterAddr+2);
+
+ /* Set the selected pin direction */
+ if (PinValue != 0)
+ {
+ tmp |= (uint8_t)pin_16_23;
+ }
+ else
+ {
+ tmp &= ~(uint8_t)pin_16_23;
+ }
+
+ /* Set the new register value */
+ MFX_IO_Write(DeviceAddr, RegisterAddr+2, tmp);
+ }
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.h b/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.h
new file mode 100644
index 0000000000..38ca8a6f6a
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/mfxstm32l152.h
@@ -0,0 +1,853 @@
+/**
+ ******************************************************************************
+ * @file mfxstm32l152.h
+ * @author MCD Application Team
+ * @brief This file contains all the functions prototypes for the
+ * mfxstm32l152.c IO expander driver.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MFXSTM32L152_H
+#define __MFXSTM32L152_H
+
+#include "board.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup Component
+ * @{
+ */
+
+/** @defgroup MFXSTM32L152
+ * @{
+ */
+
+ /**
+ * @brief GPIO: IO Pins definition
+ */
+#define MFXSTM32L152_GPIO_PIN_0 ((uint32_t)0x0001)
+#define MFXSTM32L152_GPIO_PIN_1 ((uint32_t)0x0002)
+#define MFXSTM32L152_GPIO_PIN_2 ((uint32_t)0x0004)
+#define MFXSTM32L152_GPIO_PIN_3 ((uint32_t)0x0008)
+#define MFXSTM32L152_GPIO_PIN_4 ((uint32_t)0x0010)
+#define MFXSTM32L152_GPIO_PIN_5 ((uint32_t)0x0020)
+#define MFXSTM32L152_GPIO_PIN_6 ((uint32_t)0x0040)
+#define MFXSTM32L152_GPIO_PIN_7 ((uint32_t)0x0080)
+
+#define MFXSTM32L152_GPIO_PIN_8 ((uint32_t)0x0100)
+#define MFXSTM32L152_GPIO_PIN_9 ((uint32_t)0x0200)
+#define MFXSTM32L152_GPIO_PIN_10 ((uint32_t)0x0400)
+#define MFXSTM32L152_GPIO_PIN_11 ((uint32_t)0x0800)
+#define MFXSTM32L152_GPIO_PIN_12 ((uint32_t)0x1000)
+#define MFXSTM32L152_GPIO_PIN_13 ((uint32_t)0x2000)
+#define MFXSTM32L152_GPIO_PIN_14 ((uint32_t)0x4000)
+#define MFXSTM32L152_GPIO_PIN_15 ((uint32_t)0x8000)
+
+#define MFXSTM32L152_GPIO_PIN_16 ((uint32_t)0x010000)
+#define MFXSTM32L152_GPIO_PIN_17 ((uint32_t)0x020000)
+#define MFXSTM32L152_GPIO_PIN_18 ((uint32_t)0x040000)
+#define MFXSTM32L152_GPIO_PIN_19 ((uint32_t)0x080000)
+#define MFXSTM32L152_GPIO_PIN_20 ((uint32_t)0x100000)
+#define MFXSTM32L152_GPIO_PIN_21 ((uint32_t)0x200000)
+#define MFXSTM32L152_GPIO_PIN_22 ((uint32_t)0x400000)
+#define MFXSTM32L152_GPIO_PIN_23 ((uint32_t)0x800000)
+
+#define MFXSTM32L152_AGPIO_PIN_0 MFXSTM32L152_GPIO_PIN_16
+#define MFXSTM32L152_AGPIO_PIN_1 MFXSTM32L152_GPIO_PIN_17
+#define MFXSTM32L152_AGPIO_PIN_2 MFXSTM32L152_GPIO_PIN_18
+#define MFXSTM32L152_AGPIO_PIN_3 MFXSTM32L152_GPIO_PIN_19
+#define MFXSTM32L152_AGPIO_PIN_4 MFXSTM32L152_GPIO_PIN_20
+#define MFXSTM32L152_AGPIO_PIN_5 MFXSTM32L152_GPIO_PIN_21
+#define MFXSTM32L152_AGPIO_PIN_6 MFXSTM32L152_GPIO_PIN_22
+#define MFXSTM32L152_AGPIO_PIN_7 MFXSTM32L152_GPIO_PIN_23
+
+#define MFXSTM32L152_GPIO_PINS_ALL ((uint32_t)0xFFFFFF)
+#define IO_PIN_ALL MFXSTM32L152_GPIO_PINS_ALL
+/**
+ * @brief IO Bit SET and Bit RESET enumeration
+ */
+typedef enum
+{
+ IO_PIN_RESET = 0,
+ IO_PIN_SET
+}IO_PinState;
+
+typedef enum
+{
+ IO_MODE_INPUT = 0, /* input floating */
+ IO_MODE_OUTPUT, /* output Push Pull */
+ IO_MODE_IT_RISING_EDGE, /* float input - irq detect on rising edge */
+ IO_MODE_IT_FALLING_EDGE, /* float input - irq detect on falling edge */
+ IO_MODE_IT_LOW_LEVEL, /* float input - irq detect on low level */
+ IO_MODE_IT_HIGH_LEVEL, /* float input - irq detect on high level */
+ /* following modes only available on MFX*/
+ IO_MODE_ANALOG, /* analog mode */
+ IO_MODE_OFF, /* when pin isn't used*/
+ IO_MODE_INPUT_PU, /* input with internal pull up resistor */
+ IO_MODE_INPUT_PD, /* input with internal pull down resistor */
+ IO_MODE_OUTPUT_OD, /* Open Drain output without internal resistor */
+ IO_MODE_OUTPUT_OD_PU, /* Open Drain output with internal pullup resistor */
+ IO_MODE_OUTPUT_OD_PD, /* Open Drain output with internal pulldown resistor */
+ IO_MODE_OUTPUT_PP, /* PushPull output without internal resistor */
+ IO_MODE_OUTPUT_PP_PU, /* PushPull output with internal pullup resistor */
+ IO_MODE_OUTPUT_PP_PD, /* PushPull output with internal pulldown resistor */
+ IO_MODE_IT_RISING_EDGE_PU, /* push up resistor input - irq on rising edge */
+ IO_MODE_IT_RISING_EDGE_PD, /* push dw resistor input - irq on rising edge */
+ IO_MODE_IT_FALLING_EDGE_PU, /* push up resistor input - irq on falling edge */
+ IO_MODE_IT_FALLING_EDGE_PD, /* push dw resistor input - irq on falling edge */
+ IO_MODE_IT_LOW_LEVEL_PU, /* push up resistor input - irq detect on low level */
+ IO_MODE_IT_LOW_LEVEL_PD, /* push dw resistor input - irq detect on low level */
+ IO_MODE_IT_HIGH_LEVEL_PU, /* push up resistor input - irq detect on high level */
+ IO_MODE_IT_HIGH_LEVEL_PD, /* push dw resistor input - irq detect on high level */
+
+}IO_ModeTypedef;
+
+/** @defgroup IO_Driver_structure IO Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Reset)(uint16_t);
+
+ void (*Start)(uint16_t, uint32_t);
+ uint8_t (*Config)(uint16_t, uint32_t, IO_ModeTypedef);
+ void (*WritePin)(uint16_t, uint32_t, uint8_t);
+ uint32_t (*ReadPin)(uint16_t, uint32_t);
+
+ void (*EnableIT)(uint16_t);
+ void (*DisableIT)(uint16_t);
+ uint32_t (*ITStatus)(uint16_t, uint32_t);
+ void (*ClearIT)(uint16_t, uint32_t);
+
+}IO_DrvTypeDef;
+
+typedef struct
+{
+ uint16_t AmpliGain; /*!< Specifies ampli gain value
+ */
+ uint16_t VddMin; /*!< Specifies minimum MCU VDD can reach to protect MCU from reset
+ */
+ uint16_t Shunt0Value; /*!< Specifies value of Shunt 0 if existing
+ */
+ uint16_t Shunt1Value; /*!< Specifies value of Shunt 1 if existing
+ */
+ uint16_t Shunt2Value; /*!< Specifies value of Shunt 2 if existing
+ */
+ uint16_t Shunt3Value; /*!< Specifies value of Shunt 3 if existing
+ */
+ uint16_t Shunt4Value; /*!< Specifies value of Shunt 4 if existing
+ */
+ uint16_t Shunt0StabDelay; /*!< Specifies delay of Shunt 0 stabilization if existing
+ */
+ uint16_t Shunt1StabDelay; /*!< Specifies delay of Shunt 1 stabilization if existing
+ */
+ uint16_t Shunt2StabDelay; /*!< Specifies delay of Shunt 2 stabilization if existing
+ */
+ uint16_t Shunt3StabDelay; /*!< Specifies delay of Shunt 3 stabilization if existing
+ */
+ uint16_t Shunt4StabDelay; /*!< Specifies delay of Shunt 4 stabilization if existing
+ */
+ uint8_t ShuntNbOnBoard; /*!< Specifies number of shunts that are present on board
+ This parameter can be a value of @ref IDD_shunt_number */
+ uint8_t ShuntNbUsed; /*!< Specifies number of shunts used for measurement
+ This parameter can be a value of @ref IDD_shunt_number */
+ uint8_t VrefMeasurement; /*!< Specifies if Vref is automatically measured before each Idd measurement
+ This parameter can be a value of @ref IDD_Vref_Measurement */
+ uint8_t Calibration; /*!< Specifies if calibration is done before each Idd measurement
+ */
+ uint8_t PreDelayUnit; /*!< Specifies Pre delay unit
+ This parameter can be a value of @ref IDD_PreDelay */
+ uint8_t PreDelayValue; /*!< Specifies Pre delay value in selected unit
+ */
+ uint8_t MeasureNb; /*!< Specifies number of Measure to be performed
+ This parameter can be a value between 1 and 256 */
+ uint8_t DeltaDelayUnit; /*!< Specifies Delta delay unit
+ This parameter can be a value of @ref IDD_DeltaDelay */
+ uint8_t DeltaDelayValue; /*!< Specifies Delta delay between 2 measures
+ value can be between 1 and 128 */
+}IDD_ConfigTypeDef;
+/**
+ * @}
+ */
+
+/** @defgroup IDD_Driver_structure IDD Driver structure
+ * @{
+ */
+typedef struct
+{
+ void (*Init)(uint16_t);
+ void (*DeInit)(uint16_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Reset)(uint16_t);
+ void (*LowPower)(uint16_t);
+ void (*WakeUp)(uint16_t);
+ void (*Start)(uint16_t);
+ void (*Config)(uint16_t,IDD_ConfigTypeDef);
+ void (*GetValue)(uint16_t, uint32_t *);
+ void (*EnableIT)(uint16_t);
+ void (*ClearIT)(uint16_t);
+ uint8_t (*GetITStatus)(uint16_t);
+ void (*DisableIT)(uint16_t);
+ void (*ErrorEnableIT)(uint16_t);
+ void (*ErrorClearIT)(uint16_t);
+ uint8_t (*ErrorGetITStatus)(uint16_t);
+ void (*ErrorDisableIT)(uint16_t);
+ uint8_t (*ErrorGetSrc)(uint16_t);
+ uint8_t (*ErrorGetCode)(uint16_t);
+}IDD_DrvTypeDef;
+
+typedef struct
+{
+ void (*Init)(uint16_t);
+ uint16_t (*ReadID)(uint16_t);
+ void (*Reset)(uint16_t);
+ void (*Start)(uint16_t);
+ uint8_t (*DetectTouch)(uint16_t);
+ void (*GetXY)(uint16_t, uint16_t*, uint16_t*);
+ void (*EnableIT)(uint16_t);
+ void (*ClearIT)(uint16_t);
+ uint8_t (*GetITStatus)(uint16_t);
+ void (*DisableIT)(uint16_t);
+}TS_DrvTypeDef;
+
+/* Exported types ------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Exported_Types
+ * @{
+ */
+typedef struct
+{
+ uint8_t SYS_CTRL;
+ uint8_t ERROR_SRC;
+ uint8_t ERROR_MSG;
+ uint8_t IRQ_OUT;
+ uint8_t IRQ_SRC_EN;
+ uint8_t IRQ_PENDING;
+ uint8_t IDD_CTRL;
+ uint8_t IDD_PRE_DELAY;
+ uint8_t IDD_SHUNT0_MSB;
+ uint8_t IDD_SHUNT0_LSB;
+ uint8_t IDD_SHUNT1_MSB;
+ uint8_t IDD_SHUNT1_LSB;
+ uint8_t IDD_SHUNT2_MSB;
+ uint8_t IDD_SHUNT2_LSB;
+ uint8_t IDD_SHUNT3_MSB;
+ uint8_t IDD_SHUNT3_LSB;
+ uint8_t IDD_SHUNT4_MSB;
+ uint8_t IDD_SHUNT4_LSB;
+ uint8_t IDD_GAIN_MSB;
+ uint8_t IDD_GAIN_LSB;
+ uint8_t IDD_VDD_MIN_MSB;
+ uint8_t IDD_VDD_MIN_LSB;
+ uint8_t IDD_VALUE_MSB;
+ uint8_t IDD_VALUE_MID;
+ uint8_t IDD_VALUE_LSB;
+ uint8_t IDD_CAL_OFFSET_MSB;
+ uint8_t IDD_CAL_OFFSET_LSB;
+ uint8_t IDD_SHUNT_USED;
+}IDD_dbgTypeDef;
+
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Exported_Constants
+ * @{
+ */
+
+ /**
+ * @brief MFX COMMON defines
+ */
+
+ /**
+ * @brief Register address: chip IDs (R)
+ */
+#define MFXSTM32L152_REG_ADR_ID ((uint8_t)0x00)
+ /**
+ * @brief Register address: chip FW_VERSION (R)
+ */
+#define MFXSTM32L152_REG_ADR_FW_VERSION_MSB ((uint8_t)0x01)
+#define MFXSTM32L152_REG_ADR_FW_VERSION_LSB ((uint8_t)0x00)
+ /**
+ * @brief Register address: System Control Register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_SYS_CTRL ((uint8_t)0x40)
+ /**
+ * @brief Register address: Vdd monitoring (R)
+ */
+#define MFXSTM32L152_REG_ADR_VDD_REF_MSB ((uint8_t)0x06)
+#define MFXSTM32L152_REG_ADR_VDD_REF_LSB ((uint8_t)0x07)
+ /**
+ * @brief Register address: Error source
+ */
+#define MFXSTM32L152_REG_ADR_ERROR_SRC ((uint8_t)0x03)
+ /**
+ * @brief Register address: Error Message
+ */
+#define MFXSTM32L152_REG_ADR_ERROR_MSG ((uint8_t)0x04)
+
+ /**
+ * @brief Reg Addr IRQs: to config the pin that informs Main MCU that MFX events appear
+ */
+#define MFXSTM32L152_REG_ADR_MFX_IRQ_OUT ((uint8_t)0x41)
+ /**
+ * @brief Reg Addr IRQs: to select the events which activate the MFXSTM32L152_IRQ_OUT signal
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_SRC_EN ((uint8_t)0x42)
+ /**
+ * @brief Reg Addr IRQs: the Main MCU must read the IRQ_PENDING register to know the interrupt reason
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_PENDING ((uint8_t)0x08)
+ /**
+ * @brief Reg Addr IRQs: the Main MCU must acknowledge it thanks to a writing access to the IRQ_ACK register
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_ACK ((uint8_t)0x44)
+
+ /**
+ * @brief MFXSTM32L152_REG_ADR_ID choices
+ */
+#define MFXSTM32L152_ID_1 ((uint8_t)0x7B)
+#define MFXSTM32L152_ID_2 ((uint8_t)0x79)
+
+ /**
+ * @brief MFXSTM32L152_REG_ADR_SYS_CTRL choices
+ */
+#define MFXSTM32L152_SWRST ((uint8_t)0x80)
+#define MFXSTM32L152_STANDBY ((uint8_t)0x40)
+#define MFXSTM32L152_ALTERNATE_GPIO_EN ((uint8_t)0x08) /* by the way if IDD and TS are enabled they take automatically the AF pins*/
+#define MFXSTM32L152_IDD_EN ((uint8_t)0x04)
+#define MFXSTM32L152_TS_EN ((uint8_t)0x02)
+#define MFXSTM32L152_GPIO_EN ((uint8_t)0x01)
+
+ /**
+ * @brief MFXSTM32L152_REG_ADR_ERROR_SRC choices
+ */
+#define MFXSTM32L152_IDD_ERROR_SRC ((uint8_t)0x04) /* Error raised by Idd */
+#define MFXSTM32L152_TS_ERROR_SRC ((uint8_t)0x02) /* Error raised by Touch Screen */
+#define MFXSTM32L152_GPIO_ERROR_SRC ((uint8_t)0x01) /* Error raised by Gpio */
+
+ /**
+ * @brief MFXSTM32L152_REG_ADR_MFX_IRQ_OUT choices
+ */
+#define MFXSTM32L152_OUT_PIN_TYPE_OPENDRAIN ((uint8_t)0x00)
+#define MFXSTM32L152_OUT_PIN_TYPE_PUSHPULL ((uint8_t)0x01)
+#define MFXSTM32L152_OUT_PIN_POLARITY_LOW ((uint8_t)0x00)
+#define MFXSTM32L152_OUT_PIN_POLARITY_HIGH ((uint8_t)0x02)
+
+ /**
+ * @brief REG_ADR_IRQ_SRC_EN, REG_ADR_IRQ_PENDING & REG_ADR_IRQ_ACK choices
+ */
+#define MFXSTM32L152_IRQ_TS_OVF ((uint8_t)0x80) /* TouchScreen FIFO Overflow irq*/
+#define MFXSTM32L152_IRQ_TS_FULL ((uint8_t)0x40) /* TouchScreen FIFO Full irq*/
+#define MFXSTM32L152_IRQ_TS_TH ((uint8_t)0x20) /* TouchScreen FIFO threshold triggered irq*/
+#define MFXSTM32L152_IRQ_TS_NE ((uint8_t)0x10) /* TouchScreen FIFO Not Empty irq*/
+#define MFXSTM32L152_IRQ_TS_DET ((uint8_t)0x08) /* TouchScreen Detect irq*/
+#define MFXSTM32L152_IRQ_ERROR ((uint8_t)0x04) /* Error message from MFXSTM32L152 firmware irq */
+#define MFXSTM32L152_IRQ_IDD ((uint8_t)0x02) /* IDD function irq */
+#define MFXSTM32L152_IRQ_GPIO ((uint8_t)0x01) /* General GPIO irq (only for SRC_EN and PENDING) */
+#define MFXSTM32L152_IRQ_ALL ((uint8_t)0xFF) /* All global interrupts */
+#define MFXSTM32L152_IRQ_TS (MFXSTM32L152_IRQ_TS_DET | MFXSTM32L152_IRQ_TS_NE | MFXSTM32L152_IRQ_TS_TH | MFXSTM32L152_IRQ_TS_FULL | MFXSTM32L152_IRQ_TS_OVF )
+
+
+ /**
+ * @brief GPIO: 24 programmable input/output called MFXSTM32L152_GPIO[23:0] are provided
+ */
+
+ /**
+ * @brief Reg addr: GPIO DIRECTION (R/W): GPIO pins direction: (0) input, (1) output.
+ */
+#define MFXSTM32L152_REG_ADR_GPIO_DIR1 ((uint8_t)0x60) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_DIR2 ((uint8_t)0x61) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_DIR3 ((uint8_t)0x62) /* agpio [0:7] */
+ /**
+ * @brief Reg addr: GPIO TYPE (R/W): If GPIO in output: (0) output push pull, (1) output open drain.
+ * If GPIO in input: (0) input without pull resistor, (1) input with pull resistor.
+ */
+#define MFXSTM32L152_REG_ADR_GPIO_TYPE1 ((uint8_t)0x64) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_TYPE2 ((uint8_t)0x65) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_TYPE3 ((uint8_t)0x66) /* agpio [0:7] */
+ /**
+ * @brief Reg addr: GPIO PULL_UP_PULL_DOWN (R/W): discussion open with Jean Claude
+ */
+#define MFXSTM32L152_REG_ADR_GPIO_PUPD1 ((uint8_t)0x68) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_PUPD2 ((uint8_t)0x69) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_PUPD3 ((uint8_t)0x6A) /* agpio [0:7] */
+ /**
+ * @brief Reg addr: GPIO SET (W): When GPIO is in output mode, write (1) puts the corresponding GPO in High level.
+ */
+#define MFXSTM32L152_REG_ADR_GPO_SET1 ((uint8_t)0x6C) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPO_SET2 ((uint8_t)0x6D) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPO_SET3 ((uint8_t)0x6E) /* agpio [0:7] */
+ /**
+ * @brief Reg addr: GPIO CLEAR (W): When GPIO is in output mode, write (1) puts the corresponding GPO in Low level.
+ */
+#define MFXSTM32L152_REG_ADR_GPO_CLR1 ((uint8_t)0x70) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPO_CLR2 ((uint8_t)0x71) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPO_CLR3 ((uint8_t)0x72) /* agpio [0:7] */
+ /**
+ * @brief Reg addr: GPIO STATE (R): Give state of the GPIO pin.
+ */
+#define MFXSTM32L152_REG_ADR_GPIO_STATE1 ((uint8_t)0x10) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_GPIO_STATE2 ((uint8_t)0x11) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_GPIO_STATE3 ((uint8_t)0x12) /* agpio [0:7] */
+
+ /**
+ * @brief GPIO IRQ_GPIs
+ */
+/* GPIOs can INDIVIDUALLY generate interruption to the Main MCU thanks to the MFXSTM32L152_IRQ_OUT signal */
+/* the general MFXSTM32L152_IRQ_GPIO_SRC_EN shall be enabled too */
+ /**
+ * @brief GPIO IRQ_GPI_SRC1/2/3 (R/W): registers enable or not the feature to generate irq
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC1 ((uint8_t)0x48) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC2 ((uint8_t)0x49) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_SRC3 ((uint8_t)0x4A) /* agpio [0:7] */
+ /**
+ * @brief GPIO IRQ_GPI_EVT1/2/3 (R/W): Irq generated on level (0) or edge (1).
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT1 ((uint8_t)0x4C) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT2 ((uint8_t)0x4D) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_EVT3 ((uint8_t)0x4E) /* agpio [0:7] */
+ /**
+ * @brief GPIO IRQ_GPI_TYPE1/2/3 (R/W): Irq generated on (0) : Low level or Falling edge. (1) : High level or Rising edge.
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE1 ((uint8_t)0x50) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE2 ((uint8_t)0x51) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_TYPE3 ((uint8_t)0x52) /* agpio [0:7] */
+ /**
+ * @brief GPIO IRQ_GPI_PENDING1/2/3 (R): irq occurs
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING1 ((uint8_t)0x0C) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING2 ((uint8_t)0x0D) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_PENDING3 ((uint8_t)0x0E) /* agpio [0:7] */
+ /**
+ * @brief GPIO IRQ_GPI_ACK1/2/3 (W): Write (1) to acknowledge IRQ event
+ */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK1 ((uint8_t)0x54) /* gpio [0:7] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK2 ((uint8_t)0x55) /* gpio [8:15] */
+#define MFXSTM32L152_REG_ADR_IRQ_GPI_ACK3 ((uint8_t)0x56) /* agpio [0:7] */
+
+
+ /**
+ * @brief GPIO: IO Pins definition
+ */
+#define MFXSTM32L152_GPIO_PIN_0 ((uint32_t)0x0001)
+#define MFXSTM32L152_GPIO_PIN_1 ((uint32_t)0x0002)
+#define MFXSTM32L152_GPIO_PIN_2 ((uint32_t)0x0004)
+#define MFXSTM32L152_GPIO_PIN_3 ((uint32_t)0x0008)
+#define MFXSTM32L152_GPIO_PIN_4 ((uint32_t)0x0010)
+#define MFXSTM32L152_GPIO_PIN_5 ((uint32_t)0x0020)
+#define MFXSTM32L152_GPIO_PIN_6 ((uint32_t)0x0040)
+#define MFXSTM32L152_GPIO_PIN_7 ((uint32_t)0x0080)
+
+#define MFXSTM32L152_GPIO_PIN_8 ((uint32_t)0x0100)
+#define MFXSTM32L152_GPIO_PIN_9 ((uint32_t)0x0200)
+#define MFXSTM32L152_GPIO_PIN_10 ((uint32_t)0x0400)
+#define MFXSTM32L152_GPIO_PIN_11 ((uint32_t)0x0800)
+#define MFXSTM32L152_GPIO_PIN_12 ((uint32_t)0x1000)
+#define MFXSTM32L152_GPIO_PIN_13 ((uint32_t)0x2000)
+#define MFXSTM32L152_GPIO_PIN_14 ((uint32_t)0x4000)
+#define MFXSTM32L152_GPIO_PIN_15 ((uint32_t)0x8000)
+
+#define MFXSTM32L152_GPIO_PIN_16 ((uint32_t)0x010000)
+#define MFXSTM32L152_GPIO_PIN_17 ((uint32_t)0x020000)
+#define MFXSTM32L152_GPIO_PIN_18 ((uint32_t)0x040000)
+#define MFXSTM32L152_GPIO_PIN_19 ((uint32_t)0x080000)
+#define MFXSTM32L152_GPIO_PIN_20 ((uint32_t)0x100000)
+#define MFXSTM32L152_GPIO_PIN_21 ((uint32_t)0x200000)
+#define MFXSTM32L152_GPIO_PIN_22 ((uint32_t)0x400000)
+#define MFXSTM32L152_GPIO_PIN_23 ((uint32_t)0x800000)
+
+#define MFXSTM32L152_AGPIO_PIN_0 MFXSTM32L152_GPIO_PIN_16
+#define MFXSTM32L152_AGPIO_PIN_1 MFXSTM32L152_GPIO_PIN_17
+#define MFXSTM32L152_AGPIO_PIN_2 MFXSTM32L152_GPIO_PIN_18
+#define MFXSTM32L152_AGPIO_PIN_3 MFXSTM32L152_GPIO_PIN_19
+#define MFXSTM32L152_AGPIO_PIN_4 MFXSTM32L152_GPIO_PIN_20
+#define MFXSTM32L152_AGPIO_PIN_5 MFXSTM32L152_GPIO_PIN_21
+#define MFXSTM32L152_AGPIO_PIN_6 MFXSTM32L152_GPIO_PIN_22
+#define MFXSTM32L152_AGPIO_PIN_7 MFXSTM32L152_GPIO_PIN_23
+
+#define MFXSTM32L152_GPIO_PINS_ALL ((uint32_t)0xFFFFFF)
+
+ /**
+ * @brief GPIO: constant
+ */
+#define MFXSTM32L152_GPIO_DIR_IN ((uint8_t)0x0)
+#define MFXSTM32L152_GPIO_DIR_OUT ((uint8_t)0x1)
+#define MFXSTM32L152_IRQ_GPI_EVT_LEVEL ((uint8_t)0x0)
+#define MFXSTM32L152_IRQ_GPI_EVT_EDGE ((uint8_t)0x1)
+#define MFXSTM32L152_IRQ_GPI_TYPE_LLFE ((uint8_t)0x0) /* Low Level Falling Edge */
+#define MFXSTM32L152_IRQ_GPI_TYPE_HLRE ((uint8_t)0x1) /*High Level Raising Edge */
+#define MFXSTM32L152_GPI_WITHOUT_PULL_RESISTOR ((uint8_t)0x0)
+#define MFXSTM32L152_GPI_WITH_PULL_RESISTOR ((uint8_t)0x1)
+#define MFXSTM32L152_GPO_PUSH_PULL ((uint8_t)0x0)
+#define MFXSTM32L152_GPO_OPEN_DRAIN ((uint8_t)0x1)
+#define MFXSTM32L152_GPIO_PULL_DOWN ((uint8_t)0x0)
+#define MFXSTM32L152_GPIO_PULL_UP ((uint8_t)0x1)
+
+
+ /**
+ * @brief TOUCH SCREEN Registers
+ */
+
+ /**
+ * @brief Touch Screen Registers
+ */
+#define MFXSTM32L152_TS_SETTLING ((uint8_t)0xA0)
+#define MFXSTM32L152_TS_TOUCH_DET_DELAY ((uint8_t)0xA1)
+#define MFXSTM32L152_TS_AVE ((uint8_t)0xA2)
+#define MFXSTM32L152_TS_TRACK ((uint8_t)0xA3)
+#define MFXSTM32L152_TS_FIFO_TH ((uint8_t)0xA4)
+#define MFXSTM32L152_TS_FIFO_STA ((uint8_t)0x20)
+#define MFXSTM32L152_TS_FIFO_LEVEL ((uint8_t)0x21)
+#define MFXSTM32L152_TS_XY_DATA ((uint8_t)0x24)
+
+ /**
+ * @brief TS registers masks
+ */
+#define MFXSTM32L152_TS_CTRL_STATUS ((uint8_t)0x08)
+#define MFXSTM32L152_TS_CLEAR_FIFO ((uint8_t)0x80)
+
+
+/**
+ * @brief Register address: Idd control register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_CTRL ((uint8_t)0x80)
+
+/**
+ * @brief Register address: Idd pre delay register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_PRE_DELAY ((uint8_t)0x81)
+
+/**
+ * @brief Register address: Idd Shunt registers (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT0_MSB ((uint8_t)0x82)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT0_LSB ((uint8_t)0x83)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT1_MSB ((uint8_t)0x84)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT1_LSB ((uint8_t)0x85)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT2_MSB ((uint8_t)0x86)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT2_LSB ((uint8_t)0x87)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT3_MSB ((uint8_t)0x88)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT3_LSB ((uint8_t)0x89)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT4_MSB ((uint8_t)0x8A)
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT4_LSB ((uint8_t)0x8B)
+
+/**
+ * @brief Register address: Idd ampli gain register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_GAIN_MSB ((uint8_t)0x8C)
+#define MFXSTM32L152_REG_ADR_IDD_GAIN_LSB ((uint8_t)0x8D)
+
+/**
+ * @brief Register address: Idd VDD min register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_VDD_MIN_MSB ((uint8_t)0x8E)
+#define MFXSTM32L152_REG_ADR_IDD_VDD_MIN_LSB ((uint8_t)0x8F)
+
+/**
+ * @brief Register address: Idd value register (R)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_VALUE_MSB ((uint8_t)0x14)
+#define MFXSTM32L152_REG_ADR_IDD_VALUE_MID ((uint8_t)0x15)
+#define MFXSTM32L152_REG_ADR_IDD_VALUE_LSB ((uint8_t)0x16)
+
+/**
+ * @brief Register address: Idd calibration offset register (R)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_CAL_OFFSET_MSB ((uint8_t)0x18)
+#define MFXSTM32L152_REG_ADR_IDD_CAL_OFFSET_LSB ((uint8_t)0x19)
+
+/**
+ * @brief Register address: Idd shunt used offset register (R)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_SHUNT_USED ((uint8_t)0x1A)
+
+/**
+ * @brief Register address: shunt stabilisation delay registers (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_SH0_STABILIZATION ((uint8_t)0x90)
+#define MFXSTM32L152_REG_ADR_IDD_SH1_STABILIZATION ((uint8_t)0x91)
+#define MFXSTM32L152_REG_ADR_IDD_SH2_STABILIZATION ((uint8_t)0x92)
+#define MFXSTM32L152_REG_ADR_IDD_SH3_STABILIZATION ((uint8_t)0x93)
+#define MFXSTM32L152_REG_ADR_IDD_SH4_STABILIZATION ((uint8_t)0x94)
+
+/**
+ * @brief Register address: Idd number of measurements register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_NBR_OF_MEAS ((uint8_t)0x96)
+
+/**
+ * @brief Register address: Idd delta delay between 2 measurements register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_MEAS_DELTA_DELAY ((uint8_t)0x97)
+
+/**
+ * @brief Register address: Idd number of shunt on board register (R/W)
+ */
+#define MFXSTM32L152_REG_ADR_IDD_SHUNTS_ON_BOARD ((uint8_t)0x98)
+
+
+
+/** @defgroup IDD_Control_Register_Defines IDD Control Register Defines
+ * @{
+ */
+/**
+ * @brief IDD control register masks
+ */
+#define MFXSTM32L152_IDD_CTRL_REQ ((uint8_t)0x01)
+#define MFXSTM32L152_IDD_CTRL_SHUNT_NB ((uint8_t)0x0E)
+#define MFXSTM32L152_IDD_CTRL_VREF_DIS ((uint8_t)0x40)
+#define MFXSTM32L152_IDD_CTRL_CAL_DIS ((uint8_t)0x80)
+
+/**
+ * @brief IDD Shunt Number
+ */
+#define MFXSTM32L152_IDD_SHUNT_NB_1 ((uint8_t) 0x01)
+#define MFXSTM32L152_IDD_SHUNT_NB_2 ((uint8_t) 0x02)
+#define MFXSTM32L152_IDD_SHUNT_NB_3 ((uint8_t) 0x03)
+#define MFXSTM32L152_IDD_SHUNT_NB_4 ((uint8_t) 0x04)
+#define MFXSTM32L152_IDD_SHUNT_NB_5 ((uint8_t) 0x05)
+
+/**
+ * @brief Vref Measurement
+ */
+#define MFXSTM32L152_IDD_VREF_AUTO_MEASUREMENT_ENABLE ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_VREF_AUTO_MEASUREMENT_DISABLE ((uint8_t) 0x70)
+
+/**
+ * @brief IDD Calibration
+ */
+#define MFXSTM32L152_IDD_AUTO_CALIBRATION_ENABLE ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_AUTO_CALIBRATION_DISABLE ((uint8_t) 0x80)
+/**
+ * @}
+ */
+
+/** @defgroup IDD_PreDelay_Defines IDD PreDelay Defines
+ * @{
+ */
+/**
+ * @brief IDD PreDelay masks
+ */
+#define MFXSTM32L152_IDD_PREDELAY_UNIT ((uint8_t) 0x80)
+#define MFXSTM32L152_IDD_PREDELAY_VALUE ((uint8_t) 0x7F)
+
+
+/**
+ * @brief IDD PreDelay unit
+ */
+#define MFXSTM32L152_IDD_PREDELAY_0_5_MS ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_PREDELAY_20_MS ((uint8_t) 0x80)
+/**
+ * @}
+ */
+
+/** @defgroup IDD_DeltaDelay_Defines IDD Delta DElay Defines
+ * @{
+ */
+/**
+ * @brief IDD Delta Delay masks
+ */
+#define MFXSTM32L152_IDD_DELTADELAY_UNIT ((uint8_t) 0x80)
+#define MFXSTM32L152_IDD_DELTADELAY_VALUE ((uint8_t) 0x7F)
+
+
+/**
+ * @brief IDD Delta Delay unit
+ */
+#define MFXSTM32L152_IDD_DELTADELAY_0_5_MS ((uint8_t) 0x00)
+#define MFXSTM32L152_IDD_DELTADELAY_20_MS ((uint8_t) 0x80)
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+
+/* Exported macro ------------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Exported_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+
+/** @defgroup MFXSTM32L152_Exported_Functions
+ * @{
+ */
+
+/**
+ * @brief MFXSTM32L152 Control functions
+ */
+void mfxstm32l152_Init(uint16_t DeviceAddr);
+void mfxstm32l152_DeInit(uint16_t DeviceAddr);
+void mfxstm32l152_Reset(uint16_t DeviceAddr);
+uint16_t mfxstm32l152_ReadID(uint16_t DeviceAddr);
+uint16_t mfxstm32l152_ReadFwVersion(uint16_t DeviceAddr);
+void mfxstm32l152_LowPower(uint16_t DeviceAddr);
+void mfxstm32l152_WakeUp(uint16_t DeviceAddr);
+
+void mfxstm32l152_EnableITSource(uint16_t DeviceAddr, uint8_t Source);
+void mfxstm32l152_DisableITSource(uint16_t DeviceAddr, uint8_t Source);
+uint8_t mfxstm32l152_GlobalITStatus(uint16_t DeviceAddr, uint8_t Source);
+void mfxstm32l152_ClearGlobalIT(uint16_t DeviceAddr, uint8_t Source);
+
+void mfxstm32l152_SetIrqOutPinPolarity(uint16_t DeviceAddr, uint8_t Polarity);
+void mfxstm32l152_SetIrqOutPinType(uint16_t DeviceAddr, uint8_t Type);
+
+
+/**
+ * @brief MFXSTM32L152 IO functionalities functions
+ */
+void mfxstm32l152_IO_Start(uint16_t DeviceAddr, uint32_t IO_Pin);
+uint8_t mfxstm32l152_IO_Config(uint16_t DeviceAddr, uint32_t IO_Pin, IO_ModeTypedef IO_Mode);
+void mfxstm32l152_IO_WritePin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t PinState);
+uint32_t mfxstm32l152_IO_ReadPin(uint16_t DeviceAddr, uint32_t IO_Pin);
+void mfxstm32l152_IO_EnableIT(uint16_t DeviceAddr);
+void mfxstm32l152_IO_DisableIT(uint16_t DeviceAddr);
+uint32_t mfxstm32l152_IO_ITStatus(uint16_t DeviceAddr, uint32_t IO_Pin);
+void mfxstm32l152_IO_ClearIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+
+void mfxstm32l152_IO_InitPin(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Direction);
+void mfxstm32l152_IO_EnableAF(uint16_t DeviceAddr);
+void mfxstm32l152_IO_DisableAF(uint16_t DeviceAddr);
+void mfxstm32l152_IO_SetIrqTypeMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Type);
+void mfxstm32l152_IO_SetIrqEvtMode(uint16_t DeviceAddr, uint32_t IO_Pin, uint8_t Evt);
+void mfxstm32l152_IO_EnablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+void mfxstm32l152_IO_DisablePinIT(uint16_t DeviceAddr, uint32_t IO_Pin);
+
+/**
+ * @brief MFXSTM32L152 Touch screen functionalities functions
+ */
+void mfxstm32l152_TS_Start(uint16_t DeviceAddr);
+uint8_t mfxstm32l152_TS_DetectTouch(uint16_t DeviceAddr);
+void mfxstm32l152_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y);
+void mfxstm32l152_TS_EnableIT(uint16_t DeviceAddr);
+void mfxstm32l152_TS_DisableIT(uint16_t DeviceAddr);
+uint8_t mfxstm32l152_TS_ITStatus (uint16_t DeviceAddr);
+void mfxstm32l152_TS_ClearIT (uint16_t DeviceAddr);
+
+/**
+ * @brief MFXSTM32L152 IDD current measurement functionalities functions
+ */
+void mfxstm32l152_IDD_Start(uint16_t DeviceAddr);
+void mfxstm32l152_IDD_Config(uint16_t DeviceAddr, IDD_ConfigTypeDef MfxIddConfig);
+void mfxstm32l152_IDD_ConfigShuntNbLimit(uint16_t DeviceAddr, uint8_t ShuntNbLimit);
+void mfxstm32l152_IDD_GetValue(uint16_t DeviceAddr, uint32_t *ReadValue);
+uint8_t mfxstm32l152_IDD_GetShuntUsed(uint16_t DeviceAddr);
+void mfxstm32l152_IDD_EnableIT(uint16_t DeviceAddr);
+void mfxstm32l152_IDD_ClearIT(uint16_t DeviceAddr);
+uint8_t mfxstm32l152_IDD_GetITStatus(uint16_t DeviceAddr);
+void mfxstm32l152_IDD_DisableIT(uint16_t DeviceAddr);
+
+/**
+ * @brief MFXSTM32L152 Error management functions
+ */
+uint8_t mfxstm32l152_Error_ReadSrc(uint16_t DeviceAddr);
+uint8_t mfxstm32l152_Error_ReadMsg(uint16_t DeviceAddr);
+void mfxstm32l152_Error_EnableIT(uint16_t DeviceAddr);
+void mfxstm32l152_Error_ClearIT(uint16_t DeviceAddr);
+uint8_t mfxstm32l152_Error_GetITStatus(uint16_t DeviceAddr);
+void mfxstm32l152_Error_DisableIT(uint16_t DeviceAddr);
+
+uint8_t mfxstm32l152_ReadReg(uint16_t DeviceAddr, uint8_t RegAddr);
+void mfxstm32l152_WriteReg(uint16_t DeviceAddr, uint8_t RegAddr, uint8_t Value);
+
+
+
+/**
+ * @brief iobus prototypes (they should be defined in common/stm32_iobus.h)
+ */
+void MFX_IO_Init(void);
+void MFX_IO_DeInit(void);
+void MFX_IO_ITConfig (void);
+void MFX_IO_EnableWakeupPin(void);
+void MFX_IO_Wakeup(void);
+void MFX_IO_Delay(uint32_t delay);
+void MFX_IO_Write(uint16_t addr, uint8_t reg, uint8_t value);
+uint8_t MFX_IO_Read(uint16_t addr, uint8_t reg);
+uint16_t MFX_IO_ReadMultiple(uint16_t addr, uint8_t reg, uint8_t *buffer, uint16_t length);
+
+/**
+ * @}
+ */
+
+/* Touch screen driver structure */
+extern TS_DrvTypeDef mfxstm32l152_ts_drv;
+
+/* IO driver structure */
+extern IO_DrvTypeDef mfxstm32l152_io_drv;
+
+/* IDD driver structure */
+extern IDD_DrvTypeDef mfxstm32l152_idd_drv;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MFXSTM32L152_H */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/spi_sample.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/spi_sample.c
new file mode 100644
index 0000000000..ca31b0aa47
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/spi_sample.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-09-15 thread-liu first version
+ */
+
+#include "board.h"
+
+#if defined(BSP_USING_SPI1)
+#include <drv_spi.h>
+
+#define SPI_NAME "spi1"
+#define SPI_DEVICE_NAME "spi10"
+static struct rt_spi_device *spi_dev = RT_NULL;
+
+/* attach spi1 device */
+static int rt_spi_device_init(void)
+{
+ struct rt_spi_configuration cfg;
+
+ rt_hw_spi_device_attach(SPI_NAME, SPI_DEVICE_NAME, NULL, NULL);
+
+ cfg.data_width = 8;
+ cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB | RT_SPI_NO_CS;
+ cfg.max_hz = 1 *1000 *1000;
+
+ spi_dev = (struct rt_spi_device *)rt_device_find(SPI_DEVICE_NAME);
+
+ if (RT_NULL == spi_dev)
+ {
+ rt_kprintf("spi sample run failed! can't find %s device!\n", SPI_NAME);
+ return RT_ERROR;
+ }
+
+ rt_spi_configure(spi_dev, &cfg);
+
+ return RT_EOK;
+}
+INIT_APP_EXPORT(rt_spi_device_init);
+
+/* spi5 loopback mode test case */
+static int spi_sample(int argc, char **argv)
+{
+ rt_uint8_t t_buf[8], r_buf[8];
+ int i = 0;
+ static struct rt_spi_message msg1;
+
+ if (argc != 9)
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("spi_sample 1 2 3 4 5 6 7 8\n");
+ return -RT_ERROR;
+ }
+
+ for (i = 0; i < 8; i++)
+ {
+ t_buf[i] = atoi(argv[i+1]);
+ }
+
+ msg1.send_buf = &t_buf;
+ msg1.recv_buf = &r_buf;
+ msg1.length = sizeof(t_buf);
+ msg1.cs_take = 1;
+ msg1.cs_release = 0;
+ msg1.next = RT_NULL;
+
+ rt_spi_transfer_message(spi_dev, &msg1);
+
+ rt_kprintf("spi rbuf : ");
+ for (i = 0; i < sizeof(t_buf); i++)
+ {
+ rt_kprintf("%x ", r_buf[i]);
+ }
+
+ rt_kprintf("\nspi loopback mode test over!\n");
+
+ return RT_EOK;
+}
+MSH_CMD_EXPORT(spi_sample, spi loopback test);
+
+#endif /* BSP_USING_SPI5 */
diff --git a/bsp/stm32/stm32mp157a-st-ev1/board/ports/timer_sample.c b/bsp/stm32/stm32mp157a-st-ev1/board/ports/timer_sample.c
new file mode 100644
index 0000000000..fdbc721c8d
--- /dev/null
+++ b/bsp/stm32/stm32mp157a-st-ev1/board/ports/timer_sample.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2020-07-27 thread-liu first version
+ */
+
+#include <board.h>
+
+#if defined(BSP_USING_TIM14) && defined(BSP_USING_ADC2)
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define HWTIMER_DEV_NAME "timer14"
+#define HWADC_DEV_NAME "adc2"
+#define REFER_VOLTAGE 330 /* voltage reference */
+#define CONVERT_BITS (1 << 12) /* Conversion digit */
+#define ADC_DEV_CHANNEL 6
+
+static rt_adc_device_t adc_dev = RT_NULL;
+
+static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size)
+{
+ rt_uint32_t value = 0 , vol = 0;
+
+ /* read adc value */
+ value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
+ rt_kprintf("the value is :%d \n", value);
+
+ vol = value * REFER_VOLTAGE / CONVERT_BITS;
+ rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
+
+ return 0;
+}
+
+static int hwtimer_stop(void)
+{
+ rt_err_t ret = RT_EOK;
+ rt_device_t hw_dev = RT_NULL;
+
+ hw_dev = rt_device_find(HWTIMER_DEV_NAME);
+ if (hw_dev == RT_NULL)
+ {
+ rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEV_NAME);
+ return RT_ERROR;
+ }
+
+ ret = rt_device_close(hw_dev);
+ if (ret != RT_EOK)
+ {
+ rt_kprintf("close %s device failed!\n", HWTIMER_DEV_NAME);
+ return ret;
+ }
+
+ /* close adc channel */
+ ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);
+
+ return ret;
+}
+
+static int hwtimer_start(void)
+{
+ rt_err_t ret = RT_EOK;
+ rt_hwtimerval_t timeout_s;
+ rt_device_t hw_dev = RT_NULL;
+
+ rt_hwtimer_mode_t mode;
+
+ hw_dev = rt_device_find(HWTIMER_DEV_NAME);
+ if (hw_dev == RT_NULL)
+ {
+ rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEV_NAME);
+ return RT_ERROR;
+ }
+
+ /* find adc dev */
+ adc_dev = (rt_adc_device_t)rt_device_find(HWADC_DEV_NAME);
+ if (adc_dev == RT_NULL)
+ {
+ rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWADC_DEV_NAME);
+ return RT_ERROR;
+ }
+
+ /* Open the device in read/write mode */
+ ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
+ if (ret != RT_EOK)
+ {
+ rt_kprintf("open %s device failed!\n", HWTIMER_DEV_NAME);
+ return ret;
+ }
+
+ /* Set the timeout callback function */
+ rt_device_set_rx_indicate(hw_dev, timeout_cb);
+
+ /* Set the mode to periodic timer */
+ mode = HWTIMER_MODE_PERIOD;
+ ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);
+ if (ret != RT_EOK)
+ {
+ rt_kprintf("set mode failed! ret is :%d\n", ret);
+ return ret;
+ }
+
+ timeout_s.sec = 5;
+ timeout_s.usec = 0;
+
+ if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s))
+ {
+ rt_kprintf("set timeout value failed\n");
+ return RT_ERROR;
+ }
+
+ rt_thread_mdelay(3500);
+
+ rt_device_read(hw_dev, 0, &timeout_s, sizeof(timeout_s));
+ rt_kprintf("Read: Sec = %d, Usec = %d\n", timeout_s.sec, timeout_s.usec);
+
+ /* enable adc channel */
+ ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
+
+ return ret;
+}
+
+static int tim_sample(int argc, char *argv[])
+{
+ if (argc > 1)
+ {
+ if (!rt_strcmp(argv[1], "start"))
+ {
+ rt_kprintf("tim14 will start\n");
+ hwtimer_start();
+ return RT_EOK;
+ }
+ else if (!rt_strcmp(argv[1], "stop"))
+ {
+ hwtimer_stop();
+ rt_kprintf("stop tim14 success!\n");
+ return RT_EOK;
+ }
+ else
+ {
+ goto _exit;
+ }
+ }
+_exit:
+ {
+ rt_kprintf("Usage:\n");
+ rt_kprintf("tim_sample start - start TIM14 \n");
+ rt_kprintf("tim_sample stop - stop TIM14 \n");
+ }
+
+ return RT_ERROR;
+}
+MSH_CMD_EXPORT(tim_sample, tim sample);
+
+#endif
diff --git a/bsp/stm32/stm32mp157a-st-ev1/rtconfig.py b/bsp/stm32/stm32mp157a-st-ev1/rtconfig.py
index b1cad1d512..3daaf0c1db 100644
--- a/bsp/stm32/stm32mp157a-st-ev1/rtconfig.py
+++ b/bsp/stm32/stm32mp157a-st-ev1/rtconfig.py
@@ -23,7 +23,7 @@ elif CROSS_TOOL == 'keil':
EXEC_PATH = r'C:/Keil_v5'
elif CROSS_TOOL == 'iar':
PLATFORM = 'iar'
- EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.0'
+ EXEC_PATH = r'D:\software\Embedded Workbench 8.3'
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
diff --git a/bsp/thead-smart/README.md b/bsp/thead-smart/README.md
index 990818a606..c65180f26b 100644
--- a/bsp/thead-smart/README.md
+++ b/bsp/thead-smart/README.md
@@ -1,8 +1,10 @@
# T-HEAD SMART-EVB Introduction
SMART-EVB is a development board provided by T-HEAD, based on FPGA to provide implementation, integrating T-HEAD's RISC-V CPU (eg. E902/E906/C906) and C-SKY CPU (eg. E805/E804/E803/E802 ), integrates basic peripheral resources such as GPIO/TIMER/UART/RAM.
-##The main resources on board are as follows:
+## The main resources on board are as follows:
+
1. SMART-EVB for E906/E906F/E906FD
+
| res | description |
| -- | -- |
|ISA | RISCV |
@@ -12,6 +14,7 @@ SMART-EVB is a development board provided by T-HEAD, based on FPGA to provide im
2. SMART-EVB for E804/E804F/E804D
+
| res | description |
| -- | -- |
|ISA | C-SKY |
@@ -22,24 +25,24 @@ SMART-EVB is a development board provided by T-HEAD, based on FPGA to provide im
# Compile T-HEAD BSP
SMART-EVB BSP supports GCC compiler, the version information is:
+
1. SMART-EVB for E906/E906F/E906FD
+
| IDE/Compiler| version|
| - | - |
| GCC | gcc version 8.4.0 (C-SKY RISCV Tools V1.9.6 B20200616) |
# run smart-evb bsp
+
1. Connect JTAG
2. Connect the serial port
3. riscv64-unknown-elf-gdb rtthread-e906f.elf
run log as follows:
-```
+```bash
\ | /
- RT - Thread Operating System
/ | \ 4.0.3 build Sep 2 2020
2006 - 2020 Copyright by rt-thread team
msh >
```
-
-
-
diff --git a/components/dfs/filesystems/devfs/devfs.c b/components/dfs/filesystems/devfs/devfs.c
index 7637074dbb..e457f18727 100644
--- a/components/dfs/filesystems/devfs/devfs.c
+++ b/components/dfs/filesystems/devfs/devfs.c
@@ -326,7 +326,7 @@ static const struct dfs_filesystem_ops _device_fs =
int devfs_init(void)
{
- /* register rom file system */
+ /* register device file system */
dfs_register(&_device_fs);
return 0;
diff --git a/components/dfs/filesystems/romfs/dfs_romfs.c b/components/dfs/filesystems/romfs/dfs_romfs.c
index dcc34e5830..17dbee52f5 100644
--- a/components/dfs/filesystems/romfs/dfs_romfs.c
+++ b/components/dfs/filesystems/romfs/dfs_romfs.c
@@ -62,7 +62,7 @@ struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const ch
return root_dirent;
}
- /* goto root directy entries */
+ /* goto root directory entries */
dirent = (struct romfs_dirent *)root_dirent->data;
dirent_size = root_dirent->size;
diff --git a/components/drivers/audio/audio.c b/components/drivers/audio/audio.c
index 846dad07cf..6614b75ff5 100644
--- a/components/drivers/audio/audio.c
+++ b/components/drivers/audio/audio.c
@@ -12,7 +12,6 @@
#include <stdio.h>
#include <string.h>
#include <rthw.h>
-#include <rtthread.h>
#include <rtdevice.h>
#define DBG_TAG "audio"
@@ -590,7 +589,6 @@ int rt_audio_samplerate_to_speed(rt_uint32_t bitValue)
speed = 192000;
break;
default:
-
break;
}
diff --git a/components/drivers/audio/audio_pipe.c b/components/drivers/audio/audio_pipe.c
index d7c37009b6..0a6f090a83 100644
--- a/components/drivers/audio/audio_pipe.c
+++ b/components/drivers/audio/audio_pipe.c
@@ -9,9 +9,6 @@
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtdevice.h>
-
#include "audio_pipe.h"
static void _rt_pipe_resume_writer(struct rt_audio_pipe *pipe)
diff --git a/components/drivers/audio/audio_pipe.h b/components/drivers/audio/audio_pipe.h
index 85a3eb1793..3ae3bc8498 100644
--- a/components/drivers/audio/audio_pipe.h
+++ b/components/drivers/audio/audio_pipe.h
@@ -12,7 +12,6 @@
/**
* Pipe Device
*/
-#include <rtthread.h>
#include <rtdevice.h>
#ifndef RT_PIPE_BUFSZ
@@ -71,6 +70,6 @@ rt_err_t rt_audio_pipe_detach(struct rt_audio_pipe *pipe);
#ifdef RT_USING_HEAP
rt_err_t rt_audio_pipe_create(const char *name, rt_int32_t flag, rt_size_t size);
void rt_audio_pipe_destroy(struct rt_audio_pipe *pipe);
-#endif
-#endif
+#endif /* RT_USING_HEAP */
+#endif /* __AUDIO_PIPE_H__ */
diff --git a/components/drivers/include/drivers/alarm.h b/components/drivers/include/drivers/alarm.h
index dd59f4c1e8..e59c4142c7 100644
--- a/components/drivers/include/drivers/alarm.h
+++ b/components/drivers/include/drivers/alarm.h
@@ -49,6 +49,8 @@ struct rt_alarm
rt_uint32_t flag;
rt_alarm_callback_t callback;
struct tm wktime;
+
+ void *user_data;
};
struct rt_alarm_setup
diff --git a/components/drivers/include/ipc/ringbuffer.h b/components/drivers/include/ipc/ringbuffer.h
index 4487d02c47..2afd2ca213 100644
--- a/components/drivers/include/ipc/ringbuffer.h
+++ b/components/drivers/include/ipc/ringbuffer.h
@@ -71,6 +71,7 @@ rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb, const rt_uint8_t *pt
rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch);
rt_size_t rt_ringbuffer_putchar_force(struct rt_ringbuffer *rb, const rt_uint8_t ch);
rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb, rt_uint8_t *ptr, rt_uint16_t length);
+rt_size_t rt_ringbuffer_peak(struct rt_ringbuffer *rb, rt_uint8_t **ptr);
rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch);
rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb);
diff --git a/components/drivers/rtc/alarm.c b/components/drivers/rtc/alarm.c
index 53cb538321..ea1b150e7a 100644
--- a/components/drivers/rtc/alarm.c
+++ b/components/drivers/rtc/alarm.c
@@ -14,8 +14,16 @@
#include <rtthread.h>
#include <rtdevice.h>
+#ifndef _WIN32
+#include <sys/time.h>
+#endif
+
#define RT_RTC_YEARS_MAX 137
+#ifdef RT_USING_SOFT_RTC
+#define RT_ALARM_DELAY 0
+#else
#define RT_ALARM_DELAY 2
+#endif
#define RT_ALARM_STATE_INITED 0x02
#define RT_ALARM_STATE_START 0x01
#define RT_ALARM_STATE_STOP 0x00
@@ -41,10 +49,12 @@ static rt_err_t alarm_set(struct rt_alarm *alarm)
rt_err_t ret;
device = rt_device_find("rtc");
+
if (device == RT_NULL)
{
return (RT_ERROR);
}
+
if (alarm->flag & RT_ALARM_STATE_START)
wkalarm.enable = RT_TRUE;
else
@@ -215,7 +225,11 @@ static void alarm_update(rt_uint32_t event)
{
/* get time of now */
timestamp = time(RT_NULL);
- localtime_r(&timestamp, &now);
+#ifdef _WIN32
+ _gmtime32_s(&now, &timestamp);
+#else
+ gmtime_r(&timestamp, &now);
+#endif
for (next = _container.head.next; next != &_container.head; next = next->next)
{
@@ -225,7 +239,11 @@ static void alarm_update(rt_uint32_t event)
}
timestamp = time(RT_NULL);
- localtime_r(&timestamp, &now);
+#ifdef _WIN32
+ _gmtime32_s(&now, &timestamp);
+#else
+ gmtime_r(&timestamp, &now);
+#endif
sec_now = alarm_mkdaysec(&now);
for (next = _container.head.next; next != &_container.head; next = next->next)
@@ -233,7 +251,6 @@ static void alarm_update(rt_uint32_t event)
alarm = rt_list_entry(next, struct rt_alarm, list);
/* calculate seconds from 00:00:00 */
sec_alarm = alarm_mkdaysec(&alarm->wktime);
-
if (alarm->flag & RT_ALARM_STATE_START)
{
sec_tmp = sec_alarm - sec_now;
@@ -257,6 +274,7 @@ static void alarm_update(rt_uint32_t event)
}
}
}
+
/* enable the alarm after now first */
if (sec_next < 24 * 3600)
{
@@ -329,7 +347,12 @@ static rt_err_t alarm_setup(rt_alarm_t alarm, struct tm *wktime)
setup = &alarm->wktime;
*setup = *wktime;
timestamp = time(RT_NULL);
- localtime_r(&timestamp, &now);
+
+#ifdef _WIN32
+ _gmtime32_s(&now, &timestamp);
+#else
+ gmtime_r(&timestamp, &now);
+#endif
/* if these are a "don't care" value,we set them to now*/
if ((setup->tm_sec > 59) || (setup->tm_sec < 0))
@@ -526,21 +549,28 @@ rt_err_t rt_alarm_control(rt_alarm_t alarm, int cmd, void *arg)
rt_err_t rt_alarm_start(rt_alarm_t alarm)
{
rt_int32_t sec_now, sec_old, sec_new;
- rt_err_t ret = RT_ERROR;
+ rt_err_t ret = RT_EOK;
time_t timestamp;
struct tm now;
if (alarm == RT_NULL)
- return (ret);
+ return (RT_ERROR);
rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
if (!(alarm->flag & RT_ALARM_STATE_START))
{
if (alarm_setup(alarm, &alarm->wktime) != RT_EOK)
+ {
+ ret = RT_ERROR;
goto _exit;
+ }
timestamp = time(RT_NULL);
- localtime_r(&timestamp, &now);
+#ifdef _WIN32
+ _gmtime32_s(&now, &timestamp);
+#else
+ gmtime_r(&timestamp, &now);
+#endif
alarm->flag |= RT_ALARM_STATE_START;
@@ -593,10 +623,10 @@ _exit:
*/
rt_err_t rt_alarm_stop(rt_alarm_t alarm)
{
- rt_err_t ret = RT_ERROR;
+ rt_err_t ret = RT_EOK;
if (alarm == RT_NULL)
- return (ret);
+ return (RT_ERROR);
rt_mutex_take(&_container.mutex, RT_WAITING_FOREVER);
if (!(alarm->flag & RT_ALARM_STATE_START))
goto _exit;
@@ -695,23 +725,59 @@ static void rt_alarmsvc_thread_init(void *param)
}
}
+struct _alarm_flag
+{
+ const char* name;
+ rt_uint32_t flag;
+};
+
+static const struct _alarm_flag _alarm_flag_tbl[] =
+{
+ {"N", 0xffff}, /* none */
+ {"O", RT_ALARM_ONESHOT}, /* only alarm onece */
+ {"D", RT_ALARM_DAILY}, /* alarm everyday */
+ {"W", RT_ALARM_WEEKLY}, /* alarm weekly at Monday or Friday etc. */
+ {"Mo", RT_ALARM_MONTHLY}, /* alarm monthly at someday */
+ {"Y", RT_ALARM_YAERLY}, /* alarm yearly at a certain date */
+ {"H", RT_ALARM_HOUR}, /* alarm each hour at a certain min:second */
+ {"M", RT_ALARM_MINUTE}, /* alarm each minute at a certain second */
+ {"S", RT_ALARM_SECOND}, /* alarm each second */
+};
+
+static rt_uint8_t _alarm_flag_tbl_size = sizeof(_alarm_flag_tbl) / sizeof(_alarm_flag_tbl[0]);
+
+static rt_uint8_t get_alarm_flag_index(rt_uint32_t alarm_flag)
+{
+ for (rt_uint8_t index = 0; index < _alarm_flag_tbl_size; index++)
+ {
+ alarm_flag &= 0xff00;
+ if (alarm_flag == _alarm_flag_tbl[index].flag)
+ {
+ return index;
+ }
+ }
+
+ return 0;
+}
+
void rt_alarm_dump(void)
{
rt_list_t *next;
rt_alarm_t alarm;
rt_uint8_t index = 0;
- rt_kprintf("| alarm_id | YYYY-MM-DD hh:mm:ss | weekday | flags |\n");
- rt_kprintf("+----------+---------------------+---------+---------+\n");
+ rt_kprintf("| id | YYYY-MM-DD hh:mm:ss | week | flag | en |\n");
+ rt_kprintf("+----+---------------------+------+------+----+\n");
for (next = _container.head.next; next != &_container.head; next = next->next)
{
alarm = rt_list_entry(next, struct rt_alarm, list);
- rt_kprintf("| No %5d | %04d-%02d-%02d %02d:%02d:%02d | %7d | 0x%04x |\n",
+ rt_uint8_t flag_index = get_alarm_flag_index(alarm->flag);
+ rt_kprintf("| %2d | %04d-%02d-%02d %02d:%02d:%02d | %2d | %2s | %2d |\n",
index++, alarm->wktime.tm_year + 1900, alarm->wktime.tm_mon + 1, alarm->wktime.tm_mday,
alarm->wktime.tm_hour, alarm->wktime.tm_min, alarm->wktime.tm_sec,
- alarm->wktime.tm_wday, alarm->flag);
+ alarm->wktime.tm_wday, _alarm_flag_tbl[flag_index].name, alarm->flag & RT_ALARM_STATE_START);
}
- rt_kprintf("+----------+---------------------+---------+---------+\n");
+ rt_kprintf("+----+---------------------+------+------+----+\n");
}
FINSH_FUNCTION_EXPORT_ALIAS(rt_alarm_dump, __cmd_alarm_dump, dump alarm info);
diff --git a/components/drivers/rtc/soft_rtc.c b/components/drivers/rtc/soft_rtc.c
index adcbf81fe3..6a04314675 100644
--- a/components/drivers/rtc/soft_rtc.c
+++ b/components/drivers/rtc/soft_rtc.c
@@ -11,8 +11,7 @@
#include <time.h>
#include <string.h>
#include <rtthread.h>
-
-#include <drivers/rtc.h>
+#include <rtdevice.h>
#ifdef RT_USING_SOFT_RTC
@@ -28,9 +27,37 @@ static struct rt_device soft_rtc_dev;
static rt_tick_t init_tick;
static time_t init_time;
+#ifdef RT_USING_ALARM
+
+static struct rt_rtc_wkalarm wkalarm;
+static struct rt_timer alarm_time;
+
+static void alarm_timeout(void *param)
+{
+ rt_alarm_update(param, 1);
+}
+
+static void soft_rtc_alarm_update(struct rt_rtc_wkalarm *palarm)
+{
+ rt_tick_t next_tick;
+
+ if (palarm->enable)
+ {
+ next_tick = RT_TICK_PER_SECOND;
+ rt_timer_control(&alarm_time, RT_TIMER_CTRL_SET_TIME, &next_tick);
+ rt_timer_start(&alarm_time);
+ }
+ else
+ {
+ rt_timer_stop(&alarm_time);
+ }
+}
+
+#endif
+
static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
{
- time_t *time;
+ time_t *t;
struct tm time_temp;
RT_ASSERT(dev != RT_NULL);
@@ -39,16 +66,27 @@ static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
switch (cmd)
{
case RT_DEVICE_CTRL_RTC_GET_TIME:
- time = (time_t *) args;
- *time = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
+ t = (time_t *) args;
+ *t = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
break;
-
case RT_DEVICE_CTRL_RTC_SET_TIME:
{
- time = (time_t *) args;
- init_time = *time - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
+ t = (time_t *) args;
+ init_time = *t - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
+#ifdef RT_USING_ALARM
+ soft_rtc_alarm_update(&wkalarm);
+#endif
break;
}
+#ifdef RT_USING_ALARM
+ case RT_DEVICE_CTRL_RTC_GET_ALARM:
+ *((struct rt_rtc_wkalarm *)args) = wkalarm;
+ break;
+ case RT_DEVICE_CTRL_RTC_SET_ALARM:
+ wkalarm = *((struct rt_rtc_wkalarm *)args);
+ soft_rtc_alarm_update(&wkalarm);
+ break;
+#endif
}
return RT_EOK;
@@ -78,6 +116,15 @@ int rt_soft_rtc_init(void)
/* make sure only one 'rtc' device */
RT_ASSERT(!rt_device_find("rtc"));
+#ifdef RT_USING_ALARM
+ rt_timer_init(&alarm_time,
+ "alarm",
+ alarm_timeout,
+ &soft_rtc_dev,
+ 0,
+ RT_TIMER_FLAG_SOFT_TIMER|RT_TIMER_FLAG_ONE_SHOT);
+#endif
+
init_tick = rt_tick_get();
init_time = mktime(&time_new);
diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c
index 2511f18102..c2cc2f615c 100644
--- a/components/drivers/serial/serial.c
+++ b/components/drivers/serial/serial.c
@@ -221,7 +221,10 @@ rt_inline int _serial_poll_rx(struct rt_serial_device *serial, rt_uint8_t *data,
*data = ch;
data ++; length --;
- if (ch == '\n') break;
+ if(serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)
+ {
+ if (ch == '\n') break;
+ }
}
return size - length;
diff --git a/components/drivers/src/ringbuffer.c b/components/drivers/src/ringbuffer.c
index c6a491a7cc..88afd19506 100644
--- a/components/drivers/src/ringbuffer.c
+++ b/components/drivers/src/ringbuffer.c
@@ -194,6 +194,40 @@ rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb,
RTM_EXPORT(rt_ringbuffer_get);
/**
+ * peak data from ring buffer
+ */
+rt_size_t rt_ringbuffer_peak(struct rt_ringbuffer *rb, rt_uint8_t **ptr)
+{
+ RT_ASSERT(rb != RT_NULL);
+
+ *ptr = RT_NULL;
+
+ /* whether has enough data */
+ rt_size_t size = rt_ringbuffer_data_len(rb);
+
+ /* no data */
+ if (size == 0)
+ return 0;
+
+ *ptr = &rb->buffer_ptr[rb->read_index];
+
+ if(rb->buffer_size - rb->read_index > size)
+ {
+ rb->read_index += size;
+ return size;
+ }
+
+ size = rb->buffer_size - rb->read_index;
+
+ /* we are going into the other side of the mirror */
+ rb->read_mirror = ~rb->read_mirror;
+ rb->read_index = 0;
+
+ return size;
+}
+RTM_EXPORT(rt_ringbuffer_peak);
+
+/**
* put a character into ring buffer
*/
rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch)
diff --git a/components/drivers/src/workqueue.c b/components/drivers/src/workqueue.c
index 2e0280df3a..2b5630d8d0 100644
--- a/components/drivers/src/workqueue.c
+++ b/components/drivers/src/workqueue.c
@@ -424,6 +424,6 @@ int rt_work_sys_workqueue_init(void)
return RT_EOK;
}
-INIT_DEVICE_EXPORT(rt_work_sys_workqueue_init);
+INIT_PREV_EXPORT(rt_work_sys_workqueue_init);
#endif
#endif
diff --git a/components/drivers/usb/usbdevice/class/audio_mic.c b/components/drivers/usb/usbdevice/class/audio_mic.c
index 4ac85711ad..23ade2d9b6 100644
--- a/components/drivers/usb/usbdevice/class/audio_mic.c
+++ b/components/drivers/usb/usbdevice/class/audio_mic.c
@@ -9,10 +9,7 @@
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtservice.h>
#include <rtdevice.h>
-
#include "drivers/usb_device.h"
#include "audio.h"
diff --git a/components/drivers/usb/usbdevice/class/audio_speaker.c b/components/drivers/usb/usbdevice/class/audio_speaker.c
index 84c36d2053..e9a3ffaf40 100644
--- a/components/drivers/usb/usbdevice/class/audio_speaker.c
+++ b/components/drivers/usb/usbdevice/class/audio_speaker.c
@@ -9,10 +9,7 @@
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtservice.h>
#include <rtdevice.h>
-
#include "drivers/usb_device.h"
#include "audio.h"
diff --git a/components/drivers/usb/usbdevice/class/cdc_vcom.c b/components/drivers/usb/usbdevice/class/cdc_vcom.c
index 64230533ae..f9ea466bd5 100644
--- a/components/drivers/usb/usbdevice/class/cdc_vcom.c
+++ b/components/drivers/usb/usbdevice/class/cdc_vcom.c
@@ -13,8 +13,6 @@
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtservice.h>
#include <rtdevice.h>
#include <drivers/serial.h>
#include "drivers/usb_device.h"
diff --git a/components/drivers/usb/usbdevice/class/hid.c b/components/drivers/usb/usbdevice/class/hid.c
index a4acce75ea..52e50296a4 100644
--- a/components/drivers/usb/usbdevice/class/hid.c
+++ b/components/drivers/usb/usbdevice/class/hid.c
@@ -11,13 +11,9 @@
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtservice.h>
#include <rtdevice.h>
-
#include "drivers/usb_common.h"
#include "drivers/usb_device.h"
-
#include "hid.h"
#ifdef RT_USB_DEVICE_HID
diff --git a/components/drivers/usb/usbdevice/class/mstorage.c b/components/drivers/usb/usbdevice/class/mstorage.c
index d0a2b7f736..6991d97eae 100644
--- a/components/drivers/usb/usbdevice/class/mstorage.c
+++ b/components/drivers/usb/usbdevice/class/mstorage.c
@@ -12,7 +12,6 @@
*/
#include <rtthread.h>
-#include <rtservice.h>
#include "drivers/usb_device.h"
#include "mstorage.h"
diff --git a/components/drivers/usb/usbdevice/class/winusb.c b/components/drivers/usb/usbdevice/class/winusb.c
index 729e39f663..4af6dba3cf 100644
--- a/components/drivers/usb/usbdevice/class/winusb.c
+++ b/components/drivers/usb/usbdevice/class/winusb.c
@@ -8,8 +8,6 @@
* 2017-11-16 ZYH first version
*/
#include <rthw.h>
-#include <rtthread.h>
-#include <rtservice.h>
#include <rtdevice.h>
#include <drivers/usb_device.h>
#include "winusb.h"
diff --git a/components/libc/compilers/common/termios.h b/components/libc/compilers/common/termios.h
index ee2b4d5718..414d0c0cb3 100644
--- a/components/libc/compilers/common/termios.h
+++ b/components/libc/compilers/common/termios.h
@@ -9,6 +9,8 @@
#ifndef _TERMIOS_H__
#define _TERMIOS_H__
+#include <rtconfig.h>
+
#ifdef RT_USING_POSIX_TERMIOS
#include <sys/types.h>
#include <posix_termios.h>
diff --git a/components/net/lwip-1.4.1/src/netif/ethernetif.c b/components/net/lwip-1.4.1/src/netif/ethernetif.c
index d31ea813bc..f2570f9e2b 100644
--- a/components/net/lwip-1.4.1/src/netif/ethernetif.c
+++ b/components/net/lwip-1.4.1/src/netif/ethernetif.c
@@ -156,6 +156,16 @@ static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_
static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled)
{
netdev_low_level_set_dhcp_status(netif, is_enabled);
+
+ if(RT_TRUE == is_enabled)
+ {
+ dhcp_start((struct netif *)netif->user_data);
+ }
+ else
+ {
+ dhcp_stop((struct netif *)netif->user_data);
+ }
+
return ERR_OK;
}
#endif /* RT_LWIP_DHCP */
diff --git a/components/net/lwip-2.1.2/src/netif/ethernetif.c b/components/net/lwip-2.1.2/src/netif/ethernetif.c
index 10865930c1..52bd0fb7b6 100644
--- a/components/net/lwip-2.1.2/src/netif/ethernetif.c
+++ b/components/net/lwip-2.1.2/src/netif/ethernetif.c
@@ -163,6 +163,16 @@ static int lwip_netdev_set_dns_server(struct netdev *netif, uint8_t dns_num, ip_
static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled)
{
netdev_low_level_set_dhcp_status(netif, is_enabled);
+
+ if(RT_TRUE == is_enabled)
+ {
+ dhcp_start((struct netif *)netif->user_data);
+ }
+ else
+ {
+ dhcp_stop((struct netif *)netif->user_data);
+ }
+
return ERR_OK;
}
#endif /* RT_LWIP_DHCP */
diff --git a/libcpu/risc-v/common/context_gcc.S b/libcpu/risc-v/common/context_gcc.S
index 9f356f4191..e5fc8536ea 100644
--- a/libcpu/risc-v/common/context_gcc.S
+++ b/libcpu/risc-v/common/context_gcc.S
@@ -48,7 +48,7 @@ rt_hw_context_switch_to:
#ifdef RT_USING_SMP
mv a0, a1
- jal rt_cpus_lock_status_restore
+ call rt_cpus_lock_status_restore
#endif
LOAD a0, 2 * REGBYTES(sp)
csrw mstatus, a0
@@ -161,7 +161,7 @@ save_mpie:
#ifdef RT_USING_SMP
mv a0, a2
- jal rt_cpus_lock_status_restore
+ call rt_cpus_lock_status_restore
#endif /*RT_USING_SMP*/
j rt_hw_context_switch_exit
diff --git a/libcpu/risc-v/k210/interrupt_gcc.S b/libcpu/risc-v/k210/interrupt_gcc.S
index dc4a720dea..d695d04e4b 100644
--- a/libcpu/risc-v/k210/interrupt_gcc.S
+++ b/libcpu/risc-v/k210/interrupt_gcc.S
@@ -119,7 +119,7 @@ trap_entry:
mv sp, s0
mv a0, s0
call rt_scheduler_do_irq_switch
- j rt_hw_context_switch_exit
+ tail rt_hw_context_switch_exit
#else
@@ -143,4 +143,4 @@ trap_entry:
#endif
spurious_interrupt:
- j rt_hw_context_switch_exit
+ tail rt_hw_context_switch_exit
diff --git a/libcpu/risc-v/k210/startup_gcc.S b/libcpu/risc-v/k210/startup_gcc.S
index cc7126e8ab..f40ab1b6f8 100644
--- a/libcpu/risc-v/k210/startup_gcc.S
+++ b/libcpu/risc-v/k210/startup_gcc.S
@@ -116,18 +116,21 @@ _start:
/* other cpu core, jump to cpu entry directly */
bnez a0, secondary_cpu_entry
- j primary_cpu_entry
+ tail primary_cpu_entry
secondary_cpu_entry:
#ifdef RT_USING_SMP
la a0, secondary_boot_flag
ld a0, 0(a0)
li a1, 0xa55a
- beq a0, a1, secondary_cpu_c_start
+ beq a0, a1, 1f
#endif
j secondary_cpu_entry
#ifdef RT_USING_SMP
+1:
+ tail secondary_cpu_c_start
+
.data
.global secondary_boot_flag
.align 3
diff --git a/src/timer.c b/src/timer.c
index 4b9003794c..4d021ab367 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -331,7 +331,6 @@ rt_err_t rt_timer_start(rt_timer_t timer)
_rt_timer_remove(timer);
/* change status of timer */
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
- rt_hw_interrupt_enable(level);
RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent)));
@@ -342,9 +341,6 @@ rt_err_t rt_timer_start(rt_timer_t timer)
RT_ASSERT(timer->init_tick < RT_TICK_MAX / 2);
timer->timeout_tick = rt_tick_get() + timer->init_tick;
- /* disable interrupt */
- level = rt_hw_interrupt_disable();
-
#ifdef RT_USING_TIMER_SOFT
if (timer->parent.flag & RT_TIMER_FLAG_SOFT_TIMER)
{