From d6fab307bf49f0be9f669909aac06ae85a17d1bc Mon Sep 17 00:00:00 2001 From: jzlv Date: Fri, 18 Nov 2022 16:26:34 +0800 Subject: [PATCH] [update] update lhal, soc and demos * Add flash driver and init in boards. * Add timeout for all poll wait apis * Add 808 d0 startup to bringup * Update lhal device tables * Update demos --- bsp/board/bl602dk/bl602_flash.ld | 1 + bsp/board/bl602dk/board.c | 67 +- bsp/board/bl602dk/board.h | 9 +- bsp/board/bl616dk/bl616_flash.ld | 8 +- bsp/board/bl616dk/board.c | 108 +- bsp/board/bl616dk/board.h | 11 +- bsp/board/bl702dk/bl702_flash.ld | 7 +- bsp/board/bl702dk/board.c | 48 +- bsp/board/bl702dk/board.h | 9 +- bsp/board/bl808dk/CMakeLists.txt | 2 +- bsp/board/bl808dk/bl808_flash_d0.ld | 256 ++ bsp/board/bl808dk/bl808_flash_m0.ld | 263 ++ bsp/board/bl808dk/board.c | 154 +- bsp/board/bl808dk/board.h | 10 +- bsp/common/fatfs/fatfs_sdh_sdcard.c | 9 - drivers/lhal/CMakeLists.txt | 4 + drivers/lhal/config/bl602/device_table.c | 7 + drivers/lhal/config/bl616/device_table.c | 9 +- drivers/lhal/config/bl702/device_table.c | 9 +- drivers/lhal/config/bl808/device_table.c | 121 +- drivers/lhal/include/arch/risc-v/csr.h | 2 +- drivers/lhal/include/arch/risc-v/riscv_arch.h | 12 +- drivers/lhal/include/bflb_adc.h | 29 +- drivers/lhal/include/bflb_dma.h | 8 +- drivers/lhal/include/bflb_efuse.h | 20 + drivers/lhal/include/bflb_flash.h | 56 + drivers/lhal/include/bflb_gpio.h | 2 +- drivers/lhal/include/bflb_i2c.h | 3 - drivers/lhal/include/bflb_ir.h | 12 + drivers/lhal/include/bflb_irq.h | 5 +- drivers/lhal/include/bflb_l1c.h | 37 +- drivers/lhal/include/bflb_pwm_v1.h | 4 +- drivers/lhal/include/bflb_sec_irq.h | 24 + drivers/lhal/include/bflb_spi.h | 24 + drivers/lhal/include/bflb_timer.h | 15 +- drivers/lhal/include/bflb_uart.h | 12 +- drivers/lhal/include/bflb_wdg.h | 4 + drivers/lhal/include/hardware/gpio_reg.h | 1 + drivers/lhal/include/hardware/ir_reg.h | 150 ++ drivers/lhal/src/bflb_adc.c | 34 +- drivers/lhal/src/bflb_gpio.c | 29 +- drivers/lhal/src/bflb_i2c.c | 41 +- drivers/lhal/src/bflb_ir.c | 26 +- drivers/lhal/src/bflb_irq.c | 33 +- drivers/lhal/src/bflb_l1c.c | 109 + drivers/lhal/src/bflb_mjpeg.c | 2 - drivers/lhal/src/bflb_pwm_v1.c | 108 +- drivers/lhal/src/bflb_pwm_v2.c | 26 +- drivers/lhal/src/bflb_sec_aes.c | 15 + drivers/lhal/src/bflb_sec_irq.c | 176 ++ drivers/lhal/src/bflb_sec_sha.c | 52 + drivers/lhal/src/bflb_sec_trng.c | 9 + drivers/lhal/src/bflb_spi.c | 23 +- drivers/lhal/src/bflb_uart.c | 111 +- drivers/soc/bl602/CMakeLists.txt | 28 +- .../bl602/bl602_std/include/bl602_common.h | 5 + .../soc/bl602/bl602_std/include/bl602_glb.h | 2 +- .../soc/bl602/bl602_std/include/bl602_l1c.h | 189 ++ .../bl602_std/include/hardware/l1c_reg.h | 318 +++ drivers/soc/bl602/bl602_std/src/bl602_aon.c | 551 +++++ .../soc/bl602/bl602_std/src/bl602_common.c | 162 ++ .../soc/bl602/bl602_std/src/bl602_ef_ctrl.c | 1872 ++++++++++++++ drivers/soc/bl602/bl602_std/src/bl602_l1c.c | 428 ++++ drivers/soc/bl602/bl602_std/src/bl602_pds.c | 841 +++++++ .../soc/bl602/bl602_std/src/bl602_sf_cfg.c | 2193 +++++++++++++++++ .../bl602/bl602_std/src/bl602_sf_cfg_ext.c | 790 ++++++ .../soc/bl602/bl602_std/src/bl602_sf_ctrl.c | 1149 +++++++++ .../soc/bl602/bl602_std/src/bl602_sflash.c | 1549 ++++++++++++ .../bl602/bl602_std/src/bl602_sflash_ext.c | 608 +++++ .../bl602/bl602_std/src/bl602_xip_sflash.c | 434 ++++ .../bl602_std/src/bl602_xip_sflash_ext.c | 583 +++++ drivers/soc/bl602/port/bl602_efuse.c | 53 + drivers/soc/bl602/port/bl602_flash.c | 201 ++ drivers/soc/bl602/startup/interrupt.c | 12 + drivers/soc/bl616/CMakeLists.txt | 20 +- .../bl616/bl616_std/include/bl616_common.h | 12 +- .../bl616/bl616_std/include/bl616_ef_ctrl.h | 2 +- .../soc/bl616/bl616_std/include/bl616_psram.h | 27 +- .../soc/bl616/bl616_std/include/bl616_sdh.h | 3 +- .../bl616/bl616_std/include/bl616_sflash.h | 2 + .../bl616_std/include/bl616_xip_sflash.h | 3 + .../soc/bl616/bl616_std/src/bl616_common.c | 10 +- .../soc/bl616/bl616_std/src/bl616_ef_cfg.c | 105 +- drivers/soc/bl616/bl616_std/src/bl616_l1c.c | 388 +++ drivers/soc/bl616/bl616_std/src/bl616_psram.c | 54 +- .../bl616/bl616_std/src/bl616_romapi_e907.c | 192 +- .../bl616/bl616_std/src/bl616_romapi_patch.c | 625 +++-- drivers/soc/bl616/bl616_std/src/bl616_sdh.c | 6 - .../soc/bl616/bl616_std/src/bl616_sf_cfg.c | 2 +- .../soc/bl616/bl616_std/src/bl616_sflash.c | 59 + .../bl616/bl616_std/src/bl616_xip_sflash.c | 29 + drivers/soc/bl616/port/bl616_efuse.c | 53 + drivers/soc/bl616/port/bl616_flash.c | 395 +++ drivers/soc/bl616/startup/vector.S | 1 + drivers/soc/bl702/CMakeLists.txt | 28 +- .../bl702/bl702_std/include/bl702_common.h | 5 + .../soc/bl702/bl702_std/include/bl702_l1c.h | 3 +- drivers/soc/bl702/bl702_std/src/bl702_l1c.c | 102 +- .../soc/bl702/bl702_std/src/bl702_romapi.c | 58 +- .../soc/bl702/bl702_std/src/bl702_sf_cfg.c | 2 +- .../bl702/bl702_std/src/bl702_sf_cfg_ext.c | 1 + .../bl702_std/src/bl702_xip_sflash_ext.c | 1 - drivers/soc/bl702/port/bl702_efuse.c | 53 + drivers/soc/bl702/port/bl702_flash.c | 198 ++ drivers/soc/bl702/startup/interrupt.c | 12 + drivers/soc/bl808/CMakeLists.txt | 15 +- .../bl808/bl808_std/include/bl808_common.h | 10 + .../soc/bl808/bl808_std/include/bl808_sdh.h | 3 +- drivers/soc/bl808/bl808_std/src/bl808_l1c.c | 408 +++ drivers/soc/bl808/bl808_std/src/bl808_sdh.c | 6 - .../soc/bl808/bl808_std/src/bl808_sf_cfg.c | 1673 +++++++++++++ .../soc/bl808/bl808_std/src/bl808_sf_ctrl.c | 1870 ++++++++++++++ .../soc/bl808/bl808_std/src/bl808_sflash.c | 2164 ++++++++++++++++ .../bl808/bl808_std/src/bl808_xip_sflash.c | 469 ++++ drivers/soc/bl808/port/bl808_efuse.c | 53 + drivers/soc/bl808/port/bl808_flash.c | 243 ++ drivers/soc/bl808/startup/d0/interrupt.c | 154 ++ drivers/soc/bl808/startup/d0/irq_ctx.h | 372 +++ drivers/soc/bl808/startup/d0/riscv_fpu.S | 221 ++ drivers/soc/bl808/startup/d0/start.S | 91 + drivers/soc/bl808/startup/d0/start_load.c | 94 + drivers/soc/bl808/startup/d0/system_bl808.c | 55 + drivers/soc/bl808/startup/d0/vector.S | 724 ++++++ drivers/soc/bl808/startup/m0/system_bl808.c | 20 - drivers/soc/bl808/startup/m0/vector.S | 1 + examples/bl808_dualcore/Makefile | 9 + .../helloworld_d0}/CMakeLists.txt | 2 +- .../bl808_dualcore/helloworld_d0/Makefile | 14 + examples/bl808_dualcore/helloworld_d0/main.c | 17 + .../bl808_dualcore/helloworld_d0/proj.conf | 2 + .../helloworld_m0}/CMakeLists.txt | 2 +- .../bl808_dualcore/helloworld_m0/Makefile | 14 + examples/bl808_dualcore/helloworld_m0/main.c | 17 + .../bl808_dualcore/helloworld_m0/proj.conf | 3 + .../CMakeLists.txt | 2 +- .../adc/{adc_oneshot_1ch => adc_dma}/Makefile | 0 examples/peripherals/adc/adc_dma/main.c | 158 ++ .../{adc_oneshot_1ch => adc_dma}/proj.conf | 0 .../CMakeLists.txt | 2 +- .../{adc_oneshot_1ch_dma => adc_int}/Makefile | 0 examples/peripherals/adc/adc_int/main.c | 137 + .../proj.conf | 0 .../peripherals/adc/adc_oneshot_1ch/main.c | 46 - .../adc/adc_oneshot_1ch_dma/main.c | 94 - .../adc/adc_oneshot_1ch_int/main.c | 66 - .../peripherals/adc/adc_poll/CMakeLists.txt | 9 + .../Makefile | 0 examples/peripherals/adc/adc_poll/main.c | 120 + .../proj.conf | 0 .../adc/adc_poll_diff_mode/CMakeLists.txt | 9 + .../Makefile | 0 .../main.c | 39 +- .../proj.conf | 0 examples/peripherals/adc/adc_tsen/main.c | 7 +- examples/peripherals/adc/adc_vbat/main.c | 25 +- examples/peripherals/cks/cks_dma/main.c | 11 +- examples/peripherals/cks/cks_normal/main.c | 43 +- .../peripherals/dma/dma_reduce_or_add/main.c | 2 + .../flash/flash_dma/CMakeLists.txt | 9 + .../gpio_output => flash/flash_dma}/Makefile | 0 examples/peripherals/flash/flash_dma/main.c | 147 ++ .../peripherals/flash/flash_dma/proj.conf | 1 + .../flash/flash_iomode/CMakeLists.txt | 9 + .../peripherals/flash/flash_iomode/Makefile | 13 + .../peripherals/flash/flash_iomode/main.c | 52 + .../peripherals/flash/flash_iomode/proj.conf | 1 + .../flash/flash_read_write/CMakeLists.txt | 9 + .../flash/flash_read_write/Makefile | 13 + .../peripherals/flash/flash_read_write/main.c | 53 + .../flash/flash_read_write/proj.conf | 1 + .../flash/flash_secure_read/CMakeLists.txt | 9 + .../flash/flash_secure_read/Makefile | 13 + .../flash/flash_secure_read/main.c | 102 + .../flash/flash_secure_read/proj.conf | 1 + .../gpio/gpio_input_output/CMakeLists.txt | 9 + .../gpio/gpio_input_output/Makefile | 13 + .../peripherals/gpio/gpio_input_output/main.c | 25 + .../proj.conf | 0 .../peripherals/gpio/gpio_interrupt/main.c | 8 +- examples/peripherals/gpio/gpio_output/main.c | 25 - .../i2c/i2c_eeprom_interrupt/main.c | 2 +- examples/peripherals/ir/ir_nec/main.c | 51 +- examples/peripherals/ir/ir_rc5/main.c | 51 +- examples/peripherals/ir/ir_swm/main.c | 57 +- .../peripherals/ir/ir_tx_dma/CMakeLists.txt | 9 + examples/peripherals/ir/ir_tx_dma/Makefile | 13 + examples/peripherals/ir/ir_tx_dma/main.c | 103 + examples/peripherals/ir/ir_tx_dma/proj.conf | 1 + .../peripherals/mjpeg/mjpeg_no_camera/main.c | 40 +- ...{test_64x64_64x64.YUYV => test_64x64.YUYV} | 0 examples/peripherals/mtimer/main.c | 3 +- examples/peripherals/psram/CMakeLists.txt | 9 + examples/peripherals/psram/Makefile | 13 + examples/peripherals/psram/main.c | 93 + examples/peripherals/psram/proj.conf | 1 + .../pwm_v1/pwm_all_channels/main.c | 2 +- examples/peripherals/pwm_v1/pwm_basic/main.c | 2 +- examples/peripherals/pwm_v1/pwm_int/main.c | 14 +- .../pwm_v2/pwm_all_channels/main.c | 36 +- examples/peripherals/pwm_v2/pwm_basic/main.c | 16 +- .../pwm_v2/pwm_config_channel/main.c | 62 +- .../peripherals/pwm_v2/pwm_deadtime/main.c | 38 +- examples/peripherals/pwm_v2/pwm_int/main.c | 54 +- examples/peripherals/spi/spi_dma/main.c | 3 +- .../peripherals/spi/spi_int/CMakeLists.txt | 9 + examples/peripherals/spi/spi_int/Makefile | 13 + examples/peripherals/spi/spi_int/main.c | 244 ++ examples/peripherals/spi/spi_int/proj.conf | 1 + examples/peripherals/spi/spi_poll/main.c | 46 +- .../timer_clksource_check/CMakeLists.txt | 9 + .../timer/timer_clksource_check/Makefile | 13 + .../timer/timer_clksource_check/main.c | 80 + .../timer/timer_clksource_check/proj.conf | 1 + examples/peripherals/timer/timer_int/main.c | 16 +- .../uart/uart_auto_baudrate/main.c | 32 +- examples/peripherals/uart/uart_cts_rts/main.c | 32 +- examples/peripherals/uart/uart_dma/main.c | 24 +- .../uart/uart_error_interrupt/main.c | 22 +- .../uart/uart_feature_control/main.c | 22 +- .../uart/uart_fifo_interrupt/main.c | 32 +- .../peripherals/uart/uart_ir/CMakeLists.txt | 9 + examples/peripherals/uart/uart_ir/Makefile | 13 + examples/peripherals/uart/uart_ir/main.c | 57 + examples/peripherals/uart/uart_ir/proj.conf | 1 + examples/peripherals/uart/uart_lin/main.c | 28 +- examples/peripherals/uart/uart_poll/main.c | 12 +- examples/peripherals/uart/uart_rs485/main.c | 32 +- .../wdg_clksource_check}/CMakeLists.txt | 2 +- .../wdg/wdg_clksource_check/Makefile | 13 + .../wdg/wdg_clksource_check/main.c | 80 + .../wdg/wdg_clksource_check/proj.conf | 1 + examples/peripherals/wdg/wdg_int/main.c | 2 +- 232 files changed, 26802 insertions(+), 1471 deletions(-) create mode 100644 bsp/board/bl808dk/bl808_flash_d0.ld create mode 100644 bsp/board/bl808dk/bl808_flash_m0.ld create mode 100644 drivers/lhal/include/bflb_efuse.h create mode 100644 drivers/lhal/include/bflb_flash.h create mode 100644 drivers/lhal/include/bflb_sec_irq.h create mode 100644 drivers/lhal/src/bflb_l1c.c create mode 100644 drivers/lhal/src/bflb_sec_irq.c create mode 100644 drivers/soc/bl602/bl602_std/include/bl602_l1c.h create mode 100644 drivers/soc/bl602/bl602_std/include/hardware/l1c_reg.h create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_aon.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_common.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_ef_ctrl.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_l1c.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_pds.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_sf_cfg.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_sf_cfg_ext.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_sf_ctrl.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_sflash.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_sflash_ext.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_xip_sflash.c create mode 100644 drivers/soc/bl602/bl602_std/src/bl602_xip_sflash_ext.c create mode 100644 drivers/soc/bl602/port/bl602_efuse.c create mode 100644 drivers/soc/bl602/port/bl602_flash.c create mode 100644 drivers/soc/bl616/bl616_std/src/bl616_l1c.c create mode 100644 drivers/soc/bl616/port/bl616_efuse.c create mode 100644 drivers/soc/bl616/port/bl616_flash.c create mode 100644 drivers/soc/bl702/port/bl702_efuse.c create mode 100644 drivers/soc/bl702/port/bl702_flash.c create mode 100644 drivers/soc/bl808/bl808_std/src/bl808_l1c.c create mode 100644 drivers/soc/bl808/bl808_std/src/bl808_sf_cfg.c create mode 100644 drivers/soc/bl808/bl808_std/src/bl808_sf_ctrl.c create mode 100644 drivers/soc/bl808/bl808_std/src/bl808_sflash.c create mode 100644 drivers/soc/bl808/bl808_std/src/bl808_xip_sflash.c create mode 100644 drivers/soc/bl808/port/bl808_efuse.c create mode 100644 drivers/soc/bl808/port/bl808_flash.c create mode 100644 drivers/soc/bl808/startup/d0/interrupt.c create mode 100644 drivers/soc/bl808/startup/d0/irq_ctx.h create mode 100644 drivers/soc/bl808/startup/d0/riscv_fpu.S create mode 100644 drivers/soc/bl808/startup/d0/start.S create mode 100644 drivers/soc/bl808/startup/d0/start_load.c create mode 100644 drivers/soc/bl808/startup/d0/system_bl808.c create mode 100644 drivers/soc/bl808/startup/d0/vector.S create mode 100644 examples/bl808_dualcore/Makefile rename examples/{peripherals/gpio/gpio_output => bl808_dualcore/helloworld_d0}/CMakeLists.txt (87%) create mode 100644 examples/bl808_dualcore/helloworld_d0/Makefile create mode 100644 examples/bl808_dualcore/helloworld_d0/main.c create mode 100644 examples/bl808_dualcore/helloworld_d0/proj.conf rename examples/{peripherals/adc/adc_oneshot_1ch => bl808_dualcore/helloworld_m0}/CMakeLists.txt (85%) create mode 100644 examples/bl808_dualcore/helloworld_m0/Makefile create mode 100644 examples/bl808_dualcore/helloworld_m0/main.c create mode 100644 examples/bl808_dualcore/helloworld_m0/proj.conf rename examples/peripherals/adc/{adc_oneshot_1ch_dma => adc_dma}/CMakeLists.txt (83%) rename examples/peripherals/adc/{adc_oneshot_1ch => adc_dma}/Makefile (100%) create mode 100644 examples/peripherals/adc/adc_dma/main.c rename examples/peripherals/adc/{adc_oneshot_1ch => adc_dma}/proj.conf (100%) rename examples/peripherals/adc/{adc_oneshot_multich => adc_int}/CMakeLists.txt (83%) rename examples/peripherals/adc/{adc_oneshot_1ch_dma => adc_int}/Makefile (100%) create mode 100644 examples/peripherals/adc/adc_int/main.c rename examples/peripherals/adc/{adc_oneshot_1ch_dma => adc_int}/proj.conf (100%) delete mode 100644 examples/peripherals/adc/adc_oneshot_1ch/main.c delete mode 100644 examples/peripherals/adc/adc_oneshot_1ch_dma/main.c delete mode 100644 examples/peripherals/adc/adc_oneshot_1ch_int/main.c create mode 100644 examples/peripherals/adc/adc_poll/CMakeLists.txt rename examples/peripherals/adc/{adc_oneshot_1ch_int => adc_poll}/Makefile (100%) create mode 100644 examples/peripherals/adc/adc_poll/main.c rename examples/peripherals/adc/{adc_oneshot_1ch_int => adc_poll}/proj.conf (100%) create mode 100644 examples/peripherals/adc/adc_poll_diff_mode/CMakeLists.txt rename examples/peripherals/adc/{adc_oneshot_multich => adc_poll_diff_mode}/Makefile (100%) rename examples/peripherals/adc/{adc_oneshot_multich => adc_poll_diff_mode}/main.c (52%) rename examples/peripherals/adc/{adc_oneshot_multich => adc_poll_diff_mode}/proj.conf (100%) create mode 100644 examples/peripherals/flash/flash_dma/CMakeLists.txt rename examples/peripherals/{gpio/gpio_output => flash/flash_dma}/Makefile (100%) create mode 100644 examples/peripherals/flash/flash_dma/main.c create mode 100644 examples/peripherals/flash/flash_dma/proj.conf create mode 100644 examples/peripherals/flash/flash_iomode/CMakeLists.txt create mode 100644 examples/peripherals/flash/flash_iomode/Makefile create mode 100644 examples/peripherals/flash/flash_iomode/main.c create mode 100644 examples/peripherals/flash/flash_iomode/proj.conf create mode 100644 examples/peripherals/flash/flash_read_write/CMakeLists.txt create mode 100644 examples/peripherals/flash/flash_read_write/Makefile create mode 100644 examples/peripherals/flash/flash_read_write/main.c create mode 100644 examples/peripherals/flash/flash_read_write/proj.conf create mode 100644 examples/peripherals/flash/flash_secure_read/CMakeLists.txt create mode 100644 examples/peripherals/flash/flash_secure_read/Makefile create mode 100644 examples/peripherals/flash/flash_secure_read/main.c create mode 100644 examples/peripherals/flash/flash_secure_read/proj.conf create mode 100644 examples/peripherals/gpio/gpio_input_output/CMakeLists.txt create mode 100644 examples/peripherals/gpio/gpio_input_output/Makefile create mode 100644 examples/peripherals/gpio/gpio_input_output/main.c rename examples/peripherals/gpio/{gpio_output => gpio_input_output}/proj.conf (100%) delete mode 100644 examples/peripherals/gpio/gpio_output/main.c create mode 100644 examples/peripherals/ir/ir_tx_dma/CMakeLists.txt create mode 100644 examples/peripherals/ir/ir_tx_dma/Makefile create mode 100644 examples/peripherals/ir/ir_tx_dma/main.c create mode 100644 examples/peripherals/ir/ir_tx_dma/proj.conf rename examples/peripherals/mjpeg/mjpeg_no_camera/{test_64x64_64x64.YUYV => test_64x64.YUYV} (100%) create mode 100644 examples/peripherals/psram/CMakeLists.txt create mode 100644 examples/peripherals/psram/Makefile create mode 100644 examples/peripherals/psram/main.c create mode 100644 examples/peripherals/psram/proj.conf create mode 100644 examples/peripherals/spi/spi_int/CMakeLists.txt create mode 100644 examples/peripherals/spi/spi_int/Makefile create mode 100644 examples/peripherals/spi/spi_int/main.c create mode 100644 examples/peripherals/spi/spi_int/proj.conf create mode 100644 examples/peripherals/timer/timer_clksource_check/CMakeLists.txt create mode 100644 examples/peripherals/timer/timer_clksource_check/Makefile create mode 100644 examples/peripherals/timer/timer_clksource_check/main.c create mode 100644 examples/peripherals/timer/timer_clksource_check/proj.conf create mode 100644 examples/peripherals/uart/uart_ir/CMakeLists.txt create mode 100644 examples/peripherals/uart/uart_ir/Makefile create mode 100644 examples/peripherals/uart/uart_ir/main.c create mode 100644 examples/peripherals/uart/uart_ir/proj.conf rename examples/peripherals/{adc/adc_oneshot_1ch_int => wdg/wdg_clksource_check}/CMakeLists.txt (83%) create mode 100644 examples/peripherals/wdg/wdg_clksource_check/Makefile create mode 100644 examples/peripherals/wdg/wdg_clksource_check/main.c create mode 100644 examples/peripherals/wdg/wdg_clksource_check/proj.conf diff --git a/bsp/board/bl602dk/bl602_flash.ld b/bsp/board/bl602dk/bl602_flash.ld index b51a8de3..ea99f13d 100644 --- a/bsp/board/bl602dk/bl602_flash.ld +++ b/bsp/board/bl602dk/bl602_flash.ld @@ -164,6 +164,7 @@ SECTIONS __system_ram_data_start__ = .; *(.system_ram) + *(.nocache_ram) . = ALIGN(4); __system_ram_data_end__ = .; diff --git a/bsp/board/bl602dk/board.c b/bsp/board/bl602dk/board.c index 3e9abc65..1b83e85f 100644 --- a/bsp/board/bl602dk/board.c +++ b/bsp/board/bl602dk/board.c @@ -2,9 +2,11 @@ #include "bflb_gpio.h" #include "bflb_clock.h" #include "bflb_rtc.h" +#include "bflb_flash.h" #include "mmheap.h" #include "board.h" #include "bl602_glb.h" +#include "bl602_sflash.h" extern uint32_t __HeapBase; extern uint32_t __HeapLimit; @@ -40,7 +42,7 @@ static void peripheral_clock_init(void) GLB_Set_SPI_CLK(ENABLE, 0); GLB_Set_I2C_CLK(ENABLE, 0); - GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 0); + GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 1); GLB_Set_DAC_CLK(ENABLE, GLB_DAC_CLK_XCLK, 0x3E); } @@ -58,6 +60,33 @@ void bl_show_log(void) printf("Copyright (c) 2022 Bouffalolab team\r\n"); } +void bl_show_flashinfo(void) +{ + SPI_Flash_Cfg_Type flashCfg; + uint8_t *pFlashCfg = NULL; + uint32_t flashCfgLen = 0; + uint32_t flashJedecId = 0; + + flashJedecId = bflb_flash_get_jedec_id(); + bflb_flash_get_cfg(&pFlashCfg, &flashCfgLen); + arch_memcpy((void *)&flashCfg, pFlashCfg, flashCfgLen); + printf("=========== flash cfg ==============\r\n"); + printf("jedec id 0x%06X\r\n", flashJedecId); + printf("mid 0x%02X\r\n", flashCfg.mid); + printf("iomode 0x%02X\r\n", flashCfg.ioMode); + printf("clk delay 0x%02X\r\n", flashCfg.clkDelay); + printf("clk invert 0x%02X\r\n", flashCfg.clkInvert); + printf("read reg cmd0 0x%02X\r\n", flashCfg.readRegCmd[0]); + printf("read reg cmd1 0x%02X\r\n", flashCfg.readRegCmd[1]); + printf("write reg cmd0 0x%02X\r\n", flashCfg.writeRegCmd[0]); + printf("write reg cmd1 0x%02X\r\n", flashCfg.writeRegCmd[1]); + printf("qe write len 0x%02X\r\n", flashCfg.qeWriteRegLen); + printf("cread support 0x%02X\r\n", flashCfg.cReadSupport); + printf("cread code 0x%02X\r\n", flashCfg.cReadMode); + printf("burst wrap cmd 0x%02X\r\n", flashCfg.burstWrapCmd); + printf("=====================================\r\n"); +} + extern void bflb_uart_set_console(struct bflb_device_s *dev); static void console_init() @@ -85,9 +114,17 @@ static void console_init() void board_init(void) { - bflb_irq_initialize(); + uintptr_t flag; + + flag = bflb_irq_save(); + + bflb_flash_init(); + system_clock_init(); peripheral_clock_init(); + bflb_irq_initialize(); + + bflb_irq_restore(flag); system_mmheap[0].addr = (uint8_t *)&__HeapBase; system_mmheap[0].mem_size = ((size_t)&__HeapLimit - (size_t)&__HeapBase); @@ -103,20 +140,20 @@ void board_init(void) printf("dynamic memory init success,heap size = %d Kbyte \r\n", system_mmheap[0].mem_size / 1024); } -void board_uart1_gpio_init() +void board_uartx_gpio_init() { - struct bflb_device_s *gpio; + // struct bflb_device_s *gpio; - gpio = bflb_device_get_by_name("gpio"); + // gpio = bflb_device_get_by_name("gpio"); // bflb_gpio_uart_init(gpio, GPIO_PIN_18, GPIO_UART_FUNC_UART1_TX); // bflb_gpio_uart_init(gpio, GPIO_PIN_19, GPIO_UART_FUNC_UART1_RX); } void board_i2c0_gpio_init() { - struct bflb_device_s *gpio; + // struct bflb_device_s *gpio; - gpio = bflb_device_get_by_name("gpio"); + // gpio = bflb_device_get_by_name("gpio"); // /* I2C0_SDA */ // bflb_gpio_init(gpio, GPIO_PIN_11, GPIO_FUNC_I2C0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); // /* I2C0_SCL */ @@ -125,9 +162,9 @@ void board_i2c0_gpio_init() void board_spi0_gpio_init() { - struct bflb_device_s *gpio; + // struct bflb_device_s *gpio; - gpio = bflb_device_get_by_name("gpio"); + // gpio = bflb_device_get_by_name("gpio"); // bflb_gpio_init(gpio, GPIO_PIN_18, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); // bflb_gpio_init(gpio, GPIO_PIN_19, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); // bflb_gpio_init(gpio, GPIO_PIN_20, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); @@ -135,9 +172,9 @@ void board_spi0_gpio_init() void board_pwm_gpio_init() { - struct bflb_device_s *gpio; + // struct bflb_device_s *gpio; - gpio = bflb_device_get_by_name("gpio"); + // gpio = bflb_device_get_by_name("gpio"); // bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); // bflb_gpio_init(gpio, GPIO_PIN_1, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); // bflb_gpio_init(gpio, GPIO_PIN_2, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); @@ -147,9 +184,9 @@ void board_pwm_gpio_init() void board_adc_gpio_init() { - struct bflb_device_s *gpio; + // struct bflb_device_s *gpio; - gpio = bflb_device_get_by_name("gpio"); + // gpio = bflb_device_get_by_name("gpio"); // bflb_gpio_init(gpio, GPIO_PIN_18, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0); // bflb_gpio_init(gpio, GPIO_PIN_19, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0); // bflb_gpio_init(gpio, GPIO_PIN_20, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0); @@ -157,9 +194,9 @@ void board_adc_gpio_init() void board_dac_gpio_init() { - struct bflb_device_s *gpio; + // struct bflb_device_s *gpio; - gpio = bflb_device_get_by_name("gpio"); + // gpio = bflb_device_get_by_name("gpio"); /* DAC_CHA */ // bflb_gpio_init(gpio, GPIO_PIN_11, GPIO_ANALOG | GPIO_SMT_EN | GPIO_DRV_0); // /* DAC_CHB */ diff --git a/bsp/board/bl602dk/board.h b/bsp/board/bl602dk/board.h index 7b527d98..c8fb9b35 100644 --- a/bsp/board/bl602dk/board.h +++ b/bsp/board/bl602dk/board.h @@ -3,11 +3,18 @@ void board_init(void); -void board_uart1_gpio_init(); +void board_uartx_gpio_init(); void board_i2c0_gpio_init(); void board_spi0_gpio_init(); void board_adc_gpio_init(); void board_dac_gpio_init(); void board_emac_gpio_init(); void board_pwm_gpio_init(); + +#define DEFAULT_TEST_UART "uart1" +#define DEFAULT_TEST_UART_DMA_TX_REQUEST DMA_REQUEST_UART1_TX +#define DEFAULT_TEST_UART_DMA_RX_REQUEST DMA_REQUEST_UART1_RX +#define DEFAULT_TEST_UART_DMA_TDR DMA_ADDR_UART1_TDR +#define DEFAULT_TEST_UART_DMA_RDR DMA_ADDR_UART1_RDR + #endif \ No newline at end of file diff --git a/bsp/board/bl616dk/bl616_flash.ld b/bsp/board/bl616dk/bl616_flash.ld index af802179..c4fc4380 100644 --- a/bsp/board/bl616dk/bl616_flash.ld +++ b/bsp/board/bl616dk/bl616_flash.ld @@ -23,10 +23,10 @@ HeapMinSize = 0x1000; /* 4KB */ MEMORY { xip_memory (rx) : ORIGIN = 0xA0000000, LENGTH = 4M - itcm_memory (rx) : ORIGIN = 0x62FC0000, LENGTH = 16K - dtcm_memory (rx) : ORIGIN = 0x62FC4000, LENGTH = 4K - nocache_ram_memory (!rx) : ORIGIN = 0x22FC5000, LENGTH = 44K+64K - ram_memory (!rx) : ORIGIN = 0x62FE0000 , LENGTH = 320K+160K-16K-4K-44K-64K + itcm_memory (rx) : ORIGIN = 0x62FC0000, LENGTH = 20K + dtcm_memory (rx) : ORIGIN = 0x62FC5000, LENGTH = 4K + nocache_ram_memory (!rx) : ORIGIN = 0x22FC6000, LENGTH = 44K+60K + ram_memory (!rx) : ORIGIN = 0x62FE0000 , LENGTH = 320K+160K-20K-4K-44K-60K } SECTIONS diff --git a/bsp/board/bl616dk/board.c b/bsp/board/bl616dk/board.c index 0fa599cb..ecd59895 100644 --- a/bsp/board/bl616dk/board.c +++ b/bsp/board/bl616dk/board.c @@ -2,11 +2,13 @@ #include "bflb_gpio.h" #include "bflb_clock.h" #include "bflb_rtc.h" +#include "bflb_flash.h" #include "mmheap.h" #include "board.h" #include "bl616_tzc_sec.h" #include "bl616_psram.h" #include "bl616_glb.h" +#include "bl616_sflash.h" #define WB_4MB_PSRAM (1) @@ -26,7 +28,7 @@ static struct heap_region system_mmheap[] = { static struct bflb_device_s *uart0; -#if (defined(CONFIG_LUA) || defined(CONFIG_BFLOG)) +#if (defined(CONFIG_LUA) || defined(CONFIG_BFLOG) || defined(CONFIG_FATFS)) static struct bflb_device_s *rtc; #endif @@ -56,10 +58,11 @@ static void peripheral_clock_init(void) GLB_Set_UART_CLK(ENABLE, HBN_UART_CLK_XCLK, 0); GLB_Set_SPI_CLK(ENABLE, GLB_SPI_CLK_MCU_MUXPLL_160M, 0); GLB_Set_I2C_CLK(ENABLE, GLB_I2C_CLK_XCLK, 0); - GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 0); + GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 1); GLB_Set_DIG_CLK_Sel(GLB_DIG_CLK_XCLK); GLB_Set_DIG_512K_CLK(ENABLE, ENABLE, 0x4E); GLB_Set_PWM1_IO_Sel(GLB_PWM1_IO_DIFF_END); + GLB_Set_IR_CLK(ENABLE, GLB_IR_CLK_SRC_XCLK, 19); GLB_Set_PKA_CLK_Sel(GLB_PKA_CLK_MCU_MUXPLL_160M); #ifdef CONFIG_BSP_SDH_SDCARD @@ -70,21 +73,16 @@ static void peripheral_clock_init(void) #endif GLB_Set_USB_CLK_From_WIFIPLL(1); + GLB_Swap_MCU_SPI_0_MOSI_With_MISO(0); } static void bflb_init_psram_gpio(void) { - GLB_GPIO_Cfg_Type cfg; - - cfg.pullType = GPIO_PULL_NONE; - cfg.drive = 0; - cfg.smtCtrl = 1; + struct bflb_device_s *gpio; + gpio = bflb_device_get_by_name("gpio"); for (uint8_t i = 0; i < 12; i++) { - cfg.gpioPin = 41 + i; - cfg.gpioMode = GPIO_MODE_INPUT; - - GLB_GPIO_Init(&cfg); + bflb_gpio_init(gpio, (41 + i), GPIO_INPUT | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_0); } } @@ -146,6 +144,33 @@ void bl_show_log(void) printf("Copyright (c) 2022 Bouffalolab team\r\n"); } +void bl_show_flashinfo(void) +{ + SPI_Flash_Cfg_Type flashCfg; + uint8_t *pFlashCfg = NULL; + uint32_t flashCfgLen = 0; + uint32_t flashJedecId = 0; + + flashJedecId = bflb_flash_get_jedec_id(); + bflb_flash_get_cfg(&pFlashCfg, &flashCfgLen); + arch_memcpy((void *)&flashCfg, pFlashCfg, flashCfgLen); + printf("=========== flash cfg ==============\r\n"); + printf("jedec id 0x%06X\r\n", flashJedecId); + printf("mid 0x%02X\r\n", flashCfg.mid); + printf("iomode 0x%02X\r\n", flashCfg.ioMode); + printf("clk delay 0x%02X\r\n", flashCfg.clkDelay); + printf("clk invert 0x%02X\r\n", flashCfg.clkInvert); + printf("read reg cmd0 0x%02X\r\n", flashCfg.readRegCmd[0]); + printf("read reg cmd1 0x%02X\r\n", flashCfg.readRegCmd[1]); + printf("write reg cmd0 0x%02X\r\n", flashCfg.writeRegCmd[0]); + printf("write reg cmd1 0x%02X\r\n", flashCfg.writeRegCmd[1]); + printf("qe write len 0x%02X\r\n", flashCfg.qeWriteRegLen); + printf("cread support 0x%02X\r\n", flashCfg.cReadSupport); + printf("cread code 0x%02X\r\n", flashCfg.cReadMode); + printf("burst wrap cmd 0x%02X\r\n", flashCfg.burstWrapCmd); + printf("=====================================\r\n"); +} + extern void bflb_uart_set_console(struct bflb_device_s *dev); static void console_init() @@ -173,9 +198,17 @@ static void console_init() void board_init(void) { - bflb_irq_initialize(); + uintptr_t flag; + + flag = bflb_irq_save(); + + bflb_flash_init(); + system_clock_init(); peripheral_clock_init(); + bflb_irq_initialize(); + + bflb_irq_restore(flag); system_mmheap[0].addr = (uint8_t *)&__HeapBase; system_mmheap[0].mem_size = ((size_t)&__HeapLimit - (size_t)&__HeapBase); @@ -187,23 +220,24 @@ void board_init(void) console_init(); bl_show_log(); + bl_show_flashinfo(); printf("dynamic memory init success,heap size = %d Kbyte \r\n", system_mmheap[0].mem_size / 1024); printf("sig1:%08lx\r\n", BL_RD_REG(GLB_BASE, GLB_UART_CFG1)); printf("sig2:%08lx\r\n", BL_RD_REG(GLB_BASE, GLB_UART_CFG2)); -#if (defined(CONFIG_LUA) || defined(CONFIG_BFLOG)) +#if (defined(CONFIG_LUA) || defined(CONFIG_BFLOG) || defined(CONFIG_FATFS)) rtc = bflb_device_get_by_name("rtc"); - bflb_rtc_set_time(rtc, BFLB_RTC_SEC2TIME(0)); #endif + #ifdef CONFIG_PSRAM board_psram_x8_init(); Tzc_Sec_PSRAMB_Access_Release(); #endif } -void board_uart1_gpio_init() +void board_uartx_gpio_init() { struct bflb_device_s *gpio; @@ -231,13 +265,17 @@ void board_spi0_gpio_init() struct bflb_device_s *gpio; gpio = bflb_device_get_by_name("gpio"); - bflb_gpio_init(gpio, GPIO_PIN_16, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); - bflb_gpio_init(gpio, GPIO_PIN_17, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); + /* spi cs */ + bflb_gpio_init(gpio, GPIO_PIN_12, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); + /* spi clk */ + bflb_gpio_init(gpio, GPIO_PIN_13, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); + /* spi miso */ bflb_gpio_init(gpio, GPIO_PIN_18, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); + /* spi mosi */ bflb_gpio_init(gpio, GPIO_PIN_19, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); } -void board_pwm0_gpio_init() +void board_pwm_gpio_init() { struct bflb_device_s *gpio; @@ -314,6 +352,15 @@ void board_sdh_gpio_init() bflb_gpio_init(gpio, GPIO_PIN_15, GPIO_FUNC_SDH | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2); } +void board_ir_gpio_init(void) +{ + struct bflb_device_s *gpio; + + gpio = bflb_device_get_by_name("gpio"); + bflb_gpio_init(gpio, GPIO_PIN_10, GPIO_INPUT | GPIO_SMT_EN | GPIO_DRV_0); + GLB_IR_RX_GPIO_Sel(GLB_GPIO_PIN_10); +} + #ifdef CONFIG_BFLOG __attribute__((weak)) uint64_t bflog_clock(void) { @@ -322,7 +369,7 @@ __attribute__((weak)) uint64_t bflog_clock(void) __attribute__((weak)) uint32_t bflog_time(void) { - return BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)); + return BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)) + 1640995200; } __attribute__((weak)) char *bflog_thread(void) @@ -332,18 +379,35 @@ __attribute__((weak)) char *bflog_thread(void) #endif #ifdef CONFIG_LUA -clock_t luaport_clock(void) +__attribute__((weak)) clock_t luaport_clock(void) { return (clock_t)CPU_Get_MTimer_Counter(); } -time_t luaport_time(time_t *seconds) +__attribute__((weak)) time_t luaport_time(time_t *seconds) { - time_t t = (time_t)BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)); + time_t t = (time_t)BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)) + 1640995200; if (seconds != NULL) { *seconds = t; } return t; } +#endif + +#ifdef CONFIG_FATFS +#include "bflb_timestamp.h" +__attribute__((weak)) uint32_t get_fattime(void) +{ + bflb_timestamp_t tm; + + bflb_timestamp_utc2time(BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)) + 1640995200, &tm); + + return ((uint32_t)(tm.year - 1980) << 25) /* Year 2015 */ + | ((uint32_t)tm.mon << 21) /* Month 1 */ + | ((uint32_t)tm.mday << 16) /* Mday 1 */ + | ((uint32_t)tm.hour << 11) /* Hour 0 */ + | ((uint32_t)tm.min << 5) /* Min 0 */ + | ((uint32_t)tm.sec >> 1); /* Sec 0 */ +} #endif \ No newline at end of file diff --git a/bsp/board/bl616dk/board.h b/bsp/board/bl616dk/board.h index 95196873..9b732ca1 100644 --- a/bsp/board/bl616dk/board.h +++ b/bsp/board/bl616dk/board.h @@ -3,13 +3,20 @@ void board_init(void); -void board_uart1_gpio_init(); +void board_uartx_gpio_init(); void board_i2c0_gpio_init(); void board_spi0_gpio_init(); -void board_pwm0_gpio_init(); +void board_pwm_gpio_init(); void board_adc_gpio_init(); void board_dac_gpio_init(); void board_emac_gpio_init(); void board_sdh_gpio_init(); +void board_ir_gpio_init(); + +#define DEFAULT_TEST_UART "uart1" +#define DEFAULT_TEST_UART_DMA_TX_REQUEST DMA_REQUEST_UART1_TX +#define DEFAULT_TEST_UART_DMA_RX_REQUEST DMA_REQUEST_UART1_RX +#define DEFAULT_TEST_UART_DMA_TDR DMA_ADDR_UART1_TDR +#define DEFAULT_TEST_UART_DMA_RDR DMA_ADDR_UART1_RDR #endif \ No newline at end of file diff --git a/bsp/board/bl702dk/bl702_flash.ld b/bsp/board/bl702dk/bl702_flash.ld index d9e20df2..0845b43e 100644 --- a/bsp/board/bl702dk/bl702_flash.ld +++ b/bsp/board/bl702dk/bl702_flash.ld @@ -22,9 +22,9 @@ StackSize = 0x1000; /* 4KB */ MEMORY { xip_memory (rx) : ORIGIN = 0x23000000, LENGTH = 1024K - itcm_memory (rx) : ORIGIN = 0x22014000, LENGTH = 8K - dtcm_memory (rx) : ORIGIN = 0x42016000, LENGTH = 4K - ram_memory (!rx) : ORIGIN = 0x42017000, LENGTH = 100K + itcm_memory (rx) : ORIGIN = 0x22014000, LENGTH = 12K + dtcm_memory (rx) : ORIGIN = 0x42017000, LENGTH = 4K + ram_memory (!rx) : ORIGIN = 0x42018000, LENGTH = 96K hbn_memory (rx) : ORIGIN = 0x40010000, LENGTH = 0xE00 /* hbn ram 4K used 3.5K*/ } @@ -158,6 +158,7 @@ SECTIONS __system_ram_data_start__ = .; *(.system_ram) + *(.nocache_ram) . = ALIGN(4); __system_ram_data_end__ = .; diff --git a/bsp/board/bl702dk/board.c b/bsp/board/bl702dk/board.c index c63b47d9..620e43e0 100644 --- a/bsp/board/bl702dk/board.c +++ b/bsp/board/bl702dk/board.c @@ -2,9 +2,11 @@ #include "bflb_gpio.h" #include "bflb_clock.h" #include "bflb_rtc.h" +#include "bflb_flash.h" #include "mmheap.h" #include "board.h" #include "bl702_glb.h" +#include "bl702_sflash.h" extern uint32_t __HeapBase; extern uint32_t __HeapLimit; @@ -43,7 +45,7 @@ static void peripheral_clock_init(void) GLB_Set_SPI_CLK(ENABLE, 0); GLB_Set_I2C_CLK(ENABLE, 0); - GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 0); + GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 1); GLB_Set_DAC_CLK(ENABLE, GLB_DAC_CLK_XCLK, 0x3E); GLB_Set_USB_CLK(ENABLE); @@ -63,6 +65,33 @@ void bl_show_log(void) printf("Copyright (c) 2022 Bouffalolab team\r\n"); } +void bl_show_flashinfo(void) +{ + SPI_Flash_Cfg_Type flashCfg; + uint8_t *pFlashCfg = NULL; + uint32_t flashCfgLen = 0; + uint32_t flashJedecId = 0; + + flashJedecId = bflb_flash_get_jedec_id(); + bflb_flash_get_cfg(&pFlashCfg, &flashCfgLen); + arch_memcpy((void *)&flashCfg, pFlashCfg, flashCfgLen); + printf("=========== flash cfg ==============\r\n"); + printf("jedec id 0x%06X\r\n", flashJedecId); + printf("mid 0x%02X\r\n", flashCfg.mid); + printf("iomode 0x%02X\r\n", flashCfg.ioMode); + printf("clk delay 0x%02X\r\n", flashCfg.clkDelay); + printf("clk invert 0x%02X\r\n", flashCfg.clkInvert); + printf("read reg cmd0 0x%02X\r\n", flashCfg.readRegCmd[0]); + printf("read reg cmd1 0x%02X\r\n", flashCfg.readRegCmd[1]); + printf("write reg cmd0 0x%02X\r\n", flashCfg.writeRegCmd[0]); + printf("write reg cmd1 0x%02X\r\n", flashCfg.writeRegCmd[1]); + printf("qe write len 0x%02X\r\n", flashCfg.qeWriteRegLen); + printf("cread support 0x%02X\r\n", flashCfg.cReadSupport); + printf("cread code 0x%02X\r\n", flashCfg.cReadMode); + printf("burst wrap cmd 0x%02X\r\n", flashCfg.burstWrapCmd); + printf("=====================================\r\n"); +} + extern void bflb_uart_set_console(struct bflb_device_s *dev); static void console_init() @@ -90,9 +119,17 @@ static void console_init() void board_init(void) { - bflb_irq_initialize(); + uintptr_t flag; + + flag = bflb_irq_save(); + + bflb_flash_init(); + system_clock_init(); peripheral_clock_init(); + bflb_irq_initialize(); + + bflb_irq_restore(flag); system_mmheap[0].addr = (uint8_t *)&__HeapBase; system_mmheap[0].mem_size = ((size_t)&__HeapLimit - (size_t)&__HeapBase); @@ -105,10 +142,12 @@ void board_init(void) bl_show_log(); + bl_show_flashinfo(); + printf("dynamic memory init success,heap size = %d Kbyte \r\n", system_mmheap[0].mem_size / 1024); } -void board_uart1_gpio_init() +void board_uartx_gpio_init() { struct bflb_device_s *gpio; @@ -133,8 +172,11 @@ void board_spi0_gpio_init() struct bflb_device_s *gpio; gpio = bflb_device_get_by_name("gpio"); + /* spi clk */ bflb_gpio_init(gpio, GPIO_PIN_18, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); + /* spi miso */ bflb_gpio_init(gpio, GPIO_PIN_19, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); + /* spi mosi */ bflb_gpio_init(gpio, GPIO_PIN_20, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); } diff --git a/bsp/board/bl702dk/board.h b/bsp/board/bl702dk/board.h index 7b527d98..c8fb9b35 100644 --- a/bsp/board/bl702dk/board.h +++ b/bsp/board/bl702dk/board.h @@ -3,11 +3,18 @@ void board_init(void); -void board_uart1_gpio_init(); +void board_uartx_gpio_init(); void board_i2c0_gpio_init(); void board_spi0_gpio_init(); void board_adc_gpio_init(); void board_dac_gpio_init(); void board_emac_gpio_init(); void board_pwm_gpio_init(); + +#define DEFAULT_TEST_UART "uart1" +#define DEFAULT_TEST_UART_DMA_TX_REQUEST DMA_REQUEST_UART1_TX +#define DEFAULT_TEST_UART_DMA_RX_REQUEST DMA_REQUEST_UART1_RX +#define DEFAULT_TEST_UART_DMA_TDR DMA_ADDR_UART1_TDR +#define DEFAULT_TEST_UART_DMA_RDR DMA_ADDR_UART1_RDR + #endif \ No newline at end of file diff --git a/bsp/board/bl808dk/CMakeLists.txt b/bsp/board/bl808dk/CMakeLists.txt index a6a539b4..92c4fa38 100644 --- a/bsp/board/bl808dk/CMakeLists.txt +++ b/bsp/board/bl808dk/CMakeLists.txt @@ -1,6 +1,6 @@ sdk_add_include_directories(.) -sdk_set_linker_script(bl808_flash.ld) +sdk_set_linker_script(bl808_flash_${CPU_ID}.ld) if(CONFIG_PSRAM) sdk_add_compile_definitions(-DCONFIG_PSRAM) diff --git a/bsp/board/bl808dk/bl808_flash_d0.ld b/bsp/board/bl808dk/bl808_flash_d0.ld new file mode 100644 index 00000000..15d31c54 --- /dev/null +++ b/bsp/board/bl808dk/bl808_flash_d0.ld @@ -0,0 +1,256 @@ +/**************************************************************************************** +* @file flash.ld +* +* @brief This file is the link script file (gnuarm or armgcc). +* +* Copyright (C) BouffaloLab 2021 +* +**************************************************************************************** +*/ + +/* configure the CPU type */ +OUTPUT_ARCH( "riscv" ) +/* link with the standard c library */ +INPUT(-lc) +/* link with the standard GCC library */ +INPUT(-lgcc) +/* configure the entry point */ +ENTRY(__start) + +StackSize = 0x0400; /* 1KB */ +HeapMinSize = 0x1000; /* 4KB */ + +MEMORY +{ + xip_memory (rx) : ORIGIN = 0x58000000, LENGTH = 32M + itcm_memory (rx) : ORIGIN = 0x3eff0000, LENGTH = 28K + dtcm_memory (rx) : ORIGIN = 0x3eff7000, LENGTH = 4K + nocache_ram_memory (!rx) : ORIGIN = 0x3eff8000, LENGTH = 0K + ram_memory (!rx) : ORIGIN = 0x3eff8000, LENGTH = 64K + xram_memory (!rx) : ORIGIN = 0x40004000, LENGTH = 16K +} + +SECTIONS +{ + + .text : + { + . = ALIGN(4); + __text_code_start__ = .; + + KEEP (*(SORT_NONE(.init))) + + *(.text) + *(.text.*) + + /* section information for shell */ + . = ALIGN(8); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + + /*put .rodata**/ + *(EXCLUDE_FILE( *bl808_glb*.o* \ + *bl808_glb_gpio*.o* \ + *bl808_pds*.o* \ + *bl808_aon*.o* \ + *bl808_hbn*.o* \ + *bl808_l1c*.o* \ + *bl808_common*.o* \ + *bl808_clock*.o* \ + *bl808_ef_ctrl*.o* \ + *bl808_sf_cfg*.o* \ + *bl808_sf_ctrl*.o* \ + *bl808_sflash*.o* \ + *bl808_xip_sflash*.o* \ + *bl808_romapi_patch*.o* ) .rodata*) + + *(.srodata) + *(.srodata.*) + + . = ALIGN(4); + __text_code_end__ = .; + } > xip_memory + + . = ALIGN(4); + __itcm_load_addr = .; + + .itcm_region : AT (__itcm_load_addr) + { + . = ALIGN(4); + __tcm_code_start__ = .; + + *(.tcm_code.*) + *(.tcm_const.*) + *(.sclock_rlt_code.*) + *(.sclock_rlt_const.*) + + *bl808_glb*.o*(.rodata*) + *bl808_glb_gpio*.o*(.rodata*) + *bl808_pds*.o*(.rodata*) + *bl808_aon*.o*(.rodata*) + *bl808_hbn*.o*(.rodata*) + *bl808_l1c*.o*(.rodata*) + *bl808_common*.o*(.rodata*) + *bl808_clock*.o*(.rodata*) + *bl808_ef_ctrl*.o*(.rodata*) + *bl808_sf_cfg*.o*(.rodata*) + *bl808_sf_ctrl*.o*(.rodata*) + *bl808_sflash*.o*(.rodata*) + *bl808_xip_sflash*.o*(.rodata*) + *bl808_romapi_patch*.o*(.rodata*) + + . = ALIGN(4); + __tcm_code_end__ = .; + } > itcm_memory + + __dtcm_load_addr = __itcm_load_addr + SIZEOF(.itcm_region); + + .dtcm_region : AT (__dtcm_load_addr) + { + . = ALIGN(4); + __tcm_data_start__ = .; + + *(.tcm_data) + /* *finger_print.o(.data*) */ + + . = ALIGN(4); + __tcm_data_end__ = .; + } > dtcm_memory + + /*************************************************************************/ + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + . = ALIGN(0x4); + . = . + StackSize; + . = ALIGN(0x4); + } > dtcm_memory + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(dtcm_memory) + LENGTH(dtcm_memory); + PROVIDE( __freertos_irq_stack_top = __StackTop); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __tcm_data_end__, "region RAM overflowed with stack") + /*************************************************************************/ + __nocache_ram_load_addr = __dtcm_load_addr + SIZEOF(.dtcm_region); + + .nocache_ram_region (NOLOAD) : AT (__nocache_ram_load_addr) + { + . = ALIGN(4); + __nocache_ram_data_start__ = .; + + *(.nocache_ram) + + . = ALIGN(4); + __nocache_ram_data_end__ = .; + } > nocache_ram_memory + + __system_ram_load_addr = __nocache_ram_load_addr + SIZEOF(.nocache_ram_region); + + .system_ram_data_region : AT (__system_ram_load_addr) + { + . = ALIGN(4); + __system_ram_data_start__ = .; + + *(.system_ram) + + . = ALIGN(4); + __system_ram_data_end__ = .; + } > ram_memory + + .system_ram_noinit_data_region (NOLOAD) : + { + . = ALIGN(4); + *(.system_ram_noinit) + + . = ALIGN(4); + } > ram_memory + + __ram_load_addr = __system_ram_load_addr + SIZEOF(.system_ram_data_region); + + /* Data section */ + RAM_DATA : AT (__ram_load_addr) + { + . = ALIGN(4); + __ram_data_start__ = .; + + PROVIDE( __global_pointer$ = . + 0x800 ); + + *(.data) + *(.data.*) + *(.sdata) + *(.sdata.*) + *(.sdata2) + *(.sdata2.*) + + . = ALIGN(4); + __ram_data_end__ = .; + } > ram_memory + + __etext_final = (__ram_load_addr + SIZEOF (RAM_DATA)); + ASSERT(__etext_final <= ORIGIN(xip_memory) + LENGTH(xip_memory), "code memory overflow") + + .bss (NOLOAD) : + { + . = ALIGN(4); + __bss_start__ = .; + + *(.bss*) + *(.sbss*) + *(COMMON) + + . = ALIGN(4); + __bss_end__ = .; + } > ram_memory + + .noinit_data (NOLOAD) : + { + . = ALIGN(4); + __noinit_data_start__ = .; + + *(.noinit_data*) + + . = ALIGN(4); + __noinit_data_end__ = .; + } > ram_memory + + .nocache_noinit_ram_region (NOLOAD) : + { + . = ALIGN(4); + __nocache_ram_data_start__ = .; + + *(.nocache_noinit_ram) + + . = ALIGN(4); + __nocache_ram_data_end__ = .; + } > nocache_ram_memory + + .heap (NOLOAD): + { + . = ALIGN(4); + __HeapBase = .; + + /*__end__ = .;*/ + /*end = __end__;*/ + KEEP(*(.heap*)) + + . = ALIGN(4); + __HeapLimit = .; + } > ram_memory + + __HeapLimit = ORIGIN(ram_memory) + LENGTH(ram_memory); + ASSERT(__HeapLimit - __HeapBase >= HeapMinSize, "heap region overflow") + +} + diff --git a/bsp/board/bl808dk/bl808_flash_m0.ld b/bsp/board/bl808dk/bl808_flash_m0.ld new file mode 100644 index 00000000..b35f1ed3 --- /dev/null +++ b/bsp/board/bl808dk/bl808_flash_m0.ld @@ -0,0 +1,263 @@ +/**************************************************************************************** +* @file flash.ld +* +* @brief This file is the link script file (gnuarm or armgcc). +* +* Copyright (C) BouffaloLab 2021 +* +**************************************************************************************** +*/ + +/* configure the CPU type */ +OUTPUT_ARCH( "riscv" ) +/* link with the standard c library */ +INPUT(-lc) +/* link with the standard GCC library */ +INPUT(-lgcc) +/* configure the entry point */ +ENTRY(__start) + +StackSize = 0x0400; /* 1KB */ +HeapMinSize = 0x1000; /* 4KB */ + +MEMORY +{ + xip_memory (rx) : ORIGIN = 0x58000000, LENGTH = 32M + itcm_memory (rx) : ORIGIN = 0x62028000, LENGTH = 20K + dtcm_memory (rx) : ORIGIN = 0x6202D000, LENGTH = 4K + nocache_ram_memory (!rx) : ORIGIN = 0x2202E000, LENGTH = 16K + 56K + ram_memory (!rx) : ORIGIN = 0x62040000, LENGTH = 160K - 56K + xram_memory (!rx) : ORIGIN = 0x40000000, LENGTH = 16K +} + +SECTIONS +{ + + .text : + { + . = ALIGN(4); + __text_code_start__ = .; + + KEEP (*(SORT_NONE(.init))) + + *(.text) + *(.text.*) + + /* section information for shell */ + . = ALIGN(4); + __fsymtab_start = .; + KEEP(*(FSymTab)) + __fsymtab_end = .; + + . = ALIGN(4); + __vsymtab_start = .; + KEEP(*(VSymTab)) + __vsymtab_end = .; + + /* section information for usb usbh_class_info */ + . = ALIGN(4); + __usbh_class_info_start__ = .; + KEEP(*(.usbh_class_info)) + . = ALIGN(4); + __usbh_class_info_end__ = .; + + /*put .rodata**/ + *(EXCLUDE_FILE( *bl808_glb*.o* \ + *bl808_glb_gpio*.o* \ + *bl808_pds*.o* \ + *bl808_aon*.o* \ + *bl808_hbn*.o* \ + *bl808_l1c*.o* \ + *bl808_common*.o* \ + *bl808_clock*.o* \ + *bl808_ef_ctrl*.o* \ + *bl808_sf_cfg*.o* \ + *bl808_sf_ctrl*.o* \ + *bl808_sflash*.o* \ + *bl808_xip_sflash*.o* \ + *bl808_romapi_patch*.o* ) .rodata*) + *(.srodata) + *(.srodata.*) + + . = ALIGN(4); + __text_code_end__ = .; + } > xip_memory + + . = ALIGN(4); + __itcm_load_addr = .; + + .itcm_region : AT (__itcm_load_addr) + { + . = ALIGN(4); + __tcm_code_start__ = .; + + *(.tcm_code.*) + *(.tcm_const.*) + *(.sclock_rlt_code.*) + *(.sclock_rlt_const.*) + + *bl808_glb*.o*(.rodata*) + *bl808_glb_gpio*.o*(.rodata*) + *bl808_pds*.o*(.rodata*) + *bl808_aon*.o*(.rodata*) + *bl808_hbn*.o*(.rodata*) + *bl808_l1c*.o*(.rodata*) + *bl808_common*.o*(.rodata*) + *bl808_clock*.o*(.rodata*) + *bl808_ef_ctrl*.o*(.rodata*) + *bl808_sf_cfg*.o*(.rodata*) + *bl808_sf_ctrl*.o*(.rodata*) + *bl808_sflash*.o*(.rodata*) + *bl808_xip_sflash*.o*(.rodata*) + *bl808_romapi_patch*.o*(.rodata*) + + . = ALIGN(4); + __tcm_code_end__ = .; + } > itcm_memory + + __dtcm_load_addr = __itcm_load_addr + SIZEOF(.itcm_region); + + .dtcm_region : AT (__dtcm_load_addr) + { + . = ALIGN(4); + __tcm_data_start__ = .; + + *(.tcm_data) + /* *finger_print.o(.data*) */ + + . = ALIGN(4); + __tcm_data_end__ = .; + } > dtcm_memory + + /*************************************************************************/ + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (NOLOAD): + { + . = ALIGN(0x4); + . = . + StackSize; + . = ALIGN(0x4); + } > dtcm_memory + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(dtcm_memory) + LENGTH(dtcm_memory); + PROVIDE( __freertos_irq_stack_top = __StackTop); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __tcm_data_end__, "region RAM overflowed with stack") + /*************************************************************************/ + __nocache_ram_load_addr = __dtcm_load_addr + SIZEOF(.dtcm_region); + + .nocache_ram_region : AT (__nocache_ram_load_addr) + { + . = ALIGN(4); + __nocache_ram_data_start__ = .; + + *(.nocache_ram) + + . = ALIGN(4); + __nocache_ram_data_end__ = .; + } > nocache_ram_memory + + __system_ram_load_addr = __nocache_ram_load_addr + SIZEOF(.nocache_ram_region); + + .system_ram_data_region : AT (__system_ram_load_addr) + { + . = ALIGN(4); + __system_ram_data_start__ = .; + + *(.system_ram) + + . = ALIGN(4); + __system_ram_data_end__ = .; + } > ram_memory + + .system_ram_noinit_data_region (NOLOAD) : + { + . = ALIGN(4); + *(.system_ram_noinit) + + . = ALIGN(4); + } > ram_memory + + __ram_load_addr = __system_ram_load_addr + SIZEOF(.system_ram_data_region); + + /* Data section */ + RAM_DATA : AT (__ram_load_addr) + { + . = ALIGN(4); + __ram_data_start__ = .; + + PROVIDE( __global_pointer$ = . + 0x800 ); + + *(.data) + *(.data.*) + *(.sdata) + *(.sdata.*) + *(.sdata2) + *(.sdata2.*) + + . = ALIGN(4); + __ram_data_end__ = .; + } > ram_memory + + __etext_final = (__ram_load_addr + SIZEOF (RAM_DATA)); + ASSERT(__etext_final <= ORIGIN(xip_memory) + LENGTH(xip_memory), "code memory overflow") + + .bss (NOLOAD) : + { + . = ALIGN(4); + __bss_start__ = .; + + *(.bss*) + *(.sbss*) + *(COMMON) + + . = ALIGN(4); + __bss_end__ = .; + } > ram_memory + + .noinit_data (NOLOAD) : + { + . = ALIGN(4); + __noinit_data_start__ = .; + + *(.noinit_data*) + + . = ALIGN(4); + __noinit_data_end__ = .; + } > ram_memory + + .nocache_noinit_ram_region (NOLOAD) : + { + . = ALIGN(4); + __nocache_noinit_ram_data_start__ = .; + + *(.nocache_noinit_ram) + *(.noncacheable) + + . = ALIGN(4); + __nocache_noinit_ram_data_end__ = .; + } > nocache_ram_memory + + .heap (NOLOAD): + { + . = ALIGN(4); + __HeapBase = .; + + /*__end__ = .;*/ + /*end = __end__;*/ + KEEP(*(.heap*)) + + . = ALIGN(4); + __HeapLimit = .; + } > ram_memory + + __HeapLimit = ORIGIN(ram_memory) + LENGTH(ram_memory); + ASSERT(__HeapLimit - __HeapBase >= HeapMinSize, "heap region overflow") + +} + diff --git a/bsp/board/bl808dk/board.c b/bsp/board/bl808dk/board.c index d98d1165..6f1d7860 100644 --- a/bsp/board/bl808dk/board.c +++ b/bsp/board/bl808dk/board.c @@ -2,8 +2,10 @@ #include "bflb_gpio.h" #include "bflb_clock.h" #include "bflb_rtc.h" +#include "bflb_flash.h" #include "mmheap.h" #include "bl808_glb.h" +#include "bl808_sflash.h" #include "bl808_psram_uhs.h" #include "bl808_tzc_sec.h" #include "bl808_ef_cfg.h" @@ -26,14 +28,12 @@ static struct heap_region system_mmheap[] = { static struct bflb_device_s *uart0; -#if (defined(CONFIG_LUA) || defined(CONFIG_BFLOG)) +#if (defined(CONFIG_LUA) || defined(CONFIG_BFLOG) || defined(CONFIG_FATFS)) static struct bflb_device_s *rtc; #endif - +#if defined(CPU_M0) static void system_clock_init(void) { - GLB_Halt_CPU(GLB_CORE_ID_D0); - GLB_Halt_CPU(GLB_CORE_ID_LP); /* wifipll/audiopll */ GLB_Power_On_XTAL_And_PLL_CLK(GLB_XTAL_40M, GLB_PLL_WIFIPLL | GLB_PLL_CPUPLL | @@ -44,8 +44,6 @@ static void system_clock_init(void) GLB_Set_DSP_System_CLK(GLB_DSP_SYS_CLK_CPUPLL_400M); CPU_Set_MTimer_CLK(ENABLE, CPU_Get_MTimer_Source_Clock() / 1000 / 1000 - 1); - GLB_Release_CPU(GLB_CORE_ID_D0); - GLB_Release_CPU(GLB_CORE_ID_LP); } static void peripheral_clock_init(void) @@ -64,10 +62,11 @@ static void peripheral_clock_init(void) GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 4); GLB_Set_UART_CLK(ENABLE, HBN_UART_CLK_XCLK, 0); + GLB_Set_DSP_UART0_CLK(ENABLE, GLB_DSP_UART_CLK_DSP_XCLK, 0); GLB_Set_SPI_CLK(ENABLE, GLB_SPI_CLK_MCU_MUXPLL_160M, 0); GLB_Set_I2C_CLK(ENABLE, GLB_I2C_CLK_XCLK, 0); GLB_Set_IR_CLK(ENABLE, GLB_IR_CLK_SRC_XCLK, 19); - GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 0); + GLB_Set_ADC_CLK(ENABLE, GLB_ADC_CLK_XCLK, 1); GLB_Set_DIG_CLK_Sel(GLB_DIG_CLK_XCLK); GLB_Set_DIG_512K_CLK(ENABLE, ENABLE, 0x4E); GLB_Set_PWM1_IO_Sel(GLB_PWM1_IO_DIFF_END); @@ -143,6 +142,7 @@ int uhs_psram_init(void) return 0; } #endif +#endif void bl_show_log(void) { @@ -158,6 +158,33 @@ void bl_show_log(void) printf("Copyright (c) 2022 Bouffalolab team\r\n"); } +void bl_show_flashinfo(void) +{ + SPI_Flash_Cfg_Type flashCfg; + uint8_t *pFlashCfg = NULL; + uint32_t flashCfgLen = 0; + uint32_t flashJedecId = 0; + + flashJedecId = bflb_flash_get_jedec_id(); + bflb_flash_get_cfg(&pFlashCfg, &flashCfgLen); + arch_memcpy((void *)&flashCfg, pFlashCfg, flashCfgLen); + printf("=========== flash cfg ==============\r\n"); + printf("jedec id 0x%06X\r\n", flashJedecId); + printf("mid 0x%02X\r\n", flashCfg.mid); + printf("iomode 0x%02X\r\n", flashCfg.ioMode); + printf("clk delay 0x%02X\r\n", flashCfg.clkDelay); + printf("clk invert 0x%02X\r\n", flashCfg.clkInvert); + printf("read reg cmd0 0x%02X\r\n", flashCfg.readRegCmd[0]); + printf("read reg cmd1 0x%02X\r\n", flashCfg.readRegCmd[1]); + printf("write reg cmd0 0x%02X\r\n", flashCfg.writeRegCmd[0]); + printf("write reg cmd1 0x%02X\r\n", flashCfg.writeRegCmd[1]); + printf("qe write len 0x%02X\r\n", flashCfg.qeWriteRegLen); + printf("cread support 0x%02X\r\n", flashCfg.cReadSupport); + printf("cread code 0x%02X\r\n", flashCfg.cReadMode); + printf("burst wrap cmd 0x%02X\r\n", flashCfg.burstWrapCmd); + printf("=====================================\r\n"); +} + extern void bflb_uart_set_console(struct bflb_device_s *dev); static void console_init() @@ -165,9 +192,13 @@ static void console_init() struct bflb_device_s *gpio; gpio = bflb_device_get_by_name("gpio"); +#if defined(CPU_M0) bflb_gpio_uart_init(gpio, GPIO_PIN_14, GPIO_UART_FUNC_UART0_TX); bflb_gpio_uart_init(gpio, GPIO_PIN_15, GPIO_UART_FUNC_UART0_RX); - +#elif defined(CPU_D0) + bflb_gpio_init(gpio, GPIO_PIN_8, 21 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); + //bflb_gpio_init(gpio, GPIO_PIN_9, 21 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); +#endif struct bflb_uart_config_s cfg; cfg.baudrate = 2000000; cfg.data_bits = UART_DATA_BITS_8; @@ -176,18 +207,74 @@ static void console_init() cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 7; - +#if defined(CPU_M0) uart0 = bflb_device_get_by_name("uart0"); - +#elif defined(CPU_D0) + uart0 = bflb_device_get_by_name("uart3"); +#endif bflb_uart_init(uart0, &cfg); bflb_uart_set_console(uart0); } +#if defined(CPU_M0) void board_init(void) { - bflb_irq_initialize(); + uintptr_t flag; + + flag = bflb_irq_save(); + + bflb_flash_init(); + + GLB_Halt_CPU(GLB_CORE_ID_D0); + GLB_Halt_CPU(GLB_CORE_ID_LP); + system_clock_init(); peripheral_clock_init(); + bflb_irq_initialize(); + + GLB_Release_CPU(GLB_CORE_ID_D0); + GLB_Release_CPU(GLB_CORE_ID_LP); + + bflb_irq_restore(flag); + + system_mmheap[0].addr = (uint8_t *)&__HeapBase; + system_mmheap[0].mem_size = ((size_t)&__HeapLimit - (size_t)&__HeapBase); + + if (system_mmheap[0].mem_size > 0) { + mmheap_init(&mmheap_root, system_mmheap); + } + + console_init(); + + bl_show_log(); + bl_show_flashinfo(); + + printf("dynamic memory init success,heap size = %d Kbyte \r\n", system_mmheap[0].mem_size / 1024); + + printf("sig1:%08x\r\n", BL_RD_REG(GLB_BASE, GLB_UART_CFG1)); + printf("sig2:%08x\r\n", BL_RD_REG(GLB_BASE, GLB_UART_CFG2)); + +#if (defined(CONFIG_LUA) || defined(CONFIG_BFLOG) || defined(CONFIG_FATFS)) + rtc = bflb_device_get_by_name("rtc"); +#endif + +#ifdef CONFIG_PSRAM + if (uhs_psram_init() < 0) { + while (1) { + } + } +#endif + /* release d0 and then do can run */ + BL_WR_WORD(IPC_SYNC_ADDR1, IPC_SYNC_FLAG); + BL_WR_WORD(IPC_SYNC_ADDR2, IPC_SYNC_FLAG); + L1C_DCache_Clean_By_Addr(IPC_SYNC_ADDR1, 8); +} +#elif defined(CPU_D0) +void board_init(void) +{ + CPU_Set_MTimer_CLK(ENABLE, CPU_Get_MTimer_Source_Clock() / 1000 / 1000 - 1); + + bflb_irq_initialize(); system_mmheap[0].addr = (uint8_t *)&__HeapBase; system_mmheap[0].mem_size = ((size_t)&__HeapLimit - (size_t)&__HeapBase); @@ -204,20 +291,10 @@ void board_init(void) printf("sig1:%08x\r\n", BL_RD_REG(GLB_BASE, GLB_UART_CFG1)); printf("sig2:%08x\r\n", BL_RD_REG(GLB_BASE, GLB_UART_CFG2)); - -#if (defined(CONFIG_LUA) || defined(CONFIG_BFLOG)) - rtc = bflb_device_get_by_name("rtc"); - bflb_rtc_set_time(rtc, BFLB_RTC_SEC2TIME(0)); -#endif -#ifdef CONFIG_PSRAM - if (uhs_psram_init() < 0) { - while (1) { - } - } -#endif } +#endif -void board_uart1_gpio_init(void) +void board_uartx_gpio_init(void) { struct bflb_device_s *gpio; @@ -245,13 +322,17 @@ void board_spi0_gpio_init(void) struct bflb_device_s *gpio; gpio = bflb_device_get_by_name("gpio"); + /* spi cs */ bflb_gpio_init(gpio, GPIO_PIN_16, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); + /* spi miso */ bflb_gpio_init(gpio, GPIO_PIN_17, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); + /* spi mosi */ bflb_gpio_init(gpio, GPIO_PIN_18, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); + /* spi clk */ bflb_gpio_init(gpio, GPIO_PIN_19, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1); } -void board_pwm0_gpio_init(void) +void board_pwm_gpio_init(void) { struct bflb_device_s *gpio; @@ -371,7 +452,7 @@ __attribute__((weak)) uint64_t bflog_clock(void) __attribute__((weak)) uint32_t bflog_time(void) { - return BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)); + return BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)) + 1640995200; } __attribute__((weak)) char *bflog_thread(void) @@ -381,18 +462,35 @@ __attribute__((weak)) char *bflog_thread(void) #endif #ifdef CONFIG_LUA -clock_t luaport_clock(void) +__attribute__((weak)) clock_t luaport_clock(void) { return (clock_t)CPU_Get_MTimer_Counter(); } -time_t luaport_time(time_t *seconds) +__attribute__((weak)) time_t luaport_time(time_t *seconds) { - time_t t = (time_t)BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)); + time_t t = (time_t)BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)) + 1640995200; if (seconds != NULL) { *seconds = t; } return t; } +#endif + +#ifdef CONFIG_FATFS +#include "bflb_timestamp.h" +__attribute__((weak)) uint32_t get_fattime(void) +{ + bflb_timestamp_t tm; + + bflb_timestamp_utc2time(BFLB_RTC_TIME2SEC(bflb_rtc_get_time(rtc)) + 1640995200, &tm); + + return ((uint32_t)(tm.year - 1980) << 25) /* Year 2015 */ + | ((uint32_t)tm.mon << 21) /* Month 1 */ + | ((uint32_t)tm.mday << 16) /* Mday 1 */ + | ((uint32_t)tm.hour << 11) /* Hour 0 */ + | ((uint32_t)tm.min << 5) /* Min 0 */ + | ((uint32_t)tm.sec >> 1); /* Sec 0 */ +} #endif \ No newline at end of file diff --git a/bsp/board/bl808dk/board.h b/bsp/board/bl808dk/board.h index 77f5bfb1..8bd89e8c 100644 --- a/bsp/board/bl808dk/board.h +++ b/bsp/board/bl808dk/board.h @@ -4,10 +4,10 @@ void board_init(void); void board_jtag_gpio_init(void); -void board_uart1_gpio_init(void); +void board_uartx_gpio_init(void); void board_i2c0_gpio_init(void); void board_spi0_gpio_init(void); -void board_pwm0_gpio_init(void); +void board_pwm_gpio_init(void); void board_adc_gpio_init(void); void board_dac_gpio_init(void); void board_ir_gpio_init(void); @@ -17,4 +17,10 @@ void board_emac_gpio_init(void); void board_sdh_gpio_init(void); #endif +#define DEFAULT_TEST_UART "uart1" +#define DEFAULT_TEST_UART_DMA_TX_REQUEST DMA_REQUEST_UART1_TX +#define DEFAULT_TEST_UART_DMA_RX_REQUEST DMA_REQUEST_UART1_RX +#define DEFAULT_TEST_UART_DMA_TDR DMA_ADDR_UART1_TDR +#define DEFAULT_TEST_UART_DMA_RDR DMA_ADDR_UART1_RDR + #endif \ No newline at end of file diff --git a/bsp/common/fatfs/fatfs_sdh_sdcard.c b/bsp/common/fatfs/fatfs_sdh_sdcard.c index b926f15a..6f58baab 100644 --- a/bsp/common/fatfs/fatfs_sdh_sdcard.c +++ b/bsp/common/fatfs/fatfs_sdh_sdcard.c @@ -104,15 +104,6 @@ int MMC_disk_ioctl(BYTE cmd, void *buff) return 0; } -DWORD get_fattime(void) -{ - return ((DWORD)(2015 - 1980) << 25) /* Year 2015 */ - | ((DWORD)1 << 21) /* Month 1 */ - | ((DWORD)1 << 16) /* Mday 1 */ - | ((DWORD)0 << 11) /* Hour 0 */ - | ((DWORD)0 << 5) /* Min 0 */ - | ((DWORD)0 >> 1); /* Sec 0 */ -} DSTATUS Translate_Result_Code(int result) { diff --git a/drivers/lhal/CMakeLists.txt b/drivers/lhal/CMakeLists.txt index a7c31e14..66ccb403 100644 --- a/drivers/lhal/CMakeLists.txt +++ b/drivers/lhal/CMakeLists.txt @@ -12,13 +12,16 @@ sdk_library_add_sources(src/bflb_emac.c) endif() sdk_library_add_sources(src/bflb_gpio.c) sdk_library_add_sources(src/bflb_i2c.c) +if((NOT ("${CHIP}" STREQUAL "bl602")) AND (NOT ("${CHIP}" STREQUAL "bl702"))) sdk_library_add_sources(src/bflb_ir.c) +endif() sdk_library_add_sources(src/bflb_uart.c) sdk_library_add_sources(src/bflb_spi.c) sdk_library_add_sources(src/bflb_rtc.c) sdk_library_add_sources(src/bflb_sec_aes.c) sdk_library_add_sources(src/bflb_sec_sha.c) sdk_library_add_sources(src/bflb_sec_trng.c) +# sdk_library_add_sources(src/bflb_sec_irq.c) sdk_library_add_sources(src/bflb_timer.c) sdk_library_add_sources(src/bflb_wdg.c) sdk_library_add_sources(src/bflb_cks.c) @@ -46,6 +49,7 @@ endif() # optional sdk_library_add_sources(src/bflb_irq.c) +sdk_library_add_sources(src/bflb_l1c.c) sdk_library_add_sources(src/bflb_mtimer.c) sdk_add_include_directories(include) diff --git a/drivers/lhal/config/bl602/device_table.c b/drivers/lhal/config/bl602/device_table.c index 0ea734eb..25fdbcc7 100644 --- a/drivers/lhal/config/bl602/device_table.c +++ b/drivers/lhal/config/bl602/device_table.c @@ -162,6 +162,13 @@ struct bflb_device_s bl602_device_table[] = { .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_PKA, .user_data = NULL }, + { .name = "watchdog", + .reg_base = TIMER_BASE, + .irq_num = BL602_IRQ_WDT, + .idx = 0, + .sub_idx = 0, + .dev_type = BFLB_DEVICE_TYPE_TIMER, + .user_data = NULL }, }; struct bflb_device_s *bflb_device_get_by_name(const char *name) diff --git a/drivers/lhal/config/bl616/device_table.c b/drivers/lhal/config/bl616/device_table.c index e5841042..bd0cb4dd 100644 --- a/drivers/lhal/config/bl616/device_table.c +++ b/drivers/lhal/config/bl616/device_table.c @@ -44,7 +44,7 @@ struct bflb_device_s bl616_device_table[] = { .idx = 0, .dev_type = BFLB_DEVICE_TYPE_SPI, .user_data = NULL }, - { .name = "pwm0", + { .name = "pwm_v2_0", .reg_base = PWM_BASE, .irq_num = BL616_IRQ_PWM, .idx = 0, @@ -191,6 +191,13 @@ struct bflb_device_s bl616_device_table[] = { .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_MJPEG, .user_data = NULL }, + { .name = "irrx", + .reg_base = IR_BASE, + .irq_num = BL616_IRQ_IRRX, + .idx = 0, + .sub_idx = 0, + .dev_type = BFLB_DEVICE_TYPE_IR, + .user_data = NULL }, }; struct bflb_device_s *bflb_device_get_by_name(const char *name) diff --git a/drivers/lhal/config/bl702/device_table.c b/drivers/lhal/config/bl702/device_table.c index 4e6bb7c7..a4963387 100644 --- a/drivers/lhal/config/bl702/device_table.c +++ b/drivers/lhal/config/bl702/device_table.c @@ -44,7 +44,7 @@ struct bflb_device_s bl702_device_table[] = { .idx = 0, .dev_type = BFLB_DEVICE_TYPE_SPI, .user_data = NULL }, - { .name = "pwm0", + { .name = "pwm_v1", .reg_base = PWM_BASE, .irq_num = BL702_IRQ_PWM, .idx = 0, @@ -169,6 +169,13 @@ struct bflb_device_s bl702_device_table[] = { .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_ETH, .user_data = NULL }, + { .name = "watchdog", + .reg_base = TIMER_BASE, + .irq_num = BL702_IRQ_WDT, + .idx = 0, + .sub_idx = 0, + .dev_type = BFLB_DEVICE_TYPE_TIMER, + .user_data = NULL }, }; struct bflb_device_s *bflb_device_get_by_name(const char *name) diff --git a/drivers/lhal/config/bl808/device_table.c b/drivers/lhal/config/bl808/device_table.c index f181cb12..777f5fec 100644 --- a/drivers/lhal/config/bl808/device_table.c +++ b/drivers/lhal/config/bl808/device_table.c @@ -7,7 +7,11 @@ struct bflb_device_s bl808_device_table[] = { { .name = "adc", .reg_base = AON_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_GPADC_DMA, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_ADC, @@ -21,116 +25,204 @@ struct bflb_device_s bl808_device_table[] = { .user_data = NULL }, { .name = "gpio", .reg_base = GLB_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_GPIO_INT0, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_GPIO, .user_data = NULL }, { .name = "uart0", .reg_base = UART0_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_UART0, +#else + .irq_num = 0xff, +#endif .idx = 0, .dev_type = BFLB_DEVICE_TYPE_UART, .user_data = NULL }, { .name = "uart1", .reg_base = UART1_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_UART1, +#else + .irq_num = 0xff, +#endif .idx = 1, .dev_type = BFLB_DEVICE_TYPE_UART, .user_data = NULL }, + { .name = "uart2", + .reg_base = UART2_BASE, +#if defined(CPU_M0) + .irq_num = BL808_IRQ_UART2, +#else + .irq_num = 0xff, +#endif + .idx = 2, + .dev_type = BFLB_DEVICE_TYPE_UART, + .user_data = NULL }, + { .name = "uart3", + .reg_base = UART3_BASE, +#if defined(CPU_M0) + .irq_num = 0xff, +#else + .irq_num = BL808_IRQ_UART3, +#endif + .idx = 3, + .dev_type = BFLB_DEVICE_TYPE_UART, + .user_data = NULL }, { .name = "spi0", .reg_base = SPI0_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_SPI0, +#else + .irq_num = 0xff, +#endif .idx = 0, .dev_type = BFLB_DEVICE_TYPE_SPI, .user_data = NULL }, - { .name = "pwm0", + { .name = "pwm_v2_0", .reg_base = PWM_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_PWM, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_PWM, .user_data = NULL }, { .name = "dma0_ch0", .reg_base = DMA0_BASE + 1 * DMA_CHANNEL_OFFSET, +#if defined(CPU_M0) .irq_num = BL808_IRQ_DMA0_ALL, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_DMA, .user_data = NULL }, { .name = "dma0_ch1", .reg_base = DMA0_BASE + 2 * DMA_CHANNEL_OFFSET, +#if defined(CPU_M0) .irq_num = BL808_IRQ_DMA0_ALL, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 1, .dev_type = BFLB_DEVICE_TYPE_DMA, .user_data = NULL }, { .name = "dma0_ch2", .reg_base = DMA0_BASE + 3 * DMA_CHANNEL_OFFSET, +#if defined(CPU_M0) .irq_num = BL808_IRQ_DMA0_ALL, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 2, .dev_type = BFLB_DEVICE_TYPE_DMA, .user_data = NULL }, { .name = "dma0_ch3", .reg_base = DMA0_BASE + 4 * DMA_CHANNEL_OFFSET, +#if defined(CPU_M0) .irq_num = BL808_IRQ_DMA0_ALL, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 3, .dev_type = BFLB_DEVICE_TYPE_DMA, .user_data = NULL }, { .name = "dma0_ch4", .reg_base = DMA0_BASE + 5 * DMA_CHANNEL_OFFSET, +#if defined(CPU_M0) .irq_num = BL808_IRQ_DMA0_ALL, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 4, .dev_type = BFLB_DEVICE_TYPE_DMA, .user_data = NULL }, { .name = "dma0_ch5", .reg_base = DMA0_BASE + 6 * DMA_CHANNEL_OFFSET, +#if defined(CPU_M0) .irq_num = BL808_IRQ_DMA0_ALL, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 5, .dev_type = BFLB_DEVICE_TYPE_DMA, .user_data = NULL }, { .name = "dma0_ch6", .reg_base = DMA0_BASE + 7 * DMA_CHANNEL_OFFSET, +#if defined(CPU_M0) .irq_num = BL808_IRQ_DMA0_ALL, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 6, .dev_type = BFLB_DEVICE_TYPE_DMA, .user_data = NULL }, { .name = "dma0_ch7", .reg_base = DMA0_BASE + 8 * DMA_CHANNEL_OFFSET, +#if defined(CPU_M0) .irq_num = BL808_IRQ_DMA0_ALL, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 7, .dev_type = BFLB_DEVICE_TYPE_DMA, .user_data = NULL }, { .name = "i2c0", .reg_base = I2C0_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_I2C0, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_I2C, .user_data = NULL }, { .name = "timer0", .reg_base = TIMER0_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_TIMER0, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_TIMER, .user_data = NULL }, { .name = "timer1", .reg_base = TIMER1_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_TIMER1, +#else + .irq_num = 0xff, +#endif .idx = 1, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_TIMER, .user_data = NULL }, { .name = "rtc", .reg_base = HBN_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_HBN_OUT0, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_RTC, @@ -165,21 +257,33 @@ struct bflb_device_s bl808_device_table[] = { .user_data = NULL }, { .name = "emac0", .reg_base = EMAC_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_EMAC, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_ETH, .user_data = NULL }, { .name = "irtx", .reg_base = IR_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_IRTX, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_IR, .user_data = NULL }, { .name = "irrx", .reg_base = IR_BASE, +#if defined(CPU_M0) .irq_num = BL808_IRQ_IRRX, +#else + .irq_num = 0xff, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_IR, @@ -191,15 +295,28 @@ struct bflb_device_s bl808_device_table[] = { .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_CKS, .user_data = NULL }, -#if defined(CPU_D0) { .name = "mjpeg", .reg_base = MJPEG_BASE, +#if defined(CPU_M0) + .irq_num = 0xff, +#else .irq_num = BL808_IRQ_MJPEG, +#endif .idx = 0, .sub_idx = 0, .dev_type = BFLB_DEVICE_TYPE_MJPEG, .user_data = NULL }, + { .name = "watchdog", + .reg_base = TIMER0_BASE, +#if defined(CPU_M0) + .irq_num = BL808_IRQ_WDT, +#else + .irq_num = 0xff, #endif + .idx = 0, + .sub_idx = 0, + .dev_type = BFLB_DEVICE_TYPE_TIMER, + .user_data = NULL }, }; struct bflb_device_s *bflb_device_get_by_name(const char *name) diff --git a/drivers/lhal/include/arch/risc-v/csr.h b/drivers/lhal/include/arch/risc-v/csr.h index 5d023edf..3b2b4627 100644 --- a/drivers/lhal/include/arch/risc-v/csr.h +++ b/drivers/lhal/include/arch/risc-v/csr.h @@ -298,7 +298,7 @@ #define CSR_DSCRATCH 0x7B2 /* In mstatus register */ - +#define MSTATUS_SIE (0x1 << 1) /* Superior Interrupt Enable */ #define MSTATUS_MIE (0x1 << 3) /* Machine Interrupt Enable */ #define MSTATUS_MPIE (0x1 << 7) /* Machine Previous Interrupt Enable */ #define MSTATUS_MPPM (0x3 << 11) /* Machine Previous Privilege (m-mode) */ diff --git a/drivers/lhal/include/arch/risc-v/riscv_arch.h b/drivers/lhal/include/arch/risc-v/riscv_arch.h index 07dcc6f0..35a901b2 100644 --- a/drivers/lhal/include/arch/risc-v/riscv_arch.h +++ b/drivers/lhal/include/arch/risc-v/riscv_arch.h @@ -1,12 +1,12 @@ #ifndef _RISCV_ARCH_H #define _RISCV_ARCH_H -#define getreg8(a) (*(volatile uint8_t *)(a)) -#define putreg8(v, a) (*(volatile uint8_t *)(a) = (v)) -#define getreg16(a) (*(volatile uint16_t *)(a)) -#define putreg16(v, a) (*(volatile uint16_t *)(a) = (v)) -#define getreg32(a) (*(volatile uint32_t *)(a)) -#define putreg32(v, a) (*(volatile uint32_t *)(a) = (v)) +#define getreg8(a) (*(volatile uint8_t *)(uintptr_t)(a)) +#define putreg8(v, a) (*(volatile uint8_t *)(uintptr_t)(a) = (v)) +#define getreg16(a) (*(volatile uint16_t *)(uintptr_t)(a)) +#define putreg16(v, a) (*(volatile uint16_t *)(uintptr_t)(a) = (v)) +#define getreg32(a) (*(volatile uint32_t *)(uintptr_t)(a)) +#define putreg32(v, a) (*(volatile uint32_t *)(uintptr_t)(a) = (v)) // #define getreg64(a) (*(volatile uint64_t *)(a)) // #define putreg64(v, a) (*(volatile uint64_t *)(a) = (v)) // #define modifyreg32(a, clearbits, setbits) putreg32((getreg32(a) & (~clearbits)) | setbits, a) diff --git a/drivers/lhal/include/bflb_adc.h b/drivers/lhal/include/bflb_adc.h index d09f968a..23bbfae8 100644 --- a/drivers/lhal/include/bflb_adc.h +++ b/drivers/lhal/include/bflb_adc.h @@ -6,15 +6,14 @@ /** @defgroup ADC_CHANNEL adc channel definition * @{ */ -#define ADC_CHANNEL_0 0 -#define ADC_CHANNEL_1 1 -#define ADC_CHANNEL_2 2 -#define ADC_CHANNEL_3 3 -#define ADC_CHANNEL_4 4 -#define ADC_CHANNEL_5 5 -#define ADC_CHANNEL_6 6 -#define ADC_CHANNEL_7 7 -#if !defined(BL702L) +#define ADC_CHANNEL_0 0 +#define ADC_CHANNEL_1 1 +#define ADC_CHANNEL_2 2 +#define ADC_CHANNEL_3 3 +#define ADC_CHANNEL_4 4 +#define ADC_CHANNEL_5 5 +#define ADC_CHANNEL_6 6 +#define ADC_CHANNEL_7 7 #define ADC_CHANNEL_8 8 #define ADC_CHANNEL_9 9 #define ADC_CHANNEL_10 10 @@ -23,16 +22,9 @@ #define ADC_CHANNEL_DACB 13 #define ADC_CHANNEL_TSEN_P 14 #define ADC_CHANNEL_TSEN_N 15 +#define ADC_CHANNEL_VREF 16 #define ADC_CHANNEL_VABT_HALF 18 #define ADC_CHANNEL_GND 23 -#else -#define ADC_CHANNEL_DACA 8 -#define ADC_CHANNEL_DACB 9 -#define ADC_CHANNEL_VBAT 10 -#define ADC_CHANNEL_TSEN 11 -#define ADC_CHANNEL_VREF 12 -#define ADC_CHANNEL_GND 13 -#endif /** * @} */ @@ -166,8 +158,9 @@ uint32_t bflb_adc_get_intstatus(struct bflb_device_s *dev); void bflb_adc_int_clear(struct bflb_device_s *dev, uint32_t int_clear); void bflb_adc_parse_result(struct bflb_device_s *dev, uint32_t *buffer, struct bflb_adc_result_s *result, uint16_t count); + void bflb_adc_tsen_init(struct bflb_device_s *dev, uint8_t tsen_mod); -float bflb_adc_tsen_get_temp(struct bflb_device_s *dev, uint32_t tsen_offset); +float bflb_adc_tsen_get_temp(struct bflb_device_s *dev); void bflb_adc_vbat_enable(struct bflb_device_s *dev); void bflb_adc_vbat_disable(struct bflb_device_s *dev); diff --git a/drivers/lhal/include/bflb_dma.h b/drivers/lhal/include/bflb_dma.h index e83d3401..00ee8b10 100644 --- a/drivers/lhal/include/bflb_dma.h +++ b/drivers/lhal/include/bflb_dma.h @@ -66,6 +66,9 @@ #if !defined(BL702L) #define DMA_ADDR_DAC_TDR (0x40002000 + 0x48) #endif +#if defined(BL702L) +#define DMA_ADDR_IR_TDR (0x4000A600 + 0x88) +#endif /** * @} */ @@ -82,6 +85,9 @@ #endif #define DMA_REQUEST_I2C0_RX 0x00000006 #define DMA_REQUEST_I2C0_TX 0x00000007 +#if defined(BL702L) +#define DMA_REQUEST_IR_TX 0x00000008 +#endif #define DMA_REQUEST_SPI0_RX 0x0000000A #define DMA_REQUEST_SPI0_TX 0x0000000B #if !defined(BL702L) @@ -165,6 +171,7 @@ #define DMA_ADDR_I2S_RDR (0x2000AB00 + 0x8C) #define DMA_ADDR_ADC_RDR (0x20002000 + 0x04) #define DMA_ADDR_DAC_TDR (0x20002000 + 0x48) +#define DMA_ADDR_IR_TDR (0x2000A600 + 0x88) /** * @} */ @@ -360,7 +367,6 @@ int bflb_dma_channel_lli_reload(struct bflb_device_s *dev, int bflb_dma_feature_control(struct bflb_device_s *dev, int cmd, size_t arg); -/* Not use */ void bflb_dma_channel_tcint_mask(struct bflb_device_s *dev, bool mask); bool bflb_dma_channel_get_tcint_status(struct bflb_device_s *dev); void bflb_dma_channel_tcint_clear(struct bflb_device_s *dev); diff --git a/drivers/lhal/include/bflb_efuse.h b/drivers/lhal/include/bflb_efuse.h new file mode 100644 index 00000000..82f2ef05 --- /dev/null +++ b/drivers/lhal/include/bflb_efuse.h @@ -0,0 +1,20 @@ +#ifndef _BFLB_EFUSE_H +#define _BFLB_EFUSE_H + +#include "bflb_core.h" + +#ifdef __cplusplus +extern "C" { +#endif + +float bflb_efuse_get_adc_trim(void); +uint32_t bflb_efuse_get_adc_tsen_trim(void); +void bflb_efuse_write_secure_boot(); +void bflb_efuse_write_aes_key(uint8_t index, uint8_t *data, uint32_t len); +void bflb_efuse_read_aes_key(uint8_t index, uint8_t *data, uint32_t len); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/drivers/lhal/include/bflb_flash.h b/drivers/lhal/include/bflb_flash.h new file mode 100644 index 00000000..6b259ff1 --- /dev/null +++ b/drivers/lhal/include/bflb_flash.h @@ -0,0 +1,56 @@ +#ifndef _BFLB_FLASH_H +#define _BFLB_FLASH_H + +#include "bflb_core.h" + +#define FLASH_IOMODE_NIO 0 /*!< Normal IO mode define */ +#define FLASH_IOMODE_DO 1 /*!< Dual Output mode define */ +#define FLASH_IOMODE_QO 2 /*!< Quad Output mode define */ +#define FLASH_IOMODE_DIO 3 /*!< Dual IO mode define */ +#define FLASH_IOMODE_QIO 4 /*!< Quad IO mode define */ + +#define FLASH_AES_KEY_128BITS 0 +#define FLASH_AES_KEY_192BITS 2 +#define FLASH_AES_KEY_256BITS 1 +#define FLASH_AES_KEY_DOUBLE_128BITS 3 + +#if defined(BL602) || defined(BL702) || defined(BL702L) +#define FLASH_XIP_BASE (0x23000000) +#elif defined(BL616) || defined(BL628) +#define FLASH_XIP_BASE (0xA0000000) +#elif defined(BL808) || defined(BL606P) +#define FLASH_XIP_BASE (0x58000000) +#endif + +struct bflb_flash_aes_config_s { + uint8_t region; + uint8_t region_enable; + uint8_t lock_enable; + const uint8_t *key; + uint8_t keybits; + uint8_t *iv; + uint32_t start_addr; + uint32_t end_addr; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +int bflb_flash_init(void); +uint32_t bflb_flash_get_jedec_id(void); +void bflb_flash_get_cfg(uint8_t **cfg_addr, uint32_t *len); +void bflb_flash_set_iomode(uint8_t iomode); +int bflb_flash_erase(uint32_t addr, uint32_t len); +int bflb_flash_write(uint32_t addr, uint8_t *data, uint32_t len); +int bflb_flash_read(uint32_t addr, uint8_t *data, uint32_t len); + +void bflb_flash_aes_init(struct bflb_flash_aes_config_s *config); +void bflb_flash_aes_enable(void); +void bflb_flash_aes_disable(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/drivers/lhal/include/bflb_gpio.h b/drivers/lhal/include/bflb_gpio.h index 8f853c43..e0339451 100644 --- a/drivers/lhal/include/bflb_gpio.h +++ b/drivers/lhal/include/bflb_gpio.h @@ -169,7 +169,7 @@ #define GPIO_INT_TRIG_MODE_SYNC_RISING_EDGE 1 #define GPIO_INT_TRIG_MODE_SYNC_LOW_LEVEL 2 #define GPIO_INT_TRIG_MODE_SYNC_HIGH_LEVEL 3 -#if defined(BL702) +#if defined(BL602) || defined(BL702) #define GPIO_INT_TRIG_MODE_ASYNC_FALLING_EDGE 4 #define GPIO_INT_TRIG_MODE_ASYNC_RISING_EDGE 5 #define GPIO_INT_TRIG_MODE_ASYNC_LOW_LEVEL 6 diff --git a/drivers/lhal/include/bflb_i2c.h b/drivers/lhal/include/bflb_i2c.h index 434f8ab9..1f072d64 100644 --- a/drivers/lhal/include/bflb_i2c.h +++ b/drivers/lhal/include/bflb_i2c.h @@ -64,11 +64,8 @@ * @{ */ #define I2C_INTCLR_END (1 << 0) /* Transfer end interrupt */ -#define I2C_INTCLR_TX_FIFO (1 << 1) /* TX FIFO ready interrupt */ -#define I2C_INTCLR_RX_FIFO (1 << 2) /* RX FIFO ready interrupt */ #define I2C_INTCLR_NACK (1 << 3) /* NACK interrupt */ #define I2C_INTCLR_ARB (1 << 4) /* Arbitration lost interrupt */ -#define I2C_INTCLR_FER (1 << 5) /* TX/RX FIFO error interrupt */ /** * @} */ diff --git a/drivers/lhal/include/bflb_ir.h b/drivers/lhal/include/bflb_ir.h index 08861a0a..ae319f31 100644 --- a/drivers/lhal/include/bflb_ir.h +++ b/drivers/lhal/include/bflb_ir.h @@ -3,6 +3,7 @@ #include "bflb_core.h" +#if !defined(BL616) /** @defgroup IR TX mode definition * @{ */ @@ -34,7 +35,9 @@ /** * @} */ +#endif +#if !defined(BL702L) /** @defgroup IR RX mode definition * @{ */ @@ -54,6 +57,7 @@ /** * @} */ +#endif /** @defgroup IR word definition * @{ @@ -64,6 +68,7 @@ * @} */ +#if !defined(BL616) /** * @brief IR TX configuration structure * @@ -124,7 +129,9 @@ struct bflb_ir_tx_config_s { uint8_t modu_width_0; uint16_t pulse_width_unit; }; +#endif +#if !defined(BL702L) /** * @brief IR RX configuration structure * @@ -145,11 +152,13 @@ struct bflb_ir_rx_config_s { uint16_t end_threshold; uint16_t fifo_threshold; }; +#endif #ifdef __cplusplus extern "C" { #endif +#if !defined(BL616) void bflb_ir_tx_init(struct bflb_device_s *dev, const struct bflb_ir_tx_config_s *config); void bflb_ir_send(struct bflb_device_s *dev, uint32_t *data, uint32_t length); void bflb_ir_swm_send(struct bflb_device_s *dev, uint16_t *data, uint8_t length); @@ -160,7 +169,9 @@ uint32_t bflb_ir_txint_status(struct bflb_device_s *dev); void bflb_ir_link_txdma(struct bflb_device_s *dev, bool enable); uint8_t bflb_ir_txfifo_cnt(struct bflb_device_s *dev); void bflb_ir_txfifo_clear(struct bflb_device_s *dev); +#endif +#if !defined(BL702L) void bflb_ir_rx_init(struct bflb_device_s *dev, const struct bflb_ir_rx_config_s *config); uint8_t bflb_ir_receive(struct bflb_device_s *dev, uint64_t *data); uint8_t bflb_ir_swm_receive(struct bflb_device_s *dev, uint16_t *data, uint8_t length); @@ -170,6 +181,7 @@ void bflb_ir_rxint_clear(struct bflb_device_s *dev); uint32_t bflb_ir_rxint_status(struct bflb_device_s *dev); uint8_t bflb_ir_rxfifo_cnt(struct bflb_device_s *dev); void bflb_ir_rxfifo_clear(struct bflb_device_s *dev); +#endif void bflb_ir_feature_control(); diff --git a/drivers/lhal/include/bflb_irq.h b/drivers/lhal/include/bflb_irq.h index 56c4a140..e88482d1 100644 --- a/drivers/lhal/include/bflb_irq.h +++ b/drivers/lhal/include/bflb_irq.h @@ -21,14 +21,15 @@ extern "C" { #endif void bflb_irq_initialize(void); -uint32_t bflb_irq_save(void); -void bflb_irq_restore(uint32_t flags); +uintptr_t bflb_irq_save(void); +void bflb_irq_restore(uintptr_t flags); int bflb_irq_attach(int irq, irq_callback isr, void *arg); int bflb_irq_detach(int irq); void bflb_irq_enable(int irq); void bflb_irq_disable(int irq); void bflb_irq_set_pending(int irq); void bflb_irq_clear_pending(int irq); +void bflb_irq_set_nlbits(uint8_t nlbits); void bflb_irq_set_priority(int irq, uint8_t preemptprio, uint8_t subprio); #ifdef __cplusplus diff --git a/drivers/lhal/include/bflb_l1c.h b/drivers/lhal/include/bflb_l1c.h index bb0b48cc..9328e2f6 100644 --- a/drivers/lhal/include/bflb_l1c.h +++ b/drivers/lhal/include/bflb_l1c.h @@ -3,31 +3,16 @@ #include "bflb_core.h" -#if defined(BL616) || defined(BL606P) || defined(BL808) || defined(BL628) -#include "csi_core.h" -#define bflb_l1c_icache_enable() csi_icache_enable() -#define bflb_l1c_icache_disable() csi_icache_disable() -#define bflb_l1c_icache_invalid_all() csi_icache_invalid() -#define bflb_l1c_dcache_enable() csi_dcache_enable() -#define bflb_l1c_dcache_disable() csi_dcache_disable() -#define bflb_l1c_dcache_clean_all() csi_dcache_clean() -#define bflb_l1c_dcache_invalidate_all() csi_icache_invalid() -#define bflb_l1c_dcache_clean_invalidate_all() csi_dcache_clean_invalid() -#define bflb_l1c_dcache_clean_range(addr, len) csi_dcache_clean_range(addr, len) -#define bflb_l1c_dcache_invalidate_range(addr, len) csi_dcache_invalid_range(addr, len) -#define bflb_l1c_dcache_clean_invalidate_range(addr, len) csi_dcache_clean_invalid_range(addr, len) -#else -#define bflb_l1c_icache_enable() -#define bflb_l1c_icache_disable() -#define bflb_l1c_icache_invalid_all() -#define bflb_l1c_dcache_enable() -#define bflb_l1c_dcache_disable() -#define bflb_l1c_dcache_clean_all() -#define bflb_l1c_dcache_invalidate_all() -#define bflb_l1c_dcache_clean_invalidate_all() -#define bflb_l1c_dcache_clean_range(addr, len) -#define bflb_l1c_dcache_invalidate_range(addr, len) -#define bflb_l1c_dcache_clean_invalidate_range(addr, len) -#endif +void bflb_l1c_icache_enable(void); +void bflb_l1c_icache_disable(void); +void bflb_l1c_icache_invalid_all(void); +void bflb_l1c_dcache_enable(void); +void bflb_l1c_dcache_disable(void); +void bflb_l1c_dcache_clean_all(void); +void bflb_l1c_dcache_invalidate_all(void); +void bflb_l1c_dcache_clean_invalidate_all(void); +void bflb_l1c_dcache_clean_range(void *addr, uint32_t size); +void bflb_l1c_dcache_invalidate_range(void *addr, uint32_t size); +void bflb_l1c_dcache_clean_invalidate_range(void *addr, uint32_t size); #endif \ No newline at end of file diff --git a/drivers/lhal/include/bflb_pwm_v1.h b/drivers/lhal/include/bflb_pwm_v1.h index 02f32188..fd6635f8 100644 --- a/drivers/lhal/include/bflb_pwm_v1.h +++ b/drivers/lhal/include/bflb_pwm_v1.h @@ -80,11 +80,11 @@ extern "C" { #endif void bflb_pwm_v1_channel_init(struct bflb_device_s *dev, uint8_t ch, const struct bflb_pwm_v1_channel_config_s *config); -void bflb_pwm_v1_channel_set_threshold(struct bflb_device_s *dev, uint8_t ch, uint16_t low_threhold, uint16_t high_threhold); -void bflb_pwm_v1_deinit(struct bflb_device_s *dev, uint8_t ch); +void bflb_pwm_v1_channel_deinit(struct bflb_device_s *dev, uint8_t ch); void bflb_pwm_v1_start(struct bflb_device_s *dev, uint8_t ch); void bflb_pwm_v1_stop(struct bflb_device_s *dev, uint8_t ch); void bflb_pwm_v1_set_period(struct bflb_device_s *dev, uint8_t ch, uint16_t period); +void bflb_pwm_v1_channel_set_threshold(struct bflb_device_s *dev, uint8_t ch, uint16_t low_threhold, uint16_t high_threhold); void bflb_pwm_v1_int_enable(struct bflb_device_s *dev, uint8_t ch, bool enable); uint32_t bflb_pwm_v1_get_intstatus(struct bflb_device_s *dev); diff --git a/drivers/lhal/include/bflb_sec_irq.h b/drivers/lhal/include/bflb_sec_irq.h new file mode 100644 index 00000000..11dcf591 --- /dev/null +++ b/drivers/lhal/include/bflb_sec_irq.h @@ -0,0 +1,24 @@ +#ifndef _BFLB_SEC_IRQ_H +#define _BFLB_SEC_IRQ_H + +#include "bflb_core.h" + +#define BFLB_SEC_ENG_IRQ_TYPE_AES 0 +#define BFLB_SEC_ENG_IRQ_TYPE_SHA 1 +#define BFLB_SEC_ENG_IRQ_TYPE_PKA 2 +#define BFLB_SEC_ENG_IRQ_TYPE_TRNG 3 +#define BFLB_SEC_ENG_IRQ_TYPE_GMAC 4 +#define BFLB_SEC_ENG_IRQ_TYPE_CDET 5 + +#ifdef __cplusplus +extern "C" { +#endif + +void bflb_sec_irq_attach(uint8_t sec_type, void (*callback)(void *arg), void *arg); +void bflb_sec_irq_detach(uint8_t sec_type); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/drivers/lhal/include/bflb_spi.h b/drivers/lhal/include/bflb_spi.h index c3cbad04..0e29d34c 100644 --- a/drivers/lhal/include/bflb_spi.h +++ b/drivers/lhal/include/bflb_spi.h @@ -70,6 +70,29 @@ * @} */ +/** @defgroup SPI_INTSTS spi interrupt status definition + * @{ + */ +#define SPI_INTSTS_TC (1 << 0) +#define SPI_INTSTS_TX_FIFO (1 << 1) +#define SPI_INTSTS_RX_FIFO (1 << 2) +#define SPI_INTSTS_SLAVE_TIMEOUT (1 << 3) +#define SPI_INTSTS_SLAVE_TX_UNDERRUN (1 << 4) +#define SPI_INTSTS_FIFO_ERR (1 << 5) +/** + * @} + */ + +/** @defgroup SPI_INTCLR spi interrupt clear definition + * @{ + */ +#define SPI_INTCLR_TC (1 << 16) +#define SPI_INTCLR_SLAVE_TIMEOUT (1 << 19) +#define SPI_INTCLR_SLAVE_TX_UNDERRUN (1 << 20) +/** + * @} + */ + /** @defgroup SPI_CMD spi feature control cmd definition * @{ */ @@ -118,6 +141,7 @@ int bflb_spi_poll_exchange(struct bflb_device_s *dev, const void *txbuffer, void bool bflb_spi_isbusy(struct bflb_device_s *dev); void bflb_spi_txint_mask(struct bflb_device_s *dev, bool mask); void bflb_spi_rxint_mask(struct bflb_device_s *dev, bool mask); +void bflb_spi_tcint_mask(struct bflb_device_s *dev, bool mask); void bflb_spi_errint_mask(struct bflb_device_s *dev, bool mask); uint32_t bflb_spi_get_intstatus(struct bflb_device_s *dev); void bflb_spi_int_clear(struct bflb_device_s *dev, uint32_t int_clear); diff --git a/drivers/lhal/include/bflb_timer.h b/drivers/lhal/include/bflb_timer.h index c04cbe8b..72199139 100644 --- a/drivers/lhal/include/bflb_timer.h +++ b/drivers/lhal/include/bflb_timer.h @@ -7,11 +7,15 @@ /** @defgroup TIMER_CLK_SOURCE timer clock source definition * @{ */ +#if !defined(BL702L) #define TIMER_CLKSRC_BCLK 0 +#endif #define TIMER_CLKSRC_32K 1 #define TIMER_CLKSRC_1K 2 #define TIMER_CLKSRC_XTAL 3 +#if !defined(BL702) && !defined(BL602) #define TIMER_CLKSRC_GPIO 4 +#endif #define TIMER_CLKSRC_NO 5 /** * @} @@ -37,15 +41,6 @@ * @} */ -/** @defgroup TIMER_CAPTURE_POLARITY timer capture polarity definition - * @{ - */ -#define TIMER_CAPTURE_POLARITY_RISING 0 -#define TIMER_CAPTURE_POLARITY_FALLING 1 -/** - * @} - */ - /** * @brief TIMER configuration structure * @@ -96,8 +91,6 @@ void bflb_timer_compint_mask(struct bflb_device_s *dev, uint8_t cmp_no, bool mas bool bflb_timer_get_compint_status(struct bflb_device_s *dev, uint8_t cmp_no); void bflb_timer_compint_clear(struct bflb_device_s *dev, uint8_t cmp_no); -void bflb_timer_capture_init(struct bflb_device_s *dev, const struct bflb_timer_capture_config_s *config); - #ifdef __cplusplus } #endif diff --git a/drivers/lhal/include/bflb_uart.h b/drivers/lhal/include/bflb_uart.h index e4aa6016..750309ab 100644 --- a/drivers/lhal/include/bflb_uart.h +++ b/drivers/lhal/include/bflb_uart.h @@ -134,6 +134,14 @@ #define UART_CMD_SET_ABR_ALLOWABLE_ERROR (0x13) #define UART_CMD_SET_SW_RTS_CONTROL (0x14) #define UART_CMD_IR_CONFIG (0x15) +#define UART_CMD_SET_TX_FREERUN (0x16) +#define UART_CMD_SET_TX_END_INTERRUPT (0x17) +#define UART_CMD_SET_RX_END_INTERRUPT (0x18) +#define UART_CMD_SET_TX_TRANSFER_LEN (0x19) +#define UART_CMD_SET_RX_TRANSFER_LEN (0x20) +#define UART_CMD_SET_TX_EN (0x21) +#define UART_CMD_SET_BCR_END_INTERRUPT (0x22) +#define UART_CMD_GET_BCR_COUNT (0x23) /** * @} */ @@ -186,9 +194,9 @@ void bflb_uart_enable(struct bflb_device_s *dev); void bflb_uart_disable(struct bflb_device_s *dev); void bflb_uart_link_txdma(struct bflb_device_s *dev, bool enable); void bflb_uart_link_rxdma(struct bflb_device_s *dev, bool enable); -void bflb_uart_putchar(struct bflb_device_s *dev, int ch); +int bflb_uart_putchar(struct bflb_device_s *dev, int ch); int bflb_uart_getchar(struct bflb_device_s *dev); -void bflb_uart_put(struct bflb_device_s *dev, uint8_t *data, uint32_t len); +int bflb_uart_put(struct bflb_device_s *dev, uint8_t *data, uint32_t len); int bflb_uart_get(struct bflb_device_s *dev, uint8_t *data, uint32_t len); bool bflb_uart_txready(struct bflb_device_s *dev); bool bflb_uart_txempty(struct bflb_device_s *dev); diff --git a/drivers/lhal/include/bflb_wdg.h b/drivers/lhal/include/bflb_wdg.h index e05124b8..f647a3ef 100644 --- a/drivers/lhal/include/bflb_wdg.h +++ b/drivers/lhal/include/bflb_wdg.h @@ -4,11 +4,15 @@ #include "bflb_core.h" #include "bflb_clock.h" +#if !defined(BL702L) #define WDG_CLKSRC_BCLK 0 +#endif #define WDG_CLKSRC_32K 1 #define WDG_CLKSRC_1K 2 #define WDG_CLKSRC_XTAL 3 +#if !defined(BL702) && !defined(BL602) #define WDG_CLKSRC_GPIO 4 +#endif #define WDG_CLKSRC_NO 5 /** @defgroup WDG_MODE Watch-dog reset/interrupt mode definition diff --git a/drivers/lhal/include/hardware/gpio_reg.h b/drivers/lhal/include/hardware/gpio_reg.h index d8554c6b..bfba6cd8 100644 --- a/drivers/lhal/include/hardware/gpio_reg.h +++ b/drivers/lhal/include/hardware/gpio_reg.h @@ -1522,6 +1522,7 @@ #define GLB_GPIO_CFGCTL33_OFFSET (0x18C)/* GPIO_CFGCTL33 */ #define GLB_GPIO_CFGCTL34_OFFSET (0x190)/* GPIO_CFGCTL34 */ #define GLB_GPIO_CFGCTL35_OFFSET (0x194)/* GPIO_CFGCTL35 */ +#define GLB_GPIO_CFGCTL36_OFFSET (0x198)/* GPIO_CFGCTL36 */ #define GLB_GPIO_INT_MASK1_OFFSET (0x1A0)/* GPIO_INT_MASK1 */ #define GLB_GPIO_INT_STAT1_OFFSET (0x1A8)/* GPIO_INT_STAT1 */ #define GLB_GPIO_INT_CLR1_OFFSET (0x1B0)/* GPIO_INT_CLR1 */ diff --git a/drivers/lhal/include/hardware/ir_reg.h b/drivers/lhal/include/hardware/ir_reg.h index aa2d4682..1ae98945 100644 --- a/drivers/lhal/include/hardware/ir_reg.h +++ b/drivers/lhal/include/hardware/ir_reg.h @@ -42,24 +42,61 @@ /* Register offsets *********************************************************/ +#if !defined(BL616) #define IRTX_CONFIG_OFFSET (0x0) /* irtx_config */ #define IRTX_INT_STS_OFFSET (0x4) /* irtx_int_sts */ +#if defined(BL602) || defined(BL702) +#define IRTX_DATA_WORD0_OFFSET (0x8) /* irtx_data_word0 */ +#define IRTX_DATA_WORD1_OFFSET (0xC) /* irtx_data_word1 */ +#endif #define IRTX_PULSE_WIDTH_OFFSET (0x10) /* irtx_pulse_width */ +#if defined(BL602) || defined(BL702) +#define IRTX_PW_OFFSET (0x14) /* irtx_pw */ +#define IRTX_SWM_PW_0_OFFSET (0x40) /* irtx_swm_pw_0 */ +#define IRTX_SWM_PW_1_OFFSET (0x44) /* irtx_swm_pw_1 */ +#define IRTX_SWM_PW_2_OFFSET (0x48) /* irtx_swm_pw_2 */ +#define IRTX_SWM_PW_3_OFFSET (0x4C) /* irtx_swm_pw_3 */ +#define IRTX_SWM_PW_4_OFFSET (0x50) /* irtx_swm_pw_4 */ +#define IRTX_SWM_PW_5_OFFSET (0x54) /* irtx_swm_pw_5 */ +#define IRTX_SWM_PW_6_OFFSET (0x58) /* irtx_swm_pw_6 */ +#define IRTX_SWM_PW_7_OFFSET (0x5C) /* irtx_swm_pw_7 */ +#else #define IRTX_PW_0_OFFSET (0x14) /* irtx_pw_0 */ #define IRTX_PW_1_OFFSET (0x18) /* irtx_pw_1 */ +#endif +#endif +#if !defined(BL702L) +#if defined(BL602) || defined(BL702) +#define IRRX_CONFIG_OFFSET (0x80) /* irrx_config */ +#define IRRX_INT_STS_OFFSET (0x84) /* irrx_int_sts */ +#define IRRX_PW_CONFIG_OFFSET (0x88) /* irrx_pw_config */ +#define IRRX_DATA_COUNT_OFFSET (0x90) /* irrx_data_count */ +#define IRRX_DATA_WORD0_OFFSET (0x94) /* irrx_data_word0 */ +#define IRRX_DATA_WORD1_OFFSET (0x98) /* irrx_data_word1 */ +#else #define IRRX_CONFIG_OFFSET (0x40) /* irrx_config */ #define IRRX_INT_STS_OFFSET (0x44) /* irrx_int_sts */ #define IRRX_PW_CONFIG_OFFSET (0x48) /* irrx_pw_config */ #define IRRX_DATA_COUNT_OFFSET (0x50) /* irrx_data_count */ #define IRRX_DATA_WORD0_OFFSET (0x54) /* irrx_data_word0 */ #define IRRX_DATA_WORD1_OFFSET (0x58) /* irrx_data_word1 */ +#endif +#endif +#if defined(BL602) || defined(BL702) +#define IRRX_SWM_FIFO_CONFIG_0_OFFSET (0xC0) /* irrx_swm_fifo_config_0 */ +#define IRRX_SWM_FIFO_RDATA_OFFSET (0xC4) /* irrx_swm_fifo_rdata */ +#else #define IR_FIFO_CONFIG_0_OFFSET (0x80) /* ir_fifo_config_0 */ #define IR_FIFO_CONFIG_1_OFFSET (0x84) /* ir_fifo_config_1 */ #define IR_FIFO_WDATA_OFFSET (0x88) /* ir_fifo_wdata */ +#if !defined(BL702L) #define IR_FIFO_RDATA_OFFSET (0x8C) /* ir_fifo_rdata */ +#endif +#endif /* Register Bitfield definitions *****************************************************/ +#if !defined(BL616) /* 0x0 : irtx_config */ #define IR_CR_IRTX_EN (1 << 0U) #define IR_CR_IRTX_OUT_INV (1 << 1U) @@ -72,24 +109,43 @@ #define IR_CR_IRTX_HEAD_HL_INV (1 << 9U) #define IR_CR_IRTX_TAIL_EN (1 << 10U) #define IR_CR_IRTX_TAIL_HL_INV (1 << 11U) +#if defined(BL602) || defined(BL702) +#define IR_CR_IRTX_DATA_NUM_SHIFT (12U) +#define IR_CR_IRTX_DATA_NUM_MASK (0x3f << IR_CR_IRTX_DATA_NUM_SHIFT) +#else #define IR_CR_IRTX_FRM_EN (1 << 12U) #define IR_CR_IRTX_FRM_CONT_EN (1 << 13U) #define IR_CR_IRTX_FRM_FRAME_SIZE_SHIFT (14U) #define IR_CR_IRTX_FRM_FRAME_SIZE_MASK (0x3 << IR_CR_IRTX_FRM_FRAME_SIZE_SHIFT) #define IR_CR_IRTX_DATA_NUM_SHIFT (16U) #define IR_CR_IRTX_DATA_NUM_MASK (0x7f << IR_CR_IRTX_DATA_NUM_SHIFT) +#endif /* 0x4 : irtx_int_sts */ #define IRTX_END_INT (1 << 0U) +#if !defined(BL602) && !defined(BL702) #define IRTX_FRDY_INT (1 << 1U) #define IRTX_FER_INT (1 << 2U) +#endif #define IR_CR_IRTX_END_MASK (1 << 8U) +#if !defined(BL602) && !defined(BL702) #define IR_CR_IRTX_FRDY_MASK (1 << 9U) #define IR_CR_IRTX_FER_MASK (1 << 10U) +#endif #define IR_CR_IRTX_END_CLR (1 << 16U) #define IR_CR_IRTX_END_EN (1 << 24U) +#if !defined(BL602) && !defined(BL702) #define IR_CR_IRTX_FRDY_EN (1 << 25U) #define IR_CR_IRTX_FER_EN (1 << 26U) +#else +/* 0x8 : irtx_data_word0 */ +#define IR_CR_IRTX_DATA_WORD0_SHIFT (0U) +#define IR_CR_IRTX_DATA_WORD0_MASK (0xffffffff<reg_base; + regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET); + regval &= ~AON_GPADC_CONV_START; + putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET); + + bflb_mtimer_delay_us(100); + regval = getreg32(reg_base + AON_GPADC_REG_CMD_OFFSET); regval |= AON_GPADC_CONV_START; putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET); @@ -398,7 +411,6 @@ void bflb_adc_parse_result(struct bflb_device_s *dev, uint32_t *buffer, struct b uint8_t vref; uint32_t conv_result = 0; uint16_t ref = 3200; - float coe = 1.0; uint8_t neg = 0; uint32_t tmp; @@ -525,7 +537,7 @@ void bflb_adc_tsen_init(struct bflb_device_s *dev, uint8_t tsen_mod) putreg32(regval, reg_base + AON_GPADC_REG_CMD_OFFSET); } -float bflb_adc_tsen_get_temp(struct bflb_device_s *dev, uint32_t tsen_offset) +float bflb_adc_tsen_get_temp(struct bflb_device_s *dev) { uint32_t regval; uint32_t reg_base; @@ -533,6 +545,7 @@ float bflb_adc_tsen_get_temp(struct bflb_device_s *dev, uint32_t tsen_offset) uint32_t v0 = 0, v1 = 0; float temp = 0; uint32_t raw_data; + uint64_t start_time; reg_base = dev->reg_base; @@ -544,30 +557,35 @@ float bflb_adc_tsen_get_temp(struct bflb_device_s *dev, uint32_t tsen_offset) regval = getreg32(reg_base + AON_GPADC_REG_CONFIG2_OFFSET); regval &= ~AON_GPADC_TSVBE_LOW; putreg32(regval, reg_base + AON_GPADC_REG_CONFIG2_OFFSET); + bflb_adc_start_conversion(dev); + start_time = bflb_mtimer_get_time_ms(); while (bflb_adc_get_count(dev) == 0) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } raw_data = bflb_adc_read_raw(dev); bflb_adc_parse_result(dev, &raw_data, &result, 1); - bflb_adc_stop_conversion(dev); v0 = result.value; - regval = getreg32(ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET); - regval |= (0 << 22); regval |= GPIP_GPADC_FIFO_CLR; putreg32(regval, ADC_GPIP_BASE + GPIP_GPADC_CONFIG_OFFSET); regval = getreg32(reg_base + AON_GPADC_REG_CONFIG2_OFFSET); regval |= AON_GPADC_TSVBE_LOW; putreg32(regval, reg_base + AON_GPADC_REG_CONFIG2_OFFSET); + bflb_adc_start_conversion(dev); + start_time = bflb_mtimer_get_time_ms(); while (bflb_adc_get_count(dev) == 0) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } raw_data = bflb_adc_read_raw(dev); bflb_adc_parse_result(dev, &raw_data, &result, 1); - bflb_adc_stop_conversion(dev); v1 = result.value; - if (v0 > v1) { temp = (((float)v0 - (float)v1) - (float)tsen_offset) / 7.753; } else { diff --git a/drivers/lhal/src/bflb_gpio.c b/drivers/lhal/src/bflb_gpio.c index 95fcabcd..15a8c2e4 100644 --- a/drivers/lhal/src/bflb_gpio.c +++ b/drivers/lhal/src/bflb_gpio.c @@ -38,11 +38,21 @@ void bflb_gpio_init(struct bflb_device_s *dev, uint8_t pin, uint32_t cfgset) } else if (mode == GPIO_OUTPUT) { regval |= (1 << (pin & 0x1f)); function = 11; +#if defined(BL702L) + if (function == 22) { + regval &= ~(1 << (pin & 0x1f)); + } +#endif } else if (mode == GPIO_ANALOG) { regval &= ~(1 << (pin & 0x1f)); function = 10; } else if (mode == GPIO_ALTERNATE) { cfg |= (1 << (is_odd * 16 + 0)); +#if defined(BL702L) + if (function == 22) { + cfg &= ~(1 << (is_odd * 16 + 0)); + } +#endif regval &= ~(1 << (pin & 0x1f)); } else { } @@ -63,7 +73,9 @@ void bflb_gpio_init(struct bflb_device_s *dev, uint8_t pin, uint32_t cfgset) cfg |= (function << (is_odd * 16 + 8)); #if defined(BL702L) /* configure output mode:set and clr mode */ - cfg |= (1 << (is_odd * 16 + 15)); + if ((function != 22) || (function != 21)) { + cfg |= (1 << (is_odd * 16 + 15)); + } #endif #elif defined(BL616) || defined(BL808) || defined(BL606P) || defined(BL628) cfg_address = reg_base + GLB_GPIO_CFG0_OFFSET + (pin << 2); @@ -109,8 +121,10 @@ void bflb_gpio_deinit(struct bflb_device_s *dev, uint8_t pin) void bflb_gpio_set(struct bflb_device_s *dev, uint8_t pin) { -#if defined(BL702) || defined(BL602) || defined(BL702L) +#if defined(BL702) || defined(BL602) putreg32(1 << (pin & 0x1f), dev->reg_base + GLB_GPIO_CFGCTL32_OFFSET); +#elif defined(BL702L) + putreg32(1 << (pin & 0x1f), dev->reg_base + GLB_GPIO_CFGCTL35_OFFSET); #elif defined(BL616) || defined(BL808) || defined(BL606P) || defined(BL628) putreg32(1 << (pin & 0x1f), dev->reg_base + GLB_GPIO_CFG138_OFFSET + ((pin >> 5) << 2)); #endif @@ -118,8 +132,10 @@ void bflb_gpio_set(struct bflb_device_s *dev, uint8_t pin) void bflb_gpio_reset(struct bflb_device_s *dev, uint8_t pin) { -#if defined(BL702) || defined(BL602) || defined(BL702L) +#if defined(BL702) || defined(BL602) putreg32(0 << (pin & 0x1f), dev->reg_base + GLB_GPIO_CFGCTL32_OFFSET); +#elif defined(BL702L) + putreg32(1 << (pin & 0x1f), dev->reg_base + GLB_GPIO_CFGCTL36_OFFSET); #elif defined(BL616) || defined(BL808) || defined(BL606P) || defined(BL628) putreg32(1 << (pin & 0x1f), dev->reg_base + GLB_GPIO_CFG140_OFFSET + ((pin >> 5) << 2)); #endif @@ -147,11 +163,16 @@ void bflb_gpio_int_init(struct bflb_device_s *dev, uint8_t pin, uint8_t trig_mod bflb_gpio_int_mask(dev, pin, true); bflb_gpio_int_clear(dev, pin); -#if defined(BL702) || defined(BL602) || defined(BL702L) +#if defined(BL702) || defined(BL602) cfg_address = reg_base + GLB_GPIO_INT_MODE_SET1_OFFSET + ((pin / 10) << 2); regval = getreg32(cfg_address); regval &= ~(0x07 << ((pin % 10) * 3)); regval |= (trig_mode << ((pin % 10) * 3)); +#elif defined(BL702L) + cfg_address = reg_base + GLB_GPIO_INT_MODE_SET1_OFFSET + ((pin / 8) << 2); + regval = getreg32(cfg_address); + regval &= ~(0x0f << ((pin % 8) * 4)); + regval |= (trig_mode << ((pin % 8) * 4)); #elif defined(BL616) || defined(BL808) || defined(BL606P) || defined(BL628) cfg_address = reg_base + GLB_GPIO_CFG0_OFFSET + (pin << 2); regval = getreg32(cfg_address); diff --git a/drivers/lhal/src/bflb_i2c.c b/drivers/lhal/src/bflb_i2c.c index 1de2535f..a82ef5fd 100644 --- a/drivers/lhal/src/bflb_i2c.c +++ b/drivers/lhal/src/bflb_i2c.c @@ -178,6 +178,7 @@ static int bflb_i2c_write_bytes(struct bflb_device_s *dev, uint8_t *data, uint32 uint32_t reg_base; uint32_t temp = 0; uint8_t *tmp_buf; + uint64_t start_time; reg_base = dev->reg_base; tmp_buf = data; @@ -187,7 +188,11 @@ static int bflb_i2c_write_bytes(struct bflb_device_s *dev, uint8_t *data, uint32 } tmp_buf += 4; len -= 4; + start_time = bflb_mtimer_get_time_ms(); while ((getreg32(reg_base + I2C_FIFO_CONFIG_1_OFFSET) & I2C_TX_FIFO_CNT_MASK) == 0) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } putreg32(temp, reg_base + I2C_FIFO_WDATA_OFFSET); if (!bflb_i2c_isenable(dev)) { @@ -200,7 +205,11 @@ static int bflb_i2c_write_bytes(struct bflb_device_s *dev, uint8_t *data, uint32 for (uint8_t i = 0; i < len; i++) { temp += (tmp_buf[i] << ((i % 4) * 8)); } + start_time = bflb_mtimer_get_time_ms(); while ((getreg32(reg_base + I2C_FIFO_CONFIG_1_OFFSET) & I2C_TX_FIFO_CNT_MASK) == 0) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } putreg32(temp, reg_base + I2C_FIFO_WDATA_OFFSET); if (!bflb_i2c_isenable(dev)) { @@ -208,7 +217,11 @@ static int bflb_i2c_write_bytes(struct bflb_device_s *dev, uint8_t *data, uint32 } } + start_time = bflb_mtimer_get_time_ms(); while (bflb_i2c_isbusy(dev) || !bflb_i2c_isend(dev)) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } bflb_i2c_disable(dev); @@ -220,6 +233,7 @@ static int bflb_i2c_read_bytes(struct bflb_device_s *dev, uint8_t *data, uint32_ uint32_t reg_base; uint32_t temp = 0; uint8_t *tmp_buf; + uint64_t start_time; reg_base = dev->reg_base; tmp_buf = data; @@ -227,7 +241,11 @@ static int bflb_i2c_read_bytes(struct bflb_device_s *dev, uint8_t *data, uint32_ bflb_i2c_enable(dev); while (len >= 4) { + start_time = bflb_mtimer_get_time_ms(); while ((getreg32(reg_base + I2C_FIFO_CONFIG_1_OFFSET) & I2C_RX_FIFO_CNT_MASK) == 0) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } temp = getreg32(reg_base + I2C_FIFO_RDATA_OFFSET); PUT_UINT32_LE(tmp_buf, temp); @@ -236,7 +254,11 @@ static int bflb_i2c_read_bytes(struct bflb_device_s *dev, uint8_t *data, uint32_ } if (len > 0) { + start_time = bflb_mtimer_get_time_ms(); while ((getreg32(reg_base + I2C_FIFO_CONFIG_1_OFFSET) & I2C_RX_FIFO_CNT_MASK) == 0) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } temp = getreg32(reg_base + I2C_FIFO_RDATA_OFFSET); @@ -245,7 +267,11 @@ static int bflb_i2c_read_bytes(struct bflb_device_s *dev, uint8_t *data, uint32_ } } + start_time = bflb_mtimer_get_time_ms(); while (bflb_i2c_isbusy(dev) || !bflb_i2c_isend(dev)) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } bflb_i2c_disable(dev); @@ -331,6 +357,7 @@ int bflb_i2c_transfer(struct bflb_device_s *dev, struct bflb_i2c_msg_s *msgs, in uint16_t subaddr = 0; uint16_t subaddr_size = 0; bool is_addr_10bit = false; + int ret = 0; bflb_i2c_disable(dev); @@ -361,14 +388,20 @@ int bflb_i2c_transfer(struct bflb_device_s *dev, struct bflb_i2c_msg_s *msgs, in if (msgs[i].flags & I2C_M_READ) { bflb_i2c_set_dir(dev, 1); if ((msgs[i].flags & I2C_M_DMA) == 0) { - bflb_i2c_read_bytes(dev, msgs[i].buffer, msgs[i].length); + ret = bflb_i2c_read_bytes(dev, msgs[i].buffer, msgs[i].length); + if (ret < 0) { + return ret; + } } else { bflb_i2c_enable(dev); } } else { bflb_i2c_set_dir(dev, 0); if ((msgs[i].flags & I2C_M_DMA) == 0) { - bflb_i2c_write_bytes(dev, msgs[i].buffer, msgs[i].length); + ret = bflb_i2c_write_bytes(dev, msgs[i].buffer, msgs[i].length); + if (ret < 0) { + return ret; + } } else { bflb_i2c_enable(dev); } @@ -408,7 +441,7 @@ uint32_t bflb_i2c_get_intstatus(struct bflb_device_s *dev) uint32_t reg_base; reg_base = dev->reg_base; - return(getreg32(reg_base + I2C_INT_STS_OFFSET) & 0xff); + return (getreg32(reg_base + I2C_INT_STS_OFFSET) & 0xff); } int bflb_i2c_feature_control(struct bflb_device_s *dev, int cmd, size_t arg) @@ -416,7 +449,7 @@ int bflb_i2c_feature_control(struct bflb_device_s *dev, int cmd, size_t arg) int ret = 0; switch (cmd) { default: - ret = -EPERM; + ret = -EPERM; break; } return ret; diff --git a/drivers/lhal/src/bflb_ir.c b/drivers/lhal/src/bflb_ir.c index 47fda835..5cccaae5 100644 --- a/drivers/lhal/src/bflb_ir.c +++ b/drivers/lhal/src/bflb_ir.c @@ -4,6 +4,7 @@ #define DIVIDE_ROUND(a, b) ((2 * a + b) / (2 * b)) +#if !defined(BL616) void bflb_ir_tx_init(struct bflb_device_s *dev, const struct bflb_ir_tx_config_s *config) { uint32_t reg_base; @@ -80,6 +81,16 @@ void bflb_ir_tx_init(struct bflb_device_s *dev, const struct bflb_ir_tx_config_s if (tx_config->tx_mode != IR_TX_CUSTOMIZE) { tx_config->modu_width_1 = ((ir_clock / 11310 + 5) / 10 - 1) & 0xff; tx_config->modu_width_0 = ((ir_clock / 5655 + 5) / 10 - 1) & 0xff; + } else { + if (tx_config->output_modulation != 0 && tx_config->freerun_enable != 0) { + tx_config->continue_enable = 0; + if (tx_config->tail_pulse_width_1 < 5) { + tx_config->tail_pulse_width_1 = 5; + } + if (tx_config->tail_pulse_width_0 < 5) { + tx_config->tail_pulse_width_0 = 5; + } + } } reg_base = dev->reg_base; @@ -172,10 +183,16 @@ void bflb_ir_send(struct bflb_device_s *dev, uint32_t *data, uint32_t length) } } - while((bflb_ir_txint_status(dev) & IR_TX_INT_END) == 0){ - /* Waiting for sending */ + if ((getreg32(reg_base + IRTX_CONFIG_OFFSET) & IR_CR_IRTX_FRM_EN) == 0) { + while((bflb_ir_txint_status(dev) & IR_TX_INT_END) == 0){ + /* Waiting for sending */ + } + } else { + while(bflb_ir_txfifo_cnt(dev) < 4){ + /* Waiting for sending */ + } } - + regval &= ~IR_CR_IRTX_EN; putreg32(regval, reg_base + IRTX_CONFIG_OFFSET); @@ -334,7 +351,9 @@ void bflb_ir_txfifo_clear(struct bflb_device_s *dev) regval |= IR_TX_FIFO_CLR; putreg32(regval, reg_base + IR_FIFO_CONFIG_0_OFFSET); } +#endif +#if !defined(BL702L) void bflb_ir_rx_init(struct bflb_device_s *dev, const struct bflb_ir_rx_config_s *config) { uint32_t reg_base; @@ -513,3 +532,4 @@ void bflb_ir_rxfifo_clear(struct bflb_device_s *dev) regval |= IR_RX_FIFO_CLR; putreg32(regval, reg_base + IR_FIFO_CONFIG_0_OFFSET); } +#endif diff --git a/drivers/lhal/src/bflb_irq.c b/drivers/lhal/src/bflb_irq.c index eab33fed..a39b3491 100644 --- a/drivers/lhal/src/bflb_irq.c +++ b/drivers/lhal/src/bflb_irq.c @@ -10,6 +10,7 @@ extern struct bflb_irq_info_s g_irqvector[]; void irq_unexpected_isr(int irq, void *arg) { + printf("irq :%d unregistered\r\n", irq); } void bflb_irq_initialize(void) @@ -23,9 +24,9 @@ void bflb_irq_initialize(void) } } -uint32_t bflb_irq_save(void) +ATTR_TCM_SECTION uintptr_t bflb_irq_save(void) { - uint32_t oldstat; + uintptr_t oldstat; /* Read mstatus & clear machine interrupt enable (MIE) in mstatus */ @@ -35,7 +36,7 @@ uint32_t bflb_irq_save(void) return oldstat; } -void bflb_irq_restore(uint32_t flags) +ATTR_TCM_SECTION void bflb_irq_restore(uintptr_t flags) { /* Write flags to mstatus */ @@ -59,6 +60,8 @@ int bflb_irq_detach(int irq) if (irq > CONFIG_IRQ_NUM) { return -EINVAL; } + g_irqvector[irq].handler = irq_unexpected_isr; + g_irqvector[irq].arg = NULL; return 0; } @@ -67,6 +70,11 @@ void bflb_irq_enable(int irq) #if defined(BL702) || defined(BL602) || defined(BL702L) putreg8(1, CLIC_HART0_BASE + CLIC_INTIE_OFFSET + irq); #else +#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0) + if (csi_vic_get_prio(irq) == 0) { + csi_vic_set_prio(irq, 1); + } +#endif csi_vic_enable_irq(irq); #endif } @@ -98,12 +106,25 @@ void bflb_irq_clear_pending(int irq) #endif } +void bflb_irq_set_nlbits(uint8_t nlbits) +{ +#if defined(BL702) || defined(BL602) || defined(BL702L) + uint8_t clicCfg = getreg8(CLIC_HART0_BASE + CLIC_CFG_OFFSET); + putreg8((clicCfg & 0xe1) | ((nlbits & 0xf) << 1), CLIC_HART0_BASE + CLIC_CFG_OFFSET); +#else +#if !defined(CPU_D0) + CLIC->CLICCFG = ((nlbits & 0xf) << 1) | 1; +#endif +#endif +} + void bflb_irq_set_priority(int irq, uint8_t preemptprio, uint8_t subprio) { -#if defined(BL702) || defined(BL602) -#elif defined(BL702L) +#if defined(BL702) || defined(BL602) || defined(BL702L) + uint8_t nlbits = getreg8(CLIC_HART0_BASE + CLIC_CFG_OFFSET) >> 1 & 0xf; + uint8_t clicIntCfg = getreg8(CLIC_HART0_BASE + CLIC_INTCFG_OFFSET + irq); + putreg8((clicIntCfg & 0xf) | (preemptprio << (8 - nlbits)) | ((subprio & (0xf >> nlbits)) << 4), CLIC_HART0_BASE + CLIC_INTCFG_OFFSET + irq); #else csi_vic_set_prio(irq, preemptprio); #endif } - diff --git a/drivers/lhal/src/bflb_l1c.c b/drivers/lhal/src/bflb_l1c.c new file mode 100644 index 00000000..a6e1a6fb --- /dev/null +++ b/drivers/lhal/src/bflb_l1c.c @@ -0,0 +1,109 @@ +#include "bflb_l1c.h" + +#if defined(BL616) || defined(BL606P) || defined(BL808) || defined(BL628) +#include "csi_core.h" +void bflb_l1c_icache_enable(void) +{ + csi_icache_enable(); +} + +void bflb_l1c_icache_disable(void) +{ + csi_icache_disable(); +} + +ATTR_TCM_SECTION void bflb_l1c_icache_invalid_all(void) +{ + csi_icache_invalid(); +} + +void bflb_l1c_dcache_enable(void) +{ + csi_dcache_enable(); +} + +void bflb_l1c_dcache_disable(void) +{ + csi_dcache_disable(); +} + +ATTR_TCM_SECTION void bflb_l1c_dcache_clean_all(void) +{ + csi_dcache_clean(); +} + +ATTR_TCM_SECTION void bflb_l1c_dcache_invalidate_all(void) +{ + csi_dcache_invalid(); +} + +ATTR_TCM_SECTION void bflb_l1c_dcache_clean_invalidate_all(void) +{ + csi_dcache_clean_invalid(); +} + +ATTR_TCM_SECTION void bflb_l1c_dcache_clean_range(void *addr, uint32_t size) +{ + csi_dcache_clean_range(addr, size); +} + +ATTR_TCM_SECTION void bflb_l1c_dcache_invalidate_range(void *addr, uint32_t size) +{ + csi_dcache_invalid_range(addr, size); +} + +ATTR_TCM_SECTION void bflb_l1c_dcache_clean_invalidate_range(void *addr, uint32_t size) +{ + csi_dcache_clean_invalid_range(addr, size); +} +#else + +extern void L1C_Cache_Enable_Set(uint8_t wayDisable); +extern void L1C_Cache_Flush(void); + +void bflb_l1c_icache_enable(void) +{ +} + +void bflb_l1c_icache_disable(void) +{ + L1C_Cache_Enable_Set(0x0f); +} + +ATTR_TCM_SECTION void bflb_l1c_icache_invalid_all(void) +{ + L1C_Cache_Flush(); +} + +void bflb_l1c_dcache_enable(void) +{ +} + +void bflb_l1c_dcache_disable(void) +{ +} + +void bflb_l1c_dcache_clean_all(void) +{ +} + +void bflb_l1c_dcache_invalidate_all(void) +{ +} + +void bflb_l1c_dcache_clean_invalidate_all(void) +{ +} + +void bflb_l1c_dcache_clean_range(void *addr, uint32_t size) +{ +} + +void bflb_l1c_dcache_invalidate_range(void *addr, uint32_t size) +{ +} + +void bflb_l1c_dcache_clean_invalidate_range(void *addr, uint32_t size) +{ +} +#endif \ No newline at end of file diff --git a/drivers/lhal/src/bflb_mjpeg.c b/drivers/lhal/src/bflb_mjpeg.c index bf5c27ce..668f5b25 100644 --- a/drivers/lhal/src/bflb_mjpeg.c +++ b/drivers/lhal/src/bflb_mjpeg.c @@ -166,8 +166,6 @@ void bflb_mjpeg_init(struct bflb_device_s *dev, const struct bflb_mjpeg_config_s if (min_framesize > config->output_bufsize) { printf("mjpeg output size is too small\r\n"); - while (1) { - } } putreg32(config->output_bufaddr, reg_base + MJPEG_JPEG_FRAME_ADDR_OFFSET); diff --git a/drivers/lhal/src/bflb_pwm_v1.c b/drivers/lhal/src/bflb_pwm_v1.c index 323cc993..396bcdd3 100644 --- a/drivers/lhal/src/bflb_pwm_v1.c +++ b/drivers/lhal/src/bflb_pwm_v1.c @@ -5,15 +5,21 @@ void bflb_pwm_v1_channel_init(struct bflb_device_s *dev, uint8_t ch, const struc { uint32_t reg_base; uint32_t regval; + uint64_t start_time; reg_base = dev->reg_base; /* stop pwm */ regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); regval |= PWM_STOP_EN; putreg32(regval, reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); + + start_time = bflb_mtimer_get_time_ms(); do { regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); regval &= PWM_STS_TOP; + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return; + } } while (regval == 0); /* config clock source and dividor */ @@ -41,37 +47,25 @@ void bflb_pwm_v1_channel_init(struct bflb_device_s *dev, uint8_t ch, const struc putreg32(regval, reg_base + PWM0_PERIOD_OFFSET + ch * 0x20); } -void bflb_pwm_v1_channel_set_threshold(struct bflb_device_s *dev, uint8_t ch, uint16_t low_threhold, uint16_t high_threhold) -{ - uint32_t reg_base; - uint32_t regval; - - reg_base = dev->reg_base; - - regval = getreg32(reg_base + PWM0_THRE1_OFFSET + ch * 0x20); - regval &= ~PWM_THRE1_MASK; - regval |= low_threhold; - putreg32(regval, reg_base + PWM0_THRE1_OFFSET + ch * 0x20); - - regval = getreg32(reg_base + PWM0_THRE2_OFFSET + ch * 0x20); - regval &= ~PWM_THRE2_MASK; - regval |= high_threhold; - putreg32(regval, reg_base + PWM0_THRE2_OFFSET + ch * 0x20); -} - -void bflb_pwm_v1_deinit(struct bflb_device_s *dev, uint8_t ch) +void bflb_pwm_v1_channel_deinit(struct bflb_device_s *dev, uint8_t ch) { uint32_t reg_base; uint32_t regval; + uint64_t start_time; reg_base = dev->reg_base; /* stop pwmx */ regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); regval |= PWM_STOP_EN; putreg32(regval, reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); + + start_time = bflb_mtimer_get_time_ms(); do { regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); regval &= PWM_STS_TOP; + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return; + } } while (regval == 0); /* restore pwmx_clkdiv register with default value */ @@ -97,6 +91,50 @@ void bflb_pwm_v1_deinit(struct bflb_device_s *dev, uint8_t ch) putreg32(0xFFFFFFFF, reg_base + PWM_INT_CONFIG_OFFSET); } +void bflb_pwm_v1_start(struct bflb_device_s *dev, uint8_t ch) +{ + uint32_t reg_base; + uint32_t regval; + uint32_t start_time; + + reg_base = dev->reg_base; + + regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); + regval &= ~PWM_STOP_EN; + putreg32(regval, reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); + + start_time = bflb_mtimer_get_time_ms(); + do { + regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); + regval &= PWM_STS_TOP; + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return; + } + } while (regval != 0); +} + +void bflb_pwm_v1_stop(struct bflb_device_s *dev, uint8_t ch) +{ + uint32_t reg_base; + uint32_t regval; + uint32_t start_time; + + reg_base = dev->reg_base; + + regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); + regval |= PWM_STOP_EN; + putreg32(regval, reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); + + start_time = bflb_mtimer_get_time_ms(); + do { + regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); + regval &= PWM_STS_TOP; + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return; + } + } while (regval == 0); +} + void bflb_pwm_v1_set_period(struct bflb_device_s *dev, uint8_t ch, uint16_t period) { uint32_t reg_base; @@ -110,36 +148,22 @@ void bflb_pwm_v1_set_period(struct bflb_device_s *dev, uint8_t ch, uint16_t peri putreg32(regval, reg_base + PWM0_PERIOD_OFFSET + ch * 0x20); } -void bflb_pwm_v1_start(struct bflb_device_s *dev, uint8_t ch) +void bflb_pwm_v1_channel_set_threshold(struct bflb_device_s *dev, uint8_t ch, uint16_t low_threhold, uint16_t high_threhold) { uint32_t reg_base; uint32_t regval; reg_base = dev->reg_base; - regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); - regval &= ~PWM_STOP_EN; - putreg32(regval, reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); - do { - regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); - regval &= PWM_STS_TOP; - } while (regval != 0); -} + regval = getreg32(reg_base + PWM0_THRE1_OFFSET + ch * 0x20); + regval &= ~PWM_THRE1_MASK; + regval |= low_threhold; + putreg32(regval, reg_base + PWM0_THRE1_OFFSET + ch * 0x20); -void bflb_pwm_v1_stop(struct bflb_device_s *dev, uint8_t ch) -{ - uint32_t reg_base; - uint32_t regval; - - reg_base = dev->reg_base; - - regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); - regval |= PWM_STOP_EN; - putreg32(regval, reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); - do { - regval = getreg32(reg_base + PWM0_CONFIG_OFFSET + ch * 0x20); - regval &= PWM_STS_TOP; - } while (regval == 0); + regval = getreg32(reg_base + PWM0_THRE2_OFFSET + ch * 0x20); + regval &= ~PWM_THRE2_MASK; + regval |= high_threhold; + putreg32(regval, reg_base + PWM0_THRE2_OFFSET + ch * 0x20); } void bflb_pwm_v1_int_enable(struct bflb_device_s *dev, uint8_t ch, bool enable) diff --git a/drivers/lhal/src/bflb_pwm_v2.c b/drivers/lhal/src/bflb_pwm_v2.c index f38786d9..90e8d349 100644 --- a/drivers/lhal/src/bflb_pwm_v2.c +++ b/drivers/lhal/src/bflb_pwm_v2.c @@ -5,15 +5,21 @@ void bflb_pwm_v2_init(struct bflb_device_s *dev, const struct bflb_pwm_v2_config { uint32_t reg_base; uint32_t regval; + uint64_t start_time; reg_base = dev->reg_base; /* stop pwm */ regval = getreg32(reg_base + PWM_MC0_CONFIG0_OFFSET); regval |= PWM_STOP_EN; putreg32(regval, reg_base + PWM_MC0_CONFIG0_OFFSET); + + start_time = bflb_mtimer_get_time_ms(); do { regval = getreg32(reg_base + PWM_MC0_CONFIG0_OFFSET); regval &= PWM_STS_STOP; + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return; + } } while (regval == 0); /* config clock source and dividor */ @@ -42,15 +48,21 @@ void bflb_pwm_v2_deinit(struct bflb_device_s *dev) { uint32_t reg_base; uint32_t regval; + uint64_t start_time; reg_base = dev->reg_base; /* stop pwm */ regval = getreg32(reg_base + PWM_MC0_CONFIG0_OFFSET); regval |= PWM_STOP_EN; putreg32(regval, reg_base + PWM_MC0_CONFIG0_OFFSET); + + start_time = bflb_mtimer_get_time_ms(); do { regval = getreg32(reg_base + PWM_MC0_CONFIG0_OFFSET); regval &= PWM_STS_STOP; + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return; + } } while (regval == 0); /* restore pwm_mc0_config0 register with default value */ @@ -99,14 +111,20 @@ void bflb_pwm_v2_start(struct bflb_device_s *dev) { uint32_t reg_base; uint32_t regval; + uint64_t start_time; reg_base = dev->reg_base; regval = getreg32(reg_base + PWM_MC0_CONFIG0_OFFSET); regval &= ~PWM_STOP_EN; putreg32(regval, reg_base + PWM_MC0_CONFIG0_OFFSET); + + start_time = bflb_mtimer_get_time_ms(); do { regval = getreg32(reg_base + PWM_MC0_CONFIG0_OFFSET); regval &= PWM_STS_STOP; + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return; + } } while (regval != 0); } @@ -114,14 +132,20 @@ void bflb_pwm_v2_stop(struct bflb_device_s *dev) { uint32_t reg_base; uint32_t regval; + uint64_t start_time; reg_base = dev->reg_base; regval = getreg32(reg_base + PWM_MC0_CONFIG0_OFFSET); regval |= PWM_STOP_EN; putreg32(regval, reg_base + PWM_MC0_CONFIG0_OFFSET); + + start_time = bflb_mtimer_get_time_ms(); do { regval = getreg32(reg_base + PWM_MC0_CONFIG0_OFFSET); regval &= PWM_STS_STOP; + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return; + } } while (regval == 0); } @@ -356,7 +380,7 @@ int bflb_pwm_v2_feature_control(struct bflb_device_s *dev, int cmd, size_t arg) break; default: - ret = -EPERM; + ret = -EPERM; break; } return ret; diff --git a/drivers/lhal/src/bflb_sec_aes.c b/drivers/lhal/src/bflb_sec_aes.c index d6c21443..c2eca63a 100644 --- a/drivers/lhal/src/bflb_sec_aes.c +++ b/drivers/lhal/src/bflb_sec_aes.c @@ -138,6 +138,7 @@ int bflb_aes_encrypt(struct bflb_device_s *dev, { uint32_t regval; uint32_t reg_base; + uint64_t start_time; uint8_t mode; uint8_t *temp_iv = (uint8_t *)iv; @@ -186,7 +187,11 @@ int bflb_aes_encrypt(struct bflb_device_s *dev, regval |= SEC_ENG_SE_AES_0_TRIG_1T; putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET); + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET) & SEC_ENG_SE_AES_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } return 0; } @@ -199,6 +204,7 @@ int bflb_aes_decrypt(struct bflb_device_s *dev, { uint32_t regval; uint32_t reg_base; + uint64_t start_time; uint8_t mode; uint8_t *temp_iv = (uint8_t *)iv; @@ -247,7 +253,11 @@ int bflb_aes_decrypt(struct bflb_device_s *dev, regval |= SEC_ENG_SE_AES_0_TRIG_1T; putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET); + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET) & SEC_ENG_SE_AES_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } return 0; } @@ -292,6 +302,7 @@ int bflb_aes_link_update(struct bflb_device_s *dev, { uint32_t regval; uint32_t reg_base; + uint64_t start_time; reg_base = dev->reg_base; @@ -320,7 +331,11 @@ int bflb_aes_link_update(struct bflb_device_s *dev, __asm volatile("nop"); __asm volatile("nop"); + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET) & SEC_ENG_SE_AES_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } return 0; diff --git a/drivers/lhal/src/bflb_sec_irq.c b/drivers/lhal/src/bflb_sec_irq.c new file mode 100644 index 00000000..99f2d296 --- /dev/null +++ b/drivers/lhal/src/bflb_sec_irq.c @@ -0,0 +1,176 @@ +#include "bflb_sec_irq.h" +#include "hardware/sec_eng_reg.h" + +struct bflb_sec_irq_callback { + void (*handler)(void *arg); + void *arg; +}; + +#if defined(BL702) || defined(BL602) || defined(BL702L) +#define BFLB_SEC_ENG_BASE ((uint32_t)0x40004000) +#elif defined(BL616) || defined(BL606P) || defined(BL808) +#define BFLB_SEC_ENG_BASE ((uint32_t)0x20004000) +#elif defined(BL628) +#define BFLB_SEC_ENG_BASE ((uint32_t)0x20080000) +#endif + +struct bflb_sec_irq_callback sec_eng_callback[6]; + +void sec_eng_isr(int irq, void *arg) +{ + uint32_t regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_AES_0_CTRL_OFFSET); + if (regval & SEC_ENG_SE_AES_0_INT) { + regval |= SEC_ENG_SE_AES_0_INT_CLR_1T; + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_AES_0_CTRL_OFFSET); + if (sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_AES].handler) { + sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_AES].handler(sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_AES].arg); + } + } + + regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_SHA_0_CTRL_OFFSET); + if (regval & SEC_ENG_SE_SHA_0_INT) { + regval |= SEC_ENG_SE_SHA_0_INT_CLR_1T; + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_SHA_0_CTRL_OFFSET); + if (sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_SHA].handler) { + sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_SHA].handler(sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_SHA].arg); + } + } + + regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_PKA_0_CTRL_0_OFFSET); + if (regval & SEC_ENG_SE_PKA_0_INT) { + regval |= SEC_ENG_SE_PKA_0_INT_CLR_1T; + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_PKA_0_CTRL_0_OFFSET); + if (sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_PKA].handler) { + sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_PKA].handler(sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_PKA].arg); + } + } + + regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_TRNG_0_CTRL_0_OFFSET); + if (regval & SEC_ENG_SE_TRNG_0_INT) { + regval |= SEC_ENG_SE_TRNG_0_INT_CLR_1T; + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_TRNG_0_CTRL_0_OFFSET); + if (sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_TRNG].handler) { + sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_TRNG].handler(sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_TRNG].arg); + } + } + + regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_GMAC_0_CTRL_0_OFFSET); + if (regval & SEC_ENG_SE_GMAC_0_INT) { + regval |= SEC_ENG_SE_GMAC_0_INT_CLR_1T; + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_GMAC_0_CTRL_0_OFFSET); + if (sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_GMAC].handler) { + sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_GMAC].handler(sec_eng_callback[BFLB_SEC_ENG_IRQ_TYPE_GMAC].arg); + } + } +} + +void bflb_sec_int_mask(uint8_t sec_type, bool mask) +{ + uint32_t regval; + + switch (sec_type) { + case BFLB_SEC_ENG_IRQ_TYPE_AES: + regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_AES_0_CTRL_OFFSET); + if (mask) { + regval |= SEC_ENG_SE_AES_0_INT_MASK; + } else { + regval &= ~SEC_ENG_SE_AES_0_INT_MASK; + } + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_AES_0_CTRL_OFFSET); + break; + case BFLB_SEC_ENG_IRQ_TYPE_SHA: + regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_SHA_0_CTRL_OFFSET); + if (mask) { + regval |= SEC_ENG_SE_SHA_0_INT_MASK; + } else { + regval &= ~SEC_ENG_SE_SHA_0_INT_MASK; + } + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_SHA_0_CTRL_OFFSET); + break; + case BFLB_SEC_ENG_IRQ_TYPE_PKA: + regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_PKA_0_CTRL_0_OFFSET); + if (mask) { + regval |= SEC_ENG_SE_PKA_0_INT_MASK; + } else { + regval &= ~SEC_ENG_SE_PKA_0_INT_MASK; + } + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_PKA_0_CTRL_0_OFFSET); + break; + case BFLB_SEC_ENG_IRQ_TYPE_TRNG: + regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_TRNG_0_CTRL_0_OFFSET); + if (mask) { + regval |= SEC_ENG_SE_TRNG_0_INT_MASK; + } else { + regval &= ~SEC_ENG_SE_TRNG_0_INT_MASK; + } + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_TRNG_0_CTRL_0_OFFSET); + break; + case BFLB_SEC_ENG_IRQ_TYPE_GMAC: + regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_GMAC_0_CTRL_0_OFFSET); + if (mask) { + regval |= SEC_ENG_SE_GMAC_0_INT_MASK; + } else { + regval &= ~SEC_ENG_SE_GMAC_0_INT_MASK; + } + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_GMAC_0_CTRL_0_OFFSET); + break; + case BFLB_SEC_ENG_IRQ_TYPE_CDET: + regval = getreg32(BFLB_SEC_ENG_BASE + SEC_ENG_SE_CDET_0_CTRL_0_OFFSET); + if (mask) { + regval |= SEC_ENG_SE_CDET_0_INT_MASK; + } else { + regval &= ~SEC_ENG_SE_CDET_0_INT_MASK; + } + putreg32(regval, BFLB_SEC_ENG_BASE + SEC_ENG_SE_CDET_0_CTRL_0_OFFSET); + break; + + default: + break; + } +} + +void bflb_sec_irq_attach(uint8_t sec_type, void (*callback)(void *arg), void *arg) +{ + sec_eng_callback[sec_type].handler = callback; + sec_eng_callback[sec_type].arg = arg; +#if defined(BL702) || defined(BL602) || defined(BL702L) + bflb_irq_attach(25, sec_eng_isr, NULL); + bflb_irq_attach(26, sec_eng_isr, NULL); + bflb_irq_attach(27, sec_eng_isr, NULL); + bflb_irq_attach(28, sec_eng_isr, NULL); + bflb_irq_attach(29, sec_eng_isr, NULL); + bflb_irq_attach(30, sec_eng_isr, NULL); + bflb_irq_enable(25); + bflb_irq_enable(26); + bflb_irq_enable(27); + bflb_irq_enable(28); + bflb_irq_enable(29); + bflb_irq_enable(30); +#elif (defined(BL606P) || defined(BL808)) && (defined(CPU_M0) || defined(CPU_LP)) + bflb_irq_attach(25, sec_eng_isr, NULL); + bflb_irq_attach(26, sec_eng_isr, NULL); + bflb_irq_attach(27, sec_eng_isr, NULL); + bflb_irq_attach(28, sec_eng_isr, NULL); + bflb_irq_enable(25); + bflb_irq_enable(26); + bflb_irq_enable(27); + bflb_irq_enable(28); +#elif defined(BL616) || defined(BL628) + bflb_irq_attach(25, sec_eng_isr, NULL); + bflb_irq_attach(26, sec_eng_isr, NULL); + bflb_irq_attach(27, sec_eng_isr, NULL); + bflb_irq_attach(28, sec_eng_isr, NULL); + bflb_irq_enable(25); + bflb_irq_enable(26); + bflb_irq_enable(27); + bflb_irq_enable(28); +#endif + bflb_sec_int_mask(sec_type, false); +} + +void bflb_sec_irq_detach(uint8_t sec_type) +{ + sec_eng_callback[sec_type].handler = NULL; + sec_eng_callback[sec_type].arg = NULL; + bflb_sec_int_mask(sec_type, true); +} diff --git a/drivers/lhal/src/bflb_sec_sha.c b/drivers/lhal/src/bflb_sec_sha.c index 1c66473d..b1c909a9 100644 --- a/drivers/lhal/src/bflb_sec_sha.c +++ b/drivers/lhal/src/bflb_sec_sha.c @@ -84,6 +84,7 @@ int bflb_sha1_update(struct bflb_device_s *dev, struct bflb_sha1_ctx_s *ctx, con uint32_t reg_base; uint32_t fill; uint32_t left; + uint64_t start_time; if (len == 0) { return 0; @@ -130,7 +131,11 @@ int bflb_sha1_update(struct bflb_device_s *dev, struct bflb_sha1_ctx_s *ctx, con len = len % 64; if (fill > 0) { + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } /* SHA need set se_sha_sel to 1 to keep the last sha state */ @@ -155,14 +160,22 @@ int bflb_sha1_update(struct bflb_device_s *dev, struct bflb_sha1_ctx_s *ctx, con } if (len > 0) { + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } /* Copy left data into temp buffer */ arch_memcpy_fast((void *)((uint8_t *)ctx->sha_buf + left), input, len); } + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } return 0; } @@ -178,6 +191,7 @@ int bflb_sha512_update(struct bflb_device_s *dev, struct bflb_sha512_ctx_s *ctx, uint32_t reg_base; uint32_t fill; uint32_t left; + uint64_t start_time; if (len == 0) { return 0; @@ -223,7 +237,11 @@ int bflb_sha512_update(struct bflb_device_s *dev, struct bflb_sha512_ctx_s *ctx, len = len % 128; if (fill > 0) { + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } /* SHA need set se_sha_sel to 1 to keep the last sha state */ @@ -248,14 +266,22 @@ int bflb_sha512_update(struct bflb_device_s *dev, struct bflb_sha512_ctx_s *ctx, } if (len > 0) { + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } /* Copy left data into temp buffer */ arch_memcpy_fast((void *)((uint8_t *)ctx->sha_buf + left), input, len); } + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } return 0; } @@ -526,6 +552,7 @@ int bflb_sha1_link_update(struct bflb_device_s *dev, uint32_t reg_base; uint32_t fill; uint32_t left; + uint64_t start_time; if (len == 0) { return 0; @@ -569,7 +596,11 @@ int bflb_sha1_link_update(struct bflb_device_s *dev, len = len % 64; if (fill > 0) { + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } /* Fill data */ @@ -586,14 +617,22 @@ int bflb_sha1_link_update(struct bflb_device_s *dev, } if (len > 0) { + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } /* Copy left data into temp buffer */ arch_memcpy_fast((void *)((uint8_t *)ctx->sha_buf + left), input, len); } + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } return 0; } @@ -615,6 +654,7 @@ int bflb_sha512_link_update(struct bflb_device_s *dev, uint32_t reg_base; uint32_t fill; uint32_t left; + uint64_t start_time; if (len == 0) { return 0; @@ -657,7 +697,11 @@ int bflb_sha512_link_update(struct bflb_device_s *dev, len = len % 128; if (fill > 0) { + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } /* Fill data */ @@ -674,14 +718,22 @@ int bflb_sha512_link_update(struct bflb_device_s *dev, } if (len > 0) { + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } /* Copy left data into temp buffer */ arch_memcpy_fast((void *)((uint8_t *)ctx->sha_buf + left), input, len); } + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_SHA_0_CTRL_OFFSET) & SEC_ENG_SE_SHA_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } return 0; } diff --git a/drivers/lhal/src/bflb_sec_trng.c b/drivers/lhal/src/bflb_sec_trng.c index eec914aa..53584857 100644 --- a/drivers/lhal/src/bflb_sec_trng.c +++ b/drivers/lhal/src/bflb_sec_trng.c @@ -13,6 +13,7 @@ int bflb_trng_read(struct bflb_device_s *dev, uint8_t data[32]) { uint32_t regval; uint32_t reg_base; + uint64_t start_time; uint8_t *p = (uint8_t *)data; reg_base = dev->reg_base; @@ -32,7 +33,11 @@ int bflb_trng_read(struct bflb_device_s *dev, uint8_t data[32]) __ASM volatile("nop"); __ASM volatile("nop"); + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_TRNG_0_CTRL_0_OFFSET) & SEC_ENG_SE_TRNG_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } regval = getreg32(reg_base + SEC_ENG_SE_TRNG_0_CTRL_0_OFFSET); @@ -49,7 +54,11 @@ int bflb_trng_read(struct bflb_device_s *dev, uint8_t data[32]) __ASM volatile("nop"); __ASM volatile("nop"); + start_time = bflb_mtimer_get_time_ms(); while (getreg32(reg_base + SEC_ENG_SE_TRNG_0_CTRL_0_OFFSET) & SEC_ENG_SE_TRNG_0_BUSY) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } /* copy trng value */ diff --git a/drivers/lhal/src/bflb_spi.c b/drivers/lhal/src/bflb_spi.c index 45da67f5..a2ec290c 100644 --- a/drivers/lhal/src/bflb_spi.c +++ b/drivers/lhal/src/bflb_spi.c @@ -215,7 +215,6 @@ ATTR_TCM_SECTION uint32_t bflb_spi_poll_send(struct bflb_device_s *dev, uint32_t regval = getreg32(reg_base + SPI_FIFO_CONFIG_1_OFFSET); fifo_cnt = (regval & SPI_RX_FIFO_CNT_MASK) >> SPI_RX_FIFO_CNT_SHIFT; } while (fifo_cnt < frame_size); - #else /* Wait for rx data */ @@ -223,7 +222,6 @@ ATTR_TCM_SECTION uint32_t bflb_spi_poll_send(struct bflb_device_s *dev, uint32_t regval = getreg32(reg_base + SPI_FIFO_CONFIG_1_OFFSET); fifo_cnt = (regval & SPI_RX_FIFO_CNT_MASK) >> SPI_RX_FIFO_CNT_SHIFT; } while (fifo_cnt == 0); - #endif regval = getreg32(reg_base + SPI_FIFO_RDATA_OFFSET); @@ -338,7 +336,6 @@ ATTR_TCM_SECTION int bflb_spi_poll_exchange(struct bflb_device_s *dev, const voi fifo_cnt = fifo_cnt > nbytes ? nbytes : fifo_cnt; nbytes -= fifo_cnt; } else { - continue; } /* read and write data */ @@ -431,6 +428,20 @@ void bflb_spi_rxint_mask(struct bflb_device_s *dev, bool mask) putreg32(regval, reg_base + SPI_INT_STS_OFFSET); } +void bflb_spi_tcint_mask(struct bflb_device_s *dev, bool mask) +{ + uint32_t regval; + uint32_t reg_base = dev->reg_base; + + regval = getreg32(reg_base + SPI_INT_STS_OFFSET); + if (mask) { + regval |= SPI_CR_SPI_END_MASK; + } else { + regval &= ~SPI_CR_SPI_END_MASK; + } + putreg32(regval, reg_base + SPI_INT_STS_OFFSET); +} + void bflb_spi_errint_mask(struct bflb_device_s *dev, bool mask) { uint32_t regval; @@ -456,8 +467,8 @@ uint32_t bflb_spi_get_intstatus(struct bflb_device_s *dev) uint32_t int_mask; reg_base = dev->reg_base; - int_status = getreg32(reg_base + SPI_INT_STS_OFFSET) & 0xff; - int_mask = getreg32(reg_base + SPI_INT_STS_OFFSET) >> 8 & 0xff; + int_status = getreg32(reg_base + SPI_INT_STS_OFFSET) & 0x1f; + int_mask = getreg32(reg_base + SPI_INT_STS_OFFSET) >> 8 & 0x1f; return (int_status & ~int_mask); } @@ -468,7 +479,7 @@ void bflb_spi_int_clear(struct bflb_device_s *dev, uint32_t int_clear) reg_base = dev->reg_base; regval = getreg32(reg_base + SPI_INT_STS_OFFSET); - regval |= int_clear << 16; + regval |= int_clear; putreg32(regval, reg_base + SPI_INT_STS_OFFSET); } diff --git a/drivers/lhal/src/bflb_uart.c b/drivers/lhal/src/bflb_uart.c index bc6cdfe8..acd93c1e 100644 --- a/drivers/lhal/src/bflb_uart.c +++ b/drivers/lhal/src/bflb_uart.c @@ -192,17 +192,23 @@ void bflb_uart_link_rxdma(struct bflb_device_s *dev, bool enable) putreg32(regval, reg_base + UART_FIFO_CONFIG_0_OFFSET); } -void bflb_uart_putchar(struct bflb_device_s *dev, int ch) +ATTR_TCM_SECTION int bflb_uart_putchar(struct bflb_device_s *dev, int ch) { + uint64_t start_time; uint32_t reg_base; reg_base = dev->reg_base; + start_time = bflb_mtimer_get_time_ms(); while ((getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET) & UART_TX_FIFO_CNT_MASK) == 0) { + if ((bflb_mtimer_get_time_ms() - start_time) > 100) { + return -ETIMEDOUT; + } } putreg8(ch, reg_base + UART_FIFO_WDATA_OFFSET); + return 0; } -int bflb_uart_getchar(struct bflb_device_s *dev) +ATTR_TCM_SECTION int bflb_uart_getchar(struct bflb_device_s *dev) { int ch = -1; uint32_t reg_base; @@ -215,14 +221,19 @@ int bflb_uart_getchar(struct bflb_device_s *dev) return ch; } -void bflb_uart_put(struct bflb_device_s *dev, uint8_t *data, uint32_t len) +ATTR_TCM_SECTION int bflb_uart_put(struct bflb_device_s *dev, uint8_t *data, uint32_t len) { + int ret; for (uint32_t i = 0; i < len; i++) { - bflb_uart_putchar(dev, data[i]); + ret = bflb_uart_putchar(dev, data[i]); + if (ret < 0) { + return ret; + } } + return 0; } -int bflb_uart_get(struct bflb_device_s *dev, uint8_t *data, uint32_t len) +ATTR_TCM_SECTION int bflb_uart_get(struct bflb_device_s *dev, uint8_t *data, uint32_t len) { int ch = -1; uint32_t count = 0; @@ -353,6 +364,7 @@ int bflb_uart_feature_control(struct bflb_device_s *dev, int cmd, size_t arg) uint32_t tmp; uint32_t tx_tmp; uint32_t rx_tmp; + uint32_t int_mask; reg_base = dev->reg_base; @@ -458,14 +470,15 @@ int bflb_uart_feature_control(struct bflb_device_s *dev, int cmd, size_t arg) tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET); rx_tmp = getreg32(reg_base + UART_INT_MASK_OFFSET); tmp &= ~UART_CR_URX_ABR_EN; - if (arg) { + if (arg == UART_AUTO_BAUD_0X55) { + tmp |= UART_CR_URX_ABR_EN; +#if !defined(BL602) && !defined(BL702) + rx_tmp &= ~UART_CR_URX_AD5_MASK; +#endif + } else { tmp |= UART_CR_URX_ABR_EN; #if !defined(BL602) && !defined(BL702) rx_tmp &= ~UART_CR_URX_ADS_MASK; - rx_tmp &= ~UART_CR_URX_AD5_MASK; - } else { - rx_tmp |= UART_CR_URX_ADS_MASK; - rx_tmp |= UART_CR_URX_AD5_MASK; #endif } @@ -619,6 +632,84 @@ int bflb_uart_feature_control(struct bflb_device_s *dev, int cmd, size_t arg) /* Configure rx ir pulse start position */ putreg32(ir_config->rx_pluse_start, reg_base + UART_URX_IR_POSITION_OFFSET); } break; +#endif + case UART_CMD_SET_TX_FREERUN: + /* Set tx freerun */ + tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET); + + if (arg) { + tx_tmp |= UART_CR_UTX_FRM_EN; + } else { + tx_tmp &= ~UART_CR_UTX_FRM_EN; + } + + putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET); + break; + case UART_CMD_SET_TX_END_INTERRUPT: + /* Set tx end interrupt */ + int_mask = getreg32(reg_base + UART_INT_MASK_OFFSET); + if (arg) { + int_mask &= ~UART_CR_UTX_END_MASK; + } else { + int_mask |= UART_CR_UTX_END_MASK; + } + putreg32(int_mask, reg_base + UART_INT_MASK_OFFSET); + break; + case UART_CMD_SET_RX_END_INTERRUPT: + /* Set rx end interrupt */ + int_mask = getreg32(reg_base + UART_INT_MASK_OFFSET); + if (arg) { + int_mask &= ~UART_CR_URX_END_MASK; + } else { + int_mask |= UART_CR_URX_END_MASK; + } + putreg32(int_mask, reg_base + UART_INT_MASK_OFFSET); + break; + case UART_CMD_SET_TX_TRANSFER_LEN: + /* Set tx transfer length */ + tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET); + + tx_tmp |= ((arg - 1) << UART_CR_UTX_LEN_SHIFT); + + putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET); + break; + case UART_CMD_SET_RX_TRANSFER_LEN: + /* Set rx transfer length */ + rx_tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET); + + rx_tmp |= ((arg - 1) << UART_CR_URX_LEN_SHIFT); + + putreg32(rx_tmp, reg_base + UART_URX_CONFIG_OFFSET); + break; + case UART_CMD_SET_TX_EN: + /* Set tx enable */ + tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET); + + if (arg) { + tx_tmp |= UART_CR_UTX_EN; + } else { + tx_tmp &= ~UART_CR_UTX_EN; + } + + putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET); + break; +#if !defined(BL602) && !defined(BL702) + case UART_CMD_SET_BCR_END_INTERRUPT: + /* Set bcr value */ + int_mask = getreg32(reg_base + UART_INT_MASK_OFFSET); + int_mask &= ~UART_CR_URX_BCR_MASK; + putreg32(int_mask, reg_base + UART_INT_MASK_OFFSET); + + rx_tmp = getreg32(reg_base + UART_URX_BCR_INT_CFG_OFFSET); + rx_tmp &= ~UART_CR_URX_BCR_VALUE_MASK; + rx_tmp |= (arg << UART_CR_URX_BCR_VALUE_SHIFT); + putreg32(rx_tmp, reg_base + UART_URX_BCR_INT_CFG_OFFSET); + break; + case UART_CMD_GET_BCR_COUNT: + /* Get bcr value */ + rx_tmp = getreg32(reg_base + UART_URX_BCR_INT_CFG_OFFSET); + return ((rx_tmp & UART_STS_URX_BCR_COUNT_MASK) >> UART_STS_URX_BCR_COUNT_SHIFT); + break; #endif default: ret = -EPERM; diff --git a/drivers/soc/bl602/CMakeLists.txt b/drivers/soc/bl602/CMakeLists.txt index a7cdbe0a..892f2a08 100644 --- a/drivers/soc/bl602/CMakeLists.txt +++ b/drivers/soc/bl602/CMakeLists.txt @@ -5,15 +5,31 @@ sdk_library_add_sources(startup/start_load.c) sdk_library_add_sources(startup/system_bl602.c) sdk_library_add_sources(startup/interrupt.c) +if(CONFIG_ROMAPI) +sdk_library_add_sources(bl602_std/src/bl602_romapi.c) +sdk_add_compile_definitions(-DBFLB_USE_ROM_DRIVER) +endif() + +sdk_library_add_sources(bl602_std/src/bl602_aon.c) +sdk_library_add_sources(bl602_std/src/bl602_common.c) sdk_library_add_sources(bl602_std/src/bl602_clock.c) +sdk_library_add_sources(bl602_std/src/bl602_ef_ctrl.c) sdk_library_add_sources(bl602_std/src/bl602_glb.c) sdk_library_add_sources(bl602_std/src/bl602_hbn.c) -sdk_library_add_sources(bl602_std/src/bl602_romapi.c) -# sdk_library_add_sources(bl602_std/src/bl602_pds.c) -# sdk_library_add_sources(bl602_std/src/bl602_common.c) -# sdk_library_add_sources(bl602_std/src/bl602_l1c.c) -# sdk_library_add_sources(bl602_std/src/bl602_aon.c) +sdk_library_add_sources(bl602_std/src/bl602_l1c.c) +sdk_library_add_sources(bl602_std/src/bl602_pds.c) + +sdk_library_add_sources(bl602_std/src/bl602_sf_cfg.c) +sdk_library_add_sources(bl602_std/src/bl602_sf_cfg_ext.c) +sdk_library_add_sources(bl602_std/src/bl602_sf_ctrl.c) +sdk_library_add_sources(bl602_std/src/bl602_sflash.c) +sdk_library_add_sources(bl602_std/src/bl602_sflash_ext.c) +sdk_library_add_sources(bl602_std/src/bl602_xip_sflash.c) +sdk_library_add_sources(bl602_std/src/bl602_xip_sflash_ext.c) + sdk_library_add_sources(port/bl602_clock.c) +sdk_library_add_sources(port/bl602_flash.c) +sdk_library_add_sources(port/bl602_efuse.c) sdk_add_include_directories( bl602_std/include @@ -24,7 +40,7 @@ SET(MCPU "riscv-e24") SET(MARCH "rv32imafc") SET(MABI "ilp32f") -sdk_add_compile_definitions(-DARCH_RISCV) +sdk_add_compile_definitions(-DARCH_RISCV -DBFLB_USE_HAL_DRIVER) sdk_add_compile_options(-march=${MARCH} -mabi=${MABI}) sdk_add_link_options(-march=${MARCH} -mabi=${MABI}) diff --git a/drivers/soc/bl602/bl602_std/include/bl602_common.h b/drivers/soc/bl602/bl602_std/include/bl602_common.h index 9f831e20..78be0b68 100644 --- a/drivers/soc/bl602/bl602_std/include/bl602_common.h +++ b/drivers/soc/bl602/bl602_std/include/bl602_common.h @@ -205,6 +205,11 @@ __ALWAYS_STATIC_INLINE void __disable_irq(void) #define arch_delay_us BL602_Delay_US #define arch_delay_ms BL602_Delay_MS +#define BFLB_Soft_CRC32 bflb_soft_crc32 +#define CPU_Interrupt_Enable(irq) +#define CPU_Interrupt_Disable(irq) +#define Interrupt_Handler_Register(irq, callback) + void BL602_Delay_US(uint32_t cnt); void BL602_Delay_MS(uint32_t cnt); #endif diff --git a/drivers/soc/bl602/bl602_std/include/bl602_glb.h b/drivers/soc/bl602/bl602_std/include/bl602_glb.h index aac7a407..41e7f8cb 100644 --- a/drivers/soc/bl602/bl602_std/include/bl602_glb.h +++ b/drivers/soc/bl602/bl602_std/include/bl602_glb.h @@ -39,7 +39,7 @@ #include "glb_reg.h" #include "pds_reg.h" #include "bl602_gpio.h" -// #include "bl602_l1c.h" +#include "bl602_l1c.h" #include "bl602_hbn.h" #include "bl602_sf_ctrl.h" #include "bl602_sf_cfg.h" diff --git a/drivers/soc/bl602/bl602_std/include/bl602_l1c.h b/drivers/soc/bl602/bl602_std/include/bl602_l1c.h new file mode 100644 index 00000000..e8fccde7 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/include/bl602_l1c.h @@ -0,0 +1,189 @@ +/** + ****************************************************************************** + * @file bl602_l1c.h + * @version V1.0 + * @date + * @brief This file is the standard driver header file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ +#ifndef __BL602_L1C_H__ +#define __BL602_L1C_H__ + +#include "l1c_reg.h" +#include "bl602_common.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup L1C + * @{ + */ + +/** @defgroup L1C_Public_Types + * @{ + */ + +/** + * @brief L1C configuration structure type definition + */ +typedef struct +{ + BL_Fun_Type wrapDis; /*!< wrap disable */ + BL_Fun_Type bypassEn; /*!< bypass cache enable */ + uint8_t wayDis; /*!< Disable part of cache ways & used as ITCM */ + BL_Fun_Type cntEn; /*!< l1c count enable */ +} L1C_CACHE_Cfg_Type; + +/** + * @brief L1C BMX arb mode type definition + */ +typedef enum { + L1C_BMX_ARB_FIX, /*!< 0->fix */ + L1C_BMX_ARB_ROUND_ROBIN, /*!< 2->round-robin */ + L1C_BMX_ARB_RANDOM, /*!< 3->random */ +} L1C_BMX_ARB_Type; + +/** + * @brief L1C BMX configuration structure type definition + */ +typedef struct +{ + uint8_t timeoutEn; /*!< Bus timeout enable: detect slave no reaponse in 1024 cycles */ + BL_Fun_Type errEn; /*!< Bus error response enable */ + L1C_BMX_ARB_Type arbMod; /*!< 0->fix, 2->round-robin, 3->random */ +} L1C_BMX_Cfg_Type; + +/** + * @brief L1C BMX bus err type definition + */ +typedef enum { + L1C_BMX_BUS_ERR_TRUSTZONE_DECODE, /*!< Bus trustzone decode error */ + L1C_BMX_BUS_ERR_ADDR_DECODE, /*!< Bus addr decode error */ +} L1C_BMX_BUS_ERR_Type; + +/** + * @brief L1C BMX bus err interrupt type definition + */ +typedef enum { + L1C_BMX_ERR_INT_ERR, /*!< L1C BMX bus err interrupt */ + L1C_BMX_ERR_INT_ALL, /*!< L1C BMX bus err interrupt max num */ +} L1C_BMX_ERR_INT_Type; + +/** + * @brief L1C BMX time out interrupt type definition + */ +typedef enum { + L1C_BMX_TO_INT_TIMEOUT, /*!< L1C_BMX timeout interrupt */ + L1C_BMX_TO_INT_ALL, /*!< L1C_BMX timeout interrupt max num */ +} L1C_BMX_TO_INT_Type; + +/*@} end of group L1C_Public_Types */ + +/** @defgroup L1C_Public_Constants + * @{ + */ + +/** @defgroup L1C_BMX_ARB_TYPE + * @{ + */ +#define IS_L1C_BMX_ARB_TYPE(type) (((type) == L1C_BMX_ARB_FIX) || \ + ((type) == L1C_BMX_ARB_ROUND_ROBIN) || \ + ((type) == L1C_BMX_ARB_RANDOM)) + +/** @defgroup L1C_BMX_BUS_ERR_TYPE + * @{ + */ +#define IS_L1C_BMX_BUS_ERR_TYPE(type) (((type) == L1C_BMX_BUS_ERR_TRUSTZONE_DECODE) || \ + ((type) == L1C_BMX_BUS_ERR_ADDR_DECODE)) + +/** @defgroup L1C_BMX_ERR_INT_TYPE + * @{ + */ +#define IS_L1C_BMX_ERR_INT_TYPE(type) (((type) == L1C_BMX_ERR_INT_ERR) || \ + ((type) == L1C_BMX_ERR_INT_ALL)) + +/** @defgroup L1C_BMX_TO_INT_TYPE + * @{ + */ +#define IS_L1C_BMX_TO_INT_TYPE(type) (((type) == L1C_BMX_TO_INT_TIMEOUT) || \ + ((type) == L1C_BMX_TO_INT_ALL)) + +/*@} end of group L1C_Public_Constants */ + +/** @defgroup L1C_Public_Macros + * @{ + */ +#if 1 +/*NP config address */ +#define L1C_CONF_REG_NP (L1C_BASE + 0x00) +#define L1C_HIT_CNT_LSB_REG_NP (L1C_BASE + 0x04) +#define L1C_HIT_CNT_MSB_REG_NP (L1C_BASE + 0x08) +#define L1C_MISS_CNT_REG_NP (L1C_BASE + 0x0C) +/* Get miss and hit count */ +#define L1C_Get_Miss_Cnt_NP() BL602_REG_RD(L1C_MISS_CNT_REG_NP) +#define L1C_Get_Hit_Cnt_LSB_NP() BL602_REG_RD(L1C_HIT_CNT_LSB_REG_NP) +#define L1C_Get_Hit_Cnt_MSB_NP() BL602_REG_RD(L1C_HIT_CNT_MSB_REG_NP) +#endif + +/*@} end of group L1C_Public_Macros */ + +/** @defgroup L1C_Public_Functions + * @{ + */ +/*----------*/ +#ifndef BFLB_USE_HAL_DRIVER +void L1C_BMX_ERR_IRQHandler(void); +void L1C_BMX_TO_IRQHandler(void); +#endif +/*----------*/ +BL_Err_Type L1C_Set_Wrap(BL_Fun_Type wrap); +BL_Err_Type L1C_Set_Way_Disable(uint8_t disableVal); +BL_Err_Type L1C_IROM_2T_Access_Set(uint8_t enable); +/*----------*/ +BL_Err_Type L1C_BMX_Init(L1C_BMX_Cfg_Type *l1cBmxCfg); +BL_Err_Type L1C_BMX_Addr_Monitor_Enable(void); +BL_Err_Type L1C_BMX_Addr_Monitor_Disable(void); +BL_Err_Type L1C_BMX_BusErrResponse_Enable(void); +BL_Err_Type L1C_BMX_BusErrResponse_Disable(void); +BL_Sts_Type L1C_BMX_Get_Status(L1C_BMX_BUS_ERR_Type errType); +uint32_t L1C_BMX_Get_Err_Addr(void); +BL_Err_Type L1C_BMX_ERR_INT_Callback_Install(L1C_BMX_ERR_INT_Type intType, intCallback_Type *cbFun); +BL_Err_Type L1C_BMX_TIMEOUT_INT_Callback_Install(L1C_BMX_TO_INT_Type intType, + intCallback_Type *cbFun); +/*----------*/; + +/*@} end of group L1C_Public_Functions */ + +/*@} end of group L1C */ + +/*@} end of group BL602_Peripheral_Driver */ + +#endif /* __BL602_L1C_H__ */ diff --git a/drivers/soc/bl602/bl602_std/include/hardware/l1c_reg.h b/drivers/soc/bl602/bl602_std/include/hardware/l1c_reg.h new file mode 100644 index 00000000..2c618383 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/include/hardware/l1c_reg.h @@ -0,0 +1,318 @@ +/** + ****************************************************************************** + * @file l1c_reg.h + * @version V1.2 + * @date 2019-11-22 + * @brief This file is the description of.IP register + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ +#ifndef __L1C_REG_H__ +#define __L1C_REG_H__ + +#include "bl602.h" + +/* 0x0 : l1c_config */ +#define L1C_CONFIG_OFFSET (0x0) +#define L1C_CACHEABLE L1C_CACHEABLE +#define L1C_CACHEABLE_POS (0U) +#define L1C_CACHEABLE_LEN (1U) +#define L1C_CACHEABLE_MSK (((1U << L1C_CACHEABLE_LEN) - 1) << L1C_CACHEABLE_POS) +#define L1C_CACHEABLE_UMSK (~(((1U << L1C_CACHEABLE_LEN) - 1) << L1C_CACHEABLE_POS)) +#define L1C_CNT_EN L1C_CNT_EN +#define L1C_CNT_EN_POS (1U) +#define L1C_CNT_EN_LEN (1U) +#define L1C_CNT_EN_MSK (((1U << L1C_CNT_EN_LEN) - 1) << L1C_CNT_EN_POS) +#define L1C_CNT_EN_UMSK (~(((1U << L1C_CNT_EN_LEN) - 1) << L1C_CNT_EN_POS)) +#define L1C_INVALID_EN L1C_INVALID_EN +#define L1C_INVALID_EN_POS (2U) +#define L1C_INVALID_EN_LEN (1U) +#define L1C_INVALID_EN_MSK (((1U << L1C_INVALID_EN_LEN) - 1) << L1C_INVALID_EN_POS) +#define L1C_INVALID_EN_UMSK (~(((1U << L1C_INVALID_EN_LEN) - 1) << L1C_INVALID_EN_POS)) +#define L1C_INVALID_DONE L1C_INVALID_DONE +#define L1C_INVALID_DONE_POS (3U) +#define L1C_INVALID_DONE_LEN (1U) +#define L1C_INVALID_DONE_MSK (((1U << L1C_INVALID_DONE_LEN) - 1) << L1C_INVALID_DONE_POS) +#define L1C_INVALID_DONE_UMSK (~(((1U << L1C_INVALID_DONE_LEN) - 1) << L1C_INVALID_DONE_POS)) +#define L1C_WAY_DIS L1C_WAY_DIS +#define L1C_WAY_DIS_POS (8U) +#define L1C_WAY_DIS_LEN (4U) +#define L1C_WAY_DIS_MSK (((1U << L1C_WAY_DIS_LEN) - 1) << L1C_WAY_DIS_POS) +#define L1C_WAY_DIS_UMSK (~(((1U << L1C_WAY_DIS_LEN) - 1) << L1C_WAY_DIS_POS)) +#define L1C_IROM_2T_ACCESS L1C_IROM_2T_ACCESS +#define L1C_IROM_2T_ACCESS_POS (12U) +#define L1C_IROM_2T_ACCESS_LEN (1U) +#define L1C_IROM_2T_ACCESS_MSK (((1U << L1C_IROM_2T_ACCESS_LEN) - 1) << L1C_IROM_2T_ACCESS_POS) +#define L1C_IROM_2T_ACCESS_UMSK (~(((1U << L1C_IROM_2T_ACCESS_LEN) - 1) << L1C_IROM_2T_ACCESS_POS)) +#define L1C_BYPASS L1C_BYPASS +#define L1C_BYPASS_POS (14U) +#define L1C_BYPASS_LEN (1U) +#define L1C_BYPASS_MSK (((1U << L1C_BYPASS_LEN) - 1) << L1C_BYPASS_POS) +#define L1C_BYPASS_UMSK (~(((1U << L1C_BYPASS_LEN) - 1) << L1C_BYPASS_POS)) +#define L1C_BMX_ERR_EN L1C_BMX_ERR_EN +#define L1C_BMX_ERR_EN_POS (15U) +#define L1C_BMX_ERR_EN_LEN (1U) +#define L1C_BMX_ERR_EN_MSK (((1U << L1C_BMX_ERR_EN_LEN) - 1) << L1C_BMX_ERR_EN_POS) +#define L1C_BMX_ERR_EN_UMSK (~(((1U << L1C_BMX_ERR_EN_LEN) - 1) << L1C_BMX_ERR_EN_POS)) +#define L1C_BMX_ARB_MODE L1C_BMX_ARB_MODE +#define L1C_BMX_ARB_MODE_POS (16U) +#define L1C_BMX_ARB_MODE_LEN (2U) +#define L1C_BMX_ARB_MODE_MSK (((1U << L1C_BMX_ARB_MODE_LEN) - 1) << L1C_BMX_ARB_MODE_POS) +#define L1C_BMX_ARB_MODE_UMSK (~(((1U << L1C_BMX_ARB_MODE_LEN) - 1) << L1C_BMX_ARB_MODE_POS)) +#define L1C_BMX_TIMEOUT_EN L1C_BMX_TIMEOUT_EN +#define L1C_BMX_TIMEOUT_EN_POS (20U) +#define L1C_BMX_TIMEOUT_EN_LEN (4U) +#define L1C_BMX_TIMEOUT_EN_MSK (((1U << L1C_BMX_TIMEOUT_EN_LEN) - 1) << L1C_BMX_TIMEOUT_EN_POS) +#define L1C_BMX_TIMEOUT_EN_UMSK (~(((1U << L1C_BMX_TIMEOUT_EN_LEN) - 1) << L1C_BMX_TIMEOUT_EN_POS)) +#define L1C_BMX_BUSY_OPTION_DIS L1C_BMX_BUSY_OPTION_DIS +#define L1C_BMX_BUSY_OPTION_DIS_POS (24U) +#define L1C_BMX_BUSY_OPTION_DIS_LEN (1U) +#define L1C_BMX_BUSY_OPTION_DIS_MSK (((1U << L1C_BMX_BUSY_OPTION_DIS_LEN) - 1) << L1C_BMX_BUSY_OPTION_DIS_POS) +#define L1C_BMX_BUSY_OPTION_DIS_UMSK (~(((1U << L1C_BMX_BUSY_OPTION_DIS_LEN) - 1) << L1C_BMX_BUSY_OPTION_DIS_POS)) +#define L1C_EARLY_RESP_DIS L1C_EARLY_RESP_DIS +#define L1C_EARLY_RESP_DIS_POS (25U) +#define L1C_EARLY_RESP_DIS_LEN (1U) +#define L1C_EARLY_RESP_DIS_MSK (((1U << L1C_EARLY_RESP_DIS_LEN) - 1) << L1C_EARLY_RESP_DIS_POS) +#define L1C_EARLY_RESP_DIS_UMSK (~(((1U << L1C_EARLY_RESP_DIS_LEN) - 1) << L1C_EARLY_RESP_DIS_POS)) +#define L1C_WRAP_DIS L1C_WRAP_DIS +#define L1C_WRAP_DIS_POS (26U) +#define L1C_WRAP_DIS_LEN (1U) +#define L1C_WRAP_DIS_MSK (((1U << L1C_WRAP_DIS_LEN) - 1) << L1C_WRAP_DIS_POS) +#define L1C_WRAP_DIS_UMSK (~(((1U << L1C_WRAP_DIS_LEN) - 1) << L1C_WRAP_DIS_POS)) + +/* 0x4 : hit_cnt_lsb */ +#define L1C_HIT_CNT_LSB_OFFSET (0x4) +#define L1C_HIT_CNT_LSB L1C_HIT_CNT_LSB +#define L1C_HIT_CNT_LSB_POS (0U) +#define L1C_HIT_CNT_LSB_LEN (32U) +#define L1C_HIT_CNT_LSB_MSK (((1U << L1C_HIT_CNT_LSB_LEN) - 1) << L1C_HIT_CNT_LSB_POS) +#define L1C_HIT_CNT_LSB_UMSK (~(((1U << L1C_HIT_CNT_LSB_LEN) - 1) << L1C_HIT_CNT_LSB_POS)) + +/* 0x8 : hit_cnt_msb */ +#define L1C_HIT_CNT_MSB_OFFSET (0x8) +#define L1C_HIT_CNT_MSB L1C_HIT_CNT_MSB +#define L1C_HIT_CNT_MSB_POS (0U) +#define L1C_HIT_CNT_MSB_LEN (32U) +#define L1C_HIT_CNT_MSB_MSK (((1U << L1C_HIT_CNT_MSB_LEN) - 1) << L1C_HIT_CNT_MSB_POS) +#define L1C_HIT_CNT_MSB_UMSK (~(((1U << L1C_HIT_CNT_MSB_LEN) - 1) << L1C_HIT_CNT_MSB_POS)) + +/* 0xC : miss_cnt */ +#define L1C_MISS_CNT_OFFSET (0xC) +#define L1C_MISS_CNT L1C_MISS_CNT +#define L1C_MISS_CNT_POS (0U) +#define L1C_MISS_CNT_LEN (32U) +#define L1C_MISS_CNT_MSK (((1U << L1C_MISS_CNT_LEN) - 1) << L1C_MISS_CNT_POS) +#define L1C_MISS_CNT_UMSK (~(((1U << L1C_MISS_CNT_LEN) - 1) << L1C_MISS_CNT_POS)) + +/* 0x10 : l1c_range */ +#define L1C_RANGE_OFFSET (0x10) + +/* 0x200 : l1c_bmx_err_addr_en */ +#define L1C_BMX_ERR_ADDR_EN_OFFSET (0x200) +#define L1C_BMX_ERR_ADDR_DIS L1C_BMX_ERR_ADDR_DIS +#define L1C_BMX_ERR_ADDR_DIS_POS (0U) +#define L1C_BMX_ERR_ADDR_DIS_LEN (1U) +#define L1C_BMX_ERR_ADDR_DIS_MSK (((1U << L1C_BMX_ERR_ADDR_DIS_LEN) - 1) << L1C_BMX_ERR_ADDR_DIS_POS) +#define L1C_BMX_ERR_ADDR_DIS_UMSK (~(((1U << L1C_BMX_ERR_ADDR_DIS_LEN) - 1) << L1C_BMX_ERR_ADDR_DIS_POS)) +#define L1C_BMX_ERR_DEC L1C_BMX_ERR_DEC +#define L1C_BMX_ERR_DEC_POS (4U) +#define L1C_BMX_ERR_DEC_LEN (1U) +#define L1C_BMX_ERR_DEC_MSK (((1U << L1C_BMX_ERR_DEC_LEN) - 1) << L1C_BMX_ERR_DEC_POS) +#define L1C_BMX_ERR_DEC_UMSK (~(((1U << L1C_BMX_ERR_DEC_LEN) - 1) << L1C_BMX_ERR_DEC_POS)) +#define L1C_BMX_ERR_TZ L1C_BMX_ERR_TZ +#define L1C_BMX_ERR_TZ_POS (5U) +#define L1C_BMX_ERR_TZ_LEN (1U) +#define L1C_BMX_ERR_TZ_MSK (((1U << L1C_BMX_ERR_TZ_LEN) - 1) << L1C_BMX_ERR_TZ_POS) +#define L1C_BMX_ERR_TZ_UMSK (~(((1U << L1C_BMX_ERR_TZ_LEN) - 1) << L1C_BMX_ERR_TZ_POS)) +#define L1C_HSEL_OPTION L1C_HSEL_OPTION +#define L1C_HSEL_OPTION_POS (16U) +#define L1C_HSEL_OPTION_LEN (4U) +#define L1C_HSEL_OPTION_MSK (((1U << L1C_HSEL_OPTION_LEN) - 1) << L1C_HSEL_OPTION_POS) +#define L1C_HSEL_OPTION_UMSK (~(((1U << L1C_HSEL_OPTION_LEN) - 1) << L1C_HSEL_OPTION_POS)) + +/* 0x204 : l1c_bmx_err_addr */ +#define L1C_BMX_ERR_ADDR_OFFSET (0x204) +#define L1C_BMX_ERR_ADDR L1C_BMX_ERR_ADDR +#define L1C_BMX_ERR_ADDR_POS (0U) +#define L1C_BMX_ERR_ADDR_LEN (32U) +#define L1C_BMX_ERR_ADDR_MSK (((1U << L1C_BMX_ERR_ADDR_LEN) - 1) << L1C_BMX_ERR_ADDR_POS) +#define L1C_BMX_ERR_ADDR_UMSK (~(((1U << L1C_BMX_ERR_ADDR_LEN) - 1) << L1C_BMX_ERR_ADDR_POS)) + +/* 0x208 : irom1_misr_dataout_0 */ +#define L1C_IROM1_MISR_DATAOUT_0_OFFSET (0x208) +#define L1C_IROM1_MISR_DATAOUT_0 L1C_IROM1_MISR_DATAOUT_0 +#define L1C_IROM1_MISR_DATAOUT_0_POS (0U) +#define L1C_IROM1_MISR_DATAOUT_0_LEN (32U) +#define L1C_IROM1_MISR_DATAOUT_0_MSK (((1U << L1C_IROM1_MISR_DATAOUT_0_LEN) - 1) << L1C_IROM1_MISR_DATAOUT_0_POS) +#define L1C_IROM1_MISR_DATAOUT_0_UMSK (~(((1U << L1C_IROM1_MISR_DATAOUT_0_LEN) - 1) << L1C_IROM1_MISR_DATAOUT_0_POS)) + +/* 0x20C : irom1_misr_dataout_1 */ +#define L1C_IROM1_MISR_DATAOUT_1_OFFSET (0x20C) + +/* 0x210 : cpu_clk_gate */ +#define L1C_CPU_CLK_GATE_OFFSET (0x210) +#define L1C_FORCE_E21_CLOCK_ON_0 L1C_FORCE_E21_CLOCK_ON_0 +#define L1C_FORCE_E21_CLOCK_ON_0_POS (0U) +#define L1C_FORCE_E21_CLOCK_ON_0_LEN (1U) +#define L1C_FORCE_E21_CLOCK_ON_0_MSK (((1U << L1C_FORCE_E21_CLOCK_ON_0_LEN) - 1) << L1C_FORCE_E21_CLOCK_ON_0_POS) +#define L1C_FORCE_E21_CLOCK_ON_0_UMSK (~(((1U << L1C_FORCE_E21_CLOCK_ON_0_LEN) - 1) << L1C_FORCE_E21_CLOCK_ON_0_POS)) +#define L1C_FORCE_E21_CLOCK_ON_1 L1C_FORCE_E21_CLOCK_ON_1 +#define L1C_FORCE_E21_CLOCK_ON_1_POS (1U) +#define L1C_FORCE_E21_CLOCK_ON_1_LEN (1U) +#define L1C_FORCE_E21_CLOCK_ON_1_MSK (((1U << L1C_FORCE_E21_CLOCK_ON_1_LEN) - 1) << L1C_FORCE_E21_CLOCK_ON_1_POS) +#define L1C_FORCE_E21_CLOCK_ON_1_UMSK (~(((1U << L1C_FORCE_E21_CLOCK_ON_1_LEN) - 1) << L1C_FORCE_E21_CLOCK_ON_1_POS)) +#define L1C_FORCE_E21_CLOCK_ON_2 L1C_FORCE_E21_CLOCK_ON_2 +#define L1C_FORCE_E21_CLOCK_ON_2_POS (2U) +#define L1C_FORCE_E21_CLOCK_ON_2_LEN (1U) +#define L1C_FORCE_E21_CLOCK_ON_2_MSK (((1U << L1C_FORCE_E21_CLOCK_ON_2_LEN) - 1) << L1C_FORCE_E21_CLOCK_ON_2_POS) +#define L1C_FORCE_E21_CLOCK_ON_2_UMSK (~(((1U << L1C_FORCE_E21_CLOCK_ON_2_LEN) - 1) << L1C_FORCE_E21_CLOCK_ON_2_POS)) + +struct l1c_reg { + /* 0x0 : l1c_config */ + union { + struct + { + uint32_t l1c_cacheable : 1; /* [ 0], r/w, 0x0 */ + uint32_t l1c_cnt_en : 1; /* [ 1], r/w, 0x0 */ + uint32_t l1c_invalid_en : 1; /* [ 2], r/w, 0x0 */ + uint32_t l1c_invalid_done : 1; /* [ 3], r, 0x0 */ + uint32_t reserved_4_7 : 4; /* [ 7: 4], rsvd, 0x0 */ + uint32_t l1c_way_dis : 4; /* [11: 8], r/w, 0xf */ + uint32_t irom_2t_access : 1; /* [ 12], r/w, 0x0 */ + uint32_t reserved_13 : 1; /* [ 13], rsvd, 0x0 */ + uint32_t l1c_bypass : 1; /* [ 14], r/w, 0x0 */ + uint32_t l1c_bmx_err_en : 1; /* [ 15], r/w, 0x0 */ + uint32_t l1c_bmx_arb_mode : 2; /* [17:16], r/w, 0x0 */ + uint32_t reserved_18_19 : 2; /* [19:18], rsvd, 0x0 */ + uint32_t l1c_bmx_timeout_en : 4; /* [23:20], r/w, 0x0 */ + uint32_t l1c_bmx_busy_option_dis : 1; /* [ 24], r/w, 0x0 */ + uint32_t early_resp_dis : 1; /* [ 25], r/w, 0x1 */ + uint32_t wrap_dis : 1; /* [ 26], r/w, 0x1 */ + uint32_t reserved_27_31 : 5; /* [31:27], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } l1c_config; + + /* 0x4 : hit_cnt_lsb */ + union { + struct + { + uint32_t hit_cnt_lsb : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } hit_cnt_lsb; + + /* 0x8 : hit_cnt_msb */ + union { + struct + { + uint32_t hit_cnt_msb : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } hit_cnt_msb; + + /* 0xC : miss_cnt */ + union { + struct + { + uint32_t miss_cnt : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } miss_cnt; + + /* 0x10 : l1c_range */ + union { + struct + { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } l1c_range; + + /* 0x14 reserved */ + uint8_t RESERVED0x14[492]; + + /* 0x200 : l1c_bmx_err_addr_en */ + union { + struct + { + uint32_t l1c_bmx_err_addr_dis : 1; /* [ 0], r/w, 0x0 */ + uint32_t reserved_1_3 : 3; /* [ 3: 1], rsvd, 0x0 */ + uint32_t l1c_bmx_err_dec : 1; /* [ 4], r, 0x0 */ + uint32_t l1c_bmx_err_tz : 1; /* [ 5], r, 0x0 */ + uint32_t reserved_6_15 : 10; /* [15: 6], rsvd, 0x0 */ + uint32_t l1c_hsel_option : 4; /* [19:16], r/w, 0x0 */ + uint32_t reserved_20_31 : 12; /* [31:20], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } l1c_bmx_err_addr_en; + + /* 0x204 : l1c_bmx_err_addr */ + union { + struct + { + uint32_t l1c_bmx_err_addr : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } l1c_bmx_err_addr; + + /* 0x208 : irom1_misr_dataout_0 */ + union { + struct + { + uint32_t irom1_misr_dataout_0 : 32; /* [31: 0], r, 0x0 */ + } BF; + uint32_t WORD; + } irom1_misr_dataout_0; + + /* 0x20C : irom1_misr_dataout_1 */ + union { + struct + { + uint32_t reserved_0_31 : 32; /* [31: 0], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } irom1_misr_dataout_1; + + /* 0x210 : cpu_clk_gate */ + union { + struct + { + uint32_t force_e21_clock_on_0 : 1; /* [ 0], r/w, 0x0 */ + uint32_t force_e21_clock_on_1 : 1; /* [ 1], r/w, 0x0 */ + uint32_t force_e21_clock_on_2 : 1; /* [ 2], r/w, 0x0 */ + uint32_t reserved_3_31 : 29; /* [31: 3], rsvd, 0x0 */ + } BF; + uint32_t WORD; + } cpu_clk_gate; +}; + +typedef volatile struct l1c_reg l1c_reg_t; + +#endif /* __L1C_REG_H__ */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_aon.c b/drivers/soc/bl602/bl602_std/src/bl602_aon.c new file mode 100644 index 00000000..3f148bd4 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_aon.c @@ -0,0 +1,551 @@ +/** + ****************************************************************************** + * @file bl602_aon.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl602_aon.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup AON + * @{ + */ + +/** @defgroup AON_Private_Macros + * @{ + */ +#define AON_CLK_SET_DUMMY_WAIT \ + { \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + } + +/*@} end of group AON_Private_Macros */ + +/** @defgroup AON_Private_Types + * @{ + */ + +/*@} end of group AON_Private_Types */ + +/** @defgroup AON_Private_Variables + * @{ + */ + +/*@} end of group AON_Private_Variables */ + +/** @defgroup AON_Global_Variables + * @{ + */ + +/*@} end of group AON_Global_Variables */ + +/** @defgroup AON_Private_Fun_Declaration + * @{ + */ + +/*@} end of group AON_Private_Fun_Declaration */ + +/** @defgroup AON_Private_Functions + * @{ + */ + +/*@} end of group AON_Private_Functions */ + +/** @defgroup AON_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Power on MXX band gap + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION AON_Power_On_MBG(void) +{ + uint32_t tmpVal = 0; + + /* Power up RF for PLL to work */ + tmpVal = BL_RD_REG(AON_BASE, AON_RF_TOP_AON); + tmpVal = BL_SET_REG_BIT(tmpVal, AON_PU_MBG_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + BL602_Delay_US(55); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power off MXX band gap + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION AON_Power_Off_MBG(void) +{ + uint32_t tmpVal = 0; + + /* Power OFF */ + tmpVal = BL_RD_REG(AON_BASE, AON_RF_TOP_AON); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_PU_MBG_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power on XTAL + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION AON_Power_On_XTAL(void) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + + tmpVal = BL_RD_REG(AON_BASE, AON_RF_TOP_AON); + tmpVal = BL_SET_REG_BIT(tmpVal, AON_PU_XTAL_AON); + tmpVal = BL_SET_REG_BIT(tmpVal, AON_PU_XTAL_BUF_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + /* Polling for ready */ + do { + BL602_Delay_US(10); + timeOut++; + tmpVal = BL_RD_REG(AON_BASE, AON_TSEN); + } while (!BL_IS_REG_BIT_SET(tmpVal, AON_XTAL_RDY) && timeOut < 120); + + if (timeOut >= 120) { + return TIMEOUT; + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Set XTAL cap code + * + * @param capIn: Cap code in + * @param capOut: Cap code out + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION AON_Set_Xtal_CapCode(uint8_t capIn, uint8_t capOut) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(AON_BASE, AON_XTAL_CFG); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_XTAL_CAPCODE_IN_AON, capIn); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_XTAL_CAPCODE_OUT_AON, capOut); + BL_WR_REG(AON_BASE, AON_XTAL_CFG, tmpVal); + + BL602_Delay_US(100); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Get XTAL cap code + * + * @param None + * + * @return Cap code + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +uint8_t ATTR_CLOCK_SECTION AON_Get_Xtal_CapCode(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(AON_BASE, AON_XTAL_CFG); + + return BL_GET_REG_BITS_VAL(tmpVal, AON_XTAL_CAPCODE_IN_AON); +} +#endif + +/****************************************************************************/ /** + * @brief Power off XTAL + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION AON_Power_Off_XTAL(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(AON_BASE, AON_RF_TOP_AON); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_PU_XTAL_AON); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_PU_XTAL_BUF_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power on bandgap system + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION AON_Power_On_BG(void) +{ + uint32_t tmpVal = 0; + + /* power up RF for PLL to work */ + tmpVal = BL_RD_REG(AON_BASE, AON_BG_SYS_TOP); + tmpVal = BL_SET_REG_BIT(tmpVal, AON_PU_BG_SYS_AON); + BL_WR_REG(AON_BASE, AON_BG_SYS_TOP, tmpVal); + + BL602_Delay_US(55); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power off bandgap system + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION AON_Power_Off_BG(void) +{ + uint32_t tmpVal = 0; + + /* power up RF for PLL to work */ + tmpVal = BL_RD_REG(AON_BASE, AON_BG_SYS_TOP); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_PU_BG_SYS_AON); + BL_WR_REG(AON_BASE, AON_BG_SYS_TOP, tmpVal); + + BL602_Delay_US(55); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power on LDO11 + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION AON_Power_On_LDO11_SOC(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(AON_BASE, AON_LDO11SOC_AND_DCTEST); + tmpVal = BL_SET_REG_BIT(tmpVal, AON_PU_LDO11SOC_AON); + BL_WR_REG(AON_BASE, AON_LDO11SOC_AND_DCTEST, tmpVal); + + BL602_Delay_US(55); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power off LDO11 + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION AON_Power_Off_LDO11_SOC(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(AON_BASE, AON_LDO11SOC_AND_DCTEST); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_PU_LDO11SOC_AON); + BL_WR_REG(AON_BASE, AON_LDO11SOC_AND_DCTEST, tmpVal); + + BL602_Delay_US(55); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power on LDO15_RF + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION AON_Power_On_LDO15_RF(void) +{ + uint32_t tmpVal = 0; + + /* ldo15rf power on */ + tmpVal = BL_RD_REG(AON_BASE, AON_RF_TOP_AON); + tmpVal = BL_SET_REG_BIT(tmpVal, AON_PU_LDO15RF_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + BL602_Delay_US(90); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power off LDO15_RF + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION AON_Power_Off_LDO15_RF(void) +{ + uint32_t tmpVal = 0; + + /* ldo15rf power off */ + tmpVal = BL_RD_REG(AON_BASE, AON_RF_TOP_AON); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_PU_LDO15RF_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief power on source follow regular + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION AON_Power_On_SFReg(void) +{ + uint32_t tmpVal = 0; + + /* power on sfreg */ + tmpVal = BL_RD_REG(AON_BASE, AON_RF_TOP_AON); + tmpVal = BL_SET_REG_BIT(tmpVal, AON_PU_SFREG_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + BL602_Delay_US(10); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief power off source follow regular + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION AON_Power_Off_SFReg(void) +{ + uint32_t tmpVal = 0; + + /* power off sfreg */ + tmpVal = BL_RD_REG(AON_BASE, AON_RF_TOP_AON); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_PU_SFREG_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power off the power can be shut down in PDS0 + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION AON_LowPower_Enter_PDS0(void) +{ + uint32_t tmpVal = 0; + + /* power off sfreg */ + tmpVal = BL_RD_REG(AON_BASE, AON_MISC); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_SW_WB_EN_AON); + BL_WR_REG(AON_BASE, AON_MISC, tmpVal); + + tmpVal = BL_RD_REG(AON_BASE, AON_RF_TOP_AON); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_PU_SFREG_AON); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_PU_LDO15RF_AON); + tmpVal = BL_CLR_REG_BIT(tmpVal, AON_PU_MBG_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + /* gating Clock */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_CGEN_CFG0); + tmpVal = tmpVal & (~(1 << 6)); + tmpVal = tmpVal & (~(1 << 7)); + BL_WR_REG(GLB_BASE, GLB_CGEN_CFG0, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power on the power powered down in PDS0 + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION AON_LowPower_Exit_PDS0(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(AON_BASE, AON_RF_TOP_AON); + + tmpVal = BL_SET_REG_BIT(tmpVal, AON_PU_MBG_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + BL602_Delay_US(20); + + tmpVal = BL_SET_REG_BIT(tmpVal, AON_PU_LDO15RF_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + BL602_Delay_US(60); + + tmpVal = BL_SET_REG_BIT(tmpVal, AON_PU_SFREG_AON); + BL_WR_REG(AON_BASE, AON_RF_TOP_AON, tmpVal); + + BL602_Delay_US(20); + + /* power on wb */ + tmpVal = BL_RD_REG(AON_BASE, AON_MISC); + tmpVal = BL_SET_REG_BIT(tmpVal, AON_SW_WB_EN_AON); + BL_WR_REG(AON_BASE, AON_MISC, tmpVal); + + /* ungating Clock */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_CGEN_CFG0); + tmpVal = tmpVal | ((1 << 6)); + tmpVal = tmpVal | ((1 << 7)); + BL_WR_REG(GLB_BASE, GLB_CGEN_CFG0, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power on the power powered down in PDS0 + * + * @param delay: None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION AON_Set_LDO11_SOC_Sstart_Delay(uint8_t delay) +{ + uint32_t tmpVal = 0; + + CHECK_PARAM((delay <= 0x3)); + + /* config ldo11soc_sstart_delay_aon */ + tmpVal = BL_RD_REG(AON_BASE, AON_LDO11SOC_AND_DCTEST); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, AON_LDO11SOC_SSTART_DELAY_AON, delay); + BL_WR_REG(AON_BASE, AON_LDO11SOC_AND_DCTEST, tmpVal); + + return SUCCESS; +} + +/*@} end of group AON_Public_Functions */ + +/*@} end of group AON */ + +/*@} end of group BL602_Peripheral_Driver */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_common.c b/drivers/soc/bl602/bl602_std/src/bl602_common.c new file mode 100644 index 00000000..473b30f8 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_common.c @@ -0,0 +1,162 @@ +#include "l1c_reg.h" +#include "bl602_common.h" + +/** @addtogroup BL602_Periph_Driver + * @{ + */ + +/****************************************************************************/ /** + * @brief delay us + * + * @param[in] core: systemcoreclock + * + * @param[in] cnt: delay cnt us + * + * @return none + * + *******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +#ifdef ARCH_ARM +#ifndef __GNUC__ +__WEAK +__ASM void ATTR_TCM_SECTION ASM_Delay_Us(uint32_t core, uint32_t cnt) +{ + lsrs r0, #0x10 muls r0, r1, r0 mov r2, r0 lsrs r2, #0x04 lsrs r2, #0x03 cmp r2, #0x01 beq end cmp r2, #0x00 beq end loop mov r0, r0 mov r0, r0 mov r0, r0 mov r0, r0 mov r0, r0 subs r2, r2, #0x01 cmp r2, #0x00 bne loop end bx lr +} +#else +__WEAK +void ATTR_TCM_SECTION ASM_Delay_Us(uint32_t core, uint32_t cnt) +{ + __asm__ __volatile__( + "lsr r0,#0x10\n\t" + "mul r0,r1,r0\n\t" + "mov r2,r0\n\t" + "lsr r2,#0x04\n\t" + "lsr r2,#0x03\n\t" + "cmp r2,#0x01\n\t" + "beq end\n\t" + "cmp r2,#0x00\n\t" + "beq end\n" + "loop :" + "mov r0,r0\n\t" + "mov r0,r0\n\t" + "mov r0,r0\n\t" + "mov r0,r0\n\t" + "mov r0,r0\n\t" + "sub r2,r2,#0x01\n\t" + "cmp r2,#0x00\n\t" + "bne loop\n" + "end :" + "mov r0,r0\n\t"); +} +#endif +#endif +#ifdef ARCH_RISCV +__WEAK +void ATTR_TCM_SECTION ASM_Delay_Us(uint32_t core, uint32_t cnt) +{ + uint32_t codeAddress = 0; + uint32_t divVal = 40; + + codeAddress = (uint32_t)&ASM_Delay_Us; + + /* 1M=100K*10, so multiple is 10 */ + /* loop function take 4 instructions, so instructionNum is 4 */ + /* if codeAddress locate at IROM space and irom_2t_access is 1, then irom2TAccess=2, else irom2TAccess=1 */ + /* divVal = multiple*instructionNum*irom2TAccess */ + if (((codeAddress & (0xF << 24)) >> 24) == 0x01) { + /* IROM space */ + if (BL_GET_REG_BITS_VAL(BL_RD_REG(L1C_BASE, L1C_CONFIG), L1C_IROM_2T_ACCESS)) { + /* instruction 2T */ + divVal = 80; + } + } + + __asm__ __volatile__( + ".align 4\n\t" + "lw a4,%1\n\t" + "lui a5,0x18\n\t" + "addi a5,a5,1696\n\t" + "divu a5,a4,a5\n\t" + "sw a5,%1\n\t" + "lw a4,%1\n\t" + "lw a5,%0\n\t" + "mul a5,a4,a5\n\t" + "sw a5,%1\n\t" + "lw a4,%1\n\t" + "lw a5,%2\n\t" + "divu a5,a4,a5\n\t" + "sw a5,%1\n\t" + "lw a5,%1\n\t" + "li a4,0x1\n\t" + "beq a5,zero,end\n\t" + "beq a5,a4,end\n\t" + "nop\n\t" + "nop\n\t" + ".align 4\n\t" + "loop :\n" + "addi a4,a5,-1\n\t" + "mv a5,a4\n\t" + "bnez a5,loop\n\t" + "nop\n\t" + "end :\n\t" + "nop\n" + : /* output */ + : "m"(cnt), "m"(core), "m"(divVal) /* input */ + : "t1", "a4", "a5" /* destruct description */ + ); +} +#endif + +/****************************************************************************/ /** + * @brief delay us + * + * @param[in] cnt: delay cnt us + * + * @return none + * + *******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION BL602_Delay_US(uint32_t cnt) +{ + ASM_Delay_Us(SystemCoreClockGet(), cnt); +} + +/****************************************************************************/ /** + * @brief delay ms + * + * @param[in] cnt: delay cnt ms + * + * @return none + * + *******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION BL602_Delay_MS(uint32_t cnt) +{ + uint32_t i = 0; + uint32_t count = 0; + + if (cnt >= 1024) { + /* delay (n*1024) ms */ + count = 1024; + + for (i = 0; i < (cnt / 1024); i++) { + BL602_Delay_US(1024 * 1000); + } + } + + if (cnt & 0x3FF) { + /* delay (1-1023)ms */ + count = cnt & 0x3FF; + BL602_Delay_US(count * 1000); + } + + //BL602_Delay_US((count<<10)-(count<<4)-(count<<3)); +} +#endif + +/*@} end of group DRIVER_Public_Functions */ + +/*@} end of group DRIVER_COMMON */ + +/*@} end of group BL602_Periph_Driver */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_ef_ctrl.c b/drivers/soc/bl602/bl602_std/src/bl602_ef_ctrl.c new file mode 100644 index 00000000..f08b5fc5 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_ef_ctrl.c @@ -0,0 +1,1872 @@ +/** + ****************************************************************************** + * @file bl602_sec_ef_ctrl.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "string.h" +#include "bl602_ef_ctrl.h" +#include "ef_data_0_reg.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup SEC_EF_CTRL + * @{ + */ + +/** @defgroup SEC_EF_CTRL_Private_Macros + * @{ + */ +#define EF_CTRL_EFUSE_CYCLE_PROTECT (0xbf << 24) +#define EF_CTRL_EFUSE_CTRL_PROTECT (0xbf << 8) +#define EF_CTRL_DFT_TIMEOUT_VAL (160 * 1000) +#ifndef BOOTROM +#define EF_CTRL_LOAD_BEFORE_READ_R0 EF_Ctrl_Load_Efuse_R0() +#else +#define EF_CTRL_LOAD_BEFORE_READ_R0 +#endif +#define EF_CTRL_DATA0_CLEAR EF_Ctrl_Clear(0, EF_CTRL_EFUSE_R0_SIZE / 4) + +/*@} end of group SEC_EF_CTRL_Private_Macros */ + +/** @defgroup SEC_EF_CTRL_Private_Types + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Private_Types */ + +/** @defgroup SEC_EF_CTRL_Private_Variables + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Private_Variables */ + +/** @defgroup SEC_EF_CTRL_Global_Variables + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Global_Variables */ + +/** @defgroup SEC_EF_CTRL_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SEC_EF_CTRL_Private_Fun_Declaration */ + +/** @defgroup SEC_EF_CTRL_Private_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Switch efuse region 0 control to AHB clock + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION EF_Ctrl_Sw_AHB_Clk_0(void) +{ + uint32_t tmpVal; + uint32_t timeout = EF_CTRL_DFT_TIMEOUT_VAL; + + while (EF_Ctrl_Busy() == SET) { + timeout--; + + if (timeout == 0) { + break; + } + } + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (EF_CTRL_SAHB_CLK << EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Program efuse region 0 + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION EF_Ctrl_Program_Efuse_0(void) +{ + uint32_t tmpVal; + + /* Select auto mode and select ef clock */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (EF_CTRL_EF_CLK << EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + /* Program */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (EF_CTRL_EF_CLK << EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (1 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (1 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + /* Add delay for POR to be stable */ + BL602_Delay_US(4); + + /* Trigger */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (EF_CTRL_EF_CLK << EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (1 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (1 << EF_CTRL_EF_IF_0_RW_POS) | + (1 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); +} +#endif + +/*@} end of group SEC_EF_CTRL_Private_Functions */ + +/** @defgroup SEC_EF_CTRL_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Load efuse region 0 + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION EF_Ctrl_Load_Efuse_R0(void) +{ + uint32_t tmpVal; + uint32_t timeout = EF_CTRL_DFT_TIMEOUT_VAL; + + EF_CTRL_DATA0_CLEAR; + + /* Trigger read */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (EF_CTRL_EF_CLK << EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (EF_CTRL_EF_CLK << EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (1 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); + + BL602_Delay_US(10); + + /* Wait for efuse control idle*/ + do { + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0); + timeout--; + + if (timeout == 0) { + break; + } + } while (BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_IF_0_BUSY) || + + (!BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_IF_0_AUTOLOAD_DONE))); + + /* Switch to AHB clock */ + tmpVal = (EF_CTRL_EFUSE_CTRL_PROTECT) | + (EF_CTRL_OP_MODE_AUTO << EF_CTRL_EF_IF_0_MANUAL_EN_POS) | + (EF_CTRL_PARA_DFT << EF_CTRL_EF_IF_0_CYC_MODIFY_POS) | + (EF_CTRL_SAHB_CLK << EF_CTRL_EF_CLK_SAHB_DATA_SEL_POS) | + (1 << EF_CTRL_EF_IF_AUTO_RD_EN_POS) | + (0 << EF_CTRL_EF_IF_POR_DIG_POS) | + (1 << EF_CTRL_EF_IF_0_INT_CLR_POS) | + (0 << EF_CTRL_EF_IF_0_RW_POS) | + (0 << EF_CTRL_EF_IF_0_TRIG_POS); + BL_WR_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Check efuse busy status + * + * @param None + * + * @return SET or RESET + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Sts_Type ATTR_TCM_SECTION EF_Ctrl_Busy(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0); + + if (BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_IF_0_BUSY)) { + return SET; + } + + return RESET; +} +#endif + +/****************************************************************************/ /** + * @brief Check efuse whether finish loading + * + * @param None + * + * @return SET or RESET + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Sts_Type ATTR_TCM_SECTION EF_Ctrl_AutoLoad_Done(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_CTRL_BASE, EF_CTRL_EF_IF_CTRL_0); + + if (BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_IF_0_AUTOLOAD_DONE)) { + return SET; + } else { + return RESET; + } +} +#endif + +/****************************************************************************/ /** + * @brief Efuse write debug password + * + * @param passWdLow: password low 32 bits + * @param passWdHigh: password high 32 bits + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_Dbg_Pwd(uint32_t passWdLow, uint32_t passWdHigh, uint8_t program) +{ + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_LOW, passWdLow); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH, passWdHigh); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read debug password + * + * @param passWdLow: password low 32 bits pointer to store value + * @param passWdHigh: password high 32 bits pointer to store value + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Dbg_Pwd(uint32_t *passWdLow, uint32_t *passWdHigh) +{ + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + *passWdLow = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_LOW); + *passWdHigh = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH); +} + +/****************************************************************************/ /** + * @brief Efuse lock reading for passwd + * + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Readlock_Dbg_Pwd(uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_RD_LOCK_DBG_PWD); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read LDO11 Vout sel trim + * + * @param Ldo11VoutSelValue: Ldo11VoutSelValue + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_Ldo11VoutSel_Opt(uint8_t *Ldo11VoutSelValue) +{ + uint32_t tmp; + Efuse_Ldo11VoutSelTrim_Info_Type *trim = (Efuse_Ldo11VoutSelTrim_Info_Type *)&tmp; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmp = (BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH)) >> 23; + + if (tmp & 0x01) { + tmp = (BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_3_W3)) >> 7; + + } else { + tmp = (BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_4_W3)) >> 7; + } + if (trim->en) { + if (trim->parity == EF_Ctrl_Get_Trim_Parity(trim->sel_value, 4)) { + *Ldo11VoutSelValue = trim->sel_value; + return SUCCESS; + } + } + return ERROR; +} + +/****************************************************************************/ /** + * @brief Efuse read LDO11 Vout sel trim + * + * @param TxPower: TxPower + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_TxPower_ATE(int8_t *TxPower) +{ + uint32_t tmp; + Efuse_TxPower_Info_Type *trim = (Efuse_TxPower_Info_Type *)&tmp; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmp = (BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH)) >> 23; + if (tmp & 0x01) { + tmp = (BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_3_W3)) >> 0; + } else { + tmp = (BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_4_W3)) >> 0; + } + //if(trim->en){ + if ((tmp >> 17) & 0x01) { //old en bit will be no longer used, now use bit17 as en bit + if (trim->parity == EF_Ctrl_Get_Trim_Parity(trim->txpower, 5)) { + if (trim->txpower >= 16) { + *TxPower = trim->txpower - 32; + } else { + *TxPower = trim->txpower; + } + + return SUCCESS; + } + } + return ERROR; +} + +/****************************************************************************/ /** + * @brief Efuse lock writing for passwd + * + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Writelock_Dbg_Pwd(uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_WR_LOCK_DBG_PWD); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read security configuration + * + * @param cfg: security configuration pointer + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_Secure_Cfg(EF_Ctrl_Sec_Param_Type *cfg, uint8_t program) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_DBG_MODE, cfg->ef_dbg_mode); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_DBG_JTAG_0_DIS, cfg->ef_dbg_jtag_0_dis); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SBOOT_EN, cfg->ef_sboot_en); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read security configuration + * + * @param cfg: security configuration pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Secure_Cfg(EF_Ctrl_Sec_Param_Type *cfg) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + + cfg->ef_dbg_mode = (EF_Ctrl_Dbg_Mode_Type)BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_DBG_MODE); + cfg->ef_dbg_jtag_0_dis = BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_DBG_JTAG_0_DIS); + cfg->ef_sboot_en = BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SBOOT_EN); + cfg->ef_no_hd_boot_en = BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_NO_HD_BOOT_EN); +} + +/****************************************************************************/ /** + * @brief Efuse write security boot configuration + * + * @param sign[1]: Sign configuration pointer + * @param aes[1]: AES configuration pointer + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_Secure_Boot(EF_Ctrl_Sign_Type sign[1], EF_Ctrl_SF_AES_Type aes[1], uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SBOOT_SIGN_MODE, sign[0]); + + if (aes[0] != EF_CTRL_SF_AES_NONE) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SF_AES_MODE, aes[0]); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_CPU0_ENC_EN, 1); + } + + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse write security boot configuration + * + * @param sign[1]: Sign configuration pointer + * @param aes[1]: AES configuration pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Secure_Boot(EF_Ctrl_Sign_Type sign[1], EF_Ctrl_SF_AES_Type aes[1]) +{ + uint32_t tmpVal; + uint32_t tmpVal2; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + + tmpVal2 = BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SBOOT_SIGN_MODE); + sign[0] = (EF_Ctrl_Sign_Type)(tmpVal2 & 0x01); + + tmpVal2 = BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_CPU0_ENC_EN); + + if (tmpVal2) { + aes[0] = (EF_Ctrl_SF_AES_Type)BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_SF_AES_MODE); + } else { + aes[0] = EF_CTRL_SF_AES_NONE; + } +} + +/****************************************************************************/ /** + * @brief Get whether do RC32K and RC32M trim + * + * @param None + * + * @return 1 for enable trim RC32M and RC32K, 0 for not + * +*******************************************************************************/ +uint8_t EF_Ctrl_Get_Trim_Enable(void) +{ + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + + return BL_GET_REG_BITS_VAL(tmpVal, EF_DATA_0_EF_TRIM_EN); +} + +/****************************************************************************/ /** + * @brief Analog Trim parity calculate + * + * @param val: Value of efuse trim data + * @param len: Length of bit to calculate + * + * @return Parity bit value + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +uint8_t ATTR_CLOCK_SECTION EF_Ctrl_Get_Trim_Parity(uint32_t val, uint8_t len) +{ + uint8_t cnt = 0; + uint8_t i = 0; + + for (i = 0; i < len; i++) { + if (val & (1 << i)) { + cnt++; + } + } + + return cnt & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief Efuse write analog trim + * + * @param index: index of analog trim + * @param trim: trim value + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_Ana_Trim(uint32_t index, uint32_t trim, uint8_t program) +{ + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (index == 0) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0, trim); + } + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read analog trim + * + * @param index: index of analog trim + * @param trim: trim value + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Ana_Trim(uint32_t index, uint32_t *trim) +{ + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + if (index == 0) { + *trim = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + } +} + +/****************************************************************************/ /** + * @brief Efuse read RC32M trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_CLOCK_SECTION EF_Ctrl_Read_RC32M_Trim(Efuse_Ana_RC32M_Trim_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + trim->trimRc32mCodeFrExt = (tmpVal >> 10) & 0xff; + trim->trimRc32mCodeFrExtParity = (tmpVal >> 18) & 0x01; + trim->trimRc32mExtCodeEn = (tmpVal >> 19) & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief Efuse read RC32K trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_CLOCK_SECTION EF_Ctrl_Read_RC32K_Trim(Efuse_Ana_RC32K_Trim_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + trim->trimRc32kCodeFrExt = (tmpVal >> 20) & 0x3ff; + trim->trimRc32kCodeFrExtParity = (tmpVal >> 30) & 0x01; + trim->trimRc32kExtCodeEn = (tmpVal >> 31) & 0x01; +} +#endif + +/****************************************************************************/ /** + * @brief Efuse read TSEN trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void ATTR_CLOCK_SECTION EF_Ctrl_Read_TSEN_Trim(Efuse_TSEN_Refcode_Corner_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W3); + trim->tsenRefcodeCornerEn = tmpVal & 0x01; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + trim->tsenRefcodeCorner = tmpVal & 0xfff; + trim->tsenRefcodeCornerParity = (tmpVal >> 12) & 0x01; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W1); + trim->tsenRefcodeCornerVersion = (tmpVal >> 30) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse read ADC Gain trim + * + * @param trim: Trim data pointer + * + * @return None + * +*******************************************************************************/ +void ATTR_CLOCK_SECTION EF_Ctrl_Read_ADC_Gain_Trim(Efuse_ADC_Gain_Coeff_Type *trim) +{ + uint32_t tmpVal = 0; + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W3); + trim->adcGainCoeff = (tmpVal >> 1) & 0xfff; + trim->adcGainCoeffParity = (tmpVal >> 13) & 0x01; + trim->adcGainCoeffEn = (tmpVal >> 14) & 0x01; +} + +/****************************************************************************/ /** + * @brief Efuse write software usage + * + * @param index: index of software usage + * @param usage: usage value + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_Sw_Usage(uint32_t index, uint32_t usage, uint8_t program) +{ + /* switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (index == 0) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_0, usage); + } + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read software usage + * + * @param index: index of software usage + * @param usage: usage value + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Sw_Usage(uint32_t index, uint32_t *usage) +{ + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + if (index == 0) { + *usage = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_SW_USAGE_0); + } +} + +/****************************************************************************/ /** + * @brief Efuse read software usage + * + * @param index: index of software usage + * @param program: usage value + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Writelock_Sw_Usage(uint32_t index, uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + + if (index == 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_WR_LOCK_SW_USAGE_0); + } + + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse write MAC address + * + * @param mac[6]: MAC address buffer + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_MAC_Address(uint8_t mac[6], uint8_t program) +{ + uint8_t *maclow = (uint8_t *)mac; + uint8_t *machigh = (uint8_t *)(mac + 4); + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + /* The low 32 bits */ + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW, BL_RDWD_FRM_BYTEP(maclow)); + /* The high 16 bits */ + tmpVal = machigh[0] + (machigh[1] << 8); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse Ctrl get zero bit count + * + * @param val: Value to count + * + * @return Zero bit count + * +*******************************************************************************/ +static uint32_t EF_Ctrl_Get_Byte_Zero_Cnt(uint8_t val) +{ + uint32_t cnt = 0; + uint32_t i = 0; + + for (i = 0; i < 8; i++) { + if ((val & (1 << i)) == 0) { + cnt += 1; + } + } + + return cnt; +} + +/****************************************************************************/ /** + * @brief Efuse read MAC address + * + * @param mac[6]: MAC address buffer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_MAC_Address(uint8_t mac[6]) +{ + uint8_t *maclow = (uint8_t *)mac; + uint8_t *machigh = (uint8_t *)(mac + 4); + uint32_t tmpVal; + uint32_t i = 0; + uint32_t cnt = 0; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW); + BL_WRWD_TO_BYTEP(maclow, tmpVal); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH); + machigh[0] = tmpVal & 0xff; + machigh[1] = (tmpVal >> 8) & 0xff; + + /* Check parity */ + for (i = 0; i < 6; i++) { + cnt += EF_Ctrl_Get_Byte_Zero_Cnt(mac[i]); + } + + if ((cnt & 0x3f) == ((tmpVal >> 16) & 0x3f)) { + /* Change to network order */ + for (i = 0; i < 3; i++) { + tmpVal = mac[i]; + mac[i] = mac[5 - i]; + mac[5 - i] = tmpVal; + } + + return SUCCESS; + } else { + return ERROR; + } +} + +/****************************************************************************/ /** + * @brief Efuse read MAC address + * + * @param mac[7]: MAC address buffer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_MAC_Address_Raw(uint8_t mac[7]) +{ + uint8_t *maclow = (uint8_t *)mac; + uint8_t *machigh = (uint8_t *)(mac + 4); + uint32_t tmpVal; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW); + BL_WRWD_TO_BYTEP(maclow, tmpVal); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH); + machigh[0] = tmpVal & 0xff; + machigh[1] = (tmpVal >> 8) & 0xff; + machigh[2] = (tmpVal >> 16) & 0xff; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Efuse lock writing for MAC address + * + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Writelock_MAC_Address(uint8_t program) +{ + uint32_t tmpVal; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_DATA_0_WR_LOCK_WIFI_MAC); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Whether a value bits is all zero + * + * @param val: value to check + * @param start: start bit + * @param len: total length of bits to check + * + * @return 1 for all bits zero 0 for others + * +*******************************************************************************/ +uint8_t EF_Ctrl_Is_All_Bits_Zero(uint32_t val, uint8_t start, uint8_t len) +{ + uint32_t mask = 0; + + val = (val >> start); + + if (len >= 32) { + mask = 0xffffffff; + } else { + mask = (1 << len) - 1; + } + + if ((val & mask) == 0) { + return 1; + } else { + return 0; + } +} + +/****************************************************************************/ /** + * @brief Whether MAC address slot is empty + * + * @param slot: MAC address slot + * @param reload: whether reload to check + * + * @return 0 for all slots full,1 for others + * +*******************************************************************************/ +uint8_t EF_Ctrl_Is_MAC_Address_Slot_Empty(uint8_t slot, uint8_t reload) +{ + uint32_t tmp1 = 0xffffffff, tmp2 = 0xffffffff; + uint32_t part1Empty = 0, part2Empty = 0; + + if (slot == 0) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW); + tmp2 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH); + } else if (slot == 1) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W0); + tmp2 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W1); + } else if (slot == 2) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_LOW); + tmp2 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH); + } + + part1Empty = (EF_Ctrl_Is_All_Bits_Zero(tmp1, 0, 32)); + part2Empty = (EF_Ctrl_Is_All_Bits_Zero(tmp2, 0, 22)); + + return (part1Empty && part2Empty); +} + +/****************************************************************************/ /** + * @brief Efuse write optional MAC address + * + * @param slot: MAC address slot + * @param mac[6]: MAC address buffer + * @param program: Whether program + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Write_MAC_Address_Opt(uint8_t slot, uint8_t mac[6], uint8_t program) +{ + uint8_t *maclow = (uint8_t *)mac; + uint8_t *machigh = (uint8_t *)(mac + 4); + uint32_t tmpVal; + uint32_t i = 0, cnt; + + if (slot >= 3) { + return ERROR; + } + + /* Change to local order */ + for (i = 0; i < 3; i++) { + tmpVal = mac[i]; + mac[i] = mac[5 - i]; + mac[5 - i] = tmpVal; + } + + if (slot == 2) { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + } else { + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + } + + /* The low 32 bits */ + if (slot == 0) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW, BL_RDWD_FRM_BYTEP(maclow)); + } else if (slot == 1) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W0, BL_RDWD_FRM_BYTEP(maclow)); + } else if (slot == 2) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_LOW, BL_RDWD_FRM_BYTEP(maclow)); + } + + /* The high 16 bits */ + tmpVal = machigh[0] + (machigh[1] << 8); + cnt = 0; + + for (i = 0; i < 6; i++) { + cnt += EF_Ctrl_Get_Byte_Zero_Cnt(mac[i]); + } + + tmpVal |= ((cnt & 0x3f) << 16); + + if (slot == 0) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH, tmpVal); + } else if (slot == 1) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W1, tmpVal); + } else if (slot == 2) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH, tmpVal); + } + + if (program) { + if (slot == 2) { + EF_Ctrl_Program_Efuse_0(); + } else { + EF_Ctrl_Program_Efuse_0(); + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Efuse read optional MAC address + * + * @param slot: MAC address slot + * @param mac[6]: MAC address buffer + * @param reload: Whether reload + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_MAC_Address_Opt(uint8_t slot, uint8_t mac[6], uint8_t reload) +{ + uint8_t *maclow = (uint8_t *)mac; + uint8_t *machigh = (uint8_t *)(mac + 4); + uint32_t tmpVal = 0; + uint32_t i = 0; + uint32_t cnt = 0; + + if (slot >= 3) { + return ERROR; + } + + /* Trigger read data from efuse */ + if (reload) { + if (slot == 2) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } else { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + } + + if (slot == 0) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_LOW); + } else if (slot == 1) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W0); + } else if (slot == 2) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_LOW); + } + + BL_WRWD_TO_BYTEP(maclow, tmpVal); + + if (slot == 0) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH); + } else if (slot == 1) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W1); + } else if (slot == 2) { + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH); + } + + machigh[0] = tmpVal & 0xff; + machigh[1] = (tmpVal >> 8) & 0xff; + + /* Check parity */ + for (i = 0; i < 6; i++) { + cnt += EF_Ctrl_Get_Byte_Zero_Cnt(mac[i]); + } + + if ((cnt & 0x3f) == ((tmpVal >> 16) & 0x3f)) { + /* Change to network order */ + for (i = 0; i < 3; i++) { + tmpVal = mac[i]; + mac[i] = mac[5 - i]; + mac[5 - i] = tmpVal; + } + + return SUCCESS; + } else { + return ERROR; + } +} + +/****************************************************************************/ /** + * @brief Efuse read chip ID + * + * @param chipID[8]: Chip ID buffer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_Chip_ID(uint8_t chipID[8]) +{ + chipID[6] = 0; + chipID[7] = 0; + return EF_Ctrl_Read_MAC_Address(chipID); +} + +/****************************************************************************/ /** + * @brief Efuse read device info + * + * @param deviceInfo: Device info pointer + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Device_Info(Efuse_Device_Info_Type *deviceInfo) +{ + uint32_t tmpVal; + uint32_t *p = (uint32_t *)deviceInfo; + + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_WIFI_MAC_HIGH); + *p = tmpVal; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_CFG_0); + deviceInfo->chip_ver = (tmpVal >> 8) & 0x07; +} + +/****************************************************************************/ /** + * @brief Whether Capcode slot is empty + * + * @param slot: Cap code slot + * @param reload: Whether reload + * + * @return 0 for all slots full,1 for others + * +*******************************************************************************/ +uint8_t EF_Ctrl_Is_CapCode_Slot_Empty(uint8_t slot, uint8_t reload) +{ + uint32_t tmp = 0xffffffff; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + if (slot == 0) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + return (EF_Ctrl_Is_All_Bits_Zero(tmp, 2, 8)); + } else if (slot == 1) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W1); + return (EF_Ctrl_Is_All_Bits_Zero(tmp, 22, 8)); + } else if (slot == 2) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH); + return (EF_Ctrl_Is_All_Bits_Zero(tmp, 22, 8)); + } + + return 0; +} + +/****************************************************************************/ /** + * @brief Efuse write Cap code + * + * @param slot: Cap code slot + * @param code: Cap code value + * @param program: Whether program + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Write_CapCode_Opt(uint8_t slot, uint8_t code, uint8_t program) +{ + uint32_t tmp; + uint8_t trim; + + if (slot >= 3) { + return ERROR; + } + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + EF_CTRL_LOAD_BEFORE_READ_R0; + + if (slot == 0) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + } else if (slot == 1) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W1); + } else if (slot == 2) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH); + } + + trim = code; + trim |= ((EF_Ctrl_Get_Trim_Parity(code, 6)) << 6); + trim |= (1 << 7); + + if (slot == 0) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0, tmp | (trim << 2)); + } else if (slot == 1) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W1, tmp | (trim << 22)); + } else if (slot == 2) { + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH, tmp | (trim << 22)); + } + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } + + while (SET == EF_Ctrl_Busy()) + ; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Efuse read Cap code + * + * @param slot: Cap code slot + * @param code: Cap code pointer + * @param reload: Whether reload + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_CapCode_Opt(uint8_t slot, uint8_t *code, uint8_t reload) +{ + uint32_t tmp; + Efuse_Capcode_Info_Type *trim = (Efuse_Capcode_Info_Type *)&tmp; + + if (slot >= 3) { + return ERROR; + } + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + if (slot == 0) { + tmp = (BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0)) >> 2; + } else if (slot == 1) { + tmp = (BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W1)) >> 22; + } else if (slot == 2) { + tmp = (BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_DBG_PWD_HIGH)) >> 22; + } + + if (trim->en) { + if (trim->parity == EF_Ctrl_Get_Trim_Parity(trim->capCode, 6)) { + *code = trim->capCode; + return SUCCESS; + } + } + + return ERROR; +} + +/****************************************************************************/ /** + * @brief Whether power offset slot is empty + * + * @param slot: Power offset code slot + * @param reload: Whether reload + * + * @return 0 for all slots full,1 for others + * +*******************************************************************************/ +uint8_t EF_Ctrl_Is_PowerOffset_Slot_Empty(uint8_t slot, uint8_t reload) +{ + uint32_t tmp1 = 0xffffffff; + uint32_t part1Empty = 0, part2Empty = 0; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + if (slot == 0) { + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W3); + part1Empty = (EF_Ctrl_Is_All_Bits_Zero(tmp1, 15, 17)); + part2Empty = 1; + } else if (slot == 1) { + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W2); + part1Empty = (EF_Ctrl_Is_All_Bits_Zero(tmp1, 0, 16)); + + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + part2Empty = (EF_Ctrl_Is_All_Bits_Zero(tmp1, 0, 1)); + } else if (slot == 2) { + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W2); + part1Empty = (EF_Ctrl_Is_All_Bits_Zero(tmp1, 16, 16)); + + tmp1 = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + part2Empty = (EF_Ctrl_Is_All_Bits_Zero(tmp1, 1, 1)); + } + + return (part1Empty && part2Empty); +} + +/****************************************************************************/ /** + * @brief Efuse write power offset + * + * @param slot: Power offset slot + * @param pwrOffset[3]: Power offset value array + * @param program: Whether program + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Write_PowerOffset_Opt(uint8_t slot, int8_t pwrOffset[3], uint8_t program) +{ + uint64_t tmp = 0; + uint32_t k = 0; + uint64_t Value = 0; + uint8_t parity; + + if (slot >= 3) { + return ERROR; + } + + for (k = 0; k < 3; k++) { + /* Use 5 bits as signed value */ + if (pwrOffset[k] > 15) { + pwrOffset[k] = 15; + } + + if (pwrOffset[k] < -16) { + pwrOffset[k] = -16; + } + + tmp = ((uint64_t)((pwrOffset[k]) & 0x1f)) << (k * 5); + Value += tmp; + } + + parity = EF_Ctrl_Get_Trim_Parity(Value, 15); + + if (slot == 0) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W3); + tmp |= (Value << 16); + tmp |= (1 << 15); + tmp |= (uint32_t)(parity << 31); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W3, tmp); + } else if (slot == 1) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W2); + tmp |= (Value << 0); + tmp |= (uint32_t)(parity << 15); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W2, tmp); + + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + tmp |= (1 << 0); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0, tmp); + } else if (slot == 2) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W2); + tmp |= (Value << 16); + tmp |= (uint32_t)(parity << 31); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W2, tmp); + + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + tmp |= (1 << 1); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0, tmp); + } + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } + + while (SET == EF_Ctrl_Busy()) + ; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Efuse read poweroffset value + * + * @param slot: Power offset slot + * @param pwrOffset[3]: Power offset array + * @param reload: Whether reload + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Read_PowerOffset_Opt(uint8_t slot, int8_t pwrOffset[3], uint8_t reload) +{ + uint64_t pwrOffsetValue = 0; + + uint32_t tmp = 0, k; + uint8_t en = 0, parity = 0; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + if (reload) { + EF_CTRL_LOAD_BEFORE_READ_R0; + } + + if (slot == 0) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W3); + en = (tmp >> 15) & 0x01; + pwrOffsetValue = (tmp >> 16) & 0x7fff; + parity = (tmp >> 31) & 0x01; + } else if (slot == 1) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W2); + pwrOffsetValue = (tmp >> 0) & 0x7fff; + parity = (tmp >> 15) & 0x01; + + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + en = (tmp >> 0) & 0x01; + } else if (slot == 2) { + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_KEY_SLOT_5_W2); + pwrOffsetValue = (tmp >> 16) & 0x7fff; + parity = (tmp >> 31) & 0x01; + + tmp = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_EF_ANA_TRIM_0); + en = (tmp >> 1) & 0x01; + } + + if (en) { + if (parity == EF_Ctrl_Get_Trim_Parity(pwrOffsetValue, 15)) { + for (k = 0; k < 3; k++) { + tmp = (pwrOffsetValue >> (k * 5)) & 0x1f; + + if (tmp >= 16) { + pwrOffset[k] = tmp - 32; + } else { + pwrOffset[k] = tmp; + } + } + + return SUCCESS; + } + } + + return ERROR; +} + +/****************************************************************************/ /** + * @brief Efuse write AES key + * + * @param index: index of key slot + * @param keyData: key data buffer + * @param len: key data length in words + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_AES_Key(uint8_t index, uint32_t *keyData, uint32_t len, uint8_t program) +{ + uint32_t *pAESKeyStart0 = (uint32_t *)(EF_DATA_BASE + 0x1C); + + if (index > 5) { + return; + } + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + /* Every key is 4 words len*/ + BL602_MemCpy4(pAESKeyStart0 + index * 4, keyData, len); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse read AES key from specified region and index + * + * @param index: index of key slot + * @param keyData: key data buffer + * @param len: key data length in words + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_AES_Key(uint8_t index, uint32_t *keyData, uint32_t len) +{ + uint32_t *pAESKeyStart0 = (uint32_t *)(EF_DATA_BASE + 0x1C); + + if (index > 5) { + return; + } + + /* Trigger read data from efuse*/ + EF_CTRL_LOAD_BEFORE_READ_R0; + + /* Every key is 4 words len*/ + BL602_MemCpy4(keyData, pAESKeyStart0 + index * 4, len); +} + +/****************************************************************************/ /** + * @brief Efuse lock writing for aes key + * + * @param index: index of key slot + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Writelock_AES_Key(uint8_t index, uint8_t program) +{ + uint32_t tmpVal; + + if (index > 5) { + return; + } + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + + if (index <= 3) { + tmpVal |= (1 << (index + 19)); + } else { + tmpVal |= (1 << (index + 19)); + tmpVal |= (1 << (index - 4 + 13)); + } + + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Efuse lock reading for aes key + * + * @param index: index of key slot + * @param program: program to efuse entity or not + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Readlock_AES_Key(uint8_t index, uint8_t program) +{ + uint32_t tmpVal; + + if (index > 5) { + return; + } + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_DATA_0_LOCK); + tmpVal |= (1 << (index + 26)); + BL_WR_REG(EF_DATA_BASE, EF_DATA_0_LOCK, tmpVal); + + if (program) { + EF_Ctrl_Program_Efuse_0(); + } +} + +/****************************************************************************/ /** + * @brief Program data to efuse region 0 + * + * @param index: index of efuse in word + * @param data: data buffer + * @param len: data length + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Program_Direct_R0(uint32_t index, uint32_t *data, uint32_t len) +{ + uint32_t *pEfuseStart0 = (uint32_t *)(EF_DATA_BASE + 0x00); + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + /* Add delay for CLK to be stable */ + BL602_Delay_US(4); + + BL602_MemCpy4(pEfuseStart0 + index, data, len); + + EF_Ctrl_Program_Efuse_0(); +} + +/****************************************************************************/ /** + * @brief Read data from efuse region 0 + * + * @param index: index of efuse in word + * @param data: data buffer + * @param len: data length + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Direct_R0(uint32_t index, uint32_t *data, uint32_t len) +{ + uint32_t *pEfuseStart0 = (uint32_t *)(EF_DATA_BASE + 0x00); + + EF_CTRL_LOAD_BEFORE_READ_R0; + + BL602_MemCpy4(data, pEfuseStart0 + index, len); +} + +/****************************************************************************/ /** + * @brief Write data to efuse region 0 without program + * + * @param index: index of efuse in word + * @param data: data buffer + * @param len: data length + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Write_R0(uint32_t index, uint32_t *data, uint32_t len) +{ + uint32_t *pEfuseStart0 = (uint32_t *)(EF_DATA_BASE + 0x00); + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + /* Add delay for CLK to be stable */ + BL602_Delay_US(4); + + BL602_MemCpy4(pEfuseStart0 + index, data, len); +} + +/****************************************************************************/ /** + * @brief Read data from efuse region 0 without reload + * + * @param index: index of efuse in word + * @param data: data buffer + * @param len: data length + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_R0(uint32_t index, uint32_t *data, uint32_t len) +{ + uint32_t *pEfuseStart0 = (uint32_t *)(EF_DATA_BASE + 0x00); + + BL602_MemCpy4(data, pEfuseStart0 + index, len); +} + +/****************************************************************************/ /** + * @brief Clear efuse data register + * + * @param index: index of efuse in word + * @param len: data length + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION EF_Ctrl_Clear(uint32_t index, uint32_t len) +{ + uint32_t *pEfuseStart0 = (uint32_t *)(EF_DATA_BASE + 0x00); + uint32_t i = 0; + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + /* Clear data */ + for (i = 0; i < len; i++) { + pEfuseStart0[index + i] = 0; + } +} +#endif + +/****************************************************************************/ /** + * @brief efuse ctrl crc enable + * + * @param None + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Crc_Enable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_CTRL_EF_CRC_CTRL_0); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_CTRL_EF_CRC_TRIG); + tmpVal = BL_CLR_REG_BIT(tmpVal, EF_CTRL_EF_CRC_MODE); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_CTRL_EF_CRC_DOUT_INV_EN); + tmpVal = BL_CLR_REG_BIT(tmpVal, EF_CTRL_EF_CRC_DOUT_ENDIAN); + tmpVal = BL_CLR_REG_BIT(tmpVal, EF_CTRL_EF_CRC_DIN_ENDIAN); + tmpVal = BL_CLR_REG_BIT(tmpVal, EF_CTRL_EF_CRC_INT_CLR); + tmpVal = BL_CLR_REG_BIT(tmpVal, EF_CTRL_EF_CRC_INT_SET); + BL_WR_REG(EF_DATA_BASE, EF_CTRL_EF_CRC_CTRL_0, tmpVal); + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_CTRL_EF_CRC_CTRL_0); + tmpVal = BL_SET_REG_BIT(tmpVal, EF_CTRL_EF_CRC_EN); + BL_WR_REG(EF_DATA_BASE, EF_CTRL_EF_CRC_CTRL_0, tmpVal); +} + +/****************************************************************************/ /** + * @brief efuse ctrl get crc busy status + * + * @param None + * + * @return DISABLE or ENABLE + * +*******************************************************************************/ +BL_Sts_Type EF_Ctrl_Crc_Is_Busy(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_CTRL_EF_CRC_CTRL_0); + return (BL_Sts_Type)BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_CRC_BUSY); +} + +/****************************************************************************/ /** + * @brief efuse ctrl set golden value + * + * @param goldenValue: Crc golden value + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Crc_Set_Golden(uint32_t goldenValue) +{ + BL_WR_REG(EF_DATA_BASE, EF_CTRL_EF_CRC_CTRL_4, goldenValue); +} + +/****************************************************************************/ /** + * @brief efuse ctrl get crc result + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type EF_Ctrl_Crc_Result(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(EF_DATA_BASE, EF_CTRL_EF_CRC_CTRL_0); + return (BL_Err_Type)BL_IS_REG_BIT_SET(tmpVal, EF_CTRL_EF_CRC_ERROR); +} + +/*@} end of group SEC_EF_CTRL_Public_Functions */ + +/*@} end of group SEC_EF_CTRL */ + +/*@} end of group BL602_Peripheral_Driver */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_l1c.c b/drivers/soc/bl602/bl602_std/src/bl602_l1c.c new file mode 100644 index 00000000..b9e065a5 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_l1c.c @@ -0,0 +1,428 @@ +/** + ****************************************************************************** + * @file bl602_l1c.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl602_l1c.h" +#include "bl602_common.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup L1C + * @{ + */ + +/** @defgroup L1C_Private_Macros + * @{ + */ + +/*@} end of group L1C_Private_Macros */ + +/** @defgroup L1C_Private_Types + * @{ + */ + +/*@} end of group L1C_Private_Types */ + +/** @defgroup L1C_Private_Variables + * @{ + */ +static intCallback_Type *l1cBmxErrIntCbfArra[L1C_BMX_ERR_INT_ALL] = { NULL }; +static intCallback_Type *l1cBmxToIntCbfArra[L1C_BMX_TO_INT_ALL] = { NULL }; + +/*@} end of group L1C_Private_Variables */ + +/** @defgroup L1C_Global_Variables + * @{ + */ + +/*@} end of group L1C_Global_Variables */ + +/** @defgroup L1C_Private_Fun_Declaration + * @{ + */ + +/*@} end of group L1C_Private_Fun_Declaration */ + +/** @defgroup L1C_Private_Functions + * @{ + */ + +/*@} end of group L1C_Private_Functions */ + +/** @defgroup L1C_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief wrap set + * + * @param wrap: ENABLE or DISABLE + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_Set_Wrap(BL_Fun_Type wrap) +{ + uint32_t tmpVal = 0; + uint8_t cacheEn = 0; + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + cacheEn = BL_IS_REG_BIT_SET(L1C_BASE, L1C_CACHEABLE); + + if (cacheEn != 0) { + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_CACHEABLE); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + } + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + + if (wrap == ENABLE) { + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_WRAP_DIS); + } else { + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_WRAP_DIS); + } + + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + + if (cacheEn != 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_CACHEABLE); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief cache way disable set + * + * @param disableVal: cache way disable value + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_Set_Way_Disable(uint8_t disableVal) +{ + uint32_t tmpVal = 0; + uint8_t cacheEn = 0; + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + cacheEn = BL_IS_REG_BIT_SET(L1C_BASE, L1C_CACHEABLE); + + if (cacheEn != 0) { + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_CACHEABLE); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + } + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, L1C_WAY_DIS, disableVal); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + + if (cacheEn != 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_CACHEABLE); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Set for ROM 2T access if CPU freq >120MHz + * + * @param enable: ENABLE or DISABLE + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_IROM_2T_Access_Set(uint8_t enable) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + + if (enable) { + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_IROM_2T_ACCESS); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_IROM_2T_ACCESS); + } + + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief L1C BMX init + * + * @param l1cBmxCfg: L1C BMX config + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type L1C_BMX_Init(L1C_BMX_Cfg_Type *l1cBmxCfg) +{ + uint32_t tmpVal = 0; + + CHECK_PARAM((l1cBmxCfg->timeoutEn) <= 0xF); + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, L1C_BMX_TIMEOUT_EN, l1cBmxCfg->timeoutEn); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, L1C_BMX_ERR_EN, l1cBmxCfg->errEn); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, L1C_BMX_ARB_MODE, l1cBmxCfg->arbMod); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + +#ifndef BFLB_USE_HAL_DRIVER + Interrupt_Handler_Register(L1C_BMX_ERR_IRQn, L1C_BMX_ERR_IRQHandler); + Interrupt_Handler_Register(L1C_BMX_TO_IRQn, L1C_BMX_TO_IRQHandler); +#endif + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief L1C BMX address monitor enable + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type L1C_BMX_Addr_Monitor_Enable(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(L1C_BASE, L1C_BMX_ERR_ADDR_EN); + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_BMX_ERR_ADDR_DIS); + BL_WR_REG(L1C_BASE, L1C_BMX_ERR_ADDR_EN, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief L1C BMX address monitor disable + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type L1C_BMX_Addr_Monitor_Disable(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(L1C_BASE, L1C_BMX_ERR_ADDR_EN); + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_BMX_ERR_ADDR_DIS); + BL_WR_REG(L1C_BASE, L1C_BMX_ERR_ADDR_EN, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief L1C BMX bus error response enable + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type L1C_BMX_BusErrResponse_Enable(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_BMX_ERR_EN); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief L1C BMX bus error response disable + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type L1C_BMX_BusErrResponse_Disable(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_BMX_ERR_EN); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Get L1C BMX error status + * + * @param errType: L1C BMX error status type + * + * @return SET or RESET + * +*******************************************************************************/ +BL_Sts_Type L1C_BMX_Get_Status(L1C_BMX_BUS_ERR_Type errType) +{ + uint32_t tmpVal = 0; + + CHECK_PARAM(IS_L1C_BMX_BUS_ERR_TYPE(errType)); + + tmpVal = BL_RD_REG(L1C_BASE, L1C_BMX_ERR_ADDR_EN); + + if (errType == L1C_BMX_BUS_ERR_TRUSTZONE_DECODE) { + return BL_GET_REG_BITS_VAL(tmpVal, L1C_BMX_ERR_TZ) ? SET : RESET; + } else { + return BL_GET_REG_BITS_VAL(tmpVal, L1C_BMX_ERR_DEC) ? SET : RESET; + } +} + +/****************************************************************************/ /** + * @brief Get L1C BMX error address + * + * @param None + * + * @return NP L1C BMX error address + * +*******************************************************************************/ +uint32_t L1C_BMX_Get_Err_Addr(void) +{ + return BL_RD_REG(L1C_BASE, L1C_BMX_ERR_ADDR); +} + +/****************************************************************************/ /** + * @brief L1C BMX error interrupt callback install + * + * @param intType: L1C BMX error interrupt type + * @param cbFun: callback + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type L1C_BMX_ERR_INT_Callback_Install(L1C_BMX_ERR_INT_Type intType, intCallback_Type *cbFun) +{ + CHECK_PARAM(IS_L1C_BMX_ERR_INT_TYPE(intType)); + + l1cBmxErrIntCbfArra[intType] = cbFun; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief L1C BMX ERR interrupt IRQ handler + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_HAL_DRIVER +void L1C_BMX_ERR_IRQHandler(void) +{ + L1C_BMX_ERR_INT_Type intType; + + for (intType = L1C_BMX_ERR_INT_ERR; intType < L1C_BMX_ERR_INT_ALL; intType++) { + if (l1cBmxErrIntCbfArra[intType] != NULL) { + l1cBmxErrIntCbfArra[intType](); + } + } + + while (1) { + MSG("L1C_BMX_ERR_IRQHandler\r\n"); + BL602_Delay_MS(1000); + } +} +#endif + +/****************************************************************************/ /** + * @brief L1C BMX timeout interrupt callback install + * + * @param intType: L1C BMX timeout interrupt type + * @param cbFun: callback + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type L1C_BMX_TIMEOUT_INT_Callback_Install(L1C_BMX_TO_INT_Type intType, intCallback_Type *cbFun) +{ + CHECK_PARAM(IS_L1C_BMX_TO_INT_TYPE(intType)); + + l1cBmxToIntCbfArra[intType] = cbFun; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief L1C BMX Time Out interrupt IRQ handler + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_HAL_DRIVER +void L1C_BMX_TO_IRQHandler(void) +{ + L1C_BMX_TO_INT_Type intType; + + for (intType = L1C_BMX_TO_INT_TIMEOUT; intType < L1C_BMX_TO_INT_ALL; intType++) { + if (l1cBmxToIntCbfArra[intType] != NULL) { + l1cBmxToIntCbfArra[intType](); + } + } + + while (1) { + MSG("L1C_BMX_TO_IRQHandler\r\n"); + BL602_Delay_MS(1000); + } +} +#endif + +/*@} end of group L1C_Public_Functions */ + +/*@} end of group L1C */ + +/*@} end of group BL602_Peripheral_Driver */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_pds.c b/drivers/soc/bl602/bl602_std/src/bl602_pds.c new file mode 100644 index 00000000..dd3d40fe --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_pds.c @@ -0,0 +1,841 @@ +/** + ****************************************************************************** + * @file bl602_pds.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl602.h" +#include "bl602_pds.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup PDS + * @{ + */ + +/** @defgroup PDS_Private_Macros + * @{ + */ + +/*@} end of group PDS_Private_Macros */ + +/** @defgroup PDS_Private_Types + * @{ + */ + +/*@} end of group PDS_Private_Types */ + +/** @defgroup PDS_Private_Variables + * @{ + */ +static intCallback_Type *pdsIntCbfArra[4][1] = { { NULL }, { NULL }, { NULL }, { NULL } }; + +/*@} end of group PDS_Private_Variables */ + +/** @defgroup PDS_Global_Variables + * @{ + */ + +/*@} end of group PDS_Global_Variables */ + +/** @defgroup PDS_Private_Fun_Declaration + * @{ + */ + +/*@} end of group PDS_Private_Fun_Declaration */ + +/** @defgroup PDS_Private_Functions + * @{ + */ + +/*@} end of group PDS_Private_Functions */ + +/** @defgroup PDS_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief PDS software reset + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION PDS_Reset(void) +{ + uint32_t tmpVal = 0; + + tmpVal = *(uint32_t *)0x40000014; + tmpVal = tmpVal | (1 << 14); + *(uint32_t *)0x40000014 = tmpVal; + + tmpVal = *(uint32_t *)0x40000014; + tmpVal = tmpVal & ~(1 << 14); + *(uint32_t *)0x40000014 = tmpVal; + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Enable power down sleep + * + * @param cfg: power down sleep configuration 1 + * @param cfg4: power down sleep configuration 2 + * @param pdsSleepCnt: power down sleep count cycle + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +// #ifndef BFLB_USE_ROM_DRIVER +// __WEAK +BL_Err_Type ATTR_TCM_SECTION PDS_Enable(PDS_CTL_Type *cfg, PDS_CTL4_Type *cfg4, uint32_t pdsSleepCnt) +{ + uint32_t tmpVal = 0; + + /* PDS sleep time 0 <=> sleep forever */ + /* PDS sleep time 1~PDS_WARMUP_LATENCY_CNT <=> error */ + /* PDS sleep time >PDS_WARMUP_LATENCY_CNT <=> correct */ + if (!pdsSleepCnt) { + cfg->sleepForever = 1; + } else if ((pdsSleepCnt) && (pdsSleepCnt <= PDS_WARMUP_LATENCY_CNT)) { + return ERROR; + } else { + BL_WR_REG(PDS_BASE, PDS_TIME1, pdsSleepCnt - PDS_WARMUP_LATENCY_CNT); + } + + /* PDS_CTL4 config */ + BL_WR_REG(PDS_BASE, PDS_CTL4, *(uint32_t *)cfg4); + + /* PDS_CTL config */ + if (cfg->pdsStart) { + tmpVal = BL_RD_REG(PDS_BASE, PDS_INT); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CR_PDS_INT_CLR); + BL_WR_REG(PDS_BASE, PDS_INT, tmpVal); + + tmpVal = BL_RD_REG(PDS_BASE, PDS_INT); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CR_PDS_INT_CLR); + BL_WR_REG(PDS_BASE, PDS_INT, tmpVal); + + BL_WR_REG(PDS_BASE, PDS_CTL, (*(uint32_t *)cfg & ~(1 << 0))); + BL_WR_REG(PDS_BASE, PDS_CTL, (*(uint32_t *)cfg | (1 << 0))); + } else { + BL_WR_REG(PDS_BASE, PDS_CTL, *(uint32_t *)cfg); + } + + return SUCCESS; +} +// #endif + +/****************************************************************************/ /** + * @brief power down sleep force configure + * + * @param cfg2: power down sleep force configuration 1 + * @param cfg3: power down sleep force configuration 2 + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION PDS_Force_Config(PDS_CTL2_Type *cfg2, PDS_CTL3_Type *cfg3) +{ + /* PDS_CTL2 config */ + BL_WR_REG(PDS_BASE, PDS_CTL2, *(uint32_t *)cfg2); + + /* PDS_CTL3 config */ + BL_WR_REG(PDS_BASE, PDS_CTL3, *(uint32_t *)cfg3); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief power down sleep ram configure + * + * @param ramCfg: power down sleep force ram configuration + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION PDS_RAM_Config(PDS_RAM_CFG_Type *ramCfg) +{ + uint32_t tmpVal = 0; + + if (NULL == ramCfg) { + return SUCCESS; + } + + tmpVal = BL_RD_REG(GLB_BASE, GLB_MBIST_CTL); + /* enter bist mode (make ram idle/slp) */ + //tmpVal = tmpVal&~0x1F; + //tmpVal = tmpVal|0x18; + /* enter bist mode (make ram ret) */ + tmpVal = tmpVal | (0x1 << 3); + BL_WR_REG(GLB_BASE, GLB_MBIST_CTL, tmpVal); + + /* PDS_RAM1 config */ + BL_WR_REG(PDS_BASE, PDS_RAM1, *(uint32_t *)ramCfg); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_MBIST_CTL); + /* exit bist mode (make ram idle/slp) */ + //tmpVal = tmpVal&~0x1F; + /* exit bist mode (make ram ret) */ + tmpVal = tmpVal & ~(0x1 << 3); + BL_WR_REG(GLB_BASE, GLB_MBIST_CTL, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief power down sleep force configure + * + * @param defaultLvCfg: power down sleep default level configuration + * @param ramCfg: ram configuration + * @param pdsSleepCnt: power down sleep time count + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +// #ifndef BFLB_USE_ROM_DRIVER +// __WEAK +BL_Err_Type ATTR_TCM_SECTION PDS_Default_Level_Config(PDS_DEFAULT_LV_CFG_Type *defaultLvCfg, PDS_RAM_CFG_Type *ramCfg, uint32_t pdsSleepCnt) +{ + /* RAM config need fix after ECO */ + PDS_RAM_Config(ramCfg); + PDS_Force_Config((PDS_CTL2_Type *)&(defaultLvCfg->pdsCtl2), (PDS_CTL3_Type *)&(defaultLvCfg->pdsCtl3)); + PDS_Enable((PDS_CTL_Type *)&(defaultLvCfg->pdsCtl), (PDS_CTL4_Type *)&(defaultLvCfg->pdsCtl4), pdsSleepCnt); + + return SUCCESS; +} +// #endif + +/****************************************************************************/ /** + * @brief power down sleep int mask + * + * @param intType: PDS int type + * @param intMask: MASK or UNMASK + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type PDS_IntMask(PDS_INT_Type intType, BL_Mask_Type intMask) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(PDS_BASE, PDS_INT); + + if (intMask != UNMASK) { + tmpVal = tmpVal | (1 << (intType + PDS_INT_MASK_BIT_OFFSET)); + } else { + tmpVal = tmpVal & ~(1 << (intType + PDS_INT_MASK_BIT_OFFSET)); + } + + BL_WR_REG(PDS_BASE, PDS_INT, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get power down sleep int status + * + * @param intType: PDS int type + * + * @return SET or RESET + * +*******************************************************************************/ +BL_Sts_Type PDS_Get_IntStatus(PDS_INT_Type intType) +{ + return (BL_RD_REG(PDS_BASE, PDS_INT) & (1 << intType)) ? SET : RESET; +} + +/****************************************************************************/ /** + * @brief clear power down sleep int status + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type PDS_IntClear(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(PDS_BASE, PDS_INT); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CR_PDS_INT_CLR); + BL_WR_REG(PDS_BASE, PDS_INT, tmpVal); + + tmpVal = BL_RD_REG(PDS_BASE, PDS_INT); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CR_PDS_INT_CLR); + BL_WR_REG(PDS_BASE, PDS_INT, tmpVal); + + tmpVal = BL_RD_REG(PDS_BASE, PDS_INT); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CR_PDS_INT_CLR); + BL_WR_REG(PDS_BASE, PDS_INT, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief get power down sleep PLL status + * + * @param None + * + * @return PDS PLL status + * +*******************************************************************************/ +PDS_PLL_STS_Type PDS_Get_PdsPllStstus(void) +{ + return (PDS_PLL_STS_Type)BL_GET_REG_BITS_VAL(BL_RD_REG(PDS_BASE, PDS_STAT), PDS_RO_PDS_PLL_STATE); +} + +/****************************************************************************/ /** + * @brief get power down sleep RF status + * + * @param None + * + * @return PDS RF status + * +*******************************************************************************/ +PDS_RF_STS_Type PDS_Get_PdsRfStstus(void) +{ + return (PDS_RF_STS_Type)BL_GET_REG_BITS_VAL(BL_RD_REG(PDS_BASE, PDS_STAT), PDS_RO_PDS_RF_STATE); +} + +/****************************************************************************/ /** + * @brief get power down sleep status + * + * @param None + * + * @return PDS status + * +*******************************************************************************/ +PDS_STS_Type PDS_Get_PdsStstus(void) +{ + return (PDS_STS_Type)BL_GET_REG_BITS_VAL(BL_RD_REG(PDS_BASE, PDS_STAT), PDS_RO_PDS_STATE); +} + +/****************************************************************************/ /** + * @brief PDS wakeup IRQHandler install + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type PDS_WAKEUP_IRQHandler_Install(void) +{ +#ifndef BFLB_USE_HAL_DRIVER + Interrupt_Handler_Register(PDS_WAKEUP_IRQn, PDS_WAKEUP_IRQHandler); +#endif + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Install PDS interrupt callback function + * + * @param intType: PDS int type + * @param cbFun: cbFun: Pointer to interrupt callback function. The type should be void (*fn)(void) + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type PDS_Int_Callback_Install(PDS_INT_Type intType, intCallback_Type *cbFun) +{ + pdsIntCbfArra[intType][0] = cbFun; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Trim RC32M + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION PDS_Trim_RC32M(void) +{ + Efuse_Ana_RC32M_Trim_Type trim; + int32_t tmpVal = 0; + + EF_Ctrl_Read_RC32M_Trim(&trim); + + if (trim.trimRc32mExtCodeEn) { + if (trim.trimRc32mCodeFrExtParity == EF_Ctrl_Get_Trim_Parity(trim.trimRc32mCodeFrExt, 8)) { + tmpVal = BL_RD_REG(PDS_BASE, PDS_RC32M_CTRL0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_RC32M_CODE_FR_EXT, trim.trimRc32mCodeFrExt); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_RC32M_EXT_CODE_EN); + BL_WR_REG(PDS_BASE, PDS_RC32M_CTRL0, tmpVal); + BL602_Delay_US(2); + return SUCCESS; + } + } + + return ERROR; +} +#endif + +/****************************************************************************/ /** + * @brief Select RC32M as PLL ref source + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION PDS_Select_RC32M_As_PLL_Ref(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_REFCLK_SEL); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_XTAL_RC32M_SEL); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Select XTAL as PLL ref source + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION PDS_Select_XTAL_As_PLL_Ref(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_REFCLK_SEL); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_XTAL_RC32M_SEL); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power on PLL + * + * @param xtalType: xtal type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION PDS_Power_On_PLL(PDS_PLL_XTAL_Type xtalType) +{ + uint32_t tmpVal = 0; + + /* Check parameter*/ + CHECK_PARAM(IS_PDS_PLL_XTAL_TYPE(xtalType)); + + /**************************/ + /* select PLL XTAL source */ + /**************************/ + + if ((xtalType == PDS_PLL_XTAL_RC32M) || (xtalType == PDS_PLL_XTAL_NONE)) { + PDS_Trim_RC32M(); + PDS_Select_RC32M_As_PLL_Ref(); + } else { + PDS_Select_XTAL_As_PLL_Ref(); + } + + /*******************************************/ + /* PLL power down first, not indispensable */ + /*******************************************/ + /* power off PLL first, this step is not indispensable */ + PDS_Power_Off_PLL(); + + /********************/ + /* PLL param config */ + /********************/ + + /* clkpll_icp_1u */ + /* clkpll_icp_5u */ + /* clkpll_int_frac_sw */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_CP); + + if (xtalType == PDS_PLL_XTAL_26M) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_ICP_1U, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_ICP_5U, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_INT_FRAC_SW, 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_ICP_1U, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_ICP_5U, 2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_INT_FRAC_SW, 0); + } + + BL_WR_REG(PDS_BASE, PDS_CLKPLL_CP, tmpVal); + + /* clkpll_c3 */ + /* clkpll_cz */ + /* clkpll_rz */ + /* clkpll_r4 */ + /* clkpll_r4_short */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_RZ); + + if (xtalType == PDS_PLL_XTAL_26M) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_C3, 2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_CZ, 2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_RZ, 5); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_R4_SHORT, 0); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_C3, 3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_CZ, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_RZ, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_R4_SHORT, 1); + } + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_R4, 2); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_RZ, tmpVal); + + /* clkpll_refdiv_ratio */ + /* clkpll_postdiv */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_POSTDIV, 0x14); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_REFDIV_RATIO, 2); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_TOP_CTRL, tmpVal); + + /* clkpll_sdmin */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_SDM); + + switch (xtalType) { + case PDS_PLL_XTAL_NONE: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x3C0000); + break; + + case PDS_PLL_XTAL_24M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x500000); + break; + + case PDS_PLL_XTAL_32M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x3C0000); + break; + + case PDS_PLL_XTAL_38P4M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x320000); + break; + + case PDS_PLL_XTAL_40M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x300000); + break; + + case PDS_PLL_XTAL_26M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x49D39D); + break; + + case PDS_PLL_XTAL_RC32M: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x3C0000); + break; + + default: + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x3C0000); + break; + } + + BL_WR_REG(PDS_BASE, PDS_CLKPLL_SDM, tmpVal); + + /* clkpll_sel_fb_clk */ + /* clkpll_sel_sample_clk can be 0/1, default is 1 */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_FBDV); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SEL_FB_CLK, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SEL_SAMPLE_CLK, 1); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_FBDV, tmpVal); + + /*************************/ + /* PLL power up sequence */ + /*************************/ + + /* pu_clkpll_sfreg=1 */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_PU_CLKPLL_SFREG); + BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal); + + BL602_Delay_US(5); + + /* pu_clkpll=1 */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_PU_CLKPLL); + BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal); + + /* clkpll_pu_cp=1 */ + /* clkpll_pu_pfd=1 */ + /* clkpll_pu_fbdv=1 */ + /* clkpll_pu_postdiv=1 */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_PU_CP); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_PU_PFD); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_PU_FBDV); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_PU_POSTDIV); + BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal); + + BL602_Delay_US(5); + + /* clkpll_sdm_reset=1 */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_SDM_RESET); + BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal); + BL602_Delay_US(1); + /* clkpll_reset_fbdv=1 */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL); + tmpVal = BL_SET_REG_BIT(tmpVal, PDS_CLKPLL_RESET_FBDV); + BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal); + BL602_Delay_US(2); + /* clkpll_reset_fbdv=0 */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_RESET_FBDV); + BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal); + BL602_Delay_US(1); + /* clkpll_sdm_reset=0 */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_SDM_RESET); + BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Fix XTAL26M Setting + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION PDS_Fix_Xtal_Settig(void) +{ + uint32_t tmpVal; + + /* Fix 26M xtal clkpll_sdmin */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_SDM); + + if (0x49D39D == BL_GET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN)) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, PDS_CLKPLL_SDMIN, 0x49D89E); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_SDM, tmpVal); + } + + return SUCCESS; +} + +/** PLL output config **/ +/* +[8] 1'h0 r/w clkpll_en_32m +[7] 1'h0 r/w clkpll_en_48m +[6] 1'h0 r/w clkpll_en_80m +[5] 1'h0 r/w clkpll_en_96m +[4] 1'h0 r/w clkpll_en_120m +[3] 1'h0 r/w clkpll_en_160m +[2] 1'h0 r/w clkpll_en_192m +[1] 1'h0 r/w clkpll_en_240m +[0] 1'h0 r/w clkpll_en_480m +*/ + +/****************************************************************************/ /** + * @brief Enable all PLL clock + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION PDS_Enable_PLL_All_Clks(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN); + tmpVal |= 0x1FF; + BL_WR_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Disable all PLL clock + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION PDS_Disable_PLL_All_Clks(void) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN); + tmpVal &= (~0x1FF); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Enable PLL clock + * + * @param pllClk: PLL clock type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION PDS_Enable_PLL_Clk(PDS_PLL_CLK_Type pllClk) +{ + uint32_t tmpVal = 0; + + /* Check parameter*/ + CHECK_PARAM(IS_PDS_PLL_CLK_TYPE(pllClk)); + + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN); + tmpVal |= (1 << pllClk); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Disable PLL clock + * + * @param pllClk: PLL clock type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION PDS_Disable_PLL_Clk(PDS_PLL_CLK_Type pllClk) +{ + uint32_t tmpVal = 0; + + /* Check parameter*/ + CHECK_PARAM(IS_PDS_PLL_CLK_TYPE(pllClk)); + + tmpVal = BL_RD_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN); + tmpVal &= (~(1 << pllClk)); + BL_WR_REG(PDS_BASE, PDS_CLKPLL_OUTPUT_EN, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power off PLL + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_CLOCK_SECTION PDS_Power_Off_PLL(void) +{ + uint32_t tmpVal = 0; + + /* pu_clkpll_sfreg=0 */ + /* pu_clkpll=0 */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_PU_CLKPLL_SFREG); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_PU_CLKPLL); + BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal); + + /* clkpll_pu_cp=0 */ + /* clkpll_pu_pfd=0 */ + /* clkpll_pu_fbdv=0 */ + /* clkpll_pu_postdiv=0 */ + tmpVal = BL_RD_REG(PDS_BASE, PDS_PU_RST_CLKPLL); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_PU_CP); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_PU_PFD); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_PU_FBDV); + tmpVal = BL_CLR_REG_BIT(tmpVal, PDS_CLKPLL_PU_POSTDIV); + BL_WR_REG(PDS_BASE, PDS_PU_RST_CLKPLL, tmpVal); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Power down sleep wake up interrupt handler + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_HAL_DRIVER +void PDS_WAKEUP_IRQHandler(void) +{ + for (PDS_INT_Type intType = PDS_INT_WAKEUP; intType < PDS_INT_MAX; intType++) { + if (PDS_Get_IntStatus(intType) && (pdsIntCbfArra[intType][0] != NULL)) { + pdsIntCbfArra[intType][0](); + } + } + + PDS_IntClear(); +} +#endif + +/*@} end of group PDS_Public_Functions */ + +/*@} end of group PDS */ + +/*@} end of group BL602_Peripheral_Driver */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_sf_cfg.c b/drivers/soc/bl602/bl602_std/src/bl602_sf_cfg.c new file mode 100644 index 00000000..8cbc7398 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_sf_cfg.c @@ -0,0 +1,2193 @@ +/** + ****************************************************************************** + * @file bl602_sf_cfg.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl602_glb.h" +#include "bl602_sf_cfg.h" +#include "bl602_xip_sflash.h" +#include "soft_crc.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup SF_CFG + * @{ + */ + +/** @defgroup SF_CFG_Private_Macros + * @{ + */ +#define BFLB_FLASH_CFG_MAGIC "FCFG" + +/*@} end of group SF_CFG_Private_Macros */ + +/** @defgroup SF_CFG_Private_Types + * @{ + */ +typedef struct +{ + uint32_t jedecID; + char *name; + const SPI_Flash_Cfg_Type *cfg; +} Flash_Info_t; + +/*@} end of group SF_CFG_Private_Types */ + +/** @defgroup SF_CFG_Private_Variables + * @{ + */ +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Winb_80DV = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xef, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 0, + .cReadMode = 0xFF, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3d, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 3, + .qeData = 0, +}; +#if 0 +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Winb_80BV = +{ + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xef, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, /*Q08BV,Q16DV: 0x02.Q32FW,Q32FV: 0x01 */ + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3d, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 3, + .qeData = 0, +}; +#endif +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xef, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x31, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 400, + .timeE32k = 1600, + .timeE64k = 2000, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 3, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Issi = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0x9d, + + .deBurstWrapCmd = 0xC0, + .deBurstWrapCmdDmyClk = 0x00, + .deBurstWrapDataMode = SF_CTRL_DATA_1_LINE, + .deBurstWrapData = 0x00, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 0, + .qeBit = 0x06, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x31, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0xA0, + + .burstWrapCmd = 0xC0, + .burstWrapCmdDmyClk = 0x00, + .burstWrapDataMode = SF_CTRL_DATA_1_LINE, + .burstWrapData = 0x06, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 5, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Gd_LQ08C_LE16C_LQ32D_WQ32E = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xc8, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 20, + .qeData = 0, +}; +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Gd_Q80E_Q16E = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xc8, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0xA0, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 20, + .qeData = 0, +}; +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Gd_WQ80E_WQ16E = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xc8, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 32 / 8, + .cReadSupport = 1, + .cReadMode = 0xA0, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 8 / 8, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 20, + .qeData = 0x12, +}; +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Gd_Q32C = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xc8, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x31, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 20, + .qeData = 0, +}; +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Mxic = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xC2, + + .deBurstWrapCmd = 0xC0, + .deBurstWrapCmdDmyClk = 0x00, + .deBurstWrapDataMode = SF_CTRL_DATA_1_LINE, + .deBurstWrapData = 0x10, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 0, + .qeBit = 0x06, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0xA5, + + .burstWrapCmd = 0xC0, + .burstWrapCmdDmyClk = 0x00, + .burstWrapDataMode = SF_CTRL_DATA_1_LINE, + .burstWrapData = 0x02, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x38, + .qppAddrMode = SF_CTRL_ADDR_4_LINES, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 45, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Mxic_1635F = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xC2, + + .deBurstWrapCmd = 0xC0, + .deBurstWrapCmdDmyClk = 0x00, + .deBurstWrapDataMode = SF_CTRL_DATA_1_LINE, + .deBurstWrapData = 0x10, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 0, + .qeBit = 0x06, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0xA5, + + .burstWrapCmd = 0xC0, + .burstWrapCmdDmyClk = 0x00, + .burstWrapDataMode = SF_CTRL_DATA_1_LINE, + .burstWrapData = 0x02, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x38, + .qppAddrMode = SF_CTRL_ADDR_4_LINES, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 45, + .qeData = 0, +}; +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Xtx_Q80B_F16B = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0x0B, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 0x01, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = 0x14, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 6000, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 20, + .qeData = 0, +}; +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Xtx = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0x0B, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 0x01, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 6000, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 20, + .qeData = 0, +}; +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Puya_Q80L_Q80H_Q16H = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0x85, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 0x01, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3d, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 8, + .qeData = 0, +}; +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Puya_Q32H = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0x85, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 0x01, + .qeBit = 0x01, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x31, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 8, + .qeData = 0, +}; +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Boya = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0x68, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 0x01, + .qeBit = 0x01, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x31, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 20, + .qeData = 0, +}; +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_FT_VQ80 = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xef, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x31, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .qpiJedecIdCmd = 0x9f, + .qpiJedecIdCmdDmyClk = 0x00, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 8, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION Flash_Info_t flashInfos[] = { + { + .jedecID = 0x1440ef, + //.name="Winb_80DV_08_33", + .cfg = &flashCfg_Winb_80DV, + }, + { + .jedecID = 0x1540ef, + //.name="Winb_16DV_16_33", + .cfg = &flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV, + }, + { + .jedecID = 0x1570ef, + //.name="Winb_16jV_16_33_DTR", + .cfg = &flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV, + }, + { + .jedecID = 0x1640ef, + //.name="Winb_32FV_32_33", + .cfg = &flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV, + }, + { + .jedecID = 0x1460ef, + //.name="Winb_80EW_08_18", + .cfg = &flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV, + }, + { + .jedecID = 0x1560ef, + //.name="Winb_16FW_16_18", + .cfg = &flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV, + }, + { + .jedecID = 0x1660ef, + //.name="Winb_32FW_32_18", + .cfg = &flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV, + }, + { + .jedecID = 0x1860ef, + //.name="Winb_128FW_128_18", + .cfg = &flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV, + }, + { + .jedecID = 0x1680ef, + //.name="Winb_32JW_32_18", + .cfg = &flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV, + }, + { + .jedecID = 0x13605e, + //.name="Zbit_04_33", + .cfg = &flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV, + }, + { + .jedecID = 0x14605e, + //.name="Zbit_08_33", + .cfg = &flashCfg_Winb_80EW_16JV_16FW_32JW_32FW_32FV, + }, + { + .jedecID = 0x14609d, + //.name="ISSI_08_33", + .cfg = &flashCfg_Issi, + }, + { + .jedecID = 0x15609d, + //.name="ISSI_16_33", + .cfg = &flashCfg_Issi, + }, + { + .jedecID = 0x16609d, + //.name="ISSI_32_33", + .cfg = &flashCfg_Issi, + }, + { + .jedecID = 0x14709d, + //.name="ISSI_08_18", + .cfg = &flashCfg_Issi, + }, + { + .jedecID = 0x15709d, + //.name="ISSI_16_18", + .cfg = &flashCfg_Issi, + }, + { + .jedecID = 0x16709d, + //.name="ISSI_32_18", + .cfg = &flashCfg_Issi, + }, + { + .jedecID = 0x1440C8, + //.name="GD_Q08E_08_33", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x1540C8, + //.name="GD_Q16E_16_33", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x1640C8, + //.name="GD_Q32C_32_33", + .cfg = &flashCfg_Gd_Q32C, + }, + { + .jedecID = 0x1460C8, + //.name="GD_LQ08C_08_18", + .cfg = &flashCfg_Gd_LQ08C_LE16C_LQ32D_WQ32E, + }, + { + .jedecID = 0x1560C8, + //.name="GD_LE16C_16_18", + .cfg = &flashCfg_Gd_LQ08C_LE16C_LQ32D_WQ32E, + }, + { + .jedecID = 0x1660C8, + //.name="GD_LQ32D_32_18", + .cfg = &flashCfg_Gd_LQ08C_LE16C_LQ32D_WQ32E, + }, + { + .jedecID = 0x1465C8, + //.name="GD_WQ80E_80_33", + .cfg = &flashCfg_Gd_WQ80E_WQ16E, + }, + { + .jedecID = 0x1565C8, + //.name="GD_WQ16E_16_33", + .cfg = &flashCfg_Gd_WQ80E_WQ16E, + }, + { + .jedecID = 0x1665C8, + //.name="GD_WQ32E_32_33", + .cfg = &flashCfg_Gd_LQ08C_LE16C_LQ32D_WQ32E, + }, + { + .jedecID = 0x3425C2, + //.name="MX_25V80_08_18", + .cfg = &flashCfg_Mxic, + }, + { + .jedecID = 0x3525C2, + //.name="MX_25U16_35_18", + .cfg = &flashCfg_Mxic_1635F, + }, + { + .jedecID = 0x3625C2, + //.name="MX_25V32_32_18", + .cfg = &flashCfg_Mxic, + }, + { + .jedecID = 0x13400B, + //.name="XT_25F04D_04_33", + .cfg = &flashCfg_Xtx, + }, + { + .jedecID = 0x15400B, + //.name="XT_25F16B_16_33", + .cfg = &flashCfg_Xtx_Q80B_F16B, + }, + { + .jedecID = 0x16400B, + //.name="XT_25F32B_32_33", + .cfg = &flashCfg_Xtx, + }, + { + .jedecID = 0x14600B, + //.name="XT_25Q80B_08_18", + .cfg = &flashCfg_Xtx_Q80B_F16B, + }, + { + .jedecID = 0x16600B, + //.name="XT_25Q32B_32_18", + .cfg = &flashCfg_Xtx, + }, + { + .jedecID = 0x146085, + //.name="Puya_Q80L/H_08_18/33", + .cfg = &flashCfg_Puya_Q80L_Q80H_Q16H, + }, + { + .jedecID = 0x156085, + //.name="Puya_Q16H_16_33", + .cfg = &flashCfg_Puya_Q80L_Q80H_Q16H, + }, + { + .jedecID = 0x166085, + //.name="Puya_Q32H_32_33", + .cfg = &flashCfg_Puya_Q32H, + }, + { + .jedecID = 0x154068, + //.name="Boya_Q16B_16_33", + .cfg = &flashCfg_Boya, + }, + { + .jedecID = 0x164068, + //.name="Boya_Q32B_32_33", + .cfg = &flashCfg_Boya, + }, + { + .jedecID = 0x174068, + //.name="Boya_Q64A_64_33", + .cfg = &flashCfg_Boya, + }, + { + .jedecID = 0x184068, + //.name="Boya_Q128A_128_33", + .cfg = &flashCfg_Boya, + }, + { + .jedecID = 0x14605E, + //.name="FT_VQ80", + .cfg = &flashCfg_FT_VQ80, + } +}; + +/*@} end of group SF_CFG_Private_Variables */ + +/** @defgroup SF_CFG_Global_Variables + * @{ + */ + +/*@} end of group SF_CFG_Global_Variables */ + +/** @defgroup SF_CFG_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SF_CFG_Private_Fun_Declaration */ + +/** @defgroup SF_CFG_Private_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Init external flash GPIO according to flash GPIO config + * + * @param extFlashPin: Flash GPIO config + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Cfg_Init_Ext_Flash_Gpio(uint8_t extFlashPin) +{ + GLB_GPIO_Cfg_Type cfg; + uint8_t gpiopins[6]; + uint8_t i = 0; + + cfg.gpioMode = GPIO_MODE_AF; + cfg.pullType = GPIO_PULL_UP; + cfg.drive = 1; + cfg.smtCtrl = 1; + cfg.gpioFun = GPIO_FUN_FLASH; + + if (extFlashPin == 0) { + gpiopins[0] = BFLB_EXTFLASH_CLK0_GPIO; + gpiopins[1] = BFLB_EXTFLASH_CS0_GPIO; + gpiopins[2] = BFLB_EXTFLASH_DATA00_GPIO; + gpiopins[3] = BFLB_EXTFLASH_DATA10_GPIO; + gpiopins[4] = BFLB_EXTFLASH_DATA20_GPIO; + gpiopins[5] = BFLB_EXTFLASH_DATA30_GPIO; + } else { + gpiopins[0] = BFLB_EXTFLASH_CLK1_GPIO; + gpiopins[1] = BFLB_EXTFLASH_CS1_GPIO; + gpiopins[2] = BFLB_EXTFLASH_DATA01_GPIO; + gpiopins[3] = BFLB_EXTFLASH_DATA11_GPIO; + gpiopins[4] = BFLB_EXTFLASH_DATA21_GPIO; + gpiopins[5] = BFLB_EXTFLASH_DATA31_GPIO; + } + + for (i = 0; i < sizeof(gpiopins); i++) { + cfg.gpioPin = gpiopins[i]; + + if (i == 0 || i == 1) { + /*flash clk and cs is output*/ + cfg.gpioMode = GPIO_MODE_OUTPUT; + } else { + /*data are bidir*/ + cfg.gpioMode = GPIO_MODE_AF; + } + + GLB_GPIO_Init(&cfg); + } +} + +/****************************************************************************/ /** + * @brief Init internal flash GPIO according to flash GPIO config + * + * @param None + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Cfg_Init_Internal_Flash_Gpio(void) +{ + GLB_GPIO_Cfg_Type gpioCfg = { + .gpioPin = GLB_GPIO_PIN_0, + .gpioFun = GPIO_FUN_SWGPIO, + .gpioMode = GPIO_MODE_INPUT, + .pullType = GPIO_PULL_NONE, + .drive = 0, + .smtCtrl = 1, + }; + + /* Turn on Flash pad, GPIO23 - GPIO28 */ + for (uint32_t pin = 23; pin < 29; pin++) { + gpioCfg.gpioPin = pin; + + if (pin == 24) { + gpioCfg.pullType = GPIO_PULL_DOWN; + } else { + gpioCfg.pullType = GPIO_PULL_NONE; + } + + GLB_GPIO_Init(&gpioCfg); + } +} + +/****************************************************************************/ /** + * @brief Deinit external flash GPIO according to flash GPIO config + * + * @param extFlashPin: Flash GPIO config + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Cfg_Deinit_Ext_Flash_Gpio(uint8_t extFlashPin) +{ + GLB_GPIO_Cfg_Type cfg; + uint8_t gpiopins[6]; + uint8_t i = 0; + + cfg.gpioMode = GPIO_MODE_INPUT; + cfg.pullType = GPIO_PULL_UP; + cfg.drive = 1; + cfg.smtCtrl = 1; + cfg.gpioFun = GPIO_FUN_SWGPIO; + + if (extFlashPin == 0) { + gpiopins[0] = BFLB_EXTFLASH_CLK0_GPIO; + gpiopins[1] = BFLB_EXTFLASH_CS0_GPIO; + gpiopins[2] = BFLB_EXTFLASH_DATA00_GPIO; + gpiopins[3] = BFLB_EXTFLASH_DATA10_GPIO; + gpiopins[4] = BFLB_EXTFLASH_DATA20_GPIO; + gpiopins[5] = BFLB_EXTFLASH_DATA30_GPIO; + + } else { + gpiopins[0] = BFLB_EXTFLASH_CLK1_GPIO; + gpiopins[1] = BFLB_EXTFLASH_CS1_GPIO; + gpiopins[2] = BFLB_EXTFLASH_DATA01_GPIO; + gpiopins[3] = BFLB_EXTFLASH_DATA11_GPIO; + gpiopins[4] = BFLB_EXTFLASH_DATA21_GPIO; + gpiopins[5] = BFLB_EXTFLASH_DATA31_GPIO; + } + + for (i = 0; i < sizeof(gpiopins); i++) { + cfg.gpioPin = gpiopins[i]; + GLB_GPIO_Init(&cfg); + } +} + +/****************************************************************************/ /** + * @brief Restore GPIO17 function + * + * @param fun: GPIO17 function + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Cfg_Restore_GPIO17_Fun(uint8_t fun) +{ + GLB_GPIO_Cfg_Type cfg; + + cfg.gpioMode = GPIO_MODE_AF; + cfg.pullType = GPIO_PULL_UP; + cfg.drive = 1; + cfg.smtCtrl = 1; + cfg.gpioPin = GLB_GPIO_PIN_17; + cfg.gpioFun = fun; + GLB_GPIO_Init(&cfg); +} + +/*@} end of group SF_CFG_Private_Functions */ + +/** @defgroup SF_CFG_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Get flash config according to flash ID + * + * @param flashID: Flash ID + * @param pFlashCfg: Flash config pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Get_Flash_Cfg_Need_Lock(uint32_t flashID, SPI_Flash_Cfg_Type *pFlashCfg) +{ + uint32_t i; + uint8_t buf[sizeof(SPI_Flash_Cfg_Type) + 8]; + uint32_t crc, *pCrc; + + if (flashID == 0) { + XIP_SFlash_Read_Via_Cache_Need_Lock(8 + BL602_FLASH_XIP_BASE, buf, sizeof(SPI_Flash_Cfg_Type) + 8); + + if (BL602_MemCmp(buf, BFLB_FLASH_CFG_MAGIC, 4) == 0) { + crc = BFLB_Soft_CRC32((uint8_t *)buf + 4, sizeof(SPI_Flash_Cfg_Type)); + pCrc = (uint32_t *)(buf + 4 + sizeof(SPI_Flash_Cfg_Type)); + + if (*pCrc == crc) { + BL602_MemCpy_Fast(pFlashCfg, (uint8_t *)buf + 4, sizeof(SPI_Flash_Cfg_Type)); + return SUCCESS; + } + } + } else { + for (i = 0; i < sizeof(flashInfos) / sizeof(flashInfos[0]); i++) { + if (flashInfos[i].jedecID == flashID) { + BL602_MemCpy_Fast(pFlashCfg, flashInfos[i].cfg, sizeof(SPI_Flash_Cfg_Type)); + return SUCCESS; + } + } + } + + return ERROR; +} + +/****************************************************************************/ /** + * @brief Init flash GPIO according to flash Pin config + * + * @param flashPinCfg: Specify flash Pin config + * @param restoreDefault: Wether to restore default setting + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Cfg_Init_Flash_Gpio(uint8_t flashPinCfg, uint8_t restoreDefault) +{ + if (restoreDefault) { + /* Set Default first */ + SF_Ctrl_Select_Pad(SF_CTRL_EMBEDDED_SEL); + GLB_Select_Internal_Flash(); + GLB_Swap_Flash_Pin(); + //SF_Cfg_Deinit_Ext_Flash_Gpio(0); + SF_Cfg_Deinit_Ext_Flash_Gpio(1); + SF_Cfg_Init_Internal_Flash_Gpio(); + } + + if (flashPinCfg > 0) { + /*01: deswap flash PIN + 10: use ext flash 1(GPIO17-22) + 11: use ext flash 0(GPIO0-2, 20-22) + */ + if (flashPinCfg == BFLB_FLASH_CFG_DESWAP) { + SF_Ctrl_Select_Pad(SF_CTRL_EMBEDDED_SEL); + /*DONOT Swap flash PIN*/ + GLB_Deswap_Flash_Pin(); + } else { + SF_Ctrl_Select_Pad(flashPinCfg - 1); + GLB_Select_External_Flash(); + SF_Cfg_Init_Ext_Flash_Gpio(flashPinCfg - BFLB_FLASH_CFG_EXT0_17_22); + } + } +} + +/****************************************************************************/ /** + * @brief Identify one flash + * + * @param callFromFlash: code run at flash or ram + * @param autoScan: Auto scan all GPIO pin + * @param flashPinCfg: Specify flash GPIO config, not auto scan + * @param restoreDefault: Wether restore default flash GPIO config + * @param pFlashCfg: Flash config pointer + * + * @return Flash ID + * +*******************************************************************************/ +__WEAK +uint32_t ATTR_TCM_SECTION SF_Cfg_Flash_Identify(uint8_t callFromFlash, + uint32_t autoScan, uint32_t flashPinCfg, uint8_t restoreDefault, SPI_Flash_Cfg_Type *pFlashCfg) +{ + uint32_t jdecId = 0; + uint32_t i = 0; + uint32_t offset; + BL_Err_Type stat; + uint8_t gpio17_fun = 0; + + BL602_MemCpy_Fast(pFlashCfg, &flashCfg_Gd_Q80E_Q16E, sizeof(SPI_Flash_Cfg_Type)); + + if (callFromFlash == 1) { + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, SF_CTRL_QIO_MODE, 1, 0, 32); + return 0; + } + } + + if (autoScan) { + flashPinCfg = 0; + + do { + if (flashPinCfg > BFLB_FLASH_CFG_EXT1_0_2_20_22) { + jdecId = 0; + break; + } + + if (flashPinCfg > BFLB_FLASH_CFG_EXT0_17_22) { + /*flashPinCfg=2 has make gpio17 into jtag,but not success*/ + SF_Cfg_Restore_GPIO17_Fun(gpio17_fun); + } + + /* select media gpio */ + if (flashPinCfg == BFLB_FLASH_CFG_EXT0_17_22) { + gpio17_fun = GLB_GPIO_Get_Fun(GLB_GPIO_PIN_17); + } + + SF_Cfg_Init_Flash_Gpio(flashPinCfg, restoreDefault); + SFlash_Reset_Continue_Read(pFlashCfg); + SFlash_DisableBurstWrap(pFlashCfg); + jdecId = 0; + SFlash_GetJedecId(pFlashCfg, (uint8_t *)&jdecId); + SFlash_DisableBurstWrap(pFlashCfg); + jdecId = jdecId & 0xffffff; + flashPinCfg++; + } while ((jdecId & 0x00ffff) == 0 || (jdecId & 0xffff00) == 0 || (jdecId & 0x00ffff) == 0xffff || (jdecId & 0xffff00) == 0xffff00); + } else { + /* select media gpio */ + SF_Cfg_Init_Flash_Gpio(flashPinCfg, restoreDefault); + SFlash_Reset_Continue_Read(pFlashCfg); + SFlash_DisableBurstWrap(pFlashCfg); + SFlash_GetJedecId(pFlashCfg, (uint8_t *)&jdecId); + SFlash_DisableBurstWrap(pFlashCfg); + jdecId = jdecId & 0xffffff; + } + + for (i = 0; i < sizeof(flashInfos) / sizeof(flashInfos[0]); i++) { + if (flashInfos[i].jedecID == jdecId) { + BL602_MemCpy_Fast(pFlashCfg, flashInfos[i].cfg, sizeof(SPI_Flash_Cfg_Type)); + break; + } + } + + if (i == sizeof(flashInfos) / sizeof(flashInfos[0])) { + if (callFromFlash == 1) { + XIP_SFlash_State_Restore(pFlashCfg, offset); + } + + return jdecId; + } else { + if (callFromFlash == 1) { + XIP_SFlash_State_Restore(pFlashCfg, offset); + } + + return (jdecId | BFLB_FLASH_ID_VALID_FLAG); + } +} +#endif + +/*@} end of group SF_CFG_Public_Functions */ + +/*@} end of group SF_CFG */ + +/*@} end of group BL602_Peripheral_Driver */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_sf_cfg_ext.c b/drivers/soc/bl602/bl602_std/src/bl602_sf_cfg_ext.c new file mode 100644 index 00000000..2a9ceca6 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_sf_cfg_ext.c @@ -0,0 +1,790 @@ +/** + ****************************************************************************** + * @file bl602_sf_cfg_ext.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl602_glb.h" +#include "bl602_sf_cfg.h" +#include "bl602_sf_cfg_ext.h" +#include "bl602_xip_sflash.h" +#include "bl602_romdriver.h" +#include "soft_crc.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup SF_CFG_EXT + * @{ + */ + +/** @defgroup SF_CFG_EXT_Private_Macros + * @{ + */ +#define BFLB_FLASH_CFG_MAGIC "FCFG" + +/*@} end of group SF_CFG_EXT_Private_Macros */ + +/** @defgroup SF_CFG_EXT_Private_Types + * @{ + */ +typedef struct { + uint32_t jedecID; + char *name; + const SPI_Flash_Cfg_Type *cfg; +}Flash_Info_t; + +/*@} end of group SF_CFG_EXT_Private_Types */ + +/** @defgroup SF_CFG_EXT_Private_Variables + * @{ + */ +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_FM_25Q08={ + .resetCreadCmd=0xff, + .resetCreadCmdSize=3, + .mid=0xc8, + + .deBurstWrapCmd=0x77, + .deBurstWrapCmdDmyClk=0x3, + .deBurstWrapDataMode=SF_CTRL_DATA_4_LINES, + .deBurstWrapData=0xF0, + + /*reg*/ + .writeEnableCmd=0x06, + .wrEnableIndex=0x00, + .wrEnableBit=0x01, + .wrEnableReadRegLen=0x01, + + .qeIndex=1, + .qeBit=0x01, + .qeWriteRegLen=0x02, + .qeReadRegLen=0x1, + + .busyIndex=0, + .busyBit=0x00, + .busyReadRegLen=0x1, + .releasePowerDown=0xab, + + .readRegCmd[0]=0x05, + .readRegCmd[1]=0x35, + .writeRegCmd[0]=0x01, + .writeRegCmd[1]=0x01, + + .fastReadQioCmd=0xeb, + .frQioDmyClk=16/8, + .cReadSupport=1, + .cReadMode=0xa0, + + .burstWrapCmd=0x77, + .burstWrapCmdDmyClk=0x3, + .burstWrapDataMode=SF_CTRL_DATA_4_LINES, + .burstWrapData=0x40, + /*erase*/ + .chipEraseCmd=0xc7, + .sectorEraseCmd=0x20, + .blk32EraseCmd=0x52, + .blk64EraseCmd=0xd8, + /*write*/ + .pageProgramCmd=0x02, + .qpageProgramCmd=0x32, + .qppAddrMode=SF_CTRL_ADDR_1_LINE, + + .ioMode=SF_CTRL_QIO_MODE, + .clkDelay=1, + .clkInvert=0x01, + + .resetEnCmd=0x66, + .resetCmd=0x99, + .cRExit=0xff, + .wrEnableWriteRegLen=0x00, + + /*id*/ + .jedecIdCmd=0x9f, + .jedecIdCmdDmyClk=0, + .qpiJedecIdCmd=0x9f, + .qpiJedecIdCmdDmyClk=0x00, + .sectorSize=4, + .pageSize=256, + + /*read*/ + .fastReadCmd=0x0b, + .frDmyClk=8/8, + .qpiFastReadCmd =0x0b, + .qpiFrDmyClk=8/8, + .fastReadDoCmd=0x3b, + .frDoDmyClk=8/8, + .fastReadDioCmd=0xbb, + .frDioDmyClk=0, + .fastReadQoCmd=0x6b, + .frQoDmyClk=8/8, + + .qpiFastReadQioCmd=0xeb, + .qpiFrQioDmyClk=16/8, + .qpiPageProgramCmd=0x02, + .writeVregEnableCmd=0x50, + + /* qpi mode */ + .enterQpi=0x38, + .exitQpi=0xff, + + /*AC*/ + .timeEsector=300, + .timeE32k=1200, + .timeE64k=1200, + .timePagePgm=5, + .timeCe=33000, + .pdDelay=20, + .qeData=0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Gd_Md_40D={ + .resetCreadCmd=0xff, + .resetCreadCmdSize=3, + .mid=0x51, + + .deBurstWrapCmd=0x77, + .deBurstWrapCmdDmyClk=0x3, + .deBurstWrapDataMode=SF_CTRL_DATA_4_LINES, + .deBurstWrapData=0xF0, + + /*reg*/ + .writeEnableCmd=0x06, + .wrEnableIndex=0x00, + .wrEnableBit=0x01, + .wrEnableReadRegLen=0x01, + + .qeIndex=1, + .qeBit=0x01, + .qeWriteRegLen=0x02, + .qeReadRegLen=0x1, + + .busyIndex=0, + .busyBit=0x00, + .busyReadRegLen=0x1, + .releasePowerDown=0xab, + + .readRegCmd[0]=0x05, + .readRegCmd[1]=0x35, + .writeRegCmd[0]=0x01, + .writeRegCmd[1]=0x01, + + .fastReadQioCmd=0xeb, + .frQioDmyClk=16/8, + .cReadSupport=0, + .cReadMode=0xA0, + + .burstWrapCmd=0x77, + .burstWrapCmdDmyClk=0x3, + .burstWrapDataMode=SF_CTRL_DATA_4_LINES, + .burstWrapData=0x40, + /*erase*/ + .chipEraseCmd=0xc7, + .sectorEraseCmd=0x20, + .blk32EraseCmd=0x52, + .blk64EraseCmd=0xd8, + /*write*/ + .pageProgramCmd=0x02, + .qpageProgramCmd=0x32, + .qppAddrMode=SF_CTRL_ADDR_1_LINE, + + .ioMode=0x11, + .clkDelay=1, + .clkInvert=0x01, + + .resetEnCmd=0x66, + .resetCmd=0x99, + .cRExit=0xff, + .wrEnableWriteRegLen=0x00, + + /*id*/ + .jedecIdCmd=0x9f, + .jedecIdCmdDmyClk=0, + .qpiJedecIdCmd=0x9f, + .qpiJedecIdCmdDmyClk=0x00, + .sectorSize=4, + .pageSize=256, + + /*read*/ + .fastReadCmd=0x0b, + .frDmyClk=8/8, + .qpiFastReadCmd =0x0b, + .qpiFrDmyClk=8/8, + .fastReadDoCmd=0x3b, + .frDoDmyClk=8/8, + .fastReadDioCmd=0xbb, + .frDioDmyClk=0, + .fastReadQoCmd=0x6b, + .frQoDmyClk=8/8, + + .qpiFastReadQioCmd=0xeb, + .qpiFrQioDmyClk=16/8, + .qpiPageProgramCmd=0x02, + .writeVregEnableCmd=0x50, + + /* qpi mode */ + .enterQpi=0x38, + .exitQpi=0xff, + + /*AC*/ + .timeEsector=300, + .timeE32k=1200, + .timeE64k=1200, + .timePagePgm=5, + .timeCe=33000, + .pdDelay=20, + .qeData=0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_XM25QH16={ + .resetCreadCmd=0xff, + .resetCreadCmdSize=3, + .mid=0x20, + + .deBurstWrapCmd=0x77, + .deBurstWrapCmdDmyClk=0x3, + .deBurstWrapDataMode=SF_CTRL_DATA_4_LINES, + .deBurstWrapData=0xF0, + + /*reg*/ + .writeEnableCmd=0x06, + .wrEnableIndex=0x00, + .wrEnableBit=0x01, + .wrEnableReadRegLen=0x01, + + .qeIndex=1, + .qeBit=0x01, + .qeWriteRegLen=0x01, + .qeReadRegLen=0x1, + + .busyIndex=0, + .busyBit=0x00, + .busyReadRegLen=0x1, + .releasePowerDown=0xab, + + .readRegCmd[0]=0x05, + .readRegCmd[1]=0x35, + .writeRegCmd[0]=0x01, + .writeRegCmd[1]=0x31, + + .fastReadQioCmd=0xeb, + .frQioDmyClk=16/8, + .cReadSupport=1, + .cReadMode=0x20, + + .burstWrapCmd=0x77, + .burstWrapCmdDmyClk=0x3, + .burstWrapDataMode=SF_CTRL_DATA_4_LINES, + .burstWrapData=0x40, + /*erase*/ + .chipEraseCmd=0xc7, + .sectorEraseCmd=0x20, + .blk32EraseCmd=0x52, + .blk64EraseCmd=0xd8, + /*write*/ + .pageProgramCmd=0x02, + .qpageProgramCmd=0x32, + .qppAddrMode=SF_CTRL_ADDR_1_LINE, + + .ioMode=SF_CTRL_QIO_MODE, + .clkDelay=1, + .clkInvert=0x01, + + .resetEnCmd=0x66, + .resetCmd=0x99, + .cRExit=0xff, + .wrEnableWriteRegLen=0x00, + + /*id*/ + .jedecIdCmd=0x9f, + .jedecIdCmdDmyClk=0, + .qpiJedecIdCmd=0x9f, + .qpiJedecIdCmdDmyClk=0x00, + .sectorSize=4, + .pageSize=256, + + /*read*/ + .fastReadCmd=0x0b, + .frDmyClk=8/8, + .qpiFastReadCmd =0x0b, + .qpiFrDmyClk=8/8, + .fastReadDoCmd=0x3b, + .frDoDmyClk=8/8, + .fastReadDioCmd=0xbb, + .frDioDmyClk=0, + .fastReadQoCmd=0x6b, + .frQoDmyClk=8/8, + + .qpiFastReadQioCmd=0xeb, + .qpiFrQioDmyClk=16/8, + .qpiPageProgramCmd=0x02, + .writeVregEnableCmd=0x50, + + /* qpi mode */ + .enterQpi=0x38, + .exitQpi=0xff, + + /*AC*/ + .timeEsector=400, + .timeE32k=1600, + .timeE64k=2000, + .timePagePgm=5, + .timeCe=33000, + .pdDelay=3, + .qeData=0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_MX_KH25={ + .resetCreadCmd=0xff, + .resetCreadCmdSize=3, + .mid=0xc2, + + .deBurstWrapCmd=0x77, + .deBurstWrapCmdDmyClk=0x3, + .deBurstWrapDataMode=SF_CTRL_DATA_4_LINES, + .deBurstWrapData=0xF0, + + /*reg*/ + .writeEnableCmd=0x06, + .wrEnableIndex=0x00, + .wrEnableBit=0x01, + .wrEnableReadRegLen=0x01, + + .qeIndex=1, + .qeBit=0x01, + .qeWriteRegLen=0x01, + .qeReadRegLen=0x1, + + .busyIndex=0, + .busyBit=0x00, + .busyReadRegLen=0x1, + .releasePowerDown=0xab, + + .readRegCmd[0]=0x05, + .readRegCmd[1]=0x00, + .writeRegCmd[0]=0x01, + .writeRegCmd[1]=0x00, + + .fastReadQioCmd=0xeb, + .frQioDmyClk=16/8, + .cReadSupport=0, + .cReadMode=0x20, + + .burstWrapCmd=0x77, + .burstWrapCmdDmyClk=0x3, + .burstWrapDataMode=SF_CTRL_DATA_4_LINES, + .burstWrapData=0x40, + /*erase*/ + .chipEraseCmd=0xc7, + .sectorEraseCmd=0x20, + .blk32EraseCmd=0x52, + .blk64EraseCmd=0xd8, + /*write*/ + .pageProgramCmd=0x02, + .qpageProgramCmd=0x32, + .qppAddrMode=SF_CTRL_ADDR_1_LINE, + + .ioMode=0x11, + .clkDelay=1, + .clkInvert=0x01, + + .resetEnCmd=0x66, + .resetCmd=0x99, + .cRExit=0xff, + .wrEnableWriteRegLen=0x00, + + /*id*/ + .jedecIdCmd=0x9f, + .jedecIdCmdDmyClk=0, + .qpiJedecIdCmd=0x9f, + .qpiJedecIdCmdDmyClk=0x00, + .sectorSize=4, + .pageSize=256, + + /*read*/ + .fastReadCmd=0x0b, + .frDmyClk=8/8, + .qpiFastReadCmd =0x0b, + .qpiFrDmyClk=8/8, + .fastReadDoCmd=0x3b, + .frDoDmyClk=8/8, + .fastReadDioCmd=0xbb, + .frDioDmyClk=0, + .fastReadQoCmd=0x6b, + .frQoDmyClk=8/8, + + .qpiFastReadQioCmd=0xeb, + .qpiFrQioDmyClk=16/8, + .qpiPageProgramCmd=0x02, + .writeVregEnableCmd=0x50, + + /* qpi mode */ + .enterQpi=0x38, + .exitQpi=0xff, + + /*AC*/ + .timeEsector=300, + .timeE32k=1200, + .timeE64k=1200, + .timePagePgm=5, + .timeCe=33000, + .pdDelay=20, + .qeData=0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_ZD_25Q16B={ + .resetCreadCmd=0xff, + .resetCreadCmdSize=3, + .mid=0xba, + + .deBurstWrapCmd=0x77, + .deBurstWrapCmdDmyClk=0x3, + .deBurstWrapDataMode=SF_CTRL_DATA_4_LINES, + .deBurstWrapData=0xF0, + + /*reg*/ + .writeEnableCmd=0x06, + .wrEnableIndex=0x00, + .wrEnableBit=0x01, + .wrEnableReadRegLen=0x01, + + .qeIndex=1, + .qeBit=0x01, + .qeWriteRegLen=0x02, + .qeReadRegLen=0x1, + + .busyIndex=0, + .busyBit=0x00, + .busyReadRegLen=0x1, + .releasePowerDown=0xab, + + .readRegCmd[0]=0x05, + .readRegCmd[1]=0x35, + .writeRegCmd[0]=0x01, + .writeRegCmd[1]=0x01, + + .fastReadQioCmd=0xeb, + .frQioDmyClk=16/8, + .cReadSupport=1, + .cReadMode=0xa0, + + .burstWrapCmd=0x77, + .burstWrapCmdDmyClk=0x3, + .burstWrapDataMode=SF_CTRL_DATA_4_LINES, + .burstWrapData=0x40, + /*erase*/ + .chipEraseCmd=0xc7, + .sectorEraseCmd=0x20, + .blk32EraseCmd=0x52, + .blk64EraseCmd=0xd8, + /*write*/ + .pageProgramCmd=0x02, + .qpageProgramCmd=0x32, + .qppAddrMode=SF_CTRL_ADDR_1_LINE, + + .ioMode=0x14, + .clkDelay=1, + .clkInvert=0x01, + + .resetEnCmd=0x66, + .resetCmd=0x99, + .cRExit=0xff, + .wrEnableWriteRegLen=0x00, + + /*id*/ + .jedecIdCmd=0x9f, + .jedecIdCmdDmyClk=0, + .qpiJedecIdCmd=0x9f, + .qpiJedecIdCmdDmyClk=0x00, + .sectorSize=4, + .pageSize=256, + + /*read*/ + .fastReadCmd=0x0b, + .frDmyClk=8/8, + .qpiFastReadCmd =0x0b, + .qpiFrDmyClk=8/8, + .fastReadDoCmd=0x3b, + .frDoDmyClk=8/8, + .fastReadDioCmd=0xbb, + .frDioDmyClk=0, + .fastReadQoCmd=0x6b, + .frQoDmyClk=8/8, + + .qpiFastReadQioCmd=0xeb, + .qpiFrQioDmyClk=16/8, + .qpiPageProgramCmd=0x02, + .writeVregEnableCmd=0x50, + + /* qpi mode */ + .enterQpi=0x38, + .exitQpi=0xff, + + /*AC*/ + .timeEsector=300, + .timeE32k=1200, + .timeE64k=1200, + .timePagePgm=5, + .timeCe=33000, + .pdDelay=20, + .qeData=0, +}; + +static const ATTR_TCM_CONST_SECTION Flash_Info_t flashInfos[]={ + { + .jedecID=0x1440A1, + //.name="FM_25Q08", + .cfg=&flashCfg_FM_25Q08, + }, + { + .jedecID=0x134051, + //.name="GD_MD04D_04_33", + .cfg=&flashCfg_Gd_Md_40D, + }, + { + .jedecID=0x144020, + //.name="XM_25QH80_80_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x154020, + //.name="XM_25QH16_16_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x164020, + //.name="XM_25QH32_32_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x174020, + //.name="XM_25QH64_64_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x1320C2, + //.name="MX_KH40_04_33", + .cfg=&flashCfg_MX_KH25, + }, + { + .jedecID=0x1420C2, + //.name="MX_KH80_08_33", + .cfg=&flashCfg_MX_KH25, + }, + { + .jedecID=0x1520C2, + //.name="MX_KH16_16_33", + .cfg=&flashCfg_MX_KH25, + }, + { + .jedecID=0x13325E, + //.name="ZB_D40B_80_33", + .cfg=&flashCfg_MX_KH25, + }, + { + .jedecID=0x14325E, + //.name="ZB_D80B_80_33", + .cfg=&flashCfg_MX_KH25, + }, + { + .jedecID=0x15405E, + //.name="ZB_25Q16B_15_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x16405E, + //.name="ZB_25Q32B_16_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x17405E, + //.name="ZB_25VQ64_64_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x15605E, + //.name="ZB_25VQ16_16_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x15345E, + //.name="ZB_25WQ16_16_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x1560EB, + //.name="TH_25Q16", + .cfg=&flashCfg_FM_25Q08, + }, + { + .jedecID=0x1740C8, + //.name="GD_25Q64E_64_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x1840C8, + //.name="GD_25Q127C_128_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x176085, + //.name="Puya_P25Q64H_64_33", + .cfg=&flashCfg_XM25QH16, + }, + { + .jedecID=0x17400B, + //.name="XT_25F64B", + .cfg=&flashCfg_FM_25Q08, + }, + { + .jedecID=0x1560BA, + //.name="ZD_25Q16B", + .cfg=&flashCfg_ZD_25Q16B, + }, + { + .jedecID=0x1460CD, + //.name="TH_25Q80HB", + .cfg=&flashCfg_FM_25Q08, + }, + { + .jedecID=0x1870EF, + //.name="W25Q128JV_128_33", + .cfg=&flashCfg_XM25QH16, + }, +}; + +/*@} end of group SF_CFG_EXT_Private_Variables */ + +/** @defgroup SF_CFG_EXT_Global_Variables + * @{ + */ + +/*@} end of group SF_CFG_EXT_Global_Variables */ + +/** @defgroup SF_CFG_EXT_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SF_CFG_EXT_Private_Fun_Declaration */ + +/** @defgroup SF_CFG_EXT_Public_Functions + * @{ + */ + +/****************************************************************************//** + * @brief Get flash config according to flash ID + * + * @param flashID: Flash ID + * @param pFlashCfg: Flash config pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(uint32_t flashID,SPI_Flash_Cfg_Type * pFlashCfg) +{ + uint32_t i; + uint8_t buf[sizeof(SPI_Flash_Cfg_Type)+8]; + uint32_t crc,*pCrc; + char flashCfgMagic[] = "FCFG"; + + if(flashID==0){ + XIP_SFlash_Read_Via_Cache_Need_Lock(8+BL602_FLASH_XIP_BASE,buf,sizeof(SPI_Flash_Cfg_Type)+8); + if(BL602_MemCmp(buf,flashCfgMagic,4)==0){ + crc=BFLB_Soft_CRC32((uint8_t *)buf+4,sizeof(SPI_Flash_Cfg_Type)); + pCrc=(uint32_t *)(buf+4+sizeof(SPI_Flash_Cfg_Type)); + if(*pCrc==crc){ + BL602_MemCpy_Fast(pFlashCfg,(uint8_t *)buf+4,sizeof(SPI_Flash_Cfg_Type)); + return SUCCESS ; + } + } + }else{ + if(SF_Cfg_Get_Flash_Cfg_Need_Lock(flashID, pFlashCfg) == SUCCESS){ + return SUCCESS; + } + for(i=0;iioMode&0xf,1,0,32); + } + if((ret&BFLB_FLASH_ID_VALID_FLAG)!=0){ + return ret; + } + + jdecId=(ret&0xffffff); + for(i=0;i
© COPYRIGHT(c) 2020 Bouffalo Lab
+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl602_sf_ctrl.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup SF_CTRL + * @{ + */ + +/** @defgroup SF_CTRL_Private_Macros + * @{ + */ + +/*@} end of group SF_CTRL_Private_Macros */ + +/** @defgroup SF_CTRL_Private_Types + * @{ + */ + +/*@} end of group SF_CTRL_Private_Types */ + +/** @defgroup SF_CTRL_Private_Variables + * @{ + */ +#define SF_CTRL_BUSY_STATE_TIMEOUT (5 * 160 * 1000) +#define SF_Ctrl_Get_AES_Region(addr, r) (addr + SF_CTRL_AES_REGION_OFFSET + (r)*0x100) + +/*@} end of group SF_CTRL_Private_Variables */ + +/** @defgroup SF_CTRL_Global_Variables + * @{ + */ + +/*@} end of group SF_CTRL_Global_Variables */ + +/** @defgroup SF_CTRL_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SF_CTRL_Private_Fun_Declaration */ + +/** @defgroup SF_CTRL_Private_Functions + * @{ + */ + +/*@} end of group SF_CTRL_Private_Functions */ + +/** @defgroup SF_CTRL_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Enable serail flash controller + * + * @param cfg: serial flash controller config + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Enable(const SF_Ctrl_Cfg_Type *cfg) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + + if (cfg == NULL) { + return; + } + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_OWNER_TYPE(cfg->owner)); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + if (cfg->clkDelay > 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N, cfg->clkDelay - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN); + } + + /* Serail out inverted, so sf ctrl send on negative edge */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_OUT_INV_SEL, cfg->clkInvert); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_SF_RX_INV_SEL, cfg->rxClkInvert); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal); + + /* Set do di and oe delay */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_0_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_0_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_0_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_1, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_1_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_1_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_1_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_2, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_2_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_2_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_2_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_3, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_3_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_3_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IO_3_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_4, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_0_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_0_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_0_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_1, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_1_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_1_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_1_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_2, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_2_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_2_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_2_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_3, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_3_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_3_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IO_3_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF2_IF_IO_DLY_4, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_0_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_0_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_0_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_1, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_1_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_1_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_1_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_2, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_2_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_2_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_2_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_3, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_3_DO_DLY_SEL, cfg->doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_3_DI_DLY_SEL, cfg->diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF3_IO_3_OE_DLY_SEL, cfg->oeDelay); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF3_IF_IO_DLY_4, tmpVal); + + /* Enable AHB access sram buffer and enable sf interface */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SRAM_EN); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_EN); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal); + + SF_Ctrl_Set_Owner(cfg->owner); +} + +/****************************************************************************/ /** + * @brief Flash pad select + * + * @param sel: pad type + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Select_Pad(SF_Ctrl_Pad_Sel sel) +{ + uint32_t tmpVal; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_PAD_SEL(sel)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_PAD_SEL, sel); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_2, tmpVal); +} + +/****************************************************************************/ /** + * @brief Set flash controller owner:I/D AHB or system AHB + * + * @param owner: owner type + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Set_Owner(SF_Ctrl_Owner_Type owner) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_OWNER_TYPE(owner)); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + /* Set owner */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL, owner); + + /* Set iahb to flash interface */ + if (owner == SF_CTRL_OWNER_IAHB) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SIF_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SIF_EN); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal); +} + +/****************************************************************************/ /** + * @brief Disable flash controller + * + * @param None + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Disable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_EN); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal); +} + +/****************************************************************************/ /** + * @brief Enable flash controller AES with big indian + * + * @param None + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Enable_BE(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_KEY_ENDIAN); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_IV_ENDIAN); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_DOUT_ENDIAN); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal); +} + +/****************************************************************************/ /** + * @brief Enable flash controller AES with little indian + * + * @param None + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Enable_LE(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_KEY_ENDIAN); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_IV_ENDIAN); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_DOUT_ENDIAN); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal); +} + +/****************************************************************************/ /** + * @brief Serial flash controller set AES region + * + * @param region: region number + * @param enable: enable or not + * @param hwKey: hardware key or software key + * @param startAddr: region start address + * @param endAddr: region end address + * @param locked: lock this region or not + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_Region(uint8_t region, uint8_t enable, + uint8_t hwKey, uint32_t startAddr, uint32_t endAddr, uint8_t locked) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, !region); + uint32_t tmpVal; + + tmpVal = BL_RD_REG(regionRegBase, SF_CTRL_SF_AES_CFG); + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_HW_KEY_EN, hwKey); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_START, startAddr / 1024); + /* sf_aes_end =1 means 1,11,1111,1111 */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_END, endAddr / 1024); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_EN, enable); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_LOCK, locked); + + BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_CFG, tmpVal); +} + +/****************************************************************************/ /** + * @brief Serial flash controller set AES key + * + * @param region: region number + * @param key: key data pointer + * @param keyType: flash controller AES key type:128 bits,192 bits or 256 bits + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_Key(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, !region); + uint32_t tmpVal, i = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_AES_KEY_TYPE(keyType)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_MODE, keyType); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); + + if (NULL != key) { + if (keyType == SF_CTRL_AES_128BITS) { + i = 4; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + */ + } else if (keyType == SF_CTRL_AES_256BITS) { + i = 8; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + */ + } else if (keyType == SF_CTRL_AES_192BITS) { + i = 6; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + */ + } + + tmpVal = SF_CTRL_SF_AES_KEY_7_OFFSET; + + while (i--) { + BL_WR_WORD(regionRegBase + tmpVal, __REV(BL_RDWD_FRM_BYTEP(key))); + key += 4; + tmpVal -= 4; + } + } +} + +/****************************************************************************/ /** + * @brief Serial flash controller set AES key with big endian + * + * @param region: region number + * @param key: key data pointer + * @param keyType: flash controller AES key type:128 bits,192 bits or 256 bits + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_Key_BE(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, !region); + uint32_t tmpVal, i = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_AES_KEY_TYPE(keyType)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_MODE, keyType); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); + + if (NULL != key) { + if (keyType == SF_CTRL_AES_128BITS) { + i = 4; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,BL_RDWD_FRM_BYTEP(key)); + key+=4; + */ + } else if (keyType == SF_CTRL_AES_256BITS) { + i = 8; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,BL_RDWD_FRM_BYTEP(key)); + key+=4; + */ + } else if (keyType == SF_CTRL_AES_192BITS) { + i = 6; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,BL_RDWD_FRM_BYTEP(key)); + */ + } + + tmpVal = SF_CTRL_SF_AES_KEY_0_OFFSET; + + while (i--) { + BL_WR_WORD(regionRegBase + tmpVal, BL_RDWD_FRM_BYTEP(key)); + key += 4; + tmpVal += 4; + } + } +} + +/****************************************************************************/ /** + * @brief Serial flash controller set AES iv + * + * @param region: region number + * @param iv: iv data pointer + * @param addrOffset: flash address offset + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_IV(uint8_t region, uint8_t *iv, uint32_t addrOffset) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, !region); + uint32_t tmpVal, i = 3; + + if (iv != NULL) { + tmpVal = SF_CTRL_SF_AES_IV_W3_OFFSET; + + while (i--) { + BL_WR_WORD(regionRegBase + tmpVal, __REV(BL_RDWD_FRM_BYTEP(iv))); + iv += 4; + tmpVal -= 4; + } + + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W3,__REV(BL_RDWD_FRM_BYTEP(iv))); + iv+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W2,__REV(BL_RDWD_FRM_BYTEP(iv))); + iv+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W1,__REV(BL_RDWD_FRM_BYTEP(iv))); + iv+=4; + */ + BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_IV_W0, addrOffset); + iv += 4; + } +} + +/****************************************************************************/ /** + * @brief Serial flash controller set AES iv with big endian + * + * @param region: region number + * @param iv: iv data pointer + * @param addrOffset: flash address offset + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_IV_BE(uint8_t region, uint8_t *iv, uint32_t addrOffset) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, !region); + uint32_t tmpVal, i = 3; + + if (iv != NULL) { + tmpVal = SF_CTRL_SF_AES_IV_W0_OFFSET; + + while (i--) { + BL_WR_WORD(regionRegBase + tmpVal, BL_RDWD_FRM_BYTEP(iv)); + iv += 4; + tmpVal += 4; + } + + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W0,BL_RDWD_FRM_BYTEP(iv)); + iv+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W1,BL_RDWD_FRM_BYTEP(iv)); + iv+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W2,BL_RDWD_FRM_BYTEP(iv)); + iv+=4; + */ + BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_IV_W3, __REV(addrOffset)); + iv += 4; + } +} + +/****************************************************************************/ /** + * @brief Enable serial flash controller AES + * + * @param None + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Enable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_EN); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); +} + +/****************************************************************************/ /** + * @brief Disable serial flash controller AES + * + * @param None + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Disable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_EN); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); +} + +/****************************************************************************/ /** + * @brief Set flash image offset + * + * @param addrOffset: Address offset value + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Set_Flash_Image_Offset(uint32_t addrOffset) +{ + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_ID0_OFFSET, addrOffset); +} + +/****************************************************************************/ /** + * @brief Get flash image offset + * + * @param None + * + * @return :Address offset value + * +*******************************************************************************/ +__WEAK +uint32_t ATTR_TCM_SECTION SF_Ctrl_Get_Flash_Image_Offset(void) +{ + return BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_ID0_OFFSET); +} + +/****************************************************************************/ /** + * @brief SF controller send one command + * + * @param sahbType: Serial flash controller clock sahb sram select + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Select_Clock(SF_Ctrl_Sahb_Type sahbType) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + if (sahbType == SF_CTRL_SAHB_CLOCK) { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_CLK_SAHB_SRAM_SEL); + } else if (sahbType == SF_CTRL_FLASH_CLOCK) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_CLK_SAHB_SRAM_SEL); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal); +} + +/****************************************************************************/ /** + * @brief SF controller send one command + * + * @param cfg: Serial flash controller command configuration pointer + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_SendCmd(SF_Ctrl_Cmd_Cfg_Type *cfg) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_CMD_MODE_TYPE(cfg->cmdMode)); + CHECK_PARAM(IS_SF_CTRL_ADDR_MODE_TYPE(cfg->addrMode)); + CHECK_PARAM(IS_SF_CTRL_DMY_MODE_TYPE(cfg->dummyMode)); + CHECK_PARAM(IS_SF_CTRL_DATA_MODE_TYPE(cfg->dataMode)); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL) != SF_CTRL_OWNER_SAHB) { + return; + } + + /* Clear trigger */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_0); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_TRIG); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_0, tmpVal); + + /* Copy command buffer */ + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_1, cfg->cmdBuf[0]); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_2, cfg->cmdBuf[1]); + + /* Configure SPI and IO mode*/ + if (SF_CTRL_CMD_1_LINE == cfg->cmdMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_QPI_MODE_EN, SF_CTRL_SPI_MODE); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_QPI_MODE_EN, SF_CTRL_QPI_MODE); + } + + if (SF_CTRL_ADDR_1_LINE == cfg->addrMode) { + if (SF_CTRL_DATA_1_LINE == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_SPI_MODE, SF_CTRL_NIO_MODE); + } else if (SF_CTRL_DATA_2_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_SPI_MODE, SF_CTRL_DO_MODE); + } else if (SF_CTRL_DATA_4_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_SPI_MODE, SF_CTRL_QO_MODE); + } + } else if (SF_CTRL_ADDR_2_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_SPI_MODE, SF_CTRL_DIO_MODE); + } else if (SF_CTRL_ADDR_4_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_SPI_MODE, SF_CTRL_QIO_MODE); + } + + /* Configure cmd */ + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_CMD_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_CMD_BYTE, 0); + + /* Configure address */ + if (cfg->addrSize != 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_ADR_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_ADR_BYTE, cfg->addrSize - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_ADR_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_ADR_BYTE, 0); + } + + /* Configure dummy */ + if (cfg->dummyClks != 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_DMY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_DMY_BYTE, cfg->dummyClks - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_DMY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_DMY_BYTE, 0); + } + + /* Configure data */ + if (cfg->nbData != 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_DAT_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_DAT_BYTE, cfg->nbData - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_DAT_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_DAT_BYTE, 0); + } + + /* Set read write flag */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_0_DAT_RW, cfg->rwFlag); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_0, tmpVal); + + //switch sf_clk_sahb_sram_sel = 1 + SF_Ctrl_Select_Clock(SF_CTRL_FLASH_CLOCK); + /* Trigger */ + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_TRIG); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_0, tmpVal); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + SF_Ctrl_Select_Clock(SF_CTRL_SAHB_CLOCK); + return; + } + } + + //switch sf_clk_sahb_sram_sel = 0 + SF_Ctrl_Select_Clock(SF_CTRL_SAHB_CLOCK); +} + +/****************************************************************************/ /** + * @brief Config SF controller for I/D cache read + * + * @param cfg: Serial flash controller command configuration pointer + * @param cmdValid: command valid or not, for continous read, cache may need no command + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Icache_Set(SF_Ctrl_Cmd_Cfg_Type *cfg, uint8_t cmdValid) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_CMD_MODE_TYPE(cfg->cmdMode)); + CHECK_PARAM(IS_SF_CTRL_ADDR_MODE_TYPE(cfg->addrMode)); + CHECK_PARAM(IS_SF_CTRL_DMY_MODE_TYPE(cfg->dummyMode)); + CHECK_PARAM(IS_SF_CTRL_DATA_MODE_TYPE(cfg->dataMode)); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL) != SF_CTRL_OWNER_IAHB) { + return; + } + + /* Copy command buffer */ + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_1, cfg->cmdBuf[0]); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_2, cfg->cmdBuf[1]); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_0); + + /* Configure SPI and IO mode*/ + if (SF_CTRL_CMD_1_LINE == cfg->cmdMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_QPI_MODE_EN, SF_CTRL_SPI_MODE); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_QPI_MODE_EN, SF_CTRL_QPI_MODE); + } + + if (SF_CTRL_ADDR_1_LINE == cfg->addrMode) { + if (SF_CTRL_DATA_1_LINE == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_NIO_MODE); + } else if (SF_CTRL_DATA_2_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_DO_MODE); + } else if (SF_CTRL_DATA_4_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_QO_MODE); + } + } else if (SF_CTRL_ADDR_2_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_DIO_MODE); + } else if (SF_CTRL_ADDR_4_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_QIO_MODE); + } + + if (cmdValid) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_BYTE, 0); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_BYTE, 0); + } + + /* Configure address */ + if (cfg->addrSize != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_BYTE, cfg->addrSize - 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_BYTE, 0); + } + + /* configure dummy */ + if (cfg->dummyClks != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_BYTE, cfg->dummyClks - 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_BYTE, 0); + } + + /* Configure data */ + if (cfg->nbData != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_EN, 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_EN, 0); + } + + /* Set read write flag */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_RW, cfg->rwFlag); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_0, tmpVal); +} + +/****************************************************************************/ /** + * @brief Config SF controller for I/D cache write + * + * @param cfg: Serial flash controller command configuration pointer + * @param cmdValid: command valid or not, cache may need no command + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Icache2_Set(SF_Ctrl_Cmd_Cfg_Type *cfg, uint8_t cmdValid) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_CMD_MODE_TYPE(cfg->cmdMode)); + CHECK_PARAM(IS_SF_CTRL_ADDR_MODE_TYPE(cfg->addrMode)); + CHECK_PARAM(IS_SF_CTRL_DMY_MODE_TYPE(cfg->dummyMode)); + CHECK_PARAM(IS_SF_CTRL_DATA_MODE_TYPE(cfg->dataMode)); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL) != SF_CTRL_OWNER_IAHB) { + return; + } + + /* Copy command buffer */ + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_4, cfg->cmdBuf[0]); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_5, cfg->cmdBuf[1]); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_3); + + /* Configure SPI and IO mode*/ + if (SF_CTRL_CMD_1_LINE == cfg->cmdMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_QPI_MODE_EN, SF_CTRL_SPI_MODE); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_QPI_MODE_EN, SF_CTRL_QPI_MODE); + } + + if (SF_CTRL_ADDR_1_LINE == cfg->addrMode) { + if (SF_CTRL_DATA_1_LINE == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_SPI_MODE, SF_CTRL_NIO_MODE); + } else if (SF_CTRL_DATA_2_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_SPI_MODE, SF_CTRL_DO_MODE); + } else if (SF_CTRL_DATA_4_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_SPI_MODE, SF_CTRL_QO_MODE); + } + } else if (SF_CTRL_ADDR_2_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_SPI_MODE, SF_CTRL_DIO_MODE); + } else if (SF_CTRL_ADDR_4_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_SPI_MODE, SF_CTRL_QIO_MODE); + } + + if (cmdValid) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_CMD_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_CMD_BYTE, 0); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_CMD_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_CMD_BYTE, 0); + } + + /* Configure address */ + if (cfg->addrSize != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_ADR_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_ADR_BYTE, cfg->addrSize - 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_ADR_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_ADR_BYTE, 0); + } + + /* configure dummy */ + if (cfg->dummyClks != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DMY_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DMY_BYTE, cfg->dummyClks - 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DMY_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DMY_BYTE, 0); + } + + /* Configure data */ + if (cfg->nbData != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DAT_EN, 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DAT_EN, 0); + } + + /* Set read write flag */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_2_DAT_RW, cfg->rwFlag); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_3, tmpVal); +} + +/****************************************************************************/ /** + * @brief Get SF Ctrl busy state + * + * @param None + * + * @return SET for SF ctrl busy or RESET for SF ctrl not busy + * +*******************************************************************************/ +__WEAK +BL_Sts_Type ATTR_TCM_SECTION SF_Ctrl_GetBusyState(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_SAHB_0); + + if (BL_IS_REG_BIT_SET(tmpVal, SF_CTRL_SF_IF_BUSY)) { + return SET; + } else { + return RESET; + } +} + +/****************************************************************************/ /** + * @brief Check is serial flash controller AES enable + * + * @param None + * + * @return Wether AES is enable + * +*******************************************************************************/ +__WEAK +uint8_t ATTR_TCM_SECTION SF_Ctrl_Is_AES_Enable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + return BL_IS_REG_BIT_SET(tmpVal, SF_CTRL_SF_AES_EN); +} + +/****************************************************************************/ /** + * @brief Get flash controller clock delay value + * + * @param None + * + * @return Clock delay value + * +*******************************************************************************/ +__WEAK +uint8_t ATTR_TCM_SECTION SF_Ctrl_Get_Clock_Delay(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN) == 0) { + return 0; + } else { + return BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N) + 1; + } +} + +/****************************************************************************/ /** + * @brief Set flash controller clock delay value + * + * @param delay: Clock delay value + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Set_Clock_Delay(uint8_t delay) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + if (delay > 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N, delay - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief SF Controller interrupt handler + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_HAL_DRIVER +void SF_Ctrl_IRQHandler(void) +{ + /* TODO: Not implemented */ +} +#endif + +/*@} end of group SF_CTRL_Public_Functions */ + +/*@} end of group SF_CTRL */ + +/*@} end of group BL602_Peripheral_Driver */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_sflash.c b/drivers/soc/bl602/bl602_std/src/bl602_sflash.c new file mode 100644 index 00000000..d0784417 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_sflash.c @@ -0,0 +1,1549 @@ +/** + ****************************************************************************** + * @file bl602_sflash.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "string.h" +#include "bl602_sflash.h" +#include "bl602_sf_ctrl.h" +#include "bl602_l1c.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup SFLASH + * @{ + */ + +/** @defgroup SFLASH_Private_Macros + * @{ + */ + +/*@} end of group SFLASH_Private_Macros */ + +/** @defgroup SFLASH_Private_Types + * @{ + */ + +/*@} end of group SFLASH_Private_Types */ + +/** @defgroup SFLASH_Private_Variables + * @{ + */ +#define SFCTRL_BUSY_STATE_TIMEOUT (5 * 160 * 1000) + +/*@} end of group SFLASH_Private_Variables */ + +/** @defgroup SFLASH_Global_Variables + * @{ + */ + +/*@} end of group SFLASH_Global_Variables */ + +/** @defgroup SFLASH_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SFLASH_Private_Fun_Declaration */ + +/** @defgroup SFLASH_Private_Functions + * @{ + */ + +/*@} end of group SFLASH_Private_Functions */ + +/** @defgroup SFLASH_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Init serial flash control interface + * + * @param pSfCtrlCfg: Serial flash controller configuration pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_Init(const SF_Ctrl_Cfg_Type *pSfCtrlCfg) +{ + SF_Ctrl_Enable(pSfCtrlCfg); +} + +/****************************************************************************/ /** + * @brief Set serial flash control interface SPI or QPI mode + * + * @param mode: Serial flash interface mode + * + * @return BFLB_RET:SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_SetSPIMode(SF_Ctrl_Mode_Type mode) +{ + BL_Err_Type stat = SUCCESS; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_MODE_TYPE(mode)); + + return stat; +} + +/****************************************************************************/ /** + * @brief Read flash register + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param regIndex: register index + * @param regValue: register value pointer to store data + * @param regLen: register value length + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Read_Reg(SPI_Flash_Cfg_Type *flashCfg, uint8_t regIndex, uint8_t *regValue, uint8_t regLen) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint32_t cnt = 0; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (flashCfg->readRegCmd[regIndex]) << 24; + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.nbData = regLen; + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SF_Ctrl_GetBusyState()) { + BL602_Delay_US(1); + cnt++; + + if (cnt > 1000) { + return ERROR; + } + } + + BL602_MemCpy(regValue, flashCtrlBuf, regLen); + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Write flash register + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param regIndex: register index + * @param regValue: register value pointer storing data + * @param regLen: register value length + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Write_Reg(SPI_Flash_Cfg_Type *flashCfg, uint8_t regIndex, uint8_t *regValue, uint8_t regLen) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t cnt = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + BL602_MemCpy(flashCtrlBuf, regValue, regLen); + + flashCmd.cmdBuf[0] = (flashCfg->writeRegCmd[regIndex]) << 24; + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.nbData = regLen; + + SF_Ctrl_SendCmd(&flashCmd); + + /* take 40ms for tw(write status register) as default */ + while (SET == SFlash_Busy(flashCfg)) { + BL602_Delay_US(100); + cnt++; + + if (cnt > 400) { + return ERROR; + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Check flash busy status + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SET for busy or RESET for not busy + * +*******************************************************************************/ +__WEAK +BL_Sts_Type ATTR_TCM_SECTION SFlash_Busy(SPI_Flash_Cfg_Type *flashCfg) +{ + uint32_t stat = 0; + SFlash_Read_Reg(flashCfg, flashCfg->busyIndex, (uint8_t *)&stat, flashCfg->busyReadRegLen); + + if ((stat & (1 << flashCfg->busyBit)) == 0) { + return RESET; + } + + return SET; +} + +/****************************************************************************/ /** + * @brief Enable flash write function + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Write_Enable(SPI_Flash_Cfg_Type *flashCfg) +{ + uint32_t stat = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + /* Write enable*/ + flashCmd.cmdBuf[0] = (flashCfg->writeEnableCmd) << 24; + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + SF_Ctrl_SendCmd(&flashCmd); + + SFlash_Read_Reg(flashCfg, flashCfg->wrEnableIndex, (uint8_t *)&stat, flashCfg->wrEnableReadRegLen); + + if ((stat & (1 << flashCfg->wrEnableBit)) != 0) { + return SUCCESS; + } + + return ERROR; +} + +/****************************************************************************/ /** + * @brief Enable flash flash controller QSPI interface + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Qspi_Enable(SPI_Flash_Cfg_Type *flashCfg) +{ + uint32_t stat = 0, ret; + + if (flashCfg->qeReadRegLen == 0) { + ret = SFlash_Write_Enable(flashCfg); + + if (SUCCESS != ret) { + return ERROR; + } + + SFlash_Write_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeWriteRegLen); + return SUCCESS; + } + + SFlash_Read_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeReadRegLen); + + if (flashCfg->qeData == 0) { + if ((stat & (1 << flashCfg->qeBit)) != 0) { + return SUCCESS; + } + } else { + if (((stat >> (flashCfg->qeBit & 0x08)) & 0xff) == flashCfg->qeData) { + return SUCCESS; + } + } + + if (flashCfg->qeWriteRegLen != 1) { + /* This is read r0,read r1 write r0,r1 case*/ + SFlash_Read_Reg(flashCfg, 0, (uint8_t *)&stat, 1); + SFlash_Read_Reg(flashCfg, 1, ((uint8_t *)&stat) + 1, 1); + + if (flashCfg->qeData == 0) { + stat |= (1 << (flashCfg->qeBit + 8 * flashCfg->qeIndex)); + } else { + stat = stat & (~(0xff << (8 * flashCfg->qeIndex))); + stat |= (flashCfg->qeData << (8 * flashCfg->qeIndex)); + } + } else { + if (flashCfg->qeData == 0) { + stat |= (1 << (flashCfg->qeBit % 8)); + } else { + stat = flashCfg->qeData; + } + } + + ret = SFlash_Write_Enable(flashCfg); + + if (SUCCESS != ret) { + return ERROR; + } + + SFlash_Write_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeWriteRegLen); + SFlash_Read_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeReadRegLen); + + if (flashCfg->qeData == 0) { + if ((stat & (1 << flashCfg->qeBit)) != 0) { + return SUCCESS; + } + } else { + if (((stat >> (flashCfg->qeBit & 0x08)) & 0xff) == flashCfg->qeData) { + return SUCCESS; + } + } + + return ERROR; +} + +/****************************************************************************/ /** + * @brief Enable flash volatile register write enable + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_Volatile_Reg_Write_Enable(SPI_Flash_Cfg_Type *flashCfg) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (flashCfg->writeVregEnableCmd) << 24; + flashCmd.rwFlag = SF_CTRL_WRITE; + + SF_Ctrl_SendCmd(&flashCmd); +} + +/****************************************************************************/ /** + * @brief Erase flash whole chip + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Chip_Erase(SPI_Flash_Cfg_Type *flashCfg) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint32_t cnt = 0; + BL_Err_Type stat = SFlash_Write_Enable(flashCfg); + + if (stat != SUCCESS) { + return stat; + } + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (flashCfg->chipEraseCmd) << 24; + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SFlash_Busy(flashCfg)) { + BL602_Delay_US(500); + cnt++; + + if (cnt > flashCfg->timeCe * 3) { + return ERROR; + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Erase flash one sector + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param secNum: flash sector number + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Sector_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t secNum) +{ + uint32_t cnt = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + BL_Err_Type stat = SFlash_Write_Enable(flashCfg); + + if (stat != SUCCESS) { + return stat; + } + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (flashCfg->sectorEraseCmd << 24) | (flashCfg->sectorSize * 1024 * secNum); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SFlash_Busy(flashCfg)) { + BL602_Delay_US(500); + cnt++; + + if (cnt > flashCfg->timeEsector * 3) { + return ERROR; + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Erase flash one 32K block + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param blkNum: flash 32K block number + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Blk32_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t blkNum) +{ + uint32_t cnt = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + BL_Err_Type stat = SFlash_Write_Enable(flashCfg); + + if (stat != SUCCESS) { + return stat; + } + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (flashCfg->blk32EraseCmd << 24) | (BFLB_SPIFLASH_BLK32K_SIZE * blkNum); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SFlash_Busy(flashCfg)) { + BL602_Delay_US(500); + cnt++; + + if (cnt > flashCfg->timeE32k * 3) { + return ERROR; + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Erase flash one 64K block + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param blkNum: flash 64K block number + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Blk64_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t blkNum) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint32_t cnt = 0; + BL_Err_Type stat = SFlash_Write_Enable(flashCfg); + + if (stat != SUCCESS) { + return stat; + } + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (flashCfg->blk64EraseCmd << 24) | (BFLB_SPIFLASH_BLK64K_SIZE * blkNum); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SFlash_Busy(flashCfg)) { + BL602_Delay_US(500); + cnt++; + + if (cnt > flashCfg->timeE64k * 3) { + return ERROR; + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Erase flash one region + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param startaddr: start address to erase + * @param endaddr: end address(include this address) to erase + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t startaddr, uint32_t endaddr) +{ + uint32_t len = 0; + uint32_t eraseLen = 0; + BL_Err_Type ret = SUCCESS; + + while (startaddr <= endaddr) { + len = endaddr - startaddr + 1; + + if (flashCfg->blk64EraseCmd != BFLB_SPIFLASH_CMD_INVALID && + (startaddr & (BFLB_SPIFLASH_BLK64K_SIZE - 1)) == 0 && + len > (BFLB_SPIFLASH_BLK64K_SIZE - flashCfg->sectorSize * 1024)) { + /* 64K margin address,and length > 64K-sector size, erase one first */ + ret = SFlash_Blk64_Erase(flashCfg, startaddr / BFLB_SPIFLASH_BLK64K_SIZE); + eraseLen = BFLB_SPIFLASH_BLK64K_SIZE; + } else if (flashCfg->blk32EraseCmd != BFLB_SPIFLASH_CMD_INVALID && + (startaddr & (BFLB_SPIFLASH_BLK32K_SIZE - 1)) == 0 && + len > (BFLB_SPIFLASH_BLK32K_SIZE - flashCfg->sectorSize * 1024)) { + /* 32K margin address,and length > 32K-sector size, erase one first */ + ret = SFlash_Blk32_Erase(flashCfg, startaddr / BFLB_SPIFLASH_BLK32K_SIZE); + eraseLen = BFLB_SPIFLASH_BLK32K_SIZE; + } else { + /* Sector erase */ + startaddr = ((startaddr) & (~(flashCfg->sectorSize * 1024 - 1))); + ret = SFlash_Sector_Erase(flashCfg, startaddr / flashCfg->sectorSize / 1024); + eraseLen = flashCfg->sectorSize * 1024; + } + + startaddr += eraseLen; + + if (ret != SUCCESS) { + return ERROR; + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Program flash one region + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param ioMode: progran mode:SPI mode or QPI mode + * @param addr: start address to be programed + * @param data: data pointer to be programed + * @param len: data length to be programed + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Program(SPI_Flash_Cfg_Type *flashCfg, + SF_Ctrl_IO_Type ioMode, uint32_t addr, uint8_t *data, uint32_t len) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t i = 0, curLen = 0; + uint32_t cnt = 0; + BL_Err_Type stat; + uint8_t cmd; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + if (SF_CTRL_NIO_MODE == ioMode || SF_CTRL_DO_MODE == ioMode || SF_CTRL_DIO_MODE == ioMode) { + cmd = flashCfg->pageProgramCmd; + } else if (SF_CTRL_QIO_MODE == ioMode || SF_CTRL_QO_MODE == ioMode) { + flashCmd.addrMode = (SF_Ctrl_Addr_Mode_Type)flashCfg->qppAddrMode; + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + cmd = flashCfg->qpageProgramCmd; + } else { + return ERROR; + } + + /* Prepare command */ + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.addrSize = 3; + + for (i = 0; i < len;) { + /* Write enable is needed for every program */ + stat = SFlash_Write_Enable(flashCfg); + + if (stat != SUCCESS) { + return stat; + } + + /* Get current programmed length within page size */ + curLen = flashCfg->pageSize - addr % flashCfg->pageSize; + + if (curLen > len - i) { + curLen = len - i; + } + + /* Prepare command */ + BL602_MemCpy_Fast(flashCtrlBuf, data, curLen); + flashCmd.cmdBuf[0] = (cmd << 24) | (addr); + flashCmd.nbData = curLen; + + SF_Ctrl_SendCmd(&flashCmd); + + /* Adjust address and programmed length */ + addr += curLen; + i += curLen; + data += curLen; + + /* Wait for write done */ + cnt = 0; + + while (SET == SFlash_Busy(flashCfg)) { + BL602_Delay_US(100); + cnt++; + + if (cnt > flashCfg->timePagePgm * 20) { + return ERROR; + } + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Get flash unique ID + * + * @param data: data pointer to store read data + * @param idLen: unique ID len + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_GetUniqueId(uint8_t *data, uint8_t idLen) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint8_t cmd, dummyClks; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + dummyClks = 4; + cmd = 0x4B; + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = idLen; + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + BL602_MemCpy(data, flashCtrlBuf, idLen); +} + +/****************************************************************************/ /** + * @brief Get flash jedec ID + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param data: data pointer to store read data + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_GetJedecId(SPI_Flash_Cfg_Type *flashCfg, uint8_t *data) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint8_t cmd, dummyClks; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + dummyClks = flashCfg->jedecIdCmdDmyClk; + cmd = flashCfg->jedecIdCmd; + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = 3; + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + BL602_MemCpy(data, flashCtrlBuf, 3); +} + +/****************************************************************************/ /** + * @brief Get flash device ID + * + * @param data: data pointer to store read data + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_GetDeviceId(uint8_t *data) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint8_t cmd, dummyClks; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint32_t addr = 0x00000001; + uint8_t readMode = 0xFF; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.addrMode = SF_CTRL_ADDR_4_LINES; + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + dummyClks = 2; + cmd = 0x94; + flashCmd.cmdBuf[0] = (cmd << 24) | (addr); + flashCmd.cmdBuf[1] = (readMode << 24); + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 4; + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = 2; + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + BL602_MemCpy(data, flashCtrlBuf, 2); +} + +/****************************************************************************/ /** + * @brief Set flash power down + * + * @param None + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_Powerdown(void) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint8_t cmd = 0; + uint32_t timeOut = 0; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + cmd = 0xB9; + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } +} + +/****************************************************************************/ /** + * @brief Release flash power down for wake up + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_Releae_Powerdown(SPI_Flash_Cfg_Type *flashCfg) +{ + uint8_t cmd; + uint32_t timeOut = 0; + + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + cmd = flashCfg->releasePowerDown; + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } +} + +/****************************************************************************/ /** + * @brief Set flash burst wrap config + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_SetBurstWrap(SPI_Flash_Cfg_Type *flashCfg) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint8_t cmd, dummyClks; + uint32_t wrapData; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((flashCfg->ioMode >> 4) & 0x01) == 1) { + /* Disable burst wrap ,just return */ + return; + } + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.addrMode = (SF_Ctrl_Addr_Mode_Type)flashCfg->burstWrapDataMode; + flashCmd.dataMode = (SF_Ctrl_Data_Mode_Type)flashCfg->burstWrapDataMode; + dummyClks = flashCfg->burstWrapCmdDmyClk; + cmd = flashCfg->burstWrapCmd; + wrapData = flashCfg->burstWrapData; + BL602_MemCpy4((uint32_t *)flashCtrlBuf, &wrapData, 4); + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = 1; + + SF_Ctrl_SendCmd(&flashCmd); +} + +/****************************************************************************/ /** + * @brief Disable flash burst wrap config + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_DisableBurstWrap(SPI_Flash_Cfg_Type *flashCfg) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint8_t cmd, dummyClks; + uint32_t wrapData; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.addrMode = (SF_Ctrl_Addr_Mode_Type)flashCfg->deBurstWrapDataMode; + flashCmd.dataMode = (SF_Ctrl_Data_Mode_Type)flashCfg->deBurstWrapDataMode; + dummyClks = flashCfg->deBurstWrapCmdDmyClk; + cmd = flashCfg->deBurstWrapCmd; + wrapData = flashCfg->deBurstWrapData; + BL602_MemCpy4((uint32_t *)flashCtrlBuf, &wrapData, 4); + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = 1; + + SF_Ctrl_SendCmd(&flashCmd); +} + +/****************************************************************************/ /** + * @brief Software reset flash + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Software_Reset(SPI_Flash_Cfg_Type *flashCfg) +{ + uint16_t cnt = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + /* Reset enable */ + flashCmd.cmdBuf[0] = (flashCfg->resetEnCmd) << 24; + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + + /* Wait for write done */ + while (SET == SFlash_Busy(flashCfg)) { + BL602_Delay_US(100); + cnt++; + + if (cnt > 20) { + return ERROR; + } + } + + SF_Ctrl_SendCmd(&flashCmd); + + /* Reset */ + flashCmd.cmdBuf[0] = (flashCfg->resetCmd) << 24; + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + SF_Ctrl_SendCmd(&flashCmd); + + BL602_Delay_US(50); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Reset flash continous read mode + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_Reset_Continue_Read(SPI_Flash_Cfg_Type *flashCfg) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + /* Reset continous read */ + BL602_MemSet(&flashCmd.cmdBuf[0], flashCfg->resetCreadCmd, 4); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = flashCfg->resetCreadCmdSize; + SF_Ctrl_SendCmd(&flashCmd); +} + +/****************************************************************************/ /** + * @brief Set I/D bus read flash configuration in flash controller + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param ioMode: flash controller interface mode + * @param contRead: Wether enable cont read mode + * @param addr: address to read/write + * @param len: data length to read/write + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Set_IDbus_Cfg(SPI_Flash_Cfg_Type *flashCfg, + SF_Ctrl_IO_Type ioMode, uint8_t contRead, uint32_t addr, uint32_t len) +{ + uint8_t cmd, dummyClks; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint8_t cmdValid = 1; + uint8_t noReadModeCfg = 0; + uint8_t cReadSupport = 0; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + SF_Ctrl_Set_Owner(SF_CTRL_OWNER_IAHB); + + if (SF_CTRL_NIO_MODE == ioMode) { + cmd = flashCfg->fastReadCmd; + dummyClks = flashCfg->frDmyClk; + } else if (SF_CTRL_DO_MODE == ioMode) { + flashCmd.dataMode = SF_CTRL_DATA_2_LINES; + cmd = flashCfg->fastReadDoCmd; + dummyClks = flashCfg->frDoDmyClk; + } else if (SF_CTRL_DIO_MODE == ioMode) { + flashCmd.addrMode = SF_CTRL_ADDR_2_LINES; + flashCmd.dataMode = SF_CTRL_DATA_2_LINES; + cmd = flashCfg->fastReadDioCmd; + dummyClks = flashCfg->frDioDmyClk; + } else if (SF_CTRL_QO_MODE == ioMode) { + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + cmd = flashCfg->fastReadQoCmd; + dummyClks = flashCfg->frQoDmyClk; + } else if (SF_CTRL_QIO_MODE == ioMode) { + flashCmd.addrMode = SF_CTRL_ADDR_4_LINES; + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + cmd = flashCfg->fastReadQioCmd; + dummyClks = flashCfg->frQioDmyClk; + } else { + return ERROR; + } + + /*prepare command**/ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + flashCmd.cmdBuf[0] = (cmd << 24) | addr; + + if (SF_CTRL_QIO_MODE == ioMode || SF_CTRL_DIO_MODE == ioMode) { + noReadModeCfg = flashCfg->cReadSupport & 0x02; + cReadSupport = flashCfg->cReadSupport & 0x01; + + if (noReadModeCfg == 0) { + /* Read mode must be set*/ + if (cReadSupport == 0) { + /* Not support cont read,but we still need set read mode(winbond 80dv)*/ + flashCmd.cmdBuf[1] = (flashCfg->cReadMode << 24); + } else { + /* Flash support cont read, setting depend on user parameter */ + if (contRead) { + flashCmd.cmdBuf[0] = (addr << 8) | flashCfg->cReadMode; + cmdValid = 0; + } else { + flashCmd.cmdBuf[1] = ((!flashCfg->cReadMode) << 24); + } + } + + flashCmd.addrSize++; + } + } + + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = len; + SF_Ctrl_Icache_Set(&flashCmd, cmdValid); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Enable I/D bus read from flash + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param ioMode: flash controller interface mode + * @param contRead: Wether enable cont read mode + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_IDbus_Read_Enable(SPI_Flash_Cfg_Type *flashCfg, SF_Ctrl_IO_Type ioMode, uint8_t contRead) +{ + BL_Err_Type stat; + + stat = SFlash_Set_IDbus_Cfg(flashCfg, ioMode, contRead, 0, 4); + + if (SUCCESS != stat) { + return stat; + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Enable cache + * + * @param wayDisable: cache way disable config + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Cache_Enable_Set(uint8_t wayDisable) +{ + uint32_t tmpVal; + uint32_t cnt = 0; + + /* Set cacheable to 0 */ + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_CACHEABLE); + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_BYPASS); + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_WAY_DIS); + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_CNT_EN); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + /*Set Tag RAM to zero */ + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_INVALID_EN); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + /* Left space for hardware change status*/ + __NOP(); + __NOP(); + __NOP(); + __NOP(); + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_INVALID_EN); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + /* Left space for hardware change status*/ + __NOP(); + __NOP(); + __NOP(); + __NOP(); + + /* Polling for invalid done */ + do { + BL602_Delay_US(1); + cnt++; + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + } while (!BL_IS_REG_BIT_SET(tmpVal, L1C_INVALID_DONE) && cnt < 100); + + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_BYPASS); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_BYPASS); + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_WAY_DIS); + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_CNT_EN); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + + tmpVal |= (wayDisable << L1C_WAY_DIS_POS); + + /* If way disable is 0x0f, cacheable can't be set */ + if (wayDisable != 0x0f) { + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_CACHEABLE); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_CACHEABLE); + } + + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Flush cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Cache_Flush(void) +{ + uint32_t tmpVal; + + /* Disable early respone */ + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + SFlash_Cache_Enable_Set((tmpVal >> L1C_WAY_DIS_POS) & 0xf); + __NOP(); + __NOP(); + __NOP(); + __NOP(); + __NOP(); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Enable cache read from flash with cache + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param ioMode: flash controller interface mode + * @param contRead: Wether enable cont read mode + * @param wayDisable: cache way disable config + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Cache_Read_Enable(SPI_Flash_Cfg_Type *flashCfg, + SF_Ctrl_IO_Type ioMode, uint8_t contRead, uint8_t wayDisable) +{ + BL_Err_Type stat; + + /* Cache now only support 32 bytes read */ + stat = SFlash_Set_IDbus_Cfg(flashCfg, ioMode, contRead, 0, 32); + + if (SUCCESS != stat) { + return stat; + } + + return SFlash_Cache_Enable_Set(wayDisable); +} + +/****************************************************************************/ /** + * @brief Get cache hit count + * + * @param hitCountLow: hit count low 32 bits pointer + * @param hitCountHigh: hit count high 32 bits pointer + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_Cache_Hit_Count_Get(uint32_t *hitCountLow, uint32_t *hitCountHigh) +{ + *hitCountLow = BL_RD_REG(L1C_BASE, L1C_HIT_CNT_LSB); + *hitCountHigh = BL_RD_REG(L1C_BASE, L1C_HIT_CNT_MSB); +} + +/****************************************************************************/ /** + * @brief Get cache miss count + * + * @param None + * + * @return Cache miss count + * +*******************************************************************************/ +__WEAK +uint32_t ATTR_TCM_SECTION SFlash_Cache_Miss_Count_Get(void) +{ + return BL_RD_REG(L1C_BASE, L1C_MISS_CNT); +} + +/****************************************************************************/ /** + * @brief Disable read from flash with cache + * + * @param None + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SFlash_Cache_Read_Disable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_CACHEABLE); + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); +} + +/****************************************************************************/ /** + * @brief Read data from flash + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param ioMode: flash controller interface mode + * @param contRead: Wether enable cont read mode + * @param addr: flash read start address + * @param data: data pointer to store data read from flash + * @param len: data length to read + * + * @return None + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Read(SPI_Flash_Cfg_Type *flashCfg, + SF_Ctrl_IO_Type ioMode, uint8_t contRead, uint32_t addr, uint8_t *data, uint32_t len) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t curLen, i; + uint8_t cmd, dummyClks; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint8_t noReadModeCfg = 0; + uint8_t cReadSupport = 0; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + if (SF_CTRL_NIO_MODE == ioMode) { + cmd = flashCfg->fastReadCmd; + dummyClks = flashCfg->frDmyClk; + } else if (SF_CTRL_DO_MODE == ioMode) { + flashCmd.dataMode = SF_CTRL_DATA_2_LINES; + cmd = flashCfg->fastReadDoCmd; + dummyClks = flashCfg->frDoDmyClk; + } else if (SF_CTRL_DIO_MODE == ioMode) { + flashCmd.addrMode = SF_CTRL_ADDR_2_LINES; + flashCmd.dataMode = SF_CTRL_DATA_2_LINES; + cmd = flashCfg->fastReadDioCmd; + dummyClks = flashCfg->frDioDmyClk; + } else if (SF_CTRL_QO_MODE == ioMode) { + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + cmd = flashCfg->fastReadQoCmd; + dummyClks = flashCfg->frQoDmyClk; + } else if (SF_CTRL_QIO_MODE == ioMode) { + flashCmd.addrMode = SF_CTRL_ADDR_4_LINES; + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + cmd = flashCfg->fastReadQioCmd; + dummyClks = flashCfg->frQioDmyClk; + } else { + return ERROR; + } + + /* Prepare command */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + if (SF_CTRL_QIO_MODE == ioMode || SF_CTRL_DIO_MODE == ioMode) { + noReadModeCfg = flashCfg->cReadSupport & 0x02; + cReadSupport = flashCfg->cReadSupport & 0x01; + + if (noReadModeCfg == 0) { + /* Read mode must be set*/ + if (cReadSupport == 0) { + /* Not support cont read,but we still need set read mode(winbond 80dv)*/ + flashCmd.cmdBuf[1] = (flashCfg->cReadMode << 24); + } else { + /* Flash support cont read, setting depend on user parameter */ + if (contRead) { + flashCmd.cmdBuf[1] = (flashCfg->cReadMode << 24); + } else { + flashCmd.cmdBuf[1] = ((!flashCfg->cReadMode) << 24); + } + } + + flashCmd.addrSize++; + } + } + + flashCmd.dummyClks = dummyClks; + + /* Read data */ + for (i = 0; i < len;) { + /* Prepare command */ + flashCmd.cmdBuf[0] = (cmd << 24) | (addr); + curLen = len - i; + + if (curLen >= FLASH_CTRL_BUF_SIZE) { + curLen = FLASH_CTRL_BUF_SIZE; + flashCmd.nbData = curLen; + } else { + /* Make sf_ctrl word read */ + flashCmd.nbData = ((curLen + 3) >> 2) << 2; + } + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + + BL602_MemCpy_Fast(data, flashCtrlBuf, curLen); + + addr += curLen; + i += curLen; + data += curLen; + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Read flash register with read command + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param readRegCmd: read command + * @param regValue: register value pointer to store data + * @param regLen: register value length + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Read_Reg_With_Cmd(SPI_Flash_Cfg_Type *flashCfg, uint8_t readRegCmd, uint8_t *regValue, uint8_t regLen) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint32_t cnt = 0; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = readRegCmd << 24; + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.nbData = regLen; + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SF_Ctrl_GetBusyState()) { + BL602_Delay_US(1); + cnt++; + + if (cnt > 1000) { + return ERROR; + } + } + + BL602_MemCpy(regValue, flashCtrlBuf, regLen); + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Write flash register with write command + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param writeRegCmd: write command + * @param regValue: register value pointer storing data + * @param regLen: register value length + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Write_Reg_With_Cmd(SPI_Flash_Cfg_Type *flashCfg, uint8_t writeRegCmd, uint8_t *regValue, uint8_t regLen) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t cnt = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + BL602_MemCpy(flashCtrlBuf, regValue, regLen); + + flashCmd.cmdBuf[0] = writeRegCmd << 24; + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.nbData = regLen; + + SF_Ctrl_SendCmd(&flashCmd); + + /* take 40ms for tw(write status register) as default */ + while (SET == SFlash_Busy(flashCfg)) { + BL602_Delay_US(100); + cnt++; + + if (cnt > 400) { + return ERROR; + } + } + + return SUCCESS; +} +#endif + +/*@} end of group SFLASH_Public_Functions */ + +/*@} end of group SFLASH */ + +/*@} end of group BL602_Peripheral_Driver */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_sflash_ext.c b/drivers/soc/bl602/bl602_std/src/bl602_sflash_ext.c new file mode 100644 index 00000000..8d147e5a --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_sflash_ext.c @@ -0,0 +1,608 @@ +/** + ****************************************************************************** + * @file bl602_sflash_ext.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl602_l1c.h" +#include "bl602_sflash_ext.h" +#include "bl602_sf_ctrl.h" +#include "l1c_reg.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup SFLASH_EXT + * @{ + */ + +/** @defgroup SFLASH_EXT_Private_Macros + * @{ + */ + +/*@} end of group SFLASH_EXT_Private_Macros */ + +/** @defgroup SFLASH_EXT_Private_Types + * @{ + */ + +/*@} end of group SFLASH_EXT_Private_Types */ + +/** @defgroup SFLASH_EXT_Private_Variables + * @{ + */ +#define SFCTRL_BUSY_STATE_TIMEOUT (5 * 160 * 1000) + +/*@} end of group SFLASH_EXT_Private_Variables */ + +/** @defgroup SFLASH_EXT_Global_Variables + * @{ + */ + +/*@} end of group SFLASH_EXT_Global_Variables */ + +/** @defgroup SFLASH_EXT_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SFLASH_EXT_Private_Fun_Declaration */ + +/** @defgroup SFLASH_EXT_Private_Functions + * @{ + */ + +/*@} end of group SFLASH_EXT_Private_Functions */ + +/** @defgroup SFLASH_EXT_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Sflash restore from power down + * + * @param pFlashCfg: Flash configuration pointer + * @param flashContRead: Whether enable continuous read + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_Restore_From_Powerdown(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t flashContRead) +{ + BL_Err_Type stat = SUCCESS; + uint32_t jdecId = 0; + uint8_t tmp[8]; + uint8_t ioMode = pFlashCfg->ioMode & 0xf; + + /* Wake flash up from power down */ + SFlash_Releae_Powerdown(pFlashCfg); + BL602_Delay_US(120); + + SFlash_GetJedecId(pFlashCfg, (uint8_t *)&jdecId); + + if (SF_CTRL_QO_MODE == ioMode || SF_CTRL_QIO_MODE == ioMode) { + SFlash_Qspi_Enable(pFlashCfg); + } + + if (((pFlashCfg->ioMode >> 4) & 0x01) == 1) { + /* unwrap */ + L1C_Set_Wrap(DISABLE); + } else { + /* burst wrap */ + L1C_Set_Wrap(ENABLE); + /* For command that is setting register instead of send command, we need write enable */ + SFlash_Write_Enable(pFlashCfg); + SFlash_SetBurstWrap(pFlashCfg); + } + + if (flashContRead) { + stat = SFlash_Read(pFlashCfg, ioMode, 1, 0x00000000, (uint8_t *)tmp, sizeof(tmp)); + stat = SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32); + } else { + stat = SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 0, 0, 32); + } + + return stat; +} + +/****************************************************************************/ /** + * @brief Sflash enable RCV mode to recovery for erase while power drop + * + * @param pFlashCfg: Flash configuration pointer + * @param rCmd: Read RCV register cmd + * @param wCmd: Write RCV register cmd + * @param bitPos: RCV register bit pos + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_RCV_Enable(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t rCmd, uint8_t wCmd, uint8_t bitPos) +{ + BL_Err_Type stat; + uint32_t cnt = 0; + uint32_t tempVal = 0; + + while (SET == SFlash_Busy(pFlashCfg)) { + BL602_Delay_US(500); + cnt++; + + if (cnt > 20000 * 3) { + return ERROR; + } + } + + stat = SFlash_Read_Reg_With_Cmd(pFlashCfg, rCmd, (uint8_t *)&tempVal, 1); + + if (SUCCESS != stat) { + stat = ERROR; + } + + if (((tempVal >> bitPos) & 0x01) > 0) { + return SUCCESS; + } + + tempVal |= (uint32_t)(1 << bitPos); + stat = SFlash_Write_Enable(pFlashCfg); + + if (SUCCESS != stat) { + stat = ERROR; + } + + stat = SFlash_Write_Reg_With_Cmd(pFlashCfg, wCmd, (uint8_t *)&tempVal, 1); + + if (SUCCESS != stat) { + return stat; + } + + while (SET == SFlash_Busy(pFlashCfg)) { + BL602_Delay_US(500); + cnt++; + + if (cnt > 20000 * 3) { + return ERROR; + } + } + + stat = SFlash_Read_Reg_With_Cmd(pFlashCfg, rCmd, (uint8_t *)&tempVal, 1); + + if (SUCCESS != stat) { + stat = ERROR; + } + + if (((tempVal >> bitPos) & 0x01) <= 0) { + return ERROR; + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Erase flash security register one block + * + * @param pFlashCfg: Flash configuration pointer + * @param pSecRegCfg: Security register configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_Erase_Security_Register(SPI_Flash_Cfg_Type *pFlashCfg, SFlash_Sec_Reg_Cfg *pSecRegCfg) +{ + uint32_t cnt = 0; + uint8_t cmd = 0; + uint8_t secOptMode = 0; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (pSecRegCfg->enterSecOptCmd != 0x00) { + secOptMode = 1; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->enterSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + BL_Err_Type stat = SFlash_Write_Enable(pFlashCfg); + + if (stat != SUCCESS) { + return stat; + } + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + cmd = pSecRegCfg->eraseCmd; + flashCmd.cmdBuf[0] = (cmd << 24) | (pSecRegCfg->blockNum << 12); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SFlash_Busy(pFlashCfg)) { + BL602_Delay_US(500); + cnt++; + + if (cnt > pFlashCfg->timeEsector * 3) { + return ERROR; + } + } + + if (secOptMode > 0) { + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->exitSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Program flash security register one block + * + * @param pFlashCfg: Flash configuration pointer + * @param pSecRegCfg: Security register configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_Program_Security_Register(SPI_Flash_Cfg_Type *pFlashCfg, SFlash_Sec_Reg_Cfg *pSecRegCfg) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t i = 0, curLen = 0; + uint32_t cnt = 0; + BL_Err_Type stat; + uint8_t cmd; + uint8_t secOptMode = 0; + uint8_t *data = pSecRegCfg->data; + uint32_t addr = pSecRegCfg->addr; + uint32_t len = pSecRegCfg->len; + uint32_t currentAddr = 0; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (pSecRegCfg->enterSecOptCmd != 0x00) { + secOptMode = 1; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->enterSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + /* Prepare command */ + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.addrSize = 3; + cmd = pSecRegCfg->programCmd; + + for (i = 0; i < len;) { + /* Write enable is needed for every program */ + stat = SFlash_Write_Enable(pFlashCfg); + + if (stat != SUCCESS) { + return stat; + } + + /* Get current programmed length within page size */ + curLen = 256 - addr % 256; + + if (curLen > len - i) { + curLen = len - i; + } + + currentAddr = (pSecRegCfg->blockNum << 12) | addr; + + /* Prepare command */ + BL602_MemCpy_Fast(flashCtrlBuf, data, curLen); + flashCmd.cmdBuf[0] = (cmd << 24) | (currentAddr); + flashCmd.nbData = curLen; + + SF_Ctrl_SendCmd(&flashCmd); + + /* Adjust address and programmed length */ + addr += curLen; + i += curLen; + data += curLen; + + /* Wait for write done */ + cnt = 0; + + while (SET == SFlash_Busy(pFlashCfg)) { + BL602_Delay_US(100); + cnt++; + + if (cnt > pFlashCfg->timePagePgm * 20) { + return ERROR; + } + } + } + + if (secOptMode > 0) { + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->exitSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Read data from flash security register one block + * + * @param pSecRegCfg: Security register configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_Read_Security_Register(SFlash_Sec_Reg_Cfg *pSecRegCfg) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t curLen, i; + uint8_t cmd; + uint8_t secOptMode = 0; + uint8_t *data = pSecRegCfg->data; + uint32_t addr = pSecRegCfg->addr; + uint32_t len = pSecRegCfg->len; + uint32_t currentAddr = 0; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (pSecRegCfg->enterSecOptCmd != 0x00) { + secOptMode = 1; + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->enterSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + /* Prepare command */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + flashCmd.dummyClks = 1; + cmd = pSecRegCfg->readCmd; + + /* Read data */ + for (i = 0; i < len;) { + currentAddr = (pSecRegCfg->blockNum << 12) | addr; + /* Prepare command */ + flashCmd.cmdBuf[0] = (cmd << 24) | (currentAddr); + curLen = len - i; + + if (curLen >= FLASH_CTRL_BUF_SIZE) { + curLen = FLASH_CTRL_BUF_SIZE; + flashCmd.nbData = curLen; + } else { + /* Make sf_ctrl word read */ + flashCmd.nbData = ((curLen + 3) >> 2) << 2; + } + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + + BL602_MemCpy_Fast(data, flashCtrlBuf, curLen); + + addr += curLen; + i += curLen; + data += curLen; + } + + if (secOptMode > 0) { + if (((uint32_t)&flashCmd) % 4 == 0) { + BL602_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + BL602_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->exitSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + return SUCCESS; +} + +/****************************************************************************//** + * @brief Clear flash status register + * + * @param pFlashCfg: Flash configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_Clear_Status_Register(SPI_Flash_Cfg_Type *pFlashCfg) +{ + uint32_t ret = 0; + uint32_t qeValue = 0; + uint32_t regValue = 0; + uint32_t readValue = 0; + uint8_t readRegValue0 = 0; + uint8_t readRegValue1 = 0; + + if((pFlashCfg->ioMode&0xf)==SF_CTRL_QO_MODE || (pFlashCfg->ioMode&0xf)==SF_CTRL_QIO_MODE){ + qeValue = 1; + } + + SFlash_Read_Reg(pFlashCfg, 0, (uint8_t *)&readRegValue0, 1); + SFlash_Read_Reg(pFlashCfg, 1, (uint8_t *)&readRegValue1, 1); + readValue = (readRegValue0|(readRegValue1<<8)); + if ((readValue & (~((1<<(pFlashCfg->qeIndex*8+pFlashCfg->qeBit)) | + (1<<(pFlashCfg->busyIndex*8+pFlashCfg->busyBit)) | + (1<<(pFlashCfg->wrEnableIndex*8+pFlashCfg->wrEnableBit))))) == 0){ + return SUCCESS; + } + + ret = SFlash_Write_Enable(pFlashCfg); + if (SUCCESS != ret) { + return ERROR; + } + if (pFlashCfg->qeWriteRegLen == 2) { + regValue = (qeValue<<(pFlashCfg->qeIndex*8+pFlashCfg->qeBit)); + SFlash_Write_Reg(pFlashCfg, 0, (uint8_t *)®Value, 2); + } else { + if (pFlashCfg->qeIndex == 0) { + regValue = (qeValue<qeBit); + } else { + regValue = 0; + } + SFlash_Write_Reg(pFlashCfg, 0, (uint8_t *)®Value, 1); + ret = SFlash_Write_Enable(pFlashCfg); + if (SUCCESS != ret) { + return ERROR; + } + if (pFlashCfg->qeIndex == 1) { + regValue = (qeValue<qeBit); + } else { + regValue = 0; + } + SFlash_Write_Reg(pFlashCfg, 1, (uint8_t *)®Value, 1); + } + return SUCCESS; +} + +/*@} end of group SFLASH_EXT_Public_Functions */ + +/*@} end of group SFLASH_EXT */ + +/*@} end of group BL602_Peripheral_Driver */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_xip_sflash.c b/drivers/soc/bl602/bl602_std/src/bl602_xip_sflash.c new file mode 100644 index 00000000..873c8201 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_xip_sflash.c @@ -0,0 +1,434 @@ +/** + ****************************************************************************** + * @file bl602_xip_sflash.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "string.h" +#include "bl602_xip_sflash.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup XIP_SFLASH + * @{ + */ + +/** @defgroup XIP_SFLASH_Private_Macros + * @{ + */ + +/*@} end of group XIP_SFLASH_Private_Macros */ + +/** @defgroup XIP_SFLASH_Private_Types + * @{ + */ + +/*@} end of group XIP_SFLASH_Private_Types */ + +/** @defgroup XIP_SFLASH_Private_Variables + * @{ + */ + +/*@} end of group XIP_SFLASH_Private_Variables */ + +/** @defgroup XIP_SFLASH_Global_Variables + * @{ + */ + +/*@} end of group XIP_SFLASH_Global_Variables */ + +/** @defgroup XIP_SFLASH_Private_Fun_Declaration + * @{ + */ + +/*@} end of group XIP_SFLASH_Private_Fun_Declaration */ + +/** @defgroup XIP_SFLASH_Private_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Save flash controller state + * + * @param pFlashCfg: Flash config pointer + * @param offset: CPU XIP flash offset pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_State_Save(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t *offset) +{ + /* XIP_SFlash_Delay */ + volatile uint32_t i = 32 * 2; + + while (i--) + ; + + SF_Ctrl_Set_Owner(SF_CTRL_OWNER_SAHB); + /* Exit form continous read for accepting command */ + SFlash_Reset_Continue_Read(pFlashCfg); + /* Send software reset command(80bv has no this command)to deburst wrap for ISSI like */ + SFlash_Software_Reset(pFlashCfg); + /* For disable command that is setting register instaed of send command, we need write enable */ + SFlash_DisableBurstWrap(pFlashCfg); + /* Enable QE again in case reset command make it reset */ + SFlash_Qspi_Enable(pFlashCfg); + /* Deburst again to make sure */ + SFlash_DisableBurstWrap(pFlashCfg); + + /* Clear offset setting*/ + *offset = SF_Ctrl_Get_Flash_Image_Offset(); + SF_Ctrl_Set_Flash_Image_Offset(0); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Restore flash controller state + * + * @param pFlashCfg: Flash config pointer + * @param offset: CPU XIP flash offset + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_State_Restore(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t offset) +{ + uint32_t tmp[1]; + + SF_Ctrl_Set_Flash_Image_Offset(offset); + + SFlash_SetBurstWrap(pFlashCfg); + SFlash_Read(pFlashCfg, SF_CTRL_QIO_MODE, 1, 0x0, (uint8_t *)tmp, sizeof(tmp)); + SFlash_Set_IDbus_Cfg(pFlashCfg, SF_CTRL_QIO_MODE, 1, 0, 32); + + return SUCCESS; +} + +/*@} end of group XIP_SFLASH_Private_Functions */ + +/** @defgroup XIP_SFLASH_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Erase flash one region + * + * @param pFlashCfg: Flash config pointer + * @param startaddr: start address to erase + * @param endaddr: end address(include this address) to erase + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Erase_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t startaddr, uint32_t endaddr) +{ + BL_Err_Type stat; + uint32_t offset; + + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, SF_CTRL_QIO_MODE, 1, 0, 32); + } else { + stat = SFlash_Erase(pFlashCfg, startaddr, endaddr); + XIP_SFlash_State_Restore(pFlashCfg, offset); + } + + return stat; +} + +/****************************************************************************/ /** + * @brief Program flash one region + * + * @param pFlashCfg: Flash config pointer + * @param addr: start address to be programed + * @param data: data pointer to be programed + * @param len: data length to be programed + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Write_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t addr, uint8_t *data, uint32_t len) +{ + BL_Err_Type stat; + uint32_t offset; + + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, SF_CTRL_QIO_MODE, 1, 0, 32); + } else { + stat = SFlash_Program(pFlashCfg, SF_CTRL_QIO_MODE, addr, data, len); + XIP_SFlash_State_Restore(pFlashCfg, offset); + } + + return stat; +} + +/****************************************************************************/ /** + * @brief Read data from flash + * + * @param pFlashCfg: Flash config pointer + * @param addr: flash read start address + * @param data: data pointer to store data read from flash + * @param len: data length to read + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Read_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t addr, uint8_t *data, uint32_t len) +{ + BL_Err_Type stat; + uint32_t offset; + + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, SF_CTRL_QIO_MODE, 1, 0, 32); + } else { + stat = SFlash_Read(pFlashCfg, SF_CTRL_QIO_MODE, 0, addr, data, len); + XIP_SFlash_State_Restore(pFlashCfg, offset); + } + + return stat; +} + +/****************************************************************************/ /** + * @brief Get Flash Jedec ID + * + * @param pFlashCfg: Flash config pointer + * @param data: data pointer to store Jedec ID Read from flash + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_GetJedecId_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t *data) +{ + BL_Err_Type stat; + uint32_t offset; + + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, SF_CTRL_QIO_MODE, 1, 0, 32); + } else { + SFlash_GetJedecId(pFlashCfg, data); + XIP_SFlash_State_Restore(pFlashCfg, offset); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Get Flash Device ID + * + * @param pFlashCfg: Flash config pointer + * @param data: data pointer to store Device ID Read from flash + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_GetDeviceId_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t *data) +{ + BL_Err_Type stat; + uint32_t offset; + + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, SF_CTRL_QIO_MODE, 1, 0, 32); + } else { + SFlash_GetDeviceId(data); + XIP_SFlash_State_Restore(pFlashCfg, offset); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Get Flash Unique ID + * + * @param pFlashCfg: Flash config pointer + * @param data: data pointer to store Device ID Read from flash + * @param idLen: Unique id len + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_GetUniqueId_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t *data, uint8_t idLen) +{ + BL_Err_Type stat; + uint32_t offset; + + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, SF_CTRL_QIO_MODE, 1, 0, 32); + } else { + SFlash_GetUniqueId(data, idLen); + XIP_SFlash_State_Restore(pFlashCfg, offset); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Read data from flash via XIP + * + * @param addr: flash read start address + * @param data: data pointer to store data read from flash + * @param len: data length to read + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Read_Via_Cache_Need_Lock(uint32_t addr, uint8_t *data, uint32_t len) +{ + uint32_t offset; + + if (addr >= BL602_FLASH_XIP_BASE && addr < BL602_FLASH_XIP_END) { + offset = SF_Ctrl_Get_Flash_Image_Offset(); + SF_Ctrl_Set_Flash_Image_Offset(0); + /* Flash read */ + BL602_MemCpy_Fast(data, (void *)(addr), len); + SF_Ctrl_Set_Flash_Image_Offset(offset); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_Read_With_Lock(SPI_Flash_Cfg_Type *pFlashCfg,uint32_t addr, uint8_t *dst, int len) +{ + __disable_irq(); + XIP_SFlash_Read_Need_Lock(pFlashCfg, addr, dst, len); + __enable_irq(); + return 0; +} + +/****************************************************************************//** + * @brief Program flash one region with lock + * + * @param pFlashCfg: Flash config pointer + * @param addr: Start address to be programed + * @param src: Data pointer to be programed + * @param len: Data length to be programed + * + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_Write_With_Lock(SPI_Flash_Cfg_Type *pFlashCfg,uint32_t addr, uint8_t *src, int len) +{ + __disable_irq(); + XIP_SFlash_Write_Need_Lock(pFlashCfg, addr, src, len); + __enable_irq(); + return 0; +} + +/****************************************************************************//** + * @brief Erase flash one region with lock + * + * @param pFlashCfg: Flash config pointer + * @param addr: Start address to be erased + * @param len: Data length to be erased + * + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_Erase_With_Lock(SPI_Flash_Cfg_Type *pFlashCfg,uint32_t addr, int len) +{ + __disable_irq(); + XIP_SFlash_Erase_Need_Lock(pFlashCfg, addr, addr + len - 1); + __enable_irq(); + return 0; +} + +/****************************************************************************//** + * @brief XIP SFlash option save + * + * @param aesEnable: AES enable status pointer + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION XIP_SFlash_Opt_Enter(uint8_t *aesEnable) +{ + *aesEnable = SF_Ctrl_Is_AES_Enable(); + + if (*aesEnable) { + SF_Ctrl_AES_Disable(); + } +} + +/****************************************************************************/ /** + * @brief XIP SFlash option restore + * + * @param aesEnable: AES enable status + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION XIP_SFlash_Opt_Exit(uint8_t aesEnable) +{ + if (aesEnable) { + SF_Ctrl_AES_Enable(); + } +} +#endif + +/*@} end of group XIP_SFLASH_Public_Functions */ + +/*@} end of group XIP_SFLASH */ + +/*@} end of group BL602_Peripheral_Driver */ diff --git a/drivers/soc/bl602/bl602_std/src/bl602_xip_sflash_ext.c b/drivers/soc/bl602/bl602_std/src/bl602_xip_sflash_ext.c new file mode 100644 index 00000000..647629a2 --- /dev/null +++ b/drivers/soc/bl602/bl602_std/src/bl602_xip_sflash_ext.c @@ -0,0 +1,583 @@ +/** + ****************************************************************************** + * @file bl602_xip_sflash_ext.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "string.h" +#include "bl602_sf_cfg.h" +#include "bl602_sf_cfg_ext.h" +#include "bl602_xip_sflash.h" +#include "bl602_xip_sflash_ext.h" + +/** @addtogroup BL602_Peripheral_Driver + * @{ + */ + +/** @addtogroup XIP_SFLASH_EXT + * @{ + */ + +/** @defgroup XIP_SFLASH_EXT_Private_Macros + * @{ + */ + +/*@} end of group XIP_SFLASH_EXT_Private_Macros */ + +/** @defgroup XIP_SFLASH_EXT_Private_Types + * @{ + */ + +/*@} end of group XIP_SFLASH_EXT_Private_Types */ + +/** @defgroup XIP_SFLASH_EXT_Private_Variables + * @{ + */ + +static SPI_Flash_Cfg_Type flashCfg; +static uint8_t aesEnable; + +/*@} end of group XIP_SFLASH_EXT_Private_Variables */ + +/** @defgroup XIP_SFLASH_EXT_Global_Variables + * @{ + */ + +/*@} end of group XIP_SFLASH_EXT_Global_Variables */ + +/** @defgroup XIP_SFLASH_EXT_Private_Fun_Declaration + * @{ + */ + +/*@} end of group XIP_SFLASH_EXT_Private_Fun_Declaration */ + +/** @defgroup XIP_SFLASH_EXT_Private_Functions + * @{ + */ + +/*@} end of group XIP_SFLASH_EXT_Private_Functions */ + +/** @defgroup XIP_SFLASH_EXT_Public_Functions + * @{ + */ + +/****************************************************************************//** + * @brief Save flash controller state + * + * @param pFlashCfg: Flash config pointer + * @param offset: CPU XIP flash offset pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_State_Save_Ext(SPI_Flash_Cfg_Type *pFlashCfg,uint32_t *offset) +{ + /* XIP_SFlash_Delay */ + volatile uint32_t i=32*2; + while(i--); + + SF_Ctrl_Set_Owner(SF_CTRL_OWNER_SAHB); + /* Exit form continous read for accepting command */ + SFlash_Reset_Continue_Read(pFlashCfg); + /* Send software reset command(80bv has no this command)to deburst wrap for ISSI like */ + SFlash_Software_Reset(pFlashCfg); + /* For disable command that is setting register instaed of send command, we need write enable */ + SFlash_DisableBurstWrap(pFlashCfg); + if ((pFlashCfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (pFlashCfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + /* Enable QE again in case reset command make it reset */ + SFlash_Qspi_Enable(pFlashCfg); + } + /* Deburst again to make sure */ + SFlash_DisableBurstWrap(pFlashCfg); + + /* Clear offset setting*/ + *offset=SF_Ctrl_Get_Flash_Image_Offset(); + SF_Ctrl_Set_Flash_Image_Offset(0); + + return SUCCESS; +} + +/****************************************************************************//** + * @brief Restore flash controller state + * + * @param pFlashCfg: Flash config pointer + * @param offset: CPU XIP flash offset + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_State_Restore_Ext(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t offset) +{ + uint32_t tmp[1]; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + SF_Ctrl_Set_Flash_Image_Offset(offset); + + if (((pFlashCfg->ioMode >> 4) & 0x01) == 0) { + if ((pFlashCfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (pFlashCfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + SFlash_SetBurstWrap(pFlashCfg); + } + } + SFlash_Read(pFlashCfg, ioMode, 1, 0x0, (uint8_t *)tmp, sizeof(tmp)); + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32); + + return SUCCESS; +} + +/*@} end of group XIP_SFLASH_EXT_Public_Functions */ + +/** @defgroup XIP_SFLASH_EXT_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Erase flash one region + * + * @param pFlashCfg: Flash config pointer + * @param startaddr: start address to erase + * @param endaddr: end address(include this address) to erase + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Erase_Need_Lock_Ext(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t startaddr, uint32_t endaddr) +{ + BL_Err_Type stat; + uint32_t offset; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode&0xf; + + XIP_SFlash_Opt_Enter(&aesEnable); + stat=XIP_SFlash_State_Save(pFlashCfg,&offset); + if(stat!=SUCCESS){ + SFlash_Set_IDbus_Cfg(pFlashCfg,ioMode,1,0,32); + }else{ + stat=SFlash_Erase(pFlashCfg,startaddr,endaddr); + XIP_SFlash_State_Restore_Ext(pFlashCfg,offset); + } + XIP_SFlash_Opt_Exit(aesEnable); + + return stat; +} + +/****************************************************************************/ /** + * @brief Program flash one region + * + * @param pFlashCfg: Flash config pointer + * @param addr: start address to be programed + * @param data: data pointer to be programed + * @param len: data length to be programed + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Write_Need_Lock_Ext(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t addr, uint8_t *data, uint32_t len) +{ + BL_Err_Type stat; + uint32_t offset; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode&0xf; + + XIP_SFlash_Opt_Enter(&aesEnable); + stat=XIP_SFlash_State_Save(pFlashCfg,&offset); + if(stat!=SUCCESS){ + SFlash_Set_IDbus_Cfg(pFlashCfg,ioMode,1,0,32); + }else{ + stat= SFlash_Program(pFlashCfg,ioMode,addr,data,len); + XIP_SFlash_State_Restore_Ext(pFlashCfg,offset); + } + XIP_SFlash_Opt_Exit(aesEnable); + + return stat; +} + +/****************************************************************************/ /** + * @brief Read data from flash + * + * @param pFlashCfg: Flash config pointer + * @param addr: flash read start address + * @param data: data pointer to store data read from flash + * @param len: data length to read + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Read_Need_Lock_Ext(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t addr, uint8_t *data, uint32_t len) +{ + BL_Err_Type stat; + uint32_t offset; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode&0xf; + + XIP_SFlash_Opt_Enter(&aesEnable); + stat=XIP_SFlash_State_Save(pFlashCfg,&offset); + if(stat!=SUCCESS){ + SFlash_Set_IDbus_Cfg(pFlashCfg,ioMode,1,0,32); + }else{ + stat=SFlash_Read(pFlashCfg,ioMode,0,addr, data,len); + XIP_SFlash_State_Restore_Ext(pFlashCfg,offset); + } + XIP_SFlash_Opt_Exit(aesEnable); + + return stat; +} + +/****************************************************************************//** + * @brief Clear flash status register need lock + * + * @param pFlashCfg: Flash config pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Clear_Status_Register_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg) +{ + BL_Err_Type stat; + uint32_t offset; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode&0xf; + + stat=XIP_SFlash_State_Save(pFlashCfg, &offset); + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32); + } else { + stat=SFlash_Clear_Status_Register(pFlashCfg); + XIP_SFlash_State_Restore_Ext(pFlashCfg, offset); + } + + return stat; +} + +/****************************************************************************//** + * @brief Get Flash Jedec ID + * + * @param pFlashCfg: Flash config pointer + * @param data: data pointer to store Jedec ID Read from flash + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_GetJedecId_Need_Lock_Ext(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t *data) +{ + BL_Err_Type stat; + uint32_t offset; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32); + } else { + SFlash_GetJedecId(pFlashCfg, data); + XIP_SFlash_State_Restore_Ext(pFlashCfg, offset); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Get Flash Device ID + * + * @param pFlashCfg: Flash config pointer + * @param data: data pointer to store Device ID Read from flash + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_GetDeviceId_Need_Lock_Ext(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t *data) +{ + BL_Err_Type stat; + uint32_t offset; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32); + } else { + SFlash_GetDeviceId(data); + XIP_SFlash_State_Restore_Ext(pFlashCfg, offset); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Get Flash Unique ID + * + * @param pFlashCfg: Flash config pointer + * @param data: data pointer to store Device ID Read from flash + * @param idLen: Unique id len + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_GetUniqueId_Need_Lock_Ext(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t *data, uint8_t idLen) +{ + BL_Err_Type stat; + uint32_t offset; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32); + } else { + SFlash_GetUniqueId(data, idLen); + XIP_SFlash_State_Restore_Ext(pFlashCfg, offset); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Sflash enable RCV mode to recovery for erase while power drop need lock + * + * @param pFlashCfg: Flash config pointer + * @param rCmd: Read RCV register cmd + * @param wCmd: Write RCV register cmd + * @param bitPos: RCV register bit pos + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_RCV_Enable_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t rCmd, uint8_t wCmd, uint8_t bitPos) +{ + BL_Err_Type stat; + uint32_t offset; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + stat = XIP_SFlash_State_Save(pFlashCfg, &offset); + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32); + } else { + stat = SFlash_RCV_Enable(pFlashCfg, rCmd, wCmd, bitPos); + XIP_SFlash_State_Restore_Ext(pFlashCfg, offset); + } + + return stat; +} + +/****************************************************************************//** + * @brief Read data from flash with lock + * + * @param pFlashCfg: Flash config pointer + * @param addr: flash read start address + * @param dst: data pointer to store data read from flash + * @param len: data length to read + * + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_Read_With_Lock_Ext(SPI_Flash_Cfg_Type *pFlashCfg,uint32_t addr, uint8_t *dst, int len) +{ + __disable_irq(); + XIP_SFlash_Read_Need_Lock_Ext(pFlashCfg, addr, dst, len); + __enable_irq(); + return 0; +} + +/****************************************************************************//** + * @brief Program flash one region with lock + * + * @param pFlashCfg: Flash config pointer + * @param addr: Start address to be programed + * @param src: Data pointer to be programed + * @param len: Data length to be programed + * + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_Write_With_Lock_Ext(SPI_Flash_Cfg_Type *pFlashCfg,uint32_t addr, uint8_t *src, int len) +{ + __disable_irq(); + XIP_SFlash_Write_Need_Lock_Ext(pFlashCfg, addr, src, len); + __enable_irq(); + return 0; +} + +/****************************************************************************//** + * @brief Erase flash one region with lock + * + * @param pFlashCfg: Flash config pointer + * @param addr: Start address to be erased + * @param len: Data length to be erased + * + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_Erase_With_Lock_Ext(SPI_Flash_Cfg_Type *pFlashCfg,uint32_t addr, int len) +{ + __disable_irq(); + XIP_SFlash_Erase_Need_Lock_Ext(pFlashCfg, addr, addr + len - 1); + __enable_irq(); + return 0; +} + +/****************************************************************************//** + * @brief Clear flash status register with lock + * + * @param pFlashCfg: Flash config pointer + * + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_Clear_Status_Register_With_Lock(SPI_Flash_Cfg_Type *pFlashCfg) +{ + __disable_irq(); + XIP_SFlash_Clear_Status_Register_Need_Lock(pFlashCfg); + __enable_irq(); + return 0; +} + +/****************************************************************************//** + * @brief Sflash enable RCV mode to recovery for erase while power drop with lock + * + * @param pFlashCfg: Flash config pointer + * @param rCmd: Read RCV register cmd + * @param wCmd: Write RCV register cmd + * @param bitPos: RCV register bit pos + * + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_RCV_Enable_With_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t rCmd, uint8_t wCmd, uint8_t bitPos) +{ + __disable_irq(); + XIP_SFlash_RCV_Enable_Need_Lock(pFlashCfg, rCmd, wCmd, bitPos); + __enable_irq(); + return 0; +} + +/****************************************************************************//** + * @brief Read data from flash with lock + * + * @param pFlashCfg:Flash config pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Init(SPI_Flash_Cfg_Type *pFlashCfg) +{ + uint32_t ret; + + if(pFlashCfg==NULL){ + /* Get flash config identify */ + XIP_SFlash_Opt_Enter(&aesEnable); + ret=SF_Cfg_Flash_Identify_Ext(1,1,0,0,&flashCfg); + XIP_SFlash_Opt_Exit(aesEnable); + if((ret&BFLB_FLASH_ID_VALID_FLAG)==0){ + return ERROR; + } + }else{ + memcpy(&flashCfg,pFlashCfg,sizeof(flashCfg)); + } + + return SUCCESS; +} + +/****************************************************************************//** + * @brief Read data from flash with lock + * + * @param addr: flash read start address + * @param dst: data pointer to store data read from flash + * @param len: data length to read + * + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_Read(uint32_t addr, uint8_t *dst, int len) +{ + __disable_irq(); + XIP_SFlash_Opt_Enter(&aesEnable); + XIP_SFlash_Read_Need_Lock_Ext(&flashCfg, addr, dst, len); + XIP_SFlash_Opt_Exit(aesEnable); + __enable_irq(); + return 0; +} + +/****************************************************************************//** + * @brief Program flash one region with lock + * + * @param addr: Start address to be programed + * @param src: Data pointer to be programed + * @param len: Data length to be programed + * + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_Write(uint32_t addr, uint8_t *src, int len) +{ + __disable_irq(); + XIP_SFlash_Opt_Enter(&aesEnable); + XIP_SFlash_Write_Need_Lock_Ext(&flashCfg, addr, src, len); + XIP_SFlash_Opt_Exit(aesEnable); + __enable_irq(); + return 0; +} + +/****************************************************************************//** + * @brief Erase flash one region with lock + * + * @param addr: Start address to be erased + * @param len: Data length to be erased + * + * @return 0 + * +*******************************************************************************/ +__WEAK +int ATTR_TCM_SECTION XIP_SFlash_Erase(uint32_t addr, int len) +{ + __disable_irq(); + XIP_SFlash_Opt_Enter(&aesEnable); + XIP_SFlash_Erase_Need_Lock_Ext(&flashCfg, addr, addr + len - 1); + XIP_SFlash_Opt_Exit(aesEnable); + __enable_irq(); + return 0; +} +/*@} end of group XIP_SFLASH_EXT_Public_Functions */ + +/*@} end of group XIP_SFLASH_EXT */ + +/*@} end of group BL602_Peripheral_Driver */ diff --git a/drivers/soc/bl602/port/bl602_efuse.c b/drivers/soc/bl602/port/bl602_efuse.c new file mode 100644 index 00000000..f593967b --- /dev/null +++ b/drivers/soc/bl602/port/bl602_efuse.c @@ -0,0 +1,53 @@ +#include "bflb_efuse.h" +#include "bl602_ef_ctrl.h" + +float bflb_efuse_get_adc_trim(void) +{ + Efuse_ADC_Gain_Coeff_Type trim; + uint32_t tmp; + + float coe = 1.0; + + EF_Ctrl_Read_ADC_Gain_Trim(&trim); + + if (trim.adcGainCoeffEn) { + if (trim.adcGainCoeffParity == EF_Ctrl_Get_Trim_Parity(trim.adcGainCoeff, 12)) { + tmp = trim.adcGainCoeff; + + if (tmp & 0x800) { + tmp = ~tmp; + tmp += 1; + tmp = tmp & 0xfff; + coe = (1.0 + ((float)tmp / 2048.0)); + } else { + coe = (1.0 - ((float)tmp / 2048.0)); + } + } + } + + return coe; +} + +uint32_t bflb_efuse_get_adc_tsen_trim(void) +{ + Efuse_TSEN_Refcode_Corner_Type trim; + + EF_Ctrl_Read_TSEN_Trim(&trim); + if (trim.tsenRefcodeCornerEn) { + if (trim.tsenRefcodeCornerParity == EF_Ctrl_Get_Trim_Parity(trim.tsenRefcodeCorner, 12)) { + return trim.tsenRefcodeCorner; + } + } + + return 2042; +} + +void bflb_efuse_write_aes_key(uint8_t index, uint8_t *data, uint32_t len) +{ + EF_Ctrl_Write_AES_Key(index, (uint32_t *)data, len, 1); +} + +void bflb_efuse_read_aes_key(uint8_t index, uint8_t *data, uint32_t len) +{ + EF_Ctrl_Read_AES_Key(index, (uint32_t *)data, len); +} \ No newline at end of file diff --git a/drivers/soc/bl602/port/bl602_flash.c b/drivers/soc/bl602/port/bl602_flash.c new file mode 100644 index 00000000..615cd7ba --- /dev/null +++ b/drivers/soc/bl602/port/bl602_flash.c @@ -0,0 +1,201 @@ +#include "bl602_glb.h" +#include "bl602_xip_sflash.h" +#include "bl602_xip_sflash_ext.h" +#include "bl602_sf_cfg.h" +#include "bl602_sf_cfg_ext.h" +#include "bflb_flash.h" + +static uint32_t g_jedec_id = 0; +static SPI_Flash_Cfg_Type g_flash_cfg; + +void ATTR_TCM_SECTION flash_set_qspi_enable(SPI_Flash_Cfg_Type *p_flash_cfg) +{ + if ((p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + SFlash_Qspi_Enable(p_flash_cfg); + } +} + +void ATTR_TCM_SECTION flash_set_l1c_wrap(SPI_Flash_Cfg_Type *p_flash_cfg) +{ + if (((p_flash_cfg->ioMode >> 4) & 0x01) == 1) { + L1C_Set_Wrap(DISABLE); + } else { + L1C_Set_Wrap(ENABLE); + if ((p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + SFlash_SetBurstWrap(p_flash_cfg); + } + } +} + +/** + * @brief flash_config_init + * + * @return int + */ +static int ATTR_TCM_SECTION flash_config_init(SPI_Flash_Cfg_Type *p_flash_cfg, uint8_t *jedec_id) +{ + int ret = -1; + uint8_t isAesEnable = 0; + uint32_t jid = 0; + uint32_t offset = 0; + uintptr_t flag; + + flag = bflb_irq_save(); + XIP_SFlash_Opt_Enter(&isAesEnable); + XIP_SFlash_State_Save(p_flash_cfg, &offset); + SFlash_GetJedecId(p_flash_cfg, (uint8_t *)&jid); + arch_memcpy(jedec_id, (uint8_t *)&jid, 3); + jid &= 0xFFFFFF; + g_jedec_id = jid; + ret = SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(jid, p_flash_cfg); + if (ret == 0) { + p_flash_cfg->mid = (jid & 0xff); + } + + /* Set flash controler from p_flash_cfg */ + flash_set_qspi_enable(p_flash_cfg); + flash_set_l1c_wrap(p_flash_cfg); + XIP_SFlash_State_Restore_Ext(p_flash_cfg, offset); + XIP_SFlash_Opt_Exit(isAesEnable); + bflb_irq_restore(flag); + + return ret; +} + +/** + * @brief multi flash adapter + * + * @return int + */ +int ATTR_TCM_SECTION bflb_flash_init(void) +{ + int ret = -1; + uint8_t clkDelay = 1; + uint8_t clkInvert = 1; + uint32_t jedec_id = 0; + uintptr_t flag; + + flag = bflb_irq_save(); + SFlash_Cache_Flush(); + SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(0, &g_flash_cfg); + SFlash_Cache_Flush(); + bflb_irq_restore(flag); + if (g_flash_cfg.mid != 0xff) { + return 0; + } + clkDelay = g_flash_cfg.clkDelay; + clkInvert = g_flash_cfg.clkInvert; + g_flash_cfg.ioMode = g_flash_cfg.ioMode & 0x0f; + + ret = flash_config_init(&g_flash_cfg, (uint8_t *)&jedec_id); + + g_flash_cfg.clkDelay = clkDelay; + g_flash_cfg.clkInvert = clkInvert; + + return ret; +} + +uint32_t bflb_flash_get_jedecid(void) +{ + uint32_t jid = 0; + + jid = ((g_jedec_id & 0xff) << 16) + (g_jedec_id & 0xff00) + ((g_jedec_id & 0xff0000) >> 16); + return jid; +} + +void bflb_flash_get_cfg(uint8_t **cfg_addr, uint32_t *len) +{ + *cfg_addr = (uint8_t *)&g_flash_cfg; + *len = sizeof(SPI_Flash_Cfg_Type); +} + +/** + * @brief flash erase + * + * @param startaddr + * @param endaddr + * @return int + */ +int ATTR_TCM_SECTION bflb_flash_erase(uint32_t startaddr, uint32_t len) +{ + int ret = -1; + uint8_t isAesEnable = 0; + uintptr_t flag; + + flag = bflb_irq_save(); + XIP_SFlash_Opt_Enter(&isAesEnable); + ret = XIP_SFlash_Erase_Need_Lock_Ext(&g_flash_cfg, startaddr, startaddr + len - 1); + XIP_SFlash_Opt_Exit(isAesEnable); + bflb_irq_restore(flag); + + return ret; +} + +/** + * @brief flash write data + * + * @param addr + * @param data + * @param len + * @return int + */ +int ATTR_TCM_SECTION bflb_flash_write(uint32_t addr, uint8_t *data, uint32_t len) +{ + int ret = -1; + uint8_t isAesEnable = 0; + uintptr_t flag; + + flag = bflb_irq_save(); + XIP_SFlash_Opt_Enter(&isAesEnable); + ret = XIP_SFlash_Write_Need_Lock_Ext(&g_flash_cfg, addr, data, len); + XIP_SFlash_Opt_Exit(isAesEnable); + bflb_irq_restore(flag); + + return ret; +} + +/** + * @brief flash read data + * + * @param addr + * @param data + * @param len + * @return int + */ +int ATTR_TCM_SECTION bflb_flash_read(uint32_t addr, uint8_t *data, uint32_t len) +{ + int ret = -1; + uint8_t isAesEnable = 0; + uintptr_t flag; + + flag = bflb_irq_save(); + XIP_SFlash_Opt_Enter(&isAesEnable); + ret = XIP_SFlash_Read_Need_Lock_Ext(&g_flash_cfg, addr, data, len); + XIP_SFlash_Opt_Exit(isAesEnable); + bflb_irq_restore(flag); + + return ret; +} + +void bflb_flash_aes_init(struct bflb_flash_aes_config_s *config) +{ + uint8_t hw_key_enable = 0; + + if (config->key == NULL) { + hw_key_enable = 1; + } + + SF_Ctrl_AES_Set_Key_BE(config->region, (uint8_t *)config->key, config->keybits); + SF_Ctrl_AES_Set_IV_BE(config->region, (uint8_t *)config->iv, config->start_addr); + SF_Ctrl_AES_Set_Region(config->region, config->region_enable, hw_key_enable, config->start_addr, config->end_addr - 1, config->lock_enable); +} + +void bflb_flash_aes_enable(void) +{ + SF_Ctrl_AES_Enable(); +} + +void bflb_flash_aes_disable(void) +{ + SF_Ctrl_AES_Disable(); +} \ No newline at end of file diff --git a/drivers/soc/bl602/startup/interrupt.c b/drivers/soc/bl602/startup/interrupt.c index 505d942c..e60b737e 100644 --- a/drivers/soc/bl602/startup/interrupt.c +++ b/drivers/soc/bl602/startup/interrupt.c @@ -187,5 +187,17 @@ __attribute__((interrupt, aligned(64))) void default_trap_handler(void) __attribute__((interrupt)) __attribute__((weak)) void default_interrupt_handler(void) { + __asm volatile("addi sp,sp,-8"); + __asm volatile("csrr a0,mcause"); + __asm volatile("csrr a1,mepc"); + __asm volatile("sw a0,4(sp)"); + __asm volatile("sw a1,0(sp)"); + __asm volatile("csrsi mstatus,8"); interrupt_entry(); + __asm volatile("csrci mstatus,8"); + __asm volatile("lw a1,0(sp)"); + __asm volatile("lw a0,4(sp)"); + __asm volatile("csrw mepc,a1"); + __asm volatile("csrw mcause,a0"); + __asm volatile("addi sp,sp,8"); } \ No newline at end of file diff --git a/drivers/soc/bl616/CMakeLists.txt b/drivers/soc/bl616/CMakeLists.txt index c06cac4b..3f46a984 100644 --- a/drivers/soc/bl616/CMakeLists.txt +++ b/drivers/soc/bl616/CMakeLists.txt @@ -10,23 +10,31 @@ sdk_library_add_sources(startup/interrupt.c) if(CONFIG_ROMAPI) sdk_library_add_sources(bl616_std/src/bl616_romapi_e907.c) sdk_library_add_sources(bl616_std/src/bl616_romapi_patch.c) +sdk_add_compile_definitions(-DBFLB_USE_ROM_DRIVER) else() sdk_library_add_sources(bl616_std/src/bl616_aon.c) +sdk_library_add_sources(bl616_std/src/bl616_clock.c) +sdk_library_add_sources(bl616_std/src/bl616_ef_ctrl.c) +sdk_library_add_sources(bl616_std/src/bl616_glb_gpio.c) sdk_library_add_sources(bl616_std/src/bl616_glb.c) sdk_library_add_sources(bl616_std/src/bl616_hbn.c) +sdk_library_add_sources(bl616_std/src/bl616_l1c.c) sdk_library_add_sources(bl616_std/src/bl616_pds.c) -sdk_library_add_sources(bl616_std/src/bl616_clock.c) -sdk_library_add_sources(bl616_std/src/bl616_glb_gpio.c) +sdk_library_add_sources(bl616_std/src/bl616_sf_cfg.c) +sdk_library_add_sources(bl616_std/src/bl616_sf_ctrl.c) +sdk_library_add_sources(bl616_std/src/bl616_sflash.c) +sdk_library_add_sources(bl616_std/src/bl616_xip_sflash.c) endif() + sdk_library_add_sources(bl616_std/src/bl616_common.c) +sdk_library_add_sources(bl616_std/src/bl616_ef_cfg.c) sdk_library_add_sources(bl616_std/src/bl616_sdh.c) sdk_library_add_sources(bl616_std/src/bl616_tzc_sec.c) sdk_library_add_sources(bl616_std/src/bl616_psram.c) -# sdk_library_add_sources(bl616_std/src/bl616_l1c.c) -# sdk_library_add_sources(bl616_std/src/bl616_ef_ctrl.c) -# sdk_library_add_sources(bl616_std/src/bl616_ef_cfg.c) sdk_library_add_sources(port/bl616_clock.c) +sdk_library_add_sources(port/bl616_flash.c) +sdk_library_add_sources(port/bl616_efuse.c) sdk_add_include_directories( bl616_std/include @@ -37,7 +45,7 @@ SET(MCPU "e907") SET(MARCH "rv32imafcpzpsfoperand_xtheade") SET(MABI "ilp32f") -sdk_add_compile_definitions(-DARCH_RISCV) +sdk_add_compile_definitions(-DARCH_RISCV -DBFLB_USE_HAL_DRIVER) sdk_add_compile_options(-march=${MARCH} -mabi=${MABI} -mtune=${MCPU}) sdk_add_link_options(-march=${MARCH} -mabi=${MABI} -mtune=${MCPU}) diff --git a/drivers/soc/bl616/bl616_std/include/bl616_common.h b/drivers/soc/bl616/bl616_std/include/bl616_common.h index d9c77cea..47c1c149 100644 --- a/drivers/soc/bl616/bl616_std/include/bl616_common.h +++ b/drivers/soc/bl616/bl616_std/include/bl616_common.h @@ -149,6 +149,16 @@ void check_failed(uint8_t *file, uint32_t line); */ #define IS_BL_MASK_TYPE(type) (((type) == MASK) || ((type) == UNMASK)) +#define ARCH_MemCpy arch_memcpy +#define ARCH_MemSet arch_memset +#define ARCH_MemCmp arch_memcmp +#define ARCH_MemCpy4 arch_memcpy4 +#define ARCH_MemCpy_Fast arch_memcpy_fast +#define ARCH_MemSet4 arch_memset4 +#define BFLB_Soft_CRC32 bflb_soft_crc32 +#define CPU_Interrupt_Enable(irq) +#define CPU_Interrupt_Disable(irq) +#define Interrupt_Handler_Register(irq, callback) /*@} end of group COMMON_Public_Constants */ /** @defgroup DRIVER_Public_FunctionDeclaration @@ -156,7 +166,7 @@ void check_failed(uint8_t *file, uint32_t line); * @{ */ -void Interrupt_Handler_Register(IRQn_Type irq, pFunc interruptFun); +// void Interrupt_Handler_Register(IRQn_Type irq, pFunc interruptFun); void ASM_Delay_Us(uint32_t core, uint32_t cnt, uint32_t loopT); void arch_delay_us(uint32_t cnt); void arch_delay_ms(uint32_t cnt); diff --git a/drivers/soc/bl616/bl616_std/include/bl616_ef_ctrl.h b/drivers/soc/bl616/bl616_std/include/bl616_ef_ctrl.h index 92b3c1b4..ebb32e8f 100644 --- a/drivers/soc/bl616/bl616_std/include/bl616_ef_ctrl.h +++ b/drivers/soc/bl616/bl616_std/include/bl616_ef_ctrl.h @@ -445,7 +445,7 @@ uint8_t EF_Ctrl_Is_All_Bits_Zero(uint32_t val, uint8_t start, uint8_t len); uint8_t EF_Ctrl_Read_FlashDlyCoe(void); uint32_t EF_Ctrl_Get_Common_Trim_List(Efuse_Common_Trim_Cfg **trim_list); -void EF_Ctrl_Read_Common_Trim(char *name, Efuse_Common_Trim_Type *trim); +void EF_Ctrl_Read_Common_Trim(char *name, Efuse_Common_Trim_Type *trim, uint8_t reload); void EF_Ctrl_Write_Common_Trim(char *name, uint32_t value, uint8_t program); /*@} end of group EF_CTRL_Public_Functions */ diff --git a/drivers/soc/bl616/bl616_std/include/bl616_psram.h b/drivers/soc/bl616/bl616_std/include/bl616_psram.h index b9089d2a..054a866c 100644 --- a/drivers/soc/bl616/bl616_std/include/bl616_psram.h +++ b/drivers/soc/bl616/bl616_std/include/bl616_psram.h @@ -7,7 +7,7 @@ ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ *

© COPYRIGHT(c) 2022 Bouffalo Lab

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -172,11 +172,11 @@ typedef enum { * @brief PSRAM Burst Length type definition */ typedef enum { - PSRAM_WINBOND_BURST_LENGTH_128_BYTES, /*!< Burst Length 128 bytes */ - PSRAM_WINBOND_BURST_LENGTH_64_BYTES, /*!< Burst Length 64 bytes */ - PSRAM_WINBOND_BURST_LENGTH_16_BYTES, /*!< Burst Length 16 bytes */ - PSRAM_WINBOND_BURST_LENGTH_32_BYTES, /*!< Burst Length 32 bytes */ - PSRAM_WINBOND_BURST_LENGTH_512_BYTES, /*!< Burst Length 512 only for HyperBus3 */ + PSRAM_WINBOND_BURST_LENGTH_128_BYTES = 0x4, /*!< Burst Length 128 bytes */ + PSRAM_WINBOND_BURST_LENGTH_64_BYTES, /*!< Burst Length 64 bytes */ + PSRAM_WINBOND_BURST_LENGTH_16_BYTES, /*!< Burst Length 16 bytes */ + PSRAM_WINBOND_BURST_LENGTH_32_BYTES, /*!< Burst Length 32 bytes */ + PSRAM_WINBOND_BURST_LENGTH_512_BYTES, /*!< Burst Length 512 only for HyperBus3 */ } PSRAM_Winbond_Burst_Length; /** @@ -302,8 +302,7 @@ typedef struct /** @defgroup PSRAM_ID_TYPE * @{ */ -#define IS_PSRAM_ID_TYPE(type) (((type) == PSRAM0_ID) || \ - ((type) == PSRAM1_ID)) +#define IS_PSRAM_ID_TYPE(type) (((type) == PSRAM0_ID)) /** @defgroup PSRAM_CTRL_IO_MODE_TYPE * @{ @@ -466,12 +465,12 @@ typedef struct * @{ */ void PSram_Ctrl_Init(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Cfg_Type *psramCtrlCfg); -void PSram_Ctrl_Winbond_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_Reg_Type reg_addr, uint16_t *regVal); -void PSram_Ctrl_Winbond_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_Reg_Type reg_addr, - PSRAM_Winbond_Cfg_Type *reg_cfg); -void PSram_Ctrl_ApMem_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_Type reg_addr, uint16_t *regVal); -void PSram_Ctrl_ApMem_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_Type reg_addr, - PSRAM_APMemory_Cfg_Type *reg_cfg); +BL_Err_Type PSram_Ctrl_Winbond_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_Reg_Type reg_addr, uint16_t *regVal); +BL_Err_Type PSram_Ctrl_Winbond_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_Reg_Type reg_addr, + PSRAM_Winbond_Cfg_Type *reg_cfg); +BL_Err_Type PSram_Ctrl_ApMem_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_Type reg_addr, uint16_t *regVal); +BL_Err_Type PSram_Ctrl_ApMem_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_Type reg_addr, + PSRAM_APMemory_Cfg_Type *reg_cfg); void PSram_Ctrl_ApMem_Reset(PSRAM_ID_Type PSRAM_ID); void PSram_Ctrl_CK_Sel(PSRAM_ID_Type PSRAM_ID, PSRAM_Clock_Type clkSel); void PSram_Ctrl_Winbond_Reset(PSRAM_ID_Type PSRAM_ID); diff --git a/drivers/soc/bl616/bl616_std/include/bl616_sdh.h b/drivers/soc/bl616/bl616_std/include/bl616_sdh.h index 8d5ff044..e8983a53 100644 --- a/drivers/soc/bl616/bl616_std/include/bl616_sdh.h +++ b/drivers/soc/bl616/bl616_std/include/bl616_sdh.h @@ -937,9 +937,8 @@ struct SDH_Handle_Cfg_Tag { /** @defgroup SDH_Public_Functions * @{ */ -#if (defined BOOTROM) || (!defined BFLB_USE_HAL_DRIVER) void SDH_MMC1_IRQHandler(void); -#endif + void SDH_Reset(void); void SDH_Set_Timeout(uint8_t tmo); void SDH_SetSdClock(uint32_t srcClock, uint32_t busClock); diff --git a/drivers/soc/bl616/bl616_std/include/bl616_sflash.h b/drivers/soc/bl616/bl616_std/include/bl616_sflash.h index f9f589f0..2cdab119 100644 --- a/drivers/soc/bl616/bl616_std/include/bl616_sflash.h +++ b/drivers/soc/bl616/bl616_std/include/bl616_sflash.h @@ -209,6 +209,8 @@ BL_Err_Type SFlash_Read(SPI_Flash_Cfg_Type *flashCfg, SF_Ctrl_IO_Type ioMode, ui uint32_t len); BL_Err_Type SFlash_Program(SPI_Flash_Cfg_Type *flashCfg, SF_Ctrl_IO_Type ioMode, uint32_t addr, uint8_t *data, uint32_t len); +BL_Err_Type SFlash_Clear_Status_Register(SPI_Flash_Cfg_Type *flashCfg); + /*@} end of group SFLAH_Public_Functions */ /*@} end of group SFLAH */ diff --git a/drivers/soc/bl616/bl616_std/include/bl616_xip_sflash.h b/drivers/soc/bl616/bl616_std/include/bl616_xip_sflash.h index 919712bb..e25ed98f 100644 --- a/drivers/soc/bl616/bl616_std/include/bl616_xip_sflash.h +++ b/drivers/soc/bl616/bl616_std/include/bl616_xip_sflash.h @@ -88,6 +88,9 @@ BL_Err_Type XIP_SFlash_Read_Via_Cache_Need_Lock(uint32_t addr, uint8_t *data, ui void XIP_SFlash_Opt_Enter(uint8_t *aesEnable); void XIP_SFlash_Opt_Exit(uint8_t aesEnable); +BL_Err_Type XIP_SFlash_Clear_Status_Register_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, + uint8_t group, SF_Ctrl_Bank_Select bank); + /*@} end of group XIP_SFLASH_Public_Functions */ /*@} end of group XIP_SFLASH */ diff --git a/drivers/soc/bl616/bl616_std/src/bl616_common.c b/drivers/soc/bl616/bl616_std/src/bl616_common.c index f0b058f3..9248d9a1 100644 --- a/drivers/soc/bl616/bl616_std/src/bl616_common.c +++ b/drivers/soc/bl616/bl616_std/src/bl616_common.c @@ -1,5 +1,4 @@ #include "bl616_common.h" -#include #include "bl616_glb.h" #include "bl616_clock.h" @@ -62,7 +61,6 @@ * @return none * *******************************************************************************/ -#ifndef BFLB_USE_ROM_DRIVER #ifdef ARCH_RISCV __WEAK void ATTR_TCM_SECTION ASM_Delay_Us(uint32_t core, uint32_t cnt, uint32_t loopT) @@ -116,7 +114,6 @@ void ATTR_TCM_SECTION ASM_Delay_Us(uint32_t core, uint32_t cnt, uint32_t loopT) ); } #endif -#endif /****************************************************************************/ /** * @brief delay us @@ -126,14 +123,12 @@ void ATTR_TCM_SECTION ASM_Delay_Us(uint32_t core, uint32_t cnt, uint32_t loopT) * @return none * *******************************************************************************/ -#ifndef BFLB_USE_ROM_DRIVER __WEAK void ATTR_TCM_SECTION arch_delay_us(uint32_t cnt) { uint32_t coreFreq; uint32_t loopTick = 3; - -#if __riscv_xtheade == 1 +#if defined(__riscv_xthead) || defined(__riscv_xtheadc) #if ((__ICACHE_PRESENT == 1U) && (__DCACHE_PRESENT == 1U)) uint32_t iCacheEn; uint32_t dCacheEn; @@ -174,7 +169,6 @@ void ATTR_TCM_SECTION arch_delay_us(uint32_t cnt) ASM_Delay_Us(coreFreq, cnt, loopTick); } -#endif /****************************************************************************/ /** * @brief delay ms @@ -184,7 +178,6 @@ void ATTR_TCM_SECTION arch_delay_us(uint32_t cnt) * @return none * *******************************************************************************/ -#ifndef BFLB_USE_ROM_DRIVER __WEAK void ATTR_TCM_SECTION arch_delay_ms(uint32_t cnt) { @@ -205,7 +198,6 @@ void ATTR_TCM_SECTION arch_delay_ms(uint32_t cnt) arch_delay_us(count * 1000); } } -#endif #ifdef DEBUG /******************************************************************************* diff --git a/drivers/soc/bl616/bl616_std/src/bl616_ef_cfg.c b/drivers/soc/bl616/bl616_std/src/bl616_ef_cfg.c index 5373a463..6d639d50 100644 --- a/drivers/soc/bl616/bl616_std/src/bl616_ef_cfg.c +++ b/drivers/soc/bl616/bl616_std/src/bl616_ef_cfg.c @@ -107,14 +107,14 @@ static Efuse_Common_Trim_Cfg trim_lit[] = { .value_len = 4, }, { - .name = "ldo33", + .name = "ldo33_trim", .en_addr = 0x78 * 8 + 13, .parity_addr = 0x78 * 8 + 12, .value_addr = 0x78 * 8 + 8, .value_len = 4, }, { - .name = "ldo11", + .name = "ldo11_tirm", .en_addr = 0x78 * 8 + 7, .parity_addr = 0x78 * 8 + 6, .value_addr = 0x78 * 8 + 2, @@ -127,6 +127,90 @@ static Efuse_Common_Trim_Cfg trim_lit[] = { .value_addr = 0x7C * 8 + 4, .value_len = 8, }, + { + .name = "hp_poffset0", + .en_addr = 0xCC * 8 + 26, + .parity_addr = 0xC0 * 8 + 15, + .value_addr = 0xC0 * 8 + 0, + .value_len = 15, + }, + { + .name = "hp_poffset1", + .en_addr = 0xCC * 8 + 27, + .parity_addr = 0xC0 * 8 + 31, + .value_addr = 0xC0 * 8 + 16, + .value_len = 15, + }, + { + .name = "hp_poffset2", + .en_addr = 0xCC * 8 + 28, + .parity_addr = 0xC4 * 8 + 15, + .value_addr = 0xC4 * 8 + 0, + .value_len = 15, + }, + { + .name = "lp_poffset0", + .en_addr = 0xCC * 8 + 29, + .parity_addr = 0xC4 * 8 + 31, + .value_addr = 0xC4 * 8 + 16, + .value_len = 15, + }, + { + .name = "lp_poffset1", + .en_addr = 0xCC * 8 + 30, + .parity_addr = 0xC8 * 8 + 15, + .value_addr = 0xC8 * 8 + 0, + .value_len = 15, + }, + { + .name = "lp_poffset2", + .en_addr = 0xCC * 8 + 31, + .parity_addr = 0xC8 * 8 + 31, + .value_addr = 0xC8 * 8 + 16, + .value_len = 15, + }, + { + .name = "bz_poffset0", + .en_addr = 0xD0 * 8 + 26, + .parity_addr = 0xCC * 8 + 25, + .value_addr = 0xCC * 8 + 0, + .value_len = 25, + }, + { + .name = "bz_poffset1", + .en_addr = 0xD0 * 8 + 27, + .parity_addr = 0xD0 * 8 + 25, + .value_addr = 0xD0 * 8 + 0, + .value_len = 25, + }, + { + .name = "bz_poffset2", + .en_addr = 0xD0 * 8 + 28, + .parity_addr = 0xD4 * 8 + 25, + .value_addr = 0xD4 * 8 + 0, + .value_len = 25, + }, + { + .name = "tmp_mp0", + .en_addr = 0xD8 * 8 + 9, + .parity_addr = 0xD8 * 8 + 8, + .value_addr = 0xD8 * 8 + 0, + .value_len = 8, + }, + { + .name = "tmp_mp1", + .en_addr = 0xD8 * 8 + 19, + .parity_addr = 0xD8 * 8 + 18, + .value_addr = 0xD8 * 8 + 10, + .value_len = 8, + }, + { + .name = "tmp_mp2", + .en_addr = 0xD8 * 8 + 29, + .parity_addr = 0xD8 * 8 + 28, + .value_addr = 0xD8 * 8 + 20, + .value_len = 8, + }, { .name = "auadc_gain", .en_addr = 0xDC * 8 + 25, @@ -156,21 +240,21 @@ static Efuse_Common_Trim_Cfg trim_lit[] = { .value_len = 10, }, { - .name = "xtal1", + .name = "xtal0", .en_addr = 0xEC * 8 + 7, .parity_addr = 0xEC * 8 + 6, .value_addr = 0xEC * 8 + 0, .value_len = 6, }, { - .name = "xtal2", + .name = "xtal1", .en_addr = 0xF0 * 8 + 31, .parity_addr = 0xF0 * 8 + 30, .value_addr = 0xF4 * 8 + 26, .value_len = 6, }, { - .name = "xtal3", + .name = "xtal2", .en_addr = 0xF0 * 8 + 29, .parity_addr = 0xF0 * 8 + 28, .value_addr = 0xF4 * 8 + 20, @@ -298,17 +382,19 @@ uint32_t EF_Ctrl_Get_Common_Trim_List(Efuse_Common_Trim_Cfg **trim_list) * * @param name: Trim name * @param trim: Trim data pointer - * + * @param reload: Reload efuse data before read * @return None * *******************************************************************************/ -void EF_Ctrl_Read_Common_Trim(char *name, Efuse_Common_Trim_Type *trim) +void EF_Ctrl_Read_Common_Trim(char *name, Efuse_Common_Trim_Type *trim, uint8_t reload) { uint32_t tmpVal; uint32_t i = 0; - /* Trigger read data from efuse */ - EF_CTRL_LOAD_BEFORE_READ_R0; + if (reload) { + /* Trigger read data from efuse */ + EF_CTRL_LOAD_BEFORE_READ_R0; + } trim->en = 0; trim->parity = 0; @@ -363,7 +449,6 @@ void EF_Ctrl_Write_Common_Trim(char *name, uint32_t value, uint8_t program) tmpVal |= (1 << (trim_lit[i].en_addr % 32)); BL_WR_WORD(EF_DATA_BASE + (trim_lit[i].en_addr / 32) * 4, tmpVal); - parity = EF_Ctrl_Get_Trim_Parity(value, trim_lit[i].value_len); if (parity) { tmpVal = BL_RD_WORD(EF_DATA_BASE + (trim_lit[i].parity_addr / 32) * 4); diff --git a/drivers/soc/bl616/bl616_std/src/bl616_l1c.c b/drivers/soc/bl616/bl616_std/src/bl616_l1c.c new file mode 100644 index 00000000..c9917501 --- /dev/null +++ b/drivers/soc/bl616/bl616_std/src/bl616_l1c.c @@ -0,0 +1,388 @@ +/** + ****************************************************************************** + * @file bl616_l1c.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl616_l1c.h" +#include "bl616_common.h" +// #include "bl616_glb.h" + +/** @addtogroup BL616_Peripheral_Driver + * @{ + */ + +/** @addtogroup L1C + * @{ + */ + +/** @defgroup L1C_Private_Macros + * @{ + */ + +/*@} end of group L1C_Private_Macros */ + +/** @defgroup L1C_Private_Types + * @{ + */ + +/*@} end of group L1C_Private_Types */ + +/** @defgroup L1C_Private_Variables + * @{ + */ + +/*@} end of group L1C_Private_Variables */ + +/** @defgroup L1C_Global_Variables + * @{ + */ + +/*@} end of group L1C_Global_Variables */ + +/** @defgroup L1C_Private_Fun_Declaration + * @{ + */ + +/*@} end of group L1C_Private_Fun_Declaration */ + +/** @defgroup L1C_Private_Functions + * @{ + */ + +/*@} end of group L1C_Private_Functions */ + +/** @defgroup L1C_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Enable I-Cache + * + * @param wayDsiable: cache way disable config + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_ICache_Enable(uint8_t wayDsiable) +{ +#ifndef __riscv_32e + csi_icache_enable(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Enable D-Cache + * + * @param wayDsiable: cache way disable config + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Enable(uint8_t wayDsiable) +{ +#ifndef __riscv_32e + csi_dcache_enable(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Disable I-Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_ICache_Disable(void) +{ +#ifndef __riscv_32e + csi_icache_disable(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Disable D-Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Disable(void) +{ +#ifndef __riscv_32e + csi_dcache_disable(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief L1C D-Cache write set + * + * @param wtEn: L1C write through enable + * @param wbEn: L1C write back enable + * @param waEn: L1C write allocate enable + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION L1C_DCache_Write_Set(BL_Fun_Type wtEn, BL_Fun_Type wbEn, BL_Fun_Type waEn) +{ + return; +} + +/****************************************************************************/ /** + * @brief Clean all D_Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Clean_All(void) +{ +#ifndef __riscv_32e + csi_dcache_clean(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Clean and invalid all D_Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Clean_Invalid_All(void) +{ +#ifndef __riscv_32e + csi_dcache_clean_invalid(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Invalid all I-Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_ICache_Invalid_All(void) +{ +#ifndef __riscv_32e + csi_icache_invalid(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Invalid all D_Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Invalid_All(void) +{ +#ifndef __riscv_32e + csi_dcache_invalid(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Clean D-Cache according to address + * + * @param addr: Address to clean + * @param len: Length to clean + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Clean_By_Addr(uintptr_t addr, uint32_t len) +{ +#ifndef __riscv_32e +#ifdef CPU_D0 + csi_dcache_clean_range((uintptr_t *)addr, len); +#else + csi_dcache_clean_range((uint32_t *)(uintptr_t *)addr, len); +#endif +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Clean and invalid D-Cache according to address + * + * @param addr: Address to clean + * @param len: Length to clean + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Clean_Invalid_By_Addr(uintptr_t addr, uint32_t len) +{ +#ifndef __riscv_32e +#ifdef CPU_D0 + csi_dcache_clean_invalid_range((uintptr_t *)addr, len); +#else + csi_dcache_clean_invalid_range((uint32_t *)(uintptr_t *)addr, len); +#endif +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Invalid I-Cache according to address + * + * @param addr: Address to clean + * @param len: Length to clean + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_ICache_Invalid_By_Addr(uintptr_t addr, uint32_t len) +{ + L1C_ICache_Invalid_All(); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Invalid D-Cache according to address + * + * @param addr: Address to clean + * @param len: Length to clean + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Invalid_By_Addr(uintptr_t addr, uint32_t len) +{ +#ifndef __riscv_32e +#ifdef CPU_D0 + csi_dcache_invalid_range((uintptr_t *)addr, len); +#else + csi_dcache_invalid_range((uint32_t *)(uintptr_t *)addr, len); +#endif +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief cache wrap + * + * @param en: wrap enable or disable + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION L1C_Set_Wrap(uint8_t en) +{ + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief cache wrap + * + * @param core: cpu core + * @param cacheSetting: cache setting + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION L1C_Set_Cache_Setting_By_ID(uint8_t core, L1C_CACHE_Cfg_Type *cacheSetting) +{ + (void)core; + (void)cacheSetting; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Judge addr is in cache range + * + * @param addr: phyical addr + * + * @return 1 for addr is in cache range and 0 for not in cache range + * +*******************************************************************************/ +int ATTR_TCM_SECTION L1C_Is_DCache_Range(uintptr_t addr) +{ + if(((addr>>16)&0xffff)>=0x62FC){ + return 1; + }else{ + return 0; + } +} + +/****************************************************************************/ /** + * @brief Get None Cache address according to Cache address + * + * @param addr: cache addr + * + * @return none cache addr + * +*******************************************************************************/ +int ATTR_TCM_SECTION L1C_Get_None_Cache_Addr(uintptr_t addr) +{ + return (addr&0x0FFFFFFF)|0x20000000; +} + +/*@} end of group L1C_Public_Functions */ + +/*@} end of group L1C */ + +/*@} end of group BL616_Peripheral_Driver */ diff --git a/drivers/soc/bl616/bl616_std/src/bl616_psram.c b/drivers/soc/bl616/bl616_std/src/bl616_psram.c index 3dccc549..076d3ec1 100644 --- a/drivers/soc/bl616/bl616_std/src/bl616_psram.c +++ b/drivers/soc/bl616/bl616_std/src/bl616_psram.c @@ -1,13 +1,13 @@ /** ****************************************************************************** - * @file bl616p_psram_ctrl.c + * @file bl616_psram_ctrl.c * @version V1.0 * @date * @brief This file is the standard driver c file ****************************************************************************** * @attention * - *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ *

© COPYRIGHT(c) 2022 Bouffalo Lab

* * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -37,7 +37,7 @@ #include "bl616_psram.h" #include "psram_reg.h" -/** @addtogroup BL616P_Peripheral_Driver +/** @addtogroup BL616_Peripheral_Driver * @{ */ @@ -48,7 +48,7 @@ /** @defgroup PSRAM_CTRL_Private_Macros * @{ */ - +#define PSRAM_X8_CTRL_WAIT_TIMEOUT 1000 /*@} end of group PSRAM_CTRL_Private_Macros */ /** @defgroup PSRAM_CTRL_Private_Types @@ -141,6 +141,7 @@ static void PSram_Ctrl_Request(PSRAM_ID_Type PSRAM_ID) { uint32_t tmpVal = 0; uint32_t psram_base = PSRAM_CTRL_BASE + (0x1000 * PSRAM_ID); + uint32_t time_out = 0; //start configure request tmpVal = BL_RD_REG(psram_base, PSRAM_CONFIGURE); @@ -150,6 +151,9 @@ static void PSram_Ctrl_Request(PSRAM_ID_Type PSRAM_ID) //Waiting for the authorization do { tmpVal = BL_RD_REG(psram_base, PSRAM_CONFIGURE); + if (time_out++ > PSRAM_X8_CTRL_WAIT_TIMEOUT) { + break; + } } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_REG_CONFIG_GNT)); } @@ -179,13 +183,14 @@ static void PSram_Ctrl_Release(PSRAM_ID_Type PSRAM_ID) * @param reg_addr: PSRAM Register ID CR0 or CR1 * @param regVal: read Reister value * - * @return None + * @return SUCCESS or TIMEOUT * *******************************************************************************/ -void PSram_Ctrl_Winbond_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_Reg_Type reg_addr, uint16_t *regVal) +BL_Err_Type PSram_Ctrl_Winbond_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_Reg_Type reg_addr, uint16_t *regVal) { uint32_t tmpVal = 0; uint32_t psram_base = PSRAM_CTRL_BASE + (0x1000 * PSRAM_ID); + uint32_t time_out = 0; CHECK_PARAM(IS_PSRAM_WINBON_CFG_TYPE(reg_cfg)); CHECK_PARAM(IS_PSRAM_CTRL_WINBOND_CFG_REG_TYPE(reg_addr)); @@ -206,6 +211,9 @@ void PSram_Ctrl_Winbond_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_ //waiting confiure complete do { tmpVal = BL_RD_REG(psram_base, PSRAM_CONFIGURE); + if (time_out++ > PSRAM_X8_CTRL_WAIT_TIMEOUT) { + return TIMEOUT; + } } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_STS_CONFIG_R_DONE)); //read reg data form sts_config_read @@ -213,6 +221,8 @@ void PSram_Ctrl_Winbond_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_ *regVal = (uint16_t)(tmpVal >> 16); PSram_Ctrl_Release(PSRAM_ID); + + return SUCCESS; } /****************************************************************************/ /** @@ -222,14 +232,15 @@ void PSram_Ctrl_Winbond_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_ * @param reg_addr: PSRAM Register ID CR0 or CR1 * @param reg_cfg: winbond configuration * - * @return None + * @return SUCCESS or TIMEOUT * *******************************************************************************/ -void PSram_Ctrl_Winbond_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_Reg_Type reg_addr, PSRAM_Winbond_Cfg_Type *reg_cfg) +BL_Err_Type PSram_Ctrl_Winbond_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg_Reg_Type reg_addr, PSRAM_Winbond_Cfg_Type *reg_cfg) { uint32_t tmpVal = 0; uint32_t psram_base = PSRAM_CTRL_BASE + (0x1000 * PSRAM_ID); PSRAM_Ctrl_Size_Type psramDensity; + uint32_t time_out = 0; CHECK_PARAM(IS_PSRAM_WINBON_CFG_TYPE(reg_cfg)); CHECK_PARAM(IS_PSRAM_CTRL_WINBOND_CFG_REG_TYPE(reg_addr)); @@ -279,9 +290,14 @@ void PSram_Ctrl_Winbond_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg //waiting confiure complete do { tmpVal = BL_RD_REG(psram_base, PSRAM_CONFIGURE); + if (time_out++ > PSRAM_X8_CTRL_WAIT_TIMEOUT) { + return TIMEOUT; + } } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_STS_CONFIG_W_DONE)); PSram_Ctrl_Release(PSRAM_ID); + + return SUCCESS; } /****************************************************************************/ /** @@ -291,13 +307,14 @@ void PSram_Ctrl_Winbond_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_Winbond_Cfg * @param reg_addr: PSRAM Register ID CR0 or CR1 * @param regVal: read Reister value * - * @return None + * @return SUCCESS or TIMEOUT * *******************************************************************************/ -void PSram_Ctrl_ApMem_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_Type reg_addr, uint16_t *regVal) +BL_Err_Type PSram_Ctrl_ApMem_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_Type reg_addr, uint16_t *regVal) { uint32_t tmpVal = 0; uint32_t psram_base = PSRAM_CTRL_BASE + (0x1000 * PSRAM_ID); + uint32_t time_out = 0; CHECK_PARAM(IS_PSRAM_WINBON_CFG_TYPE(reg_cfg)); CHECK_PARAM(IS_PSRAM_CTRL_APMEM_CFG_REG_TYPE(reg_addr)); @@ -318,6 +335,9 @@ void PSram_Ctrl_ApMem_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_ //waiting confiure complete do { tmpVal = BL_RD_REG(psram_base, PSRAM_CONFIGURE); + if (time_out++ > PSRAM_X8_CTRL_WAIT_TIMEOUT) { + return TIMEOUT; + } } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_STS_CONFIG_R_DONE)); //read reg data form sts_config_read @@ -325,6 +345,8 @@ void PSram_Ctrl_ApMem_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_ *regVal = (uint16_t)(tmpVal >> 16); PSram_Ctrl_Release(PSRAM_ID); + + return SUCCESS; } /****************************************************************************/ /** @@ -334,13 +356,14 @@ void PSram_Ctrl_ApMem_Read_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_ * @param reg_addr: PSRAM Register ID * @param reg_cfg: winbond configuration * - * @return None + * @return SUCCESS or TIMEOUT * *******************************************************************************/ -void PSram_Ctrl_ApMem_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_Type reg_addr, PSRAM_APMemory_Cfg_Type *reg_cfg) +BL_Err_Type PSram_Ctrl_ApMem_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg_Type reg_addr, PSRAM_APMemory_Cfg_Type *reg_cfg) { uint32_t tmpVal = 0; uint32_t psram_base = PSRAM_CTRL_BASE + (0x1000 * PSRAM_ID); + uint32_t time_out = 0; CHECK_PARAM(IS_PSRAM_WINBON_CFG_TYPE(reg_cfg)); CHECK_PARAM(IS_PSRAM_CTRL_APMEM_CFG_REG_TYPE(reg_addr)); @@ -378,9 +401,14 @@ void PSram_Ctrl_ApMem_Write_Reg(PSRAM_ID_Type PSRAM_ID, PSRAM_Ctrl_ApMem_Cfg_Reg //waiting confiure complete do { tmpVal = BL_RD_REG(psram_base, PSRAM_CONFIGURE); + if (time_out++ > PSRAM_X8_CTRL_WAIT_TIMEOUT) { + return TIMEOUT; + } } while (!BL_IS_REG_BIT_SET(tmpVal, PSRAM_STS_CONFIG_W_DONE)); PSram_Ctrl_Release(PSRAM_ID); + + return SUCCESS; } /****************************************************************************/ /** @@ -528,4 +556,4 @@ void PSram_Ctrl_Debug_Timout(PSRAM_ID_Type PSRAM_ID, uint8_t enable, uint32_t ti /*@} end of group PSRAM_CTRL */ -/*@} end of group BL616P_Peripheral_Driver */ +/*@} end of group BL616_Peripheral_Driver */ diff --git a/drivers/soc/bl616/bl616_std/src/bl616_romapi_e907.c b/drivers/soc/bl616/bl616_std/src/bl616_romapi_e907.c index 5418e93c..2808c902 100644 --- a/drivers/soc/bl616/bl616_std/src/bl616_romapi_e907.c +++ b/drivers/soc/bl616/bl616_std/src/bl616_romapi_e907.c @@ -246,6 +246,7 @@ void EF_Ctrl_Load_Efuse_R0(void){ return RomDriver_EF_Ctrl_Load_Efuse_R0(); } +#if 0 __ALWAYS_INLINE ATTR_TCM_SECTION void EF_Ctrl_Program_Direct_R0(uint32_t index, uint32_t *data, uint32_t len){ return RomDriver_EF_Ctrl_Program_Direct_R0(index,data,len); @@ -255,6 +256,7 @@ __ALWAYS_INLINE ATTR_TCM_SECTION void EF_Ctrl_Program_Efuse_0(void){ return RomDriver_EF_Ctrl_Program_Efuse_0(); } +#endif __ALWAYS_INLINE ATTR_TCM_SECTION void EF_Ctrl_Read_ADC_Gain_Trim(Efuse_ADC_Gain_Coeff_Type *trim){ @@ -293,10 +295,12 @@ void EF_Ctrl_Read_Device_Info(Efuse_Device_Info_Type *deviceInfo){ } #endif +#if 0 __ALWAYS_INLINE ATTR_TCM_SECTION void EF_Ctrl_Read_Direct_R0(uint32_t index, uint32_t *data, uint32_t len){ return RomDriver_EF_Ctrl_Read_Direct_R0(index,data,len); } +#endif __ALWAYS_INLINE ATTR_TCM_SECTION void EF_Ctrl_Read_Ldo11socVoutTrim_Trim(Efuse_Ana_Ldo11socVoutTrim_Type *trim){ @@ -672,6 +676,13 @@ BL_Err_Type GLB_Set_ETH_REF_O_CLK_Sel(GLB_ETH_REF_CLK_OUT_Type clkSel){ return RomDriver_GLB_Set_ETH_REF_O_CLK_Sel(clkSel); } +#if 0 +__ALWAYS_INLINE ATTR_TCM_SECTION +BL_Err_Type GLB_Set_PEC_CLK(uint8_t enable, GLB_PEC_CLK_Type clkSel, uint8_t div){ + return RomDriver_GLB_Set_PEC_CLK(enable,clkSel,div); +} +#endif + #if 0 __ALWAYS_INLINE ATTR_TCM_SECTION BL_Err_Type GLB_Set_I2C_CLK(uint8_t enable, GLB_I2C_CLK_Type clkSel, uint8_t div){ @@ -2071,187 +2082,6 @@ void SFlash_Volatile_Reg_Write_Enable(SPI_Flash_Cfg_Type *flashCfg){ return RomDriver_SFlash_Volatile_Reg_Write_Enable(flashCfg); } -/* -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_AutoBaudDetection(UART_ID_Type uartId, BL_Fun_Type autoBaud){ - return RomDriver_UART_AutoBaudDetection(uartId,autoBaud); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_ClrRtsValue(UART_ID_Type uartId){ - return RomDriver_UART_ClrRtsValue(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_ClrTxValue(UART_ID_Type uartId){ - return RomDriver_UART_ClrTxValue(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_DeInit(UART_ID_Type uartId){ - return RomDriver_UART_DeInit(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_Disable(UART_ID_Type uartId, UART_Direction_Type direct){ - return RomDriver_UART_Disable(uartId,direct); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_Enable(UART_ID_Type uartId, UART_Direction_Type direct){ - return RomDriver_UART_Enable(uartId,direct); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_FifoConfig(UART_ID_Type uartId, UART_FifoCfg_Type *fifoCfg){ - return RomDriver_UART_FifoConfig(uartId,fifoCfg); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_GetBitWidth0X55(UART_ID_Type uartId, uint16_t *width){ - return RomDriver_UART_GetBitWidth0X55(uartId,width); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_Init(UART_ID_Type uartId, UART_CFG_Type *uartCfg){ - return RomDriver_UART_Init(uartId,uartCfg); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_IntClear(UART_ID_Type uartId, UART_INT_Type intType){ - return RomDriver_UART_IntClear(uartId,intType); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_IntMask(UART_ID_Type uartId, UART_INT_Type intType, BL_Mask_Type intMask){ - return RomDriver_UART_IntMask(uartId,intType,intMask); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_IrConfig(UART_ID_Type uartId, UART_IrCfg_Type *irCfg){ - return RomDriver_UART_IrConfig(uartId,irCfg); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_RxFifoClear(UART_ID_Type uartId){ - return RomDriver_UART_RxFifoClear(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SendData(UART_ID_Type uartId, uint8_t *data, uint32_t len){ - return RomDriver_UART_SendData(uartId,data,len); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SendDataBlock(UART_ID_Type uartId, uint8_t *data, uint32_t len){ - return RomDriver_UART_SendDataBlock(uartId,data,len); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SetAllowableError0X55(UART_ID_Type uartId, uint8_t allowableError){ - return RomDriver_UART_SetAllowableError0X55(uartId,allowableError); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_ApplyAbrResult(UART_ID_Type uartId, UART_AutoBaudDetection_Type autoBaudDet){ - return RomDriver_UART_SetBaudrate(uartId,autoBaudDet); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SetDeglitchCount(UART_ID_Type uartId, uint8_t deglitchCnt){ - return RomDriver_UART_SetDeglitchCount(uartId,deglitchCnt); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SetRS485(UART_ID_Type uartId, BL_Fun_Type enable, UART_RS485Polarity_Type polarity){ - return RomDriver_UART_SetRS485(uartId,enable,polarity); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SetRtsValue(UART_ID_Type uartId){ - return RomDriver_UART_SetRtsValue(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SetRxByteCount(UART_ID_Type uartId, uint16_t count){ - return RomDriver_UART_SetRxByteCount(uartId,count); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SetRxDataLength(UART_ID_Type uartId, uint16_t length){ - return RomDriver_UART_SetRxDataLength(uartId,length); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SetRxTimeoutValue(UART_ID_Type uartId, uint8_t time){ - return RomDriver_UART_SetRxTimeoutValue(uartId,time); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SetTxDataLength(UART_ID_Type uartId, uint16_t length){ - return RomDriver_UART_SetTxDataLength(uartId,length); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_SetTxValue(UART_ID_Type uartId){ - return RomDriver_UART_SetTxValue(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_TxFifoClear(UART_ID_Type uartId){ - return RomDriver_UART_TxFifoClear(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Err_Type UART_TxFreeRun(UART_ID_Type uartId, BL_Fun_Type txFreeRun){ - return RomDriver_UART_TxFreeRun(uartId,txFreeRun); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Sts_Type UART_GetIntStatus(UART_ID_Type uartId, UART_INT_Type intType){ - return RomDriver_UART_GetIntStatus(uartId,intType); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Sts_Type UART_GetOverflowStatus(UART_ID_Type uartId, UART_Overflow_Type overflow){ - return RomDriver_UART_GetOverflowStatus(uartId,overflow); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Sts_Type UART_GetRxBusBusyStatus(UART_ID_Type uartId){ - return RomDriver_UART_GetRxBusBusyStatus(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -BL_Sts_Type UART_GetTxBusBusyStatus(UART_ID_Type uartId){ - return RomDriver_UART_GetTxBusBusyStatus(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -uint16_t UART_GetAutoBaudCount(UART_ID_Type uartId, UART_AutoBaudDetection_Type autoBaudDet){ - return RomDriver_UART_GetAutoBaudCount(uartId,autoBaudDet); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -uint16_t UART_GetRxByteCount(UART_ID_Type uartId){ - return RomDriver_UART_GetRxByteCount(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -uint32_t UART_ReceiveData(UART_ID_Type uartId, uint8_t *data, uint32_t maxLen){ - return RomDriver_UART_ReceiveData(uartId,data,maxLen); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -uint8_t UART_GetRxFifoCount(UART_ID_Type uartId){ - return RomDriver_UART_GetRxFifoCount(uartId); -} - -__ALWAYS_INLINE ATTR_TCM_SECTION -uint8_t UART_GetTxFifoCount(UART_ID_Type uartId){ - return RomDriver_UART_GetTxFifoCount(uartId); -} -*/ #if 0 __ALWAYS_INLINE ATTR_TCM_SECTION BL_Err_Type XIP_SFlash_Erase_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t startaddr, int len, uint8_t group, SF_Ctrl_Bank_Select bank){ diff --git a/drivers/soc/bl616/bl616_std/src/bl616_romapi_patch.c b/drivers/soc/bl616/bl616_std/src/bl616_romapi_patch.c index 7aa41785..987dd2d9 100644 --- a/drivers/soc/bl616/bl616_std/src/bl616_romapi_patch.c +++ b/drivers/soc/bl616/bl616_std/src/bl616_romapi_patch.c @@ -36,7 +36,7 @@ #include "bl616_romapi_patch.h" #include "bl616_romdriver_e907.h" -// #include "softcrc.h" +#include "soft_crc.h" /* WiFi PLL Config*/ const GLB_WA_PLL_CFG_BASIC_Type ATTR_CLOCK_CONST_SECTION wifiPllBasicCfg_32M_38P4M_40M = { @@ -199,7 +199,7 @@ const GLB_SLAVE_GRP_0_TBL_Type ATTR_CLOCK_CONST_SECTION glb_slave_grp_0_table[GL { GLB_IR_CFG0_OFFSET, GLB_IR_CLK_EN_POS, 0, GLB_IR_CLK_DIV_POS, GLB_IR_CLK_EN_LEN, 0, GLB_IR_CLK_DIV_LEN }, { GLB_I2C_CFG0_OFFSET, GLB_I2C_CLK_EN_POS, GLB_I2C_CLK_SEL_POS, GLB_I2C_CLK_DIV_POS, GLB_I2C_CLK_EN_LEN, GLB_I2C_CLK_SEL_LEN, GLB_I2C_CLK_DIV_LEN }, { GLB_SPI_CFG0_OFFSET, GLB_SPI_CLK_EN_POS, GLB_SPI_CLK_SEL_POS, GLB_SPI_CLK_DIV_POS, GLB_SPI_CLK_EN_LEN, GLB_SPI_CLK_SEL_LEN, GLB_SPI_CLK_DIV_LEN }, - { 0, 0, 0, 0, 0, 0, 0 }, + { GLB_PEC_CFG0_OFFSET, GLB_PEC_CLK_EN_POS, GLB_PEC_CLK_SEL_POS, GLB_PEC_CLK_DIV_POS, GLB_PEC_CLK_EN_LEN, GLB_PEC_CLK_SEL_LEN, GLB_PEC_CLK_DIV_LEN }, { GLB_DBI_CFG0_OFFSET, GLB_DBI_CLK_EN_POS, GLB_DBI_CLK_SEL_POS, GLB_DBI_CLK_DIV_POS, GLB_DBI_CLK_EN_LEN, GLB_DBI_CLK_SEL_LEN, GLB_DBI_CLK_DIV_LEN }, { GLB_AUDIO_CFG0_OFFSET, GLB_REG_AUDIO_AUTO_DIV_EN_POS, 0, 0, GLB_REG_AUDIO_AUTO_DIV_EN_LEN, 0, 0 }, { GLB_AUDIO_CFG0_OFFSET, GLB_REG_AUDIO_ADC_CLK_EN_POS, 0, GLB_REG_AUDIO_ADC_CLK_DIV_POS, GLB_REG_AUDIO_ADC_CLK_EN_LEN, 0, GLB_REG_AUDIO_ADC_CLK_DIV_LEN }, @@ -209,11 +209,6 @@ const GLB_SLAVE_GRP_0_TBL_Type ATTR_CLOCK_CONST_SECTION glb_slave_grp_0_table[GL { GLB_PSRAM_CFG0_OFFSET, GLB_REG_PSRAMB_CLK_EN_POS, GLB_REG_PSRAMB_CLK_SEL_POS, GLB_REG_PSRAMB_CLK_DIV_POS, GLB_REG_PSRAMB_CLK_EN_LEN, GLB_REG_PSRAMB_CLK_SEL_LEN, GLB_REG_PSRAMB_CLK_DIV_LEN }, }; -// static const uint32_t uartAddr[UART_ID_MAX] = { UART0_BASE, UART1_BASE }; -// static intCallback_Type *uartIntCbfArra[UART_ID_MAX][UART_INT_ALL] = { -// { NULL } -// }; - typedef struct { uint32_t jedecID; @@ -907,186 +902,6 @@ static const ATTR_TCM_CONST_SECTION Flash_Info_t flashInfos[] = { }, }; -//UART -// static void UART_IntHandler(UART_ID_Type uartId) -// { -// uint32_t tmpVal = 0; -// uint32_t maskVal = 0; -// uint32_t UARTx = uartAddr[uartId]; - -// tmpVal = BL_RD_REG(UARTx, UART_INT_STS); -// maskVal = BL_RD_REG(UARTx, UART_INT_MASK); - -// /* Length of uart tx data transfer arrived interrupt */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_UTX_END_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_UTX_END_MASK)) { -// BL_WR_REG(UARTx, UART_INT_CLEAR, 1 << UART_CR_UTX_END_CLR_POS); - -// if (uartIntCbfArra[uartId][UART_INT_TX_END] != NULL) { -// uartIntCbfArra[uartId][UART_INT_TX_END](); -// } -// } - -// /* Length of uart rx data transfer arrived interrupt */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_URX_END_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_URX_END_MASK)) { -// BL_WR_REG(UARTx, UART_INT_CLEAR, 1 << UART_CR_URX_END_CLR_POS); - -// if (uartIntCbfArra[uartId][UART_INT_RX_END] != NULL) { -// uartIntCbfArra[uartId][UART_INT_RX_END](); -// } -// } - -// /* Tx fifo ready interrupt,auto-cleared when data is pushed */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_UTX_FRDY_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_UTX_FRDY_MASK)) { -// if (uartIntCbfArra[uartId][UART_INT_TX_FIFO_REQ] != NULL) { -// uartIntCbfArra[uartId][UART_INT_TX_FIFO_REQ](); -// } -// } - -// /* Rx fifo ready interrupt,auto-cleared when data is popped */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_URX_FRDY_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_URX_FRDY_MASK)) { -// if (uartIntCbfArra[uartId][UART_INT_RX_FIFO_REQ] != NULL) { -// uartIntCbfArra[uartId][UART_INT_RX_FIFO_REQ](); -// } -// } - -// /* Rx time-out interrupt */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_URX_RTO_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_URX_RTO_MASK)) { -// BL_WR_REG(UARTx, UART_INT_CLEAR, 1 << UART_CR_URX_RTO_CLR_POS); - -// if (uartIntCbfArra[uartId][UART_INT_RTO] != NULL) { -// uartIntCbfArra[uartId][UART_INT_RTO](); -// } -// } - -// /* Rx parity check error interrupt */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_URX_PCE_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_URX_PCE_MASK)) { -// BL_WR_REG(UARTx, UART_INT_CLEAR, 1 << UART_CR_URX_PCE_CLR_POS); - -// if (uartIntCbfArra[uartId][UART_INT_PCE] != NULL) { -// uartIntCbfArra[uartId][UART_INT_PCE](); -// } -// } - -// /* Tx fifo overflow/underflow error interrupt */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_UTX_FER_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_UTX_FER_MASK)) { -// if (uartIntCbfArra[uartId][UART_INT_TX_FER] != NULL) { -// uartIntCbfArra[uartId][UART_INT_TX_FER](); -// } -// } - -// /* Rx fifo overflow/underflow error interrupt */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_URX_FER_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_URX_FER_MASK)) { -// if (uartIntCbfArra[uartId][UART_INT_RX_FER] != NULL) { -// uartIntCbfArra[uartId][UART_INT_RX_FER](); -// } -// } - -// /* Rx lin mode sync field error interrupt */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_URX_LSE_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_URX_LSE_MASK)) { -// BL_WR_REG(UARTx, UART_INT_CLEAR, 1 << UART_CR_URX_LSE_CLR_POS); - -// if (uartIntCbfArra[uartId][UART_INT_LSE] != NULL) { -// uartIntCbfArra[uartId][UART_INT_LSE](); -// } -// } - -// /* Rx byte count reached interrupt */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_URX_BCR_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_URX_BCR_MASK)) { -// BL_WR_REG(UARTx, UART_INT_CLEAR, 1 << UART_CR_URX_BCR_CLR_POS); - -// if (uartIntCbfArra[uartId][UART_INT_BCR] != NULL) { -// uartIntCbfArra[uartId][UART_INT_BCR](); -// } -// } - -// /* Rx auto baud rate detection finish interrupt using start bit */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_URX_ADS_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_URX_ADS_MASK)) { -// BL_WR_REG(UARTx, UART_INT_CLEAR, 1 << UART_CR_URX_ADS_CLR_POS); - -// if (uartIntCbfArra[uartId][UART_INT_STARTBIT] != NULL) { -// uartIntCbfArra[uartId][UART_INT_STARTBIT](); -// } -// } - -// /* Rx auto baud rate detection finish interrupt using codeword 0x55 */ -// if (BL_IS_REG_BIT_SET(tmpVal, UART_URX_AD5_INT) && !BL_IS_REG_BIT_SET(maskVal, UART_CR_URX_AD5_MASK)) { -// BL_WR_REG(UARTx, UART_INT_CLEAR, 1 << UART_CR_URX_AD5_CLR_POS); - -// if (uartIntCbfArra[uartId][UART_INT_0X55] != NULL) { -// uartIntCbfArra[uartId][UART_INT_0X55](); -// } -// } -// } - -// #if (defined BOOTROM) || (!defined BFLB_USE_HAL_DRIVER) -// void UART1_IRQHandler(void) -// { -// UART_IntHandler(UART1_ID); -// } -// #endif - -// /****************************************************************************/ /** -// * @brief Install uart interrupt callback function -// * -// * @param uartId: UART ID type -// * @param intType: UART interrupt type -// * @param cbFun: Pointer to interrupt callback function. The type should be void (*fn)(void) -// * -// * @return SUCCESS -// * -// *******************************************************************************/ -// BL_Err_Type UART_Int_Callback_Install(UART_ID_Type uartId, UART_INT_Type intType, intCallback_Type *cbFun) -// { -// /* Check the parameters */ -// CHECK_PARAM(IS_UART_ID_TYPE(uartId)); -// CHECK_PARAM(IS_UART_INT_TYPE(intType)); - -// uartIntCbfArra[uartId][intType] = cbFun; - -// return SUCCESS; -// } - -// /****************************************************************************/ /** -// * @brief UART set baud rate function -// * -// * @param uartId: UART ID type -// * @param baudRate: baudRate need to set -// * -// * @return SUCCESS or ERROR -// * -// *******************************************************************************/ -// BL_Err_Type UART_SetBaudRate(UART_ID_Type uartId, uint32_t baudRate) -// { -// uint32_t uartClk = 0; -// uint32_t fraction = 0; -// uint32_t baudRateDivisor = 0; -// uint32_t UARTx = uartAddr[uartId]; - -// /* Check the parameters */ -// CHECK_PARAM(IS_UART_ID_TYPE(uartId)); - -// /* Get uart clk */ -// if (uartId == UART0_ID || uartId == UART1_ID) { -// uartClk = Clock_Peripheral_Clock_Get(BL_PERIPHERAL_CLOCK_UART0); -// } else { -// return ERROR; -// } - -// /* Cal the baud rate divisor */ -// fraction = uartClk * 10 / baudRate % 10; -// baudRateDivisor = uartClk / baudRate; - -// if (fraction >= 5) { -// ++baudRateDivisor; -// } - -// /* Set the baud rate register value */ -// BL_WR_REG(UARTx, UART_BIT_PRD, ((baudRateDivisor - 1) << 0x10) | ((baudRateDivisor - 1) & 0xFFFF)); - -// return SUCCESS; -// } - - //CLOCK //EFUSE //PDS @@ -1197,6 +1012,64 @@ BL_Err_Type ATTR_TCM_SECTION SFlash_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t return SUCCESS; } +/****************************************************************************//** + * @brief Clear flash status register + * + * @param flashCfg: Flash configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_Clear_Status_Register(SPI_Flash_Cfg_Type *flashCfg) +{ + uint32_t ret = 0; + uint32_t qeValue = 0; + uint32_t regValue = 0; + uint32_t readValue = 0; + uint8_t readRegValue0 = 0; + uint8_t readRegValue1 = 0; + + if((flashCfg->ioMode&0xf)==SF_CTRL_QO_MODE || (flashCfg->ioMode&0xf)==SF_CTRL_QIO_MODE){ + qeValue = 1; + } + + SFlash_Read_Reg(flashCfg, 0, (uint8_t *)&readRegValue0, 1); + SFlash_Read_Reg(flashCfg, 1, (uint8_t *)&readRegValue1, 1); + readValue = (readRegValue0|(readRegValue1<<8)); + if ((readValue & (~((1<<(flashCfg->qeIndex*8+flashCfg->qeBit)) | + (1<<(flashCfg->busyIndex*8+flashCfg->busyBit)) | + (1<<(flashCfg->wrEnableIndex*8+flashCfg->wrEnableBit))))) == 0){ + return SUCCESS; + } + + ret = SFlash_Write_Enable(flashCfg); + if (SUCCESS != ret) { + return ERROR; + } + if (flashCfg->qeWriteRegLen == 2) { + regValue = (qeValue<<(flashCfg->qeIndex*8+flashCfg->qeBit)); + SFlash_Write_Reg(flashCfg, 0, (uint8_t *)®Value, 2); + } else { + if (flashCfg->qeIndex == 0) { + regValue = (qeValue<qeBit); + } else { + regValue = 0; + } + SFlash_Write_Reg(flashCfg, 0, (uint8_t *)®Value, 1); + ret = SFlash_Write_Enable(flashCfg); + if (SUCCESS != ret) { + return ERROR; + } + if (flashCfg->qeIndex == 1) { + regValue = (qeValue<qeBit); + } else { + regValue = 0; + } + SFlash_Write_Reg(flashCfg, 1, (uint8_t *)®Value, 1); + } + return SUCCESS; +} + /****************************************************************************/ /** * @brief Get flash config according to flash ID patch * @@ -1206,43 +1079,43 @@ BL_Err_Type ATTR_TCM_SECTION SFlash_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t * @return SUCCESS or ERROR * *******************************************************************************/ -// BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(uint32_t flashID, SPI_Flash_Cfg_Type *pFlashCfg) -// { -// uint32_t i; -// uint8_t buf[sizeof(SPI_Flash_Cfg_Type) + 8]; -// uint32_t crc, *pCrc; -// uint32_t xipOffset; -// char flashCfgMagic[] = "FCFG"; +BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(uint32_t flashID, SPI_Flash_Cfg_Type *pFlashCfg) +{ + uint32_t i; + uint8_t buf[sizeof(SPI_Flash_Cfg_Type) + 8]; + uint32_t crc, *pCrc; + uint32_t xipOffset; + char flashCfgMagic[] = "FCFG"; -// if (flashID == 0) { -// xipOffset = SF_Ctrl_Get_Flash_Image_Offset(0, SF_CTRL_FLASH_BANK0); -// SF_Ctrl_Set_Flash_Image_Offset(0, 0, SF_CTRL_FLASH_BANK0); -// XIP_SFlash_Read_Via_Cache_Need_Lock(8 + BL616_FLASH_XIP_BASE, buf, sizeof(SPI_Flash_Cfg_Type) + 8); -// SF_Ctrl_Set_Flash_Image_Offset(xipOffset, 0, SF_CTRL_FLASH_BANK0); + if (flashID == 0) { + xipOffset = SF_Ctrl_Get_Flash_Image_Offset(0, SF_CTRL_FLASH_BANK0); + SF_Ctrl_Set_Flash_Image_Offset(0, 0, SF_CTRL_FLASH_BANK0); + XIP_SFlash_Read_Via_Cache_Need_Lock(8 + BL616_FLASH_XIP_BASE, buf, sizeof(SPI_Flash_Cfg_Type) + 8); + SF_Ctrl_Set_Flash_Image_Offset(xipOffset, 0, SF_CTRL_FLASH_BANK0); -// if (ARCH_MemCmp(buf, flashCfgMagic, 4) == 0) { -// crc = BFLB_Soft_CRC32((uint8_t *)buf + 4, sizeof(SPI_Flash_Cfg_Type)); -// pCrc = (uint32_t *)(buf + 4 + sizeof(SPI_Flash_Cfg_Type)); + if (ARCH_MemCmp(buf, flashCfgMagic, 4) == 0) { + crc = BFLB_Soft_CRC32((uint8_t *)buf + 4, sizeof(SPI_Flash_Cfg_Type)); + pCrc = (uint32_t *)(buf + 4 + sizeof(SPI_Flash_Cfg_Type)); -// if (*pCrc == crc) { -// ARCH_MemCpy_Fast(pFlashCfg, (uint8_t *)buf + 4, sizeof(SPI_Flash_Cfg_Type)); -// return SUCCESS; -// } -// } -// } else { -// if (RomDriver_SF_Cfg_Get_Flash_Cfg_Need_Lock(flashID, pFlashCfg) == SUCCESS) { -// return SUCCESS; -// } -// for (i = 0; i < sizeof(flashInfos) / sizeof(flashInfos[0]); i++) { -// if (flashInfos[i].jedecID == flashID) { -// ARCH_MemCpy_Fast(pFlashCfg, flashInfos[i].cfg, sizeof(SPI_Flash_Cfg_Type)); -// return SUCCESS; -// } -// } -// } + if (*pCrc == crc) { + ARCH_MemCpy_Fast(pFlashCfg, (uint8_t *)buf + 4, sizeof(SPI_Flash_Cfg_Type)); + return SUCCESS; + } + } + } else { + if (RomDriver_SF_Cfg_Get_Flash_Cfg_Need_Lock(flashID, pFlashCfg) == SUCCESS) { + return SUCCESS; + } + for (i = 0; i < sizeof(flashInfos) / sizeof(flashInfos[0]); i++) { + if (flashInfos[i].jedecID == flashID) { + ARCH_MemCpy_Fast(pFlashCfg, flashInfos[i].cfg, sizeof(SPI_Flash_Cfg_Type)); + return SUCCESS; + } + } + } -// return ERROR; -// } + return ERROR; +} /****************************************************************************/ /** * @brief Identify one flash patch @@ -1567,6 +1440,35 @@ BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_GetUniqueId_Need_Lock(SPI_Flash_Cfg_Type return SUCCESS; } +/****************************************************************************//** + * @brief Clear flash status register need lock + * + * @param pFlashCfg: Flash config pointer + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Clear_Status_Register_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + BL_Err_Type stat; + uint32_t offset; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode&0xf; + + stat=XIP_SFlash_State_Save(pFlashCfg, &offset, group, bank); + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32, bank); + } else { + stat=SFlash_Clear_Status_Register(pFlashCfg); + XIP_SFlash_State_Restore(pFlashCfg, offset, group, bank); + } + + return stat; +} + /****************************************************************************/ /** * @brief reconfigure WIFIPLL clock * @@ -2183,6 +2085,47 @@ BL_Err_Type GLB_Set_SPI_CLK(uint8_t enable, GLB_SPI_CLK_Type clkSel, uint8_t div return SUCCESS; } +/****************************************************************************/ /** + * @brief set PEC clock + * + * @param enable: Enable or disable PEC clock + * @param clkSel: clock selection + * @param div: divider + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type GLB_Set_PEC_CLK(uint8_t enable, GLB_PEC_CLK_Type clkSel, uint8_t div) +{ +#ifndef BOOTROM + uint32_t tmpVal = 0; + + CHECK_PARAM(IS_GLB_PEC_CLK_TYPE(clkSel)); + CHECK_PARAM((div <= 0x1F)); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_PEC_CFG0); + tmpVal >>= 1; + tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_PEC_CLK_EN); + BL_WR_REG(GLB_BASE, GLB_PEC_CFG0, tmpVal); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_PEC_CFG0); + tmpVal >>= 1; + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_PEC_CLK_DIV, div); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_PEC_CLK_SEL, clkSel); + BL_WR_REG(GLB_BASE, GLB_PEC_CFG0, tmpVal); + + tmpVal = BL_RD_REG(GLB_BASE, GLB_PEC_CFG0); + tmpVal >>= 1; + if (enable) { + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_PEC_CLK_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, GLB_PEC_CLK_EN); + } + BL_WR_REG(GLB_BASE, GLB_PEC_CFG0, tmpVal); +#endif + return SUCCESS; +} + /****************************************************************************/ /** * @brief set DBI clock * @@ -3008,3 +2951,245 @@ BL_Err_Type HBN_Set_BOD_Cfg(HBN_BOD_CFG_Type *cfg) return SUCCESS; } +#define GLB_CLK_SET_DUMMY_WAIT \ + { \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + __NOP(); \ + } +const uint32_t ATTR_CLOCK_CONST_SECTION usbPllSdmin_12M = 0x28000; +const uint32_t ATTR_CLOCK_CONST_SECTION sscDivSdmin_24M = 0x28000; + +void glb_40M_delay_us(uint32_t us) +{ + for (uint32_t i = 0; i < us; i++) { + GLB_CLK_SET_DUMMY_WAIT; + GLB_CLK_SET_DUMMY_WAIT; + GLB_CLK_SET_DUMMY_WAIT; + } +} + +/****************************************************************************/ /** + * @brief power on wifipll quickly + * + * @param xtalType: XTAL frequency type + * @param pllType: only power on xtal + *******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Fast_Power_On_WIFIPLL(const GLB_WA_PLL_Cfg_Type *const cfg, uint8_t waitStable) +{ + uint32_t REG_PLL_BASE_ADDRESS = 0; + uint32_t tmpVal = 0; + + REG_PLL_BASE_ADDRESS = GLB_BASE + GLB_WIFI_PLL_CFG0_OFFSET; + + /* Step1:config parameter */ + /* cfg1:Set wifipll_refclk_sel and wifipll_refdiv_ratio */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_REFDIV_RATIO, cfg->basicCfg->clkpllRefdivRatio); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 1, tmpVal); + + /* cfg2:Set wifipll_int_frac_sw,wifipll_icp_1u,wifipll_icp_5u */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_INT_FRAC_SW, cfg->basicCfg->clkpllIntFracSw); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_ICP_1U, cfg->basicCfg->clkpllIcp1u); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_ICP_5U, cfg->basicCfg->clkpllIcp5u); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 2, tmpVal); + + /* cfg3:Set wifipll_rz,wifipll_cz,wifipll_c3,wifipll_r4_short,wifipll_r4_en */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_RZ, cfg->basicCfg->clkpllRz); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_CZ, cfg->basicCfg->clkpllCz); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_C3, cfg->basicCfg->clkpllC3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_R4_SHORT, cfg->basicCfg->clkpllR4Short); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_C4_EN, cfg->basicCfg->clkpllC4En); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 3, tmpVal); + + /* cfg4:Set wifipll_sel_sample_clk */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_SEL_SAMPLE_CLK, cfg->basicCfg->clkpllSelSampleClk); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 4, tmpVal); + + /* cfg5:Set wifipll_vco_speed */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 5); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_VCO_SPEED, cfg->basicCfg->clkpllVcoSpeed); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 5, tmpVal); + + /* cfg6:Set wifipll_sdm_bypass,wifipll_sdmin */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 6); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_SDM_CTRL_HW, cfg->basicCfg->clkpllSdmCtrlHw); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_SDM_BYPASS, cfg->basicCfg->clkpllSdmBypass); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_SDMIN, cfg->clkpllSdmin); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 6, tmpVal); + + /* cfg10:always set usbpll_sdmin */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 10); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_USBPLL_SDMIN, usbPllSdmin_12M); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 10, tmpVal); + + /* cfg12:always set sscdiv_sdmin */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 12); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_SSCDIV_SDMIN, sscDivSdmin_24M); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 12, tmpVal); + + /* Step2:config pu */ + /* cfg0 : pu_wifipll_sfreg=1 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_PU_WIFIPLL_SFREG, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* delay > 2us */ + glb_40M_delay_us(3); + + /* cfg0 : pu_wifipll=1 */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_PU_WIFIPLL, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* delay > 2us */ + glb_40M_delay_us(3); + + /* toggle sdm_reset (pulse 0 > 1us) */ + /* cfg0 : wifipll_sdm_reset */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_SDM_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + glb_40M_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_SDM_RSTB, 0); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + glb_40M_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_SDM_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* Step3:reset pll */ + /* cfg0 : toggle wifipll_reset_fbdv, pulse 0 > 1us */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_FBDV_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + glb_40M_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_FBDV_RSTB, 0); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + glb_40M_delay_us(2); + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, GLB_WIFIPLL_FBDV_RSTB, 1); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 0, tmpVal); + + /* Step4:enable output clock */ + /* cfg8 : wifipll clock enable */ + tmpVal = BL_RD_WORD(REG_PLL_BASE_ADDRESS + 4 * 8); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV3); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV4); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV5); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV6); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV8); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV10); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV12); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV20); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_WIFIPLL_EN_DIV30); + BL_WR_WORD(REG_PLL_BASE_ADDRESS + 4 * 8, tmpVal); + + if (waitStable) { + /* Wait 1.5*30us */ + glb_40M_delay_us(45); + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief power on xtal and wifipll quickly + * + * @param xtalType: XTAL frequency type + * @param pllType: only power on xtal + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_CLOCK_SECTION GLB_Fast_Power_On_XTAL_40M_And_WIFIPLL(void) +{ + uint32_t tmpVal; + volatile GLB_PLL_REF_CLK_Type refClk; + + refClk = GLB_PLL_REFCLK_XTAL; + + /* power on xtal first */ + AON_Power_On_XTAL(); + + HBN_Set_MCU_XCLK_Sel(HBN_MCU_XCLK_RC32M); + HBN_Set_MCU_Root_CLK_Sel(HBN_MCU_ROOT_CLK_XCLK); + + HBN_Set_Xtal_Type(GLB_XTAL_40M); + + /* power on wifipll */ + GLB_Power_Off_WIFIPLL(); + GLB_WIFIPLL_Ref_Clk_Sel(refClk); + GLB_Fast_Power_On_WIFIPLL(&wifiPllCfg_960M[GLB_XTAL_40M], 0); + + glb_40M_delay_us(30); + + /* if power on xtal, always set xclk from xtal */ + HBN_Set_MCU_XCLK_Sel(HBN_MCU_XCLK_XTAL); + + /* enable all PLL clock output */ + /* GLB reg_pll_en = 1, cannot be zero */ + tmpVal = BL_RD_REG(GLB_BASE, GLB_SYS_CFG0); + tmpVal = BL_SET_REG_BIT(tmpVal, GLB_REG_PLL_EN); + BL_WR_REG(GLB_BASE, GLB_SYS_CFG0, tmpVal); + + GLB_CLK_SET_DUMMY_WAIT; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Program data to efuse + * + * @param offset: offset of efuse address to program + * @param pword: data pointer to buffer which is aligned to word + * @param count: count of data in words to program + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Program_Direct(uint32_t offset, uint32_t *pword, uint32_t count) +{ + uint32_t *pEfuseStart0 = (uint32_t *)(EF_DATA_BASE + offset); + + /* Switch to AHB clock */ + EF_Ctrl_Sw_AHB_Clk_0(); + + /* Add delay for CLK to be stable */ + arch_delay_us(4); + + if (pword != NULL) { + ARCH_MemCpy4(pEfuseStart0, pword, count); + } + + EF_Ctrl_Program_Efuse_0(); +} + +/****************************************************************************/ /** + * @brief Read data from efuse + * + * @param offset: offset of efuse address to read + * @param pword: data pointer to buffer which is aligned to word + * @param count: count of data in words to read + * + * @return None + * +*******************************************************************************/ +void EF_Ctrl_Read_Direct(uint32_t offset, uint32_t *pword, uint32_t count) +{ + uint32_t *pEfuseStart0 = (uint32_t *)(EF_DATA_BASE + offset); + + EF_Ctrl_Load_Efuse_R0(); + + ARCH_MemCpy4(pword, pEfuseStart0, count); +} diff --git a/drivers/soc/bl616/bl616_std/src/bl616_sdh.c b/drivers/soc/bl616/bl616_std/src/bl616_sdh.c index a6adacdb..a3888155 100644 --- a/drivers/soc/bl616/bl616_std/src/bl616_sdh.c +++ b/drivers/soc/bl616/bl616_std/src/bl616_sdh.c @@ -75,9 +75,7 @@ static SDH_Handle_Cfg_Type *sdhHandle = NULL; /** @defgroup SDH_Private_Fun_Declaration * @{ */ -#if (defined BOOTROM) || (!defined BFLB_USE_HAL_DRIVER) static void SDH_IntHandler(IRQn_Type intPeriph, SDH_Handle_Cfg_Type *handle); -#endif /*@} end of group SDH_Private_Fun_Declaration */ @@ -1229,7 +1227,6 @@ void SDH_InstallHandleCallback(SDH_Handle_Cfg_Type *handle, * @return None * *******************************************************************************/ -#if (defined BOOTROM) || (!defined BFLB_USE_HAL_DRIVER) static void SDH_IntHandler(IRQn_Type intPeriph, SDH_Handle_Cfg_Type *handle) { uint32_t intFlag, intMask; @@ -1345,7 +1342,6 @@ static void SDH_IntHandler(IRQn_Type intPeriph, SDH_Handle_Cfg_Type *handle) SDH_ClearIntStatus(intFlag); } -#endif /****************************************************************************/ /** * @brief SDH interrupt handler @@ -1355,12 +1351,10 @@ static void SDH_IntHandler(IRQn_Type intPeriph, SDH_Handle_Cfg_Type *handle) * @return None * *******************************************************************************/ -#if (defined BOOTROM) || (!defined BFLB_USE_HAL_DRIVER) void SDH_MMC1_IRQHandler(void) { SDH_IntHandler(SDH_IRQn, sdhHandle); } -#endif /*@} end of group SDH_Public_Functions */ diff --git a/drivers/soc/bl616/bl616_std/src/bl616_sf_cfg.c b/drivers/soc/bl616/bl616_std/src/bl616_sf_cfg.c index d8d10039..7762277c 100644 --- a/drivers/soc/bl616/bl616_std/src/bl616_sf_cfg.c +++ b/drivers/soc/bl616/bl616_std/src/bl616_sf_cfg.c @@ -35,8 +35,8 @@ */ #include "bl616_sf_cfg.h" -#include "softcrc.h" #include "bl616_xip_sflash.h" +#include "soft_crc.h" /** @addtogroup BL616_Peripheral_Driver * @{ diff --git a/drivers/soc/bl616/bl616_std/src/bl616_sflash.c b/drivers/soc/bl616/bl616_std/src/bl616_sflash.c index 50c180b8..3687411b 100644 --- a/drivers/soc/bl616/bl616_std/src/bl616_sflash.c +++ b/drivers/soc/bl616/bl616_std/src/bl616_sflash.c @@ -2157,6 +2157,65 @@ BL_Err_Type ATTR_TCM_SECTION SFlash_Program(SPI_Flash_Cfg_Type *flashCfg, } #endif + +/****************************************************************************//** + * @brief Clear flash status register + * + * @param flashCfg: Flash configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_Clear_Status_Register(SPI_Flash_Cfg_Type *flashCfg) +{ + uint32_t ret = 0; + uint32_t qeValue = 0; + uint32_t regValue = 0; + uint32_t readValue = 0; + uint8_t readRegValue0 = 0; + uint8_t readRegValue1 = 0; + + if((flashCfg->ioMode&0xf)==SF_CTRL_QO_MODE || (flashCfg->ioMode&0xf)==SF_CTRL_QIO_MODE){ + qeValue = 1; + } + + SFlash_Read_Reg(flashCfg, 0, (uint8_t *)&readRegValue0, 1); + SFlash_Read_Reg(flashCfg, 1, (uint8_t *)&readRegValue1, 1); + readValue = (readRegValue0|(readRegValue1<<8)); + if ((readValue & (~((1<<(flashCfg->qeIndex*8+flashCfg->qeBit)) | + (1<<(flashCfg->busyIndex*8+flashCfg->busyBit)) | + (1<<(flashCfg->wrEnableIndex*8+flashCfg->wrEnableBit))))) == 0){ + return SUCCESS; + } + + ret = SFlash_Write_Enable(flashCfg); + if (SUCCESS != ret) { + return ERROR; + } + if (flashCfg->qeWriteRegLen == 2) { + regValue = (qeValue<<(flashCfg->qeIndex*8+flashCfg->qeBit)); + SFlash_Write_Reg(flashCfg, 0, (uint8_t *)®Value, 2); + } else { + if (flashCfg->qeIndex == 0) { + regValue = (qeValue<qeBit); + } else { + regValue = 0; + } + SFlash_Write_Reg(flashCfg, 0, (uint8_t *)®Value, 1); + ret = SFlash_Write_Enable(flashCfg); + if (SUCCESS != ret) { + return ERROR; + } + if (flashCfg->qeIndex == 1) { + regValue = (qeValue<qeBit); + } else { + regValue = 0; + } + SFlash_Write_Reg(flashCfg, 1, (uint8_t *)®Value, 1); + } + return SUCCESS; +} + /*@} end of group SFLASH_Public_Functions */ /*@} end of group SFLASH */ diff --git a/drivers/soc/bl616/bl616_std/src/bl616_xip_sflash.c b/drivers/soc/bl616/bl616_std/src/bl616_xip_sflash.c index fa017278..5116ba2d 100644 --- a/drivers/soc/bl616/bl616_std/src/bl616_xip_sflash.c +++ b/drivers/soc/bl616/bl616_std/src/bl616_xip_sflash.c @@ -461,6 +461,35 @@ void ATTR_TCM_SECTION XIP_SFlash_Opt_Exit(uint8_t aesEnable) } } +/****************************************************************************//** + * @brief Clear flash status register need lock + * + * @param pFlashCfg: Flash config pointer + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Clear_Status_Register_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + BL_Err_Type stat; + uint32_t offset; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode&0xf; + + stat=XIP_SFlash_State_Save(pFlashCfg, &offset, group, bank); + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32, bank); + } else { + stat=SFlash_Clear_Status_Register(pFlashCfg); + XIP_SFlash_State_Restore(pFlashCfg, offset, group, bank); + } + + return stat; +} + /*@} end of group XIP_SFLASH_Public_Functions */ /*@} end of group XIP_SFLASH */ diff --git a/drivers/soc/bl616/port/bl616_efuse.c b/drivers/soc/bl616/port/bl616_efuse.c new file mode 100644 index 00000000..fa030e48 --- /dev/null +++ b/drivers/soc/bl616/port/bl616_efuse.c @@ -0,0 +1,53 @@ +#include "bflb_efuse.h" +#include "bl616_ef_ctrl.h" + +float bflb_efuse_get_adc_trim(void) +{ + Efuse_ADC_Gain_Coeff_Type trim; + uint32_t tmp; + + float coe = 1.0; + + EF_Ctrl_Read_ADC_Gain_Trim(&trim); + + if (trim.adcGainCoeffEn) { + if (trim.adcGainCoeffParity == EF_Ctrl_Get_Trim_Parity(trim.adcGainCoeff, 12)) { + tmp = trim.adcGainCoeff; + + if (tmp & 0x800) { + tmp = ~tmp; + tmp += 1; + tmp = tmp & 0xfff; + coe = (1.0 + ((float)tmp / 2048.0)); + } else { + coe = (1.0 - ((float)tmp / 2048.0)); + } + } + } + + return coe; +} + +uint32_t bflb_efuse_get_adc_tsen_trim(void) +{ + Efuse_TSEN_Refcode_Corner_Type trim; + + EF_Ctrl_Read_TSEN_Trim(&trim); + if (trim.tsenRefcodeCornerEn) { + if (trim.tsenRefcodeCornerParity == EF_Ctrl_Get_Trim_Parity(trim.tsenRefcodeCorner, 12)) { + return trim.tsenRefcodeCorner; + } + } + + return 2042; +} + +void bflb_efuse_write_aes_key(uint8_t index, uint8_t *data, uint32_t len) +{ + EF_Ctrl_Write_AES_Key(index, (uint32_t *)data, len, 1); +} + +void bflb_efuse_read_aes_key(uint8_t index, uint8_t *data, uint32_t len) +{ + EF_Ctrl_Read_AES_Key(index, (uint32_t *)data, len); +} \ No newline at end of file diff --git a/drivers/soc/bl616/port/bl616_flash.c b/drivers/soc/bl616/port/bl616_flash.c new file mode 100644 index 00000000..0978f75b --- /dev/null +++ b/drivers/soc/bl616/port/bl616_flash.c @@ -0,0 +1,395 @@ +#include "bl616_glb.h" +#include "bl616_xip_sflash.h" +#include "bl616_sf_cfg.h" +#include "bl616_ef_cfg.h" +#include "bflb_flash.h" + +static uint32_t flash1_size = 4 * 1024 * 1024; +static uint32_t flash2_size = 2 * 1024 * 1024; +static uint32_t g_jedec_id = 0; +static uint32_t g_jedec_id2 = 0; +static SPI_Flash_Cfg_Type g_flash_cfg; +static SPI_Flash_Cfg_Type g_flash2_cfg; + +uint32_t flash2_get_jedecid(void) +{ + uint32_t jid = 0; + + jid = ((g_jedec_id2 & 0xff) << 16) + (g_jedec_id2 & 0xff00) + ((g_jedec_id2 & 0xff0000) >> 16); + return jid; +} + +uint32_t flash_get_size(SF_Ctrl_Bank_Select bank) +{ + if (bank == SF_CTRL_FLASH_BANK1) { + return flash2_size; + } + return flash1_size; +} + +static void flash_get_clock_delay(SPI_Flash_Cfg_Type *cfg) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + /* bit0-3 for clk delay */ + if (BL_IS_REG_BIT_SET(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN)) { + cfg->clkDelay = BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N) + 1; + } else { + cfg->clkDelay = 0; + } + cfg->clkInvert = 0; + /* bit0 for clk invert */ + cfg->clkInvert |= ((BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_OUT_INV_SEL) & 1) << 0); + /* bit1 for rx clk invert */ + cfg->clkInvert |= ((BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_SF_RX_INV_SEL) & 1) << 1); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_1); + /* bit4-6 for do delay */ + cfg->clkDelay |= ((BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_0_DO_DLY_SEL) & 7) << 4); + /* bit2-4 for di delay */ + cfg->clkInvert |= ((BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_0_DI_DLY_SEL) & 7) << 2); + /* bit5-7 for oe delay */ + cfg->clkInvert |= ((BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_0_OE_DLY_SEL) & 7) << 5); +} + +static void ATTR_TCM_SECTION flash_set_qspi_enable(SPI_Flash_Cfg_Type *p_flash_cfg) +{ + if ((p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + SFlash_Qspi_Enable(p_flash_cfg); + } +} + +static void ATTR_TCM_SECTION flash_set_l1c_wrap(SPI_Flash_Cfg_Type *p_flash_cfg) +{ + if (((p_flash_cfg->ioMode >> 4) & 0x01) == 1) { + L1C_Set_Wrap(DISABLE); + } else { + L1C_Set_Wrap(ENABLE); + if ((p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + SFlash_SetBurstWrap(p_flash_cfg); + } + } +} + +/** + * @brief flash_config_init + * + * @return int + */ +static int ATTR_TCM_SECTION flash_config_init(SPI_Flash_Cfg_Type *p_flash_cfg, uint8_t *jedec_id) +{ + int ret = -1; + uint8_t isAesEnable = 0; + uint32_t jid = 0; + uint32_t offset = 0; + uintptr_t flag; + + flag = bflb_irq_save(); + XIP_SFlash_Opt_Enter(&isAesEnable); + XIP_SFlash_State_Save(p_flash_cfg, &offset, 0, 0); + SFlash_GetJedecId(p_flash_cfg, (uint8_t *)&jid); + arch_memcpy(jedec_id, (uint8_t *)&jid, 3); + jid &= 0xFFFFFF; + g_jedec_id = jid; + ret = SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(jid, p_flash_cfg); + if (ret == 0) { + p_flash_cfg->mid = (jid & 0xff); + } + + // p_flash_cfg->ioMode = 0x11; + // p_flash_cfg->cReadSupport = 0x00; + + /* Set flash controler from p_flash_cfg */ + flash_set_qspi_enable(p_flash_cfg); + flash_set_l1c_wrap(p_flash_cfg); + XIP_SFlash_State_Restore(p_flash_cfg, offset, 0, 0); + XIP_SFlash_Opt_Exit(isAesEnable); + bflb_irq_restore(flag); + + return ret; +} + +/** + * @brief flash2 init + * + * @return int + */ +static int ATTR_TCM_SECTION flash2_init(void) +{ + int stat = -1; + uint32_t ret = 0; + uint32_t jid = 0; + Efuse_Device_Info_Type deviceInfo; + SF_Ctrl_Bank2_Cfg sfBank2Cfg = { + .sbus2Select = ENABLE, + .bank2RxClkInvertSrc = DISABLE, + .bank2RxClkInvertSel = DISABLE, + .bank2DelaySrc = DISABLE, + .bank2ClkDelay = 1, + .doDelay = 0, + .diDelay = 0, + .oeDelay = 0, + .remap = SF_CTRL_REMAP_4MB, + .remapLock = 1, + }; + SF_Ctrl_Cmds_Cfg cmdsCfg = { + .ackLatency = 1, + .cmdsCoreEn = 1, + .cmdsEn = 1, + .cmdsWrapMode = 1, + .cmdsWrapLen = SF_CTRL_WRAP_LEN_4096, + }; + + EF_Ctrl_Read_Device_Info(&deviceInfo); + if (deviceInfo.memoryInfo == 0) { + /* memoryInfo==0, external flash */ + flash1_size = 64 * 1024 * 1024; + flash2_size = 0; + } else if (deviceInfo.memoryInfo == 1) { + flash1_size = 2 * 1024 * 1024; + flash2_size = 0; + } else if (deviceInfo.memoryInfo == 2) { + flash1_size = 4 * 1024 * 1024; + flash2_size = 0; + } else if (deviceInfo.memoryInfo == 3) { + /* memoryInfo==3, embedded 4MB+2MB flash */ + flash1_size = 4 * 1024 * 1024; + flash2_size = 2 * 1024 * 1024; + } else { + flash1_size = 8 * 1024 * 1024; + flash2_size = 0; + } + + if (flash2_size > 0) { + SF_Cfg_Sbus2_Flash_Init(SF_IO_EMB_SWAP_IO3IO0_AND_SF2, &sfBank2Cfg); + SF_Ctrl_Sbus2_Replace(SF_CTRL_PAD2); + ret = SF_Cfg_Flash_Identify_Ext(0, SF_IO_EMB_SWAP_IO3IO0_AND_SF2, 0, &g_flash2_cfg, 0, SF_CTRL_FLASH_BANK1); + if ((ret & BFLB_FLASH_ID_VALID_FLAG) == 0) { + return -1; + } + g_flash2_cfg.ioMode = 0x11; + g_flash2_cfg.cReadSupport = 0; + g_flash2_cfg.cReadMode = 0xff; + SFlash_GetJedecId(&g_flash2_cfg, (uint8_t *)&jid); + jid &= 0xFFFFFF; + g_jedec_id2 = jid; + + SF_Ctrl_Cmds_Set(&cmdsCfg, SF_CTRL_FLASH_BANK1); + stat = SFlash_IDbus_Read_Enable(&g_flash2_cfg, (g_flash2_cfg.ioMode & 0xf), 0, SF_CTRL_FLASH_BANK1); + if (0 != stat) { + return -1; + } + SF_Ctrl_Sbus2_Revoke_replace(); + } + + return 0; +} + +/** + * @brief multi flash adapter + * + * @return int + */ +int ATTR_TCM_SECTION bflb_flash_init(void) +{ + int ret = -1; + uint32_t jedec_id = 0; + uintptr_t flag; + + jedec_id = GLB_Get_Flash_Id_Value(); + if (jedec_id != 0) { + ret = SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(jedec_id, &g_flash_cfg); + if (ret == 0) { + g_jedec_id = jedec_id; + g_flash_cfg.ioMode &= 0x0f; + flash_get_clock_delay(&g_flash_cfg); + flash2_init(); + return 0; + } + } + + flag = bflb_irq_save(); + L1C_ICache_Invalid_All(); + SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(0, &g_flash_cfg); + L1C_ICache_Invalid_All(); + bflb_irq_restore(flag); + if (g_flash_cfg.mid != 0xff) { + g_flash_cfg.ioMode &= 0x0f; + flash_get_clock_delay(&g_flash_cfg); + flash2_init(); + return 0; + } + g_flash_cfg.ioMode &= 0x0f; + + ret = flash_config_init(&g_flash_cfg, (uint8_t *)&jedec_id); + + g_flash_cfg.ioMode &= 0x0f; + flash_get_clock_delay(&g_flash_cfg); + GLB_Set_Flash_Id_Value(g_jedec_id); + + flash2_init(); + + return ret; +} + +uint32_t bflb_flash_get_jedec_id(void) +{ + uint32_t jid = 0; + + jid = ((g_jedec_id & 0xff) << 16) + (g_jedec_id & 0xff00) + ((g_jedec_id & 0xff0000) >> 16); + return jid; +} + +void bflb_flash_get_cfg(uint8_t **cfg_addr, uint32_t *len) +{ + *cfg_addr = (uint8_t *)&g_flash_cfg; + *len = sizeof(SPI_Flash_Cfg_Type); +} + +void bflb_flash_set_iomode(uint8_t iomode) +{ + g_flash_cfg.ioMode &= ~0x1f; + if (iomode == 4) { + g_flash_cfg.ioMode |= iomode; + } else { + g_flash_cfg.ioMode |= 0x10; + g_flash_cfg.ioMode |= iomode; + } +} + +/** + * @brief erase flash via sbus + * + * @param flash absolute startaddr + * @param flash absolute endaddr + * @return int + */ +int ATTR_TCM_SECTION bflb_flash_erase(uint32_t startaddr, uint32_t len) +{ + int stat = -1; + uintptr_t flag; + + if ((startaddr + len) > (flash1_size + flash2_size)) { + return -ENOMEM; + } else if ((startaddr + len) <= flash1_size) { + flag = bflb_irq_save(); + stat = XIP_SFlash_Erase_Need_Lock(&g_flash_cfg, startaddr, len, 0, 0); + bflb_irq_restore(flag); + } else if (startaddr >= flash1_size) { + SF_Ctrl_Sbus2_Replace(SF_CTRL_PAD2); + stat = SFlash_Erase(&g_flash2_cfg, startaddr, startaddr + len - 1); + SF_Ctrl_Sbus2_Revoke_replace(); + } else { + flag = bflb_irq_save(); + stat = XIP_SFlash_Erase_Need_Lock(&g_flash_cfg, startaddr, flash1_size - startaddr, 0, 0); + bflb_irq_restore(flag); + if (stat != 0) { + return stat; + } + SF_Ctrl_Sbus2_Replace(SF_CTRL_PAD2); + stat = SFlash_Erase(&g_flash2_cfg, flash1_size, startaddr + len - flash1_size - 1); + SF_Ctrl_Sbus2_Revoke_replace(); + } + + return stat; +} + +/** + * @brief write flash data via sbus + * + * @param flash absolute addr + * @param data + * @param len + * @return int + */ +int ATTR_TCM_SECTION bflb_flash_write(uint32_t addr, uint8_t *data, uint32_t len) +{ + int stat = -1; + uintptr_t flag; + + if ((addr + len) > (flash1_size + flash2_size)) { + return -ENOMEM; + } else if ((addr + len) <= flash1_size) { + flag = bflb_irq_save(); + stat = XIP_SFlash_Write_Need_Lock(&g_flash_cfg, addr, data, len, 0, 0); + bflb_irq_restore(flag); + } else if (addr >= flash1_size) { + SF_Ctrl_Sbus2_Replace(SF_CTRL_PAD2); + stat = SFlash_Program(&g_flash2_cfg, SF_CTRL_DO_MODE, addr, data, len); + SF_Ctrl_Sbus2_Revoke_replace(); + } else { + flag = bflb_irq_save(); + stat = XIP_SFlash_Write_Need_Lock(&g_flash_cfg, addr, data, flash1_size - addr, 0, 0); + bflb_irq_restore(flag); + if (stat != 0) { + return stat; + } + SF_Ctrl_Sbus2_Replace(SF_CTRL_PAD2); + stat = SFlash_Program(&g_flash2_cfg, SF_CTRL_DO_MODE, flash1_size, data + (flash1_size - addr), addr + len - flash1_size); + SF_Ctrl_Sbus2_Revoke_replace(); + } + + return stat; +} + +/** + * @brief read flash data via sbus + * + * @param flash absolute addr + * @param data + * @param len + * @return int + */ +int ATTR_TCM_SECTION bflb_flash_read(uint32_t addr, uint8_t *data, uint32_t len) +{ + int stat = -1; + uintptr_t flag; + + if ((addr + len) > (flash1_size + flash2_size)) { + return -ENOMEM; + } else if ((addr + len) <= flash1_size) { + flag = bflb_irq_save(); + stat = XIP_SFlash_Read_Need_Lock(&g_flash_cfg, addr, data, len, 0, 0); + bflb_irq_restore(flag); + } else if (addr >= flash1_size) { + SF_Ctrl_Sbus2_Replace(SF_CTRL_PAD2); + stat = SFlash_Read(&g_flash2_cfg, SF_CTRL_DO_MODE, 0, addr, data, len); + SF_Ctrl_Sbus2_Revoke_replace(); + } else { + flag = bflb_irq_save(); + stat = XIP_SFlash_Read_Need_Lock(&g_flash_cfg, addr, data, flash1_size - addr, 0, 0); + bflb_irq_restore(flag); + if (stat != 0) { + return stat; + } + SF_Ctrl_Sbus2_Replace(SF_CTRL_PAD2); + stat = SFlash_Read(&g_flash2_cfg, SF_CTRL_DO_MODE, 0, flash1_size, data + (flash1_size - addr), addr + len - flash1_size); + SF_Ctrl_Sbus2_Revoke_replace(); + } + + return stat; +} + +void bflb_flash_aes_init(struct bflb_flash_aes_config_s *config) +{ + uint8_t hw_key_enable = 0; + + if (config->key == NULL) { + hw_key_enable = 1; + } + + SF_Ctrl_AES_Set_Key_BE(config->region, (uint8_t *)config->key, config->keybits); + SF_Ctrl_AES_Set_IV_BE(config->region, (uint8_t *)config->iv, config->start_addr); + SF_Ctrl_AES_Set_Region(config->region, config->region_enable, hw_key_enable, config->start_addr, config->end_addr - 1, config->lock_enable); +} + +void bflb_flash_aes_enable(void) +{ + SF_Ctrl_AES_Enable(); +} + +void bflb_flash_aes_disable(void) +{ + SF_Ctrl_AES_Disable(); +} \ No newline at end of file diff --git a/drivers/soc/bl616/startup/vector.S b/drivers/soc/bl616/startup/vector.S index 36001c2f..8b605245 100644 --- a/drivers/soc/bl616/startup/vector.S +++ b/drivers/soc/bl616/startup/vector.S @@ -101,6 +101,7 @@ default_interrupt_handler: * ~mem addr low: */ /* WARNING: global IRQ enabled by ipush */ + csrs mstatus, 8 /* keep stack 16bytes aligned */ addi sp, sp, -88 diff --git a/drivers/soc/bl702/CMakeLists.txt b/drivers/soc/bl702/CMakeLists.txt index 9af66e39..ac45375b 100644 --- a/drivers/soc/bl702/CMakeLists.txt +++ b/drivers/soc/bl702/CMakeLists.txt @@ -5,15 +5,31 @@ sdk_library_add_sources(startup/start_load.c) sdk_library_add_sources(startup/system_bl702.c) sdk_library_add_sources(startup/interrupt.c) +if(CONFIG_ROMAPI) +sdk_library_add_sources(bl702_std/src/bl702_romapi.c) +sdk_add_compile_definitions(-DBFLB_USE_ROM_DRIVER) +endif() + +sdk_library_add_sources(bl702_std/src/bl702_aon.c) +sdk_library_add_sources(bl702_std/src/bl702_common.c) sdk_library_add_sources(bl702_std/src/bl702_clock.c) +sdk_library_add_sources(bl702_std/src/bl702_ef_ctrl.c) sdk_library_add_sources(bl702_std/src/bl702_glb.c) sdk_library_add_sources(bl702_std/src/bl702_hbn.c) -sdk_library_add_sources(bl702_std/src/bl702_romapi.c) -# sdk_library_add_sources(bl702_std/src/bl702_pds.c) -# sdk_library_add_sources(bl702_std/src/bl702_common.c) -# sdk_library_add_sources(bl702_std/src/bl702_l1c.c) -# sdk_library_add_sources(bl702_std/src/bl702_aon.c) +sdk_library_add_sources(bl702_std/src/bl702_l1c.c) +sdk_library_add_sources(bl702_std/src/bl702_pds.c) + +sdk_library_add_sources(bl702_std/src/bl702_sf_cfg.c) +sdk_library_add_sources(bl702_std/src/bl702_sf_cfg_ext.c) +sdk_library_add_sources(bl702_std/src/bl702_sf_ctrl.c) +sdk_library_add_sources(bl702_std/src/bl702_sflash.c) +sdk_library_add_sources(bl702_std/src/bl702_sflash_ext.c) +sdk_library_add_sources(bl702_std/src/bl702_xip_sflash.c) +sdk_library_add_sources(bl702_std/src/bl702_xip_sflash_ext.c) + sdk_library_add_sources(port/bl702_clock.c) +sdk_library_add_sources(port/bl702_flash.c) +sdk_library_add_sources(port/bl702_efuse.c) sdk_add_include_directories( bl702_std/include @@ -24,7 +40,7 @@ SET(MCPU "riscv-e24") SET(MARCH "rv32imafc") SET(MABI "ilp32f") -sdk_add_compile_definitions(-DARCH_RISCV) +sdk_add_compile_definitions(-DARCH_RISCV -DBFLB_USE_HAL_DRIVER) sdk_add_compile_options(-march=${MARCH} -mabi=${MABI}) sdk_add_link_options(-march=${MARCH} -mabi=${MABI}) diff --git a/drivers/soc/bl702/bl702_std/include/bl702_common.h b/drivers/soc/bl702/bl702_std/include/bl702_common.h index 29d40ecf..0ad4b6e1 100644 --- a/drivers/soc/bl702/bl702_std/include/bl702_common.h +++ b/drivers/soc/bl702/bl702_std/include/bl702_common.h @@ -205,6 +205,11 @@ __ALWAYS_STATIC_INLINE void __disable_irq(void) #define arch_delay_us BL702_Delay_US #define arch_delay_ms BL702_Delay_MS +#define BFLB_Soft_CRC32 bflb_soft_crc32 +#define CPU_Interrupt_Enable(irq) +#define CPU_Interrupt_Disable(irq) +#define Interrupt_Handler_Register(irq, callback) + void BL702_Delay_US(uint32_t cnt); void BL702_Delay_MS(uint32_t cnt); #endif diff --git a/drivers/soc/bl702/bl702_std/include/bl702_l1c.h b/drivers/soc/bl702/bl702_std/include/bl702_l1c.h index a4faaa26..42220930 100644 --- a/drivers/soc/bl702/bl702_std/include/bl702_l1c.h +++ b/drivers/soc/bl702/bl702_std/include/bl702_l1c.h @@ -172,8 +172,7 @@ void L1C_BMX_TO_IRQHandler(void); /*----------*/ BL_Err_Type L1C_Cache_Enable_Set(uint8_t wayDisable); void L1C_Cache_Write_Set(BL_Fun_Type wtEn, BL_Fun_Type wbEn, BL_Fun_Type waEn); -BL_Err_Type L1C_Cache_Flush(uint8_t wayDisable); -BL_Err_Type L1C_Cache_Flush_Ext(void); +BL_Err_Type L1C_Cache_Flush(void); void L1C_Cache_Hit_Count_Get(uint32_t *hitCountLow, uint32_t *hitCountHigh); uint32_t L1C_Cache_Miss_Count_Get(void); void L1C_Cache_Read_Disable(void); diff --git a/drivers/soc/bl702/bl702_std/src/bl702_l1c.c b/drivers/soc/bl702/bl702_std/src/bl702_l1c.c index e3597a24..f298f972 100644 --- a/drivers/soc/bl702/bl702_std/src/bl702_l1c.c +++ b/drivers/soc/bl702/bl702_std/src/bl702_l1c.c @@ -98,64 +98,6 @@ static intCallback_Type *l1cBmxToIntCbfArra[L1C_BMX_TO_INT_ALL] = { NULL }; #ifndef BFLB_USE_ROM_DRIVER __WEAK BL_Err_Type ATTR_TCM_SECTION L1C_Cache_Enable_Set(uint8_t wayDisable) -{ - L1C_Cache_Flush(wayDisable); - - return SUCCESS; -} -#endif - -/****************************************************************************/ /** - * @brief L1C cache write set - * - * @param wtEn: L1C write through enable - * @param wbEn: L1C write back enable - * @param waEn: L1C write allocate enable - * - * @return None - * -*******************************************************************************/ -#ifndef BFLB_USE_ROM_DRIVER -__WEAK -void ATTR_TCM_SECTION L1C_Cache_Write_Set(BL_Fun_Type wtEn, BL_Fun_Type wbEn, BL_Fun_Type waEn) -{ - uint32_t tmpVal; - - tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); - - if (wtEn) { - tmpVal = BL_SET_REG_BIT(tmpVal, L1C_WT_EN); - } else { - tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_WT_EN); - } - - if (wbEn) { - tmpVal = BL_SET_REG_BIT(tmpVal, L1C_WB_EN); - } else { - tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_WB_EN); - } - - if (waEn) { - tmpVal = BL_SET_REG_BIT(tmpVal, L1C_WA_EN); - } else { - tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_WA_EN); - } - - BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); -} -#endif - -/****************************************************************************/ /** - * @brief Flush cache - * - * @param wayDisable: cache way disable config - * - * @return SUCCESS or ERROR - * -*******************************************************************************/ -#ifndef BFLB_USE_ROM_DRIVER -__WEAK -BL_Err_Type ATTR_TCM_SECTION L1C_Cache_Flush(uint8_t wayDisable) { uint32_t tmpVal; uint32_t cnt = 0; @@ -248,6 +190,46 @@ BL_Err_Type ATTR_TCM_SECTION L1C_Cache_Flush(uint8_t wayDisable) } #endif +/****************************************************************************/ /** + * @brief L1C cache write set + * + * @param wtEn: L1C write through enable + * @param wbEn: L1C write back enable + * @param waEn: L1C write allocate enable + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION L1C_Cache_Write_Set(BL_Fun_Type wtEn, BL_Fun_Type wbEn, BL_Fun_Type waEn) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); + + if (wtEn) { + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_WT_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_WT_EN); + } + + if (wbEn) { + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_WB_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_WB_EN); + } + + if (waEn) { + tmpVal = BL_SET_REG_BIT(tmpVal, L1C_WA_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, L1C_WA_EN); + } + + BL_WR_REG(L1C_BASE, L1C_CONFIG, tmpVal); +} +#endif + /****************************************************************************/ /** * @brief Flush cache external api * @@ -256,13 +238,13 @@ BL_Err_Type ATTR_TCM_SECTION L1C_Cache_Flush(uint8_t wayDisable) * @return SUCCESS or ERROR * *******************************************************************************/ -BL_Err_Type ATTR_TCM_SECTION L1C_Cache_Flush_Ext(void) +BL_Err_Type ATTR_TCM_SECTION L1C_Cache_Flush(void) { uint32_t tmpVal; /* Disable early respone */ tmpVal = BL_RD_REG(L1C_BASE, L1C_CONFIG); - L1C_Cache_Flush((tmpVal >> L1C_WAY_DIS_POS) & 0xf); + L1C_Cache_Enable_Set((tmpVal >> L1C_WAY_DIS_POS) & 0xf); __NOP(); __NOP(); __NOP(); diff --git a/drivers/soc/bl702/bl702_std/src/bl702_romapi.c b/drivers/soc/bl702/bl702_std/src/bl702_romapi.c index b633ccfc..d16341f9 100644 --- a/drivers/soc/bl702/bl702_std/src/bl702_romapi.c +++ b/drivers/soc/bl702/bl702_std/src/bl702_romapi.c @@ -53,44 +53,44 @@ __ALWAYS_INLINE ATTR_TCM_SECTION void BL702_Delay_MS(uint32_t cnt) RomDriver_BL702_Delay_MS(cnt); } -__ALWAYS_INLINE ATTR_TCM_SECTION void *BL702_MemCpy(void *dst, const void *src, uint32_t n) -{ - return RomDriver_BL702_MemCpy(dst, src, n); -} +// __ALWAYS_INLINE ATTR_TCM_SECTION void *BL702_MemCpy(void *dst, const void *src, uint32_t n) +// { +// return RomDriver_BL702_MemCpy(dst, src, n); +// } -__ALWAYS_INLINE ATTR_TCM_SECTION - uint32_t * - BL702_MemCpy4(uint32_t *dst, const uint32_t *src, uint32_t n) -{ - return RomDriver_BL702_MemCpy4(dst, src, n); -} +// __ALWAYS_INLINE ATTR_TCM_SECTION +// uint32_t * +// BL702_MemCpy4(uint32_t *dst, const uint32_t *src, uint32_t n) +// { +// return RomDriver_BL702_MemCpy4(dst, src, n); +// } // __ALWAYS_INLINE ATTR_TCM_SECTION // void* BL702_MemCpy_Fast(void *pdst, const void *psrc, uint32_t n) { // return RomDriver_BL702_MemCpy_Fast(pdst, psrc, n); // } -__ALWAYS_INLINE ATTR_TCM_SECTION void *ARCH_MemCpy_Fast(void *pdst, const void *psrc, uint32_t n) -{ - return RomDriver_ARCH_MemCpy_Fast(pdst, psrc, n); -} +// __ALWAYS_INLINE ATTR_TCM_SECTION void *ARCH_MemCpy_Fast(void *pdst, const void *psrc, uint32_t n) +// { +// return RomDriver_ARCH_MemCpy_Fast(pdst, psrc, n); +// } -__ALWAYS_INLINE ATTR_TCM_SECTION void *BL702_MemSet(void *s, uint8_t c, uint32_t n) -{ - return RomDriver_BL702_MemSet(s, c, n); -} +// __ALWAYS_INLINE ATTR_TCM_SECTION void *BL702_MemSet(void *s, uint8_t c, uint32_t n) +// { +// return RomDriver_BL702_MemSet(s, c, n); +// } -__ALWAYS_INLINE ATTR_TCM_SECTION - uint32_t * - BL702_MemSet4(uint32_t *dst, const uint32_t val, uint32_t n) -{ - return RomDriver_BL702_MemSet4(dst, val, n); -} +// __ALWAYS_INLINE ATTR_TCM_SECTION +// uint32_t * +// BL702_MemSet4(uint32_t *dst, const uint32_t val, uint32_t n) +// { +// return RomDriver_BL702_MemSet4(dst, val, n); +// } -__ALWAYS_INLINE ATTR_TCM_SECTION int BL702_MemCmp(const void *s1, const void *s2, uint32_t n) -{ - return RomDriver_BL702_MemCmp(s1, s2, n); -} +// __ALWAYS_INLINE ATTR_TCM_SECTION int BL702_MemCmp(const void *s1, const void *s2, uint32_t n) +// { +// return RomDriver_BL702_MemCmp(s1, s2, n); +// } __ALWAYS_INLINE ATTR_TCM_SECTION uint32_t @@ -780,12 +780,14 @@ __ALWAYS_INLINE ATTR_TCM_SECTION void L1C_Cache_Write_Set(BL_Fun_Type wtEn, BL_F RomDriver_L1C_Cache_Write_Set(wtEn, wbEn, waEn); } +#if 0 __ALWAYS_INLINE ATTR_TCM_SECTION BL_Err_Type L1C_Cache_Flush(uint8_t wayDisable) { return RomDriver_L1C_Cache_Flush(wayDisable); } +#endif __ALWAYS_INLINE ATTR_TCM_SECTION void L1C_Cache_Hit_Count_Get(uint32_t *hitCountLow, uint32_t *hitCountHigh) { diff --git a/drivers/soc/bl702/bl702_std/src/bl702_sf_cfg.c b/drivers/soc/bl702/bl702_std/src/bl702_sf_cfg.c index 8feff651..a333638e 100644 --- a/drivers/soc/bl702/bl702_std/src/bl702_sf_cfg.c +++ b/drivers/soc/bl702/bl702_std/src/bl702_sf_cfg.c @@ -36,8 +36,8 @@ #include "bl702_glb.h" #include "bl702_sf_cfg.h" -#include "softcrc.h" #include "bl702_xip_sflash.h" +#include "soft_crc.h" /** @addtogroup BL702_Peripheral_Driver * @{ diff --git a/drivers/soc/bl702/bl702_std/src/bl702_sf_cfg_ext.c b/drivers/soc/bl702/bl702_std/src/bl702_sf_cfg_ext.c index d90928c8..01ae803f 100644 --- a/drivers/soc/bl702/bl702_std/src/bl702_sf_cfg_ext.c +++ b/drivers/soc/bl702/bl702_std/src/bl702_sf_cfg_ext.c @@ -39,6 +39,7 @@ #include "bl702_sf_cfg_ext.h" #include "bl702_xip_sflash.h" #include "bl702_romdriver.h" +#include "soft_crc.h" /** @addtogroup BL702_Peripheral_Driver * @{ diff --git a/drivers/soc/bl702/bl702_std/src/bl702_xip_sflash_ext.c b/drivers/soc/bl702/bl702_std/src/bl702_xip_sflash_ext.c index 9e399fb4..241e0e40 100644 --- a/drivers/soc/bl702/bl702_std/src/bl702_xip_sflash_ext.c +++ b/drivers/soc/bl702/bl702_std/src/bl702_xip_sflash_ext.c @@ -34,7 +34,6 @@ ****************************************************************************** */ -#include "string.h" #include "bl702_xip_sflash_ext.h" /** @addtogroup BL702_Peripheral_Driver diff --git a/drivers/soc/bl702/port/bl702_efuse.c b/drivers/soc/bl702/port/bl702_efuse.c new file mode 100644 index 00000000..bc3366ab --- /dev/null +++ b/drivers/soc/bl702/port/bl702_efuse.c @@ -0,0 +1,53 @@ +#include "bflb_efuse.h" +#include "bl702_ef_ctrl.h" + +float bflb_efuse_get_adc_trim(void) +{ + Efuse_ADC_Gain_Coeff_Type trim; + uint32_t tmp; + + float coe = 1.0; + + EF_Ctrl_Read_ADC_Gain_Trim(&trim); + + if (trim.adcGainCoeffEn) { + if (trim.adcGainCoeffParity == EF_Ctrl_Get_Trim_Parity(trim.adcGainCoeff, 12)) { + tmp = trim.adcGainCoeff; + + if (tmp & 0x800) { + tmp = ~tmp; + tmp += 1; + tmp = tmp & 0xfff; + coe = (1.0 + ((float)tmp / 2048.0)); + } else { + coe = (1.0 - ((float)tmp / 2048.0)); + } + } + } + + return coe; +} + +uint32_t bflb_efuse_get_adc_tsen_trim(void) +{ + Efuse_TSEN_Refcode_Corner_Type trim; + + EF_Ctrl_Read_TSEN_Trim(&trim); + if (trim.tsenRefcodeCornerEn) { + if (trim.tsenRefcodeCornerParity == EF_Ctrl_Get_Trim_Parity(trim.tsenRefcodeCorner, 12)) { + return trim.tsenRefcodeCorner; + } + } + + return 2042; +} + +void bflb_efuse_write_aes_key(uint8_t index, uint8_t *data, uint32_t len) +{ + EF_Ctrl_Write_AES_Key(index, (uint32_t *)data, len, 1); +} + +void bflb_efuse_read_aes_key(uint8_t index, uint8_t *data, uint32_t len) +{ + EF_Ctrl_Read_AES_Key(index, (uint32_t *)data, len); +} \ No newline at end of file diff --git a/drivers/soc/bl702/port/bl702_flash.c b/drivers/soc/bl702/port/bl702_flash.c new file mode 100644 index 00000000..ebec1091 --- /dev/null +++ b/drivers/soc/bl702/port/bl702_flash.c @@ -0,0 +1,198 @@ +#include "bl702_glb.h" +#include "bl702_xip_sflash.h" +#include "bl702_xip_sflash_ext.h" +#include "bl702_sf_cfg.h" +#include "bl702_sf_cfg_ext.h" +#include "bl702_ef_ctrl.h" +#include "bflb_flash.h" + +static uint32_t g_jedec_id = 0; +static SPI_Flash_Cfg_Type g_flash_cfg; + +static void ATTR_TCM_SECTION flash_set_qspi_enable(SPI_Flash_Cfg_Type *p_flash_cfg) +{ + if ((p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + SFlash_Qspi_Enable(p_flash_cfg); + } +} + +static void ATTR_TCM_SECTION flash_set_l1c_wrap(SPI_Flash_Cfg_Type *p_flash_cfg) +{ + if (((p_flash_cfg->ioMode >> 4) & 0x01) == 1) { + L1C_Set_Wrap(DISABLE); + } else { + L1C_Set_Wrap(ENABLE); + if ((p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + SFlash_SetBurstWrap(p_flash_cfg); + } + } +} + +static void ATTR_TCM_SECTION flash_sf2_gpio_init(void) +{ + uint32_t tmpVal; + Efuse_Device_Info_Type devInfo; + + EF_Ctrl_Read_Device_Info(&devInfo); + /* flash_cfg != BFLB_FLASH_CFG_SF1_EXT_17_22, flash pad use SF2 */ + if (devInfo.flash_cfg != BFLB_FLASH_CFG_SF1_EXT_17_22) { + tmpVal = BL_RD_REG(GLB_BASE, GLB_GPIO_USE_PSRAM__IO); + /* GLB_CFG_GPIO_USE_PSRAM_IO == 0, need init SF2 flash gpio */ + if (BL_GET_REG_BITS_VAL(tmpVal, GLB_CFG_GPIO_USE_PSRAM_IO) == 0x00) { + SF_Cfg_Init_Ext_Flash_Gpio(1); + } + } +} + +/** + * @brief flash_config_init + * + * @return int + */ +static int ATTR_TCM_SECTION flash_config_init(SPI_Flash_Cfg_Type *p_flash_cfg, uint8_t *jedec_id) +{ + int ret = -1; + uint32_t jid = 0; + uint32_t offset = 0; + uintptr_t flag; + + flag = bflb_irq_save(); + XIP_SFlash_Opt_Enter(); + XIP_SFlash_State_Save(p_flash_cfg, &offset); + flash_sf2_gpio_init(); + SFlash_GetJedecId(p_flash_cfg, (uint8_t *)&jid); + arch_memcpy(jedec_id, (uint8_t *)&jid, 3); + jid &= 0xFFFFFF; + g_jedec_id = jid; + ret = SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(jid, p_flash_cfg); + if (ret == 0) { + p_flash_cfg->mid = (jid & 0xff); + } + + /* Set flash controler from p_flash_cfg */ + flash_set_qspi_enable(p_flash_cfg); + flash_set_l1c_wrap(p_flash_cfg); + XIP_SFlash_State_Restore(p_flash_cfg, p_flash_cfg->ioMode & 0x0f, offset); + XIP_SFlash_Opt_Exit(); + bflb_irq_restore(flag); + + return ret; +} + +/** + * @brief multi flash adapter + * + * @return int + */ +int ATTR_TCM_SECTION bflb_flash_init(void) +{ + int ret = -1; + uint8_t clkDelay = 1; + uint8_t clkInvert = 1; + uint32_t jedec_id = 0; + uintptr_t flag; + + flag = bflb_irq_save(); + L1C_Cache_Flush(); + SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(0, &g_flash_cfg); + L1C_Cache_Flush(); + bflb_irq_restore(flag); + if (g_flash_cfg.mid != 0xff) { + return 0; + } + clkDelay = g_flash_cfg.clkDelay; + clkInvert = g_flash_cfg.clkInvert; + g_flash_cfg.ioMode = g_flash_cfg.ioMode & 0x0f; + + ret = flash_config_init(&g_flash_cfg, (uint8_t *)&jedec_id); + + g_flash_cfg.clkDelay = clkDelay; + g_flash_cfg.clkInvert = clkInvert; + + return ret; +} + +uint32_t bflb_flash_get_jedec_id(void) +{ + uint32_t jid = 0; + + jid = ((g_jedec_id & 0xff) << 16) + (g_jedec_id & 0xff00) + ((g_jedec_id & 0xff0000) >> 16); + return jid; +} + +void bflb_flash_get_cfg(uint8_t **cfg_addr, uint32_t *len) +{ + *cfg_addr = (uint8_t *)&g_flash_cfg; + *len = sizeof(SPI_Flash_Cfg_Type); +} + +void bflb_flash_set_iomode(uint8_t iomode) +{ + g_flash_cfg.ioMode &= ~0x0f; + g_flash_cfg.ioMode |= iomode; +} + +int ATTR_TCM_SECTION bflb_flash_erase(uint32_t startaddr, uint32_t len) +{ + int ret = -1; + uintptr_t flag; + + flag = bflb_irq_save(); + XIP_SFlash_Opt_Enter(); + ret = XIP_SFlash_Erase_Need_Lock(&g_flash_cfg, g_flash_cfg.ioMode & 0x0f, startaddr, startaddr + len - 1); + XIP_SFlash_Opt_Exit(); + bflb_irq_restore(flag); + + return ret; +} + +int ATTR_TCM_SECTION bflb_flash_write(uint32_t addr, uint8_t *data, uint32_t len) +{ + int ret = -1; + uintptr_t flag; + + flag = bflb_irq_save(); + XIP_SFlash_Opt_Enter(); + ret = XIP_SFlash_Write_Need_Lock(&g_flash_cfg, g_flash_cfg.ioMode & 0x0f, addr, data, len); + XIP_SFlash_Opt_Exit(); + bflb_irq_restore(flag); + + return ret; +} + +int ATTR_TCM_SECTION bflb_flash_read(uint32_t addr, uint8_t *data, uint32_t len) +{ + int ret = -1; + uintptr_t flag; + + flag = bflb_irq_save(); + XIP_SFlash_Opt_Enter(); + ret = XIP_SFlash_Read_Need_Lock(&g_flash_cfg, g_flash_cfg.ioMode & 0x0f, addr, data, len); + XIP_SFlash_Opt_Exit(); + bflb_irq_restore(flag); + + return ret; +} + +void bflb_flash_aes_init(struct bflb_flash_aes_config_s *config) +{ + uint8_t hw_key_enable = 0; + + if (config->key == NULL) { + hw_key_enable = 1; + } + + SF_Ctrl_AES_Set_Key_BE(config->region, (uint8_t *)config->key, config->keybits); + SF_Ctrl_AES_Set_IV_BE(config->region, (uint8_t *)config->iv, config->start_addr); + SF_Ctrl_AES_Set_Region(config->region, config->region_enable, hw_key_enable, config->start_addr, config->end_addr - 1, config->lock_enable); +} + +void bflb_flash_aes_enable(void) +{ + SF_Ctrl_AES_Enable(); +} + +void bflb_flash_aes_disable(void) +{ + SF_Ctrl_AES_Disable(); +} \ No newline at end of file diff --git a/drivers/soc/bl702/startup/interrupt.c b/drivers/soc/bl702/startup/interrupt.c index 505d942c..e60b737e 100644 --- a/drivers/soc/bl702/startup/interrupt.c +++ b/drivers/soc/bl702/startup/interrupt.c @@ -187,5 +187,17 @@ __attribute__((interrupt, aligned(64))) void default_trap_handler(void) __attribute__((interrupt)) __attribute__((weak)) void default_interrupt_handler(void) { + __asm volatile("addi sp,sp,-8"); + __asm volatile("csrr a0,mcause"); + __asm volatile("csrr a1,mepc"); + __asm volatile("sw a0,4(sp)"); + __asm volatile("sw a1,0(sp)"); + __asm volatile("csrsi mstatus,8"); interrupt_entry(); + __asm volatile("csrci mstatus,8"); + __asm volatile("lw a1,0(sp)"); + __asm volatile("lw a0,4(sp)"); + __asm volatile("csrw mepc,a1"); + __asm volatile("csrw mcause,a0"); + __asm volatile("addi sp,sp,8"); } \ No newline at end of file diff --git a/drivers/soc/bl808/CMakeLists.txt b/drivers/soc/bl808/CMakeLists.txt index 9fae19f4..2b963859 100644 --- a/drivers/soc/bl808/CMakeLists.txt +++ b/drivers/soc/bl808/CMakeLists.txt @@ -10,17 +10,26 @@ sdk_library_add_sources(startup/${CPU_ID}/interrupt.c) sdk_library_add_sources(bl808_std/src/bl808_aon.c) sdk_library_add_sources(bl808_std/src/bl808_clock.c) sdk_library_add_sources(bl808_std/src/bl808_common.c) +sdk_library_add_sources(bl808_std/src/bl808_ef_ctrl.c) +sdk_library_add_sources(bl808_std/src/bl808_ef_cfg.c) sdk_library_add_sources(bl808_std/src/bl808_glb.c) sdk_library_add_sources(bl808_std/src/bl808_hbn.c) +sdk_library_add_sources(bl808_std/src/bl808_l1c.c) sdk_library_add_sources(bl808_std/src/bl808_pds.c) sdk_library_add_sources(bl808_std/src/bl808_sdh.c) sdk_library_add_sources(bl808_std/src/bl808_tzc_sec.c) -sdk_library_add_sources(bl808_std/src/bl808_ef_ctrl.c) -sdk_library_add_sources(bl808_std/src/bl808_ef_cfg.c) sdk_library_add_sources(bl808_std/src/bl808_psram_uhs.c) sdk_library_add_sources(bl808_std/src/bl808_uhs_phy.c) + +sdk_library_add_sources(bl808_std/src/bl808_sf_cfg.c) +sdk_library_add_sources(bl808_std/src/bl808_sf_ctrl.c) +sdk_library_add_sources(bl808_std/src/bl808_sflash.c) +sdk_library_add_sources(bl808_std/src/bl808_xip_sflash.c) + sdk_library_add_sources(port/bl808_clock.c) +sdk_library_add_sources(port/bl808_flash.c) +sdk_library_add_sources(port/bl808_efuse.c) sdk_add_include_directories( bl808_std/include @@ -41,7 +50,7 @@ SET(MARCH "rv32emcxtheadse") SET(MABI "ilp32e") endif() -sdk_add_compile_definitions(-DARCH_RISCV) +sdk_add_compile_definitions(-DARCH_RISCV -DBFLB_USE_HAL_DRIVER) sdk_add_compile_options(-march=${MARCH} -mabi=${MABI} -mtune=${MCPU}) sdk_add_link_options(-march=${MARCH} -mabi=${MABI} -mtune=${MCPU}) diff --git a/drivers/soc/bl808/bl808_std/include/bl808_common.h b/drivers/soc/bl808/bl808_std/include/bl808_common.h index 7cfd4c84..85a063f6 100644 --- a/drivers/soc/bl808/bl808_std/include/bl808_common.h +++ b/drivers/soc/bl808/bl808_std/include/bl808_common.h @@ -157,6 +157,16 @@ void check_failed(uint8_t *file, uint32_t line); */ #define IS_BL_MASK_TYPE(type) (((type) == MASK) || ((type) == UNMASK)) +#define ARCH_MemCpy arch_memcpy +#define ARCH_MemSet arch_memset +#define ARCH_MemCmp arch_memcmp +#define ARCH_MemCpy4 arch_memcpy4 +#define ARCH_MemCpy_Fast arch_memcpy_fast +#define ARCH_MemSet4 arch_memset4 +#define BFLB_Soft_CRC32 bflb_soft_crc32 +#define CPU_Interrupt_Enable(irq) +#define CPU_Interrupt_Disable(irq) +#define Interrupt_Handler_Register(irq, callback) /*@} end of group COMMON_Public_Constants */ /** @defgroup DRIVER_Public_FunctionDeclaration diff --git a/drivers/soc/bl808/bl808_std/include/bl808_sdh.h b/drivers/soc/bl808/bl808_std/include/bl808_sdh.h index 5497548d..5eb0fc7e 100644 --- a/drivers/soc/bl808/bl808_std/include/bl808_sdh.h +++ b/drivers/soc/bl808/bl808_std/include/bl808_sdh.h @@ -936,9 +936,8 @@ struct SDH_Handle_Cfg_Tag { /** @defgroup SDH_Public_Functions * @{ */ -#if (defined BOOTROM) || (!defined BFLB_USE_HAL_DRIVER) void SDH_MMC1_IRQHandler(void); -#endif + void SDH_Reset(void); void SDH_Set_Timeout(uint8_t tmo); void SDH_SetSdClock(uint32_t srcClock, uint32_t busClock); diff --git a/drivers/soc/bl808/bl808_std/src/bl808_l1c.c b/drivers/soc/bl808/bl808_std/src/bl808_l1c.c new file mode 100644 index 00000000..9f726047 --- /dev/null +++ b/drivers/soc/bl808/bl808_std/src/bl808_l1c.c @@ -0,0 +1,408 @@ +/** + ****************************************************************************** + * @file bl808_l1c.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl808_l1c.h" +#include "bl808_common.h" +#include "bl808_glb.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup L1C + * @{ + */ + +/** @defgroup L1C_Private_Macros + * @{ + */ + +/*@} end of group L1C_Private_Macros */ + +/** @defgroup L1C_Private_Types + * @{ + */ + +/*@} end of group L1C_Private_Types */ + +/** @defgroup L1C_Private_Variables + * @{ + */ + +/*@} end of group L1C_Private_Variables */ + +/** @defgroup L1C_Global_Variables + * @{ + */ + +/*@} end of group L1C_Global_Variables */ + +/** @defgroup L1C_Private_Fun_Declaration + * @{ + */ + +/*@} end of group L1C_Private_Fun_Declaration */ + +/** @defgroup L1C_Private_Functions + * @{ + */ + +/*@} end of group L1C_Private_Functions */ + +/** @defgroup L1C_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Enable I-Cache + * + * @param wayDsiable: cache way disable config + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_ICache_Enable(uint8_t wayDsiable) +{ +#ifndef __riscv_32e + csi_icache_enable(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Enable D-Cache + * + * @param wayDsiable: cache way disable config + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Enable(uint8_t wayDsiable) +{ +#ifndef __riscv_32e + csi_dcache_enable(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Disable I-Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_ICache_Disable(void) +{ +#ifndef __riscv_32e + csi_icache_disable(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Disable D-Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Disable(void) +{ +#ifndef __riscv_32e + csi_dcache_disable(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief L1C D-Cache write set + * + * @param wtEn: L1C write through enable + * @param wbEn: L1C write back enable + * @param waEn: L1C write allocate enable + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION L1C_DCache_Write_Set(BL_Fun_Type wtEn, BL_Fun_Type wbEn, BL_Fun_Type waEn) +{ + return; +} + +/****************************************************************************/ /** + * @brief Clean all D_Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Clean_All(void) +{ +#ifndef __riscv_32e + csi_dcache_clean(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Clean and invalid all D_Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Clean_Invalid_All(void) +{ +#ifndef __riscv_32e + csi_dcache_clean_invalid(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Invalid all I-Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_ICache_Invalid_All(void) +{ +#ifndef __riscv_32e + csi_icache_invalid(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Invalid all D_Cache + * + * @param None + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Invalid_All(void) +{ +#ifndef __riscv_32e + csi_dcache_invalid(); +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Clean D-Cache according to address + * + * @param addr: Address to clean + * @param len: Length to clean + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Clean_By_Addr(uintptr_t addr, uint32_t len) +{ +#ifndef __riscv_32e +#ifdef CPU_D0 + csi_dcache_clean_range((uintptr_t *)addr, len); +#else + csi_dcache_clean_range((uint32_t *)(uintptr_t *)addr, len); +#endif +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Clean and invalid D-Cache according to address + * + * @param addr: Address to clean + * @param len: Length to clean + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Clean_Invalid_By_Addr(uintptr_t addr, uint32_t len) +{ +#ifndef __riscv_32e +#ifdef CPU_D0 + csi_dcache_clean_invalid_range((uintptr_t *)addr, len); +#else + csi_dcache_clean_invalid_range((uint32_t *)(uintptr_t *)addr, len); +#endif +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Invalid I-Cache according to address + * + * @param addr: Address to clean + * @param len: Length to clean + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_ICache_Invalid_By_Addr(uintptr_t addr, uint32_t len) +{ + L1C_ICache_Invalid_All(); + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Invalid D-Cache according to address + * + * @param addr: Address to clean + * @param len: Length to clean + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +__WEAK +BL_Err_Type ATTR_TCM_SECTION L1C_DCache_Invalid_By_Addr(uintptr_t addr, uint32_t len) +{ +#ifndef __riscv_32e +#ifdef CPU_D0 + csi_dcache_invalid_range((uintptr_t *)addr, len); +#else + csi_dcache_invalid_range((uint32_t *)(uintptr_t *)addr, len); +#endif +#endif + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief cache wrap + * + * @param en: wrap enable or disable + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION L1C_Set_Wrap(uint8_t en) +{ + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief cache wrap + * + * @param core: cpu core + * @param cacheSetting: cache setting + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION L1C_Set_Cache_Setting_By_ID(uint8_t core, L1C_CACHE_Cfg_Type *cacheSetting) +{ + (void)core; + (void)cacheSetting; + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Judge addr is in cache range + * + * @param addr: phyical addr + * + * @return 1 for addr is in cache range and 0 for not in cache range + * +*******************************************************************************/ +int ATTR_TCM_SECTION L1C_Is_DCache_Range(uintptr_t addr) +{ + GLB_CORE_ID_Type core = GLB_CORE_ID_INVALID; + + /* Get core type */ + core = GLB_Get_Core_Type(); + if(core==GLB_CORE_ID_D0){ + if(((addr>>16)&0xffff)>=0x3ef8){ + return 1; + }else{ + return 0; + } + }else{ + if(((addr>>16)&0xffff)>=0x4000){ + return 1; + }else{ + return 0; + } + } +} + +/****************************************************************************/ /** + * @brief Get None Cache address according to Cache address + * + * @param addr: cache addr + * + * @return none cache addr + * +*******************************************************************************/ +int ATTR_TCM_SECTION L1C_Get_None_Cache_Addr(uintptr_t addr) +{ + GLB_CORE_ID_Type core = GLB_CORE_ID_INVALID; + + /* Get core type */ + core = GLB_Get_Core_Type(); + if(core==GLB_CORE_ID_D0){ + return addr; + }else{ + return (addr&0x0FFFFFFF)|0x20000000; + } +} + +/*@} end of group L1C_Public_Functions */ + +/*@} end of group L1C */ + +/*@} end of group BL808_Peripheral_Driver */ diff --git a/drivers/soc/bl808/bl808_std/src/bl808_sdh.c b/drivers/soc/bl808/bl808_std/src/bl808_sdh.c index 8db34aef..b877bab3 100644 --- a/drivers/soc/bl808/bl808_std/src/bl808_sdh.c +++ b/drivers/soc/bl808/bl808_std/src/bl808_sdh.c @@ -75,9 +75,7 @@ static SDH_Handle_Cfg_Type *sdhHandle = NULL; /** @defgroup SDH_Private_Fun_Declaration * @{ */ -#if (defined BOOTROM) || (!defined BFLB_USE_HAL_DRIVER) static void SDH_IntHandler(IRQn_Type intPeriph, SDH_Handle_Cfg_Type *handle); -#endif /*@} end of group SDH_Private_Fun_Declaration */ @@ -1227,7 +1225,6 @@ void SDH_InstallHandleCallback(SDH_Handle_Cfg_Type *handle, * @return None * *******************************************************************************/ -#if (defined BOOTROM) || (!defined BFLB_USE_HAL_DRIVER) static void SDH_IntHandler(IRQn_Type intPeriph, SDH_Handle_Cfg_Type *handle) { uint32_t intFlag, intMask; @@ -1343,7 +1340,6 @@ static void SDH_IntHandler(IRQn_Type intPeriph, SDH_Handle_Cfg_Type *handle) SDH_ClearIntStatus(intFlag); } -#endif /****************************************************************************/ /** * @brief SDH interrupt handler @@ -1353,12 +1349,10 @@ static void SDH_IntHandler(IRQn_Type intPeriph, SDH_Handle_Cfg_Type *handle) * @return None * *******************************************************************************/ -#if (defined BOOTROM) || (!defined BFLB_USE_HAL_DRIVER) void SDH_MMC1_IRQHandler(void) { SDH_IntHandler(SDH_IRQn, sdhHandle); } -#endif /*@} end of group SDH_Public_Functions */ diff --git a/drivers/soc/bl808/bl808_std/src/bl808_sf_cfg.c b/drivers/soc/bl808/bl808_std/src/bl808_sf_cfg.c new file mode 100644 index 00000000..47d3725e --- /dev/null +++ b/drivers/soc/bl808/bl808_std/src/bl808_sf_cfg.c @@ -0,0 +1,1673 @@ +/** + ****************************************************************************** + * @file bl808_sf_cfg.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl808_sf_cfg.h" +#include "bl808_xip_sflash.h" +#include "soft_crc.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup SF_CFG + * @{ + */ + +/** @defgroup SF_CFG_Private_Macros + * @{ + */ +#define BFLB_FLASH_CFG_MAGIC "FCFG" + +/*@} end of group SF_CFG_Private_Macros */ + +/** @defgroup SF_CFG_Private_Types + * @{ + */ +#ifndef BFLB_USE_ROM_DRIVER +typedef struct +{ + uint32_t jedecID; + char *name; + const SPI_Flash_Cfg_Type *cfg; +} Flash_Info_t; +#endif + +/*@} end of group SF_CFG_Private_Types */ + +/** @defgroup SF_CFG_Private_Variables + * @{ + */ +#ifndef BFLB_USE_ROM_DRIVER +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Winb_80DV = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xef, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 0, + .cReadMode = 0xFF, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3d, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .enter32BitsAddrCmd = 0xb7, + .exit32BitsAddrCmd = 0xe9, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 3, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Winb_16JV = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xef, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x31, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .enter32BitsAddrCmd = 0xb7, + .exit32BitsAddrCmd = 0xe9, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 400, + .timeE32k = 1600, + .timeE64k = 2000, + .timePagePgm = 5, + .timeCe = 33 * 1000, + .pdDelay = 3, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Winb_64JW = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xef, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x31, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 0, + .cReadMode = 0xf0, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .enter32BitsAddrCmd = 0xb7, + .exit32BitsAddrCmd = 0xe9, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 400, + .timeE32k = 1600, + .timeE64k = 2000, + .timePagePgm = 5, + .timeCe = 33 * 1000, + .pdDelay = 3, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Winb_256FV = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xef, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x31, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0x20, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = 0x24, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .enter32BitsAddrCmd = 0xb7, + .exit32BitsAddrCmd = 0xe9, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 400, + .timeE32k = 1600, + .timeE64k = 2000, + .timePagePgm = 5, + .timeCe = 33 * 1000, + .pdDelay = 3, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Gd_Q80E_Q16E = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xc8, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0xa0, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .enter32BitsAddrCmd = 0xb7, + .exit32BitsAddrCmd = 0xe9, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 500, + .timeE32k = 2000, + .timeE64k = 2000, + .timePagePgm = 5, + .timeCe = 33 * 1000, + .pdDelay = 20, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Gd_WQ80E_WQ16E = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xc8, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 32 / 8, + .cReadSupport = 1, + .cReadMode = 0xa0, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .enter32BitsAddrCmd = 0xb7, + .exit32BitsAddrCmd = 0xe9, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 8 / 8, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 20 * 1000, + .pdDelay = 20, + .qeData = 0x12, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Gd_Q32E_Q128E = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xc8, + + .deBurstWrapCmd = 0x77, + .deBurstWrapCmdDmyClk = 0x3, + .deBurstWrapDataMode = SF_CTRL_DATA_4_LINES, + .deBurstWrapData = 0xF0, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 1, + .qeBit = 0x01, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x31, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0xa0, + + .burstWrapCmd = 0x77, + .burstWrapCmdDmyClk = 0x3, + .burstWrapDataMode = SF_CTRL_DATA_4_LINES, + .burstWrapData = 0x40, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x32, + .qppAddrMode = SF_CTRL_ADDR_1_LINE, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .enter32BitsAddrCmd = 0xb7, + .exit32BitsAddrCmd = 0xe9, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 33 * 1000, + .pdDelay = 20, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Mxic_128 = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xC2, + + .deBurstWrapCmd = 0xC0, + .deBurstWrapCmdDmyClk = 0x00, + .deBurstWrapDataMode = SF_CTRL_DATA_1_LINE, + .deBurstWrapData = 0x10, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 0, + .qeBit = 0x06, + .qeWriteRegLen = 0x01, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x35, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0xA5, + + .burstWrapCmd = 0xC0, + .burstWrapCmdDmyClk = 0x00, + .burstWrapDataMode = SF_CTRL_DATA_1_LINE, + .burstWrapData = 0x02, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x38, + .qppAddrMode = SF_CTRL_ADDR_4_LINES, + + .ioMode = SF_CTRL_QIO_MODE, + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .enter32BitsAddrCmd = 0xb7, + .exit32BitsAddrCmd = 0xe9, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 300, + .timeE32k = 1200, + .timeE64k = 1200, + .timePagePgm = 5, + .timeCe = 33 * 1000, + .pdDelay = 45, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION SPI_Flash_Cfg_Type flashCfg_Mxic_25L256 = { + .resetCreadCmd = 0xff, + .resetCreadCmdSize = 3, + .mid = 0xc2, + + .deBurstWrapCmd = 0xC0, + .deBurstWrapCmdDmyClk = 0x00, + .deBurstWrapDataMode = SF_CTRL_DATA_1_LINE, + .deBurstWrapData = 0x10, + + /*reg*/ + .writeEnableCmd = 0x06, + .wrEnableIndex = 0x00, + .wrEnableBit = 0x01, + .wrEnableReadRegLen = 0x01, + + .qeIndex = 0, + .qeBit = 0x06, + .qeWriteRegLen = 0x02, + .qeReadRegLen = 0x1, + + .busyIndex = 0, + .busyBit = 0x00, + .busyReadRegLen = 0x1, + .releasePowerDown = 0xab, + + .readRegCmd[0] = 0x05, + .readRegCmd[1] = 0x15, + .writeRegCmd[0] = 0x01, + .writeRegCmd[1] = 0x01, + + .fastReadQioCmd = 0xeb, + .frQioDmyClk = 16 / 8, + .cReadSupport = 1, + .cReadMode = 0xA5, + + .burstWrapCmd = 0xC0, + .burstWrapCmdDmyClk = 0x00, + .burstWrapDataMode = SF_CTRL_DATA_1_LINE, + .burstWrapData = 0x02, + /*erase*/ + .chipEraseCmd = 0xc7, + .sectorEraseCmd = 0x20, + .blk32EraseCmd = 0x52, + .blk64EraseCmd = 0xd8, + /*write*/ + .pageProgramCmd = 0x02, + .qpageProgramCmd = 0x38, + .qppAddrMode = SF_CTRL_ADDR_4_LINES, + + .ioMode = (SF_CTRL_QIO_MODE | 0x20), + .clkDelay = 1, + .clkInvert = 0x3f, + + .resetEnCmd = 0x66, + .resetCmd = 0x99, + .cRExit = 0xff, + .wrEnableWriteRegLen = 0x00, + + /*id*/ + .jedecIdCmd = 0x9f, + .jedecIdCmdDmyClk = 0, + .enter32BitsAddrCmd = 0xb7, + .exit32BitsAddrCmd = 0xe9, + .sectorSize = 4, + .pageSize = 256, + + /*read*/ + .fastReadCmd = 0x0b, + .frDmyClk = 8 / 8, + .qpiFastReadCmd = 0x0b, + .qpiFrDmyClk = 8 / 8, + .fastReadDoCmd = 0x3b, + .frDoDmyClk = 8 / 8, + .fastReadDioCmd = 0xbb, + .frDioDmyClk = 0, + .fastReadQoCmd = 0x6b, + .frQoDmyClk = 8 / 8, + + .qpiFastReadQioCmd = 0xeb, + .qpiFrQioDmyClk = 16 / 8, + .qpiPageProgramCmd = 0x02, + .writeVregEnableCmd = 0x50, + + /* qpi mode */ + .enterQpi = 0x38, + .exitQpi = 0xff, + + /*AC*/ + .timeEsector = 400, + .timeE32k = 1000, + .timeE64k = 2000, + .timePagePgm = 5, + .timeCe = 33 * 1000, + .pdDelay = 20, + .qeData = 0, +}; + +static const ATTR_TCM_CONST_SECTION Flash_Info_t flashInfos[] = { + { + .jedecID = 0x1440ef, + //.name="Winb_80DV_08_33", + .cfg = &flashCfg_Winb_80DV, + }, + { + .jedecID = 0x1540ef, + //.name="Winb_16JV_16_33", + .cfg = &flashCfg_Winb_16JV, + }, + { + .jedecID = 0x1640ef, + //.name="Winb_32FV_32_33", + .cfg = &flashCfg_Winb_16JV, + }, + { + .jedecID = 0x1840ef, + //.name="Winb_128JV_128_33", + .cfg = &flashCfg_Winb_64JW, + }, + { + .jedecID = 0x1940ef, + //.name="Winb_256FV_128_33", + .cfg = &flashCfg_Winb_256FV, + }, + { + .jedecID = 0x1460ef, + //.name="Winb_80EW_08_18", + .cfg = &flashCfg_Winb_16JV, + }, + { + .jedecID = 0x1560ef, + //.name="Winb_16FW_16_18", + .cfg = &flashCfg_Winb_16JV, + }, + { + .jedecID = 0x1660ef, + //.name="Winb_32FW_32_18", + .cfg = &flashCfg_Winb_16JV, + }, + { + .jedecID = 0x1760ef, + //.name="WB_64JW_64_18", + .cfg = &flashCfg_Winb_64JW, + }, + { + .jedecID = 0x1860ef, + //.name="Winb_128JW_128_18", + .cfg = &flashCfg_Winb_64JW, + }, + { + .jedecID = 0x1570ef, + //.name="Winb_16JV_16_33", + .cfg = &flashCfg_Winb_16JV, + }, + { + .jedecID = 0x1870ef, + //.name="Winb_128JV_128_33", + .cfg = &flashCfg_Winb_64JW, + }, + { + .jedecID = 0x1680ef, + //.name="Winb_32JW_32_18", + .cfg = &flashCfg_Winb_16JV, + }, + { + .jedecID = 0x1880ef, + //.name="Winb_128JW_128_18", + .cfg = &flashCfg_Winb_64JW, + }, + { + .jedecID = 0x1440C8, + //.name="GD_Q08E_08_33", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x1540C8, + //.name="GD_Q16E_16_33", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x1640C8, + //.name="GD_Q32C_32_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x1740C8, + //.name="GD_Q64E_64_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x1840C8, + //.name="GD_Q128E_128_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x1460C8, + //.name="GD_LQ08C_08_18", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x1560C8, + //.name="GD_LE16C_16_18", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x1660C8, + //.name="GD_LQ32D_32_18", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x1760c8, + //.name="GD_LQ64E_64_18", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x1860c8, + //.name="GD_LQ128E_64_18", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x1465C8, + //.name="GD_WQ80E_80_33", + .cfg = &flashCfg_Gd_WQ80E_WQ16E, + }, + { + .jedecID = 0x1565C8, + //.name="GD_WQ16E_16_33", + .cfg = &flashCfg_Gd_WQ80E_WQ16E, + }, + { + .jedecID = 0x1665C8, + //.name="GD_WQ32E_32_33", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x15345e, + //.name="ZB_WQ16A_16_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x15405e, + //.name="ZB_Q16B_16_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x16405e, + //.name="ZB_Q32B_32_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x17405e, + //.name="ZB_Q64B_64_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x14605E, + //.name="ZB_VQ80", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x15605E, + //.name="ZB_VQ16", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x1820C2, + //.name="MX_25L128_128_33", + .cfg = &flashCfg_Mxic_128, + }, + { + .jedecID = 0x1920C2, + //.name="MX_25L256_256_33", + .cfg = &flashCfg_Mxic_25L256, + }, + { + .jedecID = 0x3925C2, + //.name="MX_25U256_256_33", + .cfg = &flashCfg_Mxic_25L256, + }, + { + .jedecID=0x144020, + //.name="XM_25QH80_80_33", + .cfg=&flashCfg_Winb_16JV, + }, + { + .jedecID=0x154020, + //.name="XM_25QH16_16_33", + .cfg=&flashCfg_Winb_16JV, + }, + { + .jedecID=0x164020, + //.name="XM_25QH32_32_33", + .cfg=&flashCfg_Winb_16JV, + }, + { + .jedecID=0x174020, + //.name="XM_25QH64_64_33", + .cfg=&flashCfg_Winb_16JV, + }, + { + .jedecID = 0x15400B, + //.name="XT_25F16B_16_33", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x16400B, + //.name="XT_25F32B_32_33", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x17400B, + //.name="XT_25F64B_32_33", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x18400B, + //.name="XT_25F128B_128_33", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x14600B, + //.name="XT_25Q80B_08_18", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x16600B, + //.name="XT_25Q32B_32_18", + .cfg = &flashCfg_Gd_Q80E_Q16E, + }, + { + .jedecID = 0x144068, + //.name="Boya_Q08B_08_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x154068, + //.name="Boya_Q16B_16_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x164068, + //.name="Boya_Q32B_32_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x174068, + //.name="Boya_Q64A_64_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + }, + { + .jedecID = 0x184068, + //.name="Boya_Q128A_128_33", + .cfg = &flashCfg_Gd_Q32E_Q128E, + } +}; +#endif + +/*@} end of group SF_CFG_Private_Variables */ + +/** @defgroup SF_CFG_Global_Variables + * @{ + */ + +/*@} end of group SF_CFG_Global_Variables */ + +/** @defgroup SF_CFG_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SF_CFG_Private_Fun_Declaration */ + +/** @defgroup SF_CFG_Private_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Init external flash GPIO according to flash GPIO config + * + * @param extFlashPin: Flash GPIO config + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Init_Ext_Flash_Gpio(uint8_t extFlashPin) +{ + GLB_GPIO_Cfg_Type cfg; + uint8_t gpiopins[6]; + uint8_t i = 0; + + cfg.gpioMode = GPIO_MODE_AF; + cfg.pullType = GPIO_PULL_UP; + cfg.drive = 2; + cfg.smtCtrl = 1; + cfg.gpioFun = GPIO_FUN_FLASH; + + if (extFlashPin == 0) { + gpiopins[0] = BFLB_EXTFLASH_CLK0_GPIO; + gpiopins[1] = BFLB_EXTFLASH_CS0_GPIO; + gpiopins[2] = BFLB_EXTFLASH_DATA00_GPIO; + gpiopins[3] = BFLB_EXTFLASH_DATA10_GPIO; + gpiopins[4] = BFLB_EXTFLASH_DATA20_GPIO; + gpiopins[5] = BFLB_EXTFLASH_DATA30_GPIO; + } else { + return ERROR; + } + + for (i = 0; i < sizeof(gpiopins); i++) { + cfg.gpioPin = gpiopins[i]; + + if (i == 0 || i == 1) { + /* flash clk and cs is output */ + cfg.gpioMode = GPIO_MODE_OUTPUT; + } else { + /* data are bidir */ + cfg.gpioMode = GPIO_MODE_AF; + } + + GLB_GPIO_Init(&cfg); + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Deinit external flash GPIO according to flash GPIO config + * + * @param extFlashPin: Flash GPIO config + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Deinit_Ext_Flash_Gpio(uint8_t extFlashPin) +{ + GLB_GPIO_Cfg_Type cfg; + uint8_t gpiopins[6]; + uint8_t i = 0; + + cfg.gpioMode = GPIO_MODE_INPUT; + cfg.pullType = GPIO_PULL_UP; + cfg.drive = 1; + cfg.smtCtrl = 1; + cfg.gpioFun = GPIO_FUN_GPIO; + + if (extFlashPin == 0) { + gpiopins[0] = BFLB_EXTFLASH_CLK0_GPIO; + gpiopins[1] = BFLB_EXTFLASH_CS0_GPIO; + gpiopins[2] = BFLB_EXTFLASH_DATA00_GPIO; + gpiopins[3] = BFLB_EXTFLASH_DATA10_GPIO; + gpiopins[4] = BFLB_EXTFLASH_DATA20_GPIO; + gpiopins[5] = BFLB_EXTFLASH_DATA30_GPIO; + } else { + return ERROR; + } + + for (i = 0; i < sizeof(gpiopins); i++) { + cfg.gpioPin = gpiopins[i]; + GLB_GPIO_Init(&cfg); + } + + return SUCCESS; +} +#endif + +/*@} end of group SF_CFG_Private_Functions */ + +/** @defgroup SF_CFG_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Get flash config according to flash ID + * + * @param flashID: Flash ID + * @param pFlashCfg: Flash config pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Get_Flash_Cfg_Need_Lock(uint32_t flashID, SPI_Flash_Cfg_Type *pFlashCfg, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + uint32_t i; + uint8_t buf[sizeof(SPI_Flash_Cfg_Type) + 8]; + uint32_t crc, *pCrc; + uint32_t xipOffset; + + if (flashID == 0) { + xipOffset = SF_Ctrl_Get_Flash_Image_Offset(group, bank); + SF_Ctrl_Set_Flash_Image_Offset(0, group, bank); + XIP_SFlash_Read_Via_Cache_Need_Lock(8 + BL808_FLASH_XIP_BASE, buf, sizeof(SPI_Flash_Cfg_Type) + 8, group, bank); + SF_Ctrl_Set_Flash_Image_Offset(xipOffset, group, bank); + + if (ARCH_MemCmp(buf, BFLB_FLASH_CFG_MAGIC, 4) == 0) { + crc = BFLB_Soft_CRC32((uint8_t *)buf + 4, sizeof(SPI_Flash_Cfg_Type)); + pCrc = (uint32_t *)(buf + 4 + sizeof(SPI_Flash_Cfg_Type)); + + if (*pCrc == crc) { + ARCH_MemCpy_Fast(pFlashCfg, (uint8_t *)buf + 4, sizeof(SPI_Flash_Cfg_Type)); + return SUCCESS; + } + } + } else { + for (i = 0; i < sizeof(flashInfos) / sizeof(flashInfos[0]); i++) { + if (flashInfos[i].jedecID == flashID) { + ARCH_MemCpy_Fast(pFlashCfg, flashInfos[i].cfg, sizeof(SPI_Flash_Cfg_Type)); + return SUCCESS; + } + } + } + + return ERROR; +} +#endif + +/****************************************************************************/ /** + * @brief Get flash config according to flash ID patch + * + * @param flashID: Flash ID + * @param pFlashCfg: Flash config pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(uint32_t flashID, SPI_Flash_Cfg_Type *pFlashCfg, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + return SF_Cfg_Get_Flash_Cfg_Need_Lock(flashID, pFlashCfg, group, bank); +} +#endif + +/****************************************************************************/ /** + * @brief Init flash GPIO according to flash Pin config + * + * @param flashPinCfg: Specify flash Pin config + * @param restoreDefault: Wether to restore default setting + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Init_Flash_Gpio(SF_Ctrl_Pin_Select flashPinCfg, uint8_t restoreDefault) +{ + uint8_t selEmbedded = 0; + uint8_t swap = 0; + + if ((flashPinCfg&(1<<3)) > 0) { + return ERROR; + } + + if (restoreDefault) { + /* Set Default first */ + GLB_Set_Flash_IO_PARM(1, 1); + SF_Ctrl_Select_Pad(SF_IO_EMB_SWAP_IO0_IO3); + + /* Default is set, so return */ + if (flashPinCfg == SF_IO_EMB_SWAP_IO0_IO3) { + return SUCCESS; + } + } + + if (flashPinCfg & (1 << 2)) { + /* Init sf2 gpio */ + SF_Cfg_Init_Ext_Flash_Gpio(0); + selEmbedded = 0; + } else { + selEmbedded = 1; + } + /* if pin select dual flash, embedded is default */ + if ((flashPinCfg & (1 << 4))) { + selEmbedded = 1; + } + + swap = ((flashPinCfg >> 1) & 1); + swap = (!swap); + GLB_Set_Flash_IO_PARM(selEmbedded, swap); + SF_Ctrl_Select_Pad(flashPinCfg); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Identify one flash + * + * @param callFromFlash: code run at flash or ram + * @param flashPinCfg: Bit 7: autoscan, Bit6-0: flash GPIO config + * @param restoreDefault: Wether restore default flash GPIO config + * @param pFlashCfg: Flash config pointer + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return Flash ID + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +uint32_t ATTR_TCM_SECTION SF_Cfg_Flash_Identify(uint8_t callFromFlash, uint8_t flashPinCfg, + uint8_t restoreDefault, SPI_Flash_Cfg_Type *pFlashCfg, uint8_t group, SF_Ctrl_Bank_Select bank) +{ + uint8_t autoScan = 0; + uint8_t flashPin = 0; + uint32_t jdecId = 0; + uint32_t i = 0; + uint32_t offset; + BL_Err_Type stat; + + autoScan = ((flashPinCfg >> 7) & 1); + flashPin = (flashPinCfg & 0x7F); + + ARCH_MemCpy_Fast(pFlashCfg, &flashCfg_Winb_16JV, sizeof(SPI_Flash_Cfg_Type)); + + if (callFromFlash == 1) { + stat = XIP_SFlash_State_Save(pFlashCfg, &offset, group, bank); + + if (stat != SUCCESS) { + SF_Ctrl_Set_Owner(SF_CTRL_OWNER_IAHB); + return 0; + } + } + + if (autoScan) { + flashPin = 0; + + do { + if (flashPin > SF_IO_EMB_SWAP_NONE_DUAL_IO0_AND_EXT_SF2) { + jdecId = 0; + break; + } + + if (!IS_SF_CTRL_PIN_SELECT(flashPin) || (flashPin&(1<<3)) > 0) { + flashPin++; + continue; + } + + SF_Cfg_Init_Flash_Gpio(flashPin, restoreDefault); + SFlash_Release_Powerdown(pFlashCfg); + SFlash_Reset_Continue_Read(pFlashCfg); + SFlash_DisableBurstWrap(pFlashCfg); + jdecId = 0; + SFlash_GetJedecId(pFlashCfg, (uint8_t *)&jdecId); + SFlash_DisableBurstWrap(pFlashCfg); + jdecId = jdecId & 0xffffff; + flashPin++; + } while ((jdecId & 0x00ffff) == 0 || (jdecId & 0xffff00) == 0 || (jdecId & 0x00ffff) == 0xffff || (jdecId & 0xffff00) == 0xffff00); + } else { + /* select media gpio */ + SF_Cfg_Init_Flash_Gpio(flashPin, restoreDefault); + SFlash_Release_Powerdown(pFlashCfg); + SFlash_Reset_Continue_Read(pFlashCfg); + SFlash_DisableBurstWrap(pFlashCfg); + SFlash_GetJedecId(pFlashCfg, (uint8_t *)&jdecId); + SFlash_DisableBurstWrap(pFlashCfg); + jdecId = jdecId & 0xffffff; + } + + for (i = 0; i < sizeof(flashInfos) / sizeof(flashInfos[0]); i++) { + if (flashInfos[i].jedecID == jdecId) { + ARCH_MemCpy_Fast(pFlashCfg, flashInfos[i].cfg, sizeof(SPI_Flash_Cfg_Type)); + break; + } + } + + if (i == sizeof(flashInfos) / sizeof(flashInfos[0])) { + if (callFromFlash == 1) { + XIP_SFlash_State_Restore(pFlashCfg, offset, group, bank); + } + + return jdecId; + } else { + if (callFromFlash == 1) { + XIP_SFlash_State_Restore(pFlashCfg, offset, group, bank); + } + + return (jdecId | BFLB_FLASH_ID_VALID_FLAG); + } +} +#endif + +/****************************************************************************/ /** + * @brief Identify one flash patch + * + * @param callFromFlash: code run at flash or ram + * @param flashPinCfg: Bit 7: autoscan, Bit6-0: flash GPIO config + * @param restoreDefault: Wether restore default flash GPIO config + * @param pFlashCfg: Flash config pointer + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return Flash ID + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +uint32_t ATTR_TCM_SECTION SF_Cfg_Flash_Identify_Ext(uint8_t callFromFlash, uint8_t flashPinCfg, + uint8_t restoreDefault, SPI_Flash_Cfg_Type *pFlashCfg, uint8_t group, SF_Ctrl_Bank_Select bank) +{ + return SF_Cfg_Flash_Identify(callFromFlash, flashPinCfg, restoreDefault, pFlashCfg, group, bank); +} +#endif + +/****************************************************************************/ /** + * @brief SF Cfg flash init + * + * @param sel: SF pin select + * @param pSfCtrlCfg: Serial flash controller configuration pointer + * @param pBank2Cfg: Serial flash2 controller configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Flash_Init(SF_Ctrl_Pin_Select sel, const SF_Ctrl_Cfg_Type *pSfCtrlCfg, const SF_Ctrl_Bank2_Cfg *pBank2Cfg) +{ + uint8_t selEmbedded = 0; + uint8_t swap = 0; + + if ((sel&(1<<3)) > 0) { + return ERROR; + } + + if (sel & (1 << 2)) { + SF_Cfg_Init_Ext_Flash_Gpio(0); + selEmbedded = 0; + } else { + selEmbedded = 1; + } + /* If pin select dual flash, embedded is default */ + if ((sel & (1 << 4))) { + selEmbedded = 1; + } + + swap = ((sel >> 1) & 1); + swap = (!swap); + GLB_Set_Flash_IO_PARM(selEmbedded, swap); + SF_Ctrl_Select_Pad(sel); + + if (sel <= SF_IO_EMB_SWAP_NONE_DUAL_IO0) { + /* Embedded pad1 io delay set */ + SF_Ctrl_Set_IO_Delay(SF_CTRL_PAD1, pSfCtrlCfg->doDelay, pSfCtrlCfg->diDelay, pSfCtrlCfg->oeDelay); + } else if (sel <= SF_IO_EXT_SF2) { + /* Pad2 or pad3 io delay set */ + SF_Ctrl_Set_IO_Delay((sel >> 2), pSfCtrlCfg->doDelay, pSfCtrlCfg->diDelay, pSfCtrlCfg->oeDelay); + } else if (sel >= SF_IO_EMB_SWAP_IO0_IO3_AND_EXT_SF2 && sel <= SF_IO_EMB_SWAP_NONE_DUAL_IO0_AND_EXT_SF2) { + /* Dual flash mode, embedded pad1 and pad2 io delay set */ + SF_Ctrl_Set_IO_Delay(SF_CTRL_PAD1, pSfCtrlCfg->doDelay, pSfCtrlCfg->diDelay, pSfCtrlCfg->oeDelay); + SF_Ctrl_Set_IO_Delay(SF_CTRL_PAD2, pBank2Cfg->doDelay, pBank2Cfg->diDelay, pBank2Cfg->oeDelay); + } + + if (pBank2Cfg != NULL) { + if (pBank2Cfg->sbus2Select) { + if (sel >= SF_IO_EMB_SWAP_IO0_IO3_AND_EXT_SF2 && sel <= SF_IO_EMB_SWAP_NONE_DUAL_IO0_AND_EXT_SF2) { + /* Default sbus2 replace opt flash2 */ + SF_Ctrl_Sbus2_Replace(SF_CTRL_PAD2); + } + } + } + + SFlash_Init(pSfCtrlCfg, pBank2Cfg); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief SF Cfg system bus 2 flash init + * + * @param sel: SF pin select + * @param pBank2Cfg: Serial flash2 controller configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SF_Cfg_Sbus2_Flash_Init(SF_Ctrl_Pin_Select sel, const SF_Ctrl_Bank2_Cfg *pBank2Cfg) +{ + if (sel < SF_IO_EMB_SWAP_IO0_IO3_AND_EXT_SF2 || sel > SF_IO_EMB_SWAP_NONE_DUAL_IO0_AND_EXT_SF2) { + return ERROR; + } + + /* Init flash2 gpio */ + if (sel & (1 << 2)) { + SF_Cfg_Init_Ext_Flash_Gpio(0); + } + + /* Set remap for flash2 xip mode */ + SF_Ctrl_Remap_Set(pBank2Cfg->remap, pBank2Cfg->remapLock); + + /* Dual flash mode, pad2 io delay set */ + SF_Ctrl_Set_IO_Delay(SF_CTRL_PAD2, pBank2Cfg->doDelay, pBank2Cfg->diDelay, pBank2Cfg->oeDelay); + + if (pBank2Cfg->sbus2Select) { + /* Default sbus2 replace opt flash2 */ + SF_Ctrl_Sbus2_Replace(SF_CTRL_PAD2); + } + + SFlash_Init(NULL, pBank2Cfg); + + return SUCCESS; +} +#endif + +/*@} end of group SF_CFG_Public_Functions */ + +/*@} end of group SF_CFG */ + +/*@} end of group BL808_Peripheral_Driver */ diff --git a/drivers/soc/bl808/bl808_std/src/bl808_sf_ctrl.c b/drivers/soc/bl808/bl808_std/src/bl808_sf_ctrl.c new file mode 100644 index 00000000..4b2c1942 --- /dev/null +++ b/drivers/soc/bl808/bl808_std/src/bl808_sf_ctrl.c @@ -0,0 +1,1870 @@ +/** + ****************************************************************************** + * @file bl808_sf_ctrl.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "bl808_sf_ctrl.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup SF_CTRL + * @{ + */ + +/** @defgroup SF_CTRL_Private_Macros + * @{ + */ + +/*@} end of group SF_CTRL_Private_Macros */ + +/** @defgroup SF_CTRL_Private_Types + * @{ + */ + +/*@} end of group SF_CTRL_Private_Types */ + +/** @defgroup SF_CTRL_Private_Variables + * @{ + */ +#define SF_CTRL_BUSY_STATE_TIMEOUT (5 * 320 * 1000) +#define SF_Ctrl_Get_AES_Region(addr, r) (addr + SF_CTRL_AES_REGION_OFFSET + (r)*0x80) + +/*@} end of group SF_CTRL_Private_Variables */ + +/** @defgroup SF_CTRL_Global_Variables + * @{ + */ + +/*@} end of group SF_CTRL_Global_Variables */ + +/** @defgroup SF_CTRL_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SF_CTRL_Private_Fun_Declaration */ + +/** @defgroup SF_CTRL_Private_Functions + * @{ + */ + +/*@} end of group SF_CTRL_Private_Functions */ + +/** @defgroup SF_CTRL_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Enable serail flash controller + * + * @param cfg: serial flash controller config + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Enable(const SF_Ctrl_Cfg_Type *cfg) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + + if (cfg == NULL) { + return; + } + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_OWNER_TYPE(cfg->owner)); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + if (cfg->en32bAddr) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_32B_ADR_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_32B_ADR_EN); + } + + if (cfg->clkDelay > 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N, cfg->clkDelay - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN); + } + + /* Serail out inverted, so sf ctrl send on negative edge */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_OUT_INV_SEL, cfg->clkInvert); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_SF_RX_INV_SEL, cfg->rxClkInvert); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal); + + /* Enable AHB access sram buffer and enable sf interface */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SRAM_EN); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_EN); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal); + + SF_Ctrl_Set_Owner(cfg->owner); +} +#endif + +/****************************************************************************/ /** + * @brief Enable serail bank2 controller + * + * @param bank2Cfg: serial bank2 controller config + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Bank2_Enable(const SF_Ctrl_Bank2_Cfg *bank2Cfg) +{ + uint32_t tmpVal = 0; + + if (bank2Cfg == NULL) { + return; + } + + /* Select if1 bank2 clock delay */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_12); + + if (bank2Cfg->bank2RxClkInvertSrc) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF2_CLK_SF_RX_INV_SRC); + + if (bank2Cfg->bank2RxClkInvertSel) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF2_CLK_SF_RX_INV_SEL); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF2_CLK_SF_RX_INV_SEL); + } + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF2_CLK_SF_RX_INV_SRC); + } + + if (bank2Cfg->bank2DelaySrc) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF2_IF_READ_DLY_SRC); + + if (bank2Cfg->bank2ClkDelay > 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF2_IF_READ_DLY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF2_IF_READ_DLY_N, bank2Cfg->bank2ClkDelay - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF2_IF_READ_DLY_EN); + } + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF2_IF_READ_DLY_SRC); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_12, tmpVal); + + /* Select sbus2 clock delay */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_0); + + if (bank2Cfg->bank2RxClkInvertSel) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL); + } + + if (bank2Cfg->bank2ClkDelay > 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF2_READ_DLY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF2_READ_DLY_N, bank2Cfg->bank2ClkDelay - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF2_READ_DLY_EN); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_0, tmpVal); + + /* Dual flash mode, enable bank2, select pad1 and pad2 */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_2); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_EN); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_MODE); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_PAD_SEL, 0); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_2, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief SF Ctrl set io delay + * + * @param pad: Pad select + * @param doDelay: DO delay select + * @param diDelay: DI delay select + * @param oeDelay: OE delay select + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Set_IO_Delay(SF_Ctrl_Pad_Type pad, uint8_t doDelay, uint8_t diDelay, uint8_t oeDelay) +{ + uint32_t tmpVal = 0; + uint32_t offset = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_PAD_TYPE(pad)); + + if (pad == SF_CTRL_PAD1) { + offset = SF_CTRL_BASE + SF_CTRL_IF_IO_DLY_1_OFFSET; + } else if (pad == SF_CTRL_PAD2) { + offset = SF_CTRL_BASE + SF_CTRL_IF_IO_DLY_2_OFFSET; + } else { + offset = SF_CTRL_BASE + SF_CTRL_IF_IO_DLY_3_OFFSET; + } + + /* Set do di and oe delay */ + tmpVal = BL_RD_REG(offset, SF_CTRL_IO_DLY_1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_0_DO_DLY_SEL, doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_0_DI_DLY_SEL, diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_0_OE_DLY_SEL, oeDelay); + BL_WR_REG(offset, SF_CTRL_IO_DLY_1, tmpVal); + + tmpVal = BL_RD_REG(offset, SF_CTRL_IO_DLY_2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_1_DO_DLY_SEL, doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_1_DI_DLY_SEL, diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_1_OE_DLY_SEL, oeDelay); + BL_WR_REG(offset, SF_CTRL_IO_DLY_2, tmpVal); + + tmpVal = BL_RD_REG(offset, SF_CTRL_IO_DLY_3); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_2_DO_DLY_SEL, doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_2_DI_DLY_SEL, diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_2_OE_DLY_SEL, oeDelay); + BL_WR_REG(offset, SF_CTRL_IO_DLY_3, tmpVal); + + tmpVal = BL_RD_REG(offset, SF_CTRL_IO_DLY_4); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_3_DO_DLY_SEL, doDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_3_DI_DLY_SEL, diDelay); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_3_OE_DLY_SEL, oeDelay); + BL_WR_REG(offset, SF_CTRL_IO_DLY_4, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Flash controller sbus2 hold sram + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Sbus2_Hold_Sram(void) +{ + uint32_t tmpVal; + + /* Sbus2 hold sram */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_1); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF2_FN_SEL); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_1, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Flash controller sbus2 release sram + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Sbus2_Release_Sram(void) +{ + uint32_t tmpVal; + + /* Sbus2 release sram */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_1); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF2_FN_SEL); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_1, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Get flash controller sbus2 status + * + * @param None + * + * @return Wether if2 is enable + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Sts_Type ATTR_TCM_SECTION SF_Ctrl_Is_Sbus2_Enable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_1); + + if (BL_IS_REG_BIT_SET(tmpVal, SF_CTRL_SF_IF2_EN)) { + if (BL_IS_REG_BIT_SET(tmpVal, SF_CTRL_SF_IF2_FN_SEL)) { + return SET; + } else { + return RESET; + } + } + + return RESET; +} +#endif + +/****************************************************************************/ /** + * @brief SF Ctrl set sbus2 repalce + * + * @param pad: SF pad to replace + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Sbus2_Replace(SF_Ctrl_Pad_Type pad) +{ + uint32_t tmpVal = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_PAD_TYPE(pad)); + + /* Sbus2 enable */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_1); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF2_EN); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_1, tmpVal); + + SF_Ctrl_Sbus2_Hold_Sram(); + + /* Sbus2 repalce pad */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_0); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF2_REPLACE_SF1); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF2_REPLACE_SF2); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF2_REPLACE_SF3); + + if (pad == SF_CTRL_PAD1) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF2_REPLACE_SF1); + } else if (pad == SF_CTRL_PAD2) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF2_REPLACE_SF2); + } else { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF2_REPLACE_SF3); + } + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF2_PAD_SEL, pad); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief SF Ctrl sbus2 revoke replace + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Sbus2_Revoke_replace(void) +{ + uint32_t tmpVal = 0; + + SF_Ctrl_Sbus2_Release_Sram(); + + /* Sbus2 clear repalce pad */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_0); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF2_REPLACE_SF1); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF2_REPLACE_SF2); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF2_REPLACE_SF3); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_0, tmpVal); + + /* Sbus2 disable */ + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_1); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF2_EN); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_1, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief SF Ctrl set sbus2 clock delay + * + * @param clkDelay: Sbus2 clock delay + * @param rxClkInvert: Sbus2 rx clock invert + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Sbus2_Set_Delay(uint8_t clkDelay, uint8_t rxClkInvert) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_0); + + if (clkDelay > 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF2_READ_DLY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF2_READ_DLY_N, clkDelay - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF2_READ_DLY_EN); + } + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_SF_IF2_RX_INV_SEL, rxClkInvert); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF2_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Get flash controller clock delay value + * + * @param en32BitsAddr: Serial flash enable or disable 32-bits addr + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_32bits_Addr_En(BL_Fun_Type en32BitsAddr) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + if (en32BitsAddr) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_32B_ADR_EN); + + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_32B_ADR_EN); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Get flash controller clock delay value + * + * @param None + * + * @return Clock delay value + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +uint8_t ATTR_TCM_SECTION SF_Ctrl_Get_Clock_Delay(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN) == 0) { + return 0; + } else { + return BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N) + 1; + } +} +#endif + +/****************************************************************************/ /** + * @brief Set flash controller clock delay value + * + * @param delay: Clock delay value + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Set_Clock_Delay(uint8_t delay) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + if (delay > 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N, delay - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief SF Ctrl get wrap queue value + * + * @param None + * + * @return Wrap queue value + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +uint8_t ATTR_TCM_SECTION SF_Ctrl_Get_Wrap_Queue_Value(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_3); + + return BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CMDS_2_WRAP_Q); +} +#endif + +/****************************************************************************/ /** + * @brief SF Ctrl set cmds config + * + * @param cmdsCfg: SF Ctrl cmds config + * @param bank: bank select type + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Cmds_Set(SF_Ctrl_Cmds_Cfg *cmdsCfg, SF_Ctrl_Bank_Select bank) +{ + uint32_t tmpVal; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_WRAP_MODE(cmdsCfg->cmdsWrapMode)); + CHECK_PARAM(IS_SF_CTRL_WRAP_LEN_TYPE(cmdsCfg->cmdsWrapLen)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_3); + + if (cmdsCfg->ackLatency) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_1_ACK_LAT); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_1_ACK_LAT); + } + + if (cmdsCfg->cmdsCoreEn) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_CORE_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_CORE_EN); + } + + if (bank == SF_CTRL_FLASH_BANK1) { + if (cmdsCfg->cmdsEn) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_2_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_2_EN); + } + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CMDS_2_WRAP_MODE, cmdsCfg->cmdsWrapMode); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CMDS_2_WRAP_LEN, cmdsCfg->cmdsWrapLen); + } else { + if (cmdsCfg->cmdsEn) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_1_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_CMDS_1_EN); + } + + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CMDS_1_WRAP_MODE, cmdsCfg->cmdsWrapMode); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CMDS_1_WRAP_LEN, cmdsCfg->cmdsWrapLen); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_3, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief SF Ctrl pad select + * + * @param sel: Pin select type + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Select_Pad(SF_Ctrl_Pin_Select sel) +{ + uint32_t tmpVal; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_PIN_SELECT(sel)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_2); + + if (sel <= SF_IO_EXT_SF2) { + /* Single flash mode, disable bank2 */ + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_EN); + + if (sel <= SF_IO_EMB_SWAP_NONE_DUAL_IO0) { + /* Select embedded pad1 */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_PAD_SEL, 0); + } else { + /* Select pad2 or pad3 */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_PAD_SEL, ((sel&0xf) >> 2)); + } + } else if (sel >= SF_IO_EMB_SWAP_IO0_IO3_AND_EXT_SF2 && sel <= SF_IO_EMB_SWAP_NONE_DUAL_IO0_AND_EXT_SF2) { + /* Dual flash mode, enable bank2, select pad1 and pad2 */ + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_EN); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_BK2_MODE); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_PAD_SEL, 0); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_2, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief SF Ctrl dual flash memory remap set + * + * @param remap: Memory remap set type + * @param lock: Memory remap lock + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Remap_Set(SF_Ctrl_Remap_Type remap, uint8_t lock) +{ + uint32_t tmpVal; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_REMAP_TYPE(remap)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_2); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AHB2SIF_REMAP, remap); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_2, tmpVal); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_2); + + if (lock) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SIF_REMAP_LOCK); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SIF_REMAP_LOCK); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_2, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief SF Ctrl select bank on system bus + * + * @param bank: bank select type + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Sbus_Select_Bank(SF_Ctrl_Bank_Select bank) +{ + /* TODO: sf_if_bk_swap */ + uint32_t tmpVal; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_BANK_SELECT(bank)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_2); + + if (bank == SF_CTRL_FLASH_BANK0) { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_BK_SEL); + } else { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_IF_0_BK_SEL); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_2, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Set flash controller owner:I/D AHB or system AHB + * + * @param owner: owner type + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Set_Owner(SF_Ctrl_Owner_Type owner) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_OWNER_TYPE(owner)); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + /* Set owner */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL, owner); + + /* Set iahb to flash interface */ + if (owner == SF_CTRL_OWNER_IAHB) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SIF_EN); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SIF_EN); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Disable flash controller + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Disable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_IF_EN); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Enable flash controller AES with big indian + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Enable_BE(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_KEY_ENDIAN); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_IV_ENDIAN); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_DIN_ENDIAN); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_DOUT_ENDIAN); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Enable flash controller AES with little indian + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Enable_LE(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_KEY_ENDIAN); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_IV_ENDIAN); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_DIN_ENDIAN); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_DOUT_ENDIAN); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Serial flash controller set AES region + * + * @param region: region number + * @param enable: enable or not + * @param hwKey: hardware key or software key + * @param startAddr: region start address + * @param endAddr: region end address + * @param locked: lock this region or not + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_Region(uint8_t region, uint8_t enable, + uint8_t hwKey, uint32_t startAddr, uint32_t endAddr, uint8_t locked) +{ + /* Do flash key eco */ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region); + uint32_t tmpVal; + + if (!hwKey) { + regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region); + } + + tmpVal = BL_RD_REG(regionRegBase, SF_CTRL_SF_AES_END); + /* sf_aes_end =1 means 1,11,1111,1111 */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_END, endAddr / 1024); + BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_END, tmpVal); + + tmpVal = BL_RD_REG(regionRegBase, SF_CTRL_SF_AES_START); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_HW_KEY_EN, hwKey); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_START, startAddr / 1024); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_EN, enable); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_REGION_LOCK, locked); + BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_START, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Serial flash controller set AES key + * + * @param region: region number + * @param key: key data pointer + * @param keyType: flash controller AES key type:128 bits,192 bits or 256 bits + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_Key(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region); + uint32_t tmpVal, i = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_AES_KEY_TYPE(keyType)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_MODE, keyType); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); + + if (NULL != key) { + if (keyType == SF_CTRL_AES_128BITS) { + i = 4; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + */ + } else if (keyType == SF_CTRL_AES_256BITS) { + i = 8; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + */ + } else if (keyType == SF_CTRL_AES_192BITS) { + i = 6; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,__REV(BL_RDWD_FRM_BYTEP(key))); + key+=4; + */ + } + + tmpVal = SF_CTRL_SF_AES_KEY_7_OFFSET; + + while (i--) { + BL_WR_WORD(regionRegBase + tmpVal, __REV(BL_RDWD_FRM_BYTEP(key))); + key += 4; + tmpVal -= 4; + } + } +} +#endif + +/****************************************************************************/ /** + * @brief Serial flash controller set AES XTS mode key + * + * @param region: region number + * @param key: key data pointer + * @param keyType: flash controller AES key type:128 bits,192 bits or 256 bits + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_XTS_Set_Key(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType) +{ + /* Do flash key eco */ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region); + uint32_t tmpVal, i = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_AES_KEY_TYPE(keyType)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_MODE, keyType); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); + + if (NULL != key) { + i = 8; + tmpVal = SF_CTRL_SF_AES_KEY_7_OFFSET; + + while (i--) { + BL_WR_WORD(regionRegBase + tmpVal, __REV(BL_RDWD_FRM_BYTEP(key))); + key += 4; + tmpVal -= 4; + } + } +} +#endif + +/****************************************************************************/ /** + * @brief Serial flash controller set AES key with big endian + * + * @param region: region number + * @param key: key data pointer + * @param keyType: flash controller AES key type:128 bits,192 bits or 256 bits + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_Key_BE(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region); + uint32_t tmpVal, i = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_AES_KEY_TYPE(keyType)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_MODE, keyType); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); + + if (NULL != key) { + if (keyType == SF_CTRL_AES_128BITS) { + i = 4; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,BL_RDWD_FRM_BYTEP(key)); + key+=4; + */ + } else if (keyType == SF_CTRL_AES_256BITS) { + i = 8; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_6,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_7,BL_RDWD_FRM_BYTEP(key)); + key+=4; + */ + } else if (keyType == SF_CTRL_AES_192BITS) { + i = 6; + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_0,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_1,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_2,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_3,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_4,BL_RDWD_FRM_BYTEP(key)); + key+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_KEY_5,BL_RDWD_FRM_BYTEP(key)); + */ + } + + tmpVal = SF_CTRL_SF_AES_KEY_0_OFFSET; + + while (i--) { + BL_WR_WORD(regionRegBase + tmpVal, BL_RDWD_FRM_BYTEP(key)); + key += 4; + tmpVal += 4; + } + } +} +#endif + +/****************************************************************************/ /** + * @brief Serial flash controller set AES XTS mode key with big endian + * + * @param region: region number + * @param key: key data pointer + * @param keyType: flash controller AES key type:128 bits,192 bits or 256 bits + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_XTS_Set_Key_BE(uint8_t region, uint8_t *key, SF_Ctrl_AES_Key_Type keyType) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region); + uint32_t tmpVal, i = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_AES_KEY_TYPE(keyType)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_AES_MODE, keyType); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); + + if (NULL != key) { + i = 8; + tmpVal = SF_CTRL_SF_AES_KEY_0_OFFSET; + + while (i--) { + BL_WR_WORD(regionRegBase + tmpVal, BL_RDWD_FRM_BYTEP(key)); + key += 4; + tmpVal += 4; + } + } +} +#endif + +/****************************************************************************/ /** + * @brief Serial flash controller set AES iv + * + * @param region: region number + * @param iv: iv data pointer + * @param addrOffset: flash address offset + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_IV(uint8_t region, uint8_t *iv, uint32_t addrOffset) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region); + uint32_t tmpVal, i = 3; + + if (iv != NULL) { + tmpVal = SF_CTRL_SF_AES_IV_W3_OFFSET; + + while (i--) { + BL_WR_WORD(regionRegBase + tmpVal, __REV(BL_RDWD_FRM_BYTEP(iv))); + iv += 4; + tmpVal -= 4; + } + + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W3,__REV(BL_RDWD_FRM_BYTEP(iv))); + iv+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W2,__REV(BL_RDWD_FRM_BYTEP(iv))); + iv+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W1,__REV(BL_RDWD_FRM_BYTEP(iv))); + iv+=4; + */ + BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_IV_W0, addrOffset); + iv += 4; + } +} +#endif + +/****************************************************************************/ /** + * @brief Serial flash controller set AES XTS iv + * + * @param region: region number + * @param iv: iv data pointer + * @param addrOffset: flash address offset + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_XTS_Set_IV(uint8_t region, uint8_t *iv, uint32_t addrOffset) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region); + uint32_t tmpVal, i = 3; + + if (iv != NULL) { + tmpVal = SF_CTRL_SF_AES_IV_W1_OFFSET; + + while (i--) { + iv += 4; + BL_WR_WORD(regionRegBase + tmpVal, (BL_RDWD_FRM_BYTEP(iv))); + tmpVal += 4; + } + + BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_IV_W0, addrOffset); + iv += 4; + } +} +#endif + +/****************************************************************************/ /** + * @brief Serial flash controller set AES iv with big endian + * + * @param region: region number + * @param iv: iv data pointer + * @param addrOffset: flash address offset + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_IV_BE(uint8_t region, uint8_t *iv, uint32_t addrOffset) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region); + uint32_t tmpVal, i = 3; + + if (iv != NULL) { + tmpVal = SF_CTRL_SF_AES_IV_W0_OFFSET; + + while (i--) { + BL_WR_WORD(regionRegBase + tmpVal, BL_RDWD_FRM_BYTEP(iv)); + iv += 4; + tmpVal += 4; + } + + /* + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W0,BL_RDWD_FRM_BYTEP(iv)); + iv+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W1,BL_RDWD_FRM_BYTEP(iv)); + iv+=4; + BL_WR_REG(regionRegBase,SF_CTRL_SF_AES_IV_W2,BL_RDWD_FRM_BYTEP(iv)); + iv+=4; + */ + BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_IV_W3, __REV(addrOffset)); + iv += 4; + } +} +#endif + +/****************************************************************************/ /** + * @brief Serial flash controller set AES XTS iv with big endian + * + * @param region: region number + * @param iv: iv data pointer + * @param addrOffset: flash address offset + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_XTS_Set_IV_BE(uint8_t region, uint8_t *iv, uint32_t addrOffset) +{ + /* Do flash key eco*/ + uint32_t regionRegBase = SF_Ctrl_Get_AES_Region(SF_CTRL_BASE, region); + uint32_t tmpVal, i = 3; + + if (iv != NULL) { + tmpVal = SF_CTRL_SF_AES_IV_W2_OFFSET; + + while (i--) { + iv += 4; + BL_WR_WORD(regionRegBase + tmpVal, __REV(BL_RDWD_FRM_BYTEP(iv))); + tmpVal -= 4; + } + + BL_WR_REG(regionRegBase, SF_CTRL_SF_AES_IV_W3, __REV(addrOffset)); + iv += 4; + } +} +#endif +#ifndef BFLB_USE_ROM_DRIVER + +/****************************************************************************/ /** + * @brief Set serial flash controller AES mode + * + * @param mode: AES mode select + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Set_Mode(SF_Ctrl_AES_Mode_Type mode) +{ + uint32_t tmpVal; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_AES_MODE_TYPE(mode)); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + + if (mode == SF_CTRL_AES_CTR_MODE) { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_BLK_MODE); + } else { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_BLK_MODE); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Enable serial flash controller AES + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Enable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AES_EN); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Disable serial flash controller AES + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_AES_Disable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AES_EN); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_AES, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Check is serial flash controller AES enable + * + * @param None + * + * @return Wether AES is enable + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Sts_Type ATTR_TCM_SECTION SF_Ctrl_Is_AES_Enable(void) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_AES); + + if (BL_IS_REG_BIT_SET(tmpVal, SF_CTRL_SF_AES_EN)) { + return SET; + } + + return RESET; +} +#endif + +/****************************************************************************/ /** + * @brief Set flash image offset + * + * @param addrOffset: Address offset value + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Set_Flash_Image_Offset(uint32_t addrOffset, uint8_t group, SF_Ctrl_Bank_Select bank) +{ + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_BANK_SELECT(bank)); + + if (group) { + if (bank == SF_CTRL_FLASH_BANK0) { + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_ID1_OFFSET, addrOffset); + } else { + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_BK2_ID1_OFFSET, addrOffset); + } + } else { + if (bank == SF_CTRL_FLASH_BANK0) { + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_ID0_OFFSET, addrOffset); + } else { + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_BK2_ID0_OFFSET, addrOffset); + } + } +} +#endif + +/****************************************************************************/ /** + * @brief Get flash image offset + * + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return :Address offset value + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +uint32_t ATTR_TCM_SECTION SF_Ctrl_Get_Flash_Image_Offset(uint8_t group, SF_Ctrl_Bank_Select bank) +{ + uint32_t tmpVal = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_BANK_SELECT(bank)); + + if (group) { + if (bank == SF_CTRL_FLASH_BANK0) { + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_ID1_OFFSET); + } else { + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_BK2_ID1_OFFSET); + } + } else { + if (bank == SF_CTRL_FLASH_BANK0) { + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_ID0_OFFSET); + } else { + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_BK2_ID0_OFFSET); + } + } + + return tmpVal; +} +#endif + +/****************************************************************************/ /** + * @brief Lock/unlock sf_id0/sf_id1/sf_bk2_id0/sf_bk2_id1 offset + * + * @param lock: lock or unlock + * + * @return :None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Lock_Flash_Image_Offset(uint8_t lock) +{ + uint32_t tmpVal; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_2); + if (lock) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_ID_OFFSET_LOCK); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_ID_OFFSET_LOCK); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_2, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief SF controller send one command + * + * @param cfg: Serial flash controller command configuration pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_SendCmd(SF_Ctrl_Cmd_Cfg_Type *cfg) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + uint32_t cmdOffset = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_CMD_MODE_TYPE(cfg->cmdMode)); + CHECK_PARAM(IS_SF_CTRL_ADDR_MODE_TYPE(cfg->addrMode)); + CHECK_PARAM(IS_SF_CTRL_DMY_MODE_TYPE(cfg->dummyMode)); + CHECK_PARAM(IS_SF_CTRL_DATA_MODE_TYPE(cfg->dataMode)); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + if (SF_Ctrl_Is_Sbus2_Enable() == RESET) { + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL) != SF_CTRL_OWNER_SAHB) { + return; + } + + cmdOffset = SF_CTRL_BASE + SF_CTRL_IF1_SAHB_OFFSET; + } else { + cmdOffset = SF_CTRL_BASE + SF_CTRL_IF2_SAHB_OFFSET; + } + + /* Clear trigger */ + tmpVal = BL_RD_REG(cmdOffset, SF_CTRL_IF_SAHB_0); + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_IF_0_TRIG); + BL_WR_REG(cmdOffset, SF_CTRL_IF_SAHB_0, tmpVal); + + /* Copy command buffer */ + BL_WR_REG(cmdOffset, SF_CTRL_IF_SAHB_1, cfg->cmdBuf[0]); + BL_WR_REG(cmdOffset, SF_CTRL_IF_SAHB_2, cfg->cmdBuf[1]); + + tmpVal = BL_RD_REG(cmdOffset, SF_CTRL_IF_SAHB_0); + + /* Configure SPI and IO mode*/ + if (SF_CTRL_CMD_1_LINE == cfg->cmdMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_QPI_MODE_EN, SF_CTRL_SPI_MODE); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_QPI_MODE_EN, SF_CTRL_QPI_MODE); + } + + if (SF_CTRL_ADDR_1_LINE == cfg->addrMode) { + if (SF_CTRL_DATA_1_LINE == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_SPI_MODE, SF_CTRL_NIO_MODE); + } else if (SF_CTRL_DATA_2_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_SPI_MODE, SF_CTRL_DO_MODE); + } else if (SF_CTRL_DATA_4_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_SPI_MODE, SF_CTRL_QO_MODE); + } + } else if (SF_CTRL_ADDR_2_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_SPI_MODE, SF_CTRL_DIO_MODE); + } else if (SF_CTRL_ADDR_4_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_SPI_MODE, SF_CTRL_QIO_MODE); + } + + /* Configure cmd */ + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_IF_0_CMD_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_CMD_BYTE, 0); + + /* Configure address */ + if (cfg->addrSize != 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_IF_0_ADR_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_ADR_BYTE, cfg->addrSize - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_IF_0_ADR_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_ADR_BYTE, 0); + } + + /* Configure dummy */ + if (cfg->dummyClks != 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_IF_0_DMY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_DMY_BYTE, cfg->dummyClks - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_IF_0_DMY_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_DMY_BYTE, 0); + } + + /* Configure data */ + if (cfg->nbData != 0) { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_IF_0_DAT_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_DAT_BYTE, cfg->nbData - 1); + } else { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_IF_0_DAT_EN); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_DAT_BYTE, 0); + } + + /* Set read write flag */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_IF_0_DAT_RW, cfg->rwFlag); + BL_WR_REG(cmdOffset, SF_CTRL_IF_SAHB_0, tmpVal); + + /* Trigger */ + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_IF_0_TRIG); + BL_WR_REG(cmdOffset, SF_CTRL_IF_SAHB_0, tmpVal); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } +} +#endif + +/****************************************************************************/ /** + * @brief SF Ctrl disable iahb to flash wrap access for XTS mode + * + * @param disable: Disable for 1 and enable for 0 + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Disable_Wrap_Access(uint8_t disable) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + if (disable) { + tmpVal = BL_CLR_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SIF_DISWRAP); + } else { + tmpVal = BL_SET_REG_BIT(tmpVal, SF_CTRL_SF_AHB2SIF_DISWRAP); + } + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_1, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Config SF controller for flash I/D cache read + * + * @param cfg: Serial flash controller command configuration pointer + * @param cmdValid: command valid or not, for continous read, cache may need no command + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Flash_Read_Icache_Set(SF_Ctrl_Cmd_Cfg_Type *cfg, uint8_t cmdValid) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_CMD_MODE_TYPE(cfg->cmdMode)); + CHECK_PARAM(IS_SF_CTRL_ADDR_MODE_TYPE(cfg->addrMode)); + CHECK_PARAM(IS_SF_CTRL_DMY_MODE_TYPE(cfg->dummyMode)); + CHECK_PARAM(IS_SF_CTRL_DATA_MODE_TYPE(cfg->dataMode)); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL) != SF_CTRL_OWNER_IAHB) { + return; + } + + /* Copy command buffer */ + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_1, cfg->cmdBuf[0]); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_2, cfg->cmdBuf[1]); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_0); + + /* Configure SPI and IO mode*/ + if (SF_CTRL_CMD_1_LINE == cfg->cmdMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_QPI_MODE_EN, SF_CTRL_SPI_MODE); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_QPI_MODE_EN, SF_CTRL_QPI_MODE); + } + + if (SF_CTRL_ADDR_1_LINE == cfg->addrMode) { + if (SF_CTRL_DATA_1_LINE == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_NIO_MODE); + } else if (SF_CTRL_DATA_2_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_DO_MODE); + } else if (SF_CTRL_DATA_4_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_QO_MODE); + } + } else if (SF_CTRL_ADDR_2_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_DIO_MODE); + } else if (SF_CTRL_ADDR_4_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_QIO_MODE); + } + + if (cmdValid) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_BYTE, 0); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_BYTE, 0); + } + + /* Configure address */ + if (cfg->addrSize != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_BYTE, cfg->addrSize - 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_BYTE, 0); + } + + /* configure dummy */ + if (cfg->dummyClks != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_BYTE, cfg->dummyClks - 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_BYTE, 0); + } + + /* Configure data */ + if (cfg->nbData != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_EN, 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_EN, 0); + } + + /* Set read write flag */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_RW, cfg->rwFlag); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_0, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Config bank2 controller for flash2 I/D cache read + * + * @param cfg: Serial flash controller command configuration pointer + * @param cmdValid: command valid or not, for continous read, cache may need no command + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SF_Ctrl_Flash2_Read_Icache_Set(SF_Ctrl_Cmd_Cfg_Type *cfg, uint8_t cmdValid) +{ + uint32_t tmpVal = 0; + uint32_t timeOut = 0; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_CMD_MODE_TYPE(cfg->cmdMode)); + CHECK_PARAM(IS_SF_CTRL_ADDR_MODE_TYPE(cfg->addrMode)); + CHECK_PARAM(IS_SF_CTRL_DMY_MODE_TYPE(cfg->dummyMode)); + CHECK_PARAM(IS_SF_CTRL_DATA_MODE_TYPE(cfg->dataMode)); + + timeOut = SF_CTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_1); + + if (BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_FN_SEL) != SF_CTRL_OWNER_IAHB) { + return; + } + + /* Copy command buffer */ + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_10, cfg->cmdBuf[0]); + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_11, cfg->cmdBuf[1]); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_9); + + /* Configure SPI and IO mode*/ + if (SF_CTRL_CMD_1_LINE == cfg->cmdMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_QPI_MODE_EN, SF_CTRL_SPI_MODE); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_QPI_MODE_EN, SF_CTRL_QPI_MODE); + } + + if (SF_CTRL_ADDR_1_LINE == cfg->addrMode) { + if (SF_CTRL_DATA_1_LINE == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_NIO_MODE); + } else if (SF_CTRL_DATA_2_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_DO_MODE); + } else if (SF_CTRL_DATA_4_LINES == cfg->dataMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_QO_MODE); + } + } else if (SF_CTRL_ADDR_2_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_DIO_MODE); + } else if (SF_CTRL_ADDR_4_LINES == cfg->addrMode) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_SPI_MODE, SF_CTRL_QIO_MODE); + } + + if (cmdValid) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_BYTE, 0); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_CMD_BYTE, 0); + } + + /* Configure address */ + if (cfg->addrSize != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_BYTE, cfg->addrSize - 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_ADR_BYTE, 0); + } + + /* configure dummy */ + if (cfg->dummyClks != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_EN, 1); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_BYTE, cfg->dummyClks - 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_EN, 0); + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DMY_BYTE, 0); + } + + /* Configure data */ + if (cfg->nbData != 0) { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_EN, 1); + } else { + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_EN, 0); + } + + /* Set read write flag */ + tmpVal = BL_SET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_1_DAT_RW, cfg->rwFlag); + + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IAHB_9, tmpVal); +} +#endif + +/****************************************************************************/ /** + * @brief Get SF Ctrl busy state + * + * @param None + * + * @return SET for SF ctrl busy or RESET for SF ctrl not busy + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Sts_Type ATTR_TCM_SECTION SF_Ctrl_GetBusyState(void) +{ + uint32_t tmpVal = 0; + uint32_t cmdOffset = 0; + + if (SF_Ctrl_Is_Sbus2_Enable() == RESET) { + cmdOffset = SF_CTRL_BASE + SF_CTRL_IF1_SAHB_OFFSET; + } else { + cmdOffset = SF_CTRL_BASE + SF_CTRL_IF2_SAHB_OFFSET; + } + + tmpVal = BL_RD_REG(cmdOffset, SF_CTRL_IF_SAHB_0); + + if (BL_IS_REG_BIT_SET(tmpVal, SF_CTRL_IF_BUSY)) { + return SET; + } + + return RESET; +} +#endif + +/****************************************************************************/ /** + * @brief SF Controller interrupt handler + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_HAL_DRIVER +void SF_Ctrl_IRQHandler(void) +{ + /* TODO: Not implemented */ +} +#endif + +/*@} end of group SF_CTRL_Public_Functions */ + +/*@} end of group SF_CTRL */ + +/*@} end of group BL808_Peripheral_Driver */ diff --git a/drivers/soc/bl808/bl808_std/src/bl808_sflash.c b/drivers/soc/bl808/bl808_std/src/bl808_sflash.c new file mode 100644 index 00000000..d6dfcb74 --- /dev/null +++ b/drivers/soc/bl808/bl808_std/src/bl808_sflash.c @@ -0,0 +1,2164 @@ +/** + ****************************************************************************** + * @file bl808_sflash.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "string.h" +#include "bl808_sflash.h" +#include "bl808_sf_ctrl.h" +#include "bl808_l1c.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup SFLASH + * @{ + */ + +/** @defgroup SFLASH_Private_Macros + * @{ + */ + +/*@} end of group SFLASH_Private_Macros */ + +/** @defgroup SFLASH_Private_Types + * @{ + */ + +/*@} end of group SFLASH_Private_Types */ + +/** @defgroup SFLASH_Private_Variables + * @{ + */ +#define SFCTRL_BUSY_STATE_TIMEOUT (5 * 320 * 1000) + +/*@} end of group SFLASH_Private_Variables */ + +/** @defgroup SFLASH_Global_Variables + * @{ + */ + +/*@} end of group SFLASH_Global_Variables */ + +/** @defgroup SFLASH_Private_Fun_Declaration + * @{ + */ + +/*@} end of group SFLASH_Private_Fun_Declaration */ + +/** @defgroup SFLASH_Private_Functions + * @{ + */ + +/*@} end of group SFLASH_Private_Functions */ + +/** @defgroup SFLASH_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Init serial flash control interface + * + * @param pSfCtrlCfg: Serial flash controller configuration pointer + * @param pBank2Cfg: Serial flash2 controller configuration pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_Init(const SF_Ctrl_Cfg_Type *pSfCtrlCfg, const SF_Ctrl_Bank2_Cfg *pBank2Cfg) +{ + uint8_t clkDelay = 0; + uint8_t rxClkInvert = 0; + + if (pBank2Cfg != NULL) { + if (pBank2Cfg->sbus2Select) { + if (pBank2Cfg->bank2DelaySrc) { + clkDelay = pBank2Cfg->bank2ClkDelay; + } else { + if (pSfCtrlCfg != NULL) { + clkDelay = pSfCtrlCfg->clkDelay; + } else { + clkDelay = 1; + } + } + + if (pBank2Cfg->bank2RxClkInvertSrc) { + rxClkInvert = pBank2Cfg->bank2RxClkInvertSel; + } else { + if (pSfCtrlCfg != NULL) { + rxClkInvert = pSfCtrlCfg->rxClkInvert; + } else { + rxClkInvert = 0; + } + } + + SF_Ctrl_Sbus2_Set_Delay(clkDelay, rxClkInvert); + } else { + SF_Ctrl_Sbus2_Revoke_replace(); + } + + SF_Ctrl_Bank2_Enable(pBank2Cfg); + } else { + SF_Ctrl_Sbus2_Revoke_replace(); + } + + if (pSfCtrlCfg != NULL) { + SF_Ctrl_Enable(pSfCtrlCfg); + } +} +#endif + +/****************************************************************************/ /** + * @brief Set serial flash control interface SPI or QPI mode + * + * @param mode: Serial flash interface mode + * + * @return BFLB_RET:SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_SetSPIMode(SF_Ctrl_Mode_Type mode) +{ + BL_Err_Type stat = SUCCESS; + + /* Check the parameters */ + CHECK_PARAM(IS_SF_CTRL_MODE_TYPE(mode)); + + return stat; +} +#endif + +/****************************************************************************/ /** + * @brief Read flash register + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param regIndex: register index + * @param regValue: register value pointer to store data + * @param regLen: register value length + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Read_Reg(SPI_Flash_Cfg_Type *flashCfg, uint8_t regIndex, uint8_t *regValue, uint8_t regLen) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint32_t cnt = 0; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (flashCfg->readRegCmd[regIndex]) << 24; + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.nbData = regLen; + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SF_Ctrl_GetBusyState()) { + arch_delay_us(1); + cnt++; + + if (cnt > 1000) { + return ERROR; + } + } + + ARCH_MemCpy(regValue, flashCtrlBuf, regLen); + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Write flash register + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param regIndex: register index + * @param regValue: register value pointer storing data + * @param regLen: register value length + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Write_Reg(SPI_Flash_Cfg_Type *flashCfg, uint8_t regIndex, uint8_t *regValue, uint8_t regLen) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t cnt = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + ARCH_MemCpy(flashCtrlBuf, regValue, regLen); + + flashCmd.cmdBuf[0] = (flashCfg->writeRegCmd[regIndex]) << 24; + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.nbData = regLen; + + SF_Ctrl_SendCmd(&flashCmd); + + /* take 40ms for tw(write status register) as default */ + while (SET == SFlash_Busy(flashCfg)) { + arch_delay_us(100); + cnt++; + + if (cnt > 400) { + return ERROR; + } + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Read flash register with read command + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param readRegCmd: read command + * @param regValue: register value pointer to store data + * @param regLen: register value length + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Read_Reg_With_Cmd(SPI_Flash_Cfg_Type *flashCfg, uint8_t readRegCmd, uint8_t *regValue, uint8_t regLen) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint32_t cnt = 0; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = readRegCmd << 24; + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.nbData = regLen; + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SF_Ctrl_GetBusyState()) { + arch_delay_us(1); + cnt++; + + if (cnt > 1000) { + return ERROR; + } + } + + ARCH_MemCpy(regValue, flashCtrlBuf, regLen); + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Write flash register with write command + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param writeRegCmd: write command + * @param regValue: register value pointer storing data + * @param regLen: register value length + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Write_Reg_With_Cmd(SPI_Flash_Cfg_Type *flashCfg, uint8_t writeRegCmd, uint8_t *regValue, uint8_t regLen) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t cnt = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + ARCH_MemCpy(flashCtrlBuf, regValue, regLen); + + flashCmd.cmdBuf[0] = writeRegCmd << 24; + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.nbData = regLen; + + SF_Ctrl_SendCmd(&flashCmd); + + /* take 40ms for tw(write status register) as default */ + while (SET == SFlash_Busy(flashCfg)) { + arch_delay_us(100); + cnt++; + + if (cnt > 400) { + return ERROR; + } + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Check flash busy status + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SET for busy or RESET for not busy + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Sts_Type ATTR_TCM_SECTION SFlash_Busy(SPI_Flash_Cfg_Type *flashCfg) +{ + uint32_t stat = 0; + SFlash_Read_Reg(flashCfg, flashCfg->busyIndex, (uint8_t *)&stat, flashCfg->busyReadRegLen); + + if ((stat & (1 << flashCfg->busyBit)) == 0) { + return RESET; + } + + return SET; +} +#endif + +/****************************************************************************/ /** + * @brief Enable flash write function + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Write_Enable(SPI_Flash_Cfg_Type *flashCfg) +{ + uint32_t stat = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + /* Write enable*/ + flashCmd.cmdBuf[0] = (flashCfg->writeEnableCmd) << 24; + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + SF_Ctrl_SendCmd(&flashCmd); + + SFlash_Read_Reg(flashCfg, flashCfg->wrEnableIndex, (uint8_t *)&stat, flashCfg->wrEnableReadRegLen); + + if ((stat & (1 << flashCfg->wrEnableBit)) != 0) { + return SUCCESS; + } + + return ERROR; +} +#endif + +/****************************************************************************/ /** + * @brief Enable flash flash controller QSPI interface + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Qspi_Enable(SPI_Flash_Cfg_Type *flashCfg) +{ + uint32_t stat = 0, ret; + + if (flashCfg->qeReadRegLen == 0) { + ret = SFlash_Write_Enable(flashCfg); + + if (SUCCESS != ret) { + return ERROR; + } + + SFlash_Write_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeWriteRegLen); + return SUCCESS; + } + + SFlash_Read_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeReadRegLen); + + if (flashCfg->qeData == 0) { + if ((stat & (1 << flashCfg->qeBit)) != 0) { + return SUCCESS; + } + } else { + if (((stat >> (flashCfg->qeBit & 0x08)) & 0xff) == flashCfg->qeData) { + return SUCCESS; + } + } + + if (flashCfg->qeWriteRegLen != 1) { + /* This is read r0,read r1 write r0,r1 case*/ + SFlash_Read_Reg(flashCfg, 0, (uint8_t *)&stat, 1); + SFlash_Read_Reg(flashCfg, 1, ((uint8_t *)&stat) + 1, 1); + + if (flashCfg->qeData == 0) { + stat |= (1 << (flashCfg->qeBit + 8 * flashCfg->qeIndex)); + } else { + stat = stat & (~(0xff << (8 * flashCfg->qeIndex))); + stat |= (flashCfg->qeData << (8 * flashCfg->qeIndex)); + } + } else { + if (flashCfg->qeData == 0) { + stat |= (1 << (flashCfg->qeBit % 8)); + } else { + stat = flashCfg->qeData; + } + } + + ret = SFlash_Write_Enable(flashCfg); + + if (SUCCESS != ret) { + return ERROR; + } + + SFlash_Write_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeWriteRegLen); + SFlash_Read_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeReadRegLen); + + if (flashCfg->qeData == 0) { + if ((stat & (1 << flashCfg->qeBit)) != 0) { + return SUCCESS; + } + } else { + if (((stat >> (flashCfg->qeBit & 0x08)) & 0xff) == flashCfg->qeData) { + return SUCCESS; + } + } + + return ERROR; +} +#endif + +/****************************************************************************/ /** + * @brief Disable flash flash controller QSPI interface + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Qspi_Disable(SPI_Flash_Cfg_Type *flashCfg) +{ + uint32_t stat = 0, ret; + + if (flashCfg->qeReadRegLen == 0) { + ret = SFlash_Write_Enable(flashCfg); + + if (SUCCESS != ret) { + return ERROR; + } + + SFlash_Write_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeWriteRegLen); + return SUCCESS; + } + + SFlash_Read_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeReadRegLen); + + if ((stat & (1 << flashCfg->qeBit)) == 0) { + return SUCCESS; + } + + if (flashCfg->qeWriteRegLen != 1) { + /* This is read r0,read r1 write r0,r1 case*/ + SFlash_Read_Reg(flashCfg, 0, (uint8_t *)&stat, 1); + SFlash_Read_Reg(flashCfg, 1, ((uint8_t *)&stat) + 1, 1); + stat &= (~(1 << (flashCfg->qeBit + 8 * flashCfg->qeIndex))); + } else { + stat &= (~(1 << (flashCfg->qeBit % 8))); + } + + ret = SFlash_Write_Enable(flashCfg); + + if (SUCCESS != ret) { + return ERROR; + } + + SFlash_Write_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeWriteRegLen); + SFlash_Read_Reg(flashCfg, flashCfg->qeIndex, (uint8_t *)&stat, flashCfg->qeReadRegLen); + + if ((stat & (1 << flashCfg->qeBit)) == 0) { + return SUCCESS; + } + + return ERROR; +} +#endif + +/****************************************************************************/ /** + * @brief Enable flash volatile register write enable + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_Volatile_Reg_Write_Enable(SPI_Flash_Cfg_Type *flashCfg) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (flashCfg->writeVregEnableCmd) << 24; + flashCmd.rwFlag = SF_CTRL_WRITE; + + SF_Ctrl_SendCmd(&flashCmd); +} +#endif + +/****************************************************************************/ /** + * @brief Erase flash whole chip + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Chip_Erase(SPI_Flash_Cfg_Type *flashCfg) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint32_t cnt = 0; + uint32_t timeout = 0; + BL_Err_Type stat = SFlash_Write_Enable(flashCfg); + + if (stat != SUCCESS) { + return stat; + } + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (flashCfg->chipEraseCmd) << 24; + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + + SF_Ctrl_SendCmd(&flashCmd); + + timeout = flashCfg->timeCe; + + if ((timeout >> 15) > 0) { + timeout = (timeout & 0x7FFF) * 1000; + } + + while (SET == SFlash_Busy(flashCfg)) { + arch_delay_us(500); + cnt++; + + if (cnt > timeout * 3) { + return ERROR; + } + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Erase flash one sector + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param secNum: flash sector number + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Sector_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t secNum) +{ + uint32_t cnt = 0; + uint8_t is32BitsAddr = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + BL_Err_Type stat = SFlash_Write_Enable(flashCfg); + + if (stat != SUCCESS) { + return stat; + } + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + is32BitsAddr = (flashCfg->ioMode & 0x20); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + if (is32BitsAddr > 0) { + flashCmd.addrSize++; + flashCmd.cmdBuf[0] = (flashCfg->sectorEraseCmd << 24) | ((flashCfg->sectorSize * 1024 * secNum) >> 8); + flashCmd.cmdBuf[1] = ((flashCfg->sectorSize * 1024 * secNum) << 24); + } else { + flashCmd.cmdBuf[0] = (flashCfg->sectorEraseCmd << 24) | (flashCfg->sectorSize * 1024 * secNum); + } + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SFlash_Busy(flashCfg)) { + arch_delay_us(500); + cnt++; + + if (cnt > flashCfg->timeEsector * 3) { + return ERROR; + } + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Erase flash one 32K block + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param blkNum: flash 32K block number + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Blk32_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t blkNum) +{ + uint32_t cnt = 0; + uint8_t is32BitsAddr = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + BL_Err_Type stat = SFlash_Write_Enable(flashCfg); + + if (stat != SUCCESS) { + return stat; + } + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + is32BitsAddr = (flashCfg->ioMode & 0x20); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + if (is32BitsAddr > 0) { + flashCmd.addrSize++; + flashCmd.cmdBuf[0] = (flashCfg->blk32EraseCmd << 24) | ((BFLB_SPIFLASH_BLK32K_SIZE * blkNum) >> 8); + flashCmd.cmdBuf[1] = ((BFLB_SPIFLASH_BLK32K_SIZE * blkNum) << 24); + } else { + flashCmd.cmdBuf[0] = (flashCfg->blk32EraseCmd << 24) | (BFLB_SPIFLASH_BLK32K_SIZE * blkNum); + } + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SFlash_Busy(flashCfg)) { + arch_delay_us(500); + cnt++; + + if (cnt > flashCfg->timeE32k * 3) { + return ERROR; + } + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Erase flash one 64K block + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param blkNum: flash 64K block number + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Blk64_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t blkNum) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint32_t cnt = 0; + uint8_t is32BitsAddr = 0; + BL_Err_Type stat = SFlash_Write_Enable(flashCfg); + + if (stat != SUCCESS) { + return stat; + } + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + is32BitsAddr = (flashCfg->ioMode & 0x20); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + if (is32BitsAddr > 0) { + flashCmd.addrSize++; + flashCmd.cmdBuf[0] = (flashCfg->blk64EraseCmd << 24) | ((BFLB_SPIFLASH_BLK64K_SIZE * blkNum) >> 8); + flashCmd.cmdBuf[1] = ((BFLB_SPIFLASH_BLK64K_SIZE * blkNum) << 24); + } else { + flashCmd.cmdBuf[0] = (flashCfg->blk64EraseCmd << 24) | (BFLB_SPIFLASH_BLK64K_SIZE * blkNum); + } + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SFlash_Busy(flashCfg)) { + arch_delay_us(500); + cnt++; + + if (cnt > flashCfg->timeE64k * 3) { + return ERROR; + } + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Erase flash one region + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param startaddr: start address to erase + * @param endaddr: end address(include this address) to erase + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Erase(SPI_Flash_Cfg_Type *flashCfg, uint32_t startaddr, uint32_t endaddr) +{ + uint32_t len = 0; + uint32_t eraseLen = 0; + BL_Err_Type ret = SUCCESS; + + if (startaddr > endaddr) { + return ERROR; + } + + while (startaddr <= endaddr) { + len = endaddr - startaddr + 1; + + if (flashCfg->blk64EraseCmd != BFLB_SPIFLASH_CMD_INVALID && + (startaddr & (BFLB_SPIFLASH_BLK64K_SIZE - 1)) == 0 && + len > (BFLB_SPIFLASH_BLK64K_SIZE - flashCfg->sectorSize * 1024)) { + /* 64K margin address,and length > 64K-sector size, erase one first */ + ret = SFlash_Blk64_Erase(flashCfg, startaddr / BFLB_SPIFLASH_BLK64K_SIZE); + eraseLen = BFLB_SPIFLASH_BLK64K_SIZE; + } else if (flashCfg->blk32EraseCmd != BFLB_SPIFLASH_CMD_INVALID && + (startaddr & (BFLB_SPIFLASH_BLK32K_SIZE - 1)) == 0 && + len > (BFLB_SPIFLASH_BLK32K_SIZE - flashCfg->sectorSize * 1024)) { + /* 32K margin address,and length > 32K-sector size, erase one first */ + ret = SFlash_Blk32_Erase(flashCfg, startaddr / BFLB_SPIFLASH_BLK32K_SIZE); + eraseLen = BFLB_SPIFLASH_BLK32K_SIZE; + } else { + /* Sector erase */ + startaddr = ((startaddr) & (~(flashCfg->sectorSize * 1024 - 1))); + ret = SFlash_Sector_Erase(flashCfg, startaddr / flashCfg->sectorSize / 1024); + eraseLen = flashCfg->sectorSize * 1024; + } + + startaddr += eraseLen; + + if (ret != SUCCESS) { + return ERROR; + } + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Get flash unique ID + * + * @param data: data pointer to store read data + * @param idLen: unique ID len + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_GetUniqueId(uint8_t *data, uint8_t idLen) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint8_t cmd, dummyClks; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + dummyClks = 4; + cmd = 0x4B; + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = idLen; + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + ARCH_MemCpy(data, flashCtrlBuf, idLen); +} +#endif + +/****************************************************************************/ /** + * @brief Get flash jedec ID + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param data: data pointer to store read data + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_GetJedecId(SPI_Flash_Cfg_Type *flashCfg, uint8_t *data) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint8_t cmd, dummyClks; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + dummyClks = flashCfg->jedecIdCmdDmyClk; + cmd = flashCfg->jedecIdCmd; + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = 3; + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + ARCH_MemCpy(data, flashCtrlBuf, 3); +} +#endif + +/****************************************************************************/ /** + * @brief Get flash device ID + * + * @param data: data pointer to store read data + * @param is32BitsAddr: Is flash addr mode in 32-bits + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_GetDeviceId(uint8_t *data, BL_Fun_Type is32BitsAddr) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint8_t cmd, dummyClks; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint32_t addr = 0x00000001; + uint8_t readMode = 0xFF; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.addrMode = SF_CTRL_ADDR_4_LINES; + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + dummyClks = 2; + cmd = 0x94; + flashCmd.addrSize = 4; + + if (is32BitsAddr) { + flashCmd.cmdBuf[0] = (cmd << 24) | (addr >> 8); + flashCmd.cmdBuf[1] = (addr << 24) | (readMode << 16); + flashCmd.addrSize++; + } else { + flashCmd.cmdBuf[0] = (cmd << 24) | (addr); + flashCmd.cmdBuf[1] = (readMode << 24); + } + + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = 2; + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } + + ARCH_MemCpy(data, flashCtrlBuf, 2); +} +#endif + +/****************************************************************************/ /** + * @brief Set flash power down + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_Powerdown(void) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint8_t cmd = 0; + uint32_t timeOut = 0; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + cmd = 0xB9; + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } +} +#endif + +/****************************************************************************/ /** + * @brief Release flash power down for wake up + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_Release_Powerdown(SPI_Flash_Cfg_Type *flashCfg) +{ + uint8_t cmd; + uint32_t timeOut = 0; + + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + cmd = flashCfg->releasePowerDown; + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return; + } + } +} +#endif + +/****************************************************************************/ /** + * @brief Sflash restore from power down + * + * @param pFlashCfg: Flash configuration pointer + * @param flashContRead: Whether enable continuous read + * @param bank: bank select type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Restore_From_Powerdown(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t flashContRead, + SF_Ctrl_Bank_Select bank) +{ + BL_Err_Type stat = SUCCESS; + uint32_t jdecId = 0; + uint8_t tmp[8]; + uint8_t ioMode = pFlashCfg->ioMode & 0xf; + + /* Wake flash up from power down */ + SFlash_Release_Powerdown(pFlashCfg); + arch_delay_us(120); + + SFlash_GetJedecId(pFlashCfg, (uint8_t *)&jdecId); + + if (SF_CTRL_QO_MODE == ioMode || SF_CTRL_QIO_MODE == ioMode) { + SFlash_Qspi_Enable(pFlashCfg); + } + + if (((pFlashCfg->ioMode >> 4) & 0x01) == 1) { + /* unwrap */ + L1C_Set_Wrap(DISABLE); + } else { + /* burst wrap */ + L1C_Set_Wrap(ENABLE); + /* For command that is setting register instead of send command, we need write enable */ + SFlash_Write_Enable(pFlashCfg); + SFlash_SetBurstWrap(pFlashCfg); + } + + if (flashContRead) { + stat = SFlash_Read(pFlashCfg, ioMode, 1, 0x00000000, (uint8_t *)tmp, sizeof(tmp)); + stat = SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32, bank); + } else { + stat = SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 0, 0, 32, bank); + } + + return stat; +} +#endif + +/****************************************************************************/ /** + * @brief Set flash burst wrap config + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_SetBurstWrap(SPI_Flash_Cfg_Type *flashCfg) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint8_t cmd, dummyClks; + uint32_t wrapData; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((flashCfg->ioMode >> 4) & 0x01) == 1) { + /* Disable burst wrap ,just return */ + return; + } + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.addrMode = (SF_Ctrl_Addr_Mode_Type)flashCfg->burstWrapDataMode; + flashCmd.dataMode = (SF_Ctrl_Data_Mode_Type)flashCfg->burstWrapDataMode; + dummyClks = flashCfg->burstWrapCmdDmyClk; + cmd = flashCfg->burstWrapCmd; + wrapData = flashCfg->burstWrapData; + ARCH_MemCpy4((uint32_t *)flashCtrlBuf, &wrapData, 4); + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = 1; + + SF_Ctrl_SendCmd(&flashCmd); +} +#endif + +/****************************************************************************/ /** + * @brief Disable flash burst wrap config + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_DisableBurstWrap(SPI_Flash_Cfg_Type *flashCfg) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint8_t cmd, dummyClks; + uint32_t wrapData; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.addrMode = (SF_Ctrl_Addr_Mode_Type)flashCfg->deBurstWrapDataMode; + flashCmd.dataMode = (SF_Ctrl_Data_Mode_Type)flashCfg->deBurstWrapDataMode; + dummyClks = flashCfg->deBurstWrapCmdDmyClk; + cmd = flashCfg->deBurstWrapCmd; + wrapData = flashCfg->deBurstWrapData; + ARCH_MemCpy4((uint32_t *)flashCtrlBuf, &wrapData, 4); + flashCmd.cmdBuf[0] = (cmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = 1; + + SF_Ctrl_SendCmd(&flashCmd); +} +#endif + +/****************************************************************************/ /** + * @brief Set flash 24-bits or 32-bits addr mode + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param en32BitsAddr: Serial flash enable or disable 32-bits addr + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Set32BitsAddrMode(SPI_Flash_Cfg_Type *flashCfg, BL_Fun_Type en32BitsAddr) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint8_t cmd = 0; + + if ((flashCfg->ioMode & 0x20) == 0) { + return ERROR; + } + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + SF_Ctrl_32bits_Addr_En(en32BitsAddr); + + if (en32BitsAddr) { + cmd = flashCfg->enter32BitsAddrCmd; + } else { + cmd = flashCfg->exit32BitsAddrCmd; + } + + flashCmd.cmdBuf[0] = (cmd << 24); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + + SF_Ctrl_SendCmd(&flashCmd); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Software reset flash + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Software_Reset(SPI_Flash_Cfg_Type *flashCfg) +{ + uint16_t cnt = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + /* Reset enable */ + flashCmd.cmdBuf[0] = (flashCfg->resetEnCmd) << 24; + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + + /* Wait for write done */ + while (SET == SFlash_Busy(flashCfg)) { + arch_delay_us(100); + cnt++; + + if (cnt > 20) { + return ERROR; + } + } + + SF_Ctrl_SendCmd(&flashCmd); + + /* Reset */ + flashCmd.cmdBuf[0] = (flashCfg->resetCmd) << 24; + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + SF_Ctrl_SendCmd(&flashCmd); + + arch_delay_us(50); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Reset flash continous read mode + * + * @param flashCfg: Serial flash parameter configuration pointer + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_Reset_Continue_Read(SPI_Flash_Cfg_Type *flashCfg) +{ + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + /* Reset continous read */ + ARCH_MemSet(&flashCmd.cmdBuf[0], flashCfg->resetCreadCmd, 4); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = flashCfg->resetCreadCmdSize; + SF_Ctrl_SendCmd(&flashCmd); +} +#endif + +/****************************************************************************/ /** + * @brief Set I/D bus read flash configuration in flash controller + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param ioMode: flash controller interface mode + * @param contRead: Wether enable cont read mode + * @param addr: address to read/write + * @param len: data length to read/write + * @param bank: bank select type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Set_IDbus_Cfg(SPI_Flash_Cfg_Type *flashCfg, SF_Ctrl_IO_Type ioMode, uint8_t contRead, + uint32_t addr, uint32_t len, SF_Ctrl_Bank_Select bank) +{ + uint8_t cmd, dummyClks; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint8_t cmdValid = 1; + uint8_t noReadModeCfg = 0; + uint8_t cReadSupport = 0; + uint8_t is32BitsAddr = 0; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + SF_Ctrl_Set_Owner(SF_CTRL_OWNER_IAHB); + + if (SF_CTRL_NIO_MODE == ioMode) { + cmd = flashCfg->fastReadCmd; + dummyClks = flashCfg->frDmyClk; + } else if (SF_CTRL_DO_MODE == ioMode) { + flashCmd.dataMode = SF_CTRL_DATA_2_LINES; + cmd = flashCfg->fastReadDoCmd; + dummyClks = flashCfg->frDoDmyClk; + } else if (SF_CTRL_DIO_MODE == ioMode) { + flashCmd.addrMode = SF_CTRL_ADDR_2_LINES; + flashCmd.dataMode = SF_CTRL_DATA_2_LINES; + cmd = flashCfg->fastReadDioCmd; + dummyClks = flashCfg->frDioDmyClk; + } else if (SF_CTRL_QO_MODE == ioMode) { + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + cmd = flashCfg->fastReadQoCmd; + dummyClks = flashCfg->frQoDmyClk; + } else if (SF_CTRL_QIO_MODE == ioMode) { + flashCmd.addrMode = SF_CTRL_ADDR_4_LINES; + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + cmd = flashCfg->fastReadQioCmd; + dummyClks = flashCfg->frQioDmyClk; + } else { + return ERROR; + } + + is32BitsAddr = (flashCfg->ioMode & 0x20); + /*prepare command**/ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + if (is32BitsAddr > 0) { + flashCmd.addrSize++; + flashCmd.cmdBuf[0] = (cmd << 24) | (addr >> 8); + flashCmd.cmdBuf[1] = (addr << 24); + } else { + flashCmd.cmdBuf[0] = (cmd << 24) | addr; + } + + if (SF_CTRL_QIO_MODE == ioMode || SF_CTRL_DIO_MODE == ioMode) { + noReadModeCfg = flashCfg->cReadSupport & 0x02; + cReadSupport = flashCfg->cReadSupport & 0x01; + + if (noReadModeCfg == 0) { + /* Read mode must be set*/ + if (cReadSupport == 0) { + /* Not support cont read,but we still need set read mode(winbond 80dv)*/ + if (is32BitsAddr > 0) { + flashCmd.cmdBuf[1] |= (flashCfg->cReadMode << 16); + } else { + flashCmd.cmdBuf[1] = (flashCfg->cReadMode << 24); + } + } else { + /* Flash support cont read, setting depend on user parameter */ + if (contRead) { + if (is32BitsAddr > 0) { + flashCmd.cmdBuf[0] = addr; + flashCmd.cmdBuf[1] = (flashCfg->cReadMode << 24); + } else { + flashCmd.cmdBuf[0] = (addr << 8) | flashCfg->cReadMode; + } + + cmdValid = 0; + } else { + if (is32BitsAddr > 0) { + flashCmd.cmdBuf[1] |= ((!flashCfg->cReadMode) << 16); + } else { + flashCmd.cmdBuf[1] = ((!flashCfg->cReadMode) << 24); + } + } + } + + flashCmd.addrSize++; + } + } + + flashCmd.dummyClks = dummyClks; + flashCmd.nbData = len; + if (bank == SF_CTRL_FLASH_BANK0) { + SF_Ctrl_Flash_Read_Icache_Set(&flashCmd, cmdValid); + } else { + SF_Ctrl_Flash2_Read_Icache_Set(&flashCmd, cmdValid); + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Enable I/D bus read from flash + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param ioMode: flash controller interface mode + * @param contRead: Wether enable cont read mode + * @param bank: bank select type + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_IDbus_Read_Enable(SPI_Flash_Cfg_Type *flashCfg, SF_Ctrl_IO_Type ioMode, + uint8_t contRead, SF_Ctrl_Bank_Select bank) +{ + BL_Err_Type stat; + + stat = SFlash_Set_IDbus_Cfg(flashCfg, ioMode, contRead, 0, 32, bank); + + if (SUCCESS != stat) { + return stat; + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Disable read from flash with IDbus + * + * @param None + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +void ATTR_TCM_SECTION SFlash_IDbus_Read_Disable(void) +{ + //L1C_Cache_Read_Disable(); +} +#endif + +/****************************************************************************/ /** + * @brief Sflash enable RCV mode to recovery for erase while power drop + * + * @param pFlashCfg: Flash configuration pointer + * @param rCmd: Read RCV register cmd + * @param wCmd: Write RCV register cmd + * @param bitPos: RCV register bit pos + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_RCV_Enable(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t rCmd, uint8_t wCmd, uint8_t bitPos) +{ + BL_Err_Type stat; + uint32_t cnt = 0; + uint32_t tempVal = 0; + + while (SET == SFlash_Busy(pFlashCfg)) { + arch_delay_us(500); + cnt++; + + if (cnt > 20000 * 3) { + return ERROR; + } + } + + stat = SFlash_Read_Reg_With_Cmd(pFlashCfg, rCmd, (uint8_t *)&tempVal, 1); + + if (SUCCESS != stat) { + stat = ERROR; + } + + if (((tempVal >> bitPos) & 0x01) > 0) { + return SUCCESS; + } + + tempVal |= (uint32_t)(1 << bitPos); + stat = SFlash_Write_Enable(pFlashCfg); + + if (SUCCESS != stat) { + stat = ERROR; + } + + stat = SFlash_Write_Reg_With_Cmd(pFlashCfg, wCmd, (uint8_t *)&tempVal, 1); + + if (SUCCESS != stat) { + return stat; + } + + while (SET == SFlash_Busy(pFlashCfg)) { + arch_delay_us(500); + cnt++; + + if (cnt > 20000 * 3) { + return ERROR; + } + } + + stat = SFlash_Read_Reg_With_Cmd(pFlashCfg, rCmd, (uint8_t *)&tempVal, 1); + + if (SUCCESS != stat) { + stat = ERROR; + } + + if (((tempVal >> bitPos) & 0x01) <= 0) { + return ERROR; + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Erase flash security register one block + * + * @param pFlashCfg: Flash configuration pointer + * @param pSecRegCfg: Security register configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_Erase_Security_Register(SPI_Flash_Cfg_Type *pFlashCfg, SFlash_Sec_Reg_Cfg *pSecRegCfg) +{ + uint32_t cnt = 0; + uint8_t cmd = 0; + uint8_t secOptMode = 0; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (pSecRegCfg->enterSecOptCmd != 0x00) { + secOptMode = 1; + + if (((uint32_t)(uintptr_t)&flashCmd) % 4 == 0) { + arch_memset4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + arch_memset(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->enterSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + BL_Err_Type stat = SFlash_Write_Enable(pFlashCfg); + + if (stat != SUCCESS) { + return stat; + } + + if (((uint32_t)(uintptr_t)&flashCmd) % 4 == 0) { + arch_memset4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + arch_memset(&flashCmd, 0, sizeof(flashCmd)); + } + + cmd = pSecRegCfg->eraseCmd; + flashCmd.cmdBuf[0] = (cmd << 24) | (pSecRegCfg->blockNum << 12); + /* rwFlag don't care */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + SF_Ctrl_SendCmd(&flashCmd); + + while (SET == SFlash_Busy(pFlashCfg)) { + arch_delay_us(500); + cnt++; + + if (cnt > pFlashCfg->timeEsector * 3) { + return ERROR; + } + } + + if (secOptMode > 0) { + if (((uint32_t)(uintptr_t)&flashCmd) % 4 == 0) { + arch_memset4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + arch_memset(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->exitSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Program flash security register one block + * + * @param pFlashCfg: Flash configuration pointer + * @param pSecRegCfg: Security register configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_Program_Security_Register(SPI_Flash_Cfg_Type *pFlashCfg, SFlash_Sec_Reg_Cfg *pSecRegCfg) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t i = 0, curLen = 0; + uint32_t cnt = 0; + BL_Err_Type stat; + uint8_t cmd; + uint8_t secOptMode = 0; + uint8_t *data = pSecRegCfg->data; + uint32_t addr = pSecRegCfg->addr; + uint32_t len = pSecRegCfg->len; + uint32_t currentAddr = 0; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (pSecRegCfg->enterSecOptCmd != 0x00) { + secOptMode = 1; + + if (((uint32_t)(uintptr_t)&flashCmd) % 4 == 0) { + arch_memset4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + arch_memset(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->enterSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + if (((uint32_t)(uintptr_t)&flashCmd) % 4 == 0) { + arch_memset4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + arch_memset(&flashCmd, 0, sizeof(flashCmd)); + } + + /* Prepare command */ + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.addrSize = 3; + cmd = pSecRegCfg->programCmd; + + for (i = 0; i < len;) { + /* Write enable is needed for every program */ + stat = SFlash_Write_Enable(pFlashCfg); + + if (stat != SUCCESS) { + return stat; + } + + /* Get current programmed length within page size */ + curLen = 256 - addr % 256; + + if (curLen > len - i) { + curLen = len - i; + } + + currentAddr = (pSecRegCfg->blockNum << 12) | addr; + + /* Prepare command */ + arch_memcpy_fast(flashCtrlBuf, data, curLen); + flashCmd.cmdBuf[0] = (cmd << 24) | (currentAddr); + flashCmd.nbData = curLen; + + SF_Ctrl_SendCmd(&flashCmd); + + /* Adjust address and programmed length */ + addr += curLen; + i += curLen; + data += curLen; + + /* Wait for write done */ + cnt = 0; + + while (SET == SFlash_Busy(pFlashCfg)) { + arch_delay_us(100); + cnt++; + + if (cnt > pFlashCfg->timePagePgm * 20) { + return ERROR; + } + } + } + + if (secOptMode > 0) { + if (((uint32_t)(uintptr_t)&flashCmd) % 4 == 0) { + arch_memset4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + arch_memset(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->exitSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Read data from flash security register one block + * + * @param pSecRegCfg: Security register configuration pointer + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +BL_Err_Type ATTR_TCM_SECTION SFlash_Read_Security_Register(SFlash_Sec_Reg_Cfg *pSecRegCfg) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t curLen, i; + uint8_t cmd; + uint8_t secOptMode = 0; + uint8_t *data = pSecRegCfg->data; + uint32_t addr = pSecRegCfg->addr; + uint32_t len = pSecRegCfg->len; + uint32_t currentAddr = 0; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (pSecRegCfg->enterSecOptCmd != 0x00) { + secOptMode = 1; + + if (((uint32_t)(uintptr_t)&flashCmd) % 4 == 0) { + arch_memset4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + arch_memset(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->enterSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + if (((uint32_t)(uintptr_t)&flashCmd) % 4 == 0) { + arch_memset4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + arch_memset(&flashCmd, 0, sizeof(flashCmd)); + } + + /* Prepare command */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + flashCmd.dummyClks = 1; + cmd = pSecRegCfg->readCmd; + + /* Read data */ + for (i = 0; i < len;) { + currentAddr = (pSecRegCfg->blockNum << 12) | addr; + /* Prepare command */ + flashCmd.cmdBuf[0] = (cmd << 24) | (currentAddr); + curLen = len - i; + + if (curLen >= NOR_FLASH_CTRL_BUF_SIZE) { + curLen = NOR_FLASH_CTRL_BUF_SIZE; + flashCmd.nbData = curLen; + } else { + /* Make sf_ctrl word read */ + flashCmd.nbData = ((curLen + 3) >> 2) << 2; + } + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + + arch_memcpy_fast(data, flashCtrlBuf, curLen); + + addr += curLen; + i += curLen; + data += curLen; + } + + if (secOptMode > 0) { + if (((uint32_t)(uintptr_t)&flashCmd) % 4 == 0) { + arch_memset4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + arch_memset(&flashCmd, 0, sizeof(flashCmd)); + } + + flashCmd.cmdBuf[0] = (pSecRegCfg->exitSecOptCmd << 24); + flashCmd.rwFlag = SF_CTRL_WRITE; + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + } + + return SUCCESS; +} + +/****************************************************************************/ /** + * @brief Read data from flash + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param ioMode: flash controller interface mode + * @param contRead: Wether enable cont read mode + * @param addr: flash read start address + * @param data: data pointer to store data read from flash + * @param len: data length to read + * + * @return None + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Read(SPI_Flash_Cfg_Type *flashCfg, + SF_Ctrl_IO_Type ioMode, uint8_t contRead, uint32_t addr, uint8_t *data, uint32_t len) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t curLen, i; + uint8_t cmd, dummyClks; + uint32_t timeOut = 0; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + uint8_t noReadModeCfg = 0; + uint8_t cReadSupport = 0; + uint8_t is32BitsAddr = 0; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + if (SF_CTRL_NIO_MODE == ioMode) { + cmd = flashCfg->fastReadCmd; + dummyClks = flashCfg->frDmyClk; + } else if (SF_CTRL_DO_MODE == ioMode) { + flashCmd.dataMode = SF_CTRL_DATA_2_LINES; + cmd = flashCfg->fastReadDoCmd; + dummyClks = flashCfg->frDoDmyClk; + } else if (SF_CTRL_DIO_MODE == ioMode) { + flashCmd.addrMode = SF_CTRL_ADDR_2_LINES; + flashCmd.dataMode = SF_CTRL_DATA_2_LINES; + cmd = flashCfg->fastReadDioCmd; + dummyClks = flashCfg->frDioDmyClk; + } else if (SF_CTRL_QO_MODE == ioMode) { + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + cmd = flashCfg->fastReadQoCmd; + dummyClks = flashCfg->frQoDmyClk; + } else if (SF_CTRL_QIO_MODE == ioMode) { + flashCmd.addrMode = SF_CTRL_ADDR_4_LINES; + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + cmd = flashCfg->fastReadQioCmd; + dummyClks = flashCfg->frQioDmyClk; + } else { + return ERROR; + } + + is32BitsAddr = (flashCfg->ioMode & 0x20); + /* Prepare command */ + flashCmd.rwFlag = SF_CTRL_READ; + flashCmd.addrSize = 3; + + if (is32BitsAddr > 0) { + flashCmd.addrSize++; + } + + if (SF_CTRL_QIO_MODE == ioMode || SF_CTRL_DIO_MODE == ioMode) { + noReadModeCfg = flashCfg->cReadSupport & 0x02; + cReadSupport = flashCfg->cReadSupport & 0x01; + + if (noReadModeCfg == 0) { + /* Read mode must be set*/ + if (cReadSupport == 0) { + /* Not support cont read,but we still need set read mode(winbond 80dv)*/ + if (is32BitsAddr > 0) { + flashCmd.cmdBuf[1] |= (flashCfg->cReadMode << 16); + } else { + flashCmd.cmdBuf[1] = (flashCfg->cReadMode << 24); + } + } else { + /* Flash support cont read, setting depend on user parameter */ + if (contRead) { + if (is32BitsAddr > 0) { + flashCmd.cmdBuf[1] |= (flashCfg->cReadMode << 16); + } else { + flashCmd.cmdBuf[1] = (flashCfg->cReadMode << 24); + } + } else { + if (is32BitsAddr > 0) { + flashCmd.cmdBuf[1] |= ((!flashCfg->cReadMode) << 16); + } else { + flashCmd.cmdBuf[1] = ((!flashCfg->cReadMode) << 24); + } + } + } + + flashCmd.addrSize++; + } + } + + flashCmd.dummyClks = dummyClks; + + /* Read data */ + for (i = 0; i < len;) { + /* Prepare command */ + if (is32BitsAddr > 0) { + flashCmd.cmdBuf[0] = (cmd << 24) | (addr >> 8); + flashCmd.cmdBuf[1] |= (addr << 24); + } else { + flashCmd.cmdBuf[0] = (cmd << 24) | (addr); + } + + curLen = len - i; + + if (curLen >= NOR_FLASH_CTRL_BUF_SIZE) { + curLen = NOR_FLASH_CTRL_BUF_SIZE; + flashCmd.nbData = curLen; + } else { + /* Make sf_ctrl word read */ + flashCmd.nbData = ((curLen + 3) >> 2) << 2; + } + + SF_Ctrl_SendCmd(&flashCmd); + + timeOut = SFCTRL_BUSY_STATE_TIMEOUT; + + while (SET == SF_Ctrl_GetBusyState()) { + timeOut--; + + if (timeOut == 0) { + return TIMEOUT; + } + } + + ARCH_MemCpy_Fast(data, flashCtrlBuf, curLen); + + addr += curLen; + i += curLen; + data += curLen; + } + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Program flash one region + * + * @param flashCfg: Serial flash parameter configuration pointer + * @param ioMode: progran mode:SPI mode or QPI mode + * @param addr: start address to be programed + * @param data: data pointer to be programed + * @param len: data length to be programed + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION SFlash_Program(SPI_Flash_Cfg_Type *flashCfg, + SF_Ctrl_IO_Type ioMode, uint32_t addr, uint8_t *data, uint32_t len) +{ + uint8_t *const flashCtrlBuf = (uint8_t *)SF_CTRL_BUF_BASE; + uint32_t i = 0, curLen = 0; + uint32_t cnt = 0; + uint8_t is32BitsAddr = 0; + BL_Err_Type stat; + uint8_t cmd; + SF_Ctrl_Cmd_Cfg_Type flashCmd; + + if (((uintptr_t)&flashCmd) % 4 == 0) { + ARCH_MemSet4((uint32_t *)&flashCmd, 0, sizeof(flashCmd) / 4); + } else { + ARCH_MemSet(&flashCmd, 0, sizeof(flashCmd)); + } + + if (SF_CTRL_NIO_MODE == ioMode || SF_CTRL_DO_MODE == ioMode || SF_CTRL_DIO_MODE == ioMode) { + cmd = flashCfg->pageProgramCmd; + } else if (SF_CTRL_QIO_MODE == ioMode || SF_CTRL_QO_MODE == ioMode) { + flashCmd.addrMode = (SF_Ctrl_Addr_Mode_Type)flashCfg->qppAddrMode; + flashCmd.dataMode = SF_CTRL_DATA_4_LINES; + cmd = flashCfg->qpageProgramCmd; + } else { + return ERROR; + } + + is32BitsAddr = (flashCfg->ioMode & 0x20); + /* Prepare command */ + flashCmd.rwFlag = SF_CTRL_WRITE; + flashCmd.addrSize = 3; + + if (is32BitsAddr > 0) { + flashCmd.addrSize++; + } + + for (i = 0; i < len;) { + /* Write enable is needed for every program */ + stat = SFlash_Write_Enable(flashCfg); + + if (stat != SUCCESS) { + return stat; + } + + /* Get current programmed length within page size */ + curLen = flashCfg->pageSize - addr % flashCfg->pageSize; + + if (curLen > len - i) { + curLen = len - i; + } + + /* Prepare command */ + ARCH_MemCpy_Fast(flashCtrlBuf, data, curLen); + + if (is32BitsAddr > 0) { + flashCmd.cmdBuf[0] = (cmd << 24) | (addr >> 8); + flashCmd.cmdBuf[1] = (addr << 24); + } else { + flashCmd.cmdBuf[0] = (cmd << 24) | (addr); + } + + flashCmd.nbData = curLen; + + SF_Ctrl_SendCmd(&flashCmd); + + /* Adjust address and programmed length */ + addr += curLen; + i += curLen; + data += curLen; + + /* Wait for write done */ + cnt = 0; + + while (SET == SFlash_Busy(flashCfg)) { + arch_delay_us(100); + cnt++; + + if (cnt > flashCfg->timePagePgm * 20) { + return ERROR; + } + } + } + + return SUCCESS; +} +#endif + +/*@} end of group SFLASH_Public_Functions */ + +/*@} end of group SFLASH */ + +/*@} end of group BL808_Peripheral_Driver */ diff --git a/drivers/soc/bl808/bl808_std/src/bl808_xip_sflash.c b/drivers/soc/bl808/bl808_std/src/bl808_xip_sflash.c new file mode 100644 index 00000000..b6c7b11c --- /dev/null +++ b/drivers/soc/bl808/bl808_std/src/bl808_xip_sflash.c @@ -0,0 +1,469 @@ +/** + ****************************************************************************** + * @file bl808_xip_sflash.c + * @version V1.0 + * @date + * @brief This file is the standard driver c file + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2020 Bouffalo Lab

+ * + * 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 Bouffalo Lab 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. + * + ****************************************************************************** + */ + +#include "string.h" +#include "bl808_xip_sflash.h" + +/** @addtogroup BL808_Peripheral_Driver + * @{ + */ + +/** @addtogroup XIP_SFLASH + * @{ + */ + +/** @defgroup XIP_SFLASH_Private_Macros + * @{ + */ + +/*@} end of group XIP_SFLASH_Private_Macros */ + +/** @defgroup XIP_SFLASH_Private_Types + * @{ + */ + +/*@} end of group XIP_SFLASH_Private_Types */ + +/** @defgroup XIP_SFLASH_Private_Variables + * @{ + */ + +/*@} end of group XIP_SFLASH_Private_Variables */ + +/** @defgroup XIP_SFLASH_Global_Variables + * @{ + */ + +/*@} end of group XIP_SFLASH_Global_Variables */ + +/** @defgroup XIP_SFLASH_Private_Fun_Declaration + * @{ + */ + +/*@} end of group XIP_SFLASH_Private_Fun_Declaration */ + +/** @defgroup XIP_SFLASH_Private_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Save flash controller state + * + * @param pFlashCfg: Flash config pointer + * @param offset: CPU XIP flash offset pointer + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_State_Save(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t *offset, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + /* XIP_SFlash_Delay */ + volatile uint32_t i = 32 * 2; + + while (i--) + ; + + if (bank == SF_CTRL_FLASH_BANK1) { + SF_Ctrl_Sbus2_Replace(SF_CTRL_PAD2); + } + SF_Ctrl_Set_Owner(SF_CTRL_OWNER_SAHB); + /* Exit form continous read for accepting command */ + SFlash_Reset_Continue_Read(pFlashCfg); + /* For disable command that is setting register instaed of send command, we need write enable */ + SFlash_DisableBurstWrap(pFlashCfg); + /* Enable 32Bits addr mode again in case reset command make it reset */ + SFlash_Set32BitsAddrMode(pFlashCfg, ENABLE); + if ((pFlashCfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (pFlashCfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + /* Enable QE again in case reset command make it reset */ + SFlash_Qspi_Enable(pFlashCfg); + } + /* Deburst again to make sure */ + SFlash_DisableBurstWrap(pFlashCfg); + + /* Clear offset setting*/ + *offset = SF_Ctrl_Get_Flash_Image_Offset(group, bank); + SF_Ctrl_Set_Flash_Image_Offset(0, group, bank); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Restore flash controller state + * + * @param pFlashCfg: Flash config pointer + * @param offset: CPU XIP flash offset + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_State_Restore(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t offset, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + uint32_t tmp[1]; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + SF_Ctrl_Set_Flash_Image_Offset(offset, group, bank); + + if(((pFlashCfg->ioMode>>4)&0x01) == 0) { + if((pFlashCfg->ioMode&0x0f)==SF_CTRL_QO_MODE || (pFlashCfg->ioMode&0x0f)==SF_CTRL_QIO_MODE) { + SFlash_SetBurstWrap(pFlashCfg); + } + } + SFlash_Set32BitsAddrMode(pFlashCfg, ENABLE); + SFlash_Read(pFlashCfg, ioMode, 1, 0x0, (uint8_t *)tmp, sizeof(tmp)); + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32, bank); + if (bank == SF_CTRL_FLASH_BANK1) { + SF_Ctrl_Sbus2_Revoke_replace(); + } + + return SUCCESS; +} +#endif + +/*@} end of group XIP_SFLASH_Private_Functions */ + +/** @defgroup XIP_SFLASH_Public_Functions + * @{ + */ + +/****************************************************************************/ /** + * @brief Erase flash one region + * + * @param pFlashCfg: Flash config pointer + * @param startaddr: start address to erase + * @param len: data length to erase + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Erase_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t startaddr, int len, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + BL_Err_Type stat; + uint32_t offset; + uint8_t aesEnable = 0; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + XIP_SFlash_Opt_Enter(&aesEnable); + stat = XIP_SFlash_State_Save(pFlashCfg, &offset, group, bank); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32, bank); + } else { + stat = SFlash_Erase(pFlashCfg, startaddr, startaddr + len - 1); + XIP_SFlash_State_Restore(pFlashCfg, offset, group, bank); + } + + XIP_SFlash_Opt_Exit(aesEnable); + + return stat; +} +#endif + +/****************************************************************************/ /** + * @brief Program flash one region + * + * @param pFlashCfg: Flash config pointer + * @param addr: start address to be programed + * @param data: data pointer to be programed + * @param len: data length to be programed + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Write_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t addr, uint8_t *data, uint32_t len, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + BL_Err_Type stat; + uint32_t offset; + uint8_t aesEnable = 0; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + XIP_SFlash_Opt_Enter(&aesEnable); + stat = XIP_SFlash_State_Save(pFlashCfg, &offset, group, bank); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32, bank); + } else { + stat = SFlash_Program(pFlashCfg, ioMode, addr, data, len); + XIP_SFlash_State_Restore(pFlashCfg, offset, group, bank); + } + + XIP_SFlash_Opt_Exit(aesEnable); + + return stat; +} +#endif + +/****************************************************************************/ /** + * @brief Read data from flash + * + * @param pFlashCfg: Flash config pointer + * @param addr: flash read start address + * @param data: data pointer to store data read from flash + * @param len: data length to read + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Read_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint32_t addr, uint8_t *data, uint32_t len, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + BL_Err_Type stat; + uint32_t offset; + uint8_t aesEnable = 0; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + XIP_SFlash_Opt_Enter(&aesEnable); + stat = XIP_SFlash_State_Save(pFlashCfg, &offset, group, bank); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32, bank); + } else { + stat = SFlash_Read(pFlashCfg, ioMode, 0, addr, data, len); + XIP_SFlash_State_Restore(pFlashCfg, offset, group, bank); + } + + XIP_SFlash_Opt_Exit(aesEnable); + + return stat; +} +#endif + +/****************************************************************************/ /** + * @brief Get Flash Jedec ID + * + * @param pFlashCfg: Flash config pointer + * @param data: data pointer to store Jedec ID Read from flash + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_GetJedecId_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t *data, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + BL_Err_Type stat; + uint32_t offset; + uint8_t aesEnable = 0; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + XIP_SFlash_Opt_Enter(&aesEnable); + stat = XIP_SFlash_State_Save(pFlashCfg, &offset, group, bank); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32, bank); + } else { + SFlash_GetJedecId(pFlashCfg, data); + XIP_SFlash_State_Restore(pFlashCfg, offset, group, bank); + } + + XIP_SFlash_Opt_Exit(aesEnable); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Get Flash Device ID + * + * @param pFlashCfg: Flash config pointer + * @param is32BitsAddr: Is flash addr mode in 32-bits + * @param data: data pointer to store Device ID Read from flash + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_GetDeviceId_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, BL_Fun_Type is32BitsAddr, uint8_t *data, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + BL_Err_Type stat; + uint32_t offset; + uint8_t aesEnable = 0; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + XIP_SFlash_Opt_Enter(&aesEnable); + stat = XIP_SFlash_State_Save(pFlashCfg, &offset, group, bank); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32, bank); + } else { + SFlash_GetDeviceId(data, is32BitsAddr); + XIP_SFlash_State_Restore(pFlashCfg, offset, group, bank); + } + + XIP_SFlash_Opt_Exit(aesEnable); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Get Flash Unique ID + * + * @param pFlashCfg: Flash config pointer + * @param data: data pointer to store Device ID Read from flash + * @param idLen: Unique id len + * @param group: CPU group id 0 or 1 + * @param bank: Flash bank select + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_GetUniqueId_Need_Lock(SPI_Flash_Cfg_Type *pFlashCfg, uint8_t *data, uint8_t idLen, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + BL_Err_Type stat; + uint32_t offset; + uint8_t aesEnable = 0; + SF_Ctrl_IO_Type ioMode = (SF_Ctrl_IO_Type)pFlashCfg->ioMode & 0xf; + + XIP_SFlash_Opt_Enter(&aesEnable); + stat = XIP_SFlash_State_Save(pFlashCfg, &offset, group, bank); + + if (stat != SUCCESS) { + SFlash_Set_IDbus_Cfg(pFlashCfg, ioMode, 1, 0, 32, bank); + } else { + SFlash_GetUniqueId(data, idLen); + XIP_SFlash_State_Restore(pFlashCfg, offset, group, bank); + } + + XIP_SFlash_Opt_Exit(aesEnable); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief Read data from flash via XIP + * + * @param addr: flash read start address + * @param data: data pointer to store data read from flash + * @param len: data length to read + * + * @return SUCCESS or ERROR + * +*******************************************************************************/ +#ifndef BFLB_USE_ROM_DRIVER +__WEAK +BL_Err_Type ATTR_TCM_SECTION XIP_SFlash_Read_Via_Cache_Need_Lock(uint32_t addr, uint8_t *data, uint32_t len, + uint8_t group, SF_Ctrl_Bank_Select bank) +{ + uint32_t offset; + + addr = addr & (BL808_FLASH_XIP_END-BL808_FLASH_XIP_BASE-1); + addr |= BL808_FLASH_XIP_BASE; + + offset = SF_Ctrl_Get_Flash_Image_Offset(group, bank); + SF_Ctrl_Set_Flash_Image_Offset(0, group, bank); + /* Flash read */ + ARCH_MemCpy_Fast(data, (void *)(uintptr_t)(addr), len); + SF_Ctrl_Set_Flash_Image_Offset(offset, group, bank); + + return SUCCESS; +} +#endif + +/****************************************************************************/ /** + * @brief XIP SFlash option save + * + * @param aesEnable: AES enable status pointer + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION XIP_SFlash_Opt_Enter(uint8_t *aesEnable) +{ + *aesEnable = SF_Ctrl_Is_AES_Enable(); + + if (*aesEnable) { + SF_Ctrl_AES_Disable(); + } +} + +/****************************************************************************/ /** + * @brief XIP SFlash option restore + * + * @param aesEnable: AES enable status + * + * @return None + * +*******************************************************************************/ +__WEAK +void ATTR_TCM_SECTION XIP_SFlash_Opt_Exit(uint8_t aesEnable) +{ + if (aesEnable) { + SF_Ctrl_AES_Enable(); + } +} + +/*@} end of group XIP_SFLASH_Public_Functions */ + +/*@} end of group XIP_SFLASH */ + +/*@} end of group BL808_Peripheral_Driver */ diff --git a/drivers/soc/bl808/port/bl808_efuse.c b/drivers/soc/bl808/port/bl808_efuse.c new file mode 100644 index 00000000..18c782c2 --- /dev/null +++ b/drivers/soc/bl808/port/bl808_efuse.c @@ -0,0 +1,53 @@ +#include "bflb_efuse.h" +#include "bl808_ef_ctrl.h" + +float bflb_efuse_get_adc_trim(void) +{ + Efuse_ADC_Gain_Coeff_Type trim; + uint32_t tmp; + + float coe = 1.0; + + EF_Ctrl_Read_ADC_Gain_Trim(&trim); + + if (trim.adcGainCoeffEn) { + if (trim.adcGainCoeffParity == EF_Ctrl_Get_Trim_Parity(trim.adcGainCoeff, 12)) { + tmp = trim.adcGainCoeff; + + if (tmp & 0x800) { + tmp = ~tmp; + tmp += 1; + tmp = tmp & 0xfff; + coe = (1.0 + ((float)tmp / 2048.0)); + } else { + coe = (1.0 - ((float)tmp / 2048.0)); + } + } + } + + return coe; +} + +uint32_t bflb_efuse_get_adc_tsen_trim(void) +{ + Efuse_TSEN_Refcode_Corner_Type trim; + + EF_Ctrl_Read_TSEN_Trim(&trim); + if (trim.tsenRefcodeCornerEn) { + if (trim.tsenRefcodeCornerParity == EF_Ctrl_Get_Trim_Parity(trim.tsenRefcodeCorner, 12)) { + return trim.tsenRefcodeCorner; + } + } + + return 2042; +} + +void bflb_efuse_write_aes_key(uint8_t index, uint8_t *data, uint32_t len) +{ + EF_Ctrl_Write_AES_Key(index, (uint32_t *)data, len, 1); +} + +void bflb_efuse_read_aes_key(uint8_t index, uint8_t *data, uint32_t len) +{ + EF_Ctrl_Read_AES_Key(index, (uint32_t *)data, len); +} \ No newline at end of file diff --git a/drivers/soc/bl808/port/bl808_flash.c b/drivers/soc/bl808/port/bl808_flash.c new file mode 100644 index 00000000..f90417f3 --- /dev/null +++ b/drivers/soc/bl808/port/bl808_flash.c @@ -0,0 +1,243 @@ +#include "bl808_glb.h" +#include "bl808_xip_sflash.h" +#include "bl808_sf_cfg.h" +#include "bflb_flash.h" + +static uint32_t g_jedec_id = 0; +static SPI_Flash_Cfg_Type g_flash_cfg; + +/** + * @brief flash_get_clock_delay + * + * @return int + */ +static int flash_get_clock_delay(SPI_Flash_Cfg_Type *cfg) +{ + uint32_t tmpVal = 0; + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_0); + /* bit0-3 for clk delay */ + if (BL_IS_REG_BIT_SET(tmpVal, SF_CTRL_SF_IF_READ_DLY_EN)) { + cfg->clkDelay = BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_IF_READ_DLY_N) + 1; + } else { + cfg->clkDelay = 0; + } + cfg->clkInvert = 0; + /* bit0 for clk invert */ + cfg->clkInvert |= ((BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_OUT_INV_SEL) & 1) << 0); + /* bit1 for rx clk invert */ + cfg->clkInvert |= ((BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_SF_CLK_SF_RX_INV_SEL) & 1) << 1); + + tmpVal = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_IF_IO_DLY_1); + /* bit4-6 for do delay */ + cfg->clkDelay |= ((BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_0_DO_DLY_SEL) & 7) << 4); + /* bit2-4 for di delay */ + cfg->clkInvert |= ((BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_0_DI_DLY_SEL) & 7) << 2); + /* bit5-7 for oe delay */ + cfg->clkInvert |= ((BL_GET_REG_BITS_VAL(tmpVal, SF_CTRL_IO_0_OE_DLY_SEL) & 7) << 5); + + return 0; +} + +/** + * @brief flash_set_qspi_enable + * + * @return int + */ +static int ATTR_TCM_SECTION flash_set_qspi_enable(SPI_Flash_Cfg_Type *p_flash_cfg) +{ + if ((p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + SFlash_Qspi_Enable(p_flash_cfg); + } + + return 0; +} + +/** + * @brief flash_set_l1c_wrap + * + * @return int + */ +static int ATTR_TCM_SECTION flash_set_l1c_wrap(SPI_Flash_Cfg_Type *p_flash_cfg) +{ + if (((p_flash_cfg->ioMode >> 4) & 0x01) == 1) { + L1C_Set_Wrap(DISABLE); + } else { + L1C_Set_Wrap(ENABLE); + if ((p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (p_flash_cfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + SFlash_SetBurstWrap(p_flash_cfg); + } + } + + return 0; +} + +/** + * @brief flash_config_init + * + * @return int + */ +static int ATTR_TCM_SECTION flash_config_init(SPI_Flash_Cfg_Type *p_flash_cfg, uint8_t *jedec_id) +{ + int ret = -1; + uint8_t isAesEnable = 0; + uint32_t jid = 0; + uint32_t offset = 0; + uintptr_t flag; + + flag = bflb_irq_save(); + XIP_SFlash_Opt_Enter(&isAesEnable); + XIP_SFlash_State_Save(p_flash_cfg, &offset, 0, 0); + SFlash_GetJedecId(p_flash_cfg, (uint8_t *)&jid); + arch_memcpy(jedec_id, (uint8_t *)&jid, 3); + jid &= 0xFFFFFF; + g_jedec_id = jid; + ret = SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(jid, p_flash_cfg, 0, 0); + if (ret == 0) { + p_flash_cfg->mid = (jid & 0xff); + } + + /* Set flash controler from p_flash_cfg */ + flash_set_qspi_enable(p_flash_cfg); + flash_set_l1c_wrap(p_flash_cfg); + XIP_SFlash_State_Restore(p_flash_cfg, offset, 0, 0); + XIP_SFlash_Opt_Exit(isAesEnable); + bflb_irq_restore(flag); + + return ret; +} + +/** + * @brief multi flash adapter + * + * @return int + */ +int ATTR_TCM_SECTION bflb_flash_init(void) +{ + int ret = -1; + uint32_t jedec_id = 0; + uintptr_t flag; + + jedec_id = GLB_Get_Flash_Id_Value(); + if (jedec_id != 0) { + ret = SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(jedec_id, &g_flash_cfg, 0, 0); + if (ret == 0) { + g_jedec_id = jedec_id; + flash_get_clock_delay(&g_flash_cfg); + return 0; + } + } + + flag = bflb_irq_save(); + L1C_ICache_Invalid_All(); + SF_Cfg_Get_Flash_Cfg_Need_Lock_Ext(0, &g_flash_cfg, 0, 0); + L1C_ICache_Invalid_All(); + bflb_irq_restore(flag); + if (g_flash_cfg.mid != 0xff) { + flash_get_clock_delay(&g_flash_cfg); + return 0; + } + + ret = flash_config_init(&g_flash_cfg, (uint8_t *)&jedec_id); + + flash_get_clock_delay(&g_flash_cfg); + GLB_Set_Flash_Id_Value(g_jedec_id); + + return ret; +} + +uint32_t bflb_flash_get_jedec_id(void) +{ + uint32_t jid = 0; + + jid = ((g_jedec_id & 0xff) << 16) + (g_jedec_id & 0xff00) + ((g_jedec_id & 0xff0000) >> 16); + return jid; +} + +void bflb_flash_get_cfg(uint8_t **cfg_addr, uint32_t *len) +{ + *cfg_addr = (uint8_t *)&g_flash_cfg; + *len = sizeof(SPI_Flash_Cfg_Type); +} + +void bflb_flash_set_iomode(uint8_t iomode) +{ + g_flash_cfg.ioMode &= ~0x1f; + if (iomode == 4) { + g_flash_cfg.ioMode |= iomode; + } else { + g_flash_cfg.ioMode |= 0x10; + g_flash_cfg.ioMode |= iomode; + } +} + +int ATTR_TCM_SECTION bflb_flash_erase(uint32_t startaddr, uint32_t len) +{ + int stat; + uintptr_t flag; + + if (startaddr >= BL808_FLASH_XIP_END - BL808_FLASH_XIP_BASE) { + return -ENOMEM; + } + + flag = bflb_irq_save(); + stat = XIP_SFlash_Erase_Need_Lock(&g_flash_cfg, startaddr, len, 0, 0); + bflb_irq_restore(flag); + + return stat; +} + +int ATTR_TCM_SECTION bflb_flash_write(uint32_t addr, uint8_t *data, uint32_t len) +{ + int stat; + uintptr_t flag; + + if (addr >= BL808_FLASH_XIP_END - BL808_FLASH_XIP_BASE) { + return -ENOMEM; + } + + flag = bflb_irq_save(); + stat = XIP_SFlash_Write_Need_Lock(&g_flash_cfg, addr, data, len, 0, 0); + bflb_irq_restore(flag); + + return stat; +} + +int ATTR_TCM_SECTION bflb_flash_read(uint32_t addr, uint8_t *data, uint32_t len) +{ + int stat; + uintptr_t flag; + + if (addr >= BL808_FLASH_XIP_END - BL808_FLASH_XIP_BASE) { + return -ENOMEM; + } + + flag = bflb_irq_save(); + stat = XIP_SFlash_Read_Need_Lock(&g_flash_cfg, addr, data, len, 0, 0); + bflb_irq_restore(flag); + + return stat; +} + +void bflb_flash_aes_init(struct bflb_flash_aes_config_s *config) +{ + uint8_t hw_key_enable = 0; + + if (config->key == NULL) { + hw_key_enable = 1; + } + + SF_Ctrl_AES_Set_Key_BE(config->region, (uint8_t *)config->key, config->keybits); + SF_Ctrl_AES_Set_IV_BE(config->region, (uint8_t *)config->iv, config->start_addr); + SF_Ctrl_AES_Set_Region(config->region, config->region_enable, hw_key_enable, config->start_addr, config->end_addr - 1, config->lock_enable); +} + +void bflb_flash_aes_enable(void) +{ + SF_Ctrl_AES_Enable(); +} + +void bflb_flash_aes_disable(void) +{ + SF_Ctrl_AES_Disable(); +} \ No newline at end of file diff --git a/drivers/soc/bl808/startup/d0/interrupt.c b/drivers/soc/bl808/startup/d0/interrupt.c new file mode 100644 index 00000000..f08b02e2 --- /dev/null +++ b/drivers/soc/bl808/startup/d0/interrupt.c @@ -0,0 +1,154 @@ +#include "bflb_core.h" +#include +#include "irq_ctx.h" +#include "bl808_glb.h" + +extern void riscv_savefpu(const uintptr_t *regs); +extern void riscv_restorefpu(const uintptr_t *regs); + +#define RV_EXCEPTION_NUM (16) +typedef uintptr_t (*exception_handler)(uintptr_t cause, uintptr_t val, uintptr_t *regs); + +typedef void (*pFunc)(void); + +struct bflb_irq_info_s g_irqvector[CONFIG_IRQ_NUM] __attribute__((aligned(16))); + +static uintptr_t exception_handler_default(uintptr_t cause, uintptr_t val, uintptr_t *regs) __attribute__((noreturn)); +static uintptr_t exception_handler_default(uintptr_t cause, uintptr_t val, uintptr_t *regs) +{ + printf("\n\rUn-handled Exception on CPU %d:\n\r", GLB_Get_Core_Type()); + // clang-format off + printf("mstatus = 0x%16llx, FS=%d, MPP=%d, MPIE=%d\n\r", regs[REG_INT_CTX_NDX], + (regs[REG_INT_CTX_NDX] >> 13) & 0x3, + (regs[REG_INT_CTX_NDX] >> 11) & 0x3, + (regs[REG_INT_CTX_NDX] >> 7) & 1); + printf("mcause: %d, mtval = 0x%16llx, mepc = 0x%16llx\n\r\n\r", (cause & 0xf), val, regs[REG_EPC_NDX]); + +const char *mcause_str[] = { + "Instruction address misaligned", + "Instruction access fault", + "Illegal instruction", + "Breakpoint", + "Load address misaligned", + "Load access fault", + "Store/AMO address misaligned", + "Store/AMO access fault", + "Environment call from U-mode", + "Environment call from S-mode", + "RSVD", + "Environment call from M-mode", + "Instruction page fault", + "Load page fault", + "RSVD", + "Store/AMO page fault" +}; + if ((cause & 0xf)) + printf("%s\r\n\r\n", mcause_str[cause & 0xf]); + +#ifndef CONFIG_ERR_NOT_DUMP_ALL_REGS + printf("ra = 0x%16llx ", regs[REG_RA]); printf("sp = 0x%16llx ", regs[REG_SP]); printf("gp = 0x%16llx ", regs[REG_GP]); + printf("tp = 0x%16llx ", regs[REG_TP]); printf("\n\r"); + + printf("t0 = 0x%16llx ", regs[REG_T0]); printf("t1 = 0x%16llx ", regs[REG_T1]); printf("t2 = 0x%16llx ", regs[REG_T2]); + printf("t3 = 0x%16llx ", regs[REG_T3]); printf("\n\r"); + printf("t4 = 0x%16llx ", regs[REG_T4]); printf("t5 = 0x%16llx ", regs[REG_T5]); printf("t6 = 0x%16llx ", regs[REG_T6]); + printf("\n\r"); + + printf("a0 = 0x%16llx ", regs[REG_A0]); printf("a1 = 0x%16llx ", regs[REG_A1]); printf("a2 = 0x%16llx ", regs[REG_A2]); + printf("a3 = 0x%16llx ", regs[REG_A3]); printf("\n\r"); + printf("a4 = 0x%16llx ", regs[REG_A4]); printf("a5 = 0x%16llx ", regs[REG_A5]); printf("a6 = 0x%16llx ", regs[REG_A6]); + printf("a7 = 0x%16llx ", regs[REG_A7]); printf("\n\r"); + + printf("s0 = 0x%16llx ", regs[REG_S0]); printf("s1 = 0x%16llx ", regs[REG_S1]); printf("s2 = 0x%16llx ", regs[REG_S2]); + printf("s3 = 0x%16llx ", regs[REG_S3]); printf("\n\r"); + printf("s4 = 0x%16llx ", regs[REG_S4]); printf("s5 = 0x%16llx ", regs[REG_S5]); printf("s6 = 0x%16llx ", regs[REG_S6]); + printf("s7 = 0x%16llx ", regs[REG_S7]); printf("\n\r"); + printf("s8 = 0x%16llx ", regs[REG_S8]); printf("s9 = 0x%16llx ", regs[REG_S9]); printf("s10 = 0x%16llx ", regs[REG_S10]); + printf("s11 = 0x%16llx ", regs[REG_S11]); printf("\n\r"); +#endif + // clang-format on + printf("\n\r"); + + while (1) { + } +} + +static uintptr_t exception_handler_ECALL_M(uintptr_t cause, uintptr_t val, uintptr_t *regs) +{ + regs[REG_EPC_NDX] += 4; + __asm volatile("nop" :: + : "memory"); + + return 0; +} + +static exception_handler exception_handlers[RV_EXCEPTION_NUM] = { + exception_handler_default, /* 0: Instruction Address Misaligned */ + exception_handler_default, /* 1: Instruction Access Fault */ + exception_handler_default, /* 2: Illegal Instruction */ + exception_handler_default, /* 3: Breakpoint */ + exception_handler_default, /* 4: Load Address Misaligned */ + exception_handler_default, /* 5: Load Access Fault */ + exception_handler_default, /* 6: Store/AMO Address Misaligned */ + exception_handler_default, /* 7: Store/AMO Access Fault */ + exception_handler_default, /* 8: Environment Call from U-mode */ + exception_handler_default, /* 9: Environment Call from S-mode */ + exception_handler_default, /* 10: Environment Call from H-mode */ + exception_handler_ECALL_M, /* 11: Environment Call from M-mode */ + exception_handler_default, /* 12: Instruction Page Fault */ + exception_handler_default, /* 13: Load Page Fault */ + exception_handler_default, /* 14: Reserved */ + exception_handler_default, /* 15: Store/AMO Page Fault */ +}; + +exception_handler exception_handler_install(uintptr_t vec, exception_handler handler) +{ + exception_handler previous = NULL; + + if (RV_EXCEPTION_NUM > vec) { + previous = exception_handlers[vec]; + exception_handlers[vec] = handler; + } + + return previous; +} + +uintptr_t *trap_c(uintptr_t cause, uintptr_t *regs) +{ + uint32_t vec = 0; + uintptr_t tval = __get_MTVAL(); + + riscv_savefpu(regs); + + vec = cause & 0x3FF; + + if (RV_EXCEPTION_NUM > vec) { + exception_handlers[vec](cause, tval, regs); + } else { + while (1) + ; + } + + riscv_restorefpu(regs); + + return regs; +} + +void interrupt_entry(uint64_t irq_num) +{ + irq_callback handler; + void *arg; + // volatile uint32_t irq_num; + + //irq_num = PLIC->PLIC_H0_MCLAIM & 0x3ff; + + if (irq_num < CONFIG_IRQ_NUM) { + handler = g_irqvector[irq_num].handler; + arg = g_irqvector[irq_num].arg; + if (handler) { + handler(irq_num, arg); + } else { + } + } else { + } +} \ No newline at end of file diff --git a/drivers/soc/bl808/startup/d0/irq_ctx.h b/drivers/soc/bl808/startup/d0/irq_ctx.h new file mode 100644 index 00000000..3639e2dd --- /dev/null +++ b/drivers/soc/bl808/startup/d0/irq_ctx.h @@ -0,0 +1,372 @@ +#ifndef __IRQ_CTX_H__ +#define __IRQ_CTX_H__ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#define CONFIG_ARCH_FPU +#define CONFIG_ARCH_DPFPU + +/* Processor PC */ + +#define REG_EPC_NDX 0 + +/* General pupose registers + * $0: Zero register does not need to be saved + * $1: ra (return address) + */ + +#define REG_X1_NDX 1 + +/* $2: Stack POinter + * $3: Global Pointer + * $4: Thread Pointer + */ + +#define REG_X2_NDX 2 +#define REG_X3_NDX 3 +#define REG_X4_NDX 4 + +/* $5-$7 = t0-t3: Temporary registers */ + +#define REG_X5_NDX 5 +#define REG_X6_NDX 6 +#define REG_X7_NDX 7 + +/* $8: s0 / fp Frame pointer */ + +#define REG_X8_NDX 8 + +/* $89 s1 Saved register */ + +#define REG_X9_NDX 9 + +/* $10-$17 = a0-a7: Argument registers */ + +#define REG_X10_NDX 10 +#define REG_X11_NDX 11 +#define REG_X12_NDX 12 +#define REG_X13_NDX 13 +#define REG_X14_NDX 14 +#define REG_X15_NDX 15 +#define REG_X16_NDX 16 +#define REG_X17_NDX 17 + +/* $18-$27 = s2-s11: Saved registers */ + +#define REG_X18_NDX 18 +#define REG_X19_NDX 19 +#define REG_X20_NDX 20 +#define REG_X21_NDX 21 +#define REG_X22_NDX 22 +#define REG_X23_NDX 23 +#define REG_X24_NDX 24 +#define REG_X25_NDX 25 +#define REG_X26_NDX 26 +#define REG_X27_NDX 27 + +/* $28-31 = t3-t6: Temporary (Volatile) registers */ + +#define REG_X28_NDX 28 +#define REG_X29_NDX 29 +#define REG_X30_NDX 30 +#define REG_X31_NDX 31 + +/* Interrupt Context register */ + +#define REG_INT_CTX_NDX 32 + +#define INT_XCPT_REGS 33 + +#define INT_XCPT_SIZE (8 * INT_XCPT_REGS) + +#ifdef CONFIG_ARCH_FPU + +#if defined(CONFIG_ARCH_DPFPU) +#define FPU_REG_SIZE 1 /* size in uint64_t */ +#elif defined(CONFIG_ARCH_QPFPU) +#define FPU_REG_SIZE 2 +#else +#error not supported !!! +#endif + +#define REG_F0_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 0) +#define REG_F1_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 1) +#define REG_F2_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 2) +#define REG_F3_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 3) +#define REG_F4_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 4) +#define REG_F5_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 5) +#define REG_F6_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 6) +#define REG_F7_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 7) +#define REG_F8_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 8) +#define REG_F9_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 9) +#define REG_F10_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 10) +#define REG_F11_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 11) +#define REG_F12_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 12) +#define REG_F13_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 13) +#define REG_F14_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 14) +#define REG_F15_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 15) +#define REG_F16_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 16) +#define REG_F17_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 17) +#define REG_F18_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 18) +#define REG_F19_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 19) +#define REG_F20_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 20) +#define REG_F21_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 21) +#define REG_F22_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 22) +#define REG_F23_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 23) +#define REG_F24_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 24) +#define REG_F25_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 25) +#define REG_F26_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 26) +#define REG_F27_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 27) +#define REG_F28_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 28) +#define REG_F29_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 29) +#define REG_F30_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 30) +#define REG_F31_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 31) +#define REG_FCSR_NDX (INT_XCPT_REGS + FPU_REG_SIZE * 32) + +#define FPU_XCPT_REGS (FPU_REG_SIZE * 33) +#else +#define FPU_XCPT_REGS 0 +#endif + +#define XCPTCONTEXT_REGS (INT_XCPT_REGS + FPU_XCPT_REGS) + +#define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS) + +/* In assembly language, values have to be referenced as byte address + * offsets. But in C, it is more convenient to reference registers as + * register save table offsets. + */ + +#ifdef __ASSEMBLY__ +#define REG_EPC (8 * REG_EPC_NDX) +#define REG_X1 (8 * REG_X1_NDX) +#define REG_X2 (8 * REG_X2_NDX) +#define REG_X3 (8 * REG_X3_NDX) +#define REG_X4 (8 * REG_X4_NDX) +#define REG_X5 (8 * REG_X5_NDX) +#define REG_X6 (8 * REG_X6_NDX) +#define REG_X7 (8 * REG_X7_NDX) +#define REG_X8 (8 * REG_X8_NDX) +#define REG_X9 (8 * REG_X9_NDX) +#define REG_X10 (8 * REG_X10_NDX) +#define REG_X11 (8 * REG_X11_NDX) +#define REG_X12 (8 * REG_X12_NDX) +#define REG_X13 (8 * REG_X13_NDX) +#define REG_X14 (8 * REG_X14_NDX) +#define REG_X15 (8 * REG_X15_NDX) +#define REG_X16 (8 * REG_X16_NDX) +#define REG_X17 (8 * REG_X17_NDX) +#define REG_X18 (8 * REG_X18_NDX) +#define REG_X19 (8 * REG_X19_NDX) +#define REG_X20 (8 * REG_X20_NDX) +#define REG_X21 (8 * REG_X21_NDX) +#define REG_X22 (8 * REG_X22_NDX) +#define REG_X23 (8 * REG_X23_NDX) +#define REG_X24 (8 * REG_X24_NDX) +#define REG_X25 (8 * REG_X25_NDX) +#define REG_X26 (8 * REG_X26_NDX) +#define REG_X27 (8 * REG_X27_NDX) +#define REG_X28 (8 * REG_X28_NDX) +#define REG_X29 (8 * REG_X29_NDX) +#define REG_X30 (8 * REG_X30_NDX) +#define REG_X31 (8 * REG_X31_NDX) +#define REG_INT_CTX (8 * REG_INT_CTX_NDX) + +#ifdef CONFIG_ARCH_FPU +#define REG_F0 (8 * REG_F0_NDX) +#define REG_F1 (8 * REG_F1_NDX) +#define REG_F2 (8 * REG_F2_NDX) +#define REG_F3 (8 * REG_F3_NDX) +#define REG_F4 (8 * REG_F4_NDX) +#define REG_F5 (8 * REG_F5_NDX) +#define REG_F6 (8 * REG_F6_NDX) +#define REG_F7 (8 * REG_F7_NDX) +#define REG_F8 (8 * REG_F8_NDX) +#define REG_F9 (8 * REG_F9_NDX) +#define REG_F10 (8 * REG_F10_NDX) +#define REG_F11 (8 * REG_F11_NDX) +#define REG_F12 (8 * REG_F12_NDX) +#define REG_F13 (8 * REG_F13_NDX) +#define REG_F14 (8 * REG_F14_NDX) +#define REG_F15 (8 * REG_F15_NDX) +#define REG_F16 (8 * REG_F16_NDX) +#define REG_F17 (8 * REG_F17_NDX) +#define REG_F18 (8 * REG_F18_NDX) +#define REG_F19 (8 * REG_F19_NDX) +#define REG_F20 (8 * REG_F20_NDX) +#define REG_F21 (8 * REG_F21_NDX) +#define REG_F22 (8 * REG_F22_NDX) +#define REG_F23 (8 * REG_F23_NDX) +#define REG_F24 (8 * REG_F24_NDX) +#define REG_F25 (8 * REG_F25_NDX) +#define REG_F26 (8 * REG_F26_NDX) +#define REG_F27 (8 * REG_F27_NDX) +#define REG_F28 (8 * REG_F28_NDX) +#define REG_F29 (8 * REG_F29_NDX) +#define REG_F30 (8 * REG_F30_NDX) +#define REG_F31 (8 * REG_F31_NDX) +#define REG_FCSR (8 * REG_FCSR_NDX) +#endif + +#else +#define REG_EPC REG_EPC_NDX +#define REG_X1 REG_X1_NDX +#define REG_X2 REG_X2_NDX +#define REG_X3 REG_X3_NDX +#define REG_X4 REG_X4_NDX +#define REG_X5 REG_X5_NDX +#define REG_X6 REG_X6_NDX +#define REG_X7 REG_X7_NDX +#define REG_X8 REG_X8_NDX +#define REG_X9 REG_X9_NDX +#define REG_X10 REG_X10_NDX +#define REG_X11 REG_X11_NDX +#define REG_X12 REG_X12_NDX +#define REG_X13 REG_X13_NDX +#define REG_X14 REG_X14_NDX +#define REG_X15 REG_X15_NDX +#define REG_X16 REG_X16_NDX +#define REG_X17 REG_X17_NDX +#define REG_X18 REG_X18_NDX +#define REG_X19 REG_X19_NDX +#define REG_X20 REG_X20_NDX +#define REG_X21 REG_X21_NDX +#define REG_X22 REG_X22_NDX +#define REG_X23 REG_X23_NDX +#define REG_X24 REG_X24_NDX +#define REG_X25 REG_X25_NDX +#define REG_X26 REG_X26_NDX +#define REG_X27 REG_X27_NDX +#define REG_X28 REG_X28_NDX +#define REG_X29 REG_X29_NDX +#define REG_X30 REG_X30_NDX +#define REG_X31 REG_X31_NDX +#define REG_INT_CTX REG_INT_CTX_NDX + +#ifdef CONFIG_ARCH_FPU +#define REG_F0 REG_F0_NDX +#define REG_F1 REG_F1_NDX +#define REG_F2 REG_F2_NDX +#define REG_F3 REG_F3_NDX +#define REG_F4 REG_F4_NDX +#define REG_F5 REG_F5_NDX +#define REG_F6 REG_F6_NDX +#define REG_F7 REG_F7_NDX +#define REG_F8 REG_F8_NDX +#define REG_F9 REG_F9_NDX +#define REG_F10 REG_F10_NDX +#define REG_F11 REG_F11_NDX +#define REG_F12 REG_F12_NDX +#define REG_F13 REG_F13_NDX +#define REG_F14 REG_F14_NDX +#define REG_F15 REG_F15_NDX +#define REG_F16 REG_F16_NDX +#define REG_F17 REG_F17_NDX +#define REG_F18 REG_F18_NDX +#define REG_F19 REG_F19_NDX +#define REG_F20 REG_F20_NDX +#define REG_F21 REG_F21_NDX +#define REG_F22 REG_F22_NDX +#define REG_F23 REG_F23_NDX +#define REG_F24 REG_F24_NDX +#define REG_F25 REG_F25_NDX +#define REG_F26 REG_F26_NDX +#define REG_F27 REG_F27_NDX +#define REG_F28 REG_F28_NDX +#define REG_F29 REG_F29_NDX +#define REG_F30 REG_F30_NDX +#define REG_F31 REG_F31_NDX +#define REG_FCSR REG_FCSR_NDX +#endif + +#endif + +/* Now define more user friendly alternative name that can be used either + * in assembly or C contexts. + */ + +/* $1 = ra: Return address */ + +#define REG_RA REG_X1 + +/* $2 = sp: The value of the stack pointer on return from the exception */ + +#define REG_SP REG_X2 + +/* $3 = gp: Only needs to be saved under conditions where there are + * multiple, per-thread values for the GP. + */ + +#define REG_GP REG_X3 + +/* $4 = tp: Thread Pointer */ + +#define REG_TP REG_X4 + +/* $5-$7 = t0-t2: Caller saved temporary registers */ + +#define REG_T0 REG_X5 +#define REG_T1 REG_X6 +#define REG_T2 REG_X7 + +/* $8 = either s0 or fp: Depends if a frame pointer is used or not */ + +#define REG_S0 REG_X8 +#define REG_FP REG_X8 + +/* $9 = s1: Caller saved register */ + +#define REG_S1 REG_X9 + +/* $10-$17 = a0-a7: Argument registers */ + +#define REG_A0 REG_X10 +#define REG_A1 REG_X11 +#define REG_A2 REG_X12 +#define REG_A3 REG_X13 +#define REG_A4 REG_X14 +#define REG_A5 REG_X15 +#define REG_A6 REG_X16 +#define REG_A7 REG_X17 + +/* $18-$27 = s2-s11: Callee saved registers */ + +#define REG_S2 REG_X18 +#define REG_S3 REG_X19 +#define REG_S4 REG_X20 +#define REG_S5 REG_X21 +#define REG_S6 REG_X22 +#define REG_S7 REG_X23 +#define REG_S8 REG_X24 +#define REG_S9 REG_X25 +#define REG_S10 REG_X26 +#define REG_S11 REG_X27 + +/* $28-$31 = t3-t6: Caller saved temporary registers */ + +#define REG_T3 REG_X28 +#define REG_T4 REG_X29 +#define REG_T5 REG_X30 +#define REG_T6 REG_X31 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Variables + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __IRQ_CTX_H__ */ diff --git a/drivers/soc/bl808/startup/d0/riscv_fpu.S b/drivers/soc/bl808/startup/d0/riscv_fpu.S new file mode 100644 index 00000000..a88e6230 --- /dev/null +++ b/drivers/soc/bl808/startup/d0/riscv_fpu.S @@ -0,0 +1,221 @@ + +/************************************************************************************ + * Included Files + ************************************************************************************/ +#define __ASSEMBLY__ +#include "irq_ctx.h" + +#if defined(CONFIG_ARCH_FPU) +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/************************************************************************************ + * Public Symbols + ************************************************************************************/ + + .globl riscv_fpuconfig + .globl riscv_savefpu + .globl riscv_savefpu_force + .globl riscv_restorefpu + + .file "riscv_fpu.S" + +#define FS_MASK 0x6000 +#define FS_OFF 0x0000 +#define FS_INITIAL 0x2000 +#define FS_CLEAN 0x4000 +#define FS_DIRTY 0x6000 + +#if defined(CONFIG_ARCH_DPFPU) +# define FLOAD fld +# define FSTORE fsd +# define LOAD ld +# define STORE sd +#elif defined(CONFIG_ARCH_QPFPU) +# define FLOAD flq +# define FSTORE fsq +#else +# define FLOAD flw +# define FSTORE fsw +# define LOAD lw +# define STORE sw +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: riscv_fpuconfig + * + * Description: + * init fpu + * + * C Function Prototype: + * void riscv_fpuconfig(void); + * + * Input Parameters: + * None + * + * Returned Value: + * This function does not return anything explicitly. + * + ************************************************************************************/ + + .type riscv_fpuconfig, function + +riscv_fpuconfig: + li a0, FS_INITIAL + csrs mstatus, a0 + csrwi fcsr, 0 + ret + +/************************************************************************************ + * Name: riscv_savefpu + * + * Description: + * Given the pointer to a register save area (in A0), save the state of the + * floating point registers. + * + * C Function Prototype: + * void riscv_savefpu(uintptr_t *regs); + * + * Input Parameters: + * regs - A pointer to the register save area in which to save the floating point + * registers + * + * Returned Value: + * None + * + ************************************************************************************/ + + .type riscv_savefpu, function + +riscv_savefpu: + LOAD t0, REG_INT_CTX(a0) + li t1, FS_MASK + and t2, t0, t1 + li t1, FS_DIRTY + bne t2, t1, 1f + li t1, ~FS_MASK + and t0, t0, t1 + li t1, FS_CLEAN + or t0, t0, t1 + STORE t0, REG_INT_CTX(a0) + + /* Store all floating point registers */ +riscv_savefpu_force: + + FSTORE f0, REG_F0(a0) + FSTORE f1, REG_F1(a0) + FSTORE f2, REG_F2(a0) + FSTORE f3, REG_F3(a0) + FSTORE f4, REG_F4(a0) + FSTORE f5, REG_F5(a0) + FSTORE f6, REG_F6(a0) + FSTORE f7, REG_F7(a0) + FSTORE f8, REG_F8(a0) + FSTORE f9, REG_F9(a0) + FSTORE f10, REG_F10(a0) + FSTORE f11, REG_F11(a0) + FSTORE f12, REG_F12(a0) + FSTORE f13, REG_F13(a0) + FSTORE f14, REG_F14(a0) + FSTORE f15, REG_F15(a0) + FSTORE f16, REG_F16(a0) + FSTORE f17, REG_F17(a0) + FSTORE f18, REG_F18(a0) + FSTORE f19, REG_F19(a0) + FSTORE f20, REG_F20(a0) + FSTORE f21, REG_F21(a0) + FSTORE f22, REG_F22(a0) + FSTORE f23, REG_F23(a0) + FSTORE f24, REG_F24(a0) + FSTORE f25, REG_F25(a0) + FSTORE f26, REG_F26(a0) + FSTORE f27, REG_F27(a0) + FSTORE f28, REG_F28(a0) + FSTORE f29, REG_F29(a0) + FSTORE f30, REG_F30(a0) + FSTORE f31, REG_F31(a0) + + frcsr t0 + STORE t0, REG_FCSR(a0) + +1: + ret + +/************************************************************************************ + * Name: riscv_restorefpu + * + * Description: + * Given the pointer to a register save area (in A0), restore the state of the + * floating point registers. + * + * C Function Prototype: + * void riscv_restorefpu(const uintptr_t *regs); + * + * Input Parameters: + * regs - A pointer to the register save area containing the floating point + * registers. + * + * Returned Value: + * This function does not return anything explicitly. However, it is called from + * interrupt level assembly logic that assumes that r0 is preserved. + * + ************************************************************************************/ + + .type riscv_restorefpu, function + +riscv_restorefpu: + LOAD t0, REG_INT_CTX(a0) + li t1, FS_MASK + and t2, t0, t1 + li t1, FS_INITIAL + ble t2, t1, 1f + + /* Load all floating point registers */ + + FLOAD f0, REG_F0(a0) + FLOAD f1, REG_F1(a0) + FLOAD f2, REG_F2(a0) + FLOAD f3, REG_F3(a0) + FLOAD f4, REG_F4(a0) + FLOAD f5, REG_F5(a0) + FLOAD f6, REG_F6(a0) + FLOAD f7, REG_F7(a0) + FLOAD f8, REG_F8(a0) + FLOAD f9, REG_F9(a0) + FLOAD f10, REG_F10(a0) + FLOAD f11, REG_F11(a0) + FLOAD f12, REG_F12(a0) + FLOAD f13, REG_F13(a0) + FLOAD f14, REG_F14(a0) + FLOAD f15, REG_F15(a0) + FLOAD f16, REG_F16(a0) + FLOAD f17, REG_F17(a0) + FLOAD f18, REG_F18(a0) + FLOAD f19, REG_F19(a0) + FLOAD f20, REG_F20(a0) + FLOAD f21, REG_F21(a0) + FLOAD f22, REG_F22(a0) + FLOAD f23, REG_F23(a0) + FLOAD f24, REG_F24(a0) + FLOAD f25, REG_F25(a0) + FLOAD f26, REG_F26(a0) + FLOAD f27, REG_F27(a0) + FLOAD f28, REG_F28(a0) + FLOAD f29, REG_F29(a0) + FLOAD f30, REG_F30(a0) + FLOAD f31, REG_F31(a0) + + /* Store the floating point control and status register */ + + LOAD t0, REG_FCSR(a0) + fscsr t0 + +1: + ret + +#endif /* CONFIG_ARCH_FPU */ diff --git a/drivers/soc/bl808/startup/d0/start.S b/drivers/soc/bl808/startup/d0/start.S new file mode 100644 index 00000000..b2d73760 --- /dev/null +++ b/drivers/soc/bl808/startup/d0/start.S @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2016-2020 Bouffalo Lab + */ +#include + + .section .init + .align 2 + .globl __start + .type __start, %function +__start: +.option push +.option norelax + la gp, __global_pointer$ +.option pop + + li t0, MSTATUS_MIE | MSTATUS_SIE + csrc mstatus, t0 + + /* mapbaddr */ + /* ? clear PLIC ?*/ + csrr t1, 0xfc1 + li t2, 0x00200004 + add t2, t2, t1 + lw t3, 0(t2) + sw t3, 0(t2) + li t4, 0x00201004 + add t2, t4, t1 + lw t3, 0(t2) + sw t3, 0(t2) + + csrw mie, zero + csrw mip, zero + + /* invalid all MMU TLB Entry */ + sfence.vma x0,x0 + + /* TODO: debug */ + csrw mcycle, zero + csrw minstret, zero + + /* + * enable thead ISA extension: + * THEADISAEE = 1, MM = 1, + */ + csrr t0, mxstatus + li t1, (1 << 22) | (1 << 15) + or t1, t1, t0 + csrw mxstatus, t1 + + /* FP: initial state */ + csrr t0, mstatus + li t1, ~0x6000 + and t0, t0, t1 + li t1, 0x2000 + or t0, t0, t1 + csrw mstatus, t0 + /* csrwi fcsr, 0 */ + + /* RVV: initial state */ + li t0, ~(3 << 23) + csrr t1, mstatus + and t2, t1, t0 + li t0, 1 << 23 + or t2, t2, t0 + csrw mstatus, t2 + + la a0, __Vectors__ + ori a0, a0, 1 + csrw mtvec, a0 + + la a0, __Vectors_S__ + ori a0, a0, 1 + csrw stvec, a0 + + .weak __StackTop + la sp, __StackTop + csrw mscratch, sp + + jal SystemInit + + /* start load code to itcm like. */ + jal start_load + + jal System_Post_Init + + jal main + + .size __start, . - __start + +__exit: + j __exit diff --git a/drivers/soc/bl808/startup/d0/start_load.c b/drivers/soc/bl808/startup/d0/start_load.c new file mode 100644 index 00000000..456d814a --- /dev/null +++ b/drivers/soc/bl808/startup/d0/start_load.c @@ -0,0 +1,94 @@ +#include + +#define __STARTUP_CLEAR_BSS 1 + +/*---------------------------------------------------------------------------- + Linker generated Symbols + *----------------------------------------------------------------------------*/ +extern uint32_t __itcm_load_addr; +extern uint32_t __dtcm_load_addr; +extern uint32_t __system_ram_load_addr; +extern uint32_t __ram_load_addr; +extern uint32_t __nocache_ram_load_addr; + +extern uint32_t __text_code_start__; +extern uint32_t __text_code_end__; +extern uint32_t __tcm_code_start__; +extern uint32_t __tcm_code_end__; +extern uint32_t __tcm_data_start__; +extern uint32_t __tcm_data_end__; +extern uint32_t __system_ram_data_start__; +extern uint32_t __system_ram_data_end__; +extern uint32_t __ram_data_start__; +extern uint32_t __ram_data_end__; +extern uint32_t __bss_start__; +extern uint32_t __bss_end__; +extern uint32_t __noinit_data_start__; +extern uint32_t __noinit_data_end__; +extern uint32_t __nocache_ram_data_start__; +extern uint32_t __nocache_ram_data_end__; + +extern uint32_t __StackTop; +extern uint32_t __StackLimit; +extern uint32_t __HeapBase; +extern uint32_t __HeapLimit; + +//extern uint32_t __copy_table_start__; +//extern uint32_t __copy_table_end__; +//extern uint32_t __zero_table_start__; +//extern uint32_t __zero_table_end__; + +void start_load(void) +{ + uint32_t *pSrc, *pDest; + uint32_t *pTable __attribute__((unused)); + + /* Copy ITCM code */ + pSrc = &__itcm_load_addr; + pDest = &__tcm_code_start__; + + for (; pDest < &__tcm_code_end__;) { + *pDest++ = *pSrc++; + } + + /* Copy DTCM code */ + pSrc = &__dtcm_load_addr; + pDest = &__tcm_data_start__; + + for (; pDest < &__tcm_data_end__;) { + *pDest++ = *pSrc++; + } + + /* BF Add system RAM data copy */ + pSrc = &__system_ram_load_addr; + pDest = &__system_ram_data_start__; + + for (; pDest < &__system_ram_data_end__;) { + *pDest++ = *pSrc++; + } + + /* BF Add OCARAM data copy */ + pSrc = &__ram_load_addr; + pDest = &__ram_data_start__; + + for (; pDest < &__ram_data_end__;) { + *pDest++ = *pSrc++; + } + +#ifdef __STARTUP_CLEAR_BSS + /* Single BSS section scheme. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * Both addresses must be aligned to 4 bytes boundary. + */ + pDest = &__bss_start__; + + for (; pDest < &__bss_end__;) { + *pDest++ = 0ul; + } + +#endif +} diff --git a/drivers/soc/bl808/startup/d0/system_bl808.c b/drivers/soc/bl808/startup/d0/system_bl808.c new file mode 100644 index 00000000..096d70fc --- /dev/null +++ b/drivers/soc/bl808/startup/d0/system_bl808.c @@ -0,0 +1,55 @@ +#include "bl808_clock.h" +#include "bl808_ef_cfg.h" + +#define BL808_B0 (0x0) +#define BL808_B1 (0x1) + +void SystemInit(void) +{ + uintptr_t tmpVal = 0; + + while ((BL_RD_WORD(IPC_SYNC_ADDR1) != IPC_SYNC_FLAG) || + (BL_RD_WORD(IPC_SYNC_ADDR2) != IPC_SYNC_FLAG)) { + // clang-format off + __NOP(); __NOP(); __NOP(); __NOP(); + __NOP(); __NOP(); __NOP(); __NOP(); + __NOP(); __NOP(); __NOP(); __NOP(); + __NOP(); __NOP(); __NOP(); __NOP(); + // clang-format on + /* if cache is off, comment this and this api need to start load itcm*/ + // L1C_DCache_Invalid_By_Addr(IPC_SYNC_ADDR1, 8); + }; + /* clear this flags for system reboot */ + BL_WR_WORD(IPC_SYNC_ADDR1, 0x0); + BL_WR_WORD(IPC_SYNC_ADDR2, 0x0); + + /* turn on cache to speed up boot sequence */ + csi_icache_enable(); + csi_dcache_enable(); + + /* enable I/D Cache preload. */ + tmpVal = __get_MHINT(); + tmpVal |= (1 << 8) | (1 << 2); + /* clear AMR */ + tmpVal &= (~0x18); + __set_MHINT(tmpVal); +} + +void System_Post_Init(void) +{ + csi_dcache_clean(); + + /* fix amr setting */ + uintptr_t tmpVal = 0; + Efuse_Chip_Info_Type chip_info; + EF_Ctrl_Get_Chip_Info(&chip_info); + /* if not B0 enable AMR */ + if (chip_info.chipInfo != BL808_B0) { + tmpVal = __get_MHINT(); + tmpVal |= (1 << 3); + __set_MHINT(tmpVal); + } + + /* global IRQ enable */ + __enable_irq(); +} \ No newline at end of file diff --git a/drivers/soc/bl808/startup/d0/vector.S b/drivers/soc/bl808/startup/d0/vector.S new file mode 100644 index 00000000..42102d13 --- /dev/null +++ b/drivers/soc/bl808/startup/d0/vector.S @@ -0,0 +1,724 @@ +#define __ASSEMBLY__ +#include "irq_ctx.h" + +/* Enable interrupts when returning from the handler */ +#define MSTATUS_PRV1 0x0080 +#define SSTATUS_PRV1 0x0020 + +.section .text + .align 6 + .globl __Vectors__ + .type __Vectors__, @object +__Vectors__: +.option push +.option norvc + j exception_common /* 0 */ + j Stspend_Handler /* 1 */ + j Default_Handler /* 2 */ +#if defined(__OS_FREERTOS__) + j Mtspend_Handler /* 3 */ +#else + j M_SoftIRQ_ISR /* 3 : Machine Software Interrupt */ +#endif + j Default_Handler /* 4 */ + j Scoret_Handler /* 5 */ + j Default_Handler /* 6 */ + j Mcoret_Handler /* 7 */ + j Default_Handler /* 8 */ + j Sirq_Handler_M /* 9 */ + j Default_Handler /* 10 */ + j Default_IRQHandler /* 11 */ + j Default_Handler /* 12 */ + j Default_Handler /* 13 */ + j Default_Handler /* 14 */ + j Default_Handler /* 15 */ + j Default_Handler /* 16 */ + j HPM_OVF_IRQHandler /* 17 */ +.option pop + +.section .text + .align 6 + .globl __Vectors_S__ + .type __Vectors_S__, @object +__Vectors_S__: +.option push +.option norvc + j exception_common /* 0 */ + j Stspend_Handler_S /* 1 */ + j Default_Handler /* 2 */ + j M_SoftIRQ_ISR /* 3 */ + j Default_Handler /* 4 */ + j Scoret_Handler /* 5 */ + j Default_Handler /* 6 */ + j Mcoret_Handler /* 7 */ + j Default_Handler /* 8 */ + j Sirq_Handler /* 9 */ + j Default_Handler /* 10 */ + j Default_IRQHandler /* 11 */ + j Default_Handler /* 12 */ + j Default_Handler /* 13 */ + j Default_Handler /* 14 */ + j Default_Handler /* 15 */ + j Default_Handler /* 16 */ + j HPM_OVF_IRQHandler /* 17 */ +.option pop + +.section .bss.vector.g_trap_stack + .align 4 + .globl g_trapstackalloc + .global g_trapstackbase + .global g_top_trapstack +g_trapstackalloc: +g_trapstackbase: + .space 2048 /* 32I(64bit) + 32D(64bit) + 32V(128bit) */ +g_top_trapstack: +g_trap_sp: + +irq_nested_level: +.long 0 + +.text + + .align 2 + .global Scoret_Handler + .weak Scoret_Handler + .type Scoret_Handler, %function +Scoret_Handler: + j Stspend_Handler + + .align 2 + .global Mcoret_Handler + .weak Mcoret_Handler + .type Mcoret_Handler, %function +Mcoret_Handler: + addi sp, sp, -(76+76) + sd t0, (4+4)(sp) + sd t1, (8+8)(sp) + sd t2, (12+12)(sp) + + csrr t0, mepc + sd t0, (68+68)(sp) + sd t2, (72+72)(sp) + sd ra, (0 +0 )(sp) + sd a0, (16+16)(sp) + sd a1, (20+20)(sp) + sd a2, (24+24)(sp) + sd a3, (28+28)(sp) + sd a4, (32+32)(sp) + sd a5, (36+36)(sp) + sd a6, (40+40)(sp) + sd a7, (44+44)(sp) + sd t3, (48+48)(sp) + sd t4, (52+52)(sp) + sd t5, (56+56)(sp) + sd t6, (60+60)(sp) + + addi sp, sp, -160 + fsd ft0, (0 +0 )(sp) + fsd ft1, (4 +4 )(sp) + fsd ft2, (8 +8 )(sp) + fsd ft3, (12+12)(sp) + fsd ft4, (16+16)(sp) + fsd ft5, (20+20)(sp) + fsd ft6, (24+24)(sp) + fsd ft7, (28+28)(sp) + fsd fa0, (32+32)(sp) + fsd fa1, (36+36)(sp) + fsd fa2, (40+40)(sp) + fsd fa3, (44+44)(sp) + fsd fa4, (48+48)(sp) + fsd fa5, (52+52)(sp) + fsd fa6, (56+56)(sp) + fsd fa7, (60+60)(sp) + fsd ft8, (64+64)(sp) + fsd ft9, (68+68)(sp) + fsd ft10,(72+72)(sp) + fsd ft11,(76+76)(sp) + +#if defined(__OS_FREERTOS__) + la t2, CORET_IRQHandler + jalr t2 +#else + li a0, 7 + la t2, interrupt_entry + jalr t2 +#endif + csrc mstatus, 8 + + li t0, MSTATUS_PRV1 + csrs mstatus, t0 + + fld ft0, (0 +0 )(sp) + fld ft1, (4 +4 )(sp) + fld ft2, (8 +8 )(sp) + fld ft3, (12+12)(sp) + fld ft4, (16+16)(sp) + fld ft5, (20+20)(sp) + fld ft6, (24+24)(sp) + fld ft7, (28+28)(sp) + fld fa0, (32+32)(sp) + fld fa1, (36+36)(sp) + fld fa2, (40+40)(sp) + fld fa3, (44+44)(sp) + fld fa4, (48+48)(sp) + fld fa5, (52+52)(sp) + fld fa6, (56+56)(sp) + fld fa7, (60+60)(sp) + fld ft8, (64+64)(sp) + fld ft9, (68+68)(sp) + fld ft10,(72+72)(sp) + fld ft11,(76+76)(sp) + + addi sp, sp, 160 + + ld t0, (68+68)(sp) + csrw mepc, t0 + ld ra, (0 +0 )(sp) + ld t0, (4 +4 )(sp) + ld t1, (8 +8 )(sp) + ld t2, (12+12)(sp) + ld a0, (16+16)(sp) + ld a1, (20+20)(sp) + ld a2, (24+24)(sp) + ld a3, (28+28)(sp) + ld a4, (32+32)(sp) + ld a5, (36+36)(sp) + ld a6, (40+40)(sp) + ld a7, (44+44)(sp) + ld t3, (48+48)(sp) + ld t4, (52+52)(sp) + ld t5, (56+56)(sp) + ld t6, (60+60)(sp) + + addi sp, sp, (76+76) + mret + +/**************************************************************************** + * Name: Sirq_Handler + ****************************************************************************/ + /* S-mode external IRQ handler */ + .align 2 + .global Sirq_Handler + .weak Sirq_Handler + .type Sirq_Handler, %function +Sirq_Handler: + addi sp, sp, -(76+76) + sd t0, (4+4)(sp) + sd t1, (8+8)(sp) + sd t2, (12+12)(sp) + + li t0, 0xe0201000 + lw t2, 4(t0) + + csrr t0, sepc + sd t0, (68+68)(sp) + sd t2, (72+72)(sp) + sd ra, (0 +0 )(sp) + sd a0, (16+16)(sp) + sd a1, (20+20)(sp) + sd a2, (24+24)(sp) + sd a3, (28+28)(sp) + sd a4, (32+32)(sp) + sd a5, (36+36)(sp) + sd a6, (40+40)(sp) + sd a7, (44+44)(sp) + sd t3, (48+48)(sp) + sd t4, (52+52)(sp) + sd t5, (56+56)(sp) + sd t6, (60+60)(sp) + + addi sp, sp, -160 + fsd ft0, (0 +0 )(sp) + fsd ft1, (4 +4 )(sp) + fsd ft2, (8 +8 )(sp) + fsd ft3, (12+12)(sp) + fsd ft4, (16+16)(sp) + fsd ft5, (20+20)(sp) + fsd ft6, (24+24)(sp) + fsd ft7, (28+28)(sp) + fsd fa0, (32+32)(sp) + fsd fa1, (36+36)(sp) + fsd fa2, (40+40)(sp) + fsd fa3, (44+44)(sp) + fsd fa4, (48+48)(sp) + fsd fa5, (52+52)(sp) + fsd fa6, (56+56)(sp) + fsd fa7, (60+60)(sp) + fsd ft8, (64+64)(sp) + fsd ft9, (68+68)(sp) + fsd ft10,(72+72)(sp) + fsd ft11,(76+76)(sp) + + andi t2, t2, 0x3FF + mv a0, t2 + slli t2, t2, 3 + + la t2, interrupt_entry + jalr t2 + + csrc sstatus, 2 + + + /* write PLIC_CLAIM and exit interrupt */ + lw a1, (72+72+160)(sp) + andi a0, a1, 0x3FF + + li a2, 0xe0201000 + sw a0, 4(a2) + + li t0, SSTATUS_PRV1 + csrs sstatus, t0 + + fld ft0, (0 +0 )(sp) + fld ft1, (4 +4 )(sp) + fld ft2, (8 +8 )(sp) + fld ft3, (12+12)(sp) + fld ft4, (16+16)(sp) + fld ft5, (20+20)(sp) + fld ft6, (24+24)(sp) + fld ft7, (28+28)(sp) + fld fa0, (32+32)(sp) + fld fa1, (36+36)(sp) + fld fa2, (40+40)(sp) + fld fa3, (44+44)(sp) + fld fa4, (48+48)(sp) + fld fa5, (52+52)(sp) + fld fa6, (56+56)(sp) + fld fa7, (60+60)(sp) + fld ft8, (64+64)(sp) + fld ft9, (68+68)(sp) + fld ft10,(72+72)(sp) + fld ft11,(76+76)(sp) + + addi sp, sp, 160 + + ld t0, (68+68)(sp) + csrw sepc, t0 + ld ra, (0 +0 )(sp) + ld t0, (4 +4 )(sp) + ld t1, (8 +8 )(sp) + ld t2, (12+12)(sp) + ld a0, (16+16)(sp) + ld a1, (20+20)(sp) + ld a2, (24+24)(sp) + ld a3, (28+28)(sp) + ld a4, (32+32)(sp) + ld a5, (36+36)(sp) + ld a6, (40+40)(sp) + ld a7, (44+44)(sp) + ld t3, (48+48)(sp) + ld t4, (52+52)(sp) + ld t5, (56+56)(sp) + ld t6, (60+60)(sp) + + addi sp, sp, (76+76) + sret + +/**************************************************************************** + * Name: Sirq_Handler_M + ****************************************************************************/ + /* Sirq in M-Mode will be handled here */ + /* 1. IRQ is enabled in PLIC for S-Mode */ + /* 2. No IRQ delegation */ + .align 2 + .global Sirq_Handler_M + .weak Sirq_Handler_M + .type Sirq_Handler_M, %function +Sirq_Handler_M: + addi sp, sp, -(76+76) + sd t0, (4+4)(sp) + sd t1, (8+8)(sp) + sd t2, (12+12)(sp) + + csrr t0, 0xfc1 + li t1, 0x00201000 + add t0, t0, t1 + lw t2, 4(t0) + + csrr t0, mepc + sd t0, (68+68)(sp) + sd t2, (72+72)(sp) + sd ra, (0 +0 )(sp) + sd a0, (16+16)(sp) + sd a1, (20+20)(sp) + sd a2, (24+24)(sp) + sd a3, (28+28)(sp) + sd a4, (32+32)(sp) + sd a5, (36+36)(sp) + sd a6, (40+40)(sp) + sd a7, (44+44)(sp) + sd t3, (48+48)(sp) + sd t4, (52+52)(sp) + sd t5, (56+56)(sp) + sd t6, (60+60)(sp) + + addi sp, sp, -160 + fsd ft0, (0 +0 )(sp) + fsd ft1, (4 +4 )(sp) + fsd ft2, (8 +8 )(sp) + fsd ft3, (12+12)(sp) + fsd ft4, (16+16)(sp) + fsd ft5, (20+20)(sp) + fsd ft6, (24+24)(sp) + fsd ft7, (28+28)(sp) + fsd fa0, (32+32)(sp) + fsd fa1, (36+36)(sp) + fsd fa2, (40+40)(sp) + fsd fa3, (44+44)(sp) + fsd fa4, (48+48)(sp) + fsd fa5, (52+52)(sp) + fsd fa6, (56+56)(sp) + fsd fa7, (60+60)(sp) + fsd ft8, (64+64)(sp) + fsd ft9, (68+68)(sp) + fsd ft10,(72+72)(sp) + fsd ft11,(76+76)(sp) + + andi t2, t2, 0x3FF + mv a0, t2 + slli t2, t2, 3 + + la t2, interrupt_entry + jalr t2 + + csrc mstatus, 8 + + + /* write PLIC_CLAIM and exit interrupt */ + lw a1, (72+72+160)(sp) + andi a0, a1, 0x3FF + + csrr a2, 0xfc1 + li a1, 0x00201000 + add a2, a2, a1 + sw a0, 4(a2) + + li t0, MSTATUS_PRV1 + csrs mstatus, t0 + + fld ft0, (0 +0 )(sp) + fld ft1, (4 +4 )(sp) + fld ft2, (8 +8 )(sp) + fld ft3, (12+12)(sp) + fld ft4, (16+16)(sp) + fld ft5, (20+20)(sp) + fld ft6, (24+24)(sp) + fld ft7, (28+28)(sp) + fld fa0, (32+32)(sp) + fld fa1, (36+36)(sp) + fld fa2, (40+40)(sp) + fld fa3, (44+44)(sp) + fld fa4, (48+48)(sp) + fld fa5, (52+52)(sp) + fld fa6, (56+56)(sp) + fld fa7, (60+60)(sp) + fld ft8, (64+64)(sp) + fld ft9, (68+68)(sp) + fld ft10,(72+72)(sp) + fld ft11,(76+76)(sp) + + addi sp, sp, 160 + + ld t0, (68+68)(sp) + csrw mepc, t0 + ld ra, (0 +0 )(sp) + ld t0, (4 +4 )(sp) + ld t1, (8 +8 )(sp) + ld t2, (12+12)(sp) + ld a0, (16+16)(sp) + ld a1, (20+20)(sp) + ld a2, (24+24)(sp) + ld a3, (28+28)(sp) + ld a4, (32+32)(sp) + ld a5, (36+36)(sp) + ld a6, (40+40)(sp) + ld a7, (44+44)(sp) + ld t3, (48+48)(sp) + ld t4, (52+52)(sp) + ld t5, (56+56)(sp) + ld t6, (60+60)(sp) + + addi sp, sp, (76+76) + mret + +/**************************************************************************** + * Name: Default_IRQHandler + ****************************************************************************/ + /* M-mode external IRQ handler */ + .align 2 + .global Default_IRQHandler + .weak Default_IRQHandler + .type Default_IRQHandler, %function +Default_IRQHandler: + addi sp, sp, -(76+76) + sd t0, (4+4)(sp) + sd t1, (8+8)(sp) + sd t2, (12+12)(sp) + + csrr t0, 0xfc1 + li t1, 0x00200000 + add t0, t0, t1 + lw t2, 4(t0) + + csrr t0, mepc + sd t0, (68+68)(sp) + sd t2, (72+72)(sp) + sd ra, (0 +0 )(sp) + sd a0, (16+16)(sp) + sd a1, (20+20)(sp) + sd a2, (24+24)(sp) + sd a3, (28+28)(sp) + sd a4, (32+32)(sp) + sd a5, (36+36)(sp) + sd a6, (40+40)(sp) + sd a7, (44+44)(sp) + sd t3, (48+48)(sp) + sd t4, (52+52)(sp) + sd t5, (56+56)(sp) + sd t6, (60+60)(sp) + + addi sp, sp, -160 + fsd ft0, (0 +0 )(sp) + fsd ft1, (4 +4 )(sp) + fsd ft2, (8 +8 )(sp) + fsd ft3, (12+12)(sp) + fsd ft4, (16+16)(sp) + fsd ft5, (20+20)(sp) + fsd ft6, (24+24)(sp) + fsd ft7, (28+28)(sp) + fsd fa0, (32+32)(sp) + fsd fa1, (36+36)(sp) + fsd fa2, (40+40)(sp) + fsd fa3, (44+44)(sp) + fsd fa4, (48+48)(sp) + fsd fa5, (52+52)(sp) + fsd fa6, (56+56)(sp) + fsd fa7, (60+60)(sp) + fsd ft8, (64+64)(sp) + fsd ft9, (68+68)(sp) + fsd ft10,(72+72)(sp) + fsd ft11,(76+76)(sp) + + la t0, irq_nested_level + lw t1, 0(t0) + addi t1, t1, 1 + sw t1, 0(t0) + + andi t2, t2, 0x3FF + mv a0, t2 + slli t2, t2, 3 + + la t2, interrupt_entry + jalr t2 + + csrc mstatus, 8 + + + la t0, irq_nested_level + lw t1, 0(t0) + addi t1, t1, -1 + sw t1, 0(t0) + + /* write PLIC_CLAIM and exit interrupt */ + lw a1, (72+72+160)(sp) + andi a0, a1, 0x3FF + + csrr a2, 0xfc1 + li a1, 0x00200000 + add a2, a2, a1 + sw a0, 4(a2) + + li t0, MSTATUS_PRV1 + csrs mstatus, t0 + + fld ft0, (0 +0 )(sp) + fld ft1, (4 +4 )(sp) + fld ft2, (8 +8 )(sp) + fld ft3, (12+12)(sp) + fld ft4, (16+16)(sp) + fld ft5, (20+20)(sp) + fld ft6, (24+24)(sp) + fld ft7, (28+28)(sp) + fld fa0, (32+32)(sp) + fld fa1, (36+36)(sp) + fld fa2, (40+40)(sp) + fld fa3, (44+44)(sp) + fld fa4, (48+48)(sp) + fld fa5, (52+52)(sp) + fld fa6, (56+56)(sp) + fld fa7, (60+60)(sp) + fld ft8, (64+64)(sp) + fld ft9, (68+68)(sp) + fld ft10,(72+72)(sp) + fld ft11,(76+76)(sp) + + addi sp, sp, 160 + + ld t0, (68+68)(sp) + csrw mepc, t0 + ld ra, (0 +0 )(sp) + ld t0, (4 +4 )(sp) + ld t1, (8 +8 )(sp) + ld t2, (12+12)(sp) + ld a0, (16+16)(sp) + ld a1, (20+20)(sp) + ld a2, (24+24)(sp) + ld a3, (28+28)(sp) + ld a4, (32+32)(sp) + ld a5, (36+36)(sp) + ld a6, (40+40)(sp) + ld a7, (44+44)(sp) + ld t3, (48+48)(sp) + ld t4, (52+52)(sp) + ld t5, (56+56)(sp) + ld t6, (60+60)(sp) + + addi sp, sp, (76+76) + mret + +/**************************************************************************** + * Name: exception_common + ****************************************************************************/ + .align 6 + .weak exception_common + .global exception_common + .global Default_Handler + .type exception_common, %function + +Default_Handler: +exception_common: + + addi sp, sp, -XCPTCONTEXT_SIZE + + sd x1, REG_X1(sp) /* ra */ + /* sd x3, REG_X3(sp) */ /* gp */ + sd x4, REG_X4(sp) /* tp */ + sd x5, REG_X5(sp) /* t0 */ + sd x6, REG_X6(sp) /* t1 */ + sd x7, REG_X7(sp) /* t2 */ + sd x8, REG_X8(sp) /* s0 */ + sd x9, REG_X9(sp) /* s1 */ + sd x10, REG_X10(sp) /* a0 */ + sd x11, REG_X11(sp) /* a1 */ + sd x12, REG_X12(sp) /* a2 */ + sd x13, REG_X13(sp) /* a3 */ + sd x14, REG_X14(sp) /* a4 */ + sd x15, REG_X15(sp) /* a5 */ + sd x16, REG_X16(sp) /* a6 */ + sd x17, REG_X17(sp) /* a7 */ + sd x18, REG_X18(sp) /* s2 */ + sd x19, REG_X19(sp) /* s3 */ + sd x20, REG_X20(sp) /* s4 */ + sd x21, REG_X21(sp) /* s5 */ + sd x22, REG_X22(sp) /* s6 */ + sd x23, REG_X23(sp) /* s7 */ + sd x24, REG_X24(sp) /* s8 */ + sd x25, REG_X25(sp) /* s9 */ + sd x26, REG_X26(sp) /* s10 */ + sd x27, REG_X27(sp) /* s11 */ + sd x28, REG_X28(sp) /* t3 */ + sd x29, REG_X29(sp) /* t4 */ + sd x30, REG_X30(sp) /* t5 */ + sd x31, REG_X31(sp) /* t6 */ + + csrr s0, mstatus + sd s0, REG_INT_CTX(sp) /* mstatus */ + + addi s0, sp, XCPTCONTEXT_SIZE + sd s0, REG_X2(sp) /* original SP */ + + /* Setup arg0(exception cause), arg1(context) */ + + csrr a0, mcause /* exception cause */ + csrr s0, mepc + sd s0, REG_EPC(sp) /* exception PC */ + + mv a1, sp /* context = sp */ + + la sp, g_trap_sp + + /* Call interrupt handler in C */ + + jal x1, trap_c + + /* If context switch is needed, return a new sp */ + + mv sp, a0 + ld s0, REG_EPC(sp) /* restore mepc */ + csrw mepc, s0 + + ld s0, REG_INT_CTX(sp) /* restore mstatus */ + csrw mstatus, s0 + + /* ld x3, REG_X3(sp) */ /* gp */ + ld x4, REG_X4(sp) /* tp */ + ld x5, REG_X5(sp) /* t0 */ + ld x6, REG_X6(sp) /* t1 */ + ld x7, REG_X7(sp) /* t2 */ + ld x8, REG_X8(sp) /* s0 */ + ld x9, REG_X9(sp) /* s1 */ + ld x10, REG_X10(sp) /* a0 */ + ld x11, REG_X11(sp) /* a1 */ + ld x12, REG_X12(sp) /* a2 */ + ld x13, REG_X13(sp) /* a3 */ + ld x14, REG_X14(sp) /* a4 */ + ld x15, REG_X15(sp) /* a5 */ + ld x16, REG_X16(sp) /* a6 */ + ld x17, REG_X17(sp) /* a7 */ + ld x18, REG_X18(sp) /* s2 */ + ld x19, REG_X19(sp) /* s3 */ + ld x20, REG_X20(sp) /* s4 */ + ld x21, REG_X21(sp) /* s5 */ + ld x22, REG_X22(sp) /* s6 */ + ld x23, REG_X23(sp) /* s7 */ + ld x24, REG_X24(sp) /* s8 */ + ld x25, REG_X25(sp) /* s9 */ + ld x26, REG_X26(sp) /* s10 */ + ld x27, REG_X27(sp) /* s11 */ + ld x28, REG_X28(sp) /* t3 */ + ld x29, REG_X29(sp) /* t4 */ + ld x30, REG_X30(sp) /* t5 */ + ld x31, REG_X31(sp) /* t6 */ + + ld x1, REG_X1(sp) /* ra */ + + ld sp, REG_X2(sp) /* restore original sp */ + + /* Return from Machine Interrupt */ + + mret + + +/* Macro to define default handlers. Default handler + * will be weak symbol and just dead loops. They can be + * overwritten by other handlers */ + .macro def_irq_handler handler_name + .weak \handler_name + .globl \handler_name + .set \handler_name, Default_Handler + .endm + + def_irq_handler Stspend_Handler + def_irq_handler Stspend_Handler_S + def_irq_handler Mtspend_Handler + def_irq_handler M_SoftIRQ_ISR + def_irq_handler CORET_IRQHandler + def_irq_handler STIM0_IRQHandler + def_irq_handler STIM1_IRQHandler + def_irq_handler STIM2_IRQHandler + def_irq_handler STIM3_IRQHandler + def_irq_handler TIM0_IRQHandler + def_irq_handler TIM1_IRQHandler + def_irq_handler TIM2_IRQHandler + def_irq_handler TIM3_IRQHandler + def_irq_handler USART_IRQHandler + def_irq_handler GPIO0_IRQHandler + def_irq_handler GPIO1_IRQHandler + def_irq_handler GPIO2_IRQHandler + def_irq_handler GPIO3_IRQHandler + def_irq_handler GPIO4_IRQHandler + def_irq_handler GPIO5_IRQHandler + def_irq_handler GPIO6_IRQHandler + def_irq_handler GPIO7_IRQHandler + def_irq_handler PAD_IRQHandler + def_irq_handler HPM_OVF_IRQHandler diff --git a/drivers/soc/bl808/startup/m0/system_bl808.c b/drivers/soc/bl808/startup/m0/system_bl808.c index 1b20e626..1d9ac9fc 100644 --- a/drivers/soc/bl808/startup/m0/system_bl808.c +++ b/drivers/soc/bl808/startup/m0/system_bl808.c @@ -110,30 +110,10 @@ void SystemInit(void) GLB_Set_EM_Sel(GLB_WRAM160KB_EM0KB); } -#if defined(DUAL_CORE) -volatile uintptr_t ATTR_MP_SHARE_DATA_SECTION master_copy_done = 0; -#endif - void System_Post_Init(void) { - /* Bootrom not use dcache,so ignore this flush*/ -#ifndef BOOTROM csi_dcache_clean(); -#endif -#if defined(DUAL_CORE) - __DSB(); - -#if defined(DUAL_CORE) - if (GLB_CORE_ID_M0 == GLB_Get_Core_Type()) { -#endif - master_copy_done = 0xE906DAD5; -#if defined(DUAL_CORE) - } -#endif - - __DSB(); -#endif PDS_Power_On_MM_System(); /* make D0 all ram avalable for mcu usage */ GLB_Set_DSP_L2SRAM_Available_Size(3, 1, 1, 1); diff --git a/drivers/soc/bl808/startup/m0/vector.S b/drivers/soc/bl808/startup/m0/vector.S index 36001c2f..8b605245 100644 --- a/drivers/soc/bl808/startup/m0/vector.S +++ b/drivers/soc/bl808/startup/m0/vector.S @@ -101,6 +101,7 @@ default_interrupt_handler: * ~mem addr low: */ /* WARNING: global IRQ enabled by ipush */ + csrs mstatus, 8 /* keep stack 16bytes aligned */ addi sp, sp, -88 diff --git a/examples/bl808_dualcore/Makefile b/examples/bl808_dualcore/Makefile new file mode 100644 index 00000000..8d7dc301 --- /dev/null +++ b/examples/bl808_dualcore/Makefile @@ -0,0 +1,9 @@ +build_dirs += helloworld_m0 +build_dirs += helloworld_d0 + +all: $(build_dirs) + +$(build_dirs): + make -C $@ + +.PHONY: $(build_dirs) \ No newline at end of file diff --git a/examples/peripherals/gpio/gpio_output/CMakeLists.txt b/examples/bl808_dualcore/helloworld_d0/CMakeLists.txt similarity index 87% rename from examples/peripherals/gpio/gpio_output/CMakeLists.txt rename to examples/bl808_dualcore/helloworld_d0/CMakeLists.txt index 90320147..273cfe95 100644 --- a/examples/peripherals/gpio/gpio_output/CMakeLists.txt +++ b/examples/bl808_dualcore/helloworld_d0/CMakeLists.txt @@ -6,4 +6,4 @@ find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) sdk_set_main_file(main.c) -project(gpio_output) +project(helloworld) diff --git a/examples/bl808_dualcore/helloworld_d0/Makefile b/examples/bl808_dualcore/helloworld_d0/Makefile new file mode 100644 index 00000000..0e5cceeb --- /dev/null +++ b/examples/bl808_dualcore/helloworld_d0/Makefile @@ -0,0 +1,14 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../.. + +export BL_SDK_BASE + +CHIP ?= bl808 +BOARD ?= bl808dk +CPU_ID ?= d0 +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/bl808_dualcore/helloworld_d0/main.c b/examples/bl808_dualcore/helloworld_d0/main.c new file mode 100644 index 00000000..a24ee1f6 --- /dev/null +++ b/examples/bl808_dualcore/helloworld_d0/main.c @@ -0,0 +1,17 @@ +#include "bflb_mtimer.h" +#include "board.h" +#include "log.h" + +int main(void) +{ + board_init(); + while (1) { + LOG_F("hello world d0\r\n"); + LOG_E("hello world d0\r\n"); + LOG_W("hello world d0\r\n"); + LOG_I("hello world d0\r\n"); + LOG_D("hello world d0\r\n"); + LOG_T("hello world d0\r\n"); + bflb_mtimer_delay_ms(1000); + } +} diff --git a/examples/bl808_dualcore/helloworld_d0/proj.conf b/examples/bl808_dualcore/helloworld_d0/proj.conf new file mode 100644 index 00000000..75cf0407 --- /dev/null +++ b/examples/bl808_dualcore/helloworld_d0/proj.conf @@ -0,0 +1,2 @@ +set(CONFIG_VLIBC 0) +set(CONFIG_BFLOG 0) \ No newline at end of file diff --git a/examples/peripherals/adc/adc_oneshot_1ch/CMakeLists.txt b/examples/bl808_dualcore/helloworld_m0/CMakeLists.txt similarity index 85% rename from examples/peripherals/adc/adc_oneshot_1ch/CMakeLists.txt rename to examples/bl808_dualcore/helloworld_m0/CMakeLists.txt index 4ad28023..273cfe95 100644 --- a/examples/peripherals/adc/adc_oneshot_1ch/CMakeLists.txt +++ b/examples/bl808_dualcore/helloworld_m0/CMakeLists.txt @@ -6,4 +6,4 @@ find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) sdk_set_main_file(main.c) -project(adc_oneshot_1ch) +project(helloworld) diff --git a/examples/bl808_dualcore/helloworld_m0/Makefile b/examples/bl808_dualcore/helloworld_m0/Makefile new file mode 100644 index 00000000..74c1eabd --- /dev/null +++ b/examples/bl808_dualcore/helloworld_m0/Makefile @@ -0,0 +1,14 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../.. + +export BL_SDK_BASE + +CHIP ?= bl808 +BOARD ?= bl808dk +CPU_ID ?= m0 +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/bl808_dualcore/helloworld_m0/main.c b/examples/bl808_dualcore/helloworld_m0/main.c new file mode 100644 index 00000000..6b2c26ca --- /dev/null +++ b/examples/bl808_dualcore/helloworld_m0/main.c @@ -0,0 +1,17 @@ +#include "bflb_mtimer.h" +#include "board.h" +#include "log.h" + +int main(void) +{ + board_init(); + while (1) { + LOG_F("hello world m0\r\n"); + LOG_E("hello world m0\r\n"); + LOG_W("hello world m0\r\n"); + LOG_I("hello world m0\r\n"); + LOG_D("hello world m0\r\n"); + LOG_T("hello world m0\r\n"); + bflb_mtimer_delay_ms(1000); + } +} diff --git a/examples/bl808_dualcore/helloworld_m0/proj.conf b/examples/bl808_dualcore/helloworld_m0/proj.conf new file mode 100644 index 00000000..54ef6859 --- /dev/null +++ b/examples/bl808_dualcore/helloworld_m0/proj.conf @@ -0,0 +1,3 @@ +set(CONFIG_VLIBC 0) +set(CONFIG_BFLOG 0) +set(CONFIG_PSRAM 1) \ No newline at end of file diff --git a/examples/peripherals/adc/adc_oneshot_1ch_dma/CMakeLists.txt b/examples/peripherals/adc/adc_dma/CMakeLists.txt similarity index 83% rename from examples/peripherals/adc/adc_oneshot_1ch_dma/CMakeLists.txt rename to examples/peripherals/adc/adc_dma/CMakeLists.txt index f555d349..f5061422 100644 --- a/examples/peripherals/adc/adc_oneshot_1ch_dma/CMakeLists.txt +++ b/examples/peripherals/adc/adc_dma/CMakeLists.txt @@ -6,4 +6,4 @@ find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) sdk_set_main_file(main.c) -project(adc_oneshot_1ch_dma) +project(adc_dma) diff --git a/examples/peripherals/adc/adc_oneshot_1ch/Makefile b/examples/peripherals/adc/adc_dma/Makefile similarity index 100% rename from examples/peripherals/adc/adc_oneshot_1ch/Makefile rename to examples/peripherals/adc/adc_dma/Makefile diff --git a/examples/peripherals/adc/adc_dma/main.c b/examples/peripherals/adc/adc_dma/main.c new file mode 100644 index 00000000..eeb9ae30 --- /dev/null +++ b/examples/peripherals/adc/adc_dma/main.c @@ -0,0 +1,158 @@ +#include "bflb_adc.h" +#include "bflb_mtimer.h" +#include "bflb_dma.h" +#include "board.h" + +struct bflb_device_s *adc; +struct bflb_device_s *dma0_ch0; + +#define TEST_ADC_CHANNEL_0 1 +#define TEST_ADC_CHANNEL_1 1 +#define TEST_ADC_CHANNEL_2 1 +#define TEST_ADC_CHANNEL_3 1 +#define TEST_ADC_CHANNEL_4 1 +#define TEST_ADC_CHANNEL_5 1 +#define TEST_ADC_CHANNEL_6 1 +#define TEST_ADC_CHANNEL_7 1 +#define TEST_ADC_CHANNEL_8 1 +#define TEST_ADC_CHANNEL_9 1 +#define TEST_ADC_CHANNEL_10 1 + +#define TEST_ADC_CHANNELS (TEST_ADC_CHANNEL_0 + \ + TEST_ADC_CHANNEL_1 + \ + TEST_ADC_CHANNEL_2 + \ + TEST_ADC_CHANNEL_3 + \ + TEST_ADC_CHANNEL_4 + \ + TEST_ADC_CHANNEL_5 + \ + TEST_ADC_CHANNEL_6 + \ + TEST_ADC_CHANNEL_7 + \ + TEST_ADC_CHANNEL_8 + \ + TEST_ADC_CHANNEL_9 + \ + TEST_ADC_CHANNEL_10) + +struct bflb_adc_channel_s chan[] = { +#if TEST_ADC_CHANNEL_0 + { .pos_chan = ADC_CHANNEL_0, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_1 + { .pos_chan = ADC_CHANNEL_1, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_2 + { .pos_chan = ADC_CHANNEL_2, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_3 + { .pos_chan = ADC_CHANNEL_3, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_4 + { .pos_chan = ADC_CHANNEL_4, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_5 + { .pos_chan = ADC_CHANNEL_5, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_6 + { .pos_chan = ADC_CHANNEL_6, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_7 + { .pos_chan = ADC_CHANNEL_7, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_8 + { .pos_chan = ADC_CHANNEL_8, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_9 + { .pos_chan = ADC_CHANNEL_9, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_10 + { .pos_chan = ADC_CHANNEL_10, + .neg_chan = ADC_CHANNEL_GND }, +#endif +}; + +static uint8_t dma_tc_flag0 = 0; + +#define TEST_COUNT 16 + +ATTR_NOCACHE_NOINIT_RAM_SECTION uint32_t raw_data[TEST_ADC_CHANNELS * TEST_COUNT]; + +void dma0_ch0_isr(void *arg) +{ + dma_tc_flag0++; + printf("tc done\r\n"); +} + +int main(void) +{ + board_init(); + board_adc_gpio_init(); + + adc = bflb_device_get_by_name("adc"); + + /* adc clock = XCLK / 2 / 32 */ + struct bflb_adc_config_s cfg; + cfg.clk_div = ADC_CLK_DIV_32; + cfg.scan_conv_mode = true; + cfg.continuous_conv_mode = true; + cfg.differential_mode = false; + cfg.resolution = ADC_RESOLUTION_16B; + cfg.vref = ADC_VREF_3P2V; + + bflb_adc_init(adc, &cfg); + bflb_adc_channel_config(adc, chan, TEST_ADC_CHANNELS); + bflb_adc_link_rxdma(adc, true); + + dma0_ch0 = bflb_device_get_by_name("dma0_ch0"); + + struct bflb_dma_channel_config_s config; + + config.direction = DMA_PERIPH_TO_MEMORY; + config.src_req = DMA_REQUEST_ADC; + config.dst_req = DMA_REQUEST_NONE; + config.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE; + config.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE; + config.src_burst_count = DMA_BURST_INCR1; + config.dst_burst_count = DMA_BURST_INCR1; + config.src_width = DMA_DATA_WIDTH_32BIT; + config.dst_width = DMA_DATA_WIDTH_32BIT; + bflb_dma_channel_init(dma0_ch0, &config); + + bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL); + + struct bflb_dma_channel_lli_pool_s lli[1]; /* max trasnfer size 4064 * 1 */ + struct bflb_dma_channel_lli_transfer_s transfers[1]; + + memset(raw_data, 0, sizeof(raw_data)); + + transfers[0].src_addr = (uint32_t)DMA_ADDR_ADC_RDR; + transfers[0].dst_addr = (uint32_t)raw_data; + transfers[0].nbytes = sizeof(raw_data); + + bflb_dma_channel_lli_reload(dma0_ch0, lli, 1, transfers, 1); + bflb_dma_channel_start(dma0_ch0); + + bflb_adc_start_conversion(adc); + + while (dma_tc_flag0 != 1) { + bflb_mtimer_delay_ms(1); + } + + bflb_adc_stop_conversion(adc); + + for (size_t j = 0; j < TEST_ADC_CHANNELS * TEST_COUNT; j++) { + struct bflb_adc_result_s result; + printf("raw data:%08x\r\n", raw_data[j]); + bflb_adc_parse_result(adc, &raw_data[j], &result, 1); + printf("pos chan %d,%d mv \r\n", result.pos_chan, result.millivolt); + } + + while (1) { + } +} diff --git a/examples/peripherals/adc/adc_oneshot_1ch/proj.conf b/examples/peripherals/adc/adc_dma/proj.conf similarity index 100% rename from examples/peripherals/adc/adc_oneshot_1ch/proj.conf rename to examples/peripherals/adc/adc_dma/proj.conf diff --git a/examples/peripherals/adc/adc_oneshot_multich/CMakeLists.txt b/examples/peripherals/adc/adc_int/CMakeLists.txt similarity index 83% rename from examples/peripherals/adc/adc_oneshot_multich/CMakeLists.txt rename to examples/peripherals/adc/adc_int/CMakeLists.txt index 496c64e0..9c1aa83c 100644 --- a/examples/peripherals/adc/adc_oneshot_multich/CMakeLists.txt +++ b/examples/peripherals/adc/adc_int/CMakeLists.txt @@ -6,4 +6,4 @@ find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) sdk_set_main_file(main.c) -project(adc_oneshot_multich) +project(adc_int) diff --git a/examples/peripherals/adc/adc_oneshot_1ch_dma/Makefile b/examples/peripherals/adc/adc_int/Makefile similarity index 100% rename from examples/peripherals/adc/adc_oneshot_1ch_dma/Makefile rename to examples/peripherals/adc/adc_int/Makefile diff --git a/examples/peripherals/adc/adc_int/main.c b/examples/peripherals/adc/adc_int/main.c new file mode 100644 index 00000000..c2000557 --- /dev/null +++ b/examples/peripherals/adc/adc_int/main.c @@ -0,0 +1,137 @@ +#include "bflb_adc.h" +#include "bflb_mtimer.h" +#include "board.h" + +struct bflb_device_s *adc; + +#define TEST_ADC_CHANNEL_0 1 +#define TEST_ADC_CHANNEL_1 1 +#define TEST_ADC_CHANNEL_2 1 +#define TEST_ADC_CHANNEL_3 1 +#define TEST_ADC_CHANNEL_4 1 +#define TEST_ADC_CHANNEL_5 1 +#define TEST_ADC_CHANNEL_6 1 +#define TEST_ADC_CHANNEL_7 1 +#define TEST_ADC_CHANNEL_8 1 +#define TEST_ADC_CHANNEL_9 1 +#define TEST_ADC_CHANNEL_10 1 + +#define TEST_ADC_CHANNELS (TEST_ADC_CHANNEL_0 + \ + TEST_ADC_CHANNEL_1 + \ + TEST_ADC_CHANNEL_2 + \ + TEST_ADC_CHANNEL_3 + \ + TEST_ADC_CHANNEL_4 + \ + TEST_ADC_CHANNEL_5 + \ + TEST_ADC_CHANNEL_6 + \ + TEST_ADC_CHANNEL_7 + \ + TEST_ADC_CHANNEL_8 + \ + TEST_ADC_CHANNEL_9 + \ + TEST_ADC_CHANNEL_10) + +#define TEST_COUNT 10 + +struct bflb_adc_channel_s chan[] = { +#if TEST_ADC_CHANNEL_0 + { .pos_chan = ADC_CHANNEL_0, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_1 + { .pos_chan = ADC_CHANNEL_1, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_2 + { .pos_chan = ADC_CHANNEL_2, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_3 + { .pos_chan = ADC_CHANNEL_3, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_4 + { .pos_chan = ADC_CHANNEL_4, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_5 + { .pos_chan = ADC_CHANNEL_5, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_6 + { .pos_chan = ADC_CHANNEL_6, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_7 + { .pos_chan = ADC_CHANNEL_7, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_8 + { .pos_chan = ADC_CHANNEL_8, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_9 + { .pos_chan = ADC_CHANNEL_9, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_10 + { .pos_chan = ADC_CHANNEL_10, + .neg_chan = ADC_CHANNEL_GND }, +#endif +}; + +volatile uint32_t raw_data[TEST_ADC_CHANNELS]; +volatile uint8_t read_count = 0; + +void adc_isr(int irq, void *arg) +{ + uint32_t intstatus = bflb_adc_get_intstatus(adc); + if (intstatus & ADC_INTSTS_ADC_READY) { + bflb_adc_int_clear(adc, ADC_INTCLR_ADC_READY); + uint8_t count = bflb_adc_get_count(adc); + for (size_t i = 0; i < count; i++) { + raw_data[read_count] = bflb_adc_read_raw(adc); + read_count++; + } + } +} + +int main(void) +{ + board_init(); + board_adc_gpio_init(); + + adc = bflb_device_get_by_name("adc"); + + /* adc clock = XCLK / 2 / 32 */ + struct bflb_adc_config_s cfg; + cfg.clk_div = ADC_CLK_DIV_32; + cfg.scan_conv_mode = true; + cfg.continuous_conv_mode = false; + cfg.differential_mode = false; + cfg.resolution = ADC_RESOLUTION_16B; + cfg.vref = ADC_VREF_3P2V; + + bflb_adc_init(adc, &cfg); + bflb_adc_channel_config(adc, chan, TEST_ADC_CHANNELS); + bflb_adc_rxint_mask(adc, false); + bflb_irq_attach(adc->irq_num, adc_isr, NULL); + bflb_irq_enable(adc->irq_num); + + for (size_t i = 0; i < TEST_COUNT; i++) { + read_count = 0; + bflb_adc_start_conversion(adc); + + while (read_count < TEST_ADC_CHANNELS) { + bflb_mtimer_delay_ms(1); + } + for (size_t j = 0; j < TEST_ADC_CHANNELS; j++) { + struct bflb_adc_result_s result; + printf("raw data:%08x\r\n", raw_data[j]); + bflb_adc_parse_result(adc, (uint32_t *)&raw_data[j], &result, 1); + printf("pos chan %d,%d mv \r\n", result.pos_chan, result.millivolt); + } + bflb_adc_stop_conversion(adc); + bflb_mtimer_delay_ms(100); + } + + while (1) { + } +} diff --git a/examples/peripherals/adc/adc_oneshot_1ch_dma/proj.conf b/examples/peripherals/adc/adc_int/proj.conf similarity index 100% rename from examples/peripherals/adc/adc_oneshot_1ch_dma/proj.conf rename to examples/peripherals/adc/adc_int/proj.conf diff --git a/examples/peripherals/adc/adc_oneshot_1ch/main.c b/examples/peripherals/adc/adc_oneshot_1ch/main.c deleted file mode 100644 index 954ff150..00000000 --- a/examples/peripherals/adc/adc_oneshot_1ch/main.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "bflb_adc.h" -#include "bflb_mtimer.h" -#include "board.h" - -struct bflb_device_s *adc; - -int main(void) -{ - board_init(); - board_adc_gpio_init(); - - adc = bflb_device_get_by_name("adc"); - - struct bflb_adc_config_s cfg; - cfg.clk_div = ADC_CLK_DIV_32; - cfg.scan_conv_mode = false; - cfg.continuous_conv_mode = false; - cfg.differential_mode = false; - cfg.resolution = ADC_RESOLUTION_16B; - cfg.vref = ADC_VREF_3P2V; - - struct bflb_adc_channel_s chan; - - chan.pos_chan = ADC_CHANNEL_8; - chan.neg_chan = ADC_CHANNEL_GND; - - bflb_adc_init(adc, &cfg); - bflb_adc_channel_config(adc, &chan, 1); - - for (uint32_t i = 0; i < 10; i++) { - bflb_adc_start_conversion(adc); - - while (bflb_adc_get_count(adc) == 0) { - } - struct bflb_adc_result_s result; - uint32_t raw_data = bflb_adc_read_raw(adc); - printf("raw data:%08x\r\n", raw_data); - bflb_adc_parse_result(adc, &raw_data, &result, 1); - printf("pos chan %d,%d mv \r\n", result.pos_chan, result.millivolt); - bflb_adc_stop_conversion(adc); - bflb_mtimer_delay_ms(100); - } - - while (1) { - } -} diff --git a/examples/peripherals/adc/adc_oneshot_1ch_dma/main.c b/examples/peripherals/adc/adc_oneshot_1ch_dma/main.c deleted file mode 100644 index 93a90363..00000000 --- a/examples/peripherals/adc/adc_oneshot_1ch_dma/main.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "bflb_adc.h" -#include "bflb_mtimer.h" -#include "bflb_dma.h" -#include "board.h" - -struct bflb_device_s *adc; -struct bflb_device_s *dma0_ch0; - -extern void board_init(); - -static uint8_t dma_tc_flag0 = 0; - -#define ADC_CONVERT_COUNT 16 - -ATTR_NOCACHE_NOINIT_RAM_SECTION uint32_t raw_data[ADC_CONVERT_COUNT]; - -void dma0_ch0_isr(void *arg) -{ - dma_tc_flag0++; - printf("tc done\r\n"); -} - -int main(void) -{ - board_init(); - board_adc_gpio_init(); - - adc = bflb_device_get_by_name("adc"); - - struct bflb_adc_config_s cfg; - cfg.clk_div = ADC_CLK_DIV_32; - cfg.scan_conv_mode = false; - cfg.continuous_conv_mode = true; - cfg.differential_mode = false; - cfg.resolution = ADC_RESOLUTION_16B; - cfg.vref = ADC_VREF_3P2V; - - struct bflb_adc_channel_s chan; - - chan.pos_chan = ADC_CHANNEL_0; - chan.neg_chan = ADC_CHANNEL_GND; - - bflb_adc_init(adc, &cfg); - bflb_adc_channel_config(adc, &chan, 1); - bflb_adc_link_rxdma(adc, true); - - struct bflb_dma_channel_config_s config; - - dma0_ch0 = bflb_device_get_by_name("dma0_ch0"); - - config.direction = DMA_PERIPH_TO_MEMORY; - config.src_req = DMA_REQUEST_ADC; - config.dst_req = DMA_REQUEST_NONE; - config.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE; - config.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE; - config.src_burst_count = DMA_BURST_INCR1; - config.dst_burst_count = DMA_BURST_INCR1; - config.src_width = DMA_DATA_WIDTH_32BIT; - config.dst_width = DMA_DATA_WIDTH_32BIT; - bflb_dma_channel_init(dma0_ch0, &config); - - bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL); - - struct bflb_dma_channel_lli_pool_s lli[1]; /* max trasnfer size 4064 * 1 */ - struct bflb_dma_channel_lli_transfer_s transfers[1]; - - memset(raw_data, 0, sizeof(raw_data)); - - transfers[0].src_addr = (uint32_t)DMA_ADDR_ADC_RDR; - transfers[0].dst_addr = (uint32_t)raw_data; - transfers[0].nbytes = 64; - - bflb_dma_channel_lli_reload(dma0_ch0, lli, 1, transfers, 1); - bflb_dma_channel_start(dma0_ch0); - - bflb_adc_start_conversion(adc); - - while (dma_tc_flag0 != 1) { - bflb_mtimer_delay_ms(1); - } - struct bflb_adc_result_s result[ADC_CONVERT_COUNT]; - - bflb_adc_parse_result(adc, raw_data, result, ADC_CONVERT_COUNT); - - for (uint8_t i = 0; i < ADC_CONVERT_COUNT; i++) { - printf("raw data:%08x\r\n", raw_data[i]); - printf("pos chan %d,%d mv \r\n", result[i].pos_chan, result[i].millivolt); - } - - bflb_adc_stop_conversion(adc); - - while (1) { - } -} diff --git a/examples/peripherals/adc/adc_oneshot_1ch_int/main.c b/examples/peripherals/adc/adc_oneshot_1ch_int/main.c deleted file mode 100644 index abb5c0cd..00000000 --- a/examples/peripherals/adc/adc_oneshot_1ch_int/main.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "bflb_adc.h" -#include "bflb_mtimer.h" -#include "board.h" - -struct bflb_device_s *adc; -static uint8_t int_flag = 0; - -void adc_isr(int irq, void *arg) -{ - uint32_t intstatus = bflb_adc_get_intstatus(adc); - if (intstatus&ADC_INTSTS_ADC_READY) { - struct bflb_adc_result_s result; - - printf("INT fifo count = %d \n", bflb_adc_get_count(adc)); - - do { - uint32_t raw_data = bflb_adc_read_raw(adc); - if (raw_data) { - bflb_adc_parse_result(adc, &raw_data, &result, 1); - printf("PosId = %d NegId = %d V= %d mV \n", result.pos_chan, result.neg_chan, result.millivolt); - bflb_adc_int_clear(adc, ADC_INTCLR_ADC_READY); - int_flag++; - } - } while (bflb_adc_get_count(adc) != 0); - - if (int_flag > 16) { - bflb_adc_rxint_mask(adc, true); - } - } -} - -int main(void) -{ - board_init(); - board_adc_gpio_init(); - - adc = bflb_device_get_by_name("adc"); - - struct bflb_adc_config_s cfg; - cfg.clk_div = ADC_CLK_DIV_32; - cfg.scan_conv_mode = false; - cfg.continuous_conv_mode = false; - cfg.differential_mode = false; - cfg.resolution = ADC_RESOLUTION_16B; - cfg.vref = ADC_VREF_3P2V; - - struct bflb_adc_channel_s chan; - - chan.pos_chan = ADC_CHANNEL_8; - chan.neg_chan = ADC_CHANNEL_GND; - - bflb_adc_init(adc, &cfg); - bflb_adc_channel_config(adc, &chan, 1); - - bflb_adc_int_clear(adc, ADC_INTCLR_ADC_READY); - bflb_adc_rxint_mask(adc, false); - bflb_irq_attach(adc->irq_num, adc_isr, adc); - bflb_irq_enable(adc->irq_num); - - while (int_flag < 16) { - printf("%d\r\n", int_flag); - bflb_adc_start_conversion(adc); - bflb_mtimer_delay_ms(500); - bflb_adc_stop_conversion(adc); - } -} diff --git a/examples/peripherals/adc/adc_poll/CMakeLists.txt b/examples/peripherals/adc/adc_poll/CMakeLists.txt new file mode 100644 index 00000000..3f7af4cf --- /dev/null +++ b/examples/peripherals/adc/adc_poll/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(adc_poll) diff --git a/examples/peripherals/adc/adc_oneshot_1ch_int/Makefile b/examples/peripherals/adc/adc_poll/Makefile similarity index 100% rename from examples/peripherals/adc/adc_oneshot_1ch_int/Makefile rename to examples/peripherals/adc/adc_poll/Makefile diff --git a/examples/peripherals/adc/adc_poll/main.c b/examples/peripherals/adc/adc_poll/main.c new file mode 100644 index 00000000..90e8c1a7 --- /dev/null +++ b/examples/peripherals/adc/adc_poll/main.c @@ -0,0 +1,120 @@ +#include "bflb_adc.h" +#include "bflb_mtimer.h" +#include "board.h" + +struct bflb_device_s *adc; + +#define TEST_ADC_CHANNEL_0 1 +#define TEST_ADC_CHANNEL_1 1 +#define TEST_ADC_CHANNEL_2 1 +#define TEST_ADC_CHANNEL_3 1 +#define TEST_ADC_CHANNEL_4 1 +#define TEST_ADC_CHANNEL_5 1 +#define TEST_ADC_CHANNEL_6 1 +#define TEST_ADC_CHANNEL_7 1 +#define TEST_ADC_CHANNEL_8 1 +#define TEST_ADC_CHANNEL_9 1 +#define TEST_ADC_CHANNEL_10 1 + +#define TEST_ADC_CHANNELS (TEST_ADC_CHANNEL_0 + \ + TEST_ADC_CHANNEL_1 + \ + TEST_ADC_CHANNEL_2 + \ + TEST_ADC_CHANNEL_3 + \ + TEST_ADC_CHANNEL_4 + \ + TEST_ADC_CHANNEL_5 + \ + TEST_ADC_CHANNEL_6 + \ + TEST_ADC_CHANNEL_7 + \ + TEST_ADC_CHANNEL_8 + \ + TEST_ADC_CHANNEL_9 + \ + TEST_ADC_CHANNEL_10) + +#define TEST_COUNT 10 + +struct bflb_adc_channel_s chan[] = { +#if TEST_ADC_CHANNEL_0 + { .pos_chan = ADC_CHANNEL_0, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_1 + { .pos_chan = ADC_CHANNEL_1, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_2 + { .pos_chan = ADC_CHANNEL_2, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_3 + { .pos_chan = ADC_CHANNEL_3, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_4 + { .pos_chan = ADC_CHANNEL_4, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_5 + { .pos_chan = ADC_CHANNEL_5, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_6 + { .pos_chan = ADC_CHANNEL_6, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_7 + { .pos_chan = ADC_CHANNEL_7, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_8 + { .pos_chan = ADC_CHANNEL_8, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_9 + { .pos_chan = ADC_CHANNEL_9, + .neg_chan = ADC_CHANNEL_GND }, +#endif +#if TEST_ADC_CHANNEL_10 + { .pos_chan = ADC_CHANNEL_10, + .neg_chan = ADC_CHANNEL_GND }, +#endif +}; + +int main(void) +{ + board_init(); + board_adc_gpio_init(); + + adc = bflb_device_get_by_name("adc"); + + /* adc clock = XCLK / 2 / 32 */ + struct bflb_adc_config_s cfg; + cfg.clk_div = ADC_CLK_DIV_32; + cfg.scan_conv_mode = true; + cfg.continuous_conv_mode = false; + cfg.differential_mode = false; + cfg.resolution = ADC_RESOLUTION_16B; + cfg.vref = ADC_VREF_3P2V; + + bflb_adc_init(adc, &cfg); + bflb_adc_channel_config(adc, chan, TEST_ADC_CHANNELS); + + for (uint32_t i = 0; i < TEST_COUNT; i++) { + bflb_adc_start_conversion(adc); + + while (bflb_adc_get_count(adc) < TEST_ADC_CHANNELS) { + bflb_mtimer_delay_ms(1); + } + + for (size_t j = 0; j < TEST_ADC_CHANNELS; j++) { + struct bflb_adc_result_s result; + uint32_t raw_data = bflb_adc_read_raw(adc); + printf("raw data:%08x\r\n", raw_data); + bflb_adc_parse_result(adc, &raw_data, &result, 1); + printf("pos chan %d,%d mv \r\n", result.pos_chan, result.millivolt); + } + + bflb_adc_stop_conversion(adc); + bflb_mtimer_delay_ms(100); + } + + while (1) { + } +} diff --git a/examples/peripherals/adc/adc_oneshot_1ch_int/proj.conf b/examples/peripherals/adc/adc_poll/proj.conf similarity index 100% rename from examples/peripherals/adc/adc_oneshot_1ch_int/proj.conf rename to examples/peripherals/adc/adc_poll/proj.conf diff --git a/examples/peripherals/adc/adc_poll_diff_mode/CMakeLists.txt b/examples/peripherals/adc/adc_poll_diff_mode/CMakeLists.txt new file mode 100644 index 00000000..6a5ab583 --- /dev/null +++ b/examples/peripherals/adc/adc_poll_diff_mode/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(adc_poll_diff_mode) diff --git a/examples/peripherals/adc/adc_oneshot_multich/Makefile b/examples/peripherals/adc/adc_poll_diff_mode/Makefile similarity index 100% rename from examples/peripherals/adc/adc_oneshot_multich/Makefile rename to examples/peripherals/adc/adc_poll_diff_mode/Makefile diff --git a/examples/peripherals/adc/adc_oneshot_multich/main.c b/examples/peripherals/adc/adc_poll_diff_mode/main.c similarity index 52% rename from examples/peripherals/adc/adc_oneshot_multich/main.c rename to examples/peripherals/adc/adc_poll_diff_mode/main.c index 2847f518..b8f253a1 100644 --- a/examples/peripherals/adc/adc_oneshot_multich/main.c +++ b/examples/peripherals/adc/adc_poll_diff_mode/main.c @@ -4,6 +4,17 @@ struct bflb_device_s *adc; +#define TEST_ADC_CHANNELS 2 + +#define TEST_COUNT 10 + +struct bflb_adc_channel_s chan[] = { + { .pos_chan = ADC_CHANNEL_2, + .neg_chan = ADC_CHANNEL_GND }, + { .pos_chan = ADC_CHANNEL_GND, + .neg_chan = ADC_CHANNEL_3 }, +}; + int main(void) { board_init(); @@ -11,37 +22,31 @@ int main(void) adc = bflb_device_get_by_name("adc"); + /* adc clock = XCLK / 2 / 32 */ struct bflb_adc_config_s cfg; cfg.clk_div = ADC_CLK_DIV_32; cfg.scan_conv_mode = true; cfg.continuous_conv_mode = false; - cfg.differential_mode = false; + cfg.differential_mode = true; cfg.resolution = ADC_RESOLUTION_16B; cfg.vref = ADC_VREF_3P2V; - struct bflb_adc_channel_s chan[3]; - - chan[0].pos_chan = ADC_CHANNEL_8; - chan[0].neg_chan = ADC_CHANNEL_GND; - chan[1].pos_chan = ADC_CHANNEL_9; - chan[1].neg_chan = ADC_CHANNEL_GND; - chan[2].pos_chan = ADC_CHANNEL_10; - chan[2].neg_chan = ADC_CHANNEL_GND; - bflb_adc_init(adc, &cfg); - bflb_adc_channel_config(adc, chan, 3); + bflb_adc_channel_config(adc, chan, TEST_ADC_CHANNELS); - for (uint32_t i = 0; i < 10; i++) { + for (uint32_t i = 0; i < TEST_COUNT; i++) { bflb_adc_start_conversion(adc); - while (bflb_adc_get_count(adc) < 3) { - } - struct bflb_adc_result_s result; - for (uint8_t i = 0; i < 3; i++) { + while (bflb_adc_get_count(adc) < TEST_ADC_CHANNELS) { + bflb_mtimer_delay_ms(1); + } + + for (size_t j = 0; j < TEST_ADC_CHANNELS; j++) { + struct bflb_adc_result_s result; uint32_t raw_data = bflb_adc_read_raw(adc); printf("raw data:%08x\r\n", raw_data); bflb_adc_parse_result(adc, &raw_data, &result, 1); - printf("pos chan %d,%d mv \r\n", result.pos_chan, result.millivolt); + printf("pos chan %d,neg chan %d,%d mv \r\n", result.pos_chan, result.neg_chan, result.millivolt); } bflb_adc_stop_conversion(adc); diff --git a/examples/peripherals/adc/adc_oneshot_multich/proj.conf b/examples/peripherals/adc/adc_poll_diff_mode/proj.conf similarity index 100% rename from examples/peripherals/adc/adc_oneshot_multich/proj.conf rename to examples/peripherals/adc/adc_poll_diff_mode/proj.conf diff --git a/examples/peripherals/adc/adc_tsen/main.c b/examples/peripherals/adc/adc_tsen/main.c index cf7689a8..fd8a68c7 100644 --- a/examples/peripherals/adc/adc_tsen/main.c +++ b/examples/peripherals/adc/adc_tsen/main.c @@ -1,4 +1,5 @@ #include "bflb_adc.h" +#include "bflb_efuse.h" #include "bflb_mtimer.h" #include "board.h" @@ -10,12 +11,12 @@ int main(void) board_adc_gpio_init(); uint16_t i = 0; float average_filter = 0.0; - uint16_t tsen_offset = 2042; adc = bflb_device_get_by_name("adc"); + /* adc clock = XCLK / 2 / 32 */ struct bflb_adc_config_s cfg; - cfg.clk_div = ADC_CLK_DIV_16; + cfg.clk_div = ADC_CLK_DIV_32; cfg.scan_conv_mode = false; cfg.continuous_conv_mode = false; cfg.differential_mode = false; @@ -33,7 +34,7 @@ int main(void) while (1) { for (i = 0; i < 50; i++) { - average_filter += bflb_adc_tsen_get_temp(adc, tsen_offset); + average_filter += bflb_adc_tsen_get_temp(adc); bflb_mtimer_delay_ms(10); } diff --git a/examples/peripherals/adc/adc_vbat/main.c b/examples/peripherals/adc/adc_vbat/main.c index 7dfd3c6b..05de8bb9 100644 --- a/examples/peripherals/adc/adc_vbat/main.c +++ b/examples/peripherals/adc/adc_vbat/main.c @@ -7,17 +7,17 @@ struct bflb_device_s *adc; int main(void) { board_init(); - uint16_t i = 0; adc = bflb_device_get_by_name("adc"); + /* adc clock = XCLK / 2 / 32 */ struct bflb_adc_config_s cfg; - cfg.clk_div = ADC_CLK_DIV_4; + cfg.clk_div = ADC_CLK_DIV_32; cfg.scan_conv_mode = false; cfg.continuous_conv_mode = false; cfg.differential_mode = false; cfg.resolution = ADC_RESOLUTION_16B; - cfg.vref = ADC_VREF_2P0V; + cfg.vref = ADC_VREF_3P2V; struct bflb_adc_channel_s chan; @@ -29,19 +29,16 @@ int main(void) bflb_adc_vbat_enable(adc); struct bflb_adc_result_s result; - for (i = 0; i < 10; i++) { + for (uint16_t i = 0; i < 10; i++) { bflb_adc_start_conversion(adc); + while (bflb_adc_get_count(adc) == 0) { + bflb_mtimer_delay_ms(1); + } + uint32_t raw_data = bflb_adc_read_raw(adc); - while (bflb_adc_get_count(adc) == 0) - ; - do { - uint32_t raw_data = bflb_adc_read_raw(adc); - if (raw_data) { - bflb_adc_parse_result(adc, &raw_data, &result, 1); - printf("vBat = %d mV\n", (uint32_t)(result.millivolt * 2)); - bflb_adc_stop_conversion(adc); - } - } while (bflb_adc_get_count(adc) != 0); + bflb_adc_parse_result(adc, &raw_data, &result, 1); + printf("vBat = %d mV\r\n", (uint32_t)(result.millivolt * 2)); + bflb_adc_stop_conversion(adc); bflb_mtimer_delay_ms(500); } diff --git a/examples/peripherals/cks/cks_dma/main.c b/examples/peripherals/cks/cks_dma/main.c index bfdcc211..ae8db2e0 100644 --- a/examples/peripherals/cks/cks_dma/main.c +++ b/examples/peripherals/cks/cks_dma/main.c @@ -2,10 +2,9 @@ #include "bflb_cks.h" #include "bflb_dma.h" #include "bflb_mtimer.h" -#include "bl628_memorymap.h" #include "bflb_core.h" -#define DATA_LEN 1024 +#define DATA_LEN 512 static volatile uint8_t dma_tc_flag0 = 0; struct bflb_device_s *cks; @@ -23,7 +22,7 @@ uint16_t sw_chksum(uint8_t *data, uint32_t len) { uint32_t size = len; if (len % 2 == 1) { - size=len-1; + size = len - 1; sum += data[size]; } @@ -48,7 +47,7 @@ uint16_t get_cks_with_dma(uint8_t* data,uint32_t length) struct bflb_dma_channel_lli_transfer_s transfers[1]; transfers[0].src_addr = (uint32_t)data; - transfers[0].dst_addr = (uint32_t)(CKS_BASE+0x4); + transfers[0].dst_addr = (uint32_t)(cks->reg_base + 0x4); transfers[0].nbytes = length; bflb_dma_channel_lli_reload(dma0_ch0, lli, 20, transfers, 1); @@ -70,10 +69,10 @@ static void test_case1(void){ uint32_t time = 0, i; struct bflb_dma_channel_config_s config; - static uint32_t data_src1[DATA_LEN/4]; + uint32_t data_src1[DATA_LEN/4]; for(i = 0;i < DATA_LEN; i++){ - ((uint8_t *)data_src1)[i] = i&0xff; + ((uint8_t *)data_src1)[i] = i & 0xff; } time = (unsigned int)bflb_mtimer_get_time_us(); diff --git a/examples/peripherals/cks/cks_normal/main.c b/examples/peripherals/cks/cks_normal/main.c index 709fd4d3..fc70dc62 100644 --- a/examples/peripherals/cks/cks_normal/main.c +++ b/examples/peripherals/cks/cks_normal/main.c @@ -22,7 +22,7 @@ static void test_case1(struct bflb_device_s *dev) { cks = bflb_cks_compute(dev, (uint8_t *)data_src1, sizeof(data_src1)); if (cks != (data_src1_cks[0] << 8 | data_src1_cks[1])) { - printf("Error! CKS result with LE is %04x, should be %02x%02x\r\n", cks, data_src1_cks[1], data_src1_cks[0]); + printf("Error! CKS result with LE is %04x, should be %02x%02x\r\n", cks, data_src1_cks[0], data_src1_cks[1]); } else { printf("Pass\r\n"); } @@ -59,7 +59,11 @@ static void test_case2(struct bflb_device_s *dev) { checksum = (checksum >> 16) + (checksum & 0xFFFF); } - printf("CKS LE result is %04x, %04x\r\n", cks, (uint16_t)~checksum); + if (cks != (uint16_t)(~checksum << 8 | (~checksum >> 8 & 0xff))) { + printf("Error! CKS result with LE is %04x, should be %04x\r\n", cks, (uint16_t)(~checksum << 8 | (~checksum >> 8 & 0xff))); + } else { + printf("Pass\r\n"); + } bflb_cks_reset(dev); bflb_cks_set_endian(dev, CKS_BIG_ENDIAN); @@ -75,11 +79,10 @@ static void test_case2(struct bflb_device_s *dev) { checksum = (checksum >> 16) + (checksum & 0xFFFF); } - printf("CKS BE result is %04x, %04x\r\n", cks, (uint16_t)~checksum); - if (cks == ((uint16_t)~checksum)) { - printf("====== Success %04X Checksum=====\r\n", cks); + if (cks != (uint16_t)~checksum) { + printf("Error! CKS result with BE is %04x, should be %04x\r\n", cks, (uint16_t)~checksum); } else { - printf("====== Failed %04X Checksum======\r\n", cks); + printf("Pass\r\n"); } } @@ -104,7 +107,11 @@ static void test_case3(struct bflb_device_s *dev) { checksum = (checksum >> 16) + (checksum & 0xFFFF); } - printf("CKS LE result is %04x, %04x\r\n", cks, (uint16_t)~checksum); + if (cks != (uint16_t)(~checksum << 8 | (~checksum >> 8 & 0xff))) { + printf("Error! CKS result with LE is %04x, should be %04x\r\n", cks, (uint16_t)(~checksum << 8 | (~checksum >> 8 & 0xff))); + } else { + printf("Pass\r\n"); + } bflb_cks_reset(dev); bflb_cks_set_endian(dev, CKS_BIG_ENDIAN); @@ -120,11 +127,10 @@ static void test_case3(struct bflb_device_s *dev) { checksum = (checksum >> 16) + (checksum & 0xFFFF); } - printf("CKS BE result is %04x, %04x\r\n", cks, (uint16_t)~checksum); - if (cks == ((uint16_t)~checksum)) { - printf("====== Success %04X Checksum=====\r\n", cks); + if (cks != (uint16_t)~checksum) { + printf("Error! CKS result with BE is %04x, should be %04x\r\n", cks, (uint16_t)~checksum); } else { - printf("====== Failed %04X Checksum======\r\n", cks); + printf("Pass\r\n"); } } @@ -152,7 +158,11 @@ static void test_case4(struct bflb_device_s *dev) { } cks = bflb_cks_compute(dev, &data_segment_two, 1); - printf("CKS LE result is %04x, %04x\r\n", cks, (uint16_t)~checksum); + if (cks != (uint16_t)(~checksum << 8 | (~checksum >> 8 & 0xff))) { + printf("Error! CKS result with LE is %04x, should be %04x\r\n", cks, (uint16_t)(~checksum << 8 | (~checksum >> 8 & 0xff))); + } else { + printf("Pass\r\n"); + } bflb_cks_reset(dev); bflb_cks_set_endian(dev, CKS_BIG_ENDIAN); @@ -170,11 +180,10 @@ static void test_case4(struct bflb_device_s *dev) { } cks = bflb_cks_compute(dev, &data_segment_two, 1); - printf("CKS BE result is %04x, %04x\r\n", cks, (uint16_t)~checksum); - if (cks == ((uint16_t)~checksum)) { - printf("====== Success %04X Checksum=====\r\n", cks); + if (cks != (uint16_t)~checksum) { + printf("Error! CKS result with BE is %04x, should be %04x\r\n", cks, (uint16_t)~checksum); } else { - printf("====== Failed %04X Checksum======\r\n", cks); + printf("Pass\r\n"); } } @@ -230,6 +239,8 @@ static void test_case5(struct bflb_device_s *dev) { if (sw_cks != hw_cks) { printf("Error!\r\n"); + } else { + printf("Pass\r\n"); } } diff --git a/examples/peripherals/dma/dma_reduce_or_add/main.c b/examples/peripherals/dma/dma_reduce_or_add/main.c index 7efe3add..99bdf443 100644 --- a/examples/peripherals/dma/dma_reduce_or_add/main.c +++ b/examples/peripherals/dma/dma_reduce_or_add/main.c @@ -124,6 +124,8 @@ int main(void) config.dst_width = DMA_DATA_WIDTH_32BIT; bflb_dma_channel_init(dma0_ch0, &config); + bflb_dma_channel_tcint_mask(dma0_ch0, false); + transfers[0].nbytes = DMA_TRANSFER_LENGTH + 1; bflb_dma_channel_lli_reload(dma0_ch0, lli, 20, transfers, 1); diff --git a/examples/peripherals/flash/flash_dma/CMakeLists.txt b/examples/peripherals/flash/flash_dma/CMakeLists.txt new file mode 100644 index 00000000..38b49285 --- /dev/null +++ b/examples/peripherals/flash/flash_dma/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(flash_dma) diff --git a/examples/peripherals/gpio/gpio_output/Makefile b/examples/peripherals/flash/flash_dma/Makefile similarity index 100% rename from examples/peripherals/gpio/gpio_output/Makefile rename to examples/peripherals/flash/flash_dma/Makefile diff --git a/examples/peripherals/flash/flash_dma/main.c b/examples/peripherals/flash/flash_dma/main.c new file mode 100644 index 00000000..a6e2d4b2 --- /dev/null +++ b/examples/peripherals/flash/flash_dma/main.c @@ -0,0 +1,147 @@ +#include "bflb_flash.h" +#include "bflb_dma.h" +#include "board.h" + +#define DMA_BUFFER_LENGTH 260 +#define DMA_FLASH_ADDR_OFFSET 0 /* 0 or 28 */ + +static ATTR_NOCACHE_NOINIT_RAM_SECTION uint8_t dst_buffer[DMA_BUFFER_LENGTH]; + +static uint8_t src_burst[] = { + DMA_BURST_INCR1, + DMA_BURST_INCR1, + DMA_BURST_INCR1, + DMA_BURST_INCR4, + DMA_BURST_INCR4, + DMA_BURST_INCR4, + DMA_BURST_INCR8, + DMA_BURST_INCR8, + DMA_BURST_INCR8, + DMA_BURST_INCR16, + DMA_BURST_INCR16, + DMA_BURST_INCR16, +}; + +static uint8_t dst_burst[] = { + DMA_BURST_INCR1, + DMA_BURST_INCR1, + DMA_BURST_INCR1, + DMA_BURST_INCR4, + DMA_BURST_INCR4, + DMA_BURST_INCR4, + DMA_BURST_INCR8, + DMA_BURST_INCR8, + DMA_BURST_INCR8, + DMA_BURST_INCR16, + DMA_BURST_INCR16, + DMA_BURST_INCR16, +}; + +static uint8_t src_width[] = { + DMA_DATA_WIDTH_8BIT, + DMA_DATA_WIDTH_16BIT, + DMA_DATA_WIDTH_32BIT, + DMA_DATA_WIDTH_8BIT, + DMA_DATA_WIDTH_16BIT, + DMA_DATA_WIDTH_32BIT, + DMA_DATA_WIDTH_8BIT, + DMA_DATA_WIDTH_16BIT, + DMA_DATA_WIDTH_32BIT, + DMA_DATA_WIDTH_8BIT, + DMA_DATA_WIDTH_16BIT, + DMA_DATA_WIDTH_32BIT, +}; + +static uint8_t dst_width[] = { + DMA_DATA_WIDTH_8BIT, + DMA_DATA_WIDTH_16BIT, + DMA_DATA_WIDTH_32BIT, + DMA_DATA_WIDTH_8BIT, + DMA_DATA_WIDTH_16BIT, + DMA_DATA_WIDTH_32BIT, + DMA_DATA_WIDTH_8BIT, + DMA_DATA_WIDTH_16BIT, + DMA_DATA_WIDTH_32BIT, + DMA_DATA_WIDTH_8BIT, + DMA_DATA_WIDTH_16BIT, + DMA_DATA_WIDTH_32BIT, +}; + +static uint8_t dma_tc_flag0 = 0; + +struct bflb_device_s *dma0_ch0; + +volatile uint64_t start_time; + +void dma0_ch0_isr(void *arg) +{ + printf("cost time:%d us\r\n", (uint32_t)(bflb_mtimer_get_time_us() - start_time)); + dma_tc_flag0++; + printf("tc done\r\n"); +} + +int main(void) +{ + board_init(); + + uint8_t write_buf[DMA_BUFFER_LENGTH]; + + for (uint16_t i = 0; i < DMA_BUFFER_LENGTH; i++) { + write_buf[i] = (i & 0xff) + i / 256; + } + + /* erase 0x00010000 4k flash */ + bflb_flash_erase(0x00010000, 4096); + + /* write 0x00010000 flash data */ + bflb_flash_write(0x00010000, write_buf, sizeof(write_buf)); /* FLASH_XIP_BASE - 0x2000 + 0x00010000 */ + + dma0_ch0 = bflb_device_get_by_name("dma0_ch0"); + + struct bflb_dma_channel_config_s config; + + for (uint8_t i = 0; i < sizeof(src_burst); i++) { + dma_tc_flag0 = 0; + memset(dst_buffer, 0, DMA_BUFFER_LENGTH); + + config.direction = DMA_MEMORY_TO_MEMORY; + config.src_req = 0; + config.dst_req = 0; + config.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE; + config.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE; + config.src_burst_count = src_burst[i]; + config.dst_burst_count = dst_burst[i]; + config.src_width = src_width[i]; + config.dst_width = dst_width[i]; + bflb_dma_channel_init(dma0_ch0, &config); + + bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL); + + struct bflb_dma_channel_lli_pool_s lli[1]; /* max trasnfer size 4064 * 1 */ + struct bflb_dma_channel_lli_transfer_s transfers[1]; + + transfers[0].src_addr = (uint32_t)(FLASH_XIP_BASE - 0x2000 + 0x00010000 + DMA_FLASH_ADDR_OFFSET); + transfers[0].dst_addr = (uint32_t)dst_buffer; + transfers[0].nbytes = DMA_BUFFER_LENGTH - DMA_FLASH_ADDR_OFFSET; + + bflb_dma_channel_lli_reload(dma0_ch0, lli, 1, transfers, 1); + + start_time = bflb_mtimer_get_time_us(); + bflb_dma_channel_start(dma0_ch0); + while (dma_tc_flag0 != 1) { + bflb_mtimer_delay_ms(1); + } + + for (uint16_t j = 0; j < (DMA_BUFFER_LENGTH - DMA_FLASH_ADDR_OFFSET); j++) { + if (dst_buffer[j] != write_buf[DMA_FLASH_ADDR_OFFSET + j]) { + printf("flash test fail at %d, expect:%d but with %d\r\n", i, write_buf[DMA_FLASH_ADDR_OFFSET + j], dst_buffer[j]); + while (1) { + } + } + } + } + + printf("flash test success\r\n"); + while (1) { + } +} \ No newline at end of file diff --git a/examples/peripherals/flash/flash_dma/proj.conf b/examples/peripherals/flash/flash_dma/proj.conf new file mode 100644 index 00000000..13320d67 --- /dev/null +++ b/examples/peripherals/flash/flash_dma/proj.conf @@ -0,0 +1 @@ +#set(CONFIG_XXX 1) \ No newline at end of file diff --git a/examples/peripherals/flash/flash_iomode/CMakeLists.txt b/examples/peripherals/flash/flash_iomode/CMakeLists.txt new file mode 100644 index 00000000..9625ce8d --- /dev/null +++ b/examples/peripherals/flash/flash_iomode/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(flash_iomode) diff --git a/examples/peripherals/flash/flash_iomode/Makefile b/examples/peripherals/flash/flash_iomode/Makefile new file mode 100644 index 00000000..44367c02 --- /dev/null +++ b/examples/peripherals/flash/flash_iomode/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. + +export BL_SDK_BASE + +CHIP ?= bl616 +BOARD ?= bl616dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/flash/flash_iomode/main.c b/examples/peripherals/flash/flash_iomode/main.c new file mode 100644 index 00000000..067c776c --- /dev/null +++ b/examples/peripherals/flash/flash_iomode/main.c @@ -0,0 +1,52 @@ +#include "bflb_flash.h" +#include "board.h" + +const char *iomode_string[] = { "NIO", "DO", "QO", "DIO", "QIO" }; + +#define FLASH_DATA_LEN 4096 + +uint8_t write_buf[FLASH_DATA_LEN]; +uint8_t read_buf[FLASH_DATA_LEN]; + +uint64_t start_time; + +int main(void) +{ + board_init(); + + for (uint16_t i = 0; i < FLASH_DATA_LEN; i++) { + write_buf[i] = i & 0xff; + } + + for (uint8_t iomode = FLASH_IOMODE_NIO; iomode <= FLASH_IOMODE_QIO; iomode++) { + printf("select flash iomode:%s\r\n", iomode_string[iomode]); + bflb_flash_set_iomode(i); + + start_time = bflb_mtimer_get_time_ms(); + + /* erase 0x00010000 4k flash */ + bflb_flash_erase(0x00010000, 4096); + + /* write 0x00010000 flash data */ + bflb_flash_write(0x00010000, write_buf, sizeof(write_buf)); + + memset(read_buf, 0, FLASH_DATA_LEN); + + /* read 0x00010000 flash data */ + bflb_flash_read(0x00010000, read_buf, sizeof(read_buf)); + + printf("cost time:%lld ms\r\n", (bflb_mtimer_get_time_ms() - start_time)); + + for (i = 0; i < FLASH_DATA_LEN; i++) { + if (read_buf[i] != (i & 0xff)) { + printf("flash test fail at %d, expect:%d but with %d\r\n", i, (i & 0xff), read_buf[i]); + while (1) { + } + } + } + } + + printf("flash test success\r\n"); + while (1) { + } +} \ No newline at end of file diff --git a/examples/peripherals/flash/flash_iomode/proj.conf b/examples/peripherals/flash/flash_iomode/proj.conf new file mode 100644 index 00000000..13320d67 --- /dev/null +++ b/examples/peripherals/flash/flash_iomode/proj.conf @@ -0,0 +1 @@ +#set(CONFIG_XXX 1) \ No newline at end of file diff --git a/examples/peripherals/flash/flash_read_write/CMakeLists.txt b/examples/peripherals/flash/flash_read_write/CMakeLists.txt new file mode 100644 index 00000000..0a7b1e9e --- /dev/null +++ b/examples/peripherals/flash/flash_read_write/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(flash_read_write) diff --git a/examples/peripherals/flash/flash_read_write/Makefile b/examples/peripherals/flash/flash_read_write/Makefile new file mode 100644 index 00000000..44367c02 --- /dev/null +++ b/examples/peripherals/flash/flash_read_write/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. + +export BL_SDK_BASE + +CHIP ?= bl616 +BOARD ?= bl616dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/flash/flash_read_write/main.c b/examples/peripherals/flash/flash_read_write/main.c new file mode 100644 index 00000000..71dfd8b5 --- /dev/null +++ b/examples/peripherals/flash/flash_read_write/main.c @@ -0,0 +1,53 @@ +#include "bflb_flash.h" +#include "board.h" + +#define FLASH_TEST_SIZE 1 * 1024 * 1024 + +int main(void) +{ + board_init(); + + uint8_t write_buf[256]; + uint8_t read_buf[256]; + + for (uint16_t i = 0; i < 256; i++) { + write_buf[i] = i; + } + + for (uint32_t i = 1; i < (FLASH_TEST_SIZE / 1024); i++) { + printf("test addr:%08x\r\n", (0x00010000 + (i - 1) * 1024)); + /* erase 0x00010000 4k flash */ + bflb_flash_erase(0x00010000 + (i - 1) * 1024, i * 1024); + + memset(read_buf, 0, 256); + + /* read 0x00010000 flash data */ + bflb_flash_read(0x00010000 + (i - 1) * 1024, read_buf, sizeof(read_buf)); + for (uint16_t j = 0; j < 256; j++) { + if (read_buf[j] != 0xff) { + printf("flash test fail at %d, expect:%d but with %d\r\n", j, 0xff, read_buf[j]); + while (1) { + } + } + } + /* write 0x00010000 flash data */ + bflb_flash_write(0x00010000 + (i - 1) * 1024, write_buf, sizeof(write_buf)); + + memset(read_buf, 0, 256); + + /* read 0x00010000 flash data */ + bflb_flash_read(0x00010000 + (i - 1) * 1024, read_buf, sizeof(read_buf)); + + for (uint16_t j = 0; j < 256; j++) { + if (read_buf[j] != write_buf[j]) { + printf("flash test fail at %d, expect:%d but with %d\r\n", j, write_buf[j], read_buf[j]); + while (1) { + } + } + } + } + + printf("flash test success\r\n"); + while (1) { + } +} \ No newline at end of file diff --git a/examples/peripherals/flash/flash_read_write/proj.conf b/examples/peripherals/flash/flash_read_write/proj.conf new file mode 100644 index 00000000..13320d67 --- /dev/null +++ b/examples/peripherals/flash/flash_read_write/proj.conf @@ -0,0 +1 @@ +#set(CONFIG_XXX 1) \ No newline at end of file diff --git a/examples/peripherals/flash/flash_secure_read/CMakeLists.txt b/examples/peripherals/flash/flash_secure_read/CMakeLists.txt new file mode 100644 index 00000000..27f3a815 --- /dev/null +++ b/examples/peripherals/flash/flash_secure_read/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(flash_secure_read) diff --git a/examples/peripherals/flash/flash_secure_read/Makefile b/examples/peripherals/flash/flash_secure_read/Makefile new file mode 100644 index 00000000..44367c02 --- /dev/null +++ b/examples/peripherals/flash/flash_secure_read/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. + +export BL_SDK_BASE + +CHIP ?= bl616 +BOARD ?= bl616dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/flash/flash_secure_read/main.c b/examples/peripherals/flash/flash_secure_read/main.c new file mode 100644 index 00000000..87cd0ff5 --- /dev/null +++ b/examples/peripherals/flash/flash_secure_read/main.c @@ -0,0 +1,102 @@ +#include "bflb_flash.h" +#include "bflb_sec_aes.h" +#include "board.h" + +uint8_t aes_ctr_128bit_key[16] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c +}; + +uint8_t aes_ctr_128bit_iv[16] = { + 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#define AES_DATA_LEN 4096 + +ATTR_NOCACHE_NOINIT_RAM_SECTION uint8_t aes_ctr_pt_buffer[AES_DATA_LEN]; +ATTR_NOCACHE_NOINIT_RAM_SECTION uint8_t aes_ctr_ct_buffer[AES_DATA_LEN]; +ATTR_NOCACHE_NOINIT_RAM_SECTION uint8_t aes_ctr_tmp_buffer[AES_DATA_LEN]; +ATTR_NOCACHE_NOINIT_RAM_SECTION uint8_t aes_ctr_tmp_buffer2[AES_DATA_LEN]; + +static void bflb_data_compare(const uint8_t *expected, uint8_t *input, uint32_t len) +{ + int i = 0; + for (i = 0; i < len; i++) { + if (input[i] != expected[i]) { + printf("Compare fail at %d,input %02x, but expect %02x\r\n", i, input[i], expected[i]); + while (1) { + } + } + } +} + +int main(void) +{ + board_init(); + + struct bflb_device_s *aes; + + for (uint32_t i = 0; i < AES_DATA_LEN; i++) { + aes_ctr_pt_buffer[i] = i & 0xff; + } + + aes = bflb_device_get_by_name("aes"); + + bflb_group0_request_aes_access(aes); + + bflb_aes_init(aes); + bflb_aes_set_mode(aes, AES_MODE_CTR); + bflb_aes_setkey(aes, aes_ctr_128bit_key, 128); + bflb_aes_encrypt(aes, aes_ctr_pt_buffer, aes_ctr_128bit_iv, aes_ctr_ct_buffer, AES_DATA_LEN); + bflb_aes_decrypt(aes, aes_ctr_ct_buffer, aes_ctr_128bit_iv, aes_ctr_tmp_buffer, AES_DATA_LEN); + bflb_data_compare(aes_ctr_pt_buffer, aes_ctr_tmp_buffer, AES_DATA_LEN); + + printf("aes ctr128 encrypt & decrypt success\r\n"); + + bflb_flash_aes_disable(); + + /* erase 0x00010000 4k flash */ + bflb_flash_erase(0x00010000, 4096); + + memset(aes_ctr_tmp_buffer, 0, AES_DATA_LEN); + /* write 0x00010000 flash data */ + bflb_flash_write(0x00010000, aes_ctr_ct_buffer, AES_DATA_LEN); + bflb_flash_read(0x00010000, aes_ctr_tmp_buffer, AES_DATA_LEN); + bflb_data_compare(aes_ctr_ct_buffer, aes_ctr_tmp_buffer, AES_DATA_LEN); + printf("flash write & read success\r\n"); + + struct bflb_flash_aes_config_s config; + config.region = 0; + config.region_enable = 1; + config.lock_enable = 0; + config.key = aes_ctr_128bit_key; + config.keybits = FLASH_AES_KEY_128BITS; + config.iv = aes_ctr_128bit_iv; + config.start_addr = 64 * 1024; /* 0x00010000 */ + config.end_addr = 68 * 1024; /* 0x00011000 */ + + bflb_flash_aes_init(&config); + bflb_flash_aes_enable(); + + /* read 0x00010000 flash data */ + bflb_data_compare(aes_ctr_pt_buffer, (uint8_t *)(FLASH_XIP_BASE - 0x2000 + 0x00010000), AES_DATA_LEN); + printf("flash decrypt with flash aes ctr128 success\r\n"); + + bflb_flash_read(0x00010000, aes_ctr_tmp_buffer, AES_DATA_LEN); + bflb_aes_decrypt(aes, &aes_ctr_tmp_buffer[0], aes_ctr_128bit_iv, &aes_ctr_tmp_buffer2[0], 1024); + aes_ctr_128bit_iv[15] = 0x40; /* update counter */ + bflb_aes_decrypt(aes, &aes_ctr_tmp_buffer[1024], aes_ctr_128bit_iv, &aes_ctr_tmp_buffer2[1024], 1024); + aes_ctr_128bit_iv[15] = 0x80; /* update counter */ + bflb_aes_decrypt(aes, &aes_ctr_tmp_buffer[1024 * 2], aes_ctr_128bit_iv, &aes_ctr_tmp_buffer2[1024 * 2], 1024); + aes_ctr_128bit_iv[15] = 0xc0; /* update counter */ + bflb_aes_decrypt(aes, &aes_ctr_tmp_buffer[1024 * 3], aes_ctr_128bit_iv, &aes_ctr_tmp_buffer2[1024 * 3], 1024); + aes_ctr_128bit_iv[15] = 0x00; /* update counter */ + aes_ctr_128bit_iv[14] = 0x01; + bflb_data_compare(aes_ctr_pt_buffer, aes_ctr_tmp_buffer2, AES_DATA_LEN); + printf("flash decrypt with sec eng aes ctr128 success\r\n"); + + printf("flash test success\r\n"); + while (1) { + } +} \ No newline at end of file diff --git a/examples/peripherals/flash/flash_secure_read/proj.conf b/examples/peripherals/flash/flash_secure_read/proj.conf new file mode 100644 index 00000000..13320d67 --- /dev/null +++ b/examples/peripherals/flash/flash_secure_read/proj.conf @@ -0,0 +1 @@ +#set(CONFIG_XXX 1) \ No newline at end of file diff --git a/examples/peripherals/gpio/gpio_input_output/CMakeLists.txt b/examples/peripherals/gpio/gpio_input_output/CMakeLists.txt new file mode 100644 index 00000000..636f3535 --- /dev/null +++ b/examples/peripherals/gpio/gpio_input_output/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(gpio_input_output) diff --git a/examples/peripherals/gpio/gpio_input_output/Makefile b/examples/peripherals/gpio/gpio_input_output/Makefile new file mode 100644 index 00000000..44367c02 --- /dev/null +++ b/examples/peripherals/gpio/gpio_input_output/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. + +export BL_SDK_BASE + +CHIP ?= bl616 +BOARD ?= bl616dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/gpio/gpio_input_output/main.c b/examples/peripherals/gpio/gpio_input_output/main.c new file mode 100644 index 00000000..3412811c --- /dev/null +++ b/examples/peripherals/gpio/gpio_input_output/main.c @@ -0,0 +1,25 @@ +#include "bflb_gpio.h" + +struct bflb_device_s *gpio; + +extern void board_init(void); + +int main(void) +{ + board_init(); + + gpio = bflb_device_get_by_name("gpio"); + printf("gpio output\r\n"); + bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0); + bflb_gpio_init(gpio, GPIO_PIN_1, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0); + + while (1) { + bflb_gpio_set(gpio, GPIO_PIN_0); + printf("GPIO_PIN_1=%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_1)); + bflb_mtimer_delay_ms(2000); + + bflb_gpio_reset(gpio, GPIO_PIN_0); + printf("GPIO_PIN_1=%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_1)); + bflb_mtimer_delay_ms(2000); + } +} diff --git a/examples/peripherals/gpio/gpio_output/proj.conf b/examples/peripherals/gpio/gpio_input_output/proj.conf similarity index 100% rename from examples/peripherals/gpio/gpio_output/proj.conf rename to examples/peripherals/gpio/gpio_input_output/proj.conf diff --git a/examples/peripherals/gpio/gpio_interrupt/main.c b/examples/peripherals/gpio/gpio_interrupt/main.c index 416b8327..35979943 100644 --- a/examples/peripherals/gpio/gpio_interrupt/main.c +++ b/examples/peripherals/gpio/gpio_interrupt/main.c @@ -8,9 +8,9 @@ extern void board_init(void); void gpio_isr(int irq, void *arg) { static int i = 0; - bool intstatus = bflb_gpio_get_intstatus(gpio, GPIO_PIN_12); + bool intstatus = bflb_gpio_get_intstatus(gpio, GPIO_PIN_0); if (intstatus) { - bflb_gpio_int_clear(gpio, GPIO_PIN_12); + bflb_gpio_int_clear(gpio, GPIO_PIN_0); printf("%d\r\n", i++); } } @@ -22,8 +22,8 @@ int main(void) gpio = bflb_device_get_by_name("gpio"); printf("gpio interrupt\r\n"); - bflb_gpio_int_init(gpio, GPIO_PIN_12, GPIO_INT_TRIG_MODE_SYNC_FALLING_EDGE); - bflb_gpio_int_mask(gpio, GPIO_PIN_12, false); + bflb_gpio_int_init(gpio, GPIO_PIN_0, GPIO_INT_TRIG_MODE_SYNC_FALLING_EDGE); + bflb_gpio_int_mask(gpio, GPIO_PIN_0, false); bflb_irq_attach(gpio->irq_num, gpio_isr, gpio); bflb_irq_enable(gpio->irq_num); diff --git a/examples/peripherals/gpio/gpio_output/main.c b/examples/peripherals/gpio/gpio_output/main.c deleted file mode 100644 index cbb0f546..00000000 --- a/examples/peripherals/gpio/gpio_output/main.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "bflb_gpio.h" - -struct bflb_device_s *gpio; - -extern void board_init(void); - -int main(void) -{ - board_init(); - - gpio = bflb_device_get_by_name("gpio"); - printf("gpio output\r\n"); - bflb_gpio_init(gpio, GPIO_PIN_12, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0); - bflb_gpio_init(gpio, GPIO_PIN_24, GPIO_INPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_0); - - while (1) { - bflb_gpio_set(gpio, GPIO_PIN_12); - printf("%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_24)); - bflb_mtimer_delay_ms(2000); - - bflb_gpio_reset(gpio, GPIO_PIN_12); - printf("%x\r\n", bflb_gpio_read(gpio, GPIO_PIN_24)); - bflb_mtimer_delay_ms(2000); - } -} diff --git a/examples/peripherals/i2c/i2c_eeprom_interrupt/main.c b/examples/peripherals/i2c/i2c_eeprom_interrupt/main.c index aefad4bb..86dd4abf 100644 --- a/examples/peripherals/i2c/i2c_eeprom_interrupt/main.c +++ b/examples/peripherals/i2c/i2c_eeprom_interrupt/main.c @@ -43,7 +43,7 @@ int main(void) /* Set i2c interrupt */ bflb_i2c_int_mask(i2c0, I2C_INT_END | I2C_INT_NACK | I2C_INT_ARB | I2C_INT_FER, false); - bflb_irq_attach(i2c0->irq_num, i2c_isr, i2c0); + bflb_irq_attach(i2c0->irq_num, i2c_isr, NULL); bflb_irq_enable(i2c0->irq_num); struct bflb_i2c_msg_s msgs[2]; diff --git a/examples/peripherals/ir/ir_nec/main.c b/examples/peripherals/ir/ir_nec/main.c index 505dc291..7d9fc11f 100644 --- a/examples/peripherals/ir/ir_nec/main.c +++ b/examples/peripherals/ir/ir_nec/main.c @@ -1,52 +1,71 @@ #include "bflb_ir.h" #include "board.h" +#ifdef IR_TX_NEC struct bflb_device_s *irtx; +#endif +#ifdef IR_RX_NEC struct bflb_device_s *irrx; +#endif /* main */ int main(void) { - uint32_t tx_buffer[1] = {0xE916FF00}; - uint64_t rx_data; - uint8_t rx_len; - struct bflb_ir_tx_config_s tx_cfg; - struct bflb_ir_rx_config_s rx_cfg; - board_init(); - + printf("IR NEC case:\n\r"); - + board_ir_gpio_init(); +#ifdef IR_TX_NEC + uint32_t tx_buffer[1] = { 0xE916FF00 }; + struct bflb_ir_tx_config_s tx_cfg; + irtx = bflb_device_get_by_name("irtx"); - irrx = bflb_device_get_by_name("irrx"); - + /* TX init */ tx_cfg.tx_mode = IR_TX_NEC; bflb_ir_tx_init(irtx, &tx_cfg); - +#endif + +#ifdef IR_RX_NEC + uint64_t rx_data; + uint8_t rx_len; + struct bflb_ir_rx_config_s rx_cfg; + + irrx = bflb_device_get_by_name("irrx"); + /* RX init */ rx_cfg.rx_mode = IR_RX_NEC; rx_cfg.input_inverse = true; rx_cfg.deglitch_enable = false; bflb_ir_rx_init(irrx, &rx_cfg); - + /* Enable rx, wait for sending */ bflb_ir_rx_enable(irrx, true); - +#endif + +#ifdef IR_TX_NEC /* Send */ bflb_ir_send(irtx, tx_buffer, 1); - + printf("Send 0x%08lx\r\n", tx_buffer[0]); +#endif + +#ifdef IR_RX_NEC /* Receive */ rx_len = bflb_ir_receive(irrx, &rx_data); - + +#ifdef IR_TX_NEC /* Check data received */ if (rx_data != tx_buffer[0]) { - printf("Data error! receive bit: %d, value: %016llx\n\r", rx_len, rx_data); + printf("Data error! receive bit: %d, value: 0x%016llx\n\r", rx_len, rx_data); } else { printf("Success\n\r"); } +#else + printf("Receive bit: %d, value: 0x%016llx\n\r", rx_len, rx_data); +#endif +#endif printf("end\n\r"); diff --git a/examples/peripherals/ir/ir_rc5/main.c b/examples/peripherals/ir/ir_rc5/main.c index 2ab5276d..078cf7ad 100644 --- a/examples/peripherals/ir/ir_rc5/main.c +++ b/examples/peripherals/ir/ir_rc5/main.c @@ -1,52 +1,71 @@ #include "bflb_ir.h" #include "board.h" +#ifdef IR_TX_NEC struct bflb_device_s *irtx; +#endif +#ifdef IR_RX_NEC struct bflb_device_s *irrx; +#endif /* main */ int main(void) { - uint32_t tx_buffer[1] = {0x123D}; - uint64_t rx_data; - uint8_t rx_len; - struct bflb_ir_tx_config_s tx_cfg; - struct bflb_ir_rx_config_s rx_cfg; - board_init(); - + printf("IR RC-5 case:\n\r"); - + board_ir_gpio_init(); +#ifdef IR_TX_NEC + uint32_t tx_buffer[1] = { 0x123D }; + struct bflb_ir_tx_config_s tx_cfg; + irtx = bflb_device_get_by_name("irtx"); - irrx = bflb_device_get_by_name("irrx"); - + /* TX init */ tx_cfg.tx_mode = IR_TX_RC5; bflb_ir_tx_init(irtx, &tx_cfg); - +#endif + +#ifdef IR_RX_NEC + uint64_t rx_data; + uint8_t rx_len; + struct bflb_ir_rx_config_s rx_cfg; + + irrx = bflb_device_get_by_name("irrx"); + /* RX init */ rx_cfg.rx_mode = IR_RX_RC5; rx_cfg.input_inverse = true; rx_cfg.deglitch_enable = false; bflb_ir_rx_init(irrx, &rx_cfg); - + /* Enable rx, wait for sending */ bflb_ir_rx_enable(irrx, true); - +#endif + +#ifdef IR_TX_NEC /* Send */ bflb_ir_send(irtx, tx_buffer, 1); - + printf("Send 0x%08lx\r\n", tx_buffer[0]); +#endif + +#ifdef IR_RX_NEC /* Receive */ rx_len = bflb_ir_receive(irrx, &rx_data); - + +#ifdef IR_TX_NEC /* Check data received */ if (rx_data != tx_buffer[0]) { - printf("Data error! receive bit: %d, value: %016llx\n\r", rx_len, rx_data); + printf("Data error! receive bit: %d, value: 0x%016llx\n\r", rx_len, rx_data); } else { printf("Success\n\r"); } +#else + printf("Receive bit: %d, value: 0x%016llx\n\r", rx_len, rx_data); +#endif +#endif printf("end\n\r"); diff --git a/examples/peripherals/ir/ir_swm/main.c b/examples/peripherals/ir/ir_swm/main.c index 261f363e..7ff920d6 100644 --- a/examples/peripherals/ir/ir_swm/main.c +++ b/examples/peripherals/ir/ir_swm/main.c @@ -1,54 +1,75 @@ #include "bflb_ir.h" #include "board.h" +#ifdef IR_TX_NEC struct bflb_device_s *irtx; +#endif +#ifdef IR_RX_NEC struct bflb_device_s *irrx; +#endif /* main */ int main(void) { - uint16_t tx_buffer[21] = {1777,1777,3555,3555,1777,1777,1777,1777,1777,1777, - 3555,1777,1777,1777,1777,3555,3555,1777,1777,3555,1777}; - uint16_t rx_buffer[30]; - uint8_t rx_len; uint32_t i; - struct bflb_ir_tx_config_s tx_cfg; - struct bflb_ir_rx_config_s rx_cfg; board_init(); - + printf("IR SWM case:\n\r"); - + board_ir_gpio_init(); +#ifdef IR_TX_NEC + uint16_t tx_buffer[] = { 1777, 1777, 3555, 3555, 1777, 1777, 1777, 1777, 1777, 1777, + 3555, 1777, 1777, 1777, 1777, 3555, 3555, 1777, 1777, 3555, 1777 }; + struct bflb_ir_tx_config_s tx_cfg; + irtx = bflb_device_get_by_name("irtx"); - irrx = bflb_device_get_by_name("irrx"); - + /* TX init */ tx_cfg.tx_mode = IR_TX_SWM; bflb_ir_tx_init(irtx, &tx_cfg); - +#endif + +#ifdef IR_RX_NEC + uint16_t rx_buffer[30]; + uint8_t rx_len; + struct bflb_ir_rx_config_s rx_cfg; + + irrx = bflb_device_get_by_name("irrx"); + /* RX init */ rx_cfg.rx_mode = IR_RX_SWM; rx_cfg.input_inverse = true; rx_cfg.deglitch_enable = false; rx_cfg.end_threshold = 3999; bflb_ir_rx_init(irrx, &rx_cfg); - + /* Enable rx, wait for sending */ bflb_ir_rx_enable(irrx, true); - +#endif + +#ifdef IR_TX_NEC /* Send */ - bflb_ir_swm_send(irtx, tx_buffer, 21); - + bflb_ir_swm_send(irtx, tx_buffer, sizeof(tx_buffer) / sizeof(tx_buffer[0])); + printf("Send bit: %d, value:\r\n", sizeof(tx_buffer) / sizeof(tx_buffer[0])); + for (i = 0; i < sizeof(tx_buffer) / sizeof(tx_buffer[0]); i++) { + printf("%d ", tx_buffer[i]); + } + printf("\r\n"); +#endif + +#ifdef IR_RX_NEC /* Receive */ rx_len = bflb_ir_swm_receive(irrx, rx_buffer, 30); - + /* Print data received */ - printf("Receive bit: %d, value:\n\r", rx_len); - for (i = 0; i < rx_len; i ++) { + printf("Receive bit: %d, value:\r\n", rx_len); + for (i = 0; i < rx_len; i++) { printf("%d ", rx_buffer[i]); } + printf("\r\n"); +#endif printf("\n\rend\n\r"); diff --git a/examples/peripherals/ir/ir_tx_dma/CMakeLists.txt b/examples/peripherals/ir/ir_tx_dma/CMakeLists.txt new file mode 100644 index 00000000..3c819ce6 --- /dev/null +++ b/examples/peripherals/ir/ir_tx_dma/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(ir_tx_dma) diff --git a/examples/peripherals/ir/ir_tx_dma/Makefile b/examples/peripherals/ir/ir_tx_dma/Makefile new file mode 100644 index 00000000..919e3fa8 --- /dev/null +++ b/examples/peripherals/ir/ir_tx_dma/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. + +export BL_SDK_BASE + +CHIP ?= bl808 +BOARD ?= bl808dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/ir/ir_tx_dma/main.c b/examples/peripherals/ir/ir_tx_dma/main.c new file mode 100644 index 00000000..90373507 --- /dev/null +++ b/examples/peripherals/ir/ir_tx_dma/main.c @@ -0,0 +1,103 @@ +#include "bflb_ir.h" +#include "bflb_dma.h" +#include "bflb_mtimer.h" +#include "board.h" + +struct bflb_device_s *irtx; +struct bflb_device_s *dma0_ch0; + +static ATTR_NOCACHE_RAM_SECTION uint32_t tx_buffer[128]; +static volatile uint8_t dma_tc_flag0 = 0; + +void dma0_ch0_isr(void *arg) +{ + dma_tc_flag0++; + printf("tc done\r\n"); +} + +/* main */ +int main(void) +{ + uint32_t i; + struct bflb_dma_channel_lli_pool_s tx_llipool[1]; + struct bflb_dma_channel_lli_transfer_s tx_transfers[1]; + + struct bflb_ir_tx_config_s tx_cfg = { + .tx_mode = IR_TX_CUSTOMIZE, + .data_bits = 0, + .tail_inverse = 0, + .tail_enable = 0, + .head_inverse = 0, + .head_enable = 0, + .logic1_inverse = 1, + .logic0_inverse = 1, + .data_enable = 1, + .swm_enable = 0, + .output_modulation = 1, + .output_inverse = 0, + .freerun_enable = 1, + .continue_enable = 1, + .fifo_width = IR_TX_FIFO_WIDTH_24BIT, + .fifo_threshold = 1, + .logic0_pulse_width_1 = 0, + .logic0_pulse_width_0 = 0, + .logic1_pulse_width_1 = 2, + .logic1_pulse_width_0 = 0, + .head_pulse_width_1 = 0, + .head_pulse_width_0 = 0, + .tail_pulse_width_1 = 0, + .tail_pulse_width_0 = 0, + .modu_width_1 = 17, + .modu_width_0 = 34, + .pulse_width_unit = 1124, + }; + + struct bflb_dma_channel_config_s dma_config = { + .direction = DMA_MEMORY_TO_PERIPH, + .src_req = DMA_REQUEST_NONE, + .dst_req = DMA_REQUEST_IR_TX, + .src_addr_inc = DMA_ADDR_INCREMENT_ENABLE, + .dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE, + .src_burst_count = DMA_BURST_INCR1, + .dst_burst_count = DMA_BURST_INCR1, + .src_width = DMA_DATA_WIDTH_32BIT, + .dst_width = DMA_DATA_WIDTH_32BIT, + }; + + board_init(); + + printf("IR TX DMA case:\n\r"); + + board_ir_gpio_init(); + + irtx = bflb_device_get_by_name("irtx"); + + /* TX init */ + bflb_ir_tx_init(irtx, &tx_cfg); + bflb_ir_link_txdma(irtx, true); + bflb_ir_tx_enable(irtx, true); + + for (i = 0; i < 128; i++) { + tx_buffer[i] = i * 0x01010101; + } + + dma0_ch0 = bflb_device_get_by_name("dma0_ch0"); + bflb_dma_channel_init(dma0_ch0, &dma_config); + bflb_dma_channel_irq_attach(dma0_ch0, dma0_ch0_isr, NULL); + + tx_transfers[0].src_addr = (uint32_t)tx_buffer; + tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_IR_TDR; + tx_transfers[0].nbytes = 128 * 4; + bflb_dma_channel_lli_reload(dma0_ch0, tx_llipool, 1, tx_transfers, 1); + bflb_dma_channel_start(dma0_ch0); + + while (dma_tc_flag0 != 1) { + bflb_mtimer_delay_ms(1); + } + printf("Check wave\r\n"); + + printf("end\n\r"); + + while (1) { + } +} diff --git a/examples/peripherals/ir/ir_tx_dma/proj.conf b/examples/peripherals/ir/ir_tx_dma/proj.conf new file mode 100644 index 00000000..13320d67 --- /dev/null +++ b/examples/peripherals/ir/ir_tx_dma/proj.conf @@ -0,0 +1 @@ +#set(CONFIG_XXX 1) \ No newline at end of file diff --git a/examples/peripherals/mjpeg/mjpeg_no_camera/main.c b/examples/peripherals/mjpeg/mjpeg_no_camera/main.c index de81aaee..d2e32c92 100644 --- a/examples/peripherals/mjpeg/mjpeg_no_camera/main.c +++ b/examples/peripherals/mjpeg/mjpeg_no_camera/main.c @@ -13,23 +13,23 @@ volatile uint32_t pic_count = 0; volatile uint32_t pic_addr[MJPEG_MAX_FRAME_COUNT] = { 0 }; volatile uint32_t pic_len[MJPEG_MAX_FRAME_COUNT] = { 0 }; -uint8_t *pic; -volatile uint32_t jpeg_len; - void mjpeg_isr(int irq, void *arg) { + uint8_t *pic; + uint32_t jpeg_len; + uint32_t intstatus = bflb_mjpeg_get_intstatus(mjpeg); if (intstatus & MJPEG_INTSTS_ONE_FRAME) { + bflb_mjpeg_int_clear(mjpeg, MJPEG_INTCLR_ONE_FRAME); jpeg_len = bflb_mjpeg_get_frame_info(mjpeg, &pic); pic_addr[pic_count] = (uint32_t)pic; pic_len[pic_count] = jpeg_len; pic_count++; bflb_mjpeg_pop_one_frame(mjpeg); - bflb_mjpeg_int_clear(mjpeg, MJPEG_INTCLR_ONE_FRAME); } } -static uint16_t Q_Table_50_Y[64] = { +static uint16_t q_table_50_y[64] = { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, @@ -40,7 +40,7 @@ static uint16_t Q_Table_50_Y[64] = { 72, 92, 95, 98, 112, 100, 103, 99 }; -static uint16_t Q_Table_50_UV[64] = { +static uint16_t q_table_50_uv[64] = { 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, @@ -51,12 +51,17 @@ static uint16_t Q_Table_50_UV[64] = { 99, 99, 99, 99, 99, 99, 99, 99 }; -uint8_t jpgHeadBuf[800] = { 0 }; -uint32_t jpgHeadLength; +uint8_t jpg_head_buf[800] = { 0 }; +uint32_t jpg_head_len; uint8_t MJPEG_QUALITY = 50; -#define BUFFER_YUV 0xA8000000 +#if defined(BL616) +#define BSP_PSRAM_BASE 0xA8000000 +#elif defined(BL808) +#define BSP_PSRAM_BASE 0x50000000 +#endif + #define SIZE_BUFFER (4 * 1024 * 1024) void bflb_mjpeg_dump_hex(uint8_t *data, uint32_t len) @@ -76,8 +81,8 @@ void bflb_mjpeg_dump_hex(uint8_t *data, uint32_t len) int main(void) { - uint16_t tmpTableY[64] = { 0 }; - uint16_t tmpTableUV[64] = { 0 }; + uint16_t tmp_table_y[64] = { 0 }; + uint16_t tmp_table_uv[64] = { 0 }; board_init(); @@ -90,16 +95,16 @@ int main(void) config.resolution_y = Y; config.input_bufaddr0 = (uint32_t)test_64x64; config.input_bufaddr1 = 0; - config.output_bufaddr = (uint32_t)BUFFER_YUV + MJPEG_MAX_FRAME_COUNT * X * Y * 2; + config.output_bufaddr = (uint32_t)BSP_PSRAM_BASE + MJPEG_MAX_FRAME_COUNT * X * Y * 2; config.output_bufsize = SIZE_BUFFER - MJPEG_MAX_FRAME_COUNT * X * Y * 2; bflb_mjpeg_init(mjpeg, &config); - bflb_mjpeg_calculate_quantize_table(MJPEG_QUALITY, Q_Table_50_Y, tmpTableY); - bflb_mjpeg_calculate_quantize_table(MJPEG_QUALITY, Q_Table_50_UV, tmpTableUV); - bflb_mjpeg_fill_quantize_table(mjpeg, tmpTableY, tmpTableUV); - jpgHeadLength = JpegHeadCreate(YUV_MODE_422, MJPEG_QUALITY, X, Y, jpgHeadBuf); - bflb_mjpeg_fill_jpeg_header_tail(mjpeg, jpgHeadBuf, jpgHeadLength); + bflb_mjpeg_calculate_quantize_table(MJPEG_QUALITY, q_table_50_y, tmp_table_y); + bflb_mjpeg_calculate_quantize_table(MJPEG_QUALITY, q_table_50_uv, tmp_table_uv); + bflb_mjpeg_fill_quantize_table(mjpeg, tmp_table_y, tmp_table_uv); + jpg_head_len = JpegHeadCreate(YUV_MODE_422, MJPEG_QUALITY, X, Y, jpg_head_buf); + bflb_mjpeg_fill_jpeg_header_tail(mjpeg, jpg_head_buf, jpg_head_len); bflb_mjpeg_tcint_mask(mjpeg, false); bflb_irq_attach(mjpeg->irq_num, mjpeg_isr, NULL); @@ -108,6 +113,7 @@ int main(void) bflb_mjpeg_sw_run(mjpeg, MJPEG_MAX_FRAME_COUNT); while (pic_count < MJPEG_MAX_FRAME_COUNT) { + printf("pic count:%d\r\n",pic_count); bflb_mtimer_delay_ms(200); } diff --git a/examples/peripherals/mjpeg/mjpeg_no_camera/test_64x64_64x64.YUYV b/examples/peripherals/mjpeg/mjpeg_no_camera/test_64x64.YUYV similarity index 100% rename from examples/peripherals/mjpeg/mjpeg_no_camera/test_64x64_64x64.YUYV rename to examples/peripherals/mjpeg/mjpeg_no_camera/test_64x64.YUYV diff --git a/examples/peripherals/mtimer/main.c b/examples/peripherals/mtimer/main.c index 286f4e2c..afbb5d80 100644 --- a/examples/peripherals/mtimer/main.c +++ b/examples/peripherals/mtimer/main.c @@ -1,4 +1,5 @@ #include "bflb_mtimer.h" +#include "board.h" void systick_isr() { @@ -7,8 +8,6 @@ void systick_isr() printf("tick:%d\r\n", tick); } -extern void board_init(void); - int main(void) { board_init(); diff --git a/examples/peripherals/psram/CMakeLists.txt b/examples/peripherals/psram/CMakeLists.txt new file mode 100644 index 00000000..7f76978b --- /dev/null +++ b/examples/peripherals/psram/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(psram) diff --git a/examples/peripherals/psram/Makefile b/examples/peripherals/psram/Makefile new file mode 100644 index 00000000..9b01b7fe --- /dev/null +++ b/examples/peripherals/psram/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../.. + +export BL_SDK_BASE + +CHIP ?= bl616 +BOARD ?= bl616dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/psram/main.c b/examples/peripherals/psram/main.c new file mode 100644 index 00000000..23968a45 --- /dev/null +++ b/examples/peripherals/psram/main.c @@ -0,0 +1,93 @@ +#include "bflb_mtimer.h" +#include "board.h" + +#if defined(BL702) +#define BSP_PSRAM_BASE 0x26000000 +#elif defined(BL616) +#define BSP_PSRAM_BASE 0xA8000000 +#elif defined(BL808) +#define BSP_PSRAM_BASE 0x50000000 +#endif + +void test32(void) +{ + uint32_t i, val; + + printf("============= check uint32_t ==============\r\n"); + + for (i = 0; i < 256; i += 4) { + *((volatile uint32_t *)(BSP_PSRAM_BASE + i)) = i / 4; + } + + for (i = 0; i < 256; i += 4) { + val = *((volatile uint32_t *)(BSP_PSRAM_BASE + i)); + printf("addr = 0x%08X, val = 0x%08X\r\n", (BSP_PSRAM_BASE + i), *((volatile uint32_t *)(BSP_PSRAM_BASE + i))); + + if (i / 4 != val) { + printf("psram check fail\r\n"); + while (1) { + } + } + } +} + +void test16(void) +{ + uint32_t i, val; + + printf("============= check uint16_t ==============\r\n"); + + for (i = 0; i < 256; i += 2) { + *((volatile uint16_t *)(BSP_PSRAM_BASE + i)) = i / 2; + } + + for (i = 0; i < 256; i += 2) { + val = *((volatile uint16_t *)(BSP_PSRAM_BASE + i)); + printf("addr = 0x%08X, val = 0x%08X\r\n", (BSP_PSRAM_BASE + i), *((volatile uint16_t *)(BSP_PSRAM_BASE + i))); + + if (i / 2 != val) { + printf("psram check fail\r\n"); + while (1) { + } + } + } +} + +void test8(void) +{ + uint32_t i; + uint8_t val; + + printf("============= check uint8_t ==============\r\n"); + + for (i = 0; i < 256; i++) { + *((volatile uint8_t *)(BSP_PSRAM_BASE + i)) = i; + } + + for (i = 0; i < 256; i++) { + val = *((volatile uint8_t *)(BSP_PSRAM_BASE + i)); + printf("addr = 0x%08X, val = 0x%08X\r\n", (BSP_PSRAM_BASE + i), *((volatile uint8_t *)(BSP_PSRAM_BASE + i))); + + if ((uint8_t)i != val) { + printf("psram check fail\r\n"); + while (1) { + } + } + } +} + +int main(void) +{ + board_init(); + + printf(" psram read write test \r\n"); + + test8(); + test16(); + test32(); + + printf(" test success\r\n"); + + while (1) { + } +} \ No newline at end of file diff --git a/examples/peripherals/psram/proj.conf b/examples/peripherals/psram/proj.conf new file mode 100644 index 00000000..a63593b8 --- /dev/null +++ b/examples/peripherals/psram/proj.conf @@ -0,0 +1 @@ +set(CONFIG_PSRAM 1) \ No newline at end of file diff --git a/examples/peripherals/pwm_v1/pwm_all_channels/main.c b/examples/peripherals/pwm_v1/pwm_all_channels/main.c index 2dd1db76..4af951be 100644 --- a/examples/peripherals/pwm_v1/pwm_all_channels/main.c +++ b/examples/peripherals/pwm_v1/pwm_all_channels/main.c @@ -9,7 +9,7 @@ int main(void) board_init(); board_pwm_gpio_init(); - pwm = bflb_device_get_by_name("pwm0"); + pwm = bflb_device_get_by_name("pwm_v1"); /* period = .XCLK / .clk_div / .period = 32MHz / 32 / 1000 = 1KHz */ struct bflb_pwm_v1_channel_config_s cfg = { diff --git a/examples/peripherals/pwm_v1/pwm_basic/main.c b/examples/peripherals/pwm_v1/pwm_basic/main.c index c10c621d..9cc81460 100644 --- a/examples/peripherals/pwm_v1/pwm_basic/main.c +++ b/examples/peripherals/pwm_v1/pwm_basic/main.c @@ -9,7 +9,7 @@ int main(void) board_init(); board_pwm_gpio_init(); - pwm = bflb_device_get_by_name("pwm0"); + pwm = bflb_device_get_by_name("pwm_v1"); /* period = .XCLK / .clk_div / .period = 32MHz / 32 / 1000 = 1KHz */ struct bflb_pwm_v1_channel_config_s cfg = { diff --git a/examples/peripherals/pwm_v1/pwm_int/main.c b/examples/peripherals/pwm_v1/pwm_int/main.c index 6a385de7..4a981157 100644 --- a/examples/peripherals/pwm_v1/pwm_int/main.c +++ b/examples/peripherals/pwm_v1/pwm_int/main.c @@ -11,29 +11,29 @@ void pwm_isr(int irq, void *arg) uint32_t intstatus = bflb_pwm_v1_get_intstatus(pwm); if (intstatus & PWM_INTSTS_REPT_CH0) { + bflb_pwm_v1_int_clear(pwm, PWM_INTCLR_REPT_CH0); static int times = 0; printf("CH0 interrupt, %d times\r\n", ++times); - bflb_pwm_v1_int_clear(pwm, PWM_INTCLR_REPT_CH0); } if (intstatus & PWM_INTSTS_REPT_CH1) { + bflb_pwm_v1_int_clear(pwm, PWM_INTCLR_REPT_CH1); static int times = 0; printf("CH1 interrupt, %d times\r\n", ++times); - bflb_pwm_v1_int_clear(pwm, PWM_INTCLR_REPT_CH1); } if (intstatus & PWM_INTSTS_REPT_CH2) { + bflb_pwm_v1_int_clear(pwm, PWM_INTCLR_REPT_CH2); static int times = 0; printf("CH2 interrupt, %d times\r\n", ++times); - bflb_pwm_v1_int_clear(pwm, PWM_INTCLR_REPT_CH2); } if (intstatus & PWM_INTSTS_REPT_CH3) { + bflb_pwm_v1_int_clear(pwm, PWM_INTCLR_REPT_CH3); static int times = 0; printf("CH3 interrupt, %d times\r\n", ++times); - bflb_pwm_v1_int_clear(pwm, PWM_INTCLR_REPT_CH3); } if (intstatus & PWM_INTSTS_REPT_CH4) { + bflb_pwm_v1_int_clear(pwm, PWM_INTCLR_REPT_CH4); static int times = 0; printf("CH4 interrupt, %d times\r\n", ++times); - bflb_pwm_v1_int_clear(pwm, PWM_INTCLR_REPT_CH4); } } @@ -42,7 +42,7 @@ int main(void) board_init(); board_pwm_gpio_init(); - pwm = bflb_device_get_by_name("pwm0"); + pwm = bflb_device_get_by_name("pwm_v1"); /* period = .XCLK / .clk_div / .period = 32MHz / 32 / 1000 = 1KHz */ struct bflb_pwm_v1_channel_config_s cfg = { @@ -56,7 +56,7 @@ int main(void) bflb_pwm_v1_channel_set_threshold(pwm, i, 100, 500 + i * 100); /* duty = ((500 + i *100)-100)/1000 */ bflb_pwm_v1_int_enable(pwm, i, true); - bflb_irq_attach(pwm->irq_num, pwm_isr, pwm); + bflb_irq_attach(pwm->irq_num, pwm_isr, NULL); bflb_irq_enable(pwm->irq_num); bflb_pwm_v1_feature_control(pwm, i, PWM_CMD_SET_REPT_COUNT, REPT_CNT); bflb_pwm_v1_start(pwm, i); diff --git a/examples/peripherals/pwm_v2/pwm_all_channels/main.c b/examples/peripherals/pwm_v2/pwm_all_channels/main.c index 28710ed6..cfd426d1 100644 --- a/examples/peripherals/pwm_v2/pwm_all_channels/main.c +++ b/examples/peripherals/pwm_v2/pwm_all_channels/main.c @@ -2,14 +2,14 @@ #include "bflb_pwm_v2.h" #include "board.h" -struct bflb_device_s *pwm0; +struct bflb_device_s *pwm; int main(void) { board_init(); - board_pwm0_gpio_init(); + board_pwm_gpio_init(); - pwm0 = bflb_device_get_by_name("pwm0"); + pwm = bflb_device_get_by_name("pwm_v2_0"); /* period = .PBCLK / .clk_div / .period = 80MHz / 80 / 1000 = 1KHz */ struct bflb_pwm_v2_config_s cfg = { @@ -18,23 +18,23 @@ int main(void) .period = 1000, }; - bflb_pwm_v2_init(pwm0, &cfg); - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH0, 100, 500); /* duty = (500-100)/1000 = 40% */ - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH1, 200, 400); /* duty = (400-200)/1000 = 20% */ - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH2, 100, 999); /* duty = (999-100)/1000 = 89.9% */ - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH3, 0, 500); /* duty = (500-0)/1000 = 50% */ - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH0); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH0); - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH1); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH1); - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH2); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH2); - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH3); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH3); - bflb_pwm_v2_start(pwm0); + bflb_pwm_v2_init(pwm, &cfg); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH0, 100, 500); /* duty = (500-100)/1000 = 40% */ + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH1, 200, 400); /* duty = (400-200)/1000 = 20% */ + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH2, 100, 999); /* duty = (999-100)/1000 = 89.9% */ + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH3, 0, 500); /* duty = (500-0)/1000 = 50% */ + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH0); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH0); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH1); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH1); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH2); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH2); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH3); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH3); + bflb_pwm_v2_start(pwm); while (1) { - printf("pwm0 all_channel running\r\n"); + printf("pwm all_channel running\r\n"); bflb_mtimer_delay_ms(2000); } } diff --git a/examples/peripherals/pwm_v2/pwm_basic/main.c b/examples/peripherals/pwm_v2/pwm_basic/main.c index efafb271..a903c36f 100644 --- a/examples/peripherals/pwm_v2/pwm_basic/main.c +++ b/examples/peripherals/pwm_v2/pwm_basic/main.c @@ -2,14 +2,14 @@ #include "bflb_pwm_v2.h" #include "board.h" -struct bflb_device_s *pwm0; +struct bflb_device_s *pwm; int main(void) { board_init(); - board_pwm0_gpio_init(); + board_pwm_gpio_init(); - pwm0 = bflb_device_get_by_name("pwm0"); + pwm = bflb_device_get_by_name("pwm_v2_0"); /* period = .XCLK / .clk_div / .period = 40MHz / 40 / 1000 = 1KHz */ struct bflb_pwm_v2_config_s cfg = { @@ -18,13 +18,13 @@ int main(void) .period = 1000, }; - bflb_pwm_v2_init(pwm0, &cfg); - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH0, 100, 500); /* duty = (500-100)/1000 = 40% */ - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH0); - bflb_pwm_v2_start(pwm0); + bflb_pwm_v2_init(pwm, &cfg); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH0, 100, 500); /* duty = (500-100)/1000 = 40% */ + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH0); + bflb_pwm_v2_start(pwm); while (1) { - printf("pwm0 basic running\r\n"); + printf("pwm basic running\r\n"); bflb_mtimer_delay_ms(2000); } } diff --git a/examples/peripherals/pwm_v2/pwm_config_channel/main.c b/examples/peripherals/pwm_v2/pwm_config_channel/main.c index e132bd61..3fc2c6bb 100644 --- a/examples/peripherals/pwm_v2/pwm_config_channel/main.c +++ b/examples/peripherals/pwm_v2/pwm_config_channel/main.c @@ -2,7 +2,7 @@ #include "bflb_pwm_v2.h" #include "board.h" -struct bflb_device_s *pwm0; +struct bflb_device_s *pwm; /* period = .32K_CLK / .clk_div / .period = 32768Hz / 32 / 1000 = 1.024Hz */ struct bflb_pwm_v2_config_s cfg = { @@ -51,41 +51,41 @@ struct bflb_pwm_v2_channel_config_s ch_cfg[PWM_V2_CH_MAX] = { { int main(void) { board_init(); - board_pwm0_gpio_init(); + board_pwm_gpio_init(); - pwm0 = bflb_device_get_by_name("pwm0"); + pwm = bflb_device_get_by_name("pwm_v2_0"); - bflb_pwm_v2_init(pwm0, &cfg); - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH0, 0, 500); /* duty = (500-0)/1000 = 50% */ - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH1, 200, 400); /* duty = (400-200)/1000 = 20% */ - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH2, 99, 999); /* duty = (999-99)/1000 = 90% */ - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH3, 300, 900); /* duty = (900-300)/1000 = 60% */ - bflb_pwm_v2_channel_init(pwm0, PWM_CH0, &ch_cfg[0]); - bflb_pwm_v2_channel_init(pwm0, PWM_CH1, &ch_cfg[1]); - bflb_pwm_v2_channel_init(pwm0, PWM_CH2, &ch_cfg[2]); - bflb_pwm_v2_channel_init(pwm0, PWM_CH3, &ch_cfg[3]); - printf("pwm0 config_channel running\r\n"); - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH0); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH0); - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH1); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH1); - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH2); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH2); - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH3); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH3); - bflb_pwm_v2_start(pwm0); + bflb_pwm_v2_init(pwm, &cfg); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH0, 0, 500); /* duty = (500-0)/1000 = 50% */ + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH1, 200, 400); /* duty = (400-200)/1000 = 20% */ + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH2, 99, 999); /* duty = (999-99)/1000 = 90% */ + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH3, 300, 900); /* duty = (900-300)/1000 = 60% */ + bflb_pwm_v2_channel_init(pwm, PWM_CH0, &ch_cfg[0]); + bflb_pwm_v2_channel_init(pwm, PWM_CH1, &ch_cfg[1]); + bflb_pwm_v2_channel_init(pwm, PWM_CH2, &ch_cfg[2]); + bflb_pwm_v2_channel_init(pwm, PWM_CH3, &ch_cfg[3]); + printf("pwm config_channel running\r\n"); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH0); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH0); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH1); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH1); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH2); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH2); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH3); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH3); + bflb_pwm_v2_start(pwm); bflb_mtimer_delay_ms(10 * 1000); - bflb_pwm_v2_channel_positive_stop(pwm0, PWM_CH0); - bflb_pwm_v2_channel_negative_stop(pwm0, PWM_CH0); - bflb_pwm_v2_channel_positive_stop(pwm0, PWM_CH1); - bflb_pwm_v2_channel_negative_stop(pwm0, PWM_CH1); - bflb_pwm_v2_channel_positive_stop(pwm0, PWM_CH2); - bflb_pwm_v2_channel_negative_stop(pwm0, PWM_CH2); - bflb_pwm_v2_channel_positive_stop(pwm0, PWM_CH3); - bflb_pwm_v2_channel_negative_stop(pwm0, PWM_CH3); + bflb_pwm_v2_channel_positive_stop(pwm, PWM_CH0); + bflb_pwm_v2_channel_negative_stop(pwm, PWM_CH0); + bflb_pwm_v2_channel_positive_stop(pwm, PWM_CH1); + bflb_pwm_v2_channel_negative_stop(pwm, PWM_CH1); + bflb_pwm_v2_channel_positive_stop(pwm, PWM_CH2); + bflb_pwm_v2_channel_negative_stop(pwm, PWM_CH2); + bflb_pwm_v2_channel_positive_stop(pwm, PWM_CH3); + bflb_pwm_v2_channel_negative_stop(pwm, PWM_CH3); while (1) { - printf("pwm0 config_channel stop, please check wave\r\n"); + printf("pwm config_channel stop, please check wave\r\n"); bflb_mtimer_delay_ms(2000); } } diff --git a/examples/peripherals/pwm_v2/pwm_deadtime/main.c b/examples/peripherals/pwm_v2/pwm_deadtime/main.c index b4bc477c..2e1b36cf 100644 --- a/examples/peripherals/pwm_v2/pwm_deadtime/main.c +++ b/examples/peripherals/pwm_v2/pwm_deadtime/main.c @@ -2,7 +2,7 @@ #include "bflb_pwm_v2.h" #include "board.h" -struct bflb_device_s *pwm0; +struct bflb_device_s *pwm; uint8_t deadtime[PWM_V2_CH_MAX] = { 0x00 + 0, /* 0, bit[7:5]=0xx: dt = [7:0]*1, range(0~127), step(1) */ @@ -14,9 +14,9 @@ uint8_t deadtime[PWM_V2_CH_MAX] = { int main(void) { board_init(); - board_pwm0_gpio_init(); + board_pwm_gpio_init(); - pwm0 = bflb_device_get_by_name("pwm0"); + pwm = bflb_device_get_by_name("pwm_v2_0"); /* period = .PBCLK / .clk_div / .period = 80MHz / 40 / 2000 = 1KHz */ struct bflb_pwm_v2_config_s cfg = { @@ -35,31 +35,31 @@ int main(void) .dead_time = 0, }; - bflb_pwm_v2_init(pwm0, &cfg); + bflb_pwm_v2_init(pwm, &cfg); /* positive raise@(0+0) fall@1000, negative fall@0 raise@(1000+0) */ - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH0, 0, 1000); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH0, 0, 1000); /* positive raise@(0+200) fall@1000, negative fall@0 raise@(1000+200) */ - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH1, 0, 1000); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH1, 0, 1000); /* positive raise@(0+400) fall@1000, negative fall@0 raise@(1000+400) */ - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH2, 0, 1000); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH2, 0, 1000); /* positive raise@(0+800) fall@1000, negative fall@0 raise@(1000+800) */ - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH3, 0, 1000); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH3, 0, 1000); for (uint8_t ch = PWM_CH0; ch < PWM_V2_CH_MAX; ch++) { ch_cfg.dead_time = deadtime[ch]; - bflb_pwm_v2_channel_init(pwm0, ch, &ch_cfg); + bflb_pwm_v2_channel_init(pwm, ch, &ch_cfg); } - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH0); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH0); - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH1); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH1); - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH2); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH2); - bflb_pwm_v2_channel_positive_start(pwm0, PWM_CH3); - bflb_pwm_v2_channel_negative_start(pwm0, PWM_CH3); - bflb_pwm_v2_start(pwm0); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH0); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH0); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH1); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH1); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH2); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH2); + bflb_pwm_v2_channel_positive_start(pwm, PWM_CH3); + bflb_pwm_v2_channel_negative_start(pwm, PWM_CH3); + bflb_pwm_v2_start(pwm); while (1) { - printf("pwm0 deadtime running\r\n"); + printf("pwm deadtime running\r\n"); bflb_mtimer_delay_ms(2000); } } diff --git a/examples/peripherals/pwm_v2/pwm_int/main.c b/examples/peripherals/pwm_v2/pwm_int/main.c index ab964486..e6af6244 100644 --- a/examples/peripherals/pwm_v2/pwm_int/main.c +++ b/examples/peripherals/pwm_v2/pwm_int/main.c @@ -4,76 +4,76 @@ #define REPT_CNT 3 -struct bflb_device_s *pwm0; +struct bflb_device_s *pwm; void pwm_isr(int irq, void *arg) { - uint32_t intstatus = bflb_pwm_v2_get_intstatus(pwm0); + uint32_t intstatus = bflb_pwm_v2_get_intstatus(pwm); if (intstatus & PWM_INTSTS_CH0_L) { + bflb_pwm_v2_int_clear(pwm, PWM_INTCLR_CH0_L); static int times = 0; printf("CH0_L interrupt, %d times\r\n", ++times); - bflb_pwm_v2_int_clear(pwm0, PWM_INTCLR_CH0_L); } if (intstatus & PWM_INTSTS_CH0_H) { + bflb_pwm_v2_int_clear(pwm, PWM_INTSTS_CH0_H); static int times = 0; printf("CH0_H interrupt, %d times\r\n", ++times); - bflb_pwm_v2_int_clear(pwm0, PWM_INTSTS_CH0_H); } if (intstatus & PWM_INTSTS_CH1_L) { + bflb_pwm_v2_int_clear(pwm, PWM_INTCLR_CH1_L); static int times = 0; printf("CH1_L interrupt, %d times\r\n", ++times); - bflb_pwm_v2_int_clear(pwm0, PWM_INTCLR_CH1_L); } if (intstatus & PWM_INTSTS_CH1_H) { + bflb_pwm_v2_int_clear(pwm, PWM_INTCLR_CH1_H); static int times = 0; printf("CH1_H interrupt, %d times\r\n", ++times); - bflb_pwm_v2_int_clear(pwm0, PWM_INTCLR_CH1_H); } if (intstatus & PWM_INTSTS_CH2_L) { + bflb_pwm_v2_int_clear(pwm, PWM_INTCLR_CH2_L); static int times = 0; printf("CH2_L interrupt, %d times\r\n", ++times); - bflb_pwm_v2_int_clear(pwm0, PWM_INTCLR_CH2_L); } if (intstatus & PWM_INTSTS_CH2_H) { + bflb_pwm_v2_int_clear(pwm, PWM_INTCLR_CH2_H); static int times = 0; printf("CH2_H interrupt, %d times\r\n", ++times); - bflb_pwm_v2_int_clear(pwm0, PWM_INTCLR_CH2_H); } if (intstatus & PWM_INTSTS_CH3_L) { + bflb_pwm_v2_int_clear(pwm, PWM_INTCLR_CH3_L); static int times = 0; printf("CH3_L interrupt, %d times\r\n", ++times); - bflb_pwm_v2_int_clear(pwm0, PWM_INTCLR_CH3_L); } if (intstatus & PWM_INTSTS_CH3_H) { + bflb_pwm_v2_int_clear(pwm, PWM_INTCLR_CH3_H); static int times = 0; printf("CH3_H interrupt, %d times\r\n", ++times); - bflb_pwm_v2_int_clear(pwm0, PWM_INTCLR_CH3_H); } if (intstatus & PWM_INTSTS_PERIOD) { + bflb_pwm_v2_int_clear(pwm, PWM_INTSTS_PERIOD); static int times = 0; printf("period interrupt, %d times\r\n", ++times); - bflb_pwm_v2_int_clear(pwm0, PWM_INTSTS_PERIOD); } if (intstatus & PWM_INTSTS_BRAKE) { + bflb_pwm_v2_int_clear(pwm, PWM_INTSTS_BRAKE); static int times = 0; printf("brake interrupt, %d times\r\n", ++times); - bflb_pwm_v2_int_clear(pwm0, PWM_INTSTS_BRAKE); } if (intstatus & PWM_INTSTS_REPT) { + bflb_pwm_v2_int_clear(pwm, PWM_INTSTS_REPT); static int times = 0; printf("rept interrupt, %d times\r\n", ++times); - bflb_pwm_v2_stop(pwm0); - bflb_pwm_v2_int_clear(pwm0, PWM_INTSTS_REPT); + bflb_pwm_v2_stop(pwm); } } int main(void) { board_init(); - board_pwm0_gpio_init(); + board_pwm_gpio_init(); - pwm0 = bflb_device_get_by_name("pwm0"); + pwm = bflb_device_get_by_name("pwm_v2_0"); /* period = .PBCLK / .clk_div / .period = 80MHz / 80 / 1000 = 1kHz */ struct bflb_pwm_v2_config_s cfg = { @@ -82,12 +82,12 @@ int main(void) .period = 1000, }; - bflb_pwm_v2_init(pwm0, &cfg); - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH0, 100, 700); - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH1, 200, 300); - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH2, 600, 800); - bflb_pwm_v2_channel_set_threshold(pwm0, PWM_CH3, 500, 900); - bflb_pwm_v2_int_enable(pwm0, PWM_INTEN_CH0_L | \ + bflb_pwm_v2_init(pwm, &cfg); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH0, 100, 700); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH1, 200, 300); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH2, 600, 800); + bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH3, 500, 900); + bflb_pwm_v2_int_enable(pwm, PWM_INTEN_CH0_L | \ PWM_INTEN_CH0_H | \ PWM_INTEN_CH1_L | \ PWM_INTEN_CH1_H | \ @@ -98,11 +98,11 @@ int main(void) PWM_INTEN_PERIOD | \ PWM_INTEN_BRAKE | \ PWM_INTEN_REPT, true); - bflb_irq_attach(pwm0->irq_num, pwm_isr, pwm0); - bflb_irq_enable(pwm0->irq_num); - bflb_pwm_v2_feature_control(pwm0, PWM_CMD_SET_REPT_COUNT, REPT_CNT); - bflb_pwm_v2_feature_control(pwm0, PWM_CMD_SET_STOP_ON_REPT, true); - bflb_pwm_v2_start(pwm0); + bflb_irq_attach(pwm->irq_num, pwm_isr, NULL); + bflb_irq_enable(pwm->irq_num); + bflb_pwm_v2_feature_control(pwm, PWM_CMD_SET_REPT_COUNT, REPT_CNT); + bflb_pwm_v2_feature_control(pwm, PWM_CMD_SET_STOP_ON_REPT, true); + bflb_pwm_v2_start(pwm); while (1) { bflb_mtimer_delay_ms(2000); diff --git a/examples/peripherals/spi/spi_dma/main.c b/examples/peripherals/spi/spi_dma/main.c index fc3f810d..ab7d4c0b 100644 --- a/examples/peripherals/spi/spi_dma/main.c +++ b/examples/peripherals/spi/spi_dma/main.c @@ -47,10 +47,11 @@ int main(void) struct bflb_dma_channel_lli_transfer_s rx_transfers[1]; struct bflb_spi_config_s spi_cfg = { - .freq = 20 * 1000 * 1000, #if (SPI_CASE_SELECT == SPI_MASTER_CASE) + .freq = 1 * 1000 * 1000, .role = SPI_ROLE_MASTER, #else + .freq = 32 * 1000 * 1000, .role = SPI_ROLE_SLAVE, #endif .mode = SPI_MODE3, diff --git a/examples/peripherals/spi/spi_int/CMakeLists.txt b/examples/peripherals/spi/spi_int/CMakeLists.txt new file mode 100644 index 00000000..3ef9b47b --- /dev/null +++ b/examples/peripherals/spi/spi_int/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(spi_int) diff --git a/examples/peripherals/spi/spi_int/Makefile b/examples/peripherals/spi/spi_int/Makefile new file mode 100644 index 00000000..44367c02 --- /dev/null +++ b/examples/peripherals/spi/spi_int/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. + +export BL_SDK_BASE + +CHIP ?= bl616 +BOARD ?= bl616dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/spi/spi_int/main.c b/examples/peripherals/spi/spi_int/main.c new file mode 100644 index 00000000..868bdb51 --- /dev/null +++ b/examples/peripherals/spi/spi_int/main.c @@ -0,0 +1,244 @@ +#include "bflb_mtimer.h" +#include "bflb_spi.h" +#include "board.h" + +#define SPI_MASTER_CASE 0 +#define SPI_SLAVE_CASE 1 + +#define SPI_CASE_SELECT SPI_MASTER_CASE + +#define BUFF_LEN (8 * 1024) + +uint32_t tx_buff[BUFF_LEN / 4]; +uint32_t rx_buff[BUFF_LEN / 4]; + +struct bflb_device_s *spi0; + +/* poll test func */ +int bflb_spi_poll_test(uint32_t data_width) +{ + uint32_t data_mask; + uint32_t *p_tx = (uint32_t *)tx_buff; + uint32_t *p_rx = (uint32_t *)rx_buff; + + switch (data_width) { + case SPI_DATA_WIDTH_8BIT: + data_mask = 0x000000FF; + break; + case SPI_DATA_WIDTH_16BIT: + data_mask = 0x0000FFFF; + break; + case SPI_DATA_WIDTH_24BIT: + data_mask = 0x00FFFFFF; + break; + case SPI_DATA_WIDTH_32BIT: + data_mask = 0xFFFFFFFF; + break; + default: + printf("data_width err\r\n"); + return -1; + break; + } + + /* data init */ + for (uint16_t i = 0; i < BUFF_LEN / 4; i++) { + p_tx[i] = i; + p_rx[i] = 0; + } + + /* set data width */ + bflb_spi_feature_control(spi0, SPI_CMD_SET_DATA_WIDTH, data_width); + + /* send data */ + for (uint16_t i = 0; i < BUFF_LEN / 4; i++) { + p_rx[i] = bflb_spi_poll_send(spi0, p_tx[i]); + } + + /* check data */ + for (uint16_t i = 0; i < BUFF_LEN / 4; i++) { + if (p_rx[i] != (p_tx[i] & data_mask)) { + printf("data error, data[%d]:tx 0x%08lX, rx 0x%08lX\r\n", i, p_tx[i], p_rx[i]); + return -1; + } + } + printf("data check success\r\n"); + + return 0; +} + +/* poll_exchange test func */ +int bflb_spi_poll_exchange_test(uint32_t data_width) +{ + void *p_tx = (uint32_t *)tx_buff; + void *p_rx = (uint32_t *)rx_buff; + + /* data init */ + switch (data_width) { + case SPI_DATA_WIDTH_8BIT: + for (uint16_t i = 0; i < BUFF_LEN; i++) { + ((uint8_t *)p_tx)[i] = i; + ((uint8_t *)p_rx)[i] = 0; + } + break; + case SPI_DATA_WIDTH_16BIT: + for (uint16_t i = 0; i < BUFF_LEN / 2; i++) { + ((uint16_t *)p_tx)[i] = i << 0; + ((uint16_t *)p_rx)[i] = 0; + } + break; + case SPI_DATA_WIDTH_24BIT: + for (uint16_t i = 0; i < BUFF_LEN / 4; i++) { + ((uint32_t *)p_tx)[i] = ((i << 0) | i) & 0x00FFFFFF; + ((uint32_t *)p_rx)[i] = 0; + } + break; + case SPI_DATA_WIDTH_32BIT: + for (uint16_t i = 0; i < BUFF_LEN / 4; i++) { + ((uint32_t *)p_tx)[i] = (i << 0) | i; + ((uint32_t *)p_rx)[i] = 0; + } + break; + default: + return -1; + break; + } + + /* set data width */ + bflb_spi_feature_control(spi0, SPI_CMD_SET_DATA_WIDTH, data_width); + + /* send data */ + printf("spi poll exchange width %ld, len %d\r\n", data_width, BUFF_LEN); + bflb_spi_poll_exchange(spi0, p_tx, p_rx, BUFF_LEN); + + /* check data */ + for (uint16_t i = 0; i < BUFF_LEN / 4; i++) { + if (((uint32_t *)p_rx)[i] != ((uint32_t *)p_tx)[i]) { + printf("data error, data[%d]:tx 0x%08lX, rx 0x%08lX\r\n", i, ((uint32_t *)p_tx)[i], ((uint32_t *)p_rx)[i]); + return -1; + } + } + printf("data check success\r\n"); + + return 0; +} + +volatile uint32_t spi_tc_done_count = 0; + +void spi_isr(int irq, void *arg) +{ + uint32_t intstatus = bflb_spi_get_intstatus(spi0); + if (intstatus & SPI_INTSTS_TC) { + bflb_spi_int_clear(spi0, SPI_INTCLR_TC); + //printf("tc done\r\n"); + spi_tc_done_count++; + } +} + +int main(void) +{ + board_init(); + board_spi0_gpio_init(); + + struct bflb_spi_config_s spi_cfg = { + .freq = 20 * 1000 * 1000, +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + .role = SPI_ROLE_MASTER, +#else + .role = SPI_ROLE_SLAVE, +#endif + .mode = SPI_MODE3, + .data_width = SPI_DATA_WIDTH_8BIT, + .bit_order = SPI_BIT_MSB, + .byte_order = SPI_BYTE_LSB, + .tx_fifo_threshold = 0, + .rx_fifo_threshold = 0, + }; + + spi0 = bflb_device_get_by_name("spi0"); + bflb_spi_init(spi0, &spi_cfg); + + bflb_spi_tcint_mask(spi0, false); + bflb_irq_attach(spi0->irq_num, spi_isr, NULL); + bflb_irq_enable(spi0->irq_num); + + bflb_spi_feature_control(spi0, SPI_CMD_SET_CS_INTERVAL, 0); + + printf("\r\n************** spi poll send 8-bit test **************\r\n"); + if (bflb_spi_poll_test(SPI_DATA_WIDTH_8BIT) < 0) { + printf("poll send 8-bit test error!!!\r\n"); + } else { + printf("poll send 8-bit test success!\r\n"); + } + + printf("\r\n************** spi poll send 16-bit test **************\r\n"); + if (bflb_spi_poll_test(SPI_DATA_WIDTH_16BIT) < 0) { + printf("poll send 16-bit test error!!!\r\n"); + } else { + printf("poll send 16-bit test success!\r\n"); + } + + printf("\r\n************** spi poll send 24-bit test **************\r\n"); + if (bflb_spi_poll_test(SPI_DATA_WIDTH_24BIT) < 0) { + printf("poll send 24-bit test error!!!\r\n"); + } else { + printf("poll send 24-bit test success!\r\n"); + } + + printf("\r\n************** spi poll send 32-bit test **************\r\n"); + if (bflb_spi_poll_test(SPI_DATA_WIDTH_32BIT) < 0) { + printf("poll send 32-bit test error!!!\r\n"); + } else { + printf("poll send 32-bit test success!\r\n"); + } + + bflb_mtimer_delay_ms(10); + + printf("\r\n************** spi poll exchange 8-bit test **************\r\n"); + + if (bflb_spi_poll_exchange_test(SPI_DATA_WIDTH_8BIT) < 0) { + printf("poll exchange 8-bit test error!!!\r\n"); + } else { + printf("poll exchange 8-bit test success!\r\n"); + } + + printf("\r\n************** spi poll exchange 16-bit test **************\r\n"); + if (bflb_spi_poll_exchange_test(SPI_DATA_WIDTH_16BIT) < 0) { + printf("poll exchange 16-bit test error!!!\r\n"); + } else { + printf("poll exchange 16-bit test success!\r\n"); + } + + printf("\r\n************** spi poll exchange 24-bit test **************\r\n"); + if (bflb_spi_poll_exchange_test(SPI_DATA_WIDTH_24BIT) < 0) { + printf("poll exchange 24-bit test error!!!\r\n"); + } else { + printf("poll exchange 24-bit test success!\r\n"); + } + + printf("\r\n************** spi poll exchange 32-bit test **************\r\n"); + if (bflb_spi_poll_exchange_test(SPI_DATA_WIDTH_32BIT) < 0) { + printf("poll exchange 32-bit test error!!!\r\n"); + } else { + printf("poll exchange 32-bit test success!\r\n"); + } + + bflb_mtimer_delay_ms(10); + + printf("\r\n************** spi poll exchange only send 32-bit test **************\r\n"); + bflb_spi_poll_exchange(spi0, tx_buff, NULL, BUFF_LEN); + printf("poll exchange 32-bit only send test end!\r\n"); + + printf("\r\n************** spi poll exchange only receive 32-bit test **************\r\n"); + bflb_spi_poll_exchange(spi0, NULL, rx_buff, BUFF_LEN); + printf("poll exchange 32-bit only receive test end!\r\n"); + + printf("\r\n************** spi poll exchange spare time clock 32-bit test **************\r\n"); + bflb_spi_poll_exchange(spi0, NULL, NULL, BUFF_LEN); + printf("poll exchange 32-bit spare time clock test end!\r\n"); + + printf("\r\nspi test end\r\n"); + + printf("spi tc done count:%d\r\n", spi_tc_done_count); + while (1) { + } +} diff --git a/examples/peripherals/spi/spi_int/proj.conf b/examples/peripherals/spi/spi_int/proj.conf new file mode 100644 index 00000000..13320d67 --- /dev/null +++ b/examples/peripherals/spi/spi_int/proj.conf @@ -0,0 +1 @@ +#set(CONFIG_XXX 1) \ No newline at end of file diff --git a/examples/peripherals/spi/spi_poll/main.c b/examples/peripherals/spi/spi_poll/main.c index 3a1ce600..48644bcf 100644 --- a/examples/peripherals/spi/spi_poll/main.c +++ b/examples/peripherals/spi/spi_poll/main.c @@ -52,6 +52,9 @@ int bflb_spi_poll_test(uint32_t data_width) /* send data */ for (uint16_t i = 0; i < BUFF_LEN / 4; i++) { p_rx[i] = bflb_spi_poll_send(spi0, p_tx[i]); +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_us(10); /* delay for slave device prepare ok */ +#endif } /* check data */ @@ -129,10 +132,11 @@ int main(void) board_spi0_gpio_init(); struct bflb_spi_config_s spi_cfg = { - .freq = 20 * 1000 * 1000, #if (SPI_CASE_SELECT == SPI_MASTER_CASE) + .freq = 1 * 1000 * 1000, .role = SPI_ROLE_MASTER, #else + .freq = 32 * 1000 * 1000, .role = SPI_ROLE_SLAVE, #endif .mode = SPI_MODE3, @@ -154,21 +158,27 @@ int main(void) } else { printf("poll send 8-bit test success!\r\n"); } - +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_ms(1000); /* delay for slave device prepare ok */ +#endif printf("\r\n************** spi poll send 16-bit test **************\r\n"); if (bflb_spi_poll_test(SPI_DATA_WIDTH_16BIT) < 0) { printf("poll send 16-bit test error!!!\r\n"); } else { printf("poll send 16-bit test success!\r\n"); } - +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_ms(1000); /* delay for slave device prepare ok */ +#endif printf("\r\n************** spi poll send 24-bit test **************\r\n"); if (bflb_spi_poll_test(SPI_DATA_WIDTH_24BIT) < 0) { printf("poll send 24-bit test error!!!\r\n"); } else { printf("poll send 24-bit test success!\r\n"); } - +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_ms(1000); /* delay for slave device prepare ok */ +#endif printf("\r\n************** spi poll send 32-bit test **************\r\n"); if (bflb_spi_poll_test(SPI_DATA_WIDTH_32BIT) < 0) { printf("poll send 32-bit test error!!!\r\n"); @@ -176,7 +186,9 @@ int main(void) printf("poll send 32-bit test success!\r\n"); } - bflb_mtimer_delay_ms(10); +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_ms(1000); /* delay for slave device prepare ok */ +#endif printf("\r\n************** spi poll exchange 8-bit test **************\r\n"); @@ -185,21 +197,27 @@ int main(void) } else { printf("poll exchange 8-bit test success!\r\n"); } - +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_ms(1000); /* delay for slave device prepare ok */ +#endif printf("\r\n************** spi poll exchange 16-bit test **************\r\n"); if (bflb_spi_poll_exchange_test(SPI_DATA_WIDTH_16BIT) < 0) { printf("poll exchange 16-bit test error!!!\r\n"); } else { printf("poll exchange 16-bit test success!\r\n"); } - +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_ms(1000); /* delay for slave device prepare ok */ +#endif printf("\r\n************** spi poll exchange 24-bit test **************\r\n"); if (bflb_spi_poll_exchange_test(SPI_DATA_WIDTH_24BIT) < 0) { printf("poll exchange 24-bit test error!!!\r\n"); } else { printf("poll exchange 24-bit test success!\r\n"); } - +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_ms(1000); /* delay for slave device prepare ok */ +#endif printf("\r\n************** spi poll exchange 32-bit test **************\r\n"); if (bflb_spi_poll_exchange_test(SPI_DATA_WIDTH_32BIT) < 0) { printf("poll exchange 32-bit test error!!!\r\n"); @@ -207,16 +225,22 @@ int main(void) printf("poll exchange 32-bit test success!\r\n"); } - bflb_mtimer_delay_ms(10); +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_ms(1000); /* delay for slave device prepare ok */ +#endif printf("\r\n************** spi poll exchange only send 32-bit test **************\r\n"); bflb_spi_poll_exchange(spi0, tx_buff, NULL, BUFF_LEN); printf("poll exchange 32-bit only send test end!\r\n"); - +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_ms(1000); /* delay for slave device prepare ok */ +#endif printf("\r\n************** spi poll exchange only receive 32-bit test **************\r\n"); bflb_spi_poll_exchange(spi0, NULL, rx_buff, BUFF_LEN); printf("poll exchange 32-bit only receive test end!\r\n"); - +#if (SPI_CASE_SELECT == SPI_MASTER_CASE) + bflb_mtimer_delay_ms(1000); /* delay for slave device prepare ok */ +#endif printf("\r\n************** spi poll exchange spare time clock 32-bit test **************\r\n"); bflb_spi_poll_exchange(spi0, NULL, NULL, BUFF_LEN); printf("poll exchange 32-bit spare time clock test end!\r\n"); diff --git a/examples/peripherals/timer/timer_clksource_check/CMakeLists.txt b/examples/peripherals/timer/timer_clksource_check/CMakeLists.txt new file mode 100644 index 00000000..8f61d97f --- /dev/null +++ b/examples/peripherals/timer/timer_clksource_check/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(timer_clksource_check) diff --git a/examples/peripherals/timer/timer_clksource_check/Makefile b/examples/peripherals/timer/timer_clksource_check/Makefile new file mode 100644 index 00000000..44367c02 --- /dev/null +++ b/examples/peripherals/timer/timer_clksource_check/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. + +export BL_SDK_BASE + +CHIP ?= bl616 +BOARD ?= bl616dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/timer/timer_clksource_check/main.c b/examples/peripherals/timer/timer_clksource_check/main.c new file mode 100644 index 00000000..37719661 --- /dev/null +++ b/examples/peripherals/timer/timer_clksource_check/main.c @@ -0,0 +1,80 @@ +#include "bflb_mtimer.h" +#include "bflb_timer.h" +#include "board.h" + +#if !defined(BL702L) +uint8_t timer_clk_src_type[] = { + TIMER_CLKSRC_BCLK, + TIMER_CLKSRC_32K, + TIMER_CLKSRC_1K, + TIMER_CLKSRC_XTAL, +}; +#else +uint8_t timer_clk_src_type[] = { + TIMER_CLKSRC_32K, + TIMER_CLKSRC_1K, + TIMER_CLKSRC_XTAL, +}; +#endif + +int main(void) +{ + uint32_t i = 0; + uint32_t j = 0; + uint32_t cnt = 0; + + board_init(); + printf("Timer clksource check\n"); + + struct bflb_device_s *timer0; + timer0 = bflb_device_get_by_name("timer0"); + + /* timer clk = clock_source/(div + 1)*/ + struct bflb_timer_config_s cfg; + cfg.counter_mode = TIMER_COUNTER_MODE_PROLOAD; + cfg.clock_source = TIMER_CLKSRC_NO; + cfg.clock_div = 9; + cfg.trigger_comp_id = TIMER_COMP_ID_0; + cfg.comp0_val = 0xFFFFFFFF; + cfg.comp1_val = 0xFFFFFFFF; + cfg.comp2_val = 0xFFFFFFFF; + cfg.preload_val = 0; + + for (i = 0; i < sizeof(timer_clk_src_type) / sizeof(timer_clk_src_type[0]); i++) { + cnt = 0; + + if (timer_clk_src_type[i] == TIMER_CLKSRC_XTAL) { + printf("Timer Src Clk is XTAL\r\n"); + } else if (timer_clk_src_type[i] == TIMER_CLKSRC_32K) { + printf("Timer Src Clk is 32K\r\n"); + } else if (timer_clk_src_type[i] == TIMER_CLKSRC_1K) { + printf("Timer Src Clk is 1K\r\n"); + } +#if !defined(BL702L) + else if (timer_clk_src_type[i] == TIMER_CLKSRC_BCLK) { + printf("Timer Src Clk is BCLK\r\n"); + } +#endif + else { + printf("Other clock, not test.\r\n"); + continue; + } + + cfg.clock_source = timer_clk_src_type[i]; + bflb_timer_init(timer0, &cfg); + + for (j = 0; j < 10; j++) { + bflb_timer_start(timer0); + bflb_mtimer_delay_ms(1000); + cnt = bflb_timer_get_countervalue(timer0); + bflb_timer_stop(timer0); + bflb_mtimer_delay_ms(10); + printf("delay 1000ms, Test %lu times, cnt: %lu\r\n", j, cnt); + } + bflb_timer_deinit(timer0); + } + printf("case success.\r\n"); + while (1) { + bflb_mtimer_delay_ms(1500); + } +} diff --git a/examples/peripherals/timer/timer_clksource_check/proj.conf b/examples/peripherals/timer/timer_clksource_check/proj.conf new file mode 100644 index 00000000..13320d67 --- /dev/null +++ b/examples/peripherals/timer/timer_clksource_check/proj.conf @@ -0,0 +1 @@ +#set(CONFIG_XXX 1) \ No newline at end of file diff --git a/examples/peripherals/timer/timer_int/main.c b/examples/peripherals/timer/timer_int/main.c index b501a713..3a9c1342 100644 --- a/examples/peripherals/timer/timer_int/main.c +++ b/examples/peripherals/timer/timer_int/main.c @@ -10,18 +10,18 @@ void timer0_isr(int irq, void *arg) { bool status = bflb_timer_get_compint_status(timer0, TIMER_COMP_ID_0); if (status) { - printf("timer0 comp0 trigger\r\n"); bflb_timer_compint_clear(timer0, TIMER_COMP_ID_0); + printf("timer0 comp0 trigger\r\n"); } status = bflb_timer_get_compint_status(timer0, TIMER_COMP_ID_1); if (status) { - printf("timer0 comp1 trigger\r\n"); bflb_timer_compint_clear(timer0, TIMER_COMP_ID_1); + printf("timer0 comp1 trigger\r\n"); } status = bflb_timer_get_compint_status(timer0, TIMER_COMP_ID_2); if (status) { - printf("timer0 comp2 trigger\r\n"); bflb_timer_compint_clear(timer0, TIMER_COMP_ID_2); + printf("timer0 comp2 trigger\r\n"); } } @@ -29,18 +29,18 @@ void timer1_isr(int irq, void *arg) { bool status = bflb_timer_get_compint_status(timer1, TIMER_COMP_ID_0); if (status) { - printf("timer1 comp0 trigger\r\n"); bflb_timer_compint_clear(timer1, TIMER_COMP_ID_0); + printf("timer1 comp0 trigger\r\n"); } status = bflb_timer_get_compint_status(timer1, TIMER_COMP_ID_1); if (status) { - printf("timer1 comp1 trigger\r\n"); bflb_timer_compint_clear(timer1, TIMER_COMP_ID_1); + printf("timer1 comp1 trigger\r\n"); } status = bflb_timer_get_compint_status(timer1, TIMER_COMP_ID_2); if (status) { - printf("timer1 comp2 trigger\r\n"); bflb_timer_compint_clear(timer1, TIMER_COMP_ID_2); + printf("timer1 comp2 trigger\r\n"); } } @@ -77,8 +77,8 @@ int main(void) bflb_timer_init(timer0, &cfg0); bflb_timer_init(timer1, &cfg1); - bflb_irq_attach(timer0->irq_num, timer0_isr, timer0); - bflb_irq_attach(timer1->irq_num, timer1_isr, timer1); + bflb_irq_attach(timer0->irq_num, timer0_isr, NULL); + bflb_irq_attach(timer1->irq_num, timer1_isr, NULL); bflb_irq_enable(timer0->irq_num); bflb_irq_enable(timer1->irq_num); diff --git a/examples/peripherals/uart/uart_auto_baudrate/main.c b/examples/peripherals/uart/uart_auto_baudrate/main.c index 30a273e9..83bd71f3 100644 --- a/examples/peripherals/uart/uart_auto_baudrate/main.c +++ b/examples/peripherals/uart/uart_auto_baudrate/main.c @@ -1,37 +1,37 @@ #include "bflb_mtimer.h" #include "bflb_uart.h" +#include "bflb_clock.h" #include "board.h" -#include "bl616_hbn.h" -struct bflb_device_s *uart1; +struct bflb_device_s *uartx; void uart_isr(int irq, void *arg) { - uint32_t intstatus = bflb_uart_get_intstatus(uart1); + uint32_t intstatus = bflb_uart_get_intstatus(uartx); int ret; uint32_t baudrate; if (intstatus & UART_INTSTS_RX_AD5) { - ret = bflb_uart_feature_control(uart1, UART_CMD_GET_AUTO_BAUD, UART_AUTO_BAUD_0X55); - baudrate = 40000000 / (ret + 1); + bflb_uart_int_clear(uartx, UART_INTCLR_RX_AD5); + ret = bflb_uart_feature_control(uartx, UART_CMD_GET_AUTO_BAUD, UART_AUTO_BAUD_0X55); + baudrate = bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_UART, uartx->idx) / (ret + 1); printf("Detected baudrate by 0x55 is %d\r\n", baudrate); } - bflb_uart_int_clear(uart1, UART_INTCLR_RX_AD5); if (intstatus & UART_INTSTS_RX_ADS) { - ret = bflb_uart_feature_control(uart1, UART_CMD_GET_AUTO_BAUD, UART_AUTO_BAUD_START); - baudrate = 40000000 / (ret + 1); + bflb_uart_int_clear(uartx, UART_INTCLR_RX_ADS); + ret = bflb_uart_feature_control(uartx, UART_CMD_GET_AUTO_BAUD, UART_AUTO_BAUD_START); + baudrate = bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_UART, uartx->idx) / (ret + 1); printf("Detected baudrate by startbit is %d\r\n", baudrate); } - bflb_uart_int_clear(uart1, UART_INTCLR_RX_ADS); } int main(void) { board_init(); - board_uart1_gpio_init(); + board_uartx_gpio_init(); - uart1 = bflb_device_get_by_name("uart1"); + uartx = bflb_device_get_by_name(DEFAULT_TEST_UART); struct bflb_uart_config_s cfg; @@ -42,13 +42,13 @@ int main(void) cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 7; - bflb_uart_init(uart1, &cfg); + bflb_uart_init(uartx, &cfg); - bflb_uart_feature_control(uart1, UART_CMD_SET_AUTO_BAUD, 1); - bflb_uart_feature_control(uart1, UART_CMD_SET_ABR_ALLOWABLE_ERROR, 3); + bflb_uart_feature_control(uartx, UART_CMD_SET_AUTO_BAUD, 1); + bflb_uart_feature_control(uartx, UART_CMD_SET_ABR_ALLOWABLE_ERROR, 3); - bflb_irq_attach(uart1->irq_num, uart_isr, uart1); - bflb_irq_enable(uart1->irq_num); + bflb_irq_attach(uartx->irq_num, uart_isr, NULL); + bflb_irq_enable(uartx->irq_num); while (1) { } diff --git a/examples/peripherals/uart/uart_cts_rts/main.c b/examples/peripherals/uart/uart_cts_rts/main.c index b3b5bf39..5c96759d 100644 --- a/examples/peripherals/uart/uart_cts_rts/main.c +++ b/examples/peripherals/uart/uart_cts_rts/main.c @@ -2,34 +2,34 @@ #include "bflb_uart.h" #include "board.h" -struct bflb_device_s *uart1; +struct bflb_device_s *uartx; void uart_isr(int irq, void *arg) { - uint32_t intstatus = bflb_uart_get_intstatus(uart1); + uint32_t intstatus = bflb_uart_get_intstatus(uartx); if (intstatus & UART_INTSTS_RX_FIFO) { - while (bflb_uart_rxavailable(uart1)) { + while (bflb_uart_rxavailable(uartx)) { printf("enter rx fifo interrupt"); - printf("0x%02x\r\n", bflb_uart_getchar(uart1)); + printf("0x%02x\r\n", bflb_uart_getchar(uartx)); } - bflb_uart_feature_control(uart1, UART_CMD_SET_RTS_VALUE, 1); + bflb_uart_feature_control(uartx, UART_CMD_SET_RTS_VALUE, 1); } if (intstatus & UART_INTSTS_RTO) { - while (bflb_uart_rxavailable(uart1)) { + bflb_uart_int_clear(uartx, UART_INTCLR_RTO); + while (bflb_uart_rxavailable(uartx)) { printf("enter rto interrupt"); - printf("0x%02x\r\n", bflb_uart_getchar(uart1)); + printf("0x%02x\r\n", bflb_uart_getchar(uartx)); } - bflb_uart_int_clear(uart1, UART_INTCLR_RTO); } } int main(void) { board_init(); - board_uart1_gpio_init(); + board_uartx_gpio_init(); - uart1 = bflb_device_get_by_name("uart1"); + uartx = bflb_device_get_by_name(DEFAULT_TEST_UART); struct bflb_uart_config_s cfg; @@ -40,14 +40,14 @@ int main(void) cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 7; - bflb_uart_init(uart1, &cfg); + bflb_uart_init(uartx, &cfg); - bflb_uart_rxint_mask(uart1, false); - bflb_irq_attach(uart1->irq_num, uart_isr, uart1); - bflb_irq_enable(uart1->irq_num); + bflb_uart_rxint_mask(uartx, false); + bflb_irq_attach(uartx->irq_num, uart_isr, NULL); + bflb_irq_enable(uartx->irq_num); - bflb_uart_feature_control(uart1, UART_CMD_SET_SW_RTS_CONTROL, true); - bflb_uart_feature_control(uart1, UART_CMD_SET_RTS_VALUE, 0); + bflb_uart_feature_control(uartx, UART_CMD_SET_SW_RTS_CONTROL, true); + bflb_uart_feature_control(uartx, UART_CMD_SET_RTS_VALUE, 0); while (1) { bflb_mtimer_delay_ms(2000); } diff --git a/examples/peripherals/uart/uart_dma/main.c b/examples/peripherals/uart/uart_dma/main.c index 6dbffde0..ae6fa454 100644 --- a/examples/peripherals/uart/uart_dma/main.c +++ b/examples/peripherals/uart/uart_dma/main.c @@ -4,7 +4,7 @@ #include "bflb_l1c.h" #include "board.h" -struct bflb_device_s *uart1; +struct bflb_device_s *uartx; struct bflb_device_s *dma0_ch0; struct bflb_device_s *dma0_ch1; @@ -45,10 +45,10 @@ void sram_init() int main(void) { board_init(); - board_uart1_gpio_init(); + board_uartx_gpio_init(); sram_init(); - uart1 = bflb_device_get_by_name("uart1"); + uartx = bflb_device_get_by_name(DEFAULT_TEST_UART); struct bflb_uart_config_s cfg; @@ -59,9 +59,9 @@ int main(void) cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 0; - bflb_uart_init(uart1, &cfg); - bflb_uart_link_txdma(uart1, true); - bflb_uart_link_rxdma(uart1, true); + bflb_uart_init(uartx, &cfg); + bflb_uart_link_txdma(uartx, true); + bflb_uart_link_rxdma(uartx, true); dma0_ch0 = bflb_device_get_by_name("dma0_ch0"); dma0_ch1 = bflb_device_get_by_name("dma0_ch1"); @@ -70,7 +70,7 @@ int main(void) config.direction = DMA_MEMORY_TO_PERIPH; config.src_req = DMA_REQUEST_NONE; - config.dst_req = DMA_REQUEST_UART1_TX; + config.dst_req = DEFAULT_TEST_UART_DMA_TX_REQUEST; config.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE; config.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE; config.src_burst_count = DMA_BURST_INCR1; @@ -82,7 +82,7 @@ int main(void) struct bflb_dma_channel_config_s rxconfig; rxconfig.direction = DMA_PERIPH_TO_MEMORY; - rxconfig.src_req = DMA_REQUEST_UART1_RX; + rxconfig.src_req = DEFAULT_TEST_UART_DMA_RX_REQUEST; rxconfig.dst_req = DMA_REQUEST_NONE; rxconfig.src_addr_inc = DMA_ADDR_INCREMENT_DISABLE; rxconfig.dst_addr_inc = DMA_ADDR_INCREMENT_ENABLE; @@ -99,20 +99,20 @@ int main(void) struct bflb_dma_channel_lli_transfer_s tx_transfers[3]; tx_transfers[0].src_addr = (uint32_t)src_buffer; - tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_UART1_TDR; + tx_transfers[0].dst_addr = (uint32_t)DEFAULT_TEST_UART_DMA_TDR; tx_transfers[0].nbytes = 4100; tx_transfers[1].src_addr = (uint32_t)src2_buffer; - tx_transfers[1].dst_addr = (uint32_t)DMA_ADDR_UART1_TDR; + tx_transfers[1].dst_addr = (uint32_t)DEFAULT_TEST_UART_DMA_TDR; tx_transfers[1].nbytes = 4100; tx_transfers[2].src_addr = (uint32_t)src3_buffer; - tx_transfers[2].dst_addr = (uint32_t)DMA_ADDR_UART1_TDR; + tx_transfers[2].dst_addr = (uint32_t)DEFAULT_TEST_UART_DMA_TDR; tx_transfers[2].nbytes = 4100; struct bflb_dma_channel_lli_pool_s rx_llipool[20]; struct bflb_dma_channel_lli_transfer_s rx_transfers[1]; - rx_transfers[0].src_addr = (uint32_t)DMA_ADDR_UART1_RDR; + rx_transfers[0].src_addr = (uint32_t)DEFAULT_TEST_UART_DMA_RDR; rx_transfers[0].dst_addr = (uint32_t)receive_buffer; rx_transfers[0].nbytes = 50; diff --git a/examples/peripherals/uart/uart_error_interrupt/main.c b/examples/peripherals/uart/uart_error_interrupt/main.c index 59b9f6ec..4835220e 100644 --- a/examples/peripherals/uart/uart_error_interrupt/main.c +++ b/examples/peripherals/uart/uart_error_interrupt/main.c @@ -2,27 +2,27 @@ #include "bflb_uart.h" #include "board.h" -struct bflb_device_s *uart1; +struct bflb_device_s *uartx; static uint8_t pce_int_flag = 0; void uart_isr(int irq, void *arg) { - uint32_t intstatus = bflb_uart_get_intstatus(uart1); + uint32_t intstatus = bflb_uart_get_intstatus(uartx); if (intstatus & UART_INTSTS_PCE) { + bflb_uart_int_clear(uartx, UART_INTCLR_PCE); pce_int_flag++; printf("Enter Parity int\r\n"); } - bflb_uart_int_clear(uart1, UART_INTCLR_PCE); } int main(void) { board_init(); - board_uart1_gpio_init(); + board_uartx_gpio_init(); - uart1 = bflb_device_get_by_name("uart1"); + uartx = bflb_device_get_by_name(DEFAULT_TEST_UART); struct bflb_uart_config_s cfg; @@ -33,17 +33,17 @@ int main(void) cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 7; - bflb_uart_init(uart1, &cfg); + bflb_uart_init(uartx, &cfg); - bflb_uart_errint_mask(uart1, false); - bflb_irq_attach(uart1->irq_num, uart_isr, uart1); - bflb_irq_enable(uart1->irq_num); + bflb_uart_errint_mask(uartx, false); + bflb_irq_attach(uartx->irq_num, uart_isr, NULL); + bflb_irq_enable(uartx->irq_num); int ch; while (1) { - ch = bflb_uart_getchar(uart1); + ch = bflb_uart_getchar(uartx); if (ch != -1) { - bflb_uart_putchar(uart1, ch); + bflb_uart_putchar(uartx, ch); } if(pce_int_flag){ pce_int_flag = 0; diff --git a/examples/peripherals/uart/uart_feature_control/main.c b/examples/peripherals/uart/uart_feature_control/main.c index 7e84e9ff..08c99f16 100644 --- a/examples/peripherals/uart/uart_feature_control/main.c +++ b/examples/peripherals/uart/uart_feature_control/main.c @@ -2,14 +2,14 @@ #include "bflb_uart.h" #include "board.h" -struct bflb_device_s *uart1; +struct bflb_device_s *uartx; int main(void) { board_init(); - board_uart1_gpio_init(); + board_uartx_gpio_init(); - uart1 = bflb_device_get_by_name("uart1"); + uartx = bflb_device_get_by_name(DEFAULT_TEST_UART); struct bflb_uart_config_s cfg; @@ -20,18 +20,18 @@ int main(void) cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 7; - bflb_uart_init(uart1, &cfg); - - bflb_uart_feature_control(uart1, UART_CMD_SET_BAUD_RATE, 2000000); - bflb_uart_feature_control(uart1, UART_CMD_SET_DATA_BITS, UART_DATA_BITS_8); - bflb_uart_feature_control(uart1, UART_CMD_SET_STOP_BITS, UART_STOP_BITS_1); - bflb_uart_feature_control(uart1, UART_CMD_SET_PARITY_BITS, UART_PARITY_EVEN); + bflb_uart_init(uartx, &cfg); + + bflb_uart_feature_control(uartx, UART_CMD_SET_BAUD_RATE, 2000000); + bflb_uart_feature_control(uartx, UART_CMD_SET_DATA_BITS, UART_DATA_BITS_8); + bflb_uart_feature_control(uartx, UART_CMD_SET_STOP_BITS, UART_STOP_BITS_1); + bflb_uart_feature_control(uartx, UART_CMD_SET_PARITY_BITS, UART_PARITY_EVEN); int ch; while (1) { - ch = bflb_uart_getchar(uart1); + ch = bflb_uart_getchar(uartx); if (ch != -1) { - bflb_uart_putchar(uart1, ch); + bflb_uart_putchar(uartx, ch); } } } diff --git a/examples/peripherals/uart/uart_fifo_interrupt/main.c b/examples/peripherals/uart/uart_fifo_interrupt/main.c index 39e4fe55..e6678cbc 100644 --- a/examples/peripherals/uart/uart_fifo_interrupt/main.c +++ b/examples/peripherals/uart/uart_fifo_interrupt/main.c @@ -2,33 +2,33 @@ #include "bflb_uart.h" #include "board.h" -struct bflb_device_s *uart1; +struct bflb_device_s *uartx; static uint8_t uart_txbuf[128] = {0}; void uart_isr(int irq, void *arg) { - uint32_t intstatus = bflb_uart_get_intstatus(uart1); + uint32_t intstatus = bflb_uart_get_intstatus(uartx); if (intstatus & UART_INTSTS_RX_FIFO) { - while (bflb_uart_rxavailable(uart1)) { + while (bflb_uart_rxavailable(uartx)) { printf("enter rx fifo interrupt"); - printf("0x%02x\r\n", bflb_uart_getchar(uart1)); + printf("0x%02x\r\n", bflb_uart_getchar(uartx)); } } if (intstatus & UART_INTSTS_RTO) { - while (bflb_uart_rxavailable(uart1)) { + bflb_uart_int_clear(uartx, UART_INTCLR_RTO); + while (bflb_uart_rxavailable(uartx)) { printf("enter rto interrupt"); - printf("0x%02x\r\n", bflb_uart_getchar(uart1)); + printf("0x%02x\r\n", bflb_uart_getchar(uartx)); } - bflb_uart_int_clear(uart1, UART_INTCLR_RTO); } if (intstatus & UART_INTSTS_TX_FIFO) { for (uint8_t i = 0; i < 27; i++) { - bflb_uart_putchar(uart1,uart_txbuf[i]); + bflb_uart_putchar(uartx,uart_txbuf[i]); } - bflb_uart_txint_mask(uart1, true); + bflb_uart_txint_mask(uartx, true); printf("tx interrupt end"); } } @@ -36,9 +36,9 @@ void uart_isr(int irq, void *arg) int main(void) { board_init(); - board_uart1_gpio_init(); + board_uartx_gpio_init(); - uart1 = bflb_device_get_by_name("uart1"); + uartx = bflb_device_get_by_name("uart3"); for(uint8_t i=0; i < 128; i++) { @@ -54,12 +54,12 @@ int main(void) cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 7; - bflb_uart_init(uart1, &cfg); + //bflb_uart_init(uartx, &cfg); - bflb_uart_txint_mask(uart1, false); - bflb_uart_rxint_mask(uart1, false); - bflb_irq_attach(uart1->irq_num, uart_isr, uart1); - bflb_irq_enable(uart1->irq_num); + bflb_uart_txint_mask(uartx, false); + bflb_uart_rxint_mask(uartx, false); + bflb_irq_attach(uartx->irq_num, uart_isr, NULL); + bflb_irq_enable(uartx->irq_num); while (1) { bflb_mtimer_delay_ms(2000); diff --git a/examples/peripherals/uart/uart_ir/CMakeLists.txt b/examples/peripherals/uart/uart_ir/CMakeLists.txt new file mode 100644 index 00000000..20b581a0 --- /dev/null +++ b/examples/peripherals/uart/uart_ir/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(uart_ir) diff --git a/examples/peripherals/uart/uart_ir/Makefile b/examples/peripherals/uart/uart_ir/Makefile new file mode 100644 index 00000000..44367c02 --- /dev/null +++ b/examples/peripherals/uart/uart_ir/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. + +export BL_SDK_BASE + +CHIP ?= bl616 +BOARD ?= bl616dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/uart/uart_ir/main.c b/examples/peripherals/uart/uart_ir/main.c new file mode 100644 index 00000000..9dff06db --- /dev/null +++ b/examples/peripherals/uart/uart_ir/main.c @@ -0,0 +1,57 @@ +#include "bflb_mtimer.h" +#include "bflb_uart.h" +#include "board.h" + +struct bflb_device_s *uartx; + +static uint8_t uart_txbuf[128] = { 0 }; +static uint8_t uart_rxbuf[128] = { 0 }; + +int main(void) +{ + board_init(); + board_uartx_gpio_init(); + + uartx = bflb_device_get_by_name("uartx"); + + for (uint8_t i = 0; i < 128; i++) { + uart_txbuf[i] = i; + uart_rxbuf[i] = 0; + } + + struct bflb_uart_config_s cfg; + + cfg.baudrate = 115200; + cfg.data_bits = UART_DATA_BITS_8; + cfg.stop_bits = UART_STOP_BITS_1; + cfg.parity = UART_PARITY_NONE; + cfg.flow_ctrl = 0; + cfg.tx_fifo_threshold = 7; + cfg.rx_fifo_threshold = 1; + bflb_uart_init(uartx, &cfg); + + struct bflb_uart_ir_config_s ircfg; + + ircfg.tx_en = 1; + ircfg.rx_en = 1; + ircfg.tx_inverse = 0; + ircfg.rx_inverse = 1; + ircfg.tx_pluse_start = 112; + ircfg.tx_pluse_stop = 159; + ircfg.rx_pluse_start = 111; + bflb_uart_feature_control(uartx, UART_CMD_IR_CONFIG, (size_t)&ircfg); + + for (uint8_t i = 0; i < 128; i++) { + bflb_uart_putchar(uartx, uart_txbuf[i]); + while (bflb_uart_feature_control(uartx, UART_CMD_GET_RX_FIFO_CNT, 1) == 0) { + } + uart_rxbuf[i] = bflb_uart_getchar(uartx); + } + printf("All data arrived\r\n"); + + for (uint8_t j = 0; j < 128; j++) { + if (uart_txbuf[j] != uart_rxbuf[j]) { + printf("check fail, %d tx: %02x, rx: %02x\r\n", j, uart_txbuf[j], uart_rxbuf[j]); + } + } +} diff --git a/examples/peripherals/uart/uart_ir/proj.conf b/examples/peripherals/uart/uart_ir/proj.conf new file mode 100644 index 00000000..13320d67 --- /dev/null +++ b/examples/peripherals/uart/uart_ir/proj.conf @@ -0,0 +1 @@ +#set(CONFIG_XXX 1) \ No newline at end of file diff --git a/examples/peripherals/uart/uart_lin/main.c b/examples/peripherals/uart/uart_lin/main.c index c39edbe3..e424d847 100644 --- a/examples/peripherals/uart/uart_lin/main.c +++ b/examples/peripherals/uart/uart_lin/main.c @@ -2,28 +2,28 @@ #include "bflb_uart.h" #include "board.h" -struct bflb_device_s *uart1; +struct bflb_device_s *uartx; static uint8_t uart_txbuf[128] = { 0 }; static uint8_t lse_int_flag = 0; void uart_isr(int irq, void *arg) { - uint32_t intstatus = bflb_uart_get_intstatus(uart1); + uint32_t intstatus = bflb_uart_get_intstatus(uartx); if (intstatus & UART_INTSTS_RX_LSE) { + bflb_uart_int_clear(uartx, UART_INTCLR_RX_LSE); lse_int_flag++; printf("enter rx lse interrupt"); } - bflb_uart_int_clear(uart1, UART_INTCLR_RX_LSE); } int main(void) { board_init(); - board_uart1_gpio_init(); + board_uartx_gpio_init(); - uart1 = bflb_device_get_by_name("uart1"); + uartx = bflb_device_get_by_name(DEFAULT_TEST_UART); struct bflb_uart_config_s cfg; @@ -36,18 +36,18 @@ int main(void) cfg.rx_fifo_threshold = 7; - bflb_uart_errint_mask(uart1, false); - bflb_irq_attach(uart1->irq_num, uart_isr, uart1); - bflb_irq_enable(uart1->irq_num); + bflb_uart_errint_mask(uartx, false); + bflb_irq_attach(uartx->irq_num, uart_isr, NULL); + bflb_irq_enable(uartx->irq_num); - bflb_uart_feature_control(uart1, UART_CMD_SET_BREAK_VALUE, 4); - bflb_uart_feature_control(uart1, UART_CMD_SET_TX_LIN_VALUE, 1); - bflb_uart_feature_control(uart1, UART_CMD_SET_RX_LIN_VALUE, 1); + bflb_uart_feature_control(uartx, UART_CMD_SET_BREAK_VALUE, 4); + bflb_uart_feature_control(uartx, UART_CMD_SET_TX_LIN_VALUE, 1); + bflb_uart_feature_control(uartx, UART_CMD_SET_RX_LIN_VALUE, 1); - bflb_uart_init(uart1, &cfg); + bflb_uart_init(uartx, &cfg); - bflb_uart_putchar(uart1, 0xff); - bflb_uart_putchar(uart1, 0x1); + bflb_uart_putchar(uartx, 0xff); + bflb_uart_putchar(uartx, 0x1); while (1) { if (lse_int_flag) { diff --git a/examples/peripherals/uart/uart_poll/main.c b/examples/peripherals/uart/uart_poll/main.c index abfad18e..9776e2ad 100644 --- a/examples/peripherals/uart/uart_poll/main.c +++ b/examples/peripherals/uart/uart_poll/main.c @@ -2,14 +2,14 @@ #include "bflb_uart.h" #include "board.h" -struct bflb_device_s *uart1; +struct bflb_device_s *uartx; int main(void) { board_init(); - board_uart1_gpio_init(); + board_uartx_gpio_init(); - uart1 = bflb_device_get_by_name("uart1"); + uartx = bflb_device_get_by_name(DEFAULT_TEST_UART); struct bflb_uart_config_s cfg; @@ -20,13 +20,13 @@ int main(void) cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 7; - bflb_uart_init(uart1, &cfg); + bflb_uart_init(uartx, &cfg); int ch; while (1) { - ch = bflb_uart_getchar(uart1); + ch = bflb_uart_getchar(uartx); if (ch != -1) { - bflb_uart_putchar(uart1, ch); + bflb_uart_putchar(uartx, ch); } } } diff --git a/examples/peripherals/uart/uart_rs485/main.c b/examples/peripherals/uart/uart_rs485/main.c index 96b1ec86..0e5535bc 100644 --- a/examples/peripherals/uart/uart_rs485/main.c +++ b/examples/peripherals/uart/uart_rs485/main.c @@ -2,38 +2,38 @@ #include "bflb_uart.h" #include "board.h" -struct bflb_device_s *uart1; +struct bflb_device_s *uartx; static uint8_t uart_txbuf[128] = { 0 }; void uart_isr(int irq, void *arg) { - uint32_t intstatus = bflb_uart_get_intstatus(uart1); + uint32_t intstatus = bflb_uart_get_intstatus(uartx); if (intstatus & UART_INTSTS_RX_FIFO) { - while (bflb_uart_rxavailable(uart1)) { + while (bflb_uart_rxavailable(uartx)) { printf("enter rx fifo interrupt"); - printf("0x%02x\r\n", bflb_uart_getchar(uart1)); + printf("0x%02x\r\n", bflb_uart_getchar(uartx)); } } if (intstatus & UART_INTSTS_RTO) { - while (bflb_uart_rxavailable(uart1)) { + bflb_uart_int_clear(uartx, UART_INTCLR_RTO); + while (bflb_uart_rxavailable(uartx)) { printf("enter rto interrupt"); - printf("0x%02x\r\n", bflb_uart_getchar(uart1)); + printf("0x%02x\r\n", bflb_uart_getchar(uartx)); } - bflb_uart_int_clear(uart1, UART_INTCLR_RTO); } } int main(void) { board_init(); - board_uart1_gpio_init(); + board_uartx_gpio_init(); for (uint8_t i = 0; i < 128; i++) { uart_txbuf[i] = i; } - uart1 = bflb_device_get_by_name("uart1"); + uartx = bflb_device_get_by_name(DEFAULT_TEST_UART); struct bflb_uart_config_s cfg; @@ -44,18 +44,18 @@ int main(void) cfg.flow_ctrl = 0; cfg.tx_fifo_threshold = 7; cfg.rx_fifo_threshold = 7; - bflb_uart_init(uart1, &cfg); + bflb_uart_init(uartx, &cfg); - bflb_uart_feature_control(uart1, UART_CMD_SET_TX_RS485_EN, 1); - bflb_uart_feature_control(uart1, UART_CMD_SET_TX_RS485_POLARITY, 1); + bflb_uart_feature_control(uartx, UART_CMD_SET_TX_RS485_EN, 1); + bflb_uart_feature_control(uartx, UART_CMD_SET_TX_RS485_POLARITY, 1); for (uint8_t i = 0; i < 128; i++) { - bflb_uart_putchar(uart1, uart_txbuf[i]); + bflb_uart_putchar(uartx, uart_txbuf[i]); } - bflb_uart_rxint_mask(uart1, false); - bflb_irq_attach(uart1->irq_num, uart_isr, uart1); - bflb_irq_enable(uart1->irq_num); + bflb_uart_rxint_mask(uartx, false); + bflb_irq_attach(uartx->irq_num, uart_isr, NULL); + bflb_irq_enable(uartx->irq_num); while (1) { bflb_mtimer_delay_ms(2000); diff --git a/examples/peripherals/adc/adc_oneshot_1ch_int/CMakeLists.txt b/examples/peripherals/wdg/wdg_clksource_check/CMakeLists.txt similarity index 83% rename from examples/peripherals/adc/adc_oneshot_1ch_int/CMakeLists.txt rename to examples/peripherals/wdg/wdg_clksource_check/CMakeLists.txt index 98883fae..c109740a 100644 --- a/examples/peripherals/adc/adc_oneshot_1ch_int/CMakeLists.txt +++ b/examples/peripherals/wdg/wdg_clksource_check/CMakeLists.txt @@ -6,4 +6,4 @@ find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) sdk_set_main_file(main.c) -project(adc_oneshot_1ch_int) +project(wdg_clksource_check) diff --git a/examples/peripherals/wdg/wdg_clksource_check/Makefile b/examples/peripherals/wdg/wdg_clksource_check/Makefile new file mode 100644 index 00000000..44367c02 --- /dev/null +++ b/examples/peripherals/wdg/wdg_clksource_check/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. + +export BL_SDK_BASE + +CHIP ?= bl616 +BOARD ?= bl616dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/wdg/wdg_clksource_check/main.c b/examples/peripherals/wdg/wdg_clksource_check/main.c new file mode 100644 index 00000000..6fa7fb44 --- /dev/null +++ b/examples/peripherals/wdg/wdg_clksource_check/main.c @@ -0,0 +1,80 @@ +#include "bflb_mtimer.h" +#include "bflb_wdg.h" +#include "board.h" + +#if !defined(BL702L) +uint8_t wdg_clk_src_type[] = { + WDG_CLKSRC_BCLK, + WDG_CLKSRC_32K, + WDG_CLKSRC_1K, + WDG_CLKSRC_XTAL, +}; +#else +uint8_t wdg_clk_src_type[] = { + WDG_CLKSRC_32K, + WDG_CLKSRC_1K, + WDG_CLKSRC_XTAL, +}; +#endif + +int main(void) +{ + uint32_t i = 0; + uint32_t j = 0; + uint32_t cnt = 0; + + board_init(); + printf("Timer clksource check\n"); + + struct bflb_device_s *wdt; + wdt = bflb_device_get_by_name("watchdog"); + + /* watchdog clk = clock_source/(div + 1)*/ + struct bflb_wdg_config_s cfg; + cfg.clock_source = WDG_CLKSRC_32K; + cfg.clock_div = 0; + cfg.comp_val = 0xffff; + cfg.mode = WDG_MODE_INTERRUPT; + + for (i = 0; i < sizeof(wdg_clk_src_type) / sizeof(wdg_clk_src_type[0]); i++) { + cnt = 0; + + if (wdg_clk_src_type[i] == WDG_CLKSRC_XTAL) { + printf("Watchdog Src Clk is XTAL\r\n"); + cfg.clock_div = 199; + } else if (wdg_clk_src_type[i] == WDG_CLKSRC_32K) { + printf("Watchdog Src Clk is 32K\r\n"); + cfg.clock_div = 1; + } else if (wdg_clk_src_type[i] == WDG_CLKSRC_1K) { + printf("Watchdog Src Clk is 1K\r\n"); + cfg.clock_div = 1; + } +#if !defined(BL702L) + else if (wdg_clk_src_type[i] == WDG_CLKSRC_BCLK) { + printf("Watchdog Src Clk is BCLK\r\n"); + cfg.clock_div = 199; + } +#endif + else { + printf("Other clock, not test.\r\n"); + continue; + } + + cfg.clock_source = wdg_clk_src_type[i]; + bflb_wdg_init(wdt, &cfg); + + for (j = 0; j < 10; j++) { + bflb_wdg_reset_countervalue(wdt); + bflb_wdg_start(wdt); + bflb_mtimer_delay_ms(200); + cnt = bflb_wdg_get_countervalue(wdt); + bflb_wdg_stop(wdt); + bflb_mtimer_delay_ms(10); + printf("Delay 200ms, div = %lu, test %lu times, cnt: %lu\r\n", cfg.clock_div + 1, j, cnt); + } + } + printf("case success.\r\n"); + while (1) { + bflb_mtimer_delay_ms(1500); + } +} diff --git a/examples/peripherals/wdg/wdg_clksource_check/proj.conf b/examples/peripherals/wdg/wdg_clksource_check/proj.conf new file mode 100644 index 00000000..13320d67 --- /dev/null +++ b/examples/peripherals/wdg/wdg_clksource_check/proj.conf @@ -0,0 +1 @@ +#set(CONFIG_XXX 1) \ No newline at end of file diff --git a/examples/peripherals/wdg/wdg_int/main.c b/examples/peripherals/wdg/wdg_int/main.c index f685ad83..fc2950ae 100644 --- a/examples/peripherals/wdg/wdg_int/main.c +++ b/examples/peripherals/wdg/wdg_int/main.c @@ -7,8 +7,8 @@ static volatile uint8_t wdg_int_arrived = 0; void wdg_isr(int irq, void *arg) { - wdg_int_arrived = 1; bflb_wdg_compint_clear(wdg); + wdg_int_arrived = 1; } int main(void)